Skip to content

Commit

Permalink
Allow synthetic references (#618)
Browse files Browse the repository at this point in the history
A synthetic reference is when you know the 'id' of the thing
you want to reference and you want Snowfakery to treat it as
a reference. It is analogous to casting a pointer in C. Or
joining using an integer as a foreign key in a DB.

Currently this is not documented, because the internal id
mechanism isn't documented and may change. But it is useful
for some upcoming Salesforce-internal features and projects.
Once it's been tested there we can figure out how to make
it more widely available.

Probably in the long run, we will allow users to control their own
'id' mechanism on a per sObject basis. Then synthetic
references-by-id will make sense to them.
  • Loading branch information
Paul Prescod authored Feb 23, 2022
1 parent 27440db commit 21f9912
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
14 changes: 13 additions & 1 deletion snowfakery/template_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,20 @@ def random_number(self, min: int, max: int, step: int = 1) -> int:
"""Pick a random number between min and max like Python's randint."""
return random.randrange(min, max + 1, step)

def reference(self, x: Any):
def reference(
self, x: Any = None, object: str = None, id: Union[str, int] = None
):
"""YAML-embeddable function to Reference another object."""
if x is not None:
return self._reference_from_scalar(x)
elif object:
try:
id = int(id)
except TypeError:
raise DataGenError("Cannot interpret id as integer")
return ObjectReference(object, id)

def _reference_from_scalar(self, x: Any):
if hasattr(x, "id"): # reference to an object with an id
target = x
elif isinstance(x, str): # name of an object
Expand Down
20 changes: 20 additions & 0 deletions tests/test_references.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,3 +518,23 @@ def test_random_reference_to_nickname_fails(self):
with pytest.raises(DataGenError) as e:
generate(StringIO(yaml))
assert "there is no table named parent" in str(e).lower()

def test_reference_by_id(self, generated_rows):
yaml = """
- object: Parent
nickname: ParentNickname
just_once: true
- object: Child
fields:
parent1:
reference: ParentNickname
parent2:
reference:
object: Parent
id: 1
"""

generate(StringIO(yaml))
child = generated_rows.table_values("Child", 0)
assert child["parent1"] == child["parent2"]

0 comments on commit 21f9912

Please sign in to comment.