Пример #1
0
 def run_fts(self):
     if os.path.exists(
             os.path.join(self.tempdir, 'superlists', 'functional_tests')):
         return self.run_command(
             Command("python manage.py test functional_tests"))
     else:
         return self.run_command(Command("python functional_tests.py"))
Пример #2
0
    def run_interactive_manage_py(self, listing):
        output_before = self.listings[self.pos + 1]
        assert isinstance(output_before, Output)

        LIKELY_INPUTS = ('yes', 'no', '1', '2', "''")
        user_input = self.listings[self.pos + 2]
        if isinstance(user_input, Command) and user_input in LIKELY_INPUTS:
            if user_input == 'yes':
                print('yes case')
                # in this case there is moar output after the yes
                output_after = self.listings[self.pos + 3]
                assert isinstance(output_after, Output)
                expected_output = Output(wrap_long_lines(output_before + ' ' + output_after.lstrip()))
                next_output = None
            elif user_input == '1':
                print('migrations 1 case')
                # in this case there is another hop
                output_after = self.listings[self.pos + 3]
                assert isinstance(output_after, Output)
                first_input = user_input
                next_input = self.listings[self.pos + 4]
                assert isinstance(next_input, Command)
                next_output = self.listings[self.pos + 5]
                expected_output = Output(wrap_long_lines(
                    output_before + '\n' + output_after + '\n' + next_output
                ))
                user_input = Command(first_input + '\n' + next_input)
            else:
                expected_output = output_before
                output_after = None
                next_output = None
            if user_input == '2':
                ignore_errors = True
            else:
                ignore_errors = False

        else:
            user_input = None
            expected_output = output_before
            output_after = None
            ignore_errors = True
            next_output = None

        output = self.run_command(listing, user_input=user_input, ignore_errors=ignore_errors)
        self.assert_console_output_correct(output, expected_output)

        listing.was_checked = True
        output_before.was_checked = True
        self.pos += 2
        if user_input is not None:
            user_input.was_run = True
            self.pos += 1
        if output_after is not None:
            output_after.was_checked = True
            self.pos += 1
        if next_output is not None:
            self.pos += 2
            next_output.was_checked = True
            first_input.was_run = True
            next_input.was_run = True
Пример #3
0
 def run_unit_tests(self):
     if os.path.exists(
             os.path.join(self.tempdir, 'superlists', 'accounts', 'tests')):
         return self.run_command(
             Command("python manage.py test lists accounts"))
     else:
         return self.run_command(Command("python manage.py test lists"))
    def check_commit(self, pos):
        if self.listings[pos].endswith('commit -a'):
            self.listings[pos] = Command(self.listings[pos] +
                                         'm "commit for listing %d"' %
                                         (self.pos, ))
        elif self.listings[pos].endswith('commit'):
            self.listings[pos] = Command(self.listings[pos] +
                                         ' -am "commit for listing %d"' %
                                         (self.pos, ))

        commit = self.run_command(self.listings[pos])
        assert 'insertion' in commit or 'changed' in commit
        self.pos += 1
Пример #5
0
 def check_test_code_cycle(self, pos, test_command_in_listings=True, ft=False):
     self.write_to_file(self.listings[pos])
     self._strip_out_any_pycs()
     if test_command_in_listings:
         pos += 1
         self.assertIn('test', self.listings[pos])
         test_run = self.run_command(self.listings[pos])
     elif ft:
         test_run = self.run_command(Command("python functional_tests.py"))
     else:
         test_run = self.run_command(Command("python manage.py test lists"))
     pos += 1
     self.assert_console_output_correct(test_run, self.listings[pos])
    def check_final_diff(self, ignore=None, diff=None):
        if diff is None:
            diff = self.run_command(
                Command('git diff -w repo/{}'.format(self.chapter_name)))
        try:
            print('checking final diff', diff)
        except io.BlockingIOError:
            pass
        self.assertNotIn('fatal:', diff)
        start_marker = 'diff --git a/\n'
        commit = Commit.from_diff(start_marker + diff)

        if ignore is None:
            if commit.lines_to_add:
                self.fail('Found lines to add in diff:\n{}'.format(
                    commit.lines_to_add))
            if commit.lines_to_remove:
                self.fail('Found lines to remove in diff:\n{}'.format(
                    commit.lines_to_remove))
            return

        if "moves" in ignore:
            ignore.remove("moves")
            difference_lines = commit.deleted_lines + commit.new_lines
        else:
            difference_lines = commit.lines_to_add + commit.lines_to_remove

        for line in difference_lines:
            if any(ignorable in line for ignorable in ignore):
                continue
            self.fail('Found divergent line in diff:\n{}'.format(line))
Пример #7
0
    def check_final_diff(self, ignore=None, diff=None):
        if diff is None:
            diff = self.run_command(
                Command('git diff -w repo/chapter_{0:02d}'.format(
                    self.chapter_no)))
        try:
            print('checking final diff', diff)
        except io.BlockingIOError:
            pass
        self.assertNotIn('fatal:', diff)
        start_marker = 'diff --git a/\n'
        commit = Commit.from_diff(start_marker + diff)
        error = AssertionError(
            'Final diff was not empty, was:\n{}'.format(diff))

        if ignore is None:
            if commit.lines_to_add or commit.lines_to_remove:
                raise error
            return

        if "moves" in ignore:
            ignore.remove("moves")
            difference_lines = commit.deleted_lines + commit.new_lines
        else:
            difference_lines = commit.lines_to_add + commit.lines_to_remove

        for line in difference_lines:
            if any(ignorable in line for ignorable in ignore):
                continue
            raise error
Пример #8
0
    def check_final_diff(self,
                         chapter,
                         ignore_moves=False,
                         ignore_secret_key=False,
                         diff=None):
        if diff is None:
            diff = self.run_command(
                Command('git diff -b repo/chapter_{0:02d}'.format(chapter)))
        try:
            print('checking final diff', diff)
        except io.BlockingIOError:
            pass
        self.assertNotIn('fatal:', diff)
        start_marker = 'diff --git a/\n'
        commit = Commit.from_diff(start_marker + diff)
        error = AssertionError(
            'Final diff was not empty, was:\n{}'.format(diff))

        if ignore_secret_key:
            for line in commit.lines_to_add + commit.lines_to_remove:
                if 'SECRET_KEY' not in line:
                    raise error

        elif ignore_moves:
            if commit.deleted_lines or commit.new_lines:
                raise AssertionError(
                    'Found lines to delete or add in diff.\nto delete:\n{}\n\nto add:\n{}'
                    .format('\n- '.join(commit.deleted_lines),
                            '\n+'.join(commit.new_lines)))

        elif commit.lines_to_add or commit.lines_to_remove:
            raise error
 def test_calls_sourcetree_run_command_and_marks_as_run(self):
     self.sourcetree.run_command = Mock()
     cmd = Command('foo')
     output = self.run_command(cmd, cwd='bar', user_input='thing')
     assert output == self.sourcetree.run_command.return_value
     self.sourcetree.run_command.assert_called_with(
         'foo', cwd='bar', user_input='thing', ignore_errors=False,
     )
     assert cmd.was_run
    def replace_command_with_check(self, pos, old, new):
        listing = self.listings[pos]
        all_listings = '\n'.join(str(t) for t in enumerate(self.listings))
        error = f'Could not find {old} at pos {pos}: "{listing}". Listings were:\n{all_listings}'
        if old not in listing:
            raise Exception(error)
        assert type(listing) == Command

        new_listing = Command(listing.replace(old, new))
        for attr, val in vars(listing).items():
            setattr(new_listing, attr, val)
        self.listings[pos] = new_listing
 def apply_patch(self, codelisting):
     tf = tempfile.NamedTemporaryFile(delete=False)
     tf.write(codelisting.contents.encode('utf8'))
     tf.write('\n'.encode('utf8'))
     tf.close()
     print('patch:\n', codelisting.contents)
     patch_output = self.run_command(
         Command('patch --fuzz=3 --no-backup-if-mismatch %s %s' %
                 (codelisting.filename, tf.name)))
     print(patch_output)
     self.assertNotIn('malformed', patch_output)
     self.assertNotIn('failed', patch_output.lower())
     codelisting.was_checked = True
     with open(os.path.join(self.tempdir, codelisting.filename)) as f:
         print(f.read())
     os.remove(tf.name)
     self.pos += 1
     codelisting.was_written = True
 def restart_dev_server(self):
     print('restarting dev server')
     self.run_command(Command('pkill -f runserver'))
     time.sleep(1)
     self.start_dev_server()
     time.sleep(1)
 def start_dev_server(self):
     self.run_command(Command('python manage.py runserver'))
     self.dev_server_running = True
     time.sleep(1)
Пример #14
0
    def recognise_listing_and_process_it(self):
        listing = self.listings[self.pos]
        if listing.dofirst:
            print("DOFIRST", listing.dofirst)
            self.sourcetree.patch_from_commit(listing.dofirst, )
        if listing.skip:
            print("SKIP")
            listing.was_checked = True
            listing.was_written = True
            self.pos += 1
        elif listing.type == 'test':
            print("TEST RUN")
            self.run_test_and_check_result()
        elif listing.type == 'bdd test':
            print("BDD TEST RUN")
            self.run_test_and_check_result(bdd=True)
        elif listing.type == 'git diff':
            print("GIT DIFF")
            self.check_diff_or_status(self.pos)
        elif listing.type == 'git status':
            print("STATUS")
            self.check_diff_or_status(self.pos)
        elif listing.type == 'git commit':
            print("COMMIT")
            self.check_commit(self.pos)

        elif listing.type == 'interactive manage.py':
            print("INTERACTIVE MANAGE.PY")
            output_before = self.listings[self.pos + 1]
            assert isinstance(output_before, Output)

            LIKELY_INPUTS = ('yes', 'no', '1', '2', "''")
            user_input = self.listings[self.pos + 2]
            if isinstance(user_input, Command) and user_input in LIKELY_INPUTS:
                if user_input == 'yes':
                    print('yes case')
                    # in this case there is moar output after the yes
                    output_after = self.listings[self.pos + 3]
                    assert isinstance(output_after, Output)
                    expected_output = Output(
                        wrap_long_lines(output_before + ' ' +
                                        output_after.lstrip()))
                    next_output = None
                elif user_input == '1':
                    print('migrations 1 case')
                    # in this case there is another hop
                    output_after = self.listings[self.pos + 3]
                    assert isinstance(output_after, Output)
                    first_input = user_input
                    next_input = self.listings[self.pos + 4]
                    assert isinstance(next_input, Command)
                    next_output = self.listings[self.pos + 5]
                    expected_output = Output(
                        wrap_long_lines(output_before + '\n' + output_after +
                                        '\n' + next_output))
                    user_input = Command(first_input + '\n' + next_input)
                else:
                    expected_output = output_before
                    output_after = None
                    next_output = None
                if user_input == '2':
                    ignore_errors = True
                else:
                    ignore_errors = False

            else:
                user_input = None
                expected_output = output_before
                output_after = None
                ignore_errors = True
                next_output = None

            output = self.run_command(listing,
                                      user_input=user_input,
                                      ignore_errors=ignore_errors)
            self.assert_console_output_correct(output, expected_output)

            listing.was_checked = True
            output_before.was_checked = True
            self.pos += 2
            if user_input is not None:
                user_input.was_run = True
                self.pos += 1
            if output_after is not None:
                output_after.was_checked = True
                self.pos += 1
            if next_output is not None:
                self.pos += 2
                next_output.was_checked = True
                first_input.was_run = True
                next_input.was_run = True

        elif listing.type == 'tree':
            print("TREE")
            self.assert_directory_tree_correct(listing)
            self.pos += 1

        elif listing.type == 'server command':
            if DO_SERVER_COMMANDS:
                server_output = self.run_server_command(listing)
            listing.was_run = True
            self.pos += 1
            next_listing = self.listings[self.pos]
            if next_listing.type == 'output' and not next_listing.skip:
                if DO_SERVER_COMMANDS:
                    for line in next_listing.split('\n'):
                        assert line.strip() in server_output
                next_listing.was_checked = True
                self.pos += 1

        elif listing.type == 'other command':
            print("A COMMAND")
            output = self.run_command(listing)
            next_listing = self.listings[self.pos + 1]
            if next_listing.type == 'output' and not next_listing.skip:
                ls = listing.startswith('ls')
                self.assert_console_output_correct(output, next_listing, ls=ls)
                next_listing.was_checked = True
                listing.was_checked = True
                self.pos += 2
            elif 'tree' in listing and next_listing.type == 'tree':
                self.assert_console_output_correct(output, next_listing)
                next_listing.was_checked = True
                listing.was_checked = True
                self.pos += 2
            else:
                listing.was_checked = True
                self.pos += 1

        elif listing.type == 'diff':
            print("DIFF")
            self.apply_patch(listing)

        elif listing.type == 'code listing currentcontents':
            actual_contents = self.sourcetree.get_contents(listing.filename)
            self.check_current_contents(listing, actual_contents)
            self.pos += 1

        elif listing.type == 'code listing':
            print("CODE")
            self.write_to_file(listing)
            self.pos += 1

        elif listing.type == 'code listing with git ref':
            print("CODE FROM GIT REF")
            self.sourcetree.apply_listing_from_commit(listing)
            self.pos += 1

        elif listing.type == 'server code listing':
            print("SERVER CODE")
            self.write_file_on_server(listing.filename, listing.contents)
            listing.was_written = True
            self.pos += 1

        elif listing.type == 'qunit output':
            self.check_qunit_output(listing)
            self.pos += 1

        elif listing.type == 'output':
            self._strip_out_any_pycs()
            test_run = self.run_unit_tests()
            if 'OK' in test_run and 'OK' not in listing:
                print('unit tests pass, must be an FT:\n', test_run)
                test_run = self.run_fts()
            try:
                self.assert_console_output_correct(test_run, listing)
            except AssertionError as e:
                if 'OK' in test_run and 'OK' in listing:
                    print('got error when checking unit tests', e)
                    test_run = self.run_fts()
                    self.assert_console_output_correct(test_run, listing)
                else:
                    raise

            self.pos += 1

        else:
            self.fail('not implemented for ' + str(listing))
Пример #15
0
    def recognise_listing_and_process_it(self):
        listing = self.listings[self.pos]
        if listing.dofirst:
            print("DOFIRST", listing.dofirst)
            self.sourcetree.patch_from_commit(
                listing.dofirst,
            )
        if listing.skip:
            print("SKIP")
            listing.was_checked = True
            listing.was_written = True
            self.pos += 1
        elif listing.type == 'test':
            print("TEST RUN")
            self.run_test_and_check_result()
        elif listing.type == 'git diff':
            print("GIT DIFF")
            self.check_diff_or_status(self.pos)
        elif listing.type == 'git status':
            print("STATUS")
            self.check_diff_or_status(self.pos)
        elif listing.type == 'git commit':
            print("COMMIT")
            self.check_commit(self.pos)

        elif listing.type == 'interactive manage.py':
            print("INTERACTIVE MANAGE.PY")
            output_before = self.listings[self.pos + 1]
            assert isinstance(output_before, Output)

            LIKELY_INPUTS = ('yes', 'no', '1', '2', "''")
            user_input = self.listings[self.pos + 2]
            if isinstance(user_input, Command) and user_input in LIKELY_INPUTS:
                if user_input == 'yes':
                    print('yes case')
                    # in this case there is moar output after the yes
                    output_after = self.listings[self.pos + 3]
                    assert isinstance(output_after, Output)
                    expected_output = Output(wrap_long_lines(output_before + ' ' + output_after.lstrip()))
                    next_output = None
                elif user_input == '1':
                    print('migrations 1 case')
                    # in this case there is another hop
                    output_after = self.listings[self.pos + 3]
                    assert isinstance(output_after, Output)
                    first_input = user_input
                    next_input = self.listings[self.pos + 4]
                    assert isinstance(next_input, Command)
                    next_output = self.listings[self.pos + 5]
                    expected_output = Output(wrap_long_lines(
                        output_before + '\n' + output_after + '\n' + next_output
                    ))
                    user_input = Command(first_input + '\n' + next_input)
                else:
                    expected_output = output_before
                    output_after = None
                    next_output = None
                if user_input == '2':
                    ignore_errors = True
                else:
                    ignore_errors = False

            else:
                user_input = None
                expected_output = output_before
                output_after = None
                ignore_errors = True
                next_output = None

            output = self.run_command(listing, user_input=user_input, ignore_errors=ignore_errors)
            self.assert_console_output_correct(output, expected_output)

            listing.was_checked = True
            output_before.was_checked = True
            self.pos += 2
            if user_input is not None:
                user_input.was_run = True
                self.pos += 1
            if output_after is not None:
                output_after.was_checked = True
                self.pos += 1
            if next_output is not None:
                self.pos += 2
                next_output.was_checked = True
                first_input.was_run = True
                next_input.was_run = True



        elif listing.type == 'tree':
            print("TREE")
            self.assert_directory_tree_correct(listing)
            self.pos += 1

        elif listing.type == 'server command':
            server_output = self.run_server_command(listing)
            listing.was_run = True
            self.pos += 1
            next_listing = self.listings[self.pos]
            if next_listing.type == 'output' and not next_listing.skip:
                for line in next_listing.split('\n'):
                    assert line.strip() in server_output
                next_listing.was_checked = True
                self.pos += 1

        elif listing.type == 'other command':
            print("A COMMAND")
            output = self.run_command(listing)
            next_listing = self.listings[self.pos + 1]
            if next_listing.type == 'output' and not next_listing.skip:
                ls = listing.startswith('ls')
                self.assert_console_output_correct(output, next_listing, ls=ls)
                next_listing.was_checked = True
                listing.was_checked = True
                self.pos += 2
            elif 'tree' in listing and next_listing.type == 'tree':
                self.assert_console_output_correct(output, next_listing)
                next_listing.was_checked = True
                listing.was_checked = True
                self.pos += 2
            else:
                listing.was_checked = True
                self.pos += 1

        elif listing.type == 'diff':
            print("DIFF")
            self.apply_patch(listing)

        elif listing.type == 'code listing currentcontents':
            actual_contents = self.sourcetree.get_contents(
                listing.filename
            )
            print("CHECK CURRENT CONTENTS")
            stripped_actual_lines = [l.strip() for l in actual_contents.split('\n')]
            listing_contents = re.sub(r' +#$', '', listing.contents, flags=re.MULTILINE)
            for line in listing_contents.split('\n'):
                if line and not '[...]' in line:
                    self.assertIn(line.strip(), stripped_actual_lines)
            listing.was_written = True
            self.pos += 1

        elif listing.type == 'code listing':
            print("CODE")
            self.write_to_file(listing)
            self.pos += 1

        elif listing.type == 'code listing with git ref':
            print("CODE FROM GIT REF")
            self.sourcetree.apply_listing_from_commit(listing)
            self.pos += 1

        elif listing.type == 'server code listing':
            print("SERVER CODE")
            self.write_file_on_server(listing.filename, listing.contents)
            self.pos += 1

        elif listing.type == 'qunit output':
            self.check_qunit_output(listing)
            self.pos += 1

        elif listing.type == 'output':
            self._strip_out_any_pycs()
            test_run = self.run_unit_tests()
            if 'OK' in test_run and not 'OK' in listing:
                print('unit tests pass, must be an FT:\n', test_run)
                test_run = self.run_fts()
            try:
                self.assert_console_output_correct(test_run, listing)
            except AssertionError as e:
                if 'OK' in test_run and 'OK' in listing:
                    print('got error when checking unit tests', e)
                    test_run = self.run_fts()
                    self.assert_console_output_correct(test_run, listing)
                else:
                    raise

            self.pos += 1

        else:
            self.fail('not implemented for ' + str(listing))