OLD | NEW |
| (Empty) |
1 // Copyright 2004-2009 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 // ======================================================================== | |
15 | |
16 | |
17 #include <atlstr.h> | |
18 #include "omaha/base/sta.h" | |
19 #include "omaha/base/sta_call.h" | |
20 #include "omaha/base/thread.h" | |
21 #include "omaha/base/utils.h" | |
22 #include "omaha/testing/unit_test.h" | |
23 | |
24 namespace omaha { | |
25 | |
26 namespace { | |
27 | |
28 class X { | |
29 public: | |
30 void f() {} | |
31 void f(int) {} | |
32 void f(unsigned int, X*) {} | |
33 void f(bool, char, long*) {} | |
34 | |
35 static void g() {} | |
36 static void g(int) {} | |
37 static void g(unsigned int, X*) {} | |
38 static void g(bool, char, long*) {} | |
39 }; | |
40 | |
41 class Y { | |
42 public: | |
43 HRESULT f() { return S_OK; } | |
44 HRESULT f(int) { return S_OK; } | |
45 HRESULT f(unsigned int, X*) { return S_OK; } | |
46 HRESULT f(bool, char, long*) { return S_OK; } | |
47 | |
48 static HRESULT g() { return S_OK; } | |
49 static HRESULT g(int) { return S_OK; } | |
50 static HRESULT g(unsigned int, X*) { return S_OK; } | |
51 static HRESULT g(bool, char, long*) { return S_OK; } | |
52 }; | |
53 | |
54 class Z { | |
55 public: | |
56 void f(char, signed char, unsigned char) {} | |
57 | |
58 void f(Y*) {} | |
59 // void f(const Y*) {} // not supported !!! | |
60 | |
61 void m() {} | |
62 void m() const {} | |
63 }; | |
64 | |
65 class Test { | |
66 public: | |
67 int Add(int i, int j) { return i + j; } | |
68 void Add(int i, int j, int* sum) { *sum = i + j; } | |
69 }; | |
70 | |
71 int Add(long i, long j) { return i + j; } | |
72 void Add(long i, long j, long* sum) { *sum = i + j; } | |
73 | |
74 void Print(const char*) {} | |
75 void Print1(CString*) {} | |
76 | |
77 } // namespace | |
78 | |
79 class CompileTest : public Runnable { | |
80 protected: | |
81 virtual void Run(); | |
82 }; | |
83 | |
84 void CompileTest::Run() { | |
85 X x; | |
86 Y y; | |
87 | |
88 CallFunction(X::g); | |
89 CallFunction(X::g, 10); | |
90 CallFunction(X::g, static_cast<unsigned int>(10), &x); | |
91 CallFunction(X::g, true, 'a', static_cast<long*>(0)); | |
92 | |
93 CallFunction(Y::g); | |
94 CallFunction(Y::g, 10); | |
95 CallFunction(Y::g, static_cast<unsigned int>(10), &x); | |
96 CallFunction(Y::g, true, 'a', static_cast<long*>(0)); | |
97 | |
98 CallMethod(&x, &X::f); | |
99 CallMethod(&x, &X::f, 10); | |
100 CallMethod(&x, &X::f, static_cast<unsigned int>(10), &x); | |
101 CallMethod(&x, &X::f, true, 'a', static_cast<long*>(0)); | |
102 | |
103 CallMethod(&y, &Y::f); | |
104 CallMethod(&y, &Y::f, 20); | |
105 CallMethod(&y, &Y::f, static_cast<unsigned int>(10), &x); | |
106 CallMethod(&y, &Y::f, true, 'a', static_cast<long*>(0)); | |
107 | |
108 Z z; | |
109 CallMethod(&z, | |
110 &Z::f, | |
111 'a', | |
112 static_cast<signed char>('a'), | |
113 static_cast<unsigned char>('a')); | |
114 | |
115 | |
116 CallMethod(&z, &Z::f, &y); | |
117 | |
118 // Does not compile: template parameter 'P' is ambiguous | |
119 // const Y cy; | |
120 // CallMethod(&z, &Z::f, &cy); | |
121 | |
122 CallMethod(&z, &Z::m); | |
123 | |
124 // Does not compile: template parameter 'T' is ambiguous | |
125 // const Z cz; | |
126 // CallMethod(&cz, &Z::m); | |
127 | |
128 // Does not compile: cannot convert from 'const Z *' to 'Z *const ' | |
129 // const Z cz; | |
130 // CallMethod<const Z, void>(&cz, &Z::m); | |
131 | |
132 CString msg(_T("test")); | |
133 CallFunction(Print, "test"); | |
134 CallFunction(Print1, &msg); | |
135 } | |
136 | |
137 class RuntimeTest : public Runnable { | |
138 protected: | |
139 virtual void Run(); | |
140 }; | |
141 | |
142 void RuntimeTest::Run() { | |
143 Test test; | |
144 ASSERT_EQ(CallMethod(&test, &Test::Add, 10, 20), 30); | |
145 | |
146 int sum(0); | |
147 CallMethod(&test, &Test::Add, -10, 20, &sum); | |
148 ASSERT_EQ(sum, 10); | |
149 | |
150 { | |
151 ASSERT_EQ(CallFunction(Add, long(10), long(20)), 30); | |
152 | |
153 long sum = 0; | |
154 CallFunction(Add, long(10), long(-20), &sum); | |
155 ASSERT_EQ(sum, -10); | |
156 } | |
157 } | |
158 | |
159 | |
160 class AsyncTest : public Runnable { | |
161 protected: | |
162 virtual void Run(); | |
163 }; | |
164 | |
165 void AsyncTest::Run() { | |
166 static X x; | |
167 static Y y; | |
168 | |
169 CallFunctionAsync(X::g); | |
170 CallFunctionAsync(X::g, 10); | |
171 CallFunctionAsync(X::g, static_cast<unsigned int>(10), &x); | |
172 CallFunctionAsync(X::g, true, 'a', static_cast<long*>(0)); | |
173 | |
174 CallFunctionAsync(Y::g); | |
175 CallFunctionAsync(Y::g, 10); | |
176 CallFunctionAsync(Y::g, static_cast<unsigned int>(10), &x); | |
177 CallFunctionAsync(Y::g, true, 'a', static_cast<long*>(0)); | |
178 | |
179 CallMethodAsync(&x, &X::f); | |
180 CallMethodAsync(&x, &X::f, 10); | |
181 CallMethodAsync(&x, &X::f, static_cast<unsigned int>(10), &x); | |
182 CallMethodAsync(&x, &X::f, true, 'a', static_cast<long*>(0)); | |
183 | |
184 CallMethodAsync(&y, &Y::f); | |
185 CallMethodAsync(&y, &Y::f, 20); | |
186 CallMethodAsync(&y, &Y::f, static_cast<unsigned int>(10), &x); | |
187 CallMethodAsync(&y, &Y::f, true, 'a', static_cast<long*>(0)); | |
188 | |
189 static Z z; | |
190 CallMethodAsync(&z, | |
191 &Z::f, | |
192 'a', | |
193 static_cast<signed char>('a'), | |
194 static_cast<unsigned char>('a')); | |
195 | |
196 | |
197 CallMethodAsync(&z, &Z::f, &y); | |
198 | |
199 // Does not compile: template parameter 'P' is ambiguous | |
200 // const Y cy; | |
201 // CallMethod(&z, &Z::f, &cy); | |
202 | |
203 CallMethodAsync(&z, &Z::m); | |
204 | |
205 // Does not compile: template parameter 'T' is ambiguous | |
206 // const Z cz; | |
207 // CallMethod(&cz, &Z::m); | |
208 | |
209 // Does not compile: cannot convert from 'const Z *' to 'Z *const ' | |
210 // const Z cz; | |
211 // CallMethod<const Z, void>(&cz, &Z::m); | |
212 | |
213 CString msg(_T("test")); | |
214 CallFunctionAsync(Print, "test"); | |
215 CallFunctionAsync(Print1, &msg); | |
216 | |
217 WaitWithMessageLoopTimed(1000); | |
218 } | |
219 | |
220 | |
221 TEST(STATest, CompileTest) { | |
222 ASSERT_SUCCEEDED(InitializeApartment(0)); | |
223 | |
224 Thread t; | |
225 CompileTest compile_test; | |
226 t.Start(&compile_test); | |
227 EXPECT_TRUE(WaitWithMessageLoop(t.GetThreadHandle())); | |
228 | |
229 ASSERT_SUCCEEDED(UninitializeApartment()); | |
230 } | |
231 | |
232 TEST(STATest, RuntimeTest) { | |
233 ASSERT_SUCCEEDED(InitializeApartment(0)); | |
234 | |
235 Thread t; | |
236 RuntimeTest runtime_test; | |
237 t.Start(&runtime_test); | |
238 EXPECT_TRUE(WaitWithMessageLoop(t.GetThreadHandle())); | |
239 | |
240 ASSERT_SUCCEEDED(UninitializeApartment()); | |
241 } | |
242 | |
243 | |
244 TEST(STATest, AsyncTest) { | |
245 ASSERT_SUCCEEDED(InitializeApartment(0)); | |
246 | |
247 Thread t; | |
248 AsyncTest async_test; | |
249 t.Start(&async_test); | |
250 EXPECT_TRUE(WaitWithMessageLoop(t.GetThreadHandle())); | |
251 | |
252 ASSERT_SUCCEEDED(UninitializeApartment()); | |
253 } | |
254 | |
255 TEST(STATest, ApartmentRefCounting) { | |
256 // Check the reference counting is working. | |
257 ASSERT_SUCCEEDED(InitializeApartment(0)); | |
258 ASSERT_SUCCEEDED(InitializeApartment(0)); | |
259 ASSERT_SUCCEEDED(UninitializeApartment()); | |
260 ASSERT_SUCCEEDED(UninitializeApartment()); | |
261 | |
262 // The call below will raise an assert in the the STA code. | |
263 ExpectAsserts expect_asserts; | |
264 ASSERT_EQ(E_UNEXPECTED, UninitializeApartment()); | |
265 } | |
266 | |
267 TEST(STATest, ScopedSTA) { | |
268 { | |
269 scoped_sta sta(0); | |
270 ASSERT_SUCCEEDED(sta.result()); | |
271 } | |
272 { | |
273 scoped_sta sta(0); | |
274 ASSERT_SUCCEEDED(sta.result()); | |
275 } | |
276 { | |
277 scoped_sta sta1(0); | |
278 scoped_sta sta2(0); | |
279 ASSERT_SUCCEEDED(sta1.result()); | |
280 ASSERT_SUCCEEDED(sta2.result()); | |
281 } | |
282 | |
283 ExpectAsserts expect_asserts; | |
284 ASSERT_EQ(E_UNEXPECTED, UninitializeApartment()); | |
285 } | |
286 | |
287 } // namespace omaha | |
288 | |
OLD | NEW |