| 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 |