]> begriffs open source - sa-parse/blob - tests/meson.build
WIP: way more csv tests
[sa-parse] / tests / meson.build
1 # Basic test configuration for CSV parser
2
3 # Define test cases with their properties
4 # Format: [test_name, test_file, test_description]
5
6 # Basic valid CSV test cases
7 csv_basic_tests = [
8     ['basic', 'csv/valid/test.csv', 'Simple test to verify the parser can be executed'],
9     ['empty', 'csv/valid/empty.csv', 'Test with empty CSV'],
10     ['quotes', 'csv/valid/quotes.csv', 'Test with quotes'],
11     ['complex', 'csv/valid/complex.csv', 'Test with complex CSV structures'],
12     ['header_only', 'csv/valid/header_only.csv', 'Test with header only CSV'],
13     ['empty_fields', 'csv/valid/empty_fields.csv', 'Test with empty fields'],
14 ]
15
16 # Edge cases that are VALID per RFC 4180 but might be tricky
17 csv_edge_tests = [
18     ['edge_double_comma', 'csv/valid/empty_fields_double_comma.csv', 'Test double comma (empty fields) - valid per RFC'],
19     ['edge_trailing_comma', 'csv/valid/trailing_empty_field.csv', 'Test trailing comma (empty field at end) - valid per RFC'],
20     ['edge_leading_comma', 'csv/valid/leading_empty_field.csv', 'Test leading comma (empty field at start) - valid per RFC'],
21     ['edge_inconsistent_columns', 'csv/valid/inconsistent_columns.csv', 'Test inconsistent column count - allowed but unusual'],
22     ['edge_no_final_newline', 'csv/valid/no_final_newline.csv', 'Test missing final newline - explicitly allowed by RFC'],
23     ['edge_blank_line', 'csv/valid/blank_line_record.csv', 'Test blank line (empty record) - valid per RFC'],
24     ['edge_tabs', 'csv/valid/tabs_in_fields.csv', 'Test tab characters in fields - valid per RFC'],
25 ]
26
27 # Test cases that are TRULY malformed according to RFC 4180
28 csv_invalid_tests = [
29     # Quote handling errors - these violate RFC 4180 rules
30     ['invalid_unclosed_quote', 'csv/invalid/unclosed_quote.csv', 'Test unclosed quote - violates RFC 4180'],
31     ['invalid_quote_in_unquoted', 'csv/invalid/quote_in_unquoted_field.csv', 'Test quote in middle of unquoted field - violates RFC 4180 rule 5'],
32     ['invalid_unescaped_quote', 'csv/invalid/unescaped_quote.csv', 'Test unescaped quote in unquoted field - violates RFC 4180 rule 5'],
33     ['invalid_text_after_quote', 'csv/invalid/text_after_quote.csv', 'Test text after closing quote - not allowed'],
34     ['invalid_char_after_quote', 'csv/invalid/char_after_quote.csv', 'Test character after closing quote - not allowed'],
35     ['invalid_text_immediately_after_quote', 'csv/invalid/text_immediately_after_quote.csv', 'Test text immediately after closing quote'],
36     ['invalid_quote_in_middle_unquoted', 'csv/invalid/quote_in_middle_unquoted.csv', 'Test quote in middle of unquoted field'],
37     ['invalid_malformed_quote_escape', 'csv/invalid/malformed_quote_escape.csv', 'Test malformed quote escaping'],
38     ['invalid_eof_in_quote', 'csv/invalid/eof_in_quote.csv', 'Test EOF inside quoted field'],
39 ]
40
41 # Stress tests that should complete without crashing (may pass or fail)
42 csv_stress_tests = [
43     ['stress_multiline_quoted', 'csv/stress/multiline_quoted_field.csv', 'Test newline inside quoted field - valid per RFC 4180'],
44     ['stress_quoted_newline', 'csv/stress/quoted_newline_field.csv', 'Test properly quoted newline field'],
45     ['stress_unicode_chars', 'csv/stress/unicode_characters.csv', 'Test unicode characters - should be valid'],
46     ['stress_extremely_long_field', 'csv/stress/extremely_long_field.csv', 'Test extremely long field content'],
47     ['stress_excessive_fields', 'csv/stress/excessive_fields.csv', 'Test excessive number of fields'],
48     ['stress_massive_records', 'csv/stress/massive_records.csv', 'Stress test with many valid records'],
49     ['stress_null_bytes', 'csv/stress/null_bytes.csv', 'Test null bytes in data'],
50     ['stress_extra_newlines', 'csv/stress/extra_trailing_newlines.csv', 'Test extra trailing newlines'],
51     ['stress_semicolon_as_text', 'csv/stress/semicolon_as_text.csv', 'Test semicolons as regular text (not delimiters)'],
52 ]
53
54 # Get shell program once
55 sh = find_program('sh')
56
57 # Create tests for basic valid cases
58 foreach test_case : csv_basic_tests
59     test_name = test_case[0]
60     test_file = test_case[1]
61     test_desc = test_case[2]
62     
63     test('csv_parser_' + test_name,
64         sh,
65         args: ['-c', csv_parser.full_path() + ' < ' + meson.current_source_dir() / test_file],
66         workdir: meson.current_source_dir(),
67         timeout: 5)
68 endforeach
69
70 # Create tests for edge cases (should pass)
71 foreach test_case : csv_edge_tests
72     test_name = test_case[0]
73     test_file = test_case[1]
74     test_desc = test_case[2]
75     
76     test('csv_parser_' + test_name,
77         sh,
78         args: ['-c', csv_parser.full_path() + ' < ' + meson.current_source_dir() / test_file],
79         workdir: meson.current_source_dir(),
80         timeout: 5)
81 endforeach
82
83 # Create tests for truly invalid cases (should fail)
84 foreach test_case : csv_invalid_tests
85     test_name = test_case[0]
86     test_file = test_case[1]
87     test_desc = test_case[2]
88     
89     test('csv_parser_' + test_name,
90         sh,
91         args: ['-c', csv_parser.full_path() + ' < ' + meson.current_source_dir() / test_file],
92         workdir: meson.current_source_dir(),
93         timeout: 30,
94         should_fail: true)
95 endforeach
96
97 # Create stress tests (may pass or fail, but should complete)
98 foreach test_case : csv_stress_tests
99     test_name = test_case[0]
100     test_file = test_case[1]
101     test_desc = test_case[2]
102     
103     test('csv_parser_' + test_name,
104         sh,
105         args: ['-c', csv_parser.full_path() + ' < ' + meson.current_source_dir() / test_file],
106         workdir: meson.current_source_dir(),
107         timeout: 60)
108 endforeach