text: #include "./test_group.hpp"
  
  namespace c4 {
  namespace yml {
  
  TEST(single_quoted, test_suite_KSS4)
  {
      csubstr yaml = R"(
  ---
  'quoted
  string'
  --- 'quoted
  string'
  ---
  - 'quoted
    string'
  ---
  - 'quoted
  string'
  ---
  'quoted
    string': 'quoted
    string'
  ---
  'quoted
  string': 'quoted
  string'
  )";
      test_check_emit_check(yaml, [](Tree const &t){
          EXPECT_EQ(t.docref(0).val(), "quoted string");
          EXPECT_EQ(t.docref(1).val(), "quoted string");
          EXPECT_EQ(t.docref(2)[0].val(), "quoted string");
          EXPECT_EQ(t.docref(3)[0].val(), "quoted string");
          EXPECT_EQ(t.docref(4)["quoted string"].val(), "quoted string");
          EXPECT_EQ(t.docref(5)["quoted string"].val(), "quoted string");
      });
  }
  
  
  TEST(single_quoted, test_suite_R4YG)
  {
      csubstr yaml = R"(
  - '	
  
  detected
  
  '
  
  )";
      test_check_emit_check(yaml, [](Tree const &t){
          EXPECT_EQ(t[0].val(), csubstr("\t\ndetected\n"));
      });
  }
  
  
  TEST(single_quoted, test_suite_PRH3)
  {
      csubstr yaml = R"(
  - ' 1st non-empty
  
   2nd non-empty 
  	3rd non-empty '
  - ' 1st non-empty
  
   2nd non-empty 	
   	3rd non-empty '
  - ' 1st non-empty
  
   2nd non-empty	 
  	3rd non-empty '
  )";
      test_check_emit_check(yaml, [](Tree const &t){
          EXPECT_EQ(t[0].val(), csubstr(" 1st non-empty\n2nd non-empty 3rd non-empty "));
          EXPECT_EQ(t[1].val(), csubstr(" 1st non-empty\n2nd non-empty 3rd non-empty "));
          EXPECT_EQ(t[2].val(), csubstr(" 1st non-empty\n2nd non-empty 3rd non-empty "));
      });
  }
  
  
  TEST(single_quoted, test_suite_T4YY)
  {
      csubstr yaml = R"(
  ---
  ' 1st non-empty
  
   2nd non-empty 
   3rd non-empty '
  ---
  '	
  
  detected
  
  '
  
  )";
      test_check_emit_check(yaml, [](Tree const &t){
          ASSERT_TRUE(t.rootref().is_stream());
          ASSERT_TRUE(t.rootref().first_child().is_doc());
          EXPECT_EQ(t.rootref().first_child().val(), csubstr(" 1st non-empty\n2nd non-empty 3rd non-empty "));
      });
  }
  
  TEST(single_quoted, test_suite_G4RS)
  {
      csubstr yaml = R"(
  single: '"Howdy!" he cried.'
  quoted: ' # Not a ''comment''.'
  tie-fighter: '|\-*-/|'
  )";
      test_check_emit_check(yaml, [](Tree const &t){
          EXPECT_EQ(t["single"].val()     , csubstr(R"("Howdy!" he cried.)"));
          EXPECT_EQ(t["quoted"].val()     , csubstr(R"( # Not a 'comment'.)"));
          EXPECT_EQ(t["tie-fighter"].val(), csubstr(R"(|\-*-/|)"));
      });
  }
  
  TEST(single_quoted, quotes_are_preserved)
  {
      csubstr yaml = R"(
  '%ROOT': '%VAL'
  '%ROOT2':
    - '%VAL'
    - '%VAL'
  )";
      test_check_emit_check(yaml, [](Tree const &t){
          ASSERT_TRUE(t.rootref().is_map());
          ASSERT_TRUE(t.rootref().has_child("%ROOT"));
          ASSERT_TRUE(t.rootref().has_child("%ROOT2"));
          ASSERT_EQ(t["%ROOT2"].num_children(), 2u);
          EXPECT_TRUE(t["%ROOT"].is_key_quoted());
          EXPECT_TRUE(t["%ROOT"].is_val_quoted());
          EXPECT_TRUE(t["%ROOT2"].is_key_quoted());
          EXPECT_TRUE(t["%ROOT2"][0].is_val_quoted());
          EXPECT_TRUE(t["%ROOT2"][1].is_val_quoted());
      });
  }
  
  
  //-----------------------------------------------------------------------------
  
  void verify_error_is_reported(csubstr case_name, csubstr yaml, Location loc={})
  {
      SCOPED_TRACE(case_name);
      SCOPED_TRACE(yaml);
      Tree tree;
      ExpectError::do_check(&tree, [&](){
          parse_in_arena(yaml, &tree);
      }, loc);
  }
  
  TEST(single_quoted, error_on_unmatched_quotes)
  {
      verify_error_is_reported("map block", R"(foo: '"
  bar: '')");
      verify_error_is_reported("seq block", R"(- '"
  - '')");
      verify_error_is_reported("map flow", R"({foo: '", bar: ''})");
      verify_error_is_reported("seq flow", R"(['", ''])");
  }
  
  TEST(single_quoted, error_on_unmatched_quotes_with_escapes)
  {
      verify_error_is_reported("map block", R"(foo: '''"
  bar: '')");
      verify_error_is_reported("seq block", R"(- '''"
  - '')");
      verify_error_is_reported("map flow", R"({foo: '''", bar: ''})");
      verify_error_is_reported("seq flow", R"(['''", ''])");
  }
  
  TEST(single_quoted, error_on_unmatched_quotes_at_end)
  {
      verify_error_is_reported("map block", R"(foo: ''
  bar: '")");
      verify_error_is_reported("seq block", R"(- ''
  - '")");
      verify_error_is_reported("map flow", R"({foo: '', bar: '"})");
      verify_error_is_reported("seq flow", R"(['', '"])");
  }
  
  TEST(single_quoted, error_on_unmatched_quotes_at_end_with_escapes)
  {
      verify_error_is_reported("map block", R"(foo: ''
  bar: '''")");
      verify_error_is_reported("seq block", R"(- ''
  - '''")");
      verify_error_is_reported("map flow", R"({foo: '', bar: '''"})");
      verify_error_is_reported("seq flow", R"(['', '''"])");
  }
  
  TEST(single_quoted, error_on_unclosed_quotes)
  {
      verify_error_is_reported("map block", R"(foo: ',
  bar: what)");
      verify_error_is_reported("seq block", R"(- '
  - what)");
      verify_error_is_reported("map flow", R"({foo: ', bar: what})");
      verify_error_is_reported("seq flow", R"([', what])");
  }
  
  TEST(single_quoted, error_on_unclosed_quotes_with_escapes)
  {
      verify_error_is_reported("map block", R"(foo: ''',
  bar: what)");
      verify_error_is_reported("seq block", R"(- '''
  - what)");
      verify_error_is_reported("map flow", R"({foo: ''', bar: what})");
      verify_error_is_reported("seq flow", R"([''', what])");
  }
  
  TEST(single_quoted, error_on_unclosed_quotes_at_end)
  {
      verify_error_is_reported("map block", R"(foo: what
  bar: ')");
      verify_error_is_reported("seq block", R"(- what
  - ')");
      verify_error_is_reported("map flow", R"({foo: what, bar: '})");
      verify_error_is_reported("seq flow", R"([what, '])");
  }
  
  TEST(single_quoted, error_on_unclosed_quotes_at_end_with_escapes)
  {
      verify_error_is_reported("map block", R"(foo: what
  bar: ''')");
      verify_error_is_reported("seq block", R"(- what
  - ''')");
      verify_error_is_reported("map flow", R"({foo: what, bar: '''})");
      verify_error_is_reported("seq flow", R"([what, '''])");
  }
  
  
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  //-----------------------------------------------------------------------------
  
  CASE_GROUP(SINGLE_QUOTED)
  {
  
  ADD_CASE_TO_GROUP("squoted, only text",
  R"('Some text without any quotes.'
  )",
    N(DOCVAL | VALQUO, "Some text without any quotes.")
  );
  
  ADD_CASE_TO_GROUP("squoted, with double quotes",
  R"('Some "text" "with double quotes"')",
    N(DOCVAL | VALQUO, "Some \"text\" \"with double quotes\"")
  );
  
  ADD_CASE_TO_GROUP("squoted, with single quotes",
  R"('Some text ''with single quotes''')",
    N(DOCVAL | VALQUO, "Some text 'with single quotes'")
  );
  
  ADD_CASE_TO_GROUP("squoted, with single and double quotes",
  R"('Some text ''with single quotes'' "and double quotes".')",
    N(DOCVAL | VALQUO, "Some text 'with single quotes' \"and double quotes\".")
  );
  
  ADD_CASE_TO_GROUP("squoted, with escapes",
  R"('Some text with escapes \n \r \t')",
    N(DOCVAL | VALQUO, "Some text with escapes \\n \\r \\t")
  );
  
  ADD_CASE_TO_GROUP("squoted, all",
  R"('Several lines of text,
  containing ''single quotes'' and "double quotes". Escapes (like \n) don''t do anything.
  
  Newlines can be added by leaving a blank line.
              Leading whitespace on lines is ignored.'
  )",
    N(DOCVAL | VALQUO, "Several lines of text, containing 'single quotes' and \"double quotes\". Escapes (like \\n) don't do anything.\nNewlines can be added by leaving a blank line. Leading whitespace on lines is ignored.")
  );
  
  ADD_CASE_TO_GROUP("squoted, empty",
  R"('')",
    N(DOCVAL | VALQUO, "")
  );
  
  ADD_CASE_TO_GROUP("squoted, blank",
  R"(
  - ''
  - ' '
  - '  '
  - '   '
  - '    '
  )",
    L{N(QV, ""), N(QV, " "), N(QV, "  "), N(QV, "   "), N(QV, "    ")}
  );
  
  ADD_CASE_TO_GROUP("squoted, numbers", // these should not be quoted when emitting
  R"(
  - -1
  - -1.0
  - +1.0
  - 1e-2
  - 1e+2
  )",
    L{N("-1"), N("-1.0"), N("+1.0"), N("1e-2"), N("1e+2")}
  );
  
  ADD_CASE_TO_GROUP("squoted, trailing space",
  R"('a aaaa  ')",
    N(DOCVAL | VALQUO, "a aaaa  ")
  );
  
  ADD_CASE_TO_GROUP("squoted, leading space",
  R"('  a aaaa')",
    N(DOCVAL | VALQUO, "  a aaaa")
  );
  
  ADD_CASE_TO_GROUP("squoted, trailing and leading space",
  R"('  012345  ')",
    N(DOCVAL | VALQUO, "  012345  ")
  );
  
  ADD_CASE_TO_GROUP("squoted, 1 squote",
  R"('''')",
    N(DOCVAL | VALQUO, "'")
  );
  
  ADD_CASE_TO_GROUP("squoted, 2 squotes",
  R"('''''')",
    N(DOCVAL | VALQUO, "''")
  );
  
  ADD_CASE_TO_GROUP("squoted, 3 squotes",
  R"('''''''')",
    N(DOCVAL | VALQUO, "'''")
  );
  
  ADD_CASE_TO_GROUP("squoted, 4 squotes",
  R"('''''''''')",
    N(DOCVAL | VALQUO, "''''")
  );
  
  ADD_CASE_TO_GROUP("squoted, 5 squotes",
  R"('''''''''''')",
    N(DOCVAL | VALQUO, "'''''")
  );
  
  /*
  ADD_CASE_TO_GROUP("squoted, example 2",
  R"('This is a key
  
  that has multiple lines
  
  ': and this is its value
  )",
    L{N("This is a key\nthat has multiple lines\n", "and this is its value")}
  );
  */
  }
  
  } // namespace yml
  } // namespace c4
  