✅ improved test coverage
This commit is contained in:
		
							parent
							
								
									c87ffad45c
								
							
						
					
					
						commit
						606a25195f
					
				
					 3 changed files with 194 additions and 19 deletions
				
			
		|  | @ -241,13 +241,13 @@ class json_sax_dom_parser : public json_sax<BasicJsonType> | |||
|                 case 1: | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex)); | ||||
|                 case 2: | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex)); | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));  // LCOV_EXCL_LINE
 | ||||
|                 case 3: | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex)); | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));  // LCOV_EXCL_LINE
 | ||||
|                 case 4: | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex)); | ||||
|                 case 5: | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex)); | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));  // LCOV_EXCL_LINE
 | ||||
|                 default: | ||||
|                     assert(false);  // LCOV_EXCL_LINE
 | ||||
|             } | ||||
|  |  | |||
|  | @ -3377,13 +3377,13 @@ class json_sax_dom_parser : public json_sax<BasicJsonType> | |||
|                 case 1: | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::parse_error*>(&ex)); | ||||
|                 case 2: | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex)); | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::invalid_iterator*>(&ex));  // LCOV_EXCL_LINE
 | ||||
|                 case 3: | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex)); | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::type_error*>(&ex));  // LCOV_EXCL_LINE
 | ||||
|                 case 4: | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::out_of_range*>(&ex)); | ||||
|                 case 5: | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex)); | ||||
|                     JSON_THROW(*reinterpret_cast<const detail::other_error*>(&ex));  // LCOV_EXCL_LINE
 | ||||
|                 default: | ||||
|                     assert(false);  // LCOV_EXCL_LINE
 | ||||
|             } | ||||
|  | @ -3946,11 +3946,11 @@ class parser | |||
|         // stack to remember the hieararchy of structured values we are parsing
 | ||||
|         std::vector<parse_state_t> states; | ||||
|         // value to avoid a goto (see comment where set to true)
 | ||||
|         bool skip_to_tail = false; | ||||
|         bool skip_to_state_evaluation = false; | ||||
| 
 | ||||
|         while (true) | ||||
|         { | ||||
|             if (not skip_to_tail) | ||||
|             if (not skip_to_state_evaluation) | ||||
|             { | ||||
|                 // invariant: get_token() was called before each iteration
 | ||||
|                 switch (last_token) | ||||
|  | @ -3999,9 +3999,11 @@ class parser | |||
|                                                     parse_error::create(101, m_lexer.get_position(), exception_message(token_type::name_separator))); | ||||
|                         } | ||||
| 
 | ||||
|                         // remember we are now inside an object
 | ||||
|                         states.push_back(parse_state_t::object_value); | ||||
| 
 | ||||
|                         // parse values
 | ||||
|                         get_token(); | ||||
|                         states.push_back(parse_state_t::object_value); | ||||
|                         continue; | ||||
|                     } | ||||
| 
 | ||||
|  | @ -4025,8 +4027,10 @@ class parser | |||
|                             break; | ||||
|                         } | ||||
| 
 | ||||
|                         // parse values (no need to call get_token)
 | ||||
|                         // remember we are now inside an array
 | ||||
|                         states.push_back(parse_state_t::array_value); | ||||
| 
 | ||||
|                         // parse values (no need to call get_token)
 | ||||
|                         continue; | ||||
|                     } | ||||
| 
 | ||||
|  | @ -4122,7 +4126,7 @@ class parser | |||
|             } | ||||
|             else | ||||
|             { | ||||
|                 skip_to_tail = false; | ||||
|                 skip_to_state_evaluation = false; | ||||
|             } | ||||
| 
 | ||||
|             // we reached this line after we successfully parsed a value
 | ||||
|  | @ -4156,12 +4160,12 @@ class parser | |||
| 
 | ||||
|                             // We are done with this array. Before we can parse
 | ||||
|                             // a new value, we need to evaluate the new state
 | ||||
|                             // first. By setting skip_to_tail to false, we are
 | ||||
|                             // effectively jumping to the beginning of this
 | ||||
|                             // switch.
 | ||||
|                             // first. By setting skip_to_state_evaluation to
 | ||||
|                             // false, we are effectively jumping to the
 | ||||
|                             // beginning of this switch.
 | ||||
|                             assert(not states.empty()); | ||||
|                             states.pop_back(); | ||||
|                             skip_to_tail = true; | ||||
|                             skip_to_state_evaluation = true; | ||||
|                             continue; | ||||
|                         } | ||||
|                         else | ||||
|  | @ -4218,12 +4222,12 @@ class parser | |||
| 
 | ||||
|                             // We are done with this object. Before we can
 | ||||
|                             // parse a new value, we need to evaluate the new
 | ||||
|                             // state first. By setting skip_to_tail to false,
 | ||||
|                             // we are effectively jumping to the beginning of
 | ||||
|                             // this switch.
 | ||||
|                             // state first. By setting skip_to_state_evaluation
 | ||||
|                             // to false, we are effectively jumping to the
 | ||||
|                             // beginning of this switch.
 | ||||
|                             assert(not states.empty()); | ||||
|                             states.pop_back(); | ||||
|                             skip_to_tail = true; | ||||
|                             skip_to_state_evaluation = true; | ||||
|                             continue; | ||||
|                         } | ||||
|                         else | ||||
|  |  | |||
|  | @ -134,6 +134,81 @@ class SaxEventLogger : public nlohmann::json::json_sax_t | |||
|     bool errored = false; | ||||
| }; | ||||
| 
 | ||||
| class SaxCountdown : public nlohmann::json::json_sax_t | ||||
| { | ||||
|   public: | ||||
|     explicit SaxCountdown(const int count) : events_left(count) | ||||
|     {} | ||||
| 
 | ||||
|     bool null() override | ||||
|     { | ||||
|         return events_left-- > 0; | ||||
|     } | ||||
| 
 | ||||
|     bool boolean(bool) override | ||||
|     { | ||||
|         return events_left-- > 0; | ||||
|     } | ||||
| 
 | ||||
|     bool number_integer(json::number_integer_t) override | ||||
|     { | ||||
|         return events_left-- > 0; | ||||
|     } | ||||
| 
 | ||||
|     bool number_unsigned(json::number_unsigned_t) override | ||||
|     { | ||||
|         return events_left-- > 0; | ||||
|     } | ||||
| 
 | ||||
|     bool number_float(json::number_float_t, const std::string&) override | ||||
|     { | ||||
|         return events_left-- > 0; | ||||
|     } | ||||
| 
 | ||||
|     bool string(std::string&&) override | ||||
|     { | ||||
|         return events_left-- > 0; | ||||
|     } | ||||
| 
 | ||||
|     bool start_object(std::size_t) override | ||||
|     { | ||||
|         return events_left-- > 0; | ||||
|     } | ||||
| 
 | ||||
|     bool key(std::string&&) override | ||||
|     { | ||||
|         return events_left-- > 0; | ||||
|     } | ||||
| 
 | ||||
|     bool end_object() override | ||||
|     { | ||||
|         return events_left-- > 0; | ||||
|     } | ||||
| 
 | ||||
|     bool start_array(std::size_t) override | ||||
|     { | ||||
|         return events_left-- > 0; | ||||
|     } | ||||
| 
 | ||||
|     bool end_array() override | ||||
|     { | ||||
|         return events_left-- > 0; | ||||
|     } | ||||
| 
 | ||||
|     bool binary(const std::vector<uint8_t>&) override | ||||
|     { | ||||
|         return events_left-- > 0; | ||||
|     } | ||||
| 
 | ||||
|     bool parse_error(std::size_t, const std::string&, const json::exception&) override | ||||
|     { | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|   private: | ||||
|     int events_left = 0; | ||||
| }; | ||||
| 
 | ||||
| json parser_helper(const std::string& s); | ||||
| bool accept_helper(const std::string& s); | ||||
| 
 | ||||
|  | @ -1595,4 +1670,100 @@ TEST_CASE("parser class") | |||
|             CHECK(j == json(true)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     SECTION("improve test coverage") | ||||
|     { | ||||
|         SECTION("parser with callback") | ||||
|         { | ||||
|             json::parser_callback_t cb = [](int, json::parse_event_t, json&) | ||||
|             { | ||||
|                 return true; | ||||
|             }; | ||||
| 
 | ||||
|             CHECK(json::parse("{\"foo\": true:", cb, false).is_discarded()); | ||||
| 
 | ||||
|             CHECK_THROWS_AS(json::parse("{\"foo\": true:", cb), json::parse_error&); | ||||
|             CHECK_THROWS_WITH(json::parse("{\"foo\": true:", cb), | ||||
|                               "[json.exception.parse_error.101] parse error at 13: syntax error - unexpected ':'; expected '}'"); | ||||
| 
 | ||||
|             CHECK_THROWS_AS(json::parse("1.18973e+4932", cb), json::out_of_range&); | ||||
|             CHECK_THROWS_WITH(json::parse("1.18973e+4932", cb), | ||||
|                               "[json.exception.out_of_range.406] number overflow parsing '1.18973e+4932'"); | ||||
|         } | ||||
| 
 | ||||
|         SECTION("SAX parser") | ||||
|         { | ||||
|             SECTION("} without value") | ||||
|             { | ||||
|                 SaxCountdown s(1); | ||||
|                 CHECK(json::sax_parse("{}", &s) == false); | ||||
|             } | ||||
| 
 | ||||
|             SECTION("} with value") | ||||
|             { | ||||
|                 SaxCountdown s(3); | ||||
|                 CHECK(json::sax_parse("{\"k1\": true}", &s) == false); | ||||
|             } | ||||
| 
 | ||||
|             SECTION("second key") | ||||
|             { | ||||
|                 SaxCountdown s(3); | ||||
|                 CHECK(json::sax_parse("{\"k1\": true, \"k2\": false}", &s) == false); | ||||
|             } | ||||
| 
 | ||||
|             SECTION("] without value") | ||||
|             { | ||||
|                 SaxCountdown s(1); | ||||
|                 CHECK(json::sax_parse("[]", &s) == false); | ||||
|             } | ||||
| 
 | ||||
|             SECTION("] with value") | ||||
|             { | ||||
|                 SaxCountdown s(2); | ||||
|                 CHECK(json::sax_parse("[1]", &s) == false); | ||||
|             } | ||||
| 
 | ||||
|             SECTION("float") | ||||
|             { | ||||
|                 SaxCountdown s(0); | ||||
|                 CHECK(json::sax_parse("3.14", &s) == false); | ||||
|             } | ||||
| 
 | ||||
|             SECTION("false") | ||||
|             { | ||||
|                 SaxCountdown s(0); | ||||
|                 CHECK(json::sax_parse("false", &s) == false); | ||||
|             } | ||||
| 
 | ||||
|             SECTION("null") | ||||
|             { | ||||
|                 SaxCountdown s(0); | ||||
|                 CHECK(json::sax_parse("null", &s) == false); | ||||
|             } | ||||
| 
 | ||||
|             SECTION("true") | ||||
|             { | ||||
|                 SaxCountdown s(0); | ||||
|                 CHECK(json::sax_parse("true", &s) == false); | ||||
|             } | ||||
| 
 | ||||
|             SECTION("unsigned") | ||||
|             { | ||||
|                 SaxCountdown s(0); | ||||
|                 CHECK(json::sax_parse("12", &s) == false); | ||||
|             } | ||||
| 
 | ||||
|             SECTION("integer") | ||||
|             { | ||||
|                 SaxCountdown s(0); | ||||
|                 CHECK(json::sax_parse("-12", &s) == false); | ||||
|             } | ||||
| 
 | ||||
|             SECTION("string") | ||||
|             { | ||||
|                 SaxCountdown s(0); | ||||
|                 CHECK(json::sax_parse("\"foo\"", &s) == false); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue