You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

572 lines
21 KiB

# -*- coding: utf-8 -*-
from __future__ import print_function, unicode_literals
import unittest
import re
import os
import dotdot
import fake_env
from pubs import pubs_cmd, update, color, content, filebroker, uis, p3, endecoder
from pubs.config import conf
import configobj
import str_fixtures
import fixtures
from pubs.commands import init_cmd, import_cmd
11 years ago
# makes the tests very noisy
PRINT_OUTPUT=False
11 years ago
CAPTURE_OUTPUT=True
# code for fake fs
class TestFakeInput(unittest.TestCase):
def test_input(self):
input = fake_env.FakeInput(['yes', 'no'])
self.assertEqual(input(), 'yes')
self.assertEqual(input(), 'no')
with self.assertRaises(fake_env.FakeInput.UnexpectedInput):
input()
def test_input2(self):
other_input = fake_env.FakeInput(['yes', 'no'], module_list=[color])
other_input.as_global()
self.assertEqual(color.input(), 'yes')
self.assertEqual(color.input(), 'no')
with self.assertRaises(fake_env.FakeInput.UnexpectedInput):
color.input()
def test_editor_input(self):
other_input = fake_env.FakeInput(['yes', 'no'],
module_list=[content, color])
other_input.as_global()
self.assertEqual(content.editor_input(), 'yes')
self.assertEqual(content.editor_input(), 'no')
with self.assertRaises(fake_env.FakeInput.UnexpectedInput):
color.input()
class CommandTestCase(unittest.TestCase):
"""Abstract TestCase intializing the fake filesystem."""
maxDiff = 1000000
def setUp(self):
self.fs = fake_env.create_fake_fs([content, filebroker, conf, init_cmd, import_cmd, configobj, update])
self.default_pubs_dir = self.fs['os'].path.expanduser('~/.pubs')
9 years ago
self.default_conf_path = self.fs['os'].path.expanduser('~/.pubsrc')
def execute_cmds(self, cmds, capture_output=CAPTURE_OUTPUT):
""" Execute a list of commands, and capture their output
A command can be a string, or a tuple of size 2, 3 or 4.
In the latter case, the command is :
1. a string reprensenting the command to execute
2. the user inputs to feed to the command during execution
3. the expected output on stdout, verified with assertEqual.
4. the expected output on stderr, verified with assertEqual.
"""
outs = []
for cmd in cmds:
inputs = []
expected_out, expected_err = None, None
actual_cmd = cmd
if not isinstance(cmd, p3.ustr):
actual_cmd = cmd[0]
if len(cmd) == 2: # Inputs provided
inputs = cmd[1]
if len(cmd) == 3: # Expected output provided
capture_output = True
expected_out = color.undye(cmd[2])
if len(cmd) == 4: # Expected error output provided
expected_err = color.undye(cmd[3])
# Always set fake input: test should not ask unexpected user input
input = fake_env.FakeInput(inputs, [content, uis, p3])
input.as_global()
try:
if capture_output:
_, stdout, stderr = fake_env.redirect(pubs_cmd.execute)(
actual_cmd.split())
actual_out = color.undye(stdout)
actual_err = color.undye(stderr)
if expected_out is not None:
self.assertEqual(actual_out, expected_out)
if expected_err is not None:
self.assertEqual(actual_err, expected_err)
outs.append(color.undye(actual_out))
else:
pubs_cmd.execute(actual_cmd.split())
except fake_env.FakeInput.UnexpectedInput:
self.fail('Unexpected input asked by command: {}.'.format(
actual_cmd))
if PRINT_OUTPUT:
11 years ago
print(outs)
return outs
def tearDown(self):
fake_env.unset_fake_fs([content, filebroker, conf, init_cmd, import_cmd, configobj])
class DataCommandTestCase(CommandTestCase):
"""Abstract TestCase intializing the fake filesystem and
copying fake data.
"""
def setUp(self):
super(DataCommandTestCase, self).setUp()
fake_env.copy_dir(self.fs, os.path.join(os.path.dirname(__file__), 'data'), 'data')
fake_env.copy_dir(self.fs, os.path.join(os.path.dirname(__file__), 'bibexamples'), 'bibexamples')
# Actual tests
class TestInit(CommandTestCase):
def test_init(self):
pubsdir = os.path.expanduser('~/pubs_test2')
self.execute_cmds(['pubs init -p {}'.format(pubsdir)])
self.assertEqual(set(self.fs['os'].listdir(pubsdir)),
11 years ago
{'bib', 'doc', 'meta', 'notes'})
def test_init2(self):
pubsdir = os.path.expanduser('~/.pubs')
self.execute_cmds(['pubs init'])
self.assertEqual(set(self.fs['os'].listdir(pubsdir)),
11 years ago
{'bib', 'doc', 'meta', 'notes'})
class TestAdd(DataCommandTestCase):
def test_add(self):
cmds = ['pubs init',
'pubs add /data/pagerank.bib -d /data/pagerank.pdf',
]
self.execute_cmds(cmds)
bib_dir = self.fs['os'].path.join(self.default_pubs_dir, 'bib')
meta_dir = self.fs['os'].path.join(self.default_pubs_dir, 'meta')
doc_dir = self.fs['os'].path.join(self.default_pubs_dir, 'doc')
self.assertEqual(set(self.fs['os'].listdir(bib_dir)), {'Page99.bib'})
self.assertEqual(set(self.fs['os'].listdir(meta_dir)), {'Page99.yaml'})
self.assertEqual(set(self.fs['os'].listdir(doc_dir)), {'Page99.pdf'})
def test_add2(self):
cmds = ['pubs init -p /not_default',
'pubs add /data/pagerank.bib -d /data/pagerank.pdf',
]
self.execute_cmds(cmds)
self.assertEqual(set(self.fs['os'].listdir('/not_default/doc')), {'Page99.pdf'})
def test_add_citekey(self):
cmds = ['pubs init',
'pubs add -k CustomCitekey /data/pagerank.bib',
]
self.execute_cmds(cmds)
bib_dir = self.fs['os'].path.join(self.default_pubs_dir, 'bib')
self.assertEqual(set(self.fs['os'].listdir(bib_dir)), {'CustomCitekey.bib'})
def test_add_utf8_citekey(self):
err = ("error: Invalid `hausdorff1949grundzüge` citekey; "
"utf-8 citekeys are not supported yet.\n"
"See https://github.com/pubs/pubs/issues/28 for details.") # actually not checked
cmds = ['pubs init',
('pubs add /bibexamples/utf8.bib', [], '', err),
]
with self.assertRaises(SystemExit):
self.execute_cmds(cmds)
def test_add_doc_nocopy_does_not_copy(self):
cmds = ['pubs init',
'pubs add /data/pagerank.bib --link -d /data/pagerank.pdf',
]
self.execute_cmds(cmds)
self.assertEqual(self.fs['os'].listdir(
self.fs['os'].path.join(self.default_pubs_dir, 'doc')),
[])
def test_add_move_removes_doc(self):
cmds = ['pubs init',
'pubs add /data/pagerank.bib --move -d /data/pagerank.pdf',
]
self.execute_cmds(cmds)
self.assertFalse(self.fs['os'].path.exists('/data/pagerank.pdf'))
def test_add_twice_fails(self):
cmds = ['pubs init',
'pubs add /data/pagerank.bib',
'pubs add -k Page99 /data/turing1950.bib',
]
with self.assertRaises(SystemExit):
self.execute_cmds(cmds)
@unittest.expectedFailure
def test_leading_citekey_space(self):
cmds = ['pubs init',
'pubs add /data/leadingspace.bib',
'pubs rename LeadingSpace NoLeadingSpace',
]
self.execute_cmds(cmds)
class TestList(DataCommandTestCase):
12 years ago
def test_list(self):
cmds = ['pubs init -p /not_default2',
'pubs list',
'pubs add /data/pagerank.bib -d /data/pagerank.pdf',
'pubs list',
]
outs = self.execute_cmds(cmds)
self.assertEqual(0, len(outs[1].splitlines()))
self.assertEqual(1, len(outs[3].splitlines()))
def test_list_several_no_date(self):
self.execute_cmds(['pubs init -p /testrepo'])
self.fs['shutil'].rmtree('testrepo')
testrepo = os.path.join(os.path.dirname(__file__), 'testrepo')
fake_env.copy_dir(self.fs, testrepo, 'testrepo')
cmds = ['pubs list',
'pubs remove -f Page99',
'pubs list',
'pubs add /data/pagerank.bib -d /data/pagerank.pdf',
'pubs list',
]
outs = self.execute_cmds(cmds)
self.assertEqual(4, len(outs[0].splitlines()))
self.assertEqual(3, len(outs[2].splitlines()))
self.assertEqual(4, len(outs[4].splitlines()))
# Last added should be last
self.assertEqual('[Page99]', outs[4].splitlines()[-1][:8])
def test_list_smart_case(self):
cmds = ['pubs init',
'pubs list',
'pubs import data/',
'pubs list title:language author:Saunders',
]
outs = self.execute_cmds(cmds)
self.assertEqual(1, len(outs[-1].splitlines()))
def test_list_ignore_case(self):
cmds = ['pubs init',
'pubs list',
'pubs import data/',
'pubs list --ignore-case title:lAnguAge author:saunders',
]
outs = self.execute_cmds(cmds)
self.assertEqual(1, len(outs[-1].splitlines()))
def test_list_force_case(self):
cmds = ['pubs init',
'pubs list',
'pubs import data/',
'pubs list --force-case title:Language author:saunders',
]
outs = self.execute_cmds(cmds)
self.assertEqual(0 + 1, len(outs[-1].split('\n')))
class TestTag(DataCommandTestCase):
def setUp(self):
super(TestTag, self).setUp()
init = ['pubs init',
'pubs add data/pagerank.bib',
'pubs add -k Turing1950 data/turing1950.bib',
]
self.execute_cmds(init)
def test_add_tag(self):
cmds = ['pubs tag Page99 search',
'pubs tag Turing1950 ai',
'pubs list',
]
correct = ['',
'',
'[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) | search\n' +
'[Turing1950] Turing, Alan M "Computing machinery and intelligence" Mind (1950) | ai\n',
]
out = self.execute_cmds(cmds)
self.assertEqual(out, correct)
def test_add_tags(self):
"""Adds several tags at once.
Also checks that tags printed in alphabetic order.
"""
cmds = ['pubs tag Page99 search+network',
'pubs list',
]
correct = ['',
'[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) | network,search\n' +
'[Turing1950] Turing, Alan M "Computing machinery and intelligence" Mind (1950) \n',
]
out = self.execute_cmds(cmds)
self.assertEqual(out, correct)
def test_remove_tag(self):
cmds = ['pubs tag Page99 search+network',
'pubs tag Page99 :network',
'pubs list',
]
correct = ['',
'',
'[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) | search\n' +
'[Turing1950] Turing, Alan M "Computing machinery and intelligence" Mind (1950) \n',
]
out = self.execute_cmds(cmds)
self.assertEqual(out, correct)
def test_add_remove_tag(self):
cmds = ['pubs tag Page99 a',
'pubs tag Page99 b-a',
'pubs list',
]
correct = ['',
'',
'[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) | b\n' +
'[Turing1950] Turing, Alan M "Computing machinery and intelligence" Mind (1950) \n',
]
out = self.execute_cmds(cmds)
self.assertEqual(out, correct)
def test_wrong_citekey(self):
cmds = ['pubs tag Page999 a',
]
with self.assertRaises(SystemExit):
self.execute_cmds(cmds)
class TestUsecase(DataCommandTestCase):
def test_first(self):
correct = ['Initializing pubs in /paper_first\n',
'added to pubs:\n[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) \n'
'data/pagerank.pdf was copied to the pubs repository.\n',
'[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) \n',
'\n',
'',
'network search\n',
'[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) | network,search\n',
]
cmds = ['pubs init -p paper_first/',
'pubs add -d data/pagerank.pdf data/pagerank.bib',
'pubs list',
'pubs tag',
'pubs tag Page99 network+search',
'pubs tag Page99',
'pubs tag search',
]
self.assertEqual(correct, self.execute_cmds(cmds, capture_output=True))
def test_second(self):
cmds = ['pubs init -p paper_second/',
'pubs add data/pagerank.bib',
'pubs add -d data/turing-mind-1950.pdf data/turing1950.bib',
'pubs add data/martius.bib',
'pubs add data/10.1371%2Fjournal.pone.0038236.bib',
'pubs list',
'pubs doc add data/pagerank.pdf Page99'
]
self.execute_cmds(cmds)
def test_third(self):
cmds = ['pubs init',
'pubs add data/pagerank.bib',
'pubs add -d data/turing-mind-1950.pdf data/turing1950.bib',
'pubs add data/martius.bib',
'pubs add data/10.1371%2Fjournal.pone.0038236.bib',
'pubs list',
'pubs doc add data/pagerank.pdf Page99',
('pubs remove Page99', ['y']),
'pubs remove -f turing1950computing',
]
self.execute_cmds(cmds)
docdir = self.fs['os'].path.expanduser('~/.pubs/doc/')
self.assertNotIn('turing-mind-1950.pdf', self.fs['os'].listdir(docdir))
def test_tag_list(self):
correct = ['Initializing pubs in /paper_first\n',
'',
'',
'',
'search network\n',
]
cmds = ['pubs init -p paper_first/',
'pubs add -d data/pagerank.pdf data/pagerank.bib',
'pubs tag',
'pubs tag Page99 network+search',
'pubs tag',
]
out = self.execute_cmds(cmds)
def clean(s):
return set(s.strip().split(' '))
self.assertEqual(clean(correct[2]), clean(out[2]))
self.assertEqual(clean(correct[4]), clean(out[4]))
def test_editor_abort(self):
12 years ago
with self.assertRaises(SystemExit):
cmds = ['pubs init',
('pubs add', ['abc', 'n']),
('pubs add', ['abc', 'y', 'abc', 'n']),
'pubs add data/pagerank.bib',
('pubs edit Page99', ['', 'a']),
12 years ago
]
self.execute_cmds(cmds)
12 years ago
def test_editor_success(self):
cmds = ['pubs init',
('pubs add', [str_fixtures.bibtex_external0]),
('pubs remove Page99', ['y']),
]
self.execute_cmds(cmds)
def test_edit(self):
bib = str_fixtures.bibtex_external0
bib1 = re.sub('year = \{1999\}', 'year = {2007}', bib)
bib2 = re.sub('Lawrence Page', 'Lawrence Ridge', bib1)
bib3 = re.sub('Page99', 'Ridge07', bib2)
line = '[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) \n'
line1 = re.sub('1999', '2007', line)
line2 = re.sub('Page,', 'Ridge,', line1)
line3 = re.sub('Page99', 'Ridge07', line2)
cmds = ['pubs init',
'pubs add data/pagerank.bib',
('pubs list', [], line),
('pubs edit Page99', [bib1]),
('pubs list', [], line1),
('pubs edit Page99', [bib2]),
('pubs list', [], line2),
('pubs edit Page99', [bib3]),
('pubs list', [], line3),
]
self.execute_cmds(cmds)
def test_export(self):
cmds = ['pubs init',
('pubs add', [str_fixtures.bibtex_external0]),
'pubs export Page99',
]
outs = self.execute_cmds(cmds)
self.assertEqual(endecoder.EnDecoder().decode_bibdata(outs[2]),
fixtures.page_bibentry)
def test_import(self):
cmds = ['pubs init',
'pubs import data/',
'pubs list'
]
outs = self.execute_cmds(cmds)
self.assertEqual(4 + 1, len(outs[-1].split('\n')))
def test_import_one(self):
cmds = ['pubs init',
'pubs import data/ Page99',
'pubs list'
]
outs = self.execute_cmds(cmds)
self.assertEqual(1 + 1, len(outs[-1].split('\n')))
def test_update(self):
cmds = ['pubs init',
'pubs add data/pagerank.bib',
'pubs update'
]
with self.assertRaises(SystemExit):
self.execute_cmds(cmds)
def test_add_with_tag(self):
cmds = ['pubs init',
'pubs add data/pagerank.bib --tags junk',
'pubs tag junk'
]
outs = self.execute_cmds(cmds)
self.assertEqual(1, len(outs[2].splitlines()))
def test_doc_open(self):
cmds = ['pubs init',
'pubs add data/pagerank.bib',
'pubs doc open Page99'
]
with self.assertRaises(SystemExit):
self.execute_cmds(cmds)
with self.assertRaises(SystemExit):
cmds[-1] == 'pubs doc open Page8'
self.execute_cmds(cmds)
def test_doc_add(self):
cmds = ['pubs init',
'pubs add data/pagerank.bib',
'pubs doc add data/pagerank.pdf Page99'
]
self.execute_cmds(cmds)
self.assertTrue(self.fs['os'].path.exists(
self.fs['os'].path.join(self.default_pubs_dir,
'doc',
'Page99.pdf')))
# Also test that do not remove original
self.assertTrue(self.fs['os'].path.exists('/data/pagerank.pdf'))
def test_doc_add_with_move(self):
cmds = ['pubs init -p paper_second/',
'pubs add data/pagerank.bib',
'pubs doc add --move data/pagerank.pdf Page99'
]
self.execute_cmds(cmds)
9 years ago
self.assertTrue(self.fs['os'].path.isfile(self.default_conf_path))
self.assertFalse(self.fs['os'].path.exists('/data/pagerank.pdf'))
def test_doc_remove(self):
cmds = ['pubs init',
'pubs add data/pagerank.bib',
'pubs doc add data/pagerank.pdf Page99',
('pubs doc remove Page99', ['y']),
]
self.execute_cmds(cmds)
docdir = self.fs['os'].path.expanduser('~/.pubs/doc/')
self.assertNotIn('turing-mind-1950.pdf', self.fs['os'].listdir(docdir))
def test_doc_export(self):
cmds = ['pubs init',
'pubs add data/pagerank.bib',
'pubs rename Page99 page100',
'pubs doc add data/pagerank.pdf page100',
'pubs doc export page100 /'
]
self.execute_cmds(cmds)
self.assertIn('page100.pdf', self.fs['os'].listdir('/'))
9 years ago
def test_alternate_config(self):
alt_conf = self.fs['os'].path.expanduser('~/.alt_conf')
cmds = ['pubs -c ' + alt_conf + ' init',
'pubs --config ' + alt_conf + ' import data/ Page99',
'pubs list -c ' + alt_conf
]
outs = self.execute_cmds(cmds)
# check if pubs works as expected
self.assertEqual(1 + 1, len(outs[-1].split('\n')))
# check whether we actually changed the config file
self.assertFalse(self.fs['os'].path.isfile(self.default_conf_path))
self.assertTrue(self.fs['os'].path.isfile(alt_conf))
if __name__ == '__main__':
unittest.main()