Lumiera  0.pre.03
»edit your freedom«
time-parsing-test.cpp
Go to the documentation of this file.
1 /*
2  TimeParsing(Test) - handling textual time(code) specifications
3 
4  Copyright (C)
5  2011, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
19 #include "lib/test/run.hpp"
20 #include "lib/test/test-helper.hpp"
22 #include "lib/time/quantiser.hpp"
23 #include "lib/time/timecode.hpp"
24 #include "lib/symbol.hpp"
25 #include "lib/util.hpp"
26 
27 using lib::Symbol;
28 
29 
30 namespace lib {
31 namespace time{
32 namespace test{
33 
35  using LERR_(INVALID_TIMECODE);
36 
37 
38  namespace { // Helper for writing test cases
39 
40  Symbol DEFAULT_GRID = "pal0";
41  Symbol OFFSET_GRID = "pal10";
42 
47  template<class FMT>
48  class Parsing
49  {
50  string const& timeSpec_;
51  PQuant grid_;
52 
53  public:
54  Parsing (string const& toParse, Symbol gridID =DEFAULT_GRID)
55  : timeSpec_(toParse)
56  , grid_(Quantiser::retrieve(gridID))
57  { }
58 
59 
60  void
61  should_yield (TimeValue const& expected)
62  {
63  TimeValue parsed = FMT::parse (timeSpec_, *grid_);
64  CHECK (parsed == expected, "parsing '%s' resulted in %s instead of %s"
65  , cStr(timeSpec_)
66  , cStr(Time(parsed))
67  , cStr(Time(expected)));
68  }
69 
70  void
71  should_yield (FSecs const& expectedSecs)
72  {
73  should_yield (Time (expectedSecs));
74  }
75 
76  void
77  should_fail ()
78  {
79  VERIFY_ERROR (INVALID_TIMECODE, FMT::parse (timeSpec_, *grid_));
80  }
81 
82  };
83 
84  }//(End)Test case helper
85 
86 
87 
88 
89  /****************************************************/
93  class TimeParsing_test : public Test
94  {
95  virtual void
96  run (Arg)
97  {
98  defineTestTimeGrids();
99 
100  parseFrames();
101  parseFractionalSeconds();
103 // parseHms();
104 // parseSmpte();
105 // parseDropFrame();
106  }
107 
108 
109  void
110  defineTestTimeGrids()
111  {
112  TimeGrid::build(DEFAULT_GRID, FrameRate::PAL);
113  TimeGrid::build(OFFSET_GRID, FrameRate::PAL, Time(0,10));
114  }
115 
116 
117  void
118  parseFrames ()
119  {
120  Parsing<format::Frames> ("0#") .should_yield (0);
121  Parsing<format::Frames> ("1#") .should_yield (FSecs(1,25) );
122  Parsing<format::Frames> ("-1#") .should_yield (FSecs(-1,25) );
123  Parsing<format::Frames> ("-0#") .should_yield (0);
124  Parsing<format::Frames> ("25#") .should_yield (1 );
125  Parsing<format::Frames> ("26#") .should_yield (Time(40,1) );
126  Parsing<format::Frames> ("25#", OFFSET_GRID).should_yield (1+10 );
127  Parsing<format::Frames> ("-1#", OFFSET_GRID).should_yield (10 - FSecs(1,25));
128 
129  Parsing<format::Frames> ("23") .should_fail();
130  Parsing<format::Frames> ("23 #") .should_fail();
131  Parsing<format::Frames> ("23.#") .should_fail();
132  Parsing<format::Frames> ("23x#") .should_fail();
133 
134  Parsing<format::Frames> ("xxx25#xxx") .should_yield (1);
135  Parsing<format::Frames> ("12 25#") .should_yield (1);
136  Parsing<format::Frames> ("12 25# 33#") .should_yield (1); // note pitfall: the first valid number is used
137  Parsing<format::Frames> ("12 25# \n 33#") .should_yield (1);
138  Parsing<format::Frames> ("12\n 25# \n 33#") .should_yield (1);
139  Parsing<format::Frames> ("12.25#") .should_fail(); // rejected because of leading dot (ambiguity)
140  }
141 
142 
143  void
144  parseFractionalSeconds ()
145  {
146  Parsing<format::Seconds> ("0sec") .should_yield (0);
147  Parsing<format::Seconds> ("1sec") .should_yield (1);
148  Parsing<format::Seconds> ("10sec") .should_yield (10);
149  Parsing<format::Seconds> ("100sec") .should_yield (100);
150  Parsing<format::Seconds> ("-10sec") .should_yield (-10);
151  Parsing<format::Seconds> ("-0sec") .should_yield (0);
152 
153  Parsing<format::Seconds> ("1/2sec") .should_yield (Time(500,0) );
154  Parsing<format::Seconds> ("1/25sec") .should_yield (Time( 40,0) );
155  Parsing<format::Seconds> ("1/250sec") .should_yield (Time( 4,0) ); // no quantisation involved in parsing
156  Parsing<format::Seconds> ("1/250sec", OFFSET_GRID).should_yield (Time(4,10)); // ...but the origin of the grid is used
157 
158  Parsing<format::Seconds> ("10/2sec") .should_yield (5);
159  Parsing<format::Seconds> ("1000/200sec") .should_yield (5);
160  Parsing<format::Seconds> ("-10/2sec") .should_yield (-5);
161  Parsing<format::Seconds> ("10/-2sec") .should_fail(); // only leading sign allowed (ambiguity)
162 
163  Parsing<format::Seconds> ("1+1/2sec") .should_yield (Time(500,1) );
164  Parsing<format::Seconds> ("1-1/2sec") .should_yield (Time(500,0) );
165  Parsing<format::Seconds> ("-1-1/2sec") .should_yield (-Time(500,1) );
166  Parsing<format::Seconds> ("-1+1/2sec") .should_yield (-Time(500,0) );
167  Parsing<format::Seconds> ("-1+1/-2sec") .should_fail();
168 
169  Parsing<format::Seconds> ("-12+24690/12345sec", OFFSET_GRID).should_yield(0); // origin=+10sec -12sec + 2/1sec == 0
170 
171  Parsing<format::Seconds> ("1") .should_fail();
172  Parsing<format::Seconds> ("1 sec") .should_fail();
173  Parsing<format::Seconds> ("--1sec") .should_fail();
174  Parsing<format::Seconds> ("/-1sec") .should_fail();
175  Parsing<format::Seconds> ("1.2sec") .should_fail();
176  Parsing<format::Seconds> ("1/.2sec") .should_fail();
177  Parsing<format::Seconds> ("1 + 2 / 4 sec") .should_fail();
178  Parsing<format::Seconds> ("1 + 2 / 4sec") .should_yield(4); // note pitfall: leading garbage not considered
179  Parsing<format::Seconds> ("xxx4secxxxx") .should_yield(4);
180  Parsing<format::Seconds> ("x1# 8/2sec 2sec").should_yield(4); // note pitfall: first valid number used
181  }
182 
183 
184  void
185  parseHms ()
186  {
187  UNIMPLEMENTED ("verify reading hour-minutes-seconds-millis time specs");
188  }
189 
190 
191  void
192  parseSmpte ()
193  {
194  }
195 
196 
197  void
198  parseDropFrame ()
199  {
200  UNIMPLEMENTED ("verify especially SMPTE-drop-frame timecode");
201  }
202  };
203 
204 
206  LAUNCHER (TimeParsing_test, "unit common");
207 
208 
209 
210 }}} // namespace lib::time::test
Interface: a grid and scale definition for time quantisation.
Definition: time-grid.hpp:77
static PQuant retrieve(Symbol gridID)
Access an existing grid definition or quantiser, known by the given symbolic ID.
CStr cStr(std::string const &rendered)
convenience shortcut: forced conversion to c-String via string.
Definition: symbol.hpp:59
Definition: run.hpp:40
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
static PGrid build(FrameRate frames_per_second)
Definition: time-grid.cpp:158
Implementation namespace for support and library code.
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:299
Token or Atom with distinct identity.
Definition: symbol.hpp:117
Timecode handling library This header defines the foundation interface TCode to represent a grid alig...
Marker types to indicate a literal string and a Symbol.
Expression builder for writing time value parsing tests.
Simplistic test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
boost::rational< int64_t > FSecs
rational representation of fractional seconds
Definition: timevalue.hpp:220
A collection of frequently used helper functions to support unit testing.
Library functions to support the formation of grid-aligned time values.
To establish a reference scale for quantised time values.
basic constant internal time value.
Definition: timevalue.hpp:133
static const FrameRate PAL
predefined constant for PAL framerate
Definition: timevalue.hpp:671