Skip to content

Commit

Permalink
Merge pull request #29 from thread/default-context-next-state
Browse files Browse the repository at this point in the history
Add defaults values to context dependent destinations
  • Loading branch information
danpalmer committed Jan 16, 2018
2 parents 725f6f1 + 0860b54 commit 658ed43
Show file tree
Hide file tree
Showing 8 changed files with 20 additions and 17 deletions.
1 change: 1 addition & 0 deletions routemaster/config/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ def _load_context_next_states(
)
for idx, yaml_option in enumerate(yaml_next_states['destinations'])
],
default=yaml_next_states['default'],
)


Expand Down
5 changes: 3 additions & 2 deletions routemaster/config/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,19 @@ class ContextNextStates(NamedTuple):
"""Defined a choice based on a path in the given `label_context`."""
path: str
destinations: Iterable[ContextNextStatesOption]
default: str # noqa: E704 misidentified "multiple statements on one line"

def next_state_for_label(self, label_context: 'Context') -> str:
"""Returns next state based on context value at `self.path`."""
val = label_context.lookup(self.path.split('.'))
for destination in self.destinations:
if destination.value == val:
return destination.state
raise RuntimeError("Handle this gracefully.")
return self.default

def all_destinations(self) -> Iterable[str]:
"""Returns all possible destination states."""
return [x.state for x in self.destinations]
return [x.state for x in self.destinations] + [self.default]


class NoNextStates(NamedTuple):
Expand Down
2 changes: 2 additions & 0 deletions routemaster/config/schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ properties:
type:
const: 'metadata'
path: *dotted_path_definition
default:
type: string
destinations:
type: array
minItems: 1
Expand Down
6 changes: 4 additions & 2 deletions routemaster/config/tests/test_loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ def test_realistic_config():
state='stage3',
value='2',
),
]
],
default='end',
),
exit_condition=ExitConditionProgram(
'foo.bar is defined',
Expand Down Expand Up @@ -271,7 +272,8 @@ def test_environment_variables_override_config_file_for_database_config():
state='stage3',
value='2',
),
]
],
default='end',
),
exit_condition=ExitConditionProgram(
'foo.bar is defined',
Expand Down
9 changes: 5 additions & 4 deletions routemaster/config/tests/test_next_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,25 @@ def test_context_next_states(make_context):
ContextNextStatesOption(state='1', value=True),
ContextNextStatesOption(state='2', value=False),
],
default='3',
)

context = make_context(label='label1', metadata={'foo': True})

assert next_states.all_destinations() == ['1', '2']
assert next_states.all_destinations() == ['1', '2', '3']
assert next_states.next_state_for_label(context) == '1'


def test_context_next_states_raises_for_no_valid_state(make_context):
def test_context_next_states_returns_default_if_no_match(make_context):
next_states = ContextNextStates(
path='metadata.foo',
destinations=[
ContextNextStatesOption(state='1', value=True),
ContextNextStatesOption(state='2', value=False),
],
default='3',
)

context = make_context(label='label1', metadata={'foo': 'bar'})

with pytest.raises(RuntimeError):
next_states.next_state_for_label(context)
assert next_states.next_state_for_label(context) == '3'
10 changes: 2 additions & 8 deletions routemaster/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,6 @@
next_states=ContextNextStates(
path='feeds.tests.should_do_alternate_action',
destinations=[
ContextNextStatesOption(
state='perform_action',
value=None,
),
ContextNextStatesOption(
state='perform_action',
value=False,
Expand All @@ -83,6 +79,7 @@
value=True,
),
],
default='perform_action',
),
exit_condition=ExitConditionProgram(
'metadata.should_progress = true',
Expand All @@ -99,10 +96,6 @@
next_states=ContextNextStates(
path='feeds.tests.should_loop',
destinations=[
ContextNextStatesOption(
state='end',
value=None,
),
ContextNextStatesOption(
state='end',
value=False,
Expand All @@ -112,6 +105,7 @@
value=True,
),
],
default='end',
),
),
Gate(
Expand Down
3 changes: 2 additions & 1 deletion routemaster/tests/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ def test_nonexistent_node_destination_invalid(app_config):
state='end',
value='2',
),
]
],
default='end',
),
exit_condition=ExitConditionProgram('false'),
),
Expand Down
1 change: 1 addition & 0 deletions test_data/realistic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ state_machines:
next:
type: context
path: foo.bar
default: end
destinations:
- state: stage3
value: '1'
Expand Down

0 comments on commit 658ed43

Please sign in to comment.