def test_constraints_everything_match(): tc_check_constraints(ps(), 'CMD', { '-a': '1', '-b': rxc(r'ab+c'), '-c': lambda x: int(x) > 5, '-d': 'xyz' }, [('-c', '99'), ('-b', 'abbbc'), ('-e', 'not checked')])
def test_cmdline_example(): _test_cmdline(ps( '\n# a comment\nextract params.txt data/b.csv data/a.csv | sort -n | tail -n 3 > last.csv\n' ), [['extract', '', [rxc(r'p.+\.txt'), {'data/a.csv', 'data/b.csv'}]], ['sort', 'n'], ['tail', 'n:', [], { '-n': '3' }]], 'Use extract, sort, and tail with redirection.', redirect_out=re.compile(r'.+\.csv'), last_line_only=True)
def test_parse_cmdline_multiple_redirect(): with pytest.raises(TF): tc_parse_cmdline(ps('b > c > d'))
def test_chunk_args_and_filenames_match(): tc_check_chunk(ps(), [['a', 'b'], 'c:d', ['p', {'q', 'r'}, 's'], { '-c': 'NNN' }], 'a b -c NNN -d p r q s'.split())
def test_parse_cmdline_pipe_after_redirect(): with pytest.raises(TF): tc_parse_cmdline(ps('b > c | d'))
def test_files_nonempty_empty_fails(): with pytest.raises(TF): tc_check_files(ps(), 'CMD', ['whoops'], [])
def test_files_text_lengthy_match_succeeds(): tc_check_files(ps(), 'CMD', ['a', 'b'], ['a', 'b'])
def test_match_str_regex_match(): tc_match_str(ps(), rxc(r'ab+c'), 'abbbc', 'regex fails to match')
def test_match_str_equal_strings(): tc_match_str(ps(), 'abc', 'abc', 'equal strings fail to match')
def test_match_str_unequal_strings(): with pytest.raises(TF): tc_match_str(ps(), 'abc', 'def', 'unequal strings match')
def test_parse_cmdline_double_bare_commands(): assert tc_parse_cmdline(ps('a | b')) == ([['a'], ['b']], None)
def test_optional_present_still_too_short(): with pytest.raises(TF): assert tc_handle_optional(ps(), [['a'], Optional()], [['a'], ['b'], ['c']])
def test_parse_cmdline_single_bare_command(): assert tc_parse_cmdline(ps('a')) == ([['a']], None)
def test_optional_present_needed(): assert tc_handle_optional(ps(), [['a'], Optional()], [['a'], ['b']])
def test_optional_absent_needed(): with pytest.raises(TF): assert tc_handle_optional(ps(), [['a']], [['a'], ['b']])
def test_optional_absent_unneeded(): assert tc_handle_optional(ps(), [['a']], [['a']]) == ([['a']], [['a']])
def test_parse_cmdline_last_line_flag_not_set(): with pytest.raises(TF): assert tc_parse_cmdline(ps('a\nb'))
def test_match_str_regex_mismatch(): with pytest.raises(TF): tc_match_str(ps(), rxc(r'ab+c'), 'ac', 'regex matches incorrectly')
def test_parse_cmdline_last_line_flag_set(): assert tc_parse_cmdline(ps('a\nb'), last_line_only=True) == ([['b']], None)
def test_match_str_callable_mismatch(): with pytest.raises(TF): tc_match_str(ps(), lambda x: x > 0, -999, 'callable matches incorrectly')
def test_parse_cmdline_single_command_with_args(): assert tc_parse_cmdline(ps('a -b')) == ([['a', '-b']], None)
def test_chunk_args_and_filenames_filename_mismatch(): with pytest.raises(TF): tc_check_chunk(ps(), [['a', 'b'], 'c:d', ['p', 'q', 'r', 's'], { '-c': 'NNN' }], 'a b -c NNN -d p r q s'.split())
def test_match_str_callable_match(): tc_match_str(ps(), lambda x: x > 0, 123, 'callable fails to match')
def test_parse_cmdline_single_command_with_redirect(): assert tc_parse_cmdline(ps('a > b')) == ([['a']], 'b')
def test_files_empty_empty_passes(): tc_check_files(ps(), 'CMD', [], [])
def test_parse_cmdline_pipe_with_redirect(): assert tc_parse_cmdline(ps('a|b -c -d "eee" | f g -h > z')) \ == \ ([['a'], ['b', '-c', '-d', 'eee'], ['f', 'g', '-h']], 'z')
def test_files_text_match_succeeds(): tc_check_files(ps(), 'CMD', ['a'], ['a'])
def test_parse_cmdline_leading_redirect(): with pytest.raises(TF): tc_parse_cmdline(ps('> b'))
def test_files_text_lengthy_mismatch_fails(): with pytest.raises(TF): tc_check_files(ps(), 'CMD', ['b', 'a'], ['a', 'b'])
def test_parse_cmdline_trailing_redirect(): with pytest.raises(TF): tc_parse_cmdline(ps('b >'))