Beispiel #1
0
    def test_not_functions(self):
        """Test make_function error conditions."""
        with self.assertRaises(ValueError):
            make_function('1+1')

        with self.assertRaises(ValueError):
            make_function('def one(): pass\ndef two(): pass')
    def test_not_functions(self):
        """Test make_function error conditions."""
        with self.assertRaises(ValueError):
            make_function('1+1')

        with self.assertRaises(ValueError):
            make_function('def one(): pass\ndef two(): pass')
Beispiel #3
0
    def make_steps(cls, step_container, steps, is_background, outline=None):
        """
        Construct either a scenario or a background calling the specified
        steps.

        The method will have debugging information corresponding to the lines
        in the feature file.
        """

        assert len(steps) > 0

        step_definitions = [cls.prepare_step(step) for step in steps]

        source = 'def run_steps(self):\n'
        if not is_background:
            source += '    self.background()\n'
        source += '\n'.join(
            '    func{i}(step{i}, *args{i}, **kwargs{i})'.format(i=i)
            for i in range(len(step_definitions)))
        source = ast.parse(source)

        # Set locations of the steps
        for step, step_call in zip(steps, source.body[0].body[1:]):
            for node in ast.walk(step_call):
                node.lineno = step.described_at.line

        # Supply all the step functions and arguments
        context = {
            k + str(i): v
            for i, definition in enumerate(step_definitions)
            for k, v in definition.items()
        }

        if is_background:
            func_name = 'background'
        else:
            func_name = step_container.name

        run_steps = make_function(
            source=source,
            context=context,
            source_file=step_container.described_at.file,
            name=func_name,
        )

        try:
            tags = step_container.tags
        except AttributeError:
            tags = ()

        for tag in tags:
            run_steps = attr(tag)(run_steps)

        if not is_background:
            run_steps = CALLBACK_REGISTRY.wrap('example', run_steps,
                                               step_container, outline, steps)

        return run_steps
Beispiel #4
0
    def make_steps(cls, step_container, steps,
                   is_background, outline=None):
        """
        Construct either a scenario or a background calling the specified
        steps.

        The method will have debugging information corresponding to the lines
        in the feature file.
        """

        assert len(steps) > 0

        step_definitions = [
            cls.prepare_step(step)
            for step in steps
        ]

        source = 'def run_steps(self):\n'
        if not is_background:
            source += '    self.background()\n'
        source += '\n'.join(
            '    func{i}(step{i}, *args{i}, **kwargs{i})'.format(i=i)
            for i in range(len(step_definitions))
        )
        source = ast.parse(source)

        # Set locations of the steps
        for step, step_call in zip(steps, source.body[0].body[1:]):
            for node in ast.walk(step_call):
                node.lineno = step.line

        # Supply all the step functions and arguments
        context = {
            k + str(i): v
            for i, definition in enumerate(step_definitions)
            for k, v in definition.items()
        }

        if is_background:
            func_name = 'background'
        else:
            func_name = step_container.name

        run_steps = make_function(
            source=source,
            context=context,
            source_file=step_container.filename,
            name=func_name,
        )

        if not is_background:
            run_steps = CALLBACK_REGISTRY.wrap('example', run_steps,
                                               step_container, outline, steps)

        return run_steps
Beispiel #5
0
    def make_background(cls, background):
        """
        Construct a method running the background steps.
        """

        if background is None:
            result = make_function('def background(self): pass')
        else:
            result = cls.make_steps(background,
                                    background.steps,
                                    is_background=True)

        return result
Beispiel #6
0
    def make_background(cls, background):
        """
        Construct a method running the background steps.
        """

        if background is None:
            result = make_function('def background(self): pass')
        else:
            result = cls.make_steps(background,
                                    background.steps,
                                    is_background=True)

        return result
Beispiel #7
0
    def make_examples(cls, scenario, index):
        """
        Construct methods for running all the examples of a scenario.

        index is the 1-based number of the scenario in the feature.
        """

        if scenario.outlines:
            for i, (outline, steps) in enumerate(scenario.evaluated, 1):
                # Create a function calling the real scenario example to show
                # the right location in the outline
                source = """
def run_example(self):
    outline(self)
                """
                source = ast.parse(source)

                # Set location of the call
                for node in ast.walk(source.body[0].body[0]):
                    node.lineno = outline.line

                context = {
                    'outline':
                    cls.make_steps(scenario,
                                   steps,
                                   is_background=False,
                                   outline=outline)
                }

                yield cls.make_example(
                    make_function(
                        source=source,
                        context=context,
                        source_file=scenario.feature.filename,
                        name='{}: Example {}'.format(scenario.name, i),
                    ),
                    scenario,
                    index,
                )
        else:
            yield cls.make_example(
                cls.make_steps(
                    scenario,
                    scenario.steps,
                    is_background=False,
                ),
                scenario,
                index,
            )
Beispiel #8
0
    def test_functions(self):
        """Test generating functions."""
        def inner(val):
            """A function to pass to the generated one."""
            return 2 * val

        adder = make_function(
            'def add(x, y): return inner(x) + y',
            context={
                'inner': inner,
            },
            name='adder',
        )
        self.assertEqual(adder(10, 3), 23)
        self.assertEqual(adder.__name__, 'adder')
    def test_functions(self):
        """Test generating functions."""
        def inner(val):
            """A function to pass to the generated one."""
            return 2 * val

        adder = make_function(
            'def add(x, y): return inner(x) + y',
            context={
                'inner': inner,
            },
            name='adder',
        )
        self.assertEqual(adder(10, 3), 23)
        self.assertEqual(adder.__name__, 'adder')
Beispiel #10
0
    def make_examples(cls, scenario, index):
        """
        Construct methods for running all the examples of a scenario.

        index is the 1-based number of the scenario in the feature.
        """

        if scenario.outlines:
            for i, (outline, steps) in enumerate(scenario.evaluated, 1):
                # Create a function calling the real scenario example to show
                # the right location in the outline
                source = """
def run_example(self):
    outline(self)
                """
                source = ast.parse(source)

                # Set location of the call
                for node in ast.walk(source.body[0].body[0]):
                    node.lineno = outline.line

                context = {
                    'outline': cls.make_steps(scenario,
                                              steps,
                                              is_background=False,
                                              outline=outline)
                }

                yield cls.make_example(
                    make_function(
                        source=source,
                        context=context,
                        source_file=scenario.feature.filename,
                        name='{}: Example {}'.format(scenario.name, i),
                    ),
                    scenario,
                    index,
                )
        else:
            yield cls.make_example(
                cls.make_steps(
                    scenario,
                    scenario.steps,
                    is_background=False,
                ),
                scenario,
                index,
            )
Beispiel #11
0
    def make_scenario(cls, scenario, index):
        """
        Construct a method running the scenario steps.

        index is the 1-based number of the scenario in the feature.
        """

        if scenario.outlines:
            source = 'def run_outlines(self):\n' + '\n'.join(
                '    outline{i}(self)'.format(i=i)
                for i in range(len(scenario.outlines))
            )
            source = ast.parse(source)

            # Set locations of the steps
            for outline, outline_call in \
                    zip(scenario.outlines, source.body[0].body):
                for node in ast.walk(outline_call):
                    node.lineno = outline.line

            context = {
                'outline' + str(i): cls.make_steps(scenario,
                                                   steps,
                                                   is_background=False,
                                                   outline=outline)
                for i, (outline, steps) in enumerate(scenario.evaluated)
            }

            result = make_function(
                source=source,
                context=context,
                source_file=scenario.feature.filename,
                name=scenario.name,
            )
        else:
            result = cls.make_steps(scenario,
                                    scenario.steps,
                                    is_background=False)

        result.is_scenario = True
        result.scenario = scenario
        result.scenario_index = index

        for tag in scenario.tags:
            result = attr(tag)(result)

        return result
Beispiel #12
0
    def make_scenario(cls, scenario, index):
        """
        Construct a method running the scenario steps.

        index is the 1-based number of the scenario in the feature.
        """

        if scenario.outlines:
            source = 'def run_outlines(self):\n' + '\n'.join(
                '    outline{i}(self)'.format(i=i)
                for i in range(len(scenario.outlines))
            )

            context = {
                'outline' + str(i): cls.make_steps(scenario,
                                                   steps,
                                                   is_background=False,
                                                   outline=outline)
                for i, (outline, steps) in enumerate(scenario.evaluated)
            }

            # TODO: Line numbers of the outline lines aren't preserved, because
            # the Outline tokens don't store the information
            result = make_function(
                source=source,
                context=context,
                source_file=scenario.feature.described_at.file,
                name=scenario.name,
            )
        else:
            result = cls.make_steps(scenario,
                                    scenario.steps,
                                    is_background=False)

        result.is_scenario = True
        result.scenario_index = index

        return result
Beispiel #13
0
    def make_scenario(cls, scenario, index):
        """
        Construct a method running the scenario steps.

        index is the 1-based number of the scenario in the feature.
        """

        if scenario.outlines:
            source = 'def run_outlines(self):\n' + '\n'.join(
                '    outline{i}(self)'.format(i=i)
                for i in range(len(scenario.outlines)))

            context = {
                'outline' + str(i): cls.make_steps(scenario,
                                                   steps,
                                                   is_background=False,
                                                   outline=outline)
                for i, (outline, steps) in enumerate(scenario.evaluated)
            }

            # TODO: Line numbers of the outline lines aren't preserved, because
            # the Outline tokens don't store the information
            result = make_function(
                source=source,
                context=context,
                source_file=scenario.feature.described_at.file,
                name=scenario.name,
            )
        else:
            result = cls.make_steps(scenario,
                                    scenario.steps,
                                    is_background=False)

        result.is_scenario = True
        result.scenario_index = index

        return result
Beispiel #14
0
    def make_steps(cls, step_container, steps, is_background, outline=None):
        """
        Construct either a scenario or a background calling the specified
        steps.

        The method will have debugging information corresponding to the lines
        in the feature file.
        """

        assert steps

        step_definitions = [cls.prepare_step(step) for step in steps]

        source = 'def run_steps(self):\n'
        if not is_background:
            source += '    self.background()\n'
        source += '\n'.join(
            # This has to be a single statement, in order to set its source
            # location as a whole below
            """
    try:
        step{i}.test = self
        func{i}(step{i}, *args{i}, **kwargs{i})
    finally:
        step{i}.test = None
            """.format(i=i) for i in range(len(step_definitions)))
        source = ast.parse(source)

        # Set locations of the steps
        step_source = source.body[0].body
        if not is_background:
            # There is no source for the background() call
            step_source = step_source[1:]
        for step, step_call in zip(steps, step_source):
            for node in ast.walk(step_call):
                node.lineno = step.line

        # Supply all the step functions and arguments
        context = {
            k + str(i): v
            for i, definition in enumerate(step_definitions)
            for k, v in definition.items()
        }

        if is_background:
            func_name = 'background'
        else:
            func_name = step_container.name

        run_steps = make_function(
            source=source,
            context=context,
            source_file=step_container.filename,
            name=func_name,
        )

        if not is_background:
            run_steps = CALLBACK_REGISTRY.wrap('example', run_steps,
                                               step_container, outline, steps)

        return run_steps
Beispiel #15
0
    def make_examples(cls, scenario, index):
        """
        Construct methods for running all the examples of a scenario.

        index is the 1-based number of the scenario in the feature.
        """

        if scenario.outlines:
            outline_example = []
            for i, (outline, steps) in enumerate(scenario.evaluated, 1):
                # Create a function calling the real scenario example to show
                # the right location in the outline
                source = """
def run_example(self):
    outline(self)
                """
                source = ast.parse(source)

                # Set location of the call
                for node in ast.walk(source.body[0].body[0]):
                    node.lineno = outline.line

                context = {
                    'outline':
                    cls.make_steps(scenario,
                                   steps,
                                   is_background=False,
                                   is_outline=True,
                                   outline=outline)
                }

                outline_example.append(
                    cls.make_example(
                        make_function(
                            source=source,
                            context=context,
                            source_file=scenario.feature.filename,
                            name='{}: Example {}'.format(scenario.name, i),
                        ),
                        scenario,
                        index,
                    ))
            source = """
def run_example(self):
    for outline  in outlines:
      outline(self)
                    """
            context = {'outlines': outline_example}

            yield (cls.make_example(
                CALLBACK_REGISTRY.wrap(
                    'example',
                    make_function(
                        source=source,
                        context=context,
                        source_file=scenario.feature.filename,
                        name='{}: Example {}'.format(scenario.name, index),
                    ), scenario, None, scenario.steps),
                scenario,
                index,
            ))
        if scenario.keyword == 'Scenario Outline':
            pass
        elif scenario.outline_header is None:
            yield cls.make_example(
                cls.make_steps(
                    scenario,
                    scenario.steps,
                    is_background=False,
                ),
                scenario,
                index,
            )