• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ossia / score / 30507431705

30 Jul 2026 02:04AM UTC coverage: 15.263% (-0.06%) from 15.321%
30507431705

push

github

jcelerier
audio: simplify pretty name for Default device

0 of 2 new or added lines in 1 file covered. (0.0%)

1386 existing lines in 18 files now uncovered.

30460 of 199565 relevant lines covered (15.26%)

1075.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.57
/src/plugins/score-lib-state/Tests/ExpressionParsingTests.cpp
1
// This is an open source non-commercial project. Dear PVS-Studio, please check
2
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
3

4
/*
5
bool checkLeaves(const State::Expression* e)
6
{
7
    auto c = e->children(); // TODO see why this isn't a const ref return.
8
    if(c.isEmpty())
9
    {
10
        return e->is<State::Relation>();
11
    }
12
    else
13
    {
14
        return std::all_of(
15
                    c.cbegin(), c.cend(),
16
                    [] (auto e) {
17
            return checkLeaves(e);
18
        });
19
    }
20
}
21

22
bool validate(const State::Expression& expr)
23
{
24
    // Check that all the leaves are relations.
25
    return checkLeaves(&expr);
26
}
27
*/
28
#define CATCH_CONFIG_MAIN
29
#include "Utils.hpp"
30

31
#include <State/Expression.hpp>
32
#include <State/ExpressionParser.hpp>
33

34
#include <ossia/network/common/destination_qualifiers.hpp>
35

36
#include <ossia-qt/js_utilities.hpp>
37

38
#include <QDebug>
39
#include <QObject>
40
#include <QString>
41

42
#include <catch2/catch_all.hpp>
43

44
using namespace score;
45
#include <State/ValueConversion.hpp>
46

47
#include <list>
48
#include <string>
49
#include <vector>
50

51
/*
52
TEST_CASE("test_parse_expr", "test_parse_expr")
53
{
54
    for (auto& input : std::list<std::string> {
55
         "(dev:/minuit <= 5) and (a:/b == 1.34);",
56
         "(dev:/minuit != [1, 2, 3.12, 'c']) and not (a:/b >= c:/d/e/f);"
57
   })
58
    {
59
        auto f(std::begin(input)), l(std::end(input));
60
        parser<decltype(f)> p;
61

62
        try
63
        {
64
            expr result;
65
            bool ok = qi::phrase_parse(f,l,p > ';',qi::space,result);
66

67
            if (!ok)
68
                qDebug() << "invalid input\n";
69
            //else
70
            //    qDebug() << "result: " << result << "\n";
71

72
        } catch (const qi::expectation_failure<decltype(f)>& e)
73
        {
74
            qDebug() << "expectation_failure at '" <<
75
QString::fromStdString(std::string(e.first, e.last)) << "'\n";
76
        }
77

78
        if (f!=l) qDebug() << "unparsed: '" <<
79
QString::fromStdString(std::string(f,l)) << "'\n";
80
    }
81

82
    exit(0);
83
}*/
84

85
// TODO move me
86
QDebug operator<<(QDebug dbg, const State::Address& a);
87
QDebug operator<<(QDebug dbg, const State::RelationMember& v);
88
QDebug operator<<(QDebug dbg, const ossia::expressions::comparator& v);
89
QDebug operator<<(QDebug dbg, const State::Relation& v);
90
QDebug operator<<(QDebug dbg, const State::BinaryOperator& v);
91
QDebug operator<<(QDebug dbg, const State::UnaryOperator& v);
92
QDebug operator<<(QDebug dbg, const State::ExprData& v);
93
QDebug operator<<(QDebug dbg, const State::Expression& v);
94

UNCOV
95
QDebug operator<<(QDebug dbg, const State::Address& a)
×
96
{
UNCOV
97
  dbg << a.toString();
×
UNCOV
98
  return dbg;
×
UNCOV
99
}
×
100

UNCOV
101
QDebug operator<<(QDebug dbg, const State::RelationMember& v)
×
102
{
UNCOV
103
  dbg << State::toString(v);
×
104
  return dbg;
×
UNCOV
105
}
×
106

107
QDebug operator<<(QDebug dbg, const ossia::expressions::comparator& v)
×
108
{
UNCOV
109
  switch(v)
×
110
  {
111
    case ossia::expressions::comparator::DIFFERENT:
112
      dbg << "!=";
×
113
      break;
×
114
    case ossia::expressions::comparator::EQUAL:
UNCOV
115
      dbg << "==";
×
116
      break;
×
117
    case ossia::expressions::comparator::GREATER:
118
      dbg << ">";
×
UNCOV
119
      break;
×
120
    case ossia::expressions::comparator::GREATER_EQUAL:
121
      dbg << ">=";
×
122
      break;
×
123
    case ossia::expressions::comparator::LOWER:
124
      dbg << "<";
×
125
      break;
×
126
    case ossia::expressions::comparator::LOWER_EQUAL:
127
      dbg << "<=";
×
128
      break;
×
129
  }
130
  return dbg;
×
131
}
132

133
QDebug operator<<(QDebug dbg, const State::Relation& v)
×
134
{
UNCOV
135
  dbg << v.lhs << v.op << v.rhs;
×
136
  return dbg;
×
137
}
×
138

139
QDebug operator<<(QDebug dbg, const State::BinaryOperator& v)
×
140
{
UNCOV
141
  switch(v)
×
142
  {
143
    case State::BinaryOperator::AND:
144
      dbg << "and";
×
145
      break;
×
146
    case State::BinaryOperator::OR:
UNCOV
147
      dbg << "or";
×
148
      break;
×
149
    case State::BinaryOperator::XOR:
150
      dbg << "xor";
×
UNCOV
151
      break;
×
152
    default:
153
      dbg << "none";
×
154
      break;
×
155
  }
156
  return dbg;
×
157
}
158

159
QDebug operator<<(QDebug dbg, const State::UnaryOperator& v)
×
160
{
UNCOV
161
  switch(v)
×
162
  {
163
    case State::UnaryOperator::Not:
UNCOV
164
      dbg << "not";
×
165
      break;
×
166
    default:
UNCOV
167
      dbg << "none";
×
168
      break;
×
169
  }
170
  return dbg;
×
171
}
172

173
QDebug operator<<(QDebug dbg, const State::ExprData& v)
38✔
174
{
175
  return dbg << v.toString();
38✔
176
}
×
177

178
QDebug operator<<(QDebug dbg, const State::Expression& v)
38✔
179
{
180
  dbg << "{";
38✔
181
  dbg << static_cast<const State::ExprData&>(v);
38✔
182
  for(auto& child : v.children())
66✔
183
  {
184
    dbg << child;
28✔
185
  }
186
  dbg << "}";
38✔
187
  return dbg;
38✔
UNCOV
188
}
×
189

190
static void debug_path(std::optional<State::AddressAccessor> addr)
4✔
191
{
192
  qDebug() << addr->toString();
4✔
193
}
4✔
194
static void debug_path(std::optional<State::Address> addr)
4✔
195
{
196
  qDebug() << addr->toString();
4✔
197
}
4✔
198
using namespace score;
199
TEST_CASE("test_parse_impulse", "test_parse_impulse")
2✔
200
{
201

202
  {
203
    std::string str("%minuit:/device/lol% impulse");
1✔
204

205
    typedef std::string::const_iterator iterator_type;
206
    Pulse_parser<iterator_type> parser;
1✔
207
    auto first = str.cbegin(), last = str.cend();
1✔
208
    State::Pulse p;
1✔
209
    bool r = parse(first, last, parser, p);
1✔
210

211
    REQUIRE(r);
1✔
212
  }
1✔
213

214
  {
215
    std::string str("{ %minuit:/device/lol% impulse }");
1✔
216

217
    typedef std::string::const_iterator iterator_type;
218
    Pulse_parser<iterator_type> parser;
1✔
219
    auto first = str.cbegin(), last = str.cend();
1✔
220
    State::Pulse p;
1✔
221
    bool r = parse(first, last, parser, p);
1✔
222

223
    REQUIRE(r);
1✔
224
  }
1✔
225

226
  {
227
    QString str("%minuit:/device/lol% impulse");
1✔
228

229
    auto expr = State::parseExpression(str);
1✔
230

231
    REQUIRE(bool(expr) == true);
1✔
232
  }
1✔
233

234
  {
235
    QString str("{ %minuit:/device/lol% impulse }");
1✔
236

237
    auto expr = State::parseExpression(str);
1✔
238

239
    REQUIRE(bool(expr) == true);
1✔
240
  }
1✔
241
}
1✔
242

243
TEST_CASE("test_parse_array", "test_parse_array")
2✔
244
{
245

246
  {
247
    std::string str("minuit:/device/lol@[7]");
1✔
248

249
    typedef std::string::const_iterator iterator_type;
250
    AddressAccessor_parser<iterator_type> parser;
1✔
251
    auto first = str.cbegin(), last = str.cend();
1✔
252
    State::AddressAccessor p;
1✔
253
    bool r = parse(first, last, parser, p);
1✔
254

255
    REQUIRE(r);
1✔
256
    REQUIRE(p.address.toString() == "minuit:/device/lol");
1✔
257
    REQUIRE(p.qualifiers.get().accessors.size() == 1);
1✔
258
    REQUIRE(p.qualifiers.get().accessors[0] == 7);
1✔
259
  }
1✔
260

261
  {
262
    std::string str("%minuit:/device/lol@[7]%");
1✔
263

264
    typedef std::string::const_iterator iterator_type;
265
    RelationMember_parser<iterator_type> parser;
1✔
266
    auto first = str.cbegin(), last = str.cend();
1✔
267
    State::RelationMember rm;
1✔
268
    bool r = parse(first, last, parser, rm);
1✔
269

270
    REQUIRE(r);
1✔
271
    REQUIRE(rm.which() == State::RelationMember::index_of<State::AddressAccessor>());
1✔
272
    auto& p = ossia::get<State::AddressAccessor>(rm);
1✔
273
    REQUIRE(p.address.toString() == "minuit:/device/lol");
1✔
274
    REQUIRE(p.qualifiers.get().accessors.size() == 1);
1✔
275
    REQUIRE(p.qualifiers.get().accessors[0] == 7);
1✔
276
  }
1✔
277

278
  {
279
    QString str("{ %minuit:/device/lol@[1][2]% < 3.14 }");
1✔
280

281
    auto expr = State::parseExpression(str);
1✔
282

283
    REQUIRE(bool(expr) == true);
1✔
284
  }
1✔
285
}
1✔
286

287
TEST_CASE("test_parse_dataspace", "test_parse_dataspace")
2✔
288
{
289
  {
290
    std::string str("minuit:/device/lol@[color.rgb]");
1✔
291

292
    typedef std::string::const_iterator iterator_type;
293
    AddressAccessor_parser<iterator_type> parser;
1✔
294
    auto first = str.cbegin(), last = str.cend();
1✔
295
    State::AddressAccessor p;
1✔
296
    bool r = parse(first, last, parser, p);
1✔
297

298
    REQUIRE(r);
1✔
299
    REQUIRE(p.address.toString() == "minuit:/device/lol");
1✔
300
    REQUIRE(p.qualifiers.get().accessors.size() == 0);
1✔
301
    REQUIRE(p.qualifiers.get().unit == ossia::rgb_u{});
1✔
302
  }
1✔
303

304
  {
305
    std::string str("minuit:/device/lol@[color.hsv.s]");
1✔
306

307
    typedef std::string::const_iterator iterator_type;
308
    AddressAccessor_parser<iterator_type> parser;
1✔
309
    auto first = str.cbegin(), last = str.cend();
1✔
310
    State::AddressAccessor p;
1✔
311
    bool r = parse(first, last, parser, p);
1✔
312

313
    REQUIRE(r);
1✔
314
    REQUIRE(p.address.toString() == "minuit:/device/lol");
1✔
315

316
    REQUIRE(p.qualifiers.get().unit == ossia::hsv_u{});
1✔
317

318
    REQUIRE(p.qualifiers.get().accessors.size() == 1);
1✔
319
    REQUIRE(p.qualifiers.get().accessors[0] == 1);
1✔
320
  }
1✔
321

322
  {
323
    QString str("{ %minuit:/device/lol@[color.rgb]% < 3.14}");
1✔
324

325
    auto expr = State::parseExpression(str);
1✔
326

327
    REQUIRE(bool(expr) == true);
1✔
328
  }
1✔
329
}
1✔
330

331
TEST_CASE("test_parse_addr", "test_parse_addr")
2✔
332
{
333
  using namespace qi;
334

335
  {
336
    std::string str("minuit:/device/lol");
1✔
337

338
    typedef std::string::const_iterator iterator_type;
339
    using ascii::space;
340
    using qi::parse;
341

342
    Address_parser<iterator_type> parser;
343
    auto first = str.cbegin(), last = str.cend();
344
    State::Address addr;
345
    bool r = parse(first, last, parser, addr);
346

347
    qDebug() << "parsed?" << r;
348
    qDebug() << addr.device;
349
    for(auto& elt : addr.path)
3✔
350
      qDebug() << elt;
2✔
351
  }
1✔
352

353
  {
354
    std::string str("%minuit:/device/lol%");
1✔
355

356
    typedef std::string::const_iterator iterator_type;
357
    RelationMember_parser<iterator_type> parser;
1✔
358
    auto first = str.cbegin(), last = str.cend();
1✔
359
    State::RelationMember rm;
1✔
360
    bool r = parse(first, last, parser, rm);
1✔
361

362
    REQUIRE(r);
1✔
363
    REQUIRE(rm.which() == State::RelationMember::index_of<State::Address>());
1✔
364
    auto& p = ossia::get<State::Address>(rm);
1✔
365
    REQUIRE(p.toString() == "minuit:/device/lol");
1✔
366
  }
1✔
367
}
1✔
368

369
TEST_CASE("test_parse_value", "test_parse_value")
2✔
370
{
371
  std::vector<std::string> str_list{
1✔
372
      "[1,2,3]", "[1]",  "[ 1 ]", "[ 1, 2, 3 ]", "[ 1, 2.3, 3, 'c' ]",
1✔
373
      "1",       "1.23", "'c'",   "\"lala\"",    "\"lala lala\""};
1✔
374

375
  for(const auto& str : str_list)
11✔
376
  {
377

378
    typedef std::string::const_iterator iterator_type;
379
    using qi::parse;
380

381
    Value_parser<iterator_type> parser;
10✔
382
    auto first = str.cbegin(), last = str.cend();
10✔
383
    ossia::value val;
10✔
384
    bool r = parse(first, last, parser, val);
10✔
385

386
    qDebug() << str.c_str() << r << val << "                    ";
10✔
387
  }
10✔
388
}
1✔
389

390
TEST_CASE("test_parse_rel_member", "test_parse_rel_member")
2✔
391
{
392
  std::vector<std::string> str_list{
1✔
393
      "minuit:/device"
1✔
394
      "1234"};
395

396
  for(const auto& str : str_list)
2✔
397
  {
398
    typedef std::string::const_iterator iterator_type;
399
    using qi::parse;
400

401
    RelationMember_parser<iterator_type> parser;
1✔
402
    auto first = str.cbegin(), last = str.cend();
1✔
403
    State::RelationMember val;
1✔
404
    bool r = parse(first, last, parser, val);
1✔
405

406
    qDebug() << str.c_str() << r;
1✔
407
  }
1✔
408
}
1✔
409

410
TEST_CASE("test_parse_rel", "test_parse_rel")
2✔
411
{
412
  std::vector<std::string> str_list{
1✔
413
      "%minuit:/device%<=1234", "%minuit:/device% <= 1234"};
1✔
414

415
  for(const auto& str : str_list)
3✔
416
  {
417
    typedef std::string::const_iterator iterator_type;
418
    using qi::parse;
419

420
    Relation_parser<iterator_type> parser;
2✔
421
    auto first = str.cbegin(), last = str.cend();
2✔
422
    State::Relation val;
2✔
423
    bool r = parse(first, last, parser, val);
2✔
424

425
    qDebug() << str.c_str() << r << val.lhs.target<State::Address>()->path
4✔
426
             << State::convert::toPrettyString(*val.rhs.target<ossia::value>());
2✔
427
  }
2✔
428
}
1✔
429

430
TEST_CASE("test_parse_expr_full", "test_parse_expr_full")
2✔
431
{
432
  for(auto& input : std::list<std::string>{
7✔
433
          "%dev:/minuit% != [1, 2, 3.12, 'c'];",
1✔
434
          "{ %dev:/minuit% != [1, 2, 3.12, 'c'] };", "%a:/b% >= %c:/d/e/f%;",
1✔
435
          "{ %a:/b% >= %c:/d/e/f% };",
1✔
436
          "{ %dev:/minuit% != [1, 2, 3.12, 'c']} and not "
1✔
437
          "{ %a:/b% >= %c:/d/e/f% };",
438
          "{ { %dev:/minuit% != [1, 2, 3.12, 'c'] } and "
1✔
439
          "not { %a:/b% >= %c:/d/e/f% } };"})
440
  {
441
    auto f(std::begin(input)), l(std::end(input));
6✔
442
    Expression_parser<decltype(f)> p;
6✔
443

444
    try
445
    {
446
      expr_raw result;
6✔
447
      bool ok = qi::phrase_parse(f, l, p > ';', qi::space, result);
6✔
448

449
      if(!ok)
6✔
450
      {
UNCOV
451
        qDebug() << "invalid input\n";
×
UNCOV
452
        continue;
×
453
      }
454

455
      State::Expression e;
6✔
456

457
      Expression_builder bldr{&e};
6✔
458
      boost::apply_visitor(bldr, result);
6✔
459
      qDebug() << e;
6✔
460

461
      std::cout << std::flush;
6✔
462
    }
6✔
463
    catch(const qi::expectation_failure<decltype(f)>& e)
464
    {
465
      using namespace std::literals;
UNCOV
466
      std::cerr << input << std::string(" : expectation_failure at '")
×
UNCOV
467
                << std::string(e.first, e.last) << std::string("'\n");
×
UNCOV
468
      REQUIRE(false);
×
UNCOV
469
    }
×
470

471
    // if (f!=l) std::cerr << "unparsed: '" << std::string(f,l) << "'\n";
472
  }
6✔
473

474
  // return 0;
475
}
1✔
476

477
TEST_CASE("test_parse_expr_multi", "test_parse_expr_multi")
2✔
478
{
479
  for(auto& input : std::list<std::string>{
5✔
480
          "{ %a:/b% != 1 };", "{ { %a:/b% != 1 } and { %a:/b% != 2 } };",
1✔
481
          "{ { %a:/b% != 1 } and { %a:/b% != 2 } and { %a:/b% != 3 } };",
1✔
482
          "{ { %a:/b% != 1 } and { %a:/b% != 2 } and { %a:/b% != 3 } and { "
1✔
483
          "%a:/b% != 4 } };"})
484
  {
485
    auto f(std::begin(input)), l(std::end(input));
4✔
486
    Expression_parser<decltype(f)> p;
4✔
487

488
    try
489
    {
490
      expr_raw result;
4✔
491
      bool ok = qi::phrase_parse(f, l, p > ';', qi::space, result);
4✔
492

493
      if(!ok)
4✔
494
      {
UNCOV
495
        qDebug() << "invalid input\n";
×
UNCOV
496
        continue;
×
497
      }
498

499
      State::Expression e;
4✔
500

501
      Expression_builder bldr{&e};
4✔
502
      boost::apply_visitor(bldr, result);
4✔
503
      qDebug() << e;
4✔
504

505
      std::cout << std::flush;
4✔
506
    }
4✔
507
    catch(const qi::expectation_failure<decltype(f)>& e)
508
    {
509
      using namespace std::literals;
UNCOV
510
      std::cerr << input << std::string(" : expectation_failure at '")
×
UNCOV
511
                << std::string(e.first, e.last) << std::string("'\n");
×
UNCOV
512
      REQUIRE(false);
×
UNCOV
513
    }
×
514

515
    // if (f!=l) std::cerr << "unparsed: '" << std::string(f,l) << "'\n";
516
  }
4✔
517

518
  // return 0;
519
}
1✔
520
TEST_CASE("test_address_dot_in_instances", "test_address_dot_in_instances")
2✔
521
{
522
  debug_path(State::parseAddressAccessor("myapp:/score/color.1@[color.rgb.r]"));
1✔
523
  debug_path(State::parseAddressAccessor("myapp:/score/color.1"));
1✔
524
  debug_path(State::parseAddressAccessor("myapp:/score/color@[color.rgb.r]"));
1✔
525
  debug_path(State::parseAddressAccessor("myapp:/score/color.1@[color.rgb]"));
1✔
526

527
  debug_path(State::parseAddress("myapp:/score/color.1@[color.rgb.r]"));
1✔
528
  debug_path(State::parseAddress("myapp:/score/color.1"));
1✔
529
  debug_path(State::parseAddress("myapp:/score/color@[color.rgb.r]"));
1✔
530
  debug_path(State::parseAddress("myapp:/score/color.1@[color.rgb]"));
1✔
531
}
1✔
532

533
TEST_CASE("test_parse_random", "test_parse_random")
2✔
534
{
535
  using namespace std::literals;
536
  REQUIRE(bool(State::parseAddressAccessor("myapp:/score/color.1@[color.rgb.r]")));
1✔
537
  REQUIRE(bool(State::parseExpression("{ %myapp:/score% > 2}"s)));
1✔
538
  REQUIRE(bool(State::parseExpression("{2 > %myapp:/stagescore% }"s)));
1✔
539
  REQUIRE(bool(State::parseExpression("{ %myapp:/score% > %myapp:/stagescore% }"s)));
1✔
540
  REQUIRE(bool(State::parseExpression("{ %myapp:/score% >= %myapp:/stagescore% }"s)));
1✔
541
  REQUIRE(bool(State::parseExpression("{ %my_app:/score% > %my_app:/stagescore% }"s)));
1✔
542
  REQUIRE(bool(State::parseExpression("{ %my_app:/score% > %my_app:/stage_score% }"s)));
1✔
543
  REQUIRE(bool(State::parseExpression("{ %my_app:/score% > %my_app:/stage_score% }"s)));
1✔
544
  REQUIRE(
1✔
545
      bool(State::parseExpression("{ { %A:/B% > %c:/D% } and { %e:/f% > %g:/h% } }"s)));
546
}
1✔
547

548
// TEST_CASE("test_parse_patternmatch", "test_parse_patternmatch")
549
//{
550
//  using namespace std::literals;
551
//
552
//  REQUIRE(bool(State::TraversalPath::make_path("myapp:/score")));
553
//  REQUIRE(bool(State::TraversalPath::make_path("myapp:/score.")));
554
//  REQUIRE(bool(State::TraversalPath::make_path("myapp:/score.*")));
555
//  REQUIRE(bool(State::TraversalPath::make_path("../score/blop")));
556
//  REQUIRE(bool(
557
//      State::TraversalPath::make_path("myapp:/score.*/[a-z]*/{blurg}")));
558
//  REQUIRE(bool(State::TraversalPath::make_path("//score")));
559
//  REQUIRE(bool(State::TraversalPath::make_path("//score/blop")));
560
//}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc