Exemplo n.º 1
0
def test_rename(testdb, fs, mocker):
    m = mocker.patch('memini.core.database.rename_table')
    fs.create_file(template.path('table1'))
    commands.rename('table1', 'table3')
    assert os.path.exists(template.path('table3'))
    assert not os.path.exists(template.path('table1'))
    m.assert_called_with('table1', 'table3')
Exemplo n.º 2
0
def test_edit(fs, mocker):
    m = mocker.patch('memini.core.template.edit')
    fs.create_file(template.path('tpl1'))
    assert os.path.isfile(template.path('tpl1'))
    commands.edit('tpl1')
    m.assert_called_with('tpl1')
    with pytest.raises(NotFoundError) as excinfo:
        commands.edit('tpl2.odt')
    assert str(excinfo.value) == 'Cannot find any template "tpl2.odt".'
Exemplo n.º 3
0
def test_rename_to_existing_template(testdb, fs):
    fs.create_file(template.path('table1'))
    fs.create_file(template.path('table3'))

    with pytest.raises(DestinationExistsError) as excinfo:
        commands.rename('table1', 'table3')
    assert str(excinfo.value) == 'Action cancelled: a template named '\
        '"table3" already exists. Please rename or remove it before using '\
        'this name.'
Exemplo n.º 4
0
def test_duplicate(testdb, fs, capsys):
    fs.create_file(template.path('table1'))
    commands.duplicate('table1', 'table3')
    assert os.path.exists(template.path('table1'))
    assert os.path.exists(template.path('table3'))
    assert database.table_exists('table1')
    assert database.table_exists('table3')
    commands.show('table1')
    table1_content = capsys.readouterr().out
    commands.show('table3')
    table3_content = capsys.readouterr().out
    assert table1_content == table3_content
Exemplo n.º 5
0
def test_rename_missing_template(testdb, fs, mocker):
    # No template for source table: automatic creation
    def create_fake_template(*args):
        fs.create_file(template.path('table1'))

    m = mocker.patch('memini.core.template.create',
                     side_effect=create_fake_template)
    commands.rename('table1', 'table4')
    m.assert_called_with('table1')
    assert os.path.exists(template.path('table4'))
    assert not os.path.exists(template.path('table1'))
    assert database.table_exists('table4')
    assert not database.table_exists('table1')
Exemplo n.º 6
0
def generate(table_name,
             nb=DEFAULT_Q_NB,
             scheme=None,
             oldest_prevail=False,
             output=None,
             force=False,
             tpl=None,
             edit_after=True,
             use_previous=False):
    """
    Generate a new document using n data from the table and the matching
    template.
    """
    if use_previous:
        sw_data = sweepstakes.load_sweepstake(int(table_name))
        table_name, rows = sw_data[0], sw_data[1:]
        table_name = table_name[0]
        if len(rows[0]) != len(database.get_cols(table_name)):
            raise ColumnsDoNotMatchError(
                len(database.get_cols(table_name)), len(rows[0]), table_name,
                database.get_cols(table_name),
                sweepstakes._get_sweepstake_name(use_previous))
    if tpl is None:
        tpl_name = table_name
    else:
        if not os.path.isfile(template.path(tpl)):
            raise NotFoundError(f'Cannot find template file: {tpl}')
        tpl_name = tpl
    if output is None:
        output = f'{table_name}.{TEMPLATE_EXT}'
    if os.path.exists(output) and not force:
        overwrite = terminal.ask_yes_no(f'Output file {output} already '
                                        f'exists, overwrite it?')
        if not overwrite:
            raise CommandCancelledError('generate')
    if not use_previous:
        rows = database.draw_rows(table_name,
                                  nb,
                                  oldest_prevail=oldest_prevail)
    data = _process_data(rows, scheme=scheme)
    template.sanitize(template.path(tpl_name))
    basic = Template(source='', filepath=template.path(tpl_name))
    basic_generated = basic.generate(o=data).render()
    with open(output, 'wb') as f:
        f.write(basic_generated.getvalue())
    if edit_after:
        edit(output)
Exemplo n.º 7
0
def test_delete(fs, mocker, testdb):
    fs.create_file(template.path('table1'))
    m = mocker.patch('memini.core.terminal.ask_yes_no')

    # User cancels the deletions
    m.side_effect = [False, False]
    commands.delete('table1')
    m.assert_has_calls([call('Delete table "table1"?'),
                        call('Delete template "table1"?')])
    assert os.path.exists(template.path('table1'))
    assert database.table_exists('table1')

    # User confirms the deletions
    m.side_effect = [True, True]
    commands.delete('table1')
    assert not os.path.exists(template.path('table1'))
    assert not database.table_exists('table1')
Exemplo n.º 8
0
def test_list_(testdb, capsys, fs, sw):
    fs.create_file(template.path('template1'))
    fs.create_file(template.path('template2'))
    commands.list_('tables')
    captured = capsys.readouterr()
    assert captured.out == 'table1\ntable2\n'
    commands.list_('templates')
    captured = capsys.readouterr()
    assert captured.out == 'template1.odt\ntemplate2.odt\n'
    for s in sw:
        fs.create_file(s)
    commands.list_('sweepstakes')
    captured = capsys.readouterr()
    assert captured.out == \
        '1_2020-07-02@15:13:22.json\n'\
        '2_2020-07-02@15:13:23.json\n'\
        '3_2020-07-02@15:13:24.json\n'
    with pytest.raises(CommandError) as excinfo:
        commands.list_('foo')
    assert str(excinfo.value) == 'Sorry, I can only list "tables", '\
        '"templates" or "sweepstakes". Please use one of these three '\
        'keywords. I will not try to list "foo".'
Exemplo n.º 9
0
def test_create_already_existing_table_or_template(testdb, capsys, fs):
    fs.create_file('some_source.txt')

    with pytest.raises(DestinationExistsError) as excinfo:
        commands.create('table1', 'some_source.txt', '<Latin>:<Français>')
    assert str(excinfo.value) == 'Action cancelled: a table named '\
        '"table1" already exists. Please rename or remove it '\
        'before using this name.'

    fs.create_file(template.path('already_in_use'))
    with pytest.raises(DestinationExistsError) as excinfo:
        commands.create('already_in_use', 'some_source.txt',
                        '<Latin>:<Français>')
    assert str(excinfo.value) == 'Action cancelled: a template named '\
        '"already_in_use" already exists. Please rename or remove it '\
        'before using this name.'
Exemplo n.º 10
0
def test_merge_errors(mocker, testdb, fs, capsys):
    with pytest.raises(MergeError) as excinfo:
        commands.merge([], 'table5')
    assert str(excinfo.value) == 'At least one table must be provided as '\
        'source.'
    with pytest.raises(MergeError) as excinfo:
        commands.merge(['table1', 'table2', 'table3', 'table4', 'table5'],
                       'table6')
    assert str(excinfo.value) == 'One or more tables cannot be found: '\
        'table3, table4, table5'
    with pytest.raises(MergeError) as excinfo:
        commands.merge(['table1', 'table2'], 'table3')
    assert str(excinfo.value) == 'All tables used as sources must have the '\
        'same number of columns. Found [2, 3] instead.'

    f1 = os.path.join(TESTS_DATADIR, 'latin_add.txt')
    fs.add_real_file(f1)

    # No template for source table: automatic creation
    def create_fake_template3(*args):
        fs.create_file(template.path('table3'))

    mocker.patch('memini.core.template.create',
                 side_effect=create_fake_template3)
    commands.create('table3', f1, '<Latin>:<Français>')
    with pytest.raises(MergeError) as excinfo:
        commands.merge(['table1', 'table3'], 'table2')
    assert str(excinfo.value) == 'Number of columns mismatch: destination '\
        'table table2 has 3 columns, while source table(s) have 2 columns.'

    # Solitary template (no matching table)
    fs.create_file(template.path('table4'))
    with pytest.raises(MergeError) as excinfo:
        commands.merge(['table1', 'table3'], 'table4')
    assert str(excinfo.value) == 'Action cancelled: a template matching '\
        '"table4" already exists, but not the matching table. Please rename '\
        'or remove it before using this name.'
Exemplo n.º 11
0
def test_edit(mocker):
    mock_popen = mocker.patch('subprocess.Popen')
    template.edit('table1')
    mock_popen.assert_called_with([prefs.EDITOR, template.path('table1')])
Exemplo n.º 12
0
def test_list_(fs):
    fs.create_file(template.path('table1'))
    fs.create_file(template.path('table2'))
    assert template.list_() == ['table1.odt', 'table2.odt']
Exemplo n.º 13
0
def test_path():
    expected = os.path.join(USER_TEMPLATES_PATH, f'NAME.{TEMPLATE_EXT}')
    assert template.path('NAME') == expected
Exemplo n.º 14
0
 def create_fake_template(*args):
     fs.create_file(template.path('table1'))
Exemplo n.º 15
0
def test_merge(mocker, testdb, fs, capsys):
    f1 = os.path.join(TESTS_DATADIR, 'latin_add.txt')
    f2 = os.path.join(TESTS_DATADIR, 'latin.txt')
    fs.add_real_file(f1)
    fs.add_real_file(f2)

    # No template for source table: automatic creation
    def create_fake_template3(*args):
        fs.create_file(template.path('table3'))

    # No template for source table: automatic creation
    def create_fake_template4(*args):
        fs.create_file(template.path('table4'))

    # No template for source table: automatic creation
    def create_fake_template5(*args):
        fs.create_file(template.path('table5'))

    mocker.patch('memini.core.template.create',
                 side_effect=create_fake_template3)
    commands.create('table3', f1, '<Latin>:<Français>')

    mocker.patch('memini.core.template.create',
                 side_effect=create_fake_template5)
    commands.create('table5', f2, '<Latin>:<Français>')

    mocker.patch('memini.core.template.create',
                 side_effect=create_fake_template4)
    commands.merge(['table1', 'table3'], 'table4')

    commands.show('table4')
    captured = capsys.readouterr()
    assert captured.out == \
        ' id |         col1        |                col2                \n'\
        '----+---------------------+------------------------------------\n'\
        '  1 |  adventus,  us, m.  |               arrivée              \n'\
        '  2 |     aqua , ae, f    |                 eau                \n'\
        '  3 |   candidus,  a, um  |                blanc               \n'\
        '  4 |    sol, solis, m    |               soleil               \n'\
        '  5 |  judex,  dicis, m.  |                juge                \n'\
        '  6 |   judicium,  i, n.  |         jugement, décision         \n'\
        '  7 |     jus, uris, n    |                droit               \n'\
        '  8 |   justitia, ae, f.  |           justice (vertu)          \n'\
        '  9 |   juvenis, is , m   |      homme jeune (30 à45 ans)      \n'\
        ' 10 | juventus,  utis, f. |              jeunesse              \n'\
        ' 11 |   labor,  oris, m.  | peine, souffrance, travail pénible \n'\
        ' 12 |   lacrima,  ae, f.  |                larme               \n'\
        ' 13 |   laetitia, ae, f.  |               la joie              \n'

    os.remove(template.path('table5'))
    mocker.patch('memini.core.template.create',
                 side_effect=create_fake_template5)
    commands.merge(['table1'], 'table5')
    commands.show('table5')
    captured = capsys.readouterr()
    assert captured.out == \
        ' id |         Latin        |       Français      \n'\
        '----+----------------------+---------------------\n'\
        '  1 |    actio, onis, f.   | procès , plaidoirie \n'\
        '  2 | admiratio,  onis, f. |      admiration     \n'\
        '  3 |   adventus,  us, m.  |       arrivée       \n'\
        '  4 |   aedilis,  is, m.   |        édile        \n'\
        '  5 |  aetas, atis, f âge  |         vie         \n'\
        '  6 |   ambitio, onis, f.  |       ambition      \n'\
        '  7 |    ambitus, us, m.   |      la brigue      \n'\
        '  8 |   amicitia,  ae, f.  |        amitié       \n'\
        '  9 |    amicus,  i, m.    |         ami         \n'\
        ' 10 |    amor,  oris, m.   |        amour        \n'\
        ' 11 |    anima,  ae, f.    |      coeur, âme     \n'\
        ' 12 |   adventus,  us, m.  |       arrivée       \n'\
        ' 13 |     aqua , ae, f     |         eau         \n'\
        ' 14 |   candidus,  a, um   |        blanc        \n'\
        ' 15 |     sol, solis, m    |        soleil       \n'