-
Notifications
You must be signed in to change notification settings - Fork 189
Expand file tree
/
Copy pathMapParserTests.cpp
More file actions
158 lines (123 loc) · 5.04 KB
/
Copy pathMapParserTests.cpp
File metadata and controls
158 lines (123 loc) · 5.04 KB
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <catch2/catch.hpp>
#include <rapidcheck/catch.h>
#include "detail/MapParser.h"
#include "detail/ParseException.h"
using namespace rc;
using namespace rc::detail;
TEST_CASE("parseMap") {
SECTION("parses empty string (or only whitespace) as empty map") {
REQUIRE(parseMap("").empty());
REQUIRE(parseMap("\n\t ").empty());
}
SECTION("parses basic maps") {
auto map = parseMap("foo=bar baz=1337");
std::map<std::string, std::string> expected = {{"foo", "bar"},
{"baz", "1337"}};
REQUIRE(map == expected);
}
SECTION("ignores whitespace") {
auto map = parseMap(" \n foo = bar \t baz = 1337 ");
std::map<std::string, std::string> expected = {{"foo", "bar"},
{"baz", "1337"}};
REQUIRE(map == expected);
}
SECTION("parses keys not followed by '=' as missing value") {
auto map = parseMap("foo=bar baz");
REQUIRE(map["baz"] == "");
}
SECTION("parses empty values") {
auto map = parseMap("foo=bar baz=");
REQUIRE(map["baz"] == "");
}
SECTION("parses double quoted string values") {
auto map = parseMap("foo=bar baz=\"testing 1 2 3 \" stuff=cool");
REQUIRE(map["baz"] == "testing 1 2 3 ");
}
SECTION("parses single quoted string values") {
auto map = parseMap("foo=bar baz='testing 1 2 3 ' stuff=cool");
REQUIRE(map["baz"] == "testing 1 2 3 ");
}
SECTION("allows escaping of quotes in double quoted strings") {
auto map = parseMap("foo=bar baz=\"quote \\\"some\\\" stuff\" stuff=cool");
REQUIRE(map["baz"] == "quote \"some\" stuff");
}
SECTION("allows escaping of quotes in single quoted strings") {
auto map = parseMap("foo=bar baz='quote \\'some\\' stuff' stuff=cool");
REQUIRE(map["baz"] == "quote 'some' stuff");
}
SECTION("allows escaping of backslash in double quoted strings") {
auto map = parseMap("foo=bar baz=\"this\\\\that\" stuff=cool");
REQUIRE(map["baz"] == "this\\that");
}
SECTION("allows escaping of backslash in single quoted strings") {
auto map = parseMap("foo=bar baz='this\\\\that' stuff=cool");
REQUIRE(map["baz"] == "this\\that");
}
SECTION("allows escaping of normal characters in double quoted string") {
auto map = parseMap("foo=bar baz=\"\\f\\o\\o\\b\\a\\r\" stuff=cool");
REQUIRE(map["baz"] == "foobar");
}
SECTION("allows escaping of normal characters in single quoted string") {
auto map = parseMap("foo=bar baz='\\f\\o\\o\\b\\a\\r' stuff=cool");
REQUIRE(map["baz"] == "foobar");
}
SECTION("allows double quoted keys") {
auto map = parseMap(" \"\\\"this=\\\\=that\\\"\"=foobar");
REQUIRE(map["\"this=\\=that\""] == "foobar");
}
SECTION("allows single quoted keys") {
auto map = parseMap(" '\\'this=\\\\=that\\''=foobar");
REQUIRE(map["'this=\\=that'"] == "foobar");
}
SECTION("if there are duplicate keys, the last value takes precedence") {
auto map = parseMap("foo=this foo=that");
REQUIRE(map["foo"] == "that");
}
SECTION("throws ParseException on unterminated double quoted string") {
REQUIRE_THROWS_AS(parseMap("foo=\"bar"), ParseException);
}
SECTION("throws ParseException on unterminated single quoted string") {
REQUIRE_THROWS_AS(parseMap("foo='bar"), ParseException);
}
}
TEST_CASE("mapToString") {
prop("parseMap(mapToString(x)) == x",
[](const std::map<std::string, std::string> &map) {
RC_PRE(map.find("") == map.end());
RC_ASSERT(parseMap(mapToString(map)) == map);
});
SECTION("does not quote strings that do not contains special chars") {
std::map<std::string, std::string> map{{"foobar", "barfoo"}};
REQUIRE(mapToString(map) == "foobar=barfoo");
}
SECTION("quotes strings that contain whitespace") {
std::map<std::string, std::string> map{{"foo bar", "bar\tfoo"}};
REQUIRE(mapToString(map) == "'foo bar'='bar\tfoo'");
}
SECTION("quotes strings that contain '='") {
std::map<std::string, std::string> map{{"foo=bar", "bar=foo"}};
REQUIRE(mapToString(map) == "'foo=bar'='bar=foo'");
}
SECTION("if string contains single quotes") {
std::map<std::string, std::string> map{{"foo'bar", "bar'foo"}};
SECTION("quotes and escapes if using single quoting") {
REQUIRE(mapToString(map, false) == "'foo\\'bar'='bar\\'foo'");
}
SECTION("quotes but does not escape if using double quoting") {
REQUIRE(mapToString(map, true) == "\"foo'bar\"=\"bar'foo\"");
}
}
SECTION("if string contains double quotes") {
std::map<std::string, std::string> map{{"foo\"bar", "bar\"foo"}};
SECTION("quotes and escapes if using double quoting") {
REQUIRE(mapToString(map, true) == "\"foo\\\"bar\"=\"bar\\\"foo\"");
}
SECTION("quotes but does not escape if using single quoting") {
REQUIRE(mapToString(map, false) == "'foo\"bar'='bar\"foo'");
}
}
SECTION("quotes and escapes strings that contains backslashes") {
std::map<std::string, std::string> map{{"foo\\bar", "bar\\foo"}};
REQUIRE(mapToString(map) == "'foo\\\\bar'='bar\\\\foo'");
}
}