| Index: update-copyright/tests/test_update_copyright.py |
| =================================================================== |
| new file mode 100644 |
| --- /dev/null |
| +++ b/update-copyright/tests/test_update_copyright.py |
| @@ -0,0 +1,118 @@ |
| +#!/usr/bin/env python3 |
| + |
| +import os |
| +import re |
| +import datetime |
| +import subprocess |
| +import pytest |
|
Vasily Kuznetsov
2017/06/19 16:25:30
PEP8 suggests that the order of imports should be
rosie
2017/06/23 14:39:24
Done.
|
| +import urllib.parse |
| + |
| +from update_copyright.update_copyright import extract_urls |
|
Vasily Kuznetsov
2017/06/19 16:25:30
According to PEP8, it would be ok to put all impor
rosie
2017/06/23 14:39:21
Done.
|
| +from update_copyright.update_copyright import text_replace |
| +from update_copyright.update_copyright import hg_commit |
| +from update_copyright.update_copyright import main |
| + |
| +CURRENT_YEAR = datetime.datetime.now().year |
| +local_dir = os.path.dirname(os.path.abspath(__file__)) |
|
Vasily Kuznetsov
2017/06/19 16:25:30
This is the path to the directory that contains th
rosie
2017/06/23 14:39:21
Done.
rosie
2017/06/23 14:39:21
Good idea. I would change it, but this variable en
|
| +data_dir = os.path.join(local_dir, 'data') |
|
Vasily Kuznetsov
2017/06/19 16:25:29
Then this would be `data_path`.
rosie
2017/06/23 14:39:21
Done.
|
| +full_data_dir = urllib.parse.urljoin('file://localhost', data_dir) |
|
Vasily Kuznetsov
2017/06/19 16:25:30
This one is a URL of the data directory, so we can
rosie
2017/06/23 14:39:24
Done.
|
| +hg_page = os.path.join(full_data_dir, 'hg_page.html') |
|
Vasily Kuznetsov
2017/06/19 16:25:29
This one would be `hg_page_url` then.
rosie
2017/06/23 14:39:23
Ended up not needing this variable either
rosie
2017/06/23 14:39:23
Done.
|
| +url_list = [os.path.join(full_data_dir + '/repo_1/'), |
| + os.path.join(full_data_dir + '/repo_2/')] |
|
Jon Sonesen
2017/06/13 16:30:20
I don't think all these constants are required, su
rosie
2017/06/23 14:39:22
Done.
|
| + |
| + |
| +@pytest.fixture() |
| +def temp_repo(tmpdir): |
| + # Returns a temporary repo containing one sample file |
|
Vasily Kuznetsov
2017/06/19 16:25:29
This should be a docstring. Normally docstrings de
rosie
2017/06/23 14:39:24
Done.
|
| + temp_dir = tmpdir.mkdir('tmp_dir') |
| + temp_repo = str(temp_dir) |
| + subprocess.check_call(['hg', 'init', temp_repo]) |
| + subprocess.check_call(['cp', os.path.join(data_dir, 'sample_file.py'), |
|
Vasily Kuznetsov
2017/06/19 16:25:30
It's better (faster) to use `shutil.copy` (see htt
rosie
2017/06/23 14:39:23
Done.
|
| + temp_repo]) |
| + subprocess.check_call(['hg', 'add', os.path.join(temp_repo, |
|
Vasily Kuznetsov
2017/06/19 16:25:30
You can combine this with the next call of `hg` by
rosie
2017/06/23 14:39:22
Done.
|
| + 'sample_file.py'), '--repository', temp_repo]) |
| + subprocess.check_call(['hg', 'commit', '-m', 'Initial commit', |
| + '--repository', temp_repo]) |
| + return temp_repo |
| + |
| + |
| +@pytest.fixture() |
| +def base_dir(tmpdir): |
|
Vasily Kuznetsov
2017/06/19 16:25:29
As we've discussed, it would be better to refactor
rosie
2017/06/23 14:39:23
Done.
|
| + # Returns a temporary directory that contains one html page and two |
|
Vasily Kuznetsov
2017/06/19 16:25:30
This should also be a docstring.
rosie
2017/06/23 14:39:24
Done.
|
| + # repositories (one with push access, the other without) |
| + tmp_repo = tmpdir.mkdir('tmp_dir') |
| + temp_dir = str(tmp_repo) |
| + subprocess.check_call(['cp', os.path.join(data_dir, 'hg_page.html'), |
| + temp_dir]) |
| + repo_1 = temp_dir + '/repo_1' |
| + repo_2 = temp_dir + '/repo_2' |
| + subprocess.check_call(['mkdir', repo_1]) |
| + subprocess.check_call(['mkdir', repo_2]) |
|
Jon Sonesen
2017/06/13 16:30:19
you can avoid the use of temporary variables here
rosie
2017/06/23 14:39:24
Setting up the temporary directory base_dir like t
|
| + subprocess.check_call(['cp', os.path.join(data_dir, 'sample_file.py'), |
| + repo_1]) |
| + subprocess.check_call(['cp', os.path.join(data_dir, 'sample_file.py'), |
| + repo_2]) |
| + subprocess.check_call(['hg', 'init', repo_1]) |
| + subprocess.check_call(['hg', 'init', repo_2]) |
| + subprocess.check_call(['hg', 'commit', '-Am', '"Initial commit"', |
| + '--repository', repo_1]) |
| + subprocess.check_call(['hg', 'commit', '-Am', '"Initial commit"', |
| + '--repository', repo_2]) |
| + |
| + # Make repo_2 read-only |
| + subprocess.check_call(['touch', os.path.join(repo_2, '.hg/hgrc')]) |
| + with open(os.path.join(repo_2, '.hg/hgrc'), 'w') as hgrc: |
| + hook = '[hooks]\npretxnchangegroup = return True' |
| + hgrc.write(hook) |
| + return str(temp_dir) |
|
Jon Sonesen
2017/06/13 16:30:20
returning the actual path object may be preferable
rosie
2017/06/23 14:39:22
Done.
|
| + |
| + |
| +def test_extract_urls(): |
| + assert url_list == extract_urls(hg_page) |
|
Jon Sonesen
2017/06/13 16:30:19
here is where you would just hand code the url lis
rosie
2017/06/23 14:39:22
Done.
|
| + |
| + |
| +def test_text_replacement(temp_repo): |
| + filename = os.path.join(temp_repo, 'sample_file.py') |
| + text_replace(temp_repo, filename) |
|
Jon Sonesen
2017/06/13 16:30:19
Have you tested that this is working? it seems tha
rosie
2017/06/23 14:39:23
In the temp_repo fixture, 'sample_file.py' is copi
|
| + with open(filename) as file: |
| + try: |
| + text = file.read() |
| + except UnicodeDecodeError: |
|
Vasily Kuznetsov
2017/06/19 16:25:30
I think you shouldn't catch this. The test should
rosie
2017/06/23 14:39:22
Done.
|
| + print("Error: Couldn't read {}{}".format(temp_repo, filename)) |
| + return |
| + pattern = re.compile(r'(copyright.*?\d{4})(?:-\d{4})?\s+eyeo gmbh', |
| + re.I) |
| + for year in re.finditer(pattern, text): |
| + dates = re.search(r'(\d{4})-(\d{4})', year.group(0)) |
| + assert dates.group(2) == str(CURRENT_YEAR) |
| + |
| + |
| +def test_hg_commit(temp_repo): |
| + subprocess.check_call(['hg', 'clone', temp_repo, 'temp']) |
| + subprocess.check_call(['touch', 'temp/foo']) |
|
Jon Sonesen
2017/06/13 16:30:19
you will want to use path.join for the temp/foo he
Vasily Kuznetsov
2017/06/19 16:25:30
And it's probably better to use something like `op
rosie
2017/06/23 14:39:23
Done.
|
| + subprocess.check_call(['hg', 'add', '--repository', 'temp']) |
| + hg_commit('temp', temp_repo) |
| + |
| + # Make sure both files contain the commmit message from hg log |
| + log_1 = subprocess.run(['hg', 'log', '--repository', temp_repo], |
| + stdout=subprocess.PIPE) |
| + assert 'Noissue - Updated copyright year' in str(log_1.stdout) |
| + subprocess.call(['rm', '-r', 'temp/']) # cleanup |
|
Vasily Kuznetsov
2017/06/19 16:25:30
It would be better to use `shutil.rmtree` instead.
rosie
2017/06/23 14:39:22
Done.
|
| + |
| + |
| +def test_all(base_dir): |
| + main(urllib.parse.urljoin('file://localhost', os.path.join( |
| + base_dir, 'hg_page.html')), base_dir) |
|
Jon Sonesen
2017/06/13 16:30:20
localhost isnt needed here, it is causing the test
rosie
2017/06/23 14:39:21
Looks like I should have used 'file:///' instead o
rosie
2017/06/23 14:39:24
Done.
|
| + |
| + # assert hg log for repo_1 |
| + log_1 = subprocess.run(['hg', 'log', '--repository', |
| + os.path.join(base_dir, 'repo_1')], |
| + stdout=subprocess.PIPE) |
| + assert 'Noissue - Updated copyright year' in str(log_1.stdout) |
| + |
| + # assert the .patch file for repo_2 |
| + with open(os.path.join(data_dir, 'tst.patch'), 'r') as file1: |
| + with open('repo_2.patch') as file2: |
| + same = set(file1).intersection(file2) |
|
Vasily Kuznetsov
2017/06/19 16:25:29
This seems unnecessarily complicated. Perhaps you
rosie
2017/06/23 14:39:21
Done.
|
| + assert 'Noissue - Updated copyright year\n' in same |
| + subprocess.call(['rm', 'repo_2.patch']) |