def _compile_recursive(self, key: str, obj: object): matcher_func, multiple = self._recursive[key] if multiple: objs = ensure_list(obj) inner_matchers = list(map_compile(self.compile, objs)) else: with on_key(key): inner_matchers = [self.compile(obj)] return RecursiveMatcherFactory(matcher_func, inner_matchers)
def test_map_compile_for_failing_func(): child_error = CompilationError("message", node=NamedNode("key")) failing_func = Mock(side_effect=[1, child_error, 2]) results = map_compile(failing_func, [3, 4, 5]) assert next(results) == 1 with raises(CompilationError) as error_info: next(results) assert error_info.value.path == [IndexedNode(1), NamedNode("key")] failing_func.assert_has_calls([call(3), call(4)])
def compile_url_param(value: object) -> UrlParam: if value is None: return value if isinstance(value, list): return list(map_compile(compile_url_param_value, value)) try: return compile_url_param_value(value) except CompilationError as error: raise CompilationError( f"Not allowed type for a request parameter: {value.__class__}", cause=error, )
def compile(self, obj: object) -> CaseCompiled: """`obj` should be a mapping.""" obj = ensure_mapping(obj) compiled = self._default label_obj = obj.get(_KEY_LABEL) with on_key(_KEY_LABEL): label = ensure_optional_str(label_obj) # `label` is always replaced. compiled = replace(compiled, label=label) enabled_obj = obj.get(_KEY_ENABLED) if enabled_obj is not None: with on_key(_KEY_ENABLED): enabled = ensure_bool(enabled_obj) compiled = replace(compiled, enabled=enabled) conditions_obj = obj.get(_KEY_CONDITIONS) if conditions_obj is not None: with on_key(_KEY_CONDITIONS): conditions = list( map_compile( self._description.compile, ensure_list(conditions_obj), ) ) compiled = replace(compiled, conditions=conditions) request_obj = obj.get(_KEY_REQUEST) if request_obj is not None: with on_key(_KEY_REQUEST): request = self._request.compile(request_obj) compiled = replace(compiled, request=request) response_obj = obj.get(_KEY_RESPONSE) if response_obj is not None: with on_key(_KEY_RESPONSE): response = self._response.compile(response_obj) compiled = replace(compiled, response=response) return compiled
def compile(self, obj: object): """`obj` should be a mapping.""" obj = ensure_mapping(obj) extraction_obj = obj.get(_KEY_DESCRIBE) with on_key(_KEY_DESCRIBE): extractor = self._extraction.compile(extraction_obj) predicate_objs = ensure_list(obj.get(_KEY_SHOULD, [])) with on_key(_KEY_SHOULD): predicates = list( map_compile( self._predicate.compile, predicate_objs, )) value_name_obj = obj.get(_KEY_AS) with on_key(_KEY_AS): value_name = ensure_optional_str(value_name_obj) return Description(extractor=extractor, predicates=predicates, value_name=value_name)
def test_map_compile_for_successful_func(): results = map_compile(lambda n: n * 2, [1, 2, 3]) assert next(results) == 2 assert next(results) == 4 assert next(results) == 6
def test_map_compile_for_empty_list(): results = map_compile(lambda x: x, []) with raises(StopIteration): next(results)
def _compile_descriptions(self, obj: object) -> List[Description]: obj = ensure_list(obj) return list(map_compile(self._description.compile, obj))
def _compile_status_code(self, obj: object) -> List[Predicate]: obj = ensure_list(obj) return list(map_compile(self._predicate.compile, obj))
def compile(self, obj: object, arguments: Optional[Arguments] = None) -> Scenario: """ Compile the given object into a scenario. Args: obj: A compiled object, which should be a mapping. arguments: Arguments to inject. Returns: The scenario as the result of compilation. Raises: CompilationError: when the compilation fails. """ obj = ensure_mapping(obj) arguments = arguments or {} label_obj = inject_arguments(obj.get(_KEY_LABEL), arguments) with on_key(_KEY_LABEL): label = ensure_optional_str(label_obj) parameters_obj = obj.get(_KEY_PARAMETERS) if parameters_obj is not None: with on_key(_KEY_PARAMETERS): parameters_obj = ensure_list(parameters_obj) parameters = list( map_compile(compile_parameter, parameters_obj)) subscenarios = [ self._compile_parameterized(obj, arguments, parameter) for parameter in parameters ] return Scenario(label=label, subscenarios=subscenarios) ordered_obj = inject_arguments(obj.get(_KEY_ORDERED, True), arguments) with on_key(_KEY_ORDERED): ordered = ensure_bool(ordered_obj) default_obj = inject_arguments(obj.get(_KEY_DEFAULT, {}), arguments) with on_key(_KEY_DEFAULT): case_compiler = self._case.compile_default(default_obj) condition_obj = inject_arguments(obj.get(_KEY_WHEN, []), arguments) with on_key(_KEY_WHEN): conditions = self._compile_conditions(condition_obj) case_obj = inject_arguments(obj.get(_KEY_CASES, []), arguments) with on_key(_KEY_CASES): cases = self._compile_cases(case_compiler, case_obj) subscenario_obj = obj.get(_KEY_SUBSCENARIOS, []) with on_key(_KEY_SUBSCENARIOS): subscenarios = self._compile_subscenarios( case_compiler, subscenario_obj, arguments, ) return Scenario( label=label, ordered=ordered, conditions=conditions, cases=cases, subscenarios=subscenarios, )
def _compile_cases(case_compiler: CaseCompiler, obj: object) -> List[Case]: return list(map_compile(case_compiler.compile_fixed, ensure_list(obj)))
def _compile_conditions(self, obj: object): return list(map_compile(self._description.compile, ensure_list(obj)))
return list(map_compile(self._description.compile, ensure_list(obj))) @staticmethod def _compile_cases(case_compiler: CaseCompiler, obj: object) -> List[Case]: return list(map_compile(case_compiler.compile_fixed, ensure_list(obj))) def _compile_subscenarios( self, case: CaseCompiler, obj: object, arguments: Arguments, ) -> List[Scenario]: compiler = ScenarioCompiler(description=self._description, case=case) return list( map_compile( lambda sub_obj: compiler.compile(sub_obj, arguments=arguments), ensure_list(obj), )) def _compile_parameterized( self, obj: Mapping, arguments: Arguments, parameter: Parameter, ) -> Scenario: template = { k: v for (k, v) in obj.items() if k not in (_KEY_LABEL, _KEY_PARAMETERS) } template["label"] = parameter.label arguments = dict(arguments)