1 //
2 // Copyright 2020 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #include "pxr/pxr.h"
25 #include "pxr/usd/ar/ar.h"
26 #include "pxr/usd/ar/defineResolverContext.h"
27 #include "pxr/usd/ar/resolverContext.h"
28 #include "pxr/base/tf/diagnostic.h"
29 #include "pxr/base/tf/hash.h"
30 
31 #include <string>
32 
33 PXR_NAMESPACE_USING_DIRECTIVE;
34 
35 template <class Data>
36 class TestContextObject
37 {
38 public:
TestContextObject(const Data & data)39     TestContextObject(const Data& data)
40         : _data(data)
41     {
42     }
43 
GetData() const44     const Data& GetData() const
45     {
46         return _data;
47     }
48 
operator <(const TestContextObject & rhs) const49     bool operator<(const TestContextObject& rhs) const
50     {
51         return _data < rhs._data;
52     }
53 
operator ==(const TestContextObject & rhs) const54     bool operator==(const TestContextObject& rhs) const
55     {
56         return _data == rhs._data;
57     }
58 
hash_value(const TestContextObject & o)59     friend size_t hash_value(const TestContextObject& o)
60     {
61         return TfHash()(o._data);
62     }
63 
64 private:
65     Data _data;
66 };
67 
68 using TestStringContextObject = TestContextObject<std::string>;
69 using TestIntContextObject = TestContextObject<int>;
70 
71 PXR_NAMESPACE_OPEN_SCOPE
72 
73 AR_DECLARE_RESOLVER_CONTEXT(TestStringContextObject);
74 AR_DECLARE_RESOLVER_CONTEXT(TestIntContextObject);
75 
76 PXR_NAMESPACE_CLOSE_SCOPE
77 
78 static void
TestDefault()79 TestDefault()
80 {
81     ArResolverContext ctx;
82     TF_AXIOM(ctx.IsEmpty());
83     TF_AXIOM(ctx.Get<TestStringContextObject>() == nullptr);
84     TF_AXIOM(ctx.Get<TestIntContextObject>() == nullptr);
85 
86     ArResolverContext ctx2;
87     TF_AXIOM(ctx2.IsEmpty());
88     TF_AXIOM(ctx2.Get<TestStringContextObject>() == nullptr);
89     TF_AXIOM(ctx.Get<TestIntContextObject>() == nullptr);
90     TF_AXIOM(ctx == ctx2);
91     TF_AXIOM(!(ctx < ctx2));
92     TF_AXIOM(!(ctx2 < ctx));
93 }
94 
95 static void
TestSingleContextObject()96 TestSingleContextObject()
97 {
98     // Create an ArResolverContext holding a single context object
99     // and verify those objects are accessible.
100     TestStringContextObject strContextObj("test string");
101     ArResolverContext ctx1(strContextObj);
102     TF_AXIOM(!ctx1.IsEmpty());
103 
104     const TestStringContextObject* strObjFromCtx =
105         ctx1.Get<TestStringContextObject>();
106     TF_AXIOM(strObjFromCtx);
107     TF_AXIOM(strObjFromCtx->GetData() == strContextObj.GetData());
108 
109     const TestIntContextObject* intObjFromCtx =
110         ctx1.Get<TestIntContextObject>();
111     TF_AXIOM(intObjFromCtx == nullptr);
112 
113     // Create an ArResolverContext that should compare equal to
114     // the original context.
115     ArResolverContext ctx2(TestStringContextObject("test string"));
116     TF_AXIOM(ctx1 == ctx2);
117     TF_AXIOM(!(ctx1 < ctx2));
118     TF_AXIOM(!(ctx2 < ctx1));
119 
120     // Create ArResolverContexts holding different context objects
121     // and verify they do not compare equal.
122     ArResolverContext ctx3;
123     TF_AXIOM(ctx1 != ctx3);
124 
125     ArResolverContext ctx4(TestStringContextObject("foo"));
126     TF_AXIOM(ctx1 != ctx4);
127 
128     ArResolverContext ctx5(TestIntContextObject(42));
129     TF_AXIOM(ctx1 != ctx5);
130 }
131 
132 #if AR_VERSION == 2
133 
134 static void
TestMultipleContextObjects()135 TestMultipleContextObjects()
136 {
137     // Create an ArResolverContext holding multiple context objects
138     // and verify those objects are accessible.
139     ArResolverContext context(
140         TestStringContextObject("test string"),
141         TestIntContextObject(42));
142     TF_AXIOM(!context.IsEmpty());
143     TF_AXIOM(context != ArResolverContext());
144 
145     const TestStringContextObject* strObjFromContext =
146         context.Get<TestStringContextObject>();
147     TF_AXIOM(strObjFromContext);
148     TF_AXIOM(strObjFromContext->GetData() == "test string");
149 
150     const TestIntContextObject* intObjFromContext =
151         context.Get<TestIntContextObject>();
152     TF_AXIOM(intObjFromContext);
153     TF_AXIOM(intObjFromContext->GetData() == 42);
154 
155     // Create an ArResolverContext holding the same context objects,
156     // but passed in different order. This ArResolverContext should
157     // still compare equal to the first context.
158     {
159         ArResolverContext testContext(
160             *intObjFromContext,
161             *strObjFromContext);
162         TF_AXIOM(context == testContext);
163         TF_AXIOM(!(context < testContext));
164         TF_AXIOM(!(testContext < context));
165         TF_AXIOM(hash_value(context) == hash_value(testContext));
166     }
167 
168     {
169         ArResolverContext testContext(
170             *intObjFromContext,
171             ArResolverContext(*strObjFromContext));
172         TF_AXIOM(context == testContext);
173         TF_AXIOM(!(context < testContext));
174         TF_AXIOM(!(testContext < context));
175         TF_AXIOM(hash_value(context) == hash_value(testContext));
176     }
177 
178     {
179         ArResolverContext testContext(
180             ArResolverContext{*intObjFromContext},
181             ArResolverContext{*strObjFromContext});
182         TF_AXIOM(context == testContext);
183         TF_AXIOM(!(context < testContext));
184         TF_AXIOM(!(testContext < context));
185         TF_AXIOM(hash_value(context) == hash_value(testContext));
186     }
187 
188     // Create ArResolverContexts holding different context objects
189     // and verify they do not compare equal.
190     TestIntContextObject intObj(42);
191     TestStringContextObject strObj("foo");
192 
193     {
194         ArResolverContext testContext(intObj);
195         TF_AXIOM(context != testContext);
196     }
197 
198     {
199         ArResolverContext testContext(strObj);
200         TF_AXIOM(context != testContext);
201     }
202 
203     {
204         ArResolverContext testContext(strObj, intObj);
205         TF_AXIOM(context != testContext);
206     }
207 
208     {
209         ArResolverContext testContext(
210             ArResolverContext{strObj},
211             ArResolverContext{intObj});
212         TF_AXIOM(context != testContext);
213     }
214 
215     {
216         ArResolverContext testContext(
217             strObj,
218             ArResolverContext{intObj});
219         TF_AXIOM(context != testContext);
220     }
221 }
222 
223 #endif
224 
main(int argc,char ** argv)225 int main(int argc, char** argv)
226 {
227     printf("TestDefault ...\n");
228     TestDefault();
229 
230     printf("TestSingleContextObject ...\n");
231     TestSingleContextObject();
232 
233 #if AR_VERSION == 2
234     printf("TestMultipleContextObjects ...\n");
235     TestMultipleContextObjects();
236 #endif
237 
238     printf("All tests passed!\n");
239     return 0;
240 }
241