def from_file(cls, file_): """ Construct a test class from a feature file. """ feature = TestFeature.from_file(file_) background = cls.make_background(feature.background) scenarios = [ cls.make_scenario(scenario, i + 1) for i, scenario in enumerate(feature.scenarios) ] before_feature, after_feature = \ CALLBACK_REGISTRY.before_after('feature') members = { 'feature': feature, 'background': background, 'before_feature': staticmethod(before_feature), 'after_feature': staticmethod(after_feature), } members.update({ scenario.__name__: scenario for scenario in scenarios }) class_name = identifier(feature.name) testclass = type(class_name, (cls,), members) testclass.feature.testclass = testclass return testclass
def from_file(cls, file_): """ Construct a test class from a feature file. """ feature = TestFeature.from_file(file_) background = cls.make_background(feature.background) scenarios = [ example for i, scenario in enumerate(feature.scenarios) for example in cls.make_examples(scenario, i + 1) ] before_feature, after_feature = \ CALLBACK_REGISTRY.before_after('feature') members = { 'feature': feature, 'background': background, 'before_feature': staticmethod(before_feature), 'after_feature': staticmethod(after_feature), } members.update({scenario.__name__: scenario for scenario in scenarios}) class_name = identifier(feature.name) testclass = type(class_name, (cls, ), members) testclass.feature.testclass = testclass return testclass
def make_function(source, context=None, source_file=None, name=None): """ Compile and evaluate given source to a function given the specified globals. Optionally set the file and name of the function. """ func = ast.parse(source) # Check that generated code is a function # pylint:disable=unidiomatic-typecheck if type(func) != type(FUNCTION_DEF_SAMPLE) \ or len(func.body) != 1 \ or type(func.body[0]) != type(FUNCTION_DEF_SAMPLE.body[0]): raise ValueError("source must be a function definition.") # pylint:enable=unidiomatic-typecheck # Set or record the function name if name is not None: func.body[0].name = name = identifier(name) else: name = func.body[0].name # TODO: What's a better default for file? if source_file is None: source_file = '<generated>' context = context or {} code = compile(func, source_file, 'exec') eval(code, context) # pylint:disable=eval-used return context[name]