Echo Writes Code

test_text.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include "crucible/parsing/text.hpp"

#include "crucible/test/expect.hpp"
#include "crucible/test/scenario.hpp"

#include <string_view>

namespace crucible::parsing::test_text {
  constexpr char8_t FOO_DATA[] = u8"FOO";

  constexpr char8_t FOB_DATA[] = u8"FOB";

  SCENARIO(text_parse_state) {
    std::u8string_view const input = FOO_DATA;
    text::TextState const initial_state(input);

    {
      auto const remaining_code_units = initial_state.get_remaining_code_units_in_input();
      auto const expected_code_units = input;
      EXPECT(std::equal(remaining_code_units.begin(), remaining_code_units.end(), expected_code_units.begin(), expected_code_units.end()));
    }

    auto next_state = initial_state.advance_by_code_units(1);

    {
      auto const remaining_code_units = next_state.get_remaining_code_units_in_input();
      auto const expected_code_units = input.substr(1);
      EXPECT(std::equal(remaining_code_units.begin(), remaining_code_units.end(), expected_code_units.begin(), expected_code_units.end()));
    }

    next_state = next_state.advance_by_code_units(2);
    EXPECT(next_state.is_finished());
  }

  SCENARIO(text_character_sequence_accept) {
    text::TextState const initial_state(FOO_DATA);
    text::CharacterSequence const parse_FOO(FOO_DATA);

    auto const result = parse_FOO(initial_state);
    EXPECT_SUCCESS(result);

    auto const &accept = result.get_success();
    auto const &final_state = accept.get_state();
    EXPECT(final_state.is_finished());
  }

  SCENARIO(text_character_sequence_reject) {
    text::TextState const initial_state(FOB_DATA);
    text::CharacterSequence const parse_FOO(FOO_DATA);

    auto const result = parse_FOO(initial_state);
    EXPECT_FAILURE(result);

    auto const &reject = result.get_failure();
    auto const &final_state = reject.get_state();
    auto const &initial_code_units = initial_state.get_remaining_code_units_in_input();
    auto const &remaining_code_units = final_state.get_remaining_code_units_in_input();
    EXPECT_EQ(initial_code_units.size(), remaining_code_units.size());

    auto const &error = reject.get_error();
    EXPECT(error.has_cause<text::CharacterSequenceMismatch>());
  }
}