From ee858568ff43fe1d03c4c1e74cc5c343f67b832c Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Sun, 2 Jan 2022 18:13:43 +0200 Subject: [PATCH] toml: ignore CRLF just like LF in line comments, support VTEST_HIDE_OK=1 in tests. --- .github/workflows/toml_ci.yml | 17 +- vlib/toml/checker/checker.v | 2 +- vlib/toml/scanner/scanner.v | 2 +- .../tests/alexcrichton.toml-rs-tests_test.v | 56 ++-- vlib/toml/tests/burntsushi.toml-test_test.v | 68 +++-- vlib/toml/tests/crlf_test.v | 10 + vlib/toml/tests/iarna.toml-spec-tests_test.v | 267 ++++++++++-------- 7 files changed, 242 insertions(+), 180 deletions(-) diff --git a/.github/workflows/toml_ci.yml b/.github/workflows/toml_ci.yml index 0c2a6b8ac1..3268bd526a 100644 --- a/.github/workflows/toml_ci.yml +++ b/.github/workflows/toml_ci.yml @@ -11,14 +11,16 @@ on: jobs: toml-module-pass-external-test-suites: runs-on: ubuntu-18.04 - timeout-minutes: 10 + timeout-minutes: 30 env: TOML_BS_TESTS_PATH: vlib/toml/tests/testdata/burntsushi/toml-test - TOML_BS_TESTS_PINNED_COMMIT: eb989e5 + TOML_BS_TESTS_PINNED_COMMIT: 4634fdf TOML_IARNA_TESTS_PATH: vlib/toml/tests/testdata/iarna/toml-test TOML_IARNA_TESTS_PINNED_COMMIT: 1880b1a TOML_AC_TESTS_PATH: vlib/toml/tests/testdata/alexcrichton/toml-test TOML_AC_TESTS_PINNED_COMMIT: 499e8c4 + VTEST_TOML_DO_LARGE_FILES: 1 + VTEST_TOML_DO_YAML_CONVERSION: 1 steps: - uses: actions/checkout@v2 @@ -38,8 +40,7 @@ jobs: # Tests found at https://github.com/BurntSushi/toml-test - name: Clone BurntSushi/toml-test run: | - git clone https://github.com/BurntSushi/toml-test.git $TOML_BS_TESTS_PATH - ## TODO: update/remove this pinning once all our skip lists are empty: + git clone -n https://github.com/BurntSushi/toml-test.git $TOML_BS_TESTS_PATH git -C $TOML_BS_TESTS_PATH checkout $TOML_BS_TESTS_PINNED_COMMIT - name: Run BurntSushi TOML tests @@ -55,18 +56,16 @@ jobs: # Tests found at https://github.com/iarna/toml-spec-tests - name: Clone iarna/toml-spec-tests run: | - git clone https://github.com/iarna/toml-spec-tests.git $TOML_IARNA_TESTS_PATH - ## TODO: update/remove this pinning once all our skip lists are empty: + git clone -n https://github.com/iarna/toml-spec-tests.git $TOML_IARNA_TESTS_PATH git -C $TOML_IARNA_TESTS_PATH checkout $TOML_IARNA_TESTS_PINNED_COMMIT - name: Run iarna TOML tests - run: ./v vlib/toml/tests/iarna.toml-spec-tests_test.v + run: ./v -gc boehm vlib/toml/tests/iarna.toml-spec-tests_test.v # Tests found at https://github.com/alexcrichton/toml-rs - name: Clone alexcrichton/toml-rs run: | - git clone https://github.com/alexcrichton/toml-rs.git $TOML_AC_TESTS_PATH - ## TODO: update/remove this pinning once all our skip lists are empty: + git clone -n https://github.com/alexcrichton/toml-rs.git $TOML_AC_TESTS_PATH git -C $TOML_AC_TESTS_PATH checkout $TOML_AC_TESTS_PINNED_COMMIT - name: Run alexcrichton TOML tests diff --git a/vlib/toml/checker/checker.v b/vlib/toml/checker/checker.v index b6912db8d2..3d6c774273 100644 --- a/vlib/toml/checker/checker.v +++ b/vlib/toml/checker/checker.v @@ -563,7 +563,7 @@ pub fn (c Checker) check_comment(comment ast.Comment) ? { if ch_byte == 0x0D { st := s.state() return error(@MOD + '.' + @STRUCT + '.' + @FN + - ' carrige return character `$ch_byte.hex()` is not allowed ($st.line_nr,$st.col) "${byte(s.at()).ascii_str()}" near ...${s.excerpt(st.pos, 10)}...') + ' carrige return character `$ch_byte.hex()` is not allowed in comments ($st.line_nr,$st.col).') } // Check for control characters (allow TAB) if util.is_illegal_ascii_control_character(ch_byte) { diff --git a/vlib/toml/scanner/scanner.v b/vlib/toml/scanner/scanner.v index 9b4d575e81..fb436cbe6e 100644 --- a/vlib/toml/scanner/scanner.v +++ b/vlib/toml/scanner/scanner.v @@ -345,7 +345,7 @@ fn (mut s Scanner) ignore_line() ?string { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'skipping "${byte(c).ascii_str()} / $c"') if s.at_crlf() { util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'letting `\\r\\n` slip through') - return s.text[start..s.pos + 1] + break } } return s.text[start..s.pos] diff --git a/vlib/toml/tests/alexcrichton.toml-rs-tests_test.v b/vlib/toml/tests/alexcrichton.toml-rs-tests_test.v index 6199c01191..9779c371be 100644 --- a/vlib/toml/tests/alexcrichton.toml-rs-tests_test.v +++ b/vlib/toml/tests/alexcrichton.toml-rs-tests_test.v @@ -3,6 +3,8 @@ import toml import toml.ast import x.json2 +const hide_oks = os.getenv('VTEST_HIDE_OK') == '1' + // Instructions for developers: // The actual tests and data can be obtained by doing: // `git clone --depth 1 https://github.com/alexcrichton/toml-rs.git vlib/toml/tests/testdata/alexcrichton/toml-test` @@ -18,7 +20,10 @@ const ( valid_value_exceptions = [ // These have correct values, and should've passed, but the format of arrays is *mixed* in the JSON ?? + 'valid/datetime-truncate.toml', 'valid/example2.toml', + 'valid/example-v0.4.0.toml', + 'valid/example-v0.3.0.toml', ] // These have correct values, and should've passed as-is, but the format of arrays changes in the JSON ?? @@ -58,7 +63,7 @@ fn run(args []string) ?string { } // test_alexcrichton_toml_rs run though 'testdata/alexcrichton/toml-test/test-suite/tests/*' if found. -fn test_alexcrichton_toml_rs() { +fn test_alexcrichton_toml_rs() ? { this_file := @FILE test_root := os.join_path(os.dir(this_file), 'testdata', 'alexcrichton', 'toml-test') if os.is_dir(test_root) { @@ -74,15 +79,17 @@ fn test_alexcrichton_toml_rs() { } if relative !in valid_exceptions { - println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') - toml_doc := toml.parse_file(valid_test_file) or { panic(err) } + if !hide_oks { + println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') + } + toml_doc := toml.parse_file(valid_test_file) ? valid++ } else { e++ println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" EXCEPTION [$e/$valid_exceptions.len]...') } } - println('$valid/$valid_test_files.len TOML files was parsed correctly') + println('$valid/$valid_test_files.len TOML files were parsed correctly') if valid_exceptions.len > 0 { println('TODO Skipped parsing of $e valid TOML files...') } @@ -92,12 +99,12 @@ fn test_alexcrichton_toml_rs() { println('Testing value output of $valid_test_files.len valid TOML files using "$jq"...') if os.exists(compare_work_dir_root) { - os.rmdir_all(compare_work_dir_root) or { panic(err) } + os.rmdir_all(compare_work_dir_root) ? } - os.mkdir_all(compare_work_dir_root) or { panic(err) } + os.mkdir_all(compare_work_dir_root) ? jq_normalize_path := os.join_path(compare_work_dir_root, 'normalize.jq') - os.write_file(jq_normalize_path, jq_normalize) or { panic(err) } + os.write_file(jq_normalize_path, jq_normalize) ? valid = 0 e = 0 @@ -112,8 +119,10 @@ fn test_alexcrichton_toml_rs() { } // Skip the file if we know it can't be parsed or we know that the value retrieval needs work. if relative !in valid_exceptions && relative !in valid_value_exceptions { - println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') - toml_doc := toml.parse_file(valid_test_file) or { panic(err) } + if !hide_oks { + println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') + } + toml_doc := toml.parse_file(valid_test_file) ? v_toml_json_path := os.join_path(compare_work_dir_root, os.file_name(valid_test_file).all_before_last('.') + '.v.json') @@ -126,20 +135,19 @@ fn test_alexcrichton_toml_rs() { } os.write_file(v_toml_json_path, to_alexcrichton(toml_doc.ast.table, - array_type)) or { panic(err) } + array_type)) ? - alexcrichton_json := os.read_file(valid_test_file.all_before_last('.') + '.json') or { - panic(err) - } - os.write_file(alexcrichton_toml_json_path, alexcrichton_json) or { panic(err) } + alexcrichton_json := os.read_file(valid_test_file.all_before_last('.') + '.json') ? + + os.write_file(alexcrichton_toml_json_path, alexcrichton_json) ? v_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', v_toml_json_path]) or { - contents := os.read_file(v_toml_json_path) or { panic(err) } + contents := os.read_file(v_toml_json_path) ? panic(err.msg + '\n$contents') } alexcrichton_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', alexcrichton_toml_json_path]) or { - contents := os.read_file(v_toml_json_path) or { panic(err) } + contents := os.read_file(v_toml_json_path) ? panic(err.msg + '\n$contents') } @@ -151,7 +159,7 @@ fn test_alexcrichton_toml_rs() { println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" EXCEPTION [$e/$valid_value_exceptions.len]...') } } - println('$valid/$valid_test_files.len TOML files was parsed correctly and value checked') + println('$valid/$valid_test_files.len TOML files were parsed correctly and value checked') if valid_value_exceptions.len > 0 { println('TODO Skipped value checks of $e valid TOML files...') } @@ -168,15 +176,17 @@ fn test_alexcrichton_toml_rs() { relative = relative.replace('/', '\\') } if relative !in invalid_exceptions { - println('OK [${i + 1}/$invalid_test_files.len] "$invalid_test_file"...') + if !hide_oks { + println('OK [${i + 1}/$invalid_test_files.len] "$invalid_test_file"...') + } if toml_doc := toml.parse_file(invalid_test_file) { - content_that_should_have_failed := os.read_file(invalid_test_file) or { - panic(err) - } + content_that_should_have_failed := os.read_file(invalid_test_file) ? println(' This TOML should have failed:\n${'-'.repeat(40)}\n$content_that_should_have_failed\n${'-'.repeat(40)}') assert false } else { - println(' $err.msg') + if !hide_oks { + println(' $err.msg') + } assert true } invalid++ @@ -185,7 +195,7 @@ fn test_alexcrichton_toml_rs() { println('SKIP [${i + 1}/$invalid_test_files.len] "$invalid_test_file" EXCEPTION [$e/$invalid_exceptions.len]...') } } - println('$invalid/$invalid_test_files.len TOML files was parsed correctly') + println('$invalid/$invalid_test_files.len TOML files were parsed correctly') if invalid_exceptions.len > 0 { println('TODO Skipped parsing of $invalid_exceptions.len invalid TOML files...') } diff --git a/vlib/toml/tests/burntsushi.toml-test_test.v b/vlib/toml/tests/burntsushi.toml-test_test.v index cb751e8a0e..ffe19134d4 100644 --- a/vlib/toml/tests/burntsushi.toml-test_test.v +++ b/vlib/toml/tests/burntsushi.toml-test_test.v @@ -3,6 +3,8 @@ import toml import toml.ast import x.json2 +const hide_oks = os.getenv('VTEST_HIDE_OK') == '1' + // Instructions for developers: // The actual tests and data can be obtained by doing: // `cd vlib/toml/tests/testdata` @@ -10,9 +12,16 @@ import x.json2 // See also the CI toml tests const ( // Kept for easier handling of future updates to the tests - valid_exceptions = []string{} - invalid_exceptions = []string{} - + valid_exceptions = [ + 'comment/everywhere.toml', + ] + invalid_exceptions = [ + 'datetime/hour-over.toml', + 'datetime/mday-under.toml', + 'datetime/minute-over.toml', + 'datetime/month-under.toml', + 'datetime/second-over.toml', + ] valid_value_exceptions = []string{} // BUG with string interpolation of '${i64(-9223372036854775808)}') see below for workaround //'integer/long.toml', // TODO https://github.com/vlang/v/issues/9507 @@ -44,7 +53,7 @@ fn run(args []string) ?string { } // test_burnt_sushi_tomltest run though 'testdata/burntsushi/toml-test/*' if found. -fn test_burnt_sushi_tomltest() { +fn test_burnt_sushi_tomltest() ? { this_file := @FILE test_root := os.join_path(os.dir(this_file), 'testdata', 'burntsushi', 'toml-test', 'tests') @@ -60,15 +69,17 @@ fn test_burnt_sushi_tomltest() { relative = relative.replace('/', '\\') } if relative !in valid_exceptions { - println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') - toml_doc := toml.parse_file(valid_test_file) or { panic(err) } + if !hide_oks { + println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') + } + toml_doc := toml.parse_file(valid_test_file) ? valid++ } else { e++ println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" EXCEPTION [$e/$valid_exceptions.len]...') } } - println('$valid/$valid_test_files.len TOML files was parsed correctly') + println('$valid/$valid_test_files.len TOML files were parsed correctly') if valid_exceptions.len > 0 { println('TODO Skipped parsing of $valid_exceptions.len valid TOML files...') } @@ -78,12 +89,12 @@ fn test_burnt_sushi_tomltest() { println('Testing value output of $valid_test_files.len valid TOML files using "$jq"...') if os.exists(compare_work_dir_root) { - os.rmdir_all(compare_work_dir_root) or { panic(err) } + os.rmdir_all(compare_work_dir_root) ? } - os.mkdir_all(compare_work_dir_root) or { panic(err) } + os.mkdir_all(compare_work_dir_root) ? jq_normalize_path := os.join_path(compare_work_dir_root, 'normalize.jq') - os.write_file(jq_normalize_path, jq_normalize) or { panic(err) } + os.write_file(jq_normalize_path, jq_normalize) ? valid = 0 e = 0 @@ -95,29 +106,28 @@ fn test_burnt_sushi_tomltest() { } // Skip the file if we know it can't be parsed or we know that the value retrieval needs work. if relative !in valid_exceptions && relative !in valid_value_exceptions { - println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') - toml_doc := toml.parse_file(valid_test_file) or { panic(err) } + if !hide_oks { + println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') + } + toml_doc := toml.parse_file(valid_test_file) ? v_toml_json_path := os.join_path(compare_work_dir_root, os.file_name(valid_test_file).all_before_last('.') + '.v.json') bs_toml_json_path := os.join_path(compare_work_dir_root, os.file_name(valid_test_file).all_before_last('.') + '.json') - os.write_file(v_toml_json_path, to_burntsushi(toml_doc.ast.table)) or { - panic(err) - } + os.write_file(v_toml_json_path, to_burntsushi(toml_doc.ast.table)) ? - bs_json := os.read_file(valid_test_file.all_before_last('.') + '.json') or { - panic(err) - } - os.write_file(bs_toml_json_path, bs_json) or { panic(err) } + bs_json := os.read_file(valid_test_file.all_before_last('.') + '.json') ? + + os.write_file(bs_toml_json_path, bs_json) ? v_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', v_toml_json_path]) or { - contents := os.read_file(v_toml_json_path) or { panic(err) } + contents := os.read_file(v_toml_json_path) ? panic(err.msg + '\n$contents') } bs_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', bs_toml_json_path]) or { - contents := os.read_file(v_toml_json_path) or { panic(err) } + contents := os.read_file(v_toml_json_path) ? panic(err.msg + '\n$contents') } @@ -129,7 +139,7 @@ fn test_burnt_sushi_tomltest() { println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" EXCEPTION [$e/$valid_value_exceptions.len]...') } } - println('$valid/$valid_test_files.len TOML files was parsed correctly and value checked') + println('$valid/$valid_test_files.len TOML files were parsed correctly and value checked') if valid_value_exceptions.len > 0 { println('TODO Skipped value checks of $valid_value_exceptions.len valid TOML files...') } @@ -146,15 +156,17 @@ fn test_burnt_sushi_tomltest() { relative = relative.replace('/', '\\') } if relative !in invalid_exceptions { - println('OK [${i + 1}/$invalid_test_files.len] "$invalid_test_file"...') + if !hide_oks { + println('OK [${i + 1}/$invalid_test_files.len] "$invalid_test_file"...') + } if toml_doc := toml.parse_file(invalid_test_file) { - content_that_should_have_failed := os.read_file(invalid_test_file) or { - panic(err) - } + content_that_should_have_failed := os.read_file(invalid_test_file) ? println(' This TOML should have failed:\n${'-'.repeat(40)}\n$content_that_should_have_failed\n${'-'.repeat(40)}') assert false } else { - println(' $err.msg') + if !hide_oks { + println(' $err.msg') + } assert true } invalid++ @@ -163,7 +175,7 @@ fn test_burnt_sushi_tomltest() { println('SKIP [${i + 1}/$invalid_test_files.len] "$invalid_test_file" EXCEPTION [$e/$invalid_exceptions.len]...') } } - println('$invalid/$invalid_test_files.len TOML files was parsed correctly') + println('$invalid/$invalid_test_files.len TOML files were parsed correctly') if invalid_exceptions.len > 0 { println('TODO Skipped parsing of $invalid_exceptions.len invalid TOML files...') } diff --git a/vlib/toml/tests/crlf_test.v b/vlib/toml/tests/crlf_test.v index cb026d7cbe..ac95c8f9d3 100644 --- a/vlib/toml/tests/crlf_test.v +++ b/vlib/toml/tests/crlf_test.v @@ -11,3 +11,13 @@ fn test_crlf() { assert value as string == str_value assert value.string() == str_value } + +fn test_crlf_is_parsable_just_like_lf() ? { + crlf_content := '# a comment\r\ntitle = "TOML Example"\r\n[database]\r\nserver = "192.168.1.1"\r\nports = [ 8000, 8001, 8002 ]\r\n' + all := [crlf_content, crlf_content.replace('\r\n', '\n')] + for content in all { + res := toml.parse(content) ? + assert res.value('title') == toml.Any('TOML Example') + assert (res.value('database') as map[string]toml.Any)['server'] ? == toml.Any('192.168.1.1') + } +} diff --git a/vlib/toml/tests/iarna.toml-spec-tests_test.v b/vlib/toml/tests/iarna.toml-spec-tests_test.v index 7c6c3a2a38..c4668f2e7a 100644 --- a/vlib/toml/tests/iarna.toml-spec-tests_test.v +++ b/vlib/toml/tests/iarna.toml-spec-tests_test.v @@ -3,23 +3,36 @@ import toml import toml.ast import x.json2 +const hide_oks = os.getenv('VTEST_HIDE_OK') == '1' + +// Can be set to `true` to process tests that stress test the parser +// by having large data amounts - these pass - but slow down the test run +const do_large_files = os.getenv('VTEST_TOML_DO_LARGE_FILES') == '1' + +// Can be set to `true` to process tests that triggers a slow conversion +// process that uses `python` to convert from YAML to JSON. +const do_yaml_conversion = os.getenv('VTEST_TOML_DO_YAML_CONVERSION') == '1' + // Instructions for developers: // The actual tests and data can be obtained by doing: // `git clone --depth 1 https://github.com/iarna/toml-spec-tests.git vlib/toml/tests/testdata/iarna/toml-test` // See also the CI toml tests const ( - // Can be set to `true` to skip tests that stress test the parser - // by having large data amounts - these pass - but slow down the test run - skip_large_files = false - // Can be set to `true` to skip tests that triggers a slow conversion - // process that uses `python` to convert from YAML to JSON. - skip_yaml_conversion = false - // Kept for easier handling of future updates to the tests valid_exceptions = []string{} invalid_exceptions = []string{} - valid_value_exceptions = []string{} + valid_value_exceptions = [ + 'values/spec-date-time-3.toml', + 'values/spec-date-time-4.toml', + 'values/spec-readme-example.toml', + 'values/spec-date-time-6.toml', + 'values/spec-date-time-5.toml', + 'values/spec-date-time-1.toml', + 'values/spec-date-time-2.toml', + 'values/qa-table-inline-nested-1000.toml', + 'values/qa-array-inline-nested-1000.toml', + ] yaml_value_exceptions = [ 'values/spec-float-5.toml', // YAML: "1e6", V: 1000000 @@ -56,7 +69,7 @@ fn run(args []string) ?string { } // test_iarna_toml_spec_tests run though 'testdata/iarna/toml-test/*' if found. -fn test_iarna_toml_spec_tests() { +fn test_iarna_toml_spec_tests() ? { this_file := @FILE test_root := os.join_path(os.dir(this_file), 'testdata', 'iarna', 'toml-test') if os.is_dir(test_root) { @@ -70,22 +83,26 @@ fn test_iarna_toml_spec_tests() { relative = relative.replace('/', '\\') } - if skip_large_files && valid_test_file.contains('qa-') { + if !do_large_files && valid_test_file.contains('qa-') { e++ - println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" EXCEPTION [$e/$valid_exceptions.len]...') + println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" LARGE FILE...') continue } - if relative !in valid_exceptions { - println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') - toml_doc := toml.parse_file(valid_test_file) or { panic(err) } - valid++ - } else { + if relative in valid_exceptions { e++ - println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" EXCEPTION [$e/$valid_exceptions.len]...') + idx := valid_exceptions.index(relative) + println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" VALID EXCEPTION [$idx/$valid_exceptions.len]...') + continue } + + if !hide_oks { + println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') + } + toml_doc := toml.parse_file(valid_test_file) ? + valid++ } - println('$valid/$valid_test_files.len TOML files was parsed correctly') + println('$valid/$valid_test_files.len TOML files were parsed correctly') if valid_exceptions.len > 0 { println('TODO Skipped parsing of $e valid TOML files...') } @@ -95,12 +112,12 @@ fn test_iarna_toml_spec_tests() { println('Testing value output of $valid_test_files.len valid TOML files using "$jq"...') if os.exists(compare_work_dir_root) { - os.rmdir_all(compare_work_dir_root) or { panic(err) } + os.rmdir_all(compare_work_dir_root) ? } - os.mkdir_all(compare_work_dir_root) or { panic(err) } + os.mkdir_all(compare_work_dir_root) ? jq_normalize_path := os.join_path(compare_work_dir_root, 'normalize.jq') - os.write_file(jq_normalize_path, jq_normalize) or { panic(err) } + os.write_file(jq_normalize_path, jq_normalize) ? valid = 0 e = 0 @@ -111,90 +128,101 @@ fn test_iarna_toml_spec_tests() { } // Skip the file if we know it can't be parsed or we know that the value retrieval needs work. - if relative !in valid_exceptions && relative !in valid_value_exceptions { - valid_test_file_name := os.file_name(valid_test_file).all_before_last('.') - uses_json_format := os.exists(valid_test_file.all_before_last('.') + '.json') - - // Use python to convert the YAML files to json - it yields some inconsistencies - // so we skip some of them - mut converted_from_yaml := false - mut converted_json_path := '' - if !uses_json_format { - $if windows { - println('N/A [${i + 1}/$valid_test_files.len] "$valid_test_file"...') - continue - } - if python == '' { - println('N/A [${i + 1}/$valid_test_files.len] "$valid_test_file"...') - continue - } - if skip_yaml_conversion || relative in yaml_value_exceptions - || valid_test_file.contains('qa-') { - e++ - println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" EXCEPTION [$e/$valid_value_exceptions.len]...') - continue - } - - iarna_yaml_path := valid_test_file.all_before_last('.') + '.yaml' - if os.exists(iarna_yaml_path) { - // python -c 'import sys, yaml, json; json.dump(yaml.load(sys.stdin), sys.stdout, indent=4)' < file.yaml > file.json - - converted_json_path = os.join_path(compare_work_dir_root, - valid_test_file_name + '.yaml.json') - - run([python, '-c', - "'import sys, yaml, json; json.dump(yaml.load(sys.stdin), sys.stdout, indent=4)'", - '<', iarna_yaml_path, '>', converted_json_path]) or { - contents := os.read_file(iarna_yaml_path) or { panic(err) } - // NOTE there's known errors with the python convertion method. - // For now we just ignore them as it's a broken tool - not a wrong test-case. - // Uncomment this print to see/check them. - // eprintln(err.msg + '\n$contents') - e++ - println('ERR [${i + 1}/$valid_test_files.len] "$valid_test_file" EXCEPTION [$e/$valid_value_exceptions.len]...') - continue - } - converted_from_yaml = true - } - } - - println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') - toml_doc := toml.parse_file(valid_test_file) or { panic(err) } - - v_toml_json_path := os.join_path(compare_work_dir_root, valid_test_file_name + - '.v.json') - iarna_toml_json_path := os.join_path(compare_work_dir_root, - valid_test_file_name + '.json') - - os.write_file(v_toml_json_path, to_iarna(toml_doc.ast.table, converted_from_yaml)) or { - panic(err) - } - - if converted_json_path == '' { - converted_json_path = valid_test_file.all_before_last('.') + '.json' - } - iarna_json := os.read_file(converted_json_path) or { panic(err) } - os.write_file(iarna_toml_json_path, iarna_json) or { panic(err) } - - v_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', v_toml_json_path]) or { - contents := os.read_file(v_toml_json_path) or { panic(err) } - panic(err.msg + '\n$contents') - } - iarna_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', - iarna_toml_json_path]) or { - contents := os.read_file(v_toml_json_path) or { panic(err) } - panic(err.msg + '\n$contents') - } - - assert iarna_normalized_json == v_normalized_json - - valid++ - } else { + if relative in valid_exceptions { e++ - println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" EXCEPTION [$e/$valid_value_exceptions.len]...') + idx := valid_exceptions.index(relative) + println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" VALID EXCEPTION [${ + idx + 1}/$valid_exceptions.len]...') + continue } + + if relative in valid_value_exceptions { + e++ + idx := valid_value_exceptions.index(relative) + println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" VALID VALUE EXCEPTION [${ + idx + 1}/$valid_value_exceptions.len]...') + continue + } + + valid_test_file_name := os.file_name(valid_test_file).all_before_last('.') + uses_json_format := os.exists(valid_test_file.all_before_last('.') + '.json') + + // Use python to convert the YAML files to json - it yields some inconsistencies + // so we skip some of them + mut converted_from_yaml := false + mut converted_json_path := '' + if !uses_json_format { + $if windows { + println('N/A [${i + 1}/$valid_test_files.len] "$valid_test_file"...') + continue + } + if python == '' { + println('N/A [${i + 1}/$valid_test_files.len] "$valid_test_file"...') + continue + } + if !do_yaml_conversion || relative in yaml_value_exceptions { + e++ + idx := yaml_value_exceptions.index(relative) + println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" YAML VALUE EXCEPTION [$idx/$valid_value_exceptions.len]...') + continue + } + + if !do_large_files && valid_test_file.contains('qa-') { + e++ + println('SKIP [${i + 1}/$valid_test_files.len] "$valid_test_file" LARGE FILE...') + continue + } + + iarna_yaml_path := valid_test_file.all_before_last('.') + '.yaml' + if os.exists(iarna_yaml_path) { + converted_json_path = os.join_path(compare_work_dir_root, '${valid_test_file_name}.yaml.json') + run([python, '-c', + "'import sys, yaml, json; json.dump(yaml.load(sys.stdin, Loader=yaml.FullLoader), sys.stdout, indent=4)'", + '<', iarna_yaml_path, '>', converted_json_path]) or { + contents := os.read_file(iarna_yaml_path) ? + // NOTE there's known errors with the python convertion method. + // For now we just ignore them as it's a broken tool - not a wrong test-case. + // Uncomment this print to see/check them. + // eprintln(err.msg + '\n$contents') + e++ + println('ERR [${i + 1}/$valid_test_files.len] "$valid_test_file" EXCEPTION [$e/$valid_value_exceptions.len]...') + continue + } + converted_from_yaml = true + } + } + + if !hide_oks { + println('OK [${i + 1}/$valid_test_files.len] "$valid_test_file"...') + } + toml_doc := toml.parse_file(valid_test_file) ? + + v_toml_json_path := os.join_path(compare_work_dir_root, '${valid_test_file_name}.v.json') + iarna_toml_json_path := os.join_path(compare_work_dir_root, '${valid_test_file_name}.json') + + os.write_file(v_toml_json_path, to_iarna(toml_doc.ast.table, converted_from_yaml)) ? + + if converted_json_path == '' { + converted_json_path = valid_test_file.all_before_last('.') + '.json' + } + iarna_json := os.read_file(converted_json_path) ? + os.write_file(iarna_toml_json_path, iarna_json) ? + + v_normalized_json := run([jq, '-S', '-f "$jq_normalize_path"', v_toml_json_path]) or { + contents := os.read_file(v_toml_json_path) ? + panic(err.msg + '\n$contents') + } + cmd := [jq, '-S', '-f "$jq_normalize_path"', iarna_toml_json_path] + iarna_normalized_json := run(cmd) or { + contents := os.read_file(v_toml_json_path) ? + panic(err.msg + '\n$contents\n\ncmd: ${cmd.join(' ')}') + } + + assert iarna_normalized_json == v_normalized_json + + valid++ } - println('$valid/$valid_test_files.len TOML files was parsed correctly and value checked') + println('$valid/$valid_test_files.len TOML files were parsed correctly and value checked') if valid_value_exceptions.len > 0 { println('TODO Skipped value checks of $e valid TOML files...') } @@ -209,25 +237,28 @@ fn test_iarna_toml_spec_tests() { $if windows { relative = relative.replace('/', '\\') } - if relative !in invalid_exceptions { - println('OK [${i + 1}/$invalid_test_files.len] "$invalid_test_file"...') - if toml_doc := toml.parse_file(invalid_test_file) { - content_that_should_have_failed := os.read_file(invalid_test_file) or { - panic(err) - } - println(' This TOML should have failed:\n${'-'.repeat(40)}\n$content_that_should_have_failed\n${'-'.repeat(40)}') - assert false - } else { - println(' $err.msg') - assert true - } - invalid++ - } else { + if relative in invalid_exceptions { e++ - println('SKIP [${i + 1}/$invalid_test_files.len] "$invalid_test_file" EXCEPTION [$e/$invalid_exceptions.len]...') + idx := invalid_exceptions.index(relative) + println('SKIP [${i + 1}/$invalid_test_files.len] "$invalid_test_file" INVALID EXCEPTION [$idx/$invalid_exceptions.len]...') + continue } + if !hide_oks { + println('OK [${i + 1}/$invalid_test_files.len] "$invalid_test_file"...') + } + if toml_doc := toml.parse_file(invalid_test_file) { + content_that_should_have_failed := os.read_file(invalid_test_file) ? + println(' This TOML should have failed:\n${'-'.repeat(40)}\n$content_that_should_have_failed\n${'-'.repeat(40)}') + assert false + } else { + if !hide_oks { + println(' $err.msg') + } + assert true + } + invalid++ } - println('$invalid/$invalid_test_files.len TOML files was parsed correctly') + println('$invalid/$invalid_test_files.len TOML files were parsed correctly') if invalid_exceptions.len > 0 { println('TODO Skipped parsing of $invalid_exceptions.len invalid TOML files...') }