Audacity 3.2.0
NumericConverterTests.cpp
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*!********************************************************************
3
4 Audacity: A Digital Audio Editor
5
6 NumericConverterTests.cpp
7
8 Dmitry Vedenko
9
10**********************************************************************/
11
12#include <catch2/catch.hpp>
13
17
18#include "Project.h"
19#include "ProjectRate.h"
21
22#include "MockedPrefs.h"
23#include "MockedAudio.h"
24
25
26TEST_CASE("ParsedNumericConverterFormatter", "")
27{
28 auto context = FormatterContext::SampleRateContext(44100.0);
29
30 auto hhmmssFormatter = CreateParsedNumericConverterFormatter(
31 context, NumericConverterType_TIME(), Verbatim("0100 h 060 m 060 s"));
32
33 REQUIRE(
34 hhmmssFormatter->ValueToString(0.0, false).valueString ==
35 "00 h 00 m 00 s");
36
37 REQUIRE(
38 hhmmssFormatter->ValueToString(30.0, false).valueString ==
39 "00 h 00 m 30 s");
40
41 REQUIRE(
42 hhmmssFormatter->ValueToString(60.0, false).valueString ==
43 "00 h 01 m 00 s");
44
45 REQUIRE(
46 hhmmssFormatter->ValueToString(60.0, false)
47 .fieldValueStrings.size() == 3);
48
49 REQUIRE(
50 hhmmssFormatter->ValueToString(60.0, false).fieldValueStrings[0] ==
51 "00");
52
53 REQUIRE(
54 hhmmssFormatter->ValueToString(60.0, false).fieldValueStrings[1] ==
55 "01");
56
57 REQUIRE(
58 hhmmssFormatter->ValueToString(60.0, false).fieldValueStrings[2] ==
59 "00");
60
61 REQUIRE(
62 hhmmssFormatter->StringToValue("foobar").has_value() == false);
63 REQUIRE(
64 hhmmssFormatter->StringToValue("01 h 30 m 15 s").has_value() == true);
65 REQUIRE(
66 *hhmmssFormatter->StringToValue("01 h 30 m 15 s") ==
67 Approx(60 * 60 + 30 * 60 + 15));
68}
69
70
71TEST_CASE("BeatsNumericConverterFormatter", "")
72{
73 MockedPrefs mockedPrefs;
74 MockedAudio mockedAudio;
75
77 auto& timeSignature = ProjectTimeSignature::Get(*project);
78
79 timeSignature.SetTempo(120.0);
80 timeSignature.SetUpperTimeSignature(3);
81 timeSignature.SetLowerTimeSignature(4);
82
84
85 REQUIRE(
86 basicFormatter->ValueToString(-1.0, false).valueString ==
87 "--- bar -- beat");
88
89 REQUIRE(
90 basicFormatter->ValueToString(0.0, false).valueString ==
91 "001 bar 01 beat");
92
93 REQUIRE(
94 basicFormatter->ValueToString(0.6, false).valueString ==
95 "001 bar 02 beat");
96
97 REQUIRE(
98 basicFormatter->ValueToString(1.0, false).valueString ==
99 "001 bar 03 beat");
100
101 REQUIRE(
102 basicFormatter->ValueToString(1.6, false).valueString ==
103 "002 bar 01 beat");
104
105 REQUIRE(basicFormatter->StringToValue("foobar").has_value() == false);
106
107 REQUIRE(basicFormatter->StringToValue("001 bar 01 beat").has_value() == true);
108 REQUIRE(
109 *basicFormatter->StringToValue("001 bar 01 beat") == Approx(0));
110 REQUIRE(
111 *basicFormatter->StringToValue("001 bar 02 beat") == Approx(0.5));
112 REQUIRE(
113 *basicFormatter->StringToValue("002 bar 01 beat") == Approx(1.5));
114
115 timeSignature.SetTempo(120.0);
116 timeSignature.SetUpperTimeSignature(3);
117 timeSignature.SetLowerTimeSignature(4);
118
119 auto fracFormatter = CreateBeatsNumericConverterFormatter(
121
122 REQUIRE(
123 fracFormatter->ValueToString(-1.0, false).valueString ==
124 "--- bar -- beat --");
125
126 REQUIRE(
127 fracFormatter->ValueToString(0.0, false).valueString ==
128 "001 bar 01 beat 01");
129
130 REQUIRE(
131 fracFormatter->ValueToString(0.6, false).valueString ==
132 "001 bar 02 beat 01");
133
134 REQUIRE(
135 fracFormatter->ValueToString(1.0, false).valueString ==
136 "001 bar 03 beat 01");
137
138 REQUIRE(
139 fracFormatter->ValueToString(1.9, false).valueString ==
140 "002 bar 01 beat 04");
141 REQUIRE(
142 *fracFormatter->StringToValue("001 bar 01 beat 01") == Approx(0));
143 REQUIRE(
144 *fracFormatter->StringToValue("001 bar 02 beat 01") == Approx(0.5));
145 REQUIRE(
146 *fracFormatter->StringToValue("002 bar 01 beat 01") == Approx(1.5));
147 REQUIRE(
148 *fracFormatter->StringToValue("001 bar 01 beat 02") == Approx(0.125));
149 REQUIRE(
150 *fracFormatter->StringToValue("001 bar 02 beat 04") == Approx(0.875));
151 REQUIRE(
152 *fracFormatter->StringToValue("002 bar 01 beat 09") ==
153 Approx(1.5 + 0.0 + 8 * (0.5 / 4)));
154
155 REQUIRE(fracFormatter->SingleStep(0.0, 2, true) == Approx(1.5));
156 REQUIRE(fracFormatter->SingleStep(0.0, 1, true) == Approx(15.0));
157 REQUIRE(fracFormatter->SingleStep(0.0, 4, true) == Approx(0.5));
158 REQUIRE(fracFormatter->SingleStep(0.0, 3, true) == Approx(5));
159
160 auto durationFormatter = CreateBeatsNumericConverterFormatter(
162
163 REQUIRE(
164 durationFormatter->ValueToString(-1.0, false).valueString ==
165 "--- bar -- beat --");
166
167 REQUIRE(
168 durationFormatter->ValueToString(0.0, false).valueString ==
169 "000 bar 00 beat 00");
170
171 REQUIRE(
172 durationFormatter->ValueToString(0.6, false).valueString ==
173 "000 bar 01 beat 00");
174
175 REQUIRE(
176 durationFormatter->ValueToString(1.0, false).valueString ==
177 "000 bar 02 beat 00");
178
179 REQUIRE(
180 durationFormatter->ValueToString(1.9, false).valueString ==
181 "001 bar 00 beat 03");
182 REQUIRE(*durationFormatter->StringToValue("000 bar 00 beat 00") == Approx(0));
183 REQUIRE(*durationFormatter->StringToValue("000 bar 01 beat 00") == Approx(0.5));
184 REQUIRE(*durationFormatter->StringToValue("001 bar 00 beat 00") == Approx(1.5));
185 REQUIRE(
186 *durationFormatter->StringToValue("000 bar 00 beat 01") == Approx(0.125));
187 REQUIRE(
188 *durationFormatter->StringToValue("000 bar 01 beat 03") == Approx(0.875));
189 REQUIRE(
190 *durationFormatter->StringToValue("001 bar 00 beat 08") ==
191 Approx(1.5 + 0.0 + 8 * (0.5 / 4)));
192
193 REQUIRE(durationFormatter->SingleStep(0.0, 2, true) == Approx(1.5));
194 REQUIRE(durationFormatter->SingleStep(0.0, 1, true) == Approx(15.0));
195 REQUIRE(durationFormatter->SingleStep(0.0, 4, true) == Approx(0.5));
196 REQUIRE(durationFormatter->SingleStep(0.0, 3, true) == Approx(5));
197
198 auto longFormatterTest = [&](double tempo)
199 {
200 timeSignature.SetTempo(tempo);
201 timeSignature.SetUpperTimeSignature(4);
202 timeSignature.SetLowerTimeSignature(4);
203
204 //const auto t = *basicFormatter->StringToValue("009 bar 02 beat");
205 //const auto r = basicFormatter->ValueToString(t, true).valueString;
206
207 //REQUIRE("009 bar 02 beat" == r);
208
209 for (int32_t bar = 0; bar < 100000; ++bar)
210 {
211 for (int32_t beat = 0; beat < 4; ++beat)
212 {
213 const auto value = bar * timeSignature.GetBarDuration() +
214 beat * timeSignature.GetBeatDuration();
215
216 basicFormatter->UpdateFormatForValue(value, true);
217
218 const auto formattedString =
219 wxString::Format("%03d bar %02d beat", bar + 1, beat + 1);
220
221 REQUIRE(
222 *basicFormatter->StringToValue(formattedString) ==
223 Approx(value));
224
225 REQUIRE(
226 basicFormatter
227 ->ValueToString(
228 *basicFormatter->StringToValue(formattedString), true)
229 .valueString == formattedString);
230 }
231 }
232 };
233
234 longFormatterTest(88);
235 longFormatterTest(117);
236}
237
238
std::unique_ptr< NumericConverterFormatter > CreateBeatsNumericConverterFormatter(const FormatterContext &context, int fracPart, bool timeFormat)
TEST_CASE("ParsedNumericConverterFormatter", "")
const NumericConverterType & NumericConverterType_TIME()
std::unique_ptr< NumericConverterFormatter > CreateParsedNumericConverterFormatter(const FormatterContext &context, NumericConverterType type, const TranslatableString &format)
an object holding per-project preferred sample rate
const auto project
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
static std::shared_ptr< AudacityProject > Create()
Use this factory function.
Definition: Project.cpp:78
static FormatterContext ProjectContext(const AudacityProject &project)
static FormatterContext SampleRateContext(double sampleRate)
static ProjectTimeSignature & Get(AudacityProject &project)