KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_sexpr_parser.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
28
30
31// Code under test
32#include <sexpr/sexpr_parser.h>
33
34#include "sexpr_test_utils.h"
35
37{
38public:
42 std::unique_ptr<SEXPR::SEXPR> Parse( const std::string& aIn )
43 {
44 return std::unique_ptr<SEXPR::SEXPR>( m_parser.Parse( aIn ) );
45 }
46
48};
49
50
56{
57 std::string m_case_name;
58 std::string m_sexpr_data;
59};
60
61
65BOOST_FIXTURE_TEST_SUITE( SexprParser, TEST_SEXPR_PARSER_FIXTURE )
66
67
71{
72 const std::vector<TEST_SEXPR_CASE> cases = {
73 {
74 "Empty string",
75 "",
76 },
77 {
78 "whitespace",
79 " ",
80 },
81 };
82
83 for( const auto& c : cases )
84 {
85 BOOST_TEST_CONTEXT( c.m_case_name )
86 {
87 const auto data = Parse( c.m_sexpr_data );
88 BOOST_CHECK_EQUAL( data.get(), nullptr );
89 }
90 }
91}
92
97{
98 const std::string content{ "this is just writing" };
99 const auto sexp = Parse( content );
100
101 BOOST_REQUIRE_NE( sexp.get(), nullptr );
103}
104
108BOOST_AUTO_TEST_CASE( ParseExceptions )
109{
110 const std::vector<TEST_SEXPR_CASE> cases = {
111 {
112 "Unclosed (symbol",
113 "(symbol",
114 },
115 {
116 "Comma",
117 ",",
118 },
119 {
120 "Int only",
121 "1",
122 },
123 {
124 "Double only",
125 "3.14",
126 },
127 {
128 "Symbol only",
129 "symbol",
130 },
131 // { // this is OK for some reason
132 // "String only",
133 // "\"string\"",
134 // },
135 };
136
137 for( const auto& c : cases )
138 {
139 BOOST_TEST_CONTEXT( c.m_case_name )
140 {
141 BOOST_CHECK_THROW( Parse( c.m_sexpr_data ), SEXPR::PARSE_EXCEPTION );
142 }
143 }
144}
145
150{
151 const std::string content{ "()" };
152 const auto sexp = Parse( content );
153
154 BOOST_REQUIRE_NE( sexp.get(), nullptr );
156}
157
161BOOST_AUTO_TEST_CASE( SimpleSymbol )
162{
163 const std::string content{ "(symbol)" };
164 const auto sexp = Parse( content );
165
166 BOOST_REQUIRE_NE( sexp.get(), nullptr );
167 BOOST_REQUIRE_PREDICATE( KI_TEST::SexprIsListOfLength, ( *sexp )( 1 ) );
168
169 const SEXPR::SEXPR& child = *sexp->GetChild( 0 );
171}
172
176BOOST_AUTO_TEST_CASE( SymbolString )
177{
178 const std::string content{ "(symbol \"string\" 42 3.14 (nested 4 ()))" };
179 const auto sexp = Parse( content );
180
181 BOOST_REQUIRE_NE( sexp.get(), nullptr );
182 BOOST_REQUIRE_PREDICATE( KI_TEST::SexprIsListOfLength, ( *sexp )( 5 ) );
183
184 BOOST_CHECK_PREDICATE( KI_TEST::SexprIsSymbolWithValue, ( *sexp->GetChild( 0 ) )( "symbol" ) );
185 BOOST_CHECK_PREDICATE( KI_TEST::SexprIsStringWithValue, ( *sexp->GetChild( 1 ) )( "string" ) );
186 BOOST_CHECK_PREDICATE( KI_TEST::SexprIsIntegerWithValue, ( *sexp->GetChild( 2 ) )( 42 ) );
187 BOOST_CHECK_PREDICATE( KI_TEST::SexprIsDoubleWithValue, ( *sexp->GetChild( 3 ) )( 3.14 ) );
188
189 // and child list
190 const SEXPR::SEXPR& sublist = *sexp->GetChild( 4 );
191 BOOST_REQUIRE_PREDICATE( KI_TEST::SexprIsListOfLength, ( sublist )( 3 ) );
193 KI_TEST::SexprIsSymbolWithValue, ( *sublist.GetChild( 0 ) )( "nested" ) );
196}
197
198
205{
206 std::string m_case_name;
207 std::string m_input;
208};
209
210BOOST_AUTO_TEST_CASE( StringRoundtrip )
211{
212 const std::vector<TEST_SEXPR_ROUNDTRIPPING> cases = {
213 {
214 "empty list",
215 "()",
216 },
217 {
218 "simple list",
219 "(42 3.14 \"string\")",
220 },
221 {
222 "nested list", // REVIEW space after 42?
223 "(42 \n (1 2))",
224 },
225 };
226
227 for( const auto& c : cases )
228 {
229 BOOST_TEST_CONTEXT( c.m_case_name )
230 {
231 const auto sexp = Parse( c.m_input );
232
233 const std::string as_str = sexp->AsString();
234
235 BOOST_CHECK_PREDICATE( KI_TEST::SexprConvertsToString, ( *sexp )( c.m_input ) );
236 }
237 }
238}
239
SEXPR * GetChild(size_t aIndex) const
Definition sexpr.cpp:49
std::unique_ptr< SEXPR::SEXPR > Parse(const std::string &aIn)
Wrap the parser function with a unique_ptr.
bool SexprIsSymbolWithValue(const SEXPR::SEXPR &aSexpr, const std::string &aVal)
Test predicate: is the s-expression a symbol with the given value?
bool SexprIsDoubleWithValue(const SEXPR::SEXPR &aSexpr, double aVal)
Test predicate: is the s-expression a double with the given value?
bool SexprIsListOfLength(const SEXPR::SEXPR &aSexpr, size_t aExpectedLength)
Test predicate: is the s-expression a list with the given length?
bool SexprIsIntegerWithValue(const SEXPR::SEXPR &aSexpr, std::int64_t aVal)
Test predicate: is the s-expression an integer with the given value?
bool SexprIsStringWithValue(const SEXPR::SEXPR &aSexpr, const std::string &aVal)
Test predicate: is the s-expression a string with the given value?
bool SexprConvertsToString(const SEXPR::SEXPR &aSexpr, const std::string &aExpStr)
Predicate to check an SEXPR object converts to the expected string.
Collection of test cases for use when multiple cases can be handled in the same test case.
Test for roundtripping (valid) s-expression back to strings.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(Empty)
Declare the test suite.
BOOST_CHECK_PREDICATE(ArePolylineEndPointsNearCircle,(chain)(c.m_geom.m_center_point)(radius)(accuracy+epsilon))
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_CHECK_EQUAL(result, "25.4")