Lumiera  0.pre.03
»edit your freedom«
placement-hierarchy-test.cpp
Go to the documentation of this file.
1 /*
2  PlacementHierarchy(Test) - cooperating hierarchical placement types
3 
4  Copyright (C) Lumiera.org
5  2009, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
28 #include "lib/test/run.hpp"
29 #include "lib/test/test-helper.hpp"
30 #include "lib/depend-inject.hpp"
35 #include "steam/asset/media.hpp"
36 #include "lib/format-cout.hpp"
37 #include "lib/error.hpp"
38 #include "lib/util.hpp"
39 
40 
41 
42 namespace steam {
43 namespace mobject {
44 namespace session {
45 namespace test {
46 
47  using session::Clip;
48  using lib::test::showSizeof;
49  using namespace mobject::test;
50  using lumiera::error::LUMIERA_ERROR_ASSERTION;
51 
52  using MediaAccessMock = lib::DependInject<vault::MediaAccessFacade>
53  ::Local<vault::test::MediaAccessMock>;
54 
55 
56  /***********************************************************************************/
64  class PlacementHierarchy_test : public Test
65  {
66 
67  virtual void
68  run (Arg)
69  {
70  MediaAccessMock useMockMedia;
71 
72 
73  typedef Placement<MObject> PMObj;
74  typedef TestPlacement<> PDummy;
75  typedef TestPlacement<TestSubMO1> PSub1;
76  typedef TestPlacement<TestSubMO2> PSub2;
78 
79  PSub1 pSub1(*new TestSubMO1);
80  PSub2 pSub2(*new TestSubMO2);
81  PSub21 pSub3(*new TestSubMO21);
82 
83  PDummy pSubM (pSub3);
84 
85  PMObj pClip = asset::Media::create("test-1", asset::VIDEO)->createClip();
86 
87  CHECK (INSTANCEOF (Placement<MObject>, &pSub1));
88  CHECK (INSTANCEOF (Placement<MObject>, &pSub2));
89  CHECK (INSTANCEOF (Placement<MObject>, &pSub3));
90  CHECK (INSTANCEOF (Placement<MObject>, &pSubM));
91 
92  CHECK (INSTANCEOF (Placement<DummyMO>, &pSub1));
93  CHECK (INSTANCEOF (Placement<DummyMO>, &pSub2));
94  CHECK (INSTANCEOF (Placement<DummyMO>, &pSub3));
95 
96  CHECK (INSTANCEOF (TestPlacement<DummyMO>, &pSub1));
97  CHECK (INSTANCEOF (TestPlacement<DummyMO>, &pSub2));
98  CHECK (INSTANCEOF (TestPlacement<DummyMO>, &pSub3));
99 
100  CHECK ( INSTANCEOF (TestPlacement<TestSubMO2>, &pSub3));
101 
102  // the following won't succeed...
103 // CHECK (INSTANCEOF (TestPlacement<TestSubMO21>, &pSub2)); // parent not instance of subclass
104 // CHECK (INSTANCEOF (TestPlacement<TestSubMO2>, &pSub1)); // separate branch in the hierarchy
105 
106  cout << showSizeof(pSub1) << endl;
107  cout << showSizeof(pSub2) << endl;
108  cout << showSizeof(pSub3) << endl;
109  cout << showSizeof(pSubM) << endl;
110  cout << showSizeof(pClip) << endl;
111 
112  CHECK (sizeof(pSub1) == sizeof(pSub3));
113  CHECK (sizeof(pClip) == sizeof(pSub3));
114 
115  cout << pSub1 << endl;
116  cout << pSub2 << endl;
117  cout << pSub3 << endl;
118  cout << pSubM << endl;
119  cout << pClip << endl;
120 
121  pSub3->specialAPI();
122 
123  CHECK (2 == pSubM.use_count());
124  CHECK (2 == pSub3.use_count());
125  pClip = pSubM; // slicing and shared ownership
126  CHECK (3 == pSubM.use_count());
127  CHECK (3 == pSub3.use_count());
128  CHECK (3 == pClip.use_count());
129 
130 
131  // now do a brute-force re-interpretation
132  // note this is still protected by an ASSERT on the operator->()
133  PSub21& hijacked = reinterpret_cast<PSub21&> (pClip);
134 
135  hijacked->specialAPI();
136  CHECK (3 == hijacked.use_count());
137  CHECK (hijacked.getID() == pClip.getID());
138 
139  cout << format_PlacementID(pSub1) << endl;
140  cout << format_PlacementID(pSub2) << endl;
141  cout << format_PlacementID(pSub3) << endl;
142  cout << format_PlacementID(pSubM) << endl;
143  cout << format_PlacementID(pClip) << endl;
144 
145  pClip = pSub1;
146  CHECK (2 == pSubM.use_count());
147  CHECK (2 == pSub3.use_count());
148 
149  CHECK (2 == pClip.use_count());
150  CHECK (2 == pSub1.use_count());
151 
152 #if false
153  VERIFY_ERROR (ASSERTION, hijacked->specialAPI() );
156 #endif
157 
158  // runtime type diagnostics based on pointee RTTI
159  CHECK ( pSub2.isCompatible<MObject>());
160  CHECK ( pSub2.isCompatible<DummyMO>());
161  CHECK ( pSub2.isCompatible<TestSubMO2>());
162  CHECK (!pSub2.isCompatible<TestSubMO21>());
163  CHECK (!pSub2.isCompatible<TestSubMO1>());
164  CHECK (!pSub2.isCompatible<Clip>());
165  }
166  };
167 
168 
170  LAUNCHER (PlacementHierarchy_test, "unit session");
171 
172 
173 }}}} // namespace steam::mobject::session::test
Automatically use custom string conversion in C++ stream output.
Subclass-1 is not defined "processible", thus will always be handled as DummyMO...
Test MObject subclass, which, contrary to any real MObject, can be created directly without involving...
Media data represented a specific kind of Asset.
Definition: run.hpp:49
Core abstraction: placement of a media object into session context.
#define INSTANCEOF(CLASS, EXPR)
shortcut for subclass test, intended for assertions only.
Definition: util.hpp:492
Per type specific configuration of instances created as service dependencies.
MObject in the Session to represent a clip on the timeline.
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
Unit test helper to access an emulated media file.
A user visible/editable Clip is a reference to a contiguous sequence of media data loaded as Asset in...
static MediaFactory create
storage for the static MediaFactory instance
Definition: media.hpp:84
Steam-Layer implementation namespace root.
Namespace of Session and user visible high-level objects.
Definition: sequence.hpp:74
MObject is the interface class for all "Media Objects".
Definition: mobject.hpp:79
This framework allows to (re)configure the lib::Depend front-end for dependency-injection.
Simple test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A collection of frequently used helper functions to support unit testing.
A hierarchy of simple dummy-Media-Objects for easy unit testing.
Lumiera error handling (C++ interface).
Subclass-2 is defined "processible", but we omit the necessary "applicable" definition in TestTool...