Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_current_stage(self):
"""
Go through the sequence of states emulating the real-life project lifecycle
"""
project = stm32pio.lib.Stm32pio(FIXTURE_PATH, parameters={'project': {'board': TEST_PROJECT_BOARD}})
for method, expected_stage in [(None, stm32pio.lib.ProjectStage.EMPTY),
('save_config', stm32pio.lib.ProjectStage.INITIALIZED),
('generate_code', stm32pio.lib.ProjectStage.GENERATED),
('pio_init', stm32pio.lib.ProjectStage.PIO_INITIALIZED),
('patch', stm32pio.lib.ProjectStage.PATCHED),
('build', stm32pio.lib.ProjectStage.BUILT),
('clean', stm32pio.lib.ProjectStage.EMPTY),
('pio_init', stm32pio.lib.ProjectStage.UNDEFINED)]:
if method is not None:
getattr(project, method)()
self.assertEqual(project.state.current_stage, expected_stage)
if expected_stage != stm32pio.lib.ProjectStage.UNDEFINED:
self.assertTrue(project.state.is_consistent)
else:
# Should be UNDEFINED when the project is messed up (pio_init() after clean())
self.assertFalse(project.state.is_consistent)
def test_status(self):
"""
Test the output returning by the app on a request to the 'status' command
"""
buffer_stdout = io.StringIO()
with contextlib.redirect_stdout(buffer_stdout), contextlib.redirect_stderr(None):
return_code = stm32pio.app.main(sys_argv=['status', '-d', str(FIXTURE_PATH)])
self.assertEqual(return_code, 0, msg="Non-zero return code")
matches_counter = 0
last_stage_pos = -1
for stage in stm32pio.lib.ProjectStage:
if stage != stm32pio.lib.ProjectStage.UNDEFINED:
match = re.search(r"^((\[ \])|(\[\*\])) {2}" + str(stage) + '$', buffer_stdout.getvalue(), re.MULTILINE)
self.assertTrue(match, msg="Status information was not found on STDOUT")
if match:
matches_counter += 1
self.assertGreater(match.start(), last_stage_pos, msg="The order of stages is messed up")
last_stage_pos = match.start()
self.assertEqual(matches_counter, len(stm32pio.lib.ProjectStage) - 1)
def state(self) -> dict:
"""
Get the current project state in the appropriate Qt form. Update the cached 'current stage' value as a side
effect
"""
if self.project is not None:
state = self.project.state
# Side-effect: caching the current stage at the same time to avoid the flooding of calls to the 'state'
# getter (many IO operations). Requests to 'state' and 'stage' are usually goes together so there is no need
# to necessarily keeps them separated
self._current_stage = str(state.current_stage)
state.pop(stm32pio.lib.ProjectStage.UNDEFINED) # exclude UNDEFINED key
# Convert to {string: boolean} dict (will be translated into the JavaScript object)
return { stage.name: value for stage, value in state.items() }
else:
return self._state
def __str__(self):
"""
Pretty human-readable complete representation of the project state (not including the service one UNDEFINED to
not confuse the end-user)
"""
# Need 2 spaces between the icon and the text to look fine
return '\n'.join(f"{'[*]' if stage_value else '[ ]'} {str(stage_name)}"
for stage_name, stage_value in self.items() if stage_name != ProjectStage.UNDEFINED)
def current_stage(self) -> ProjectStage:
last_consistent_stage = ProjectStage.UNDEFINED
not_fulfilled_stage_found = False
# Search for a consecutive sequence of True's and find the last of them. For example, if the array is
# [1,1,1,0,0,0,0]
# ^
# we should consider 2 as the last index
for stage_name, stage_fulfilled in self.items():
if stage_fulfilled:
if not_fulfilled_stage_found:
# Fall back to the UNDEFINED stage if we have breaks in conditions results array. E.g., for
# [1,1,1,0,1,0,0]
# we should return UNDEFINED as it doesn't look like a correct set of files actually
last_consistent_stage = ProjectStage.UNDEFINED
break
else:
last_consistent_stage = stage_name