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

ossia / libossia / 30501467811

30 Jul 2026 12:03AM UTC coverage: 48.37% (+0.7%) from 47.696%
30501467811

push

github

jcelerier
tests: fix the time_signature narrowing in the quantification helper

time_signature holds uint16_t; passing int members through a braced
initializer is a narrowing conversion and clang rejects it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

26683 of 55164 relevant lines covered (48.37%)

188617.67 hits per line

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

99.26
/tests/Dataflow/TokenRequestTest.cpp
1
#include "../Editor/TestUtils.hpp"
2

3
#include <ossia/detail/config.hpp>
4

5
#include <ossia/dataflow/token_request.hpp>
6

7
#include "include_catch.hpp"
8

9
#include <iterator>
10
#include <utility>
11
#include <vector>
12
TEST_CASE("test_loops_integer", "test_loops_integer")
1✔
13
{
14
  using namespace ossia;
15

16
  token_request r;
1✔
17
  r.prev_date = 0_tv;
1✔
18
  r.date = 100_tv;
1✔
19

20
  token_request_vec vec;
1✔
21
  r.loop(
1✔
22
      0_tv, 10_tv, [&](auto& req) { vec.push_back(req); }, [](const auto&) {});
20✔
23

24
  simple_token_request_vec expected{
25
      {.prev_date = 0_tv, .date = 10_tv, .offset = 0_tv},
26
      {.prev_date = 0_tv, .date = 10_tv, .offset = 10_tv},
27
      {.prev_date = 0_tv, .date = 10_tv, .offset = 20_tv},
28
      {.prev_date = 0_tv, .date = 10_tv, .offset = 30_tv},
29
      {.prev_date = 0_tv, .date = 10_tv, .offset = 40_tv},
30
      {.prev_date = 0_tv, .date = 10_tv, .offset = 50_tv},
31
      {.prev_date = 0_tv, .date = 10_tv, .offset = 60_tv},
32
      {.prev_date = 0_tv, .date = 10_tv, .offset = 70_tv},
33
      {.prev_date = 0_tv, .date = 10_tv, .offset = 80_tv},
34
      {.prev_date = 0_tv, .date = 10_tv, .offset = 90_tv}};
1✔
35

36
  REQUIRE(expected == vec);
1✔
37
}
1✔
38

39
TEST_CASE("test_loops_fract", "test_loops_fract")
1✔
40
{
41
  using namespace ossia;
42

43
  token_request r;
1✔
44
  r.prev_date = 0_tv;
1✔
45
  r.date = 97_tv;
1✔
46

47
  token_request_vec vec;
1✔
48
  r.loop(
1✔
49
      0_tv, 10_tv, [&](auto& req) { vec.push_back(req); }, [](const auto&) {});
19✔
50

51
  simple_token_request_vec expected{
52
      {.prev_date = 0_tv, .date = 10_tv, .offset = 0_tv},
53
      {.prev_date = 0_tv, .date = 10_tv, .offset = 10_tv},
54
      {.prev_date = 0_tv, .date = 10_tv, .offset = 20_tv},
55
      {.prev_date = 0_tv, .date = 10_tv, .offset = 30_tv},
56
      {.prev_date = 0_tv, .date = 10_tv, .offset = 40_tv},
57
      {.prev_date = 0_tv, .date = 10_tv, .offset = 50_tv},
58
      {.prev_date = 0_tv, .date = 10_tv, .offset = 60_tv},
59
      {.prev_date = 0_tv, .date = 10_tv, .offset = 70_tv},
60
      {.prev_date = 0_tv, .date = 10_tv, .offset = 80_tv},
61
      {.prev_date = 0_tv, .date = 7_tv, .offset = 90_tv}};
1✔
62

63
  REQUIRE(expected == vec);
1✔
64
}
1✔
65

66
TEST_CASE("test_loops_offset", "test_loops_offset")
1✔
67
{
68
  using namespace ossia;
69

70
  token_request r;
1✔
71
  r.prev_date = 2_tv;
1✔
72
  r.date = 12_tv;
1✔
73

74
  token_request_vec vec;
1✔
75
  r.loop(
1✔
76
      0_tv, 5_tv, [&](auto& req) { vec.push_back(req); }, [](const auto&) {});
5✔
77

78
  simple_token_request_vec expected{
79
      {.prev_date = 2_tv, .date = 5_tv, .offset = 0_tv},
80
      {.prev_date = 0_tv, .date = 5_tv, .offset = 3_tv},
81
      {.prev_date = 0_tv, .date = 2_tv, .offset = 8_tv},
82
  };
1✔
83

84
  REQUIRE(expected == vec);
1✔
85
}
1✔
86

87
TEST_CASE("test_loops_smaller", "test_loops_smaller")
1✔
88
{
89
  using namespace ossia;
90

91
  token_request r;
1✔
92
  r.prev_date = 0_tv;
1✔
93
  r.date = 15_tv;
1✔
94

95
  token_request_vec vec;
1✔
96
  r.loop(
1✔
97
      0_tv, 20_tv, [&](auto& req) { vec.push_back(req); }, [](const auto&) {});
1✔
98

99
  simple_token_request_vec expected{{.prev_date = 0_tv, .date = 15_tv, .offset = 0_tv}};
1✔
100

101
  REQUIRE(expected == vec);
1✔
102
}
1✔
103

104
TEST_CASE("test_loops_mid", "test_loops_mid")
1✔
105
{
106
  using namespace ossia;
107

108
  token_request r;
1✔
109
  r.prev_date = 15_tv;
1✔
110
  r.date = 30_tv;
1✔
111

112
  token_request_vec vec;
1✔
113
  r.loop(
1✔
114
      0_tv, 20_tv, [&](auto& req) { vec.push_back(req); }, [](const auto&) {});
3✔
115

116
  simple_token_request_vec expected{
117
      {.prev_date = 15_tv, .date = 20_tv, .offset = 0_tv},
118
      {.prev_date = 0_tv, .date = 10_tv, .offset = 5_tv}};
1✔
119

120
  REQUIRE(expected == vec);
1✔
121
}
1✔
122

123
TEST_CASE("test_musical_quantization", "test_musical_quantization")
1✔
124
{
125
  using namespace ossia;
126

127
  token_request r;
1✔
128
  r.prev_date = 0_tv;
1✔
129
  r.date = 2048000_tv;
1✔
130
  r.musical_end_last_bar = 0.005804985827664399;
1✔
131
  r.musical_end_position = 0.005804985827664399;
1✔
132

133
  auto res = r.get_quantification_date(8.0);
1✔
134
  REQUIRE(res == 0_tv);
1✔
135
}
1✔
136

137
namespace
138
{
139
using date_list = std::vector<std::pair<int64_t, int64_t>>;
140

141
//! A tick covering [prev; date[ in model time and [mstart; mend[ in quarters.
142
ossia::token_request musical_tick(
15✔
143
    int64_t prev, int64_t date, double mstart, double mend, uint16_t num = 4, uint16_t denom = 4)
144
{
145
  ossia::token_request t;
15✔
146
  t.prev_date = ossia::time_value{prev};
15✔
147
  t.date = ossia::time_value{date};
15✔
148
  t.musical_start_position = mstart;
15✔
149
  t.musical_end_position = mend;
15✔
150
  t.musical_start_last_bar = 0.;
15✔
151
  t.musical_start_last_signature = 0.;
15✔
152
  t.signature = ossia::time_signature{num, denom};
15✔
153
  return t;
15✔
154
}
155

156
date_list dates(const ossia::quantification_points& p)
9✔
157
{
158
  date_list out;
9✔
159
  for(auto& q : p)
23✔
160
    out.emplace_back(q.date.impl, q.index);
14✔
161
  return out;
9✔
162
}
×
163
}
164

165
TEST_CASE("quantification_dates_empty_tick", "quantification_dates")
1✔
166
{
167
  auto t = musical_tick(100, 100, 0., 1.);
1✔
168
  REQUIRE(t.get_quantification_dates(4).empty());
1✔
169
}
1✔
170

171
TEST_CASE("quantification_dates_no_rate", "quantification_dates")
1✔
172
{
173
  // A null or negative rate means "as soon as possible".
174
  auto t = musical_tick(100, 200, 0., 1.);
1✔
175
  REQUIRE(dates(t.get_quantification_dates(0)) == date_list{{100, 0}});
3✔
176
  REQUIRE(dates(t.get_quantification_dates(-1)) == date_list{{100, 0}});
3✔
177
}
1✔
178

179
TEST_CASE("quantification_dates_no_musical_info", "quantification_dates")
1✔
180
{
181
  // Without a musical position there is nothing to quantize against: the tick
182
  // itself is the point. Several nodes rely on this to step once per tick.
183
  auto t = musical_tick(100, 200, 0., 0.);
1✔
184
  REQUIRE(dates(t.get_quantification_dates(16)) == date_list{{100, 0}});
3✔
185
}
1✔
186

187
TEST_CASE("quantification_dates_several_per_tick", "quantification_dates")
1✔
188
{
189
  // The whole point of the multi-date version: one tick worth a quarter note
190
  // holds four sixteenths, and none of them may be dropped.
191
  auto t = musical_tick(0, 1000, 0., 1.);
1✔
192

193
  const auto expected = date_list{{0, 0}, {250, 1}, {500, 2}, {750, 3}};
2✔
194
  REQUIRE(dates(t.get_quantification_dates(16)) == expected);
1✔
195
}
1✔
196

197
TEST_CASE("quantification_dates_interior_point", "quantification_dates")
1✔
198
{
199
  auto t = musical_tick(0, 1000, 0.5, 1.5);
1✔
200
  const auto res = t.get_quantification_dates(4);
1✔
201

202
  REQUIRE(dates(res) == date_list{{500, 1}});
3✔
203
  // and it agrees with the single-date version
204
  auto single = t.get_quantification_date(4);
1✔
205
  REQUIRE(single.has_value());
1✔
206
  REQUIRE(*single == res[0].date);
1✔
207
}
1✔
208

209
TEST_CASE("quantification_dates_on_the_start_of_the_tick", "quantification_dates")
1✔
210
{
211
  auto t = musical_tick(400, 1000, 1., 1.5);
1✔
212
  const auto res = t.get_quantification_dates(4);
1✔
213

214
  REQUIRE(dates(res) == date_list{{400, 1}});
3✔
215

216
  auto single = t.get_quantification_date(4);
1✔
217
  REQUIRE(single.has_value());
1✔
218
  REQUIRE(*single == res[0].date);
1✔
219
}
1✔
220

221
TEST_CASE("quantification_dates_on_the_end_of_the_tick", "quantification_dates")
1✔
222
{
223
  // A point falling exactly on the end of a tick belongs to the next one,
224
  // otherwise it would fire twice.
225
  auto t = musical_tick(0, 1000, 0.5, 1.);
1✔
226
  REQUIRE(t.get_quantification_dates(4).empty());
1✔
227
  REQUIRE(!t.get_quantification_date(4).has_value());
1✔
228
}
1✔
229

230
TEST_CASE("quantification_dates_bars", "quantification_dates")
1✔
231
{
232
  // rate <= 1 counts bars: 1 is every bar, 0.5 every two bars.
233
  auto t = musical_tick(0, 1000, 0., 8.);
1✔
234

235
  REQUIRE(dates(t.get_quantification_dates(1)) == date_list{{0, 0}, {500, 1}});
3✔
236
  REQUIRE(dates(t.get_quantification_dates(0.5)) == date_list{{0, 0}});
3✔
237
}
1✔
238

239
TEST_CASE("quantification_dates_odd_signature", "quantification_dates")
1✔
240
{
241
  // 7/8: a bar is 3.5 quarters.
242
  auto t = musical_tick(0, 1000, 0., 7., 7, 8);
1✔
243
  REQUIRE(dates(t.get_quantification_dates(1)) == date_list{{0, 0}, {500, 1}});
3✔
244
}
1✔
245

246
TEST_CASE("quantification_dates_are_ordered_and_inside_the_tick", "quantification_dates")
1✔
247
{
248
  for(double rate : {1., 2., 4., 8., 16., 32.})
7✔
249
  {
250
    auto t = musical_tick(0, 4096, 0.3, 5.7);
6✔
251
    const auto res = t.get_quantification_dates(rate);
6✔
252

253
    INFO("rate " << rate);
6✔
254
    int64_t previous = -1;
6✔
255
    for(const auto& q : res)
89✔
256
    {
257
      CHECK(q.date.impl >= t.prev_date.impl);
83✔
258
      CHECK(q.date.impl < t.date.impl);
83✔
259
      CHECK(q.date.impl >= previous);
83✔
260
      previous = q.date.impl;
83✔
261
    }
262
  }
6✔
263
}
1✔
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