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/testing/expect.inl"
#include "crucible/testing/suite.hpp"

#include <string_view>

namespace crucible::parsing::test_text {
  constexpr char const FOO_DATA[] = "FOO";

  constexpr char const FOB_DATA[] = "FOB";

  SCENARIO(text, parse_state) {
    std::string_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_CONTAINER_EQ(remaining_code_units, expected_code_units);
    }

    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_CONTAINER_EQ(remaining_code_units, expected_code_units);
    }

    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_RHS(result);

    auto const &accept { result.get_rhs() };
    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_LHS(result);

    auto const &reject { result.get_lhs() };
    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.is<errors::UnexpectedInput>());
  }
}