예제 #1
0
파일: workflow.py 프로젝트: tdoric/snippet
def _set_config(config: Config) -> None:
    # validate and set IO directories that are relative to project root
    config.input_glob = [
        str(Path(config.project_root).joinpath(str(pattern)).absolute())
        for pattern in ensure_list(config.input_glob)
    ]
    config.output_dir = str(
        Path(config.project_root).joinpath(config.output_dir).absolute())
예제 #2
0
 def test_drop_lines(self):
     config = Config()
     config.drop_lines = ['# ignore me']
     self.go_exact(config, [
         start, 'test', newline, A,
         '# ignore me, this comment is unhelpful\n', B, C, stop,
         'other stuff'
     ])
예제 #3
0
    def test_wrap_raises(self):
        def x():
            raise NotImplementedError()

        config = Config()
        config.stop_on_first_failure = True
        f = []
        with self.assertRaises(NotImplementedError):
            wrap(config, f, None, x)
예제 #4
0
    def test_wrap_wraps(self):
        def x():
            raise NotImplementedError()

        config = Config()
        config.stop_on_first_failure = False
        f = []
        default = object()  # value to return on failure
        result = wrap(config, f, None, x, default)

        self.assertIs(result, default)
        self.assertEqual(len(f), 1)
        self.assertIsNone(f[0][0])
        self.assertIn("Traceback", f[0][1])
예제 #5
0
 def test_dedent_code(self):
     with self.assertRaises(exceptions.ValidationFailure):
         sequence = [
             f'  {x}' for x in [start + 'test' + newline, A, B, C, stop]
         ]
         sequence[-2] = sequence[-2].lstrip()
         self.go_exact(Config(), sequence)
예제 #6
0
 def test_indent_with_blank_line(self):
     # left pad the sequence and then have some blank lines
     sequence = [
         f'    {x}' for x in [start + 'test' + newline, A, B, C, stop]
     ]
     sequence.insert(2, '')
     self.go_exact(Config(), sequence)
예제 #7
0
 def test_multiple(self):
     sequence = [
         "some other stuff",
         start,
         "test 1 ",
         newline,
         A,
         cloak,
         "something to hide?",
         uncloak,
         B,
         C,
         stop,
         "other stuff",
         "more other stuff",
         start,
         " test 2  ",
         newline,
         A,
         B,
         C,
         stop,
         "more stuff",
     ]
     for i, parsed in enumerate(self.go(Config(), sequence)):
         with self.subTest(attempt=i):
             self.assertEqual(sample_output, parsed)
예제 #8
0
    def test_with_empty_lines(self):
        self.assertEqual(
            self.go(
                Config(),
                f"""
            {start}

            // Listening to device state changes for 2 minutes.
            Thread.sleep(120000);

            // Stopping the Wobble.
            wibbler.stop();

            {stop}
        """,
            ),
            [
                "".join(
                    [
                        "\n",
                        "// Listening to device state changes for 2 minutes.\n",
                        "Thread.sleep(120000);\n",
                        "\n",
                        "// Stopping the Wobble.\n",
                        "wibbler.stop();\n",
                    ]
                )
            ],
        )
예제 #9
0
def run(config: Config):
    examples = {}
    failures = []

    # validate and set IO directories that are relative to project root
    config.input_glob = [
        os.path.abspath(os.path.join(config.project_root, pattern)) for pattern in ensure_list(config.input_glob)
    ]
    config.output_dir = os.path.abspath(os.path.join(config.project_root, config.output_dir))

    paths = file_wrangler.find_files(config)
    logger.debug('files to parse:\n%s', textwrap.indent('\n'.join(paths), prefix='  '))

    for path in paths:
        # load the file
        lines = wrap(config, failures, path, partial(
            file_wrangler.load_file_lines, path
        ), [])

        # extract snippets
        new_examples = wrap(config, failures, path, partial(
            extract_snippets, config, lines, path
        ), {})

        # store the new examples for analysis
        examples.update(new_examples)

    unique_example_names = dict()
    for (path, line_num, example_name), code_lines in examples.items():
        existing = unique_example_names.get(example_name)
        if existing:
            raise exceptions.DuplicateName('Example with duplicate name %s %s matches %s' % (path, line_num, existing))
        else:
            unique_example_names[example_name] = (path, line_num, example_name)

    for (path, line_num, example_name), code_lines in examples.items():
        example_block = '\n'.join(code_lines)
        logger.info('example: %r', example_name)
        logger.debug('example code: %s', example_block)

        wrap(config, failures, path, partial(
            file_wrangler.write_example, config, example_name, example_block
        ))

    return examples, paths, failures
예제 #10
0
 def test_multiple(self):
     sequence = [
         'some other stuff', start, 'test 1 ', newline, A, cloak,
         'something to hide?', uncloak, B, C, stop, 'other stuff',
         'more other stuff', start, ' test 2  ', newline, A, B, C, stop,
         'more stuff'
     ]
     for i, parsed in enumerate(self.go(Config(), sequence)):
         with self.subTest(attempt=i):
             self.assertEqual(sample_output, parsed)
예제 #11
0
    def test_wrap_passthrough(self):
        counter = {"a": 0}

        def x():
            counter["a"] += 1
            return counter

        f = []
        result = wrap(Config(), f, None, x)

        self.assertEqual(result, counter)
        self.assertEqual(counter["a"], 1)
        self.assertEqual(f, [])
예제 #12
0
    def test_read(self):
        with open(self.tmp_fp, "w", encoding="utf8") as fh:
            fh.write(self.text)

        config = Config()
        config.stop_on_first_failure = True
        config.input_glob = self.tmp_fp
        config.output_dir = self.tmpdir.name

        examples, paths, failures = workflow.run(config)

        with self.subTest(part="found the file"):
            self.assertEqual([self.tmp_fp], paths)

        with self.subTest(part="no failures"):
            self.assertEqual([], failures)

        with self.subTest(part="one example extracted"):
            self.assertEqual(len(examples), self.expect_examples)

        for k, v in examples.items():
            with self.subTest(part="example matches"):
                self.assertEqual("\n".join(v), P.sample_output)
                self.assertIn(self.example_name, k[-1])
예제 #13
0
 def test_cloak(self):
     self.go_exact(
         Config(),
         [
             "some other stuff\n",
             start,
             "test",
             newline,
             A,
             cloak,
             "ignore this stuff\n",
             uncloak,
             B,
             C,
             stop,
             "other stuff",
         ],
     )
예제 #14
0
 def test_trigger_phrase(self):
     with self.assertRaises(exceptions.ValidationFailure):
         self.go_exact(Config(), [start, "test", newline, A, B, C, "assert\n", stop])
예제 #15
0
 def test_indent_tabs(self):
     # left pad the sequence by two tabs, to check result is dedented to depth of start
     sequence = [f"\t\t{x}" for x in [start + "test" + newline, A, B, C]]
     sequence.append(stop)
     self.go_exact(Config(), sequence)
예제 #16
0
 def test_plain(self):
     self.go_exact(Config(), [start, "test", newline, A, B, C, stop])
예제 #17
0
 def test_replacements(self):
     config = Config()
     config.replacements = {'self.': ''}
     self.go_exact(config,
                   [start, 'test', newline, 'self.' + A, B, C, stop])
예제 #18
0
 def test_empty(self):
     self.assertEqual(self.go(Config(), [start, "test", newline, stop]), [])
예제 #19
0
 def test_replacements(self):
     config = Config()
     config.replacements = {"self.": ""}
     self.go_exact(config, [start, "test", newline, "self." + A, B, C, stop])
예제 #20
0
 def test_unstarted(self):
     with self.assertRaises(exceptions.StartEndMismatch):
         self.go_exact(Config(), [A, B, C, stop])
예제 #21
0
 def test_indent(self):
     # left pad the sequence by two spaces, to check result is dedented to depth of start
     sequence = [f'  {x}' for x in [start + 'test' + newline, A, B, C]]
     sequence.append(stop)
     self.go_exact(Config(), sequence)
예제 #22
0
 def test_cloak_unfinished(self):
     with self.assertRaises(exceptions.CloakMismatch):
         self.go_exact(Config(), ["some other stuff", start, "test", newline, A, cloak, B, C, stop, "other stuff"])
예제 #23
0
 def test_prefix(self):
     self.go_exact(Config(), ["some other stuff", start, "test", newline, A, B, C, stop, "other stuff"])
예제 #24
0
 def test_double_stop(self):
     with self.assertRaises(exceptions.StartEndMismatch):
         self.go_exact(Config(), [start, "test", newline, A, stop, B, C, stop])
예제 #25
0
 def test_prefix(self):
     self.go_exact(Config(), [
         'some other stuff', start, 'test', newline, A, B, C, stop,
         'other stuff'
     ])
예제 #26
0
 def test_cloak_unfinished(self):
     with self.assertRaises(exceptions.CloakMismatch):
         self.go_exact(Config(), [
             'some other stuff', start, 'test', newline, A, cloak, B, C,
             stop, 'other stuff'
         ])
예제 #27
0
 def test_drop_lines(self):
     config = Config()
     config.drop_lines = ["# ignore me"]
     self.go_exact(
         config, [start, "test", newline, A, "# ignore me, this comment is unhelpful\n", B, C, stop, "other stuff"]
     )
예제 #28
0
 def test_unfinished(self):
     with self.assertRaises(exceptions.StartEndMismatch):
         self.go_exact(Config(), [start, "test", newline, A, B, C])
예제 #29
0
 def test_cloak(self):
     self.go_exact(Config(), [
         'some other stuff\n', start, 'test', newline, A, cloak,
         'ignore this stuff\n', uncloak, B, C, stop, 'other stuff'
     ])