|
1 | 1 | #include <sourcemeta/core/json.h> |
2 | 2 | #include <sourcemeta/core/jsonschema.h> |
| 3 | +#include <sourcemeta/core/options.h> |
3 | 4 |
|
4 | 5 | #include <sourcemeta/blaze/compiler.h> |
5 | 6 | #include <sourcemeta/blaze/evaluator.h> |
@@ -35,72 +36,95 @@ static std::map<std::string_view, std::size_t> global_keywords_count; |
35 | 36 | static std::map<std::string_view, std::size_t> global_steps_count; |
36 | 37 |
|
37 | 38 | auto main(int argc, char **argv) noexcept -> int { |
38 | | - if (argc < 3) { |
39 | | - std::cerr << "Usage: " << argv[0] << " <schema.json> <instance.json>\n"; |
| 39 | + sourcemeta::core::Options options; |
| 40 | + options.flag("fast", {"f"}); |
| 41 | + |
| 42 | + try { |
| 43 | + options.parse(argc, argv); |
| 44 | + } catch (const sourcemeta::core::OptionsError &error) { |
| 45 | + std::cerr << "error: " << error.what() << "\n"; |
| 46 | + return EXIT_FAILURE; |
| 47 | + } |
| 48 | + |
| 49 | + const auto &positional{options.positional()}; |
| 50 | + if (positional.size() < 2) { |
| 51 | + std::cerr << "Usage: " << argv[0] |
| 52 | + << " [--fast] <schema.json> <instance.json>\n"; |
40 | 53 | return EXIT_FAILURE; |
41 | 54 | } |
42 | 55 |
|
43 | | - const auto schema{sourcemeta::core::read_json(argv[1])}; |
44 | | - const auto schema_template{ |
45 | | - sourcemeta::blaze::compile(schema, sourcemeta::core::schema_walker, |
46 | | - sourcemeta::core::schema_resolver, |
47 | | - sourcemeta::blaze::default_schema_compiler)}; |
48 | | - const std::filesystem::path instance_path{argv[2]}; |
49 | | - const auto instance{sourcemeta::core::read_json(instance_path)}; |
50 | | - |
51 | | - sourcemeta::blaze::TraceOutput output{ |
52 | | - sourcemeta::core::schema_walker, sourcemeta::core::schema_resolver, |
53 | | - [](const sourcemeta::blaze::TraceOutput::Entry &entry) { |
54 | | - switch (entry.type) { |
55 | | - case sourcemeta::blaze::TraceOutput::EntryType::Push: |
56 | | - std::cout << "-> (push) "; |
57 | | - break; |
58 | | - case sourcemeta::blaze::TraceOutput::EntryType::Pass: |
59 | | - std::cout << "<- (pass) "; |
60 | | - break; |
61 | | - case sourcemeta::blaze::TraceOutput::EntryType::Fail: |
62 | | - std::cout << "<- (fail) "; |
63 | | - break; |
64 | | - default: |
65 | | - assert(false); |
66 | | - break; |
67 | | - } |
68 | | - |
69 | | - std::cout << "\""; |
70 | | - sourcemeta::core::stringify(entry.evaluate_path, std::cout); |
71 | | - std::cout << "\" ["; |
72 | | - std::cout << entry.name; |
73 | | - std::cout << "]\n"; |
74 | | - std::cout << " at \""; |
75 | | - sourcemeta::core::stringify(entry.instance_location, std::cout); |
76 | | - std::cout << "\"\n"; |
77 | | - |
78 | | - if (entry.type == sourcemeta::blaze::TraceOutput::EntryType::Push) { |
79 | | - global_steps_count[entry.name] += 1; |
80 | | - if (!entry.evaluate_path.empty()) { |
81 | | - assert(entry.evaluate_path.back().is_property()); |
82 | | - const auto &keyword{entry.evaluate_path.back().to_property()}; |
83 | | - global_keywords_count[keyword] += 1; |
| 56 | + const auto mode{options.contains("fast") |
| 57 | + ? sourcemeta::blaze::Mode::FastValidation |
| 58 | + : sourcemeta::blaze::Mode::Exhaustive}; |
| 59 | + |
| 60 | + try { |
| 61 | + const auto schema{ |
| 62 | + sourcemeta::core::read_json(std::filesystem::path{positional.at(0)})}; |
| 63 | + const auto schema_template{sourcemeta::blaze::compile( |
| 64 | + schema, sourcemeta::core::schema_walker, |
| 65 | + sourcemeta::core::schema_resolver, |
| 66 | + sourcemeta::blaze::default_schema_compiler, mode)}; |
| 67 | + const auto instance{ |
| 68 | + sourcemeta::core::read_json(std::filesystem::path{positional.at(1)})}; |
| 69 | + |
| 70 | + sourcemeta::blaze::TraceOutput output{ |
| 71 | + sourcemeta::core::schema_walker, sourcemeta::core::schema_resolver, |
| 72 | + [](const sourcemeta::blaze::TraceOutput::Entry &entry) { |
| 73 | + switch (entry.type) { |
| 74 | + case sourcemeta::blaze::TraceOutput::EntryType::Push: |
| 75 | + std::cout << "-> (push) "; |
| 76 | + break; |
| 77 | + case sourcemeta::blaze::TraceOutput::EntryType::Pass: |
| 78 | + std::cout << "<- (pass) "; |
| 79 | + break; |
| 80 | + case sourcemeta::blaze::TraceOutput::EntryType::Fail: |
| 81 | + std::cout << "<- (fail) "; |
| 82 | + break; |
| 83 | + default: |
| 84 | + assert(false); |
| 85 | + break; |
84 | 86 | } |
85 | | - } |
86 | | - }}; |
87 | | - sourcemeta::blaze::Evaluator evaluator; |
88 | | - const auto result{ |
89 | | - evaluator.validate(schema_template, instance, std::ref(output))}; |
90 | | - |
91 | | - std::cout << "\n"; |
92 | | - std::cout << "==== KEYWORD STATS\n"; |
93 | | - print_map(global_keywords_count); |
94 | | - std::cout << "\n"; |
95 | | - std::cout << "==== STEP STATS\n"; |
96 | | - print_map(global_steps_count); |
97 | | - std::cout << "\n"; |
98 | | - |
99 | | - if (!result) { |
100 | | - std::cerr << "FAIL\n"; |
| 87 | + |
| 88 | + std::cout << "\""; |
| 89 | + sourcemeta::core::stringify(entry.evaluate_path, std::cout); |
| 90 | + std::cout << "\" ["; |
| 91 | + std::cout << entry.name; |
| 92 | + std::cout << "]\n"; |
| 93 | + std::cout << " at \""; |
| 94 | + sourcemeta::core::stringify(entry.instance_location, std::cout); |
| 95 | + std::cout << "\"\n"; |
| 96 | + |
| 97 | + if (entry.type == sourcemeta::blaze::TraceOutput::EntryType::Push) { |
| 98 | + global_steps_count[entry.name] += 1; |
| 99 | + if (!entry.evaluate_path.empty()) { |
| 100 | + assert(entry.evaluate_path.back().is_property()); |
| 101 | + const auto &keyword{entry.evaluate_path.back().to_property()}; |
| 102 | + global_keywords_count[keyword] += 1; |
| 103 | + } |
| 104 | + } |
| 105 | + }}; |
| 106 | + sourcemeta::blaze::Evaluator evaluator; |
| 107 | + const auto result{ |
| 108 | + evaluator.validate(schema_template, instance, std::ref(output))}; |
| 109 | + |
| 110 | + std::cout << "\n"; |
| 111 | + std::cout << "==== KEYWORD STATS\n"; |
| 112 | + print_map(global_keywords_count); |
| 113 | + std::cout << "\n"; |
| 114 | + std::cout << "==== STEP STATS\n"; |
| 115 | + print_map(global_steps_count); |
| 116 | + std::cout << "\n"; |
| 117 | + |
| 118 | + if (!result) { |
| 119 | + std::cerr << "FAIL\n"; |
| 120 | + return EXIT_FAILURE; |
| 121 | + } |
| 122 | + |
| 123 | + std::cerr << "PASS\n"; |
| 124 | + } catch (const std::exception &error) { |
| 125 | + std::cerr << "error: " << error.what() << "\n"; |
101 | 126 | return EXIT_FAILURE; |
102 | 127 | } |
103 | 128 |
|
104 | | - std::cerr << "PASS\n"; |
105 | 129 | return EXIT_SUCCESS; |
106 | 130 | } |
0 commit comments