File: test_cli.py

package info (click to toggle)
metalfinder 2.1.6-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid, trixie
  • size: 248 kB
  • sloc: python: 805; sh: 8; makefile: 7
file content (179 lines) | stat: -rw-r--r-- 6,381 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/python3

"""Test the functions in metalfinder.cli"""

import logging
import os

from unittest import mock
from datetime import date, timedelta
from pathlib import Path

import pytest

from metalfinder.cli import output_choices, date_lint, dir_lint, parse_args
from metalfinder import __version__


def test_output_choices_ok(outdir):
    """Test output_choices() when path is valid"""
    choices = { 'text': str(outdir) + '/test.txt',
                'json': str(outdir) + '/test.json',
                'atom': str(outdir) + '/test.atom' }
    for _, value in choices.items():
        assert output_choices(value) == value


def test_output_choices_invalid_extension():
    """Test output_choices() errors when file extension is invalid"""
    with pytest.raises(SystemExit):
        assert output_choices('foo.notvalid')


def test_output_choices_invalid_path():
    """Test output_choices() errors when path is invalid"""
    with pytest.raises(SystemExit):
        assert output_choices('/asdkaskdm/kmasdkmD/foo.txt')


# date_lint()
def test_date_lint_ok():
    """Test date_lint() for valid ISO 8601 input"""
    assert date_lint('2100-01-01') == '2100-01-01'


def test_date_lint_not_iso_8601():
    """Test date_lint() errors when input is not ISO 8601"""
    with pytest.raises(SystemExit):
        date_lint('2100/01/01')


def test_date_lint_maxdate_too_early():
    """Test date_lint() errors when max_date earlier than today"""
    with pytest.raises(SystemExit):
        yesterday = date.today() - timedelta(days = 1)
        date_lint(str(yesterday))


def test_dir_not_path():
    """Test dir_lint() errors when dir is not a valid"""
    with pytest.raises(SystemExit):
        dir_lint('')


# parse_args()
def test_parser_no_dir(cachedir):
    """Test argparse without --directory"""
    args = parse_args(['-o', 'foo.txt', '-l', 'Montreal', '-b', 'FooBar',
                       '-c', str(cachedir)])
    assert args.directory is None
    assert args.output == 'foo.txt'
    assert args.location == 'Montreal'
    assert args.bit_appid == 'FooBar'
    assert args.cache_dir == str(cachedir)


def test_parser_no_output(cachedir, outdir):
    """Test argparse without --output"""
    with pytest.raises(SystemExit):
        _args = parse_args(['-d', str(outdir), '-l', 'Montreal', '-b', 'FooBar',
                            '-c', str(cachedir)])


def test_parser_no_location(cachedir, outdir):
    """Test argparse without --location"""
    with pytest.raises(SystemExit):
        _args = parse_args(['-d', str(outdir), '-l', 'Montreal', '-b', 'FooBar',
                            '-c', str(cachedir)])


@mock.patch.dict(os.environ, {'METALFINDER_BIT_APPID': 'FooBar'})
def test_parser_api_with_env(cachedir, outdir):
    """Test argparse with --bit_appid and METALFINDER_BIT_APPID"""
    args = parse_args(['-d', str(outdir), '-o', 'foo.txt', '-l', 'Montreal',
                       '-b', 'NonDefault', '-c', str(cachedir)])
    assert args.directory == str(outdir)
    assert args.output == 'foo.txt'
    assert args.location == 'Montreal'
    assert args.bit_appid == 'NonDefault'
    assert args.cache_dir == str(cachedir)


def test_parser_api_no_env(cachedir, outdir):
    """Test argparse with --bit_appid, without METALFINDER_BIT_APPID"""
    args = parse_args(['-d', str(outdir), '-o', 'foo.txt', '-l', 'Montreal',
                       '-b', 'FooBar', '-c', str(cachedir)])
    assert args.directory == str(outdir)
    assert args.output == 'foo.txt'
    assert args.location == 'Montreal'
    assert args.bit_appid == 'FooBar'
    assert args.cache_dir == str(cachedir)


@mock.patch.dict(os.environ, {'METALFINDER_BIT_APPID': 'FooBar'})
def test_parser_no_api_with_env(cachedir, outdir):
    """Test argparse without --bit_appid, with METALFINDER_BIT_APPID"""
    args = parse_args(['-d', str(outdir), '-o', 'foo.txt', '-l', 'Montreal',
                       '-c', str(cachedir)])
    assert args.directory == str(outdir)
    assert args.output == 'foo.txt'
    assert args.location == 'Montreal'
    assert args.bit_appid == 'FooBar'
    assert args.cache_dir == str(cachedir)


def test_parser_no_api_no_env(cachedir, outdir):
    """Test argparse without --bit_appid and METALFINDER_BIT_APPID"""
    with pytest.raises(SystemExit):
        _args = parse_args(['-d', str(outdir), '-l', 'Montreal', '-b', 'FooBar',
                            '-c', str(cachedir)])


def test_parse_cache_default(cachedir, outdir, monkeypatch):
    """Test argparse with default cache"""
    def mockreturn():
        return cachedir
    monkeypatch.setattr(Path, "home", mockreturn)
    args = parse_args(['-d', str(outdir), '-o', 'foo.txt', '-l', 'Montreal',
                       '-b', 'FooBar'])
    assert args.directory == str(outdir)
    assert args.output == 'foo.txt'
    assert args.location == 'Montreal'
    assert args.bit_appid == 'FooBar'
    assert args.cache_dir == str(cachedir) + '/.cache/metalfinder'


def test_parser_cache_non_default(cachedir, outdir):
    """Test argparse with cli non-default cache"""
    args = parse_args(['-d', str(outdir), '-o', 'foo.txt', '-l', 'Montreal',
                       '-b', 'FooBar', '-c', str(cachedir)])
    assert args.directory == str(outdir)
    assert args.output == 'foo.txt'
    assert args.location == 'Montreal'
    assert args.bit_appid == 'FooBar'
    assert args.cache_dir == str(cachedir)


def test_parser_verbose_default(cachedir):
    """Test argpase with default log level"""
    _args = parse_args(['-o', 'foo.txt', '-l', 'Montreal', '-b', 'FooBar',
                        '-c', str(cachedir)])
    assert logging.getLogger().getEffectiveLevel() == logging.WARNING


def test_parser_verbose_debug(cachedir):
    """Test argpase with info log level"""
    _args = parse_args(['-o', 'foo.txt', '-l', 'Montreal', '-b', 'FooBar',
                        '-c', str(cachedir), '--verbose'])
    assert logging.root.getEffectiveLevel() == logging.INFO


# This test cannot be done using pytest.raises(Foo), as it will exit after
# catching the exception, thus not letting us test the captured stdout.
def test_parser_version(capsys):
    """Test argparse --version outputs the right version number"""
    try:
        _args = parse_args(['--version'])
    except SystemExit:
        out, _err = capsys.readouterr()
        assert out.rstrip() == "metalfinder " + __version__