1*a65addddSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*a65addddSAndroid Build Coastguard Worker# Copyright 2016 Google Inc. All Rights Reserved. 3*a65addddSAndroid Build Coastguard Worker# 4*a65addddSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 5*a65addddSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 6*a65addddSAndroid Build Coastguard Worker# You may obtain a copy of the License at 7*a65addddSAndroid Build Coastguard Worker# 8*a65addddSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 9*a65addddSAndroid Build Coastguard Worker# 10*a65addddSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 11*a65addddSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS-IS" BASIS, 12*a65addddSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*a65addddSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 14*a65addddSAndroid Build Coastguard Worker# limitations under the License. 15*a65addddSAndroid Build Coastguard Worker 16*a65addddSAndroid Build Coastguard Workerfrom absl.testing import parameterized 17*a65addddSAndroid Build Coastguard Workerfrom fruit_test_common import * 18*a65addddSAndroid Build Coastguard Worker 19*a65addddSAndroid Build Coastguard WorkerCOMMON_DEFINITIONS = ''' 20*a65addddSAndroid Build Coastguard Worker #include "test_common.h" 21*a65addddSAndroid Build Coastguard Worker 22*a65addddSAndroid Build Coastguard Worker struct Annotation1 {}; 23*a65addddSAndroid Build Coastguard Worker ''' 24*a65addddSAndroid Build Coastguard Worker 25*a65addddSAndroid Build Coastguard Workerdef escape_regex(regex): 26*a65addddSAndroid Build Coastguard Worker # We un-escape the space because we strip the spaces in fruit_test_common, and this would otherwise leave a 27*a65addddSAndroid Build Coastguard Worker # stray backslash. 28*a65addddSAndroid Build Coastguard Worker return re.escape(regex).replace('\\ ', ' ') 29*a65addddSAndroid Build Coastguard Worker 30*a65addddSAndroid Build Coastguard Workerclass TestRegisterInstance(parameterized.TestCase): 31*a65addddSAndroid Build Coastguard Worker def test_bind_instance_success(self): 32*a65addddSAndroid Build Coastguard Worker source = ''' 33*a65addddSAndroid Build Coastguard Worker struct X { 34*a65addddSAndroid Build Coastguard Worker int n; 35*a65addddSAndroid Build Coastguard Worker 36*a65addddSAndroid Build Coastguard Worker X(int n) 37*a65addddSAndroid Build Coastguard Worker : n(n) { 38*a65addddSAndroid Build Coastguard Worker } 39*a65addddSAndroid Build Coastguard Worker }; 40*a65addddSAndroid Build Coastguard Worker 41*a65addddSAndroid Build Coastguard Worker fruit::Component<X> getComponent(X* x) { 42*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 43*a65addddSAndroid Build Coastguard Worker .bindInstance(*x); 44*a65addddSAndroid Build Coastguard Worker } 45*a65addddSAndroid Build Coastguard Worker 46*a65addddSAndroid Build Coastguard Worker int main() { 47*a65addddSAndroid Build Coastguard Worker X x(34); 48*a65addddSAndroid Build Coastguard Worker fruit::Injector<X> injector(getComponent, &x); 49*a65addddSAndroid Build Coastguard Worker X& x1 = injector.get<X&>(); 50*a65addddSAndroid Build Coastguard Worker Assert(&x == &x1); 51*a65addddSAndroid Build Coastguard Worker } 52*a65addddSAndroid Build Coastguard Worker ''' 53*a65addddSAndroid Build Coastguard Worker expect_success(COMMON_DEFINITIONS, source) 54*a65addddSAndroid Build Coastguard Worker 55*a65addddSAndroid Build Coastguard Worker def test_bind_instance_annotated_success(self): 56*a65addddSAndroid Build Coastguard Worker source = ''' 57*a65addddSAndroid Build Coastguard Worker struct X { 58*a65addddSAndroid Build Coastguard Worker int n; 59*a65addddSAndroid Build Coastguard Worker 60*a65addddSAndroid Build Coastguard Worker X(int n) 61*a65addddSAndroid Build Coastguard Worker : n(n) { 62*a65addddSAndroid Build Coastguard Worker } 63*a65addddSAndroid Build Coastguard Worker }; 64*a65addddSAndroid Build Coastguard Worker 65*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Annotated<Annotation1, X>> getComponent(X* x) { 66*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 67*a65addddSAndroid Build Coastguard Worker .bindInstance<fruit::Annotated<Annotation1, X>>(*x); 68*a65addddSAndroid Build Coastguard Worker } 69*a65addddSAndroid Build Coastguard Worker 70*a65addddSAndroid Build Coastguard Worker int main() { 71*a65addddSAndroid Build Coastguard Worker X x(34); 72*a65addddSAndroid Build Coastguard Worker fruit::Injector<fruit::Annotated<Annotation1, X>> injector(getComponent, &x); 73*a65addddSAndroid Build Coastguard Worker X& x1 = injector.get<fruit::Annotated<Annotation1, X&>>(); 74*a65addddSAndroid Build Coastguard Worker Assert(&x == &x1); 75*a65addddSAndroid Build Coastguard Worker } 76*a65addddSAndroid Build Coastguard Worker ''' 77*a65addddSAndroid Build Coastguard Worker expect_success(COMMON_DEFINITIONS, source) 78*a65addddSAndroid Build Coastguard Worker 79*a65addddSAndroid Build Coastguard Worker def test_bind_const_instance_success(self): 80*a65addddSAndroid Build Coastguard Worker source = ''' 81*a65addddSAndroid Build Coastguard Worker struct X { 82*a65addddSAndroid Build Coastguard Worker int n; 83*a65addddSAndroid Build Coastguard Worker 84*a65addddSAndroid Build Coastguard Worker X(int n) 85*a65addddSAndroid Build Coastguard Worker : n(n) { 86*a65addddSAndroid Build Coastguard Worker } 87*a65addddSAndroid Build Coastguard Worker }; 88*a65addddSAndroid Build Coastguard Worker 89*a65addddSAndroid Build Coastguard Worker fruit::Component<const X> getComponent(const X* x) { 90*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 91*a65addddSAndroid Build Coastguard Worker .bindInstance(*x); 92*a65addddSAndroid Build Coastguard Worker } 93*a65addddSAndroid Build Coastguard Worker 94*a65addddSAndroid Build Coastguard Worker const X x(34); 95*a65addddSAndroid Build Coastguard Worker 96*a65addddSAndroid Build Coastguard Worker int main() { 97*a65addddSAndroid Build Coastguard Worker fruit::Injector<const X> injector(getComponent, &x); 98*a65addddSAndroid Build Coastguard Worker const X& x1 = injector.get<const X&>(); 99*a65addddSAndroid Build Coastguard Worker Assert(&x == &x1); 100*a65addddSAndroid Build Coastguard Worker } 101*a65addddSAndroid Build Coastguard Worker ''' 102*a65addddSAndroid Build Coastguard Worker expect_success(COMMON_DEFINITIONS, source) 103*a65addddSAndroid Build Coastguard Worker 104*a65addddSAndroid Build Coastguard Worker def test_bind_const_instance_annotated_success(self): 105*a65addddSAndroid Build Coastguard Worker source = ''' 106*a65addddSAndroid Build Coastguard Worker struct X { 107*a65addddSAndroid Build Coastguard Worker int n; 108*a65addddSAndroid Build Coastguard Worker 109*a65addddSAndroid Build Coastguard Worker X(int n) 110*a65addddSAndroid Build Coastguard Worker : n(n) { 111*a65addddSAndroid Build Coastguard Worker } 112*a65addddSAndroid Build Coastguard Worker }; 113*a65addddSAndroid Build Coastguard Worker 114*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Annotated<Annotation1, const X>> getComponent(const X* x) { 115*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 116*a65addddSAndroid Build Coastguard Worker .bindInstance<fruit::Annotated<Annotation1, X>>(*x); 117*a65addddSAndroid Build Coastguard Worker } 118*a65addddSAndroid Build Coastguard Worker 119*a65addddSAndroid Build Coastguard Worker const X x(34); 120*a65addddSAndroid Build Coastguard Worker 121*a65addddSAndroid Build Coastguard Worker int main() { 122*a65addddSAndroid Build Coastguard Worker fruit::Injector<fruit::Annotated<Annotation1, const X>> injector(getComponent, &x); 123*a65addddSAndroid Build Coastguard Worker const X& x1 = injector.get<fruit::Annotated<Annotation1, const X&>>(); 124*a65addddSAndroid Build Coastguard Worker Assert(&x == &x1); 125*a65addddSAndroid Build Coastguard Worker } 126*a65addddSAndroid Build Coastguard Worker ''' 127*a65addddSAndroid Build Coastguard Worker expect_success(COMMON_DEFINITIONS, source) 128*a65addddSAndroid Build Coastguard Worker 129*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 130*a65addddSAndroid Build Coastguard Worker ('X', 'X', 'X*', 'X*'), 131*a65addddSAndroid Build Coastguard Worker ('X', 'const X', 'const X*', 'const X*'), 132*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>', 'X*', 'fruit::Annotated<Annotation1, X*>'), 133*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, const X>', 'const X*', 'fruit::Annotated<Annotation1, const X*>'), 134*a65addddSAndroid Build Coastguard Worker ]) 135*a65addddSAndroid Build Coastguard Worker def test_bind_instance_two_explicit_type_arguments_success(self, XAnnot, MaybeConstXAnnot, XPtr, XPtrAnnot): 136*a65addddSAndroid Build Coastguard Worker source = ''' 137*a65addddSAndroid Build Coastguard Worker struct X { 138*a65addddSAndroid Build Coastguard Worker int n; 139*a65addddSAndroid Build Coastguard Worker 140*a65addddSAndroid Build Coastguard Worker X(int n) 141*a65addddSAndroid Build Coastguard Worker : n(n) { 142*a65addddSAndroid Build Coastguard Worker } 143*a65addddSAndroid Build Coastguard Worker }; 144*a65addddSAndroid Build Coastguard Worker 145*a65addddSAndroid Build Coastguard Worker fruit::Component<MaybeConstXAnnot> getComponent(XPtr x) { 146*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 147*a65addddSAndroid Build Coastguard Worker .bindInstance<XAnnot, X>(*x); 148*a65addddSAndroid Build Coastguard Worker } 149*a65addddSAndroid Build Coastguard Worker 150*a65addddSAndroid Build Coastguard Worker int main() { 151*a65addddSAndroid Build Coastguard Worker X x(34); 152*a65addddSAndroid Build Coastguard Worker fruit::Injector<MaybeConstXAnnot> injector(getComponent, &x); 153*a65addddSAndroid Build Coastguard Worker XPtr x1 = injector.get<XPtrAnnot>(); 154*a65addddSAndroid Build Coastguard Worker Assert(&x == x1); 155*a65addddSAndroid Build Coastguard Worker } 156*a65addddSAndroid Build Coastguard Worker ''' 157*a65addddSAndroid Build Coastguard Worker expect_success(COMMON_DEFINITIONS, source, locals()) 158*a65addddSAndroid Build Coastguard Worker 159*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 160*a65addddSAndroid Build Coastguard Worker 'X', 161*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 162*a65addddSAndroid Build Coastguard Worker ]) 163*a65addddSAndroid Build Coastguard Worker def test_bind_instance_abstract_class_ok(self, XAnnot): 164*a65addddSAndroid Build Coastguard Worker source = ''' 165*a65addddSAndroid Build Coastguard Worker struct X { 166*a65addddSAndroid Build Coastguard Worker virtual void foo() = 0; 167*a65addddSAndroid Build Coastguard Worker }; 168*a65addddSAndroid Build Coastguard Worker 169*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponentForInstanceHelper(X* x) { 170*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 171*a65addddSAndroid Build Coastguard Worker .bindInstance<XAnnot, X>(*x); 172*a65addddSAndroid Build Coastguard Worker } 173*a65addddSAndroid Build Coastguard Worker 174*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> getComponentForInstance(X* x) { 175*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 176*a65addddSAndroid Build Coastguard Worker .install(getComponentForInstanceHelper, x) 177*a65addddSAndroid Build Coastguard Worker .bindInstance<XAnnot, X>(*x); 178*a65addddSAndroid Build Coastguard Worker } 179*a65addddSAndroid Build Coastguard Worker ''' 180*a65addddSAndroid Build Coastguard Worker expect_success( 181*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 182*a65addddSAndroid Build Coastguard Worker source, 183*a65addddSAndroid Build Coastguard Worker locals()) 184*a65addddSAndroid Build Coastguard Worker 185*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 186*a65addddSAndroid Build Coastguard Worker ('int', 'int*'), 187*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, int>', 'fruit::Annotated<Annotation1, int*>'), 188*a65addddSAndroid Build Coastguard Worker ]) 189*a65addddSAndroid Build Coastguard Worker def test_bind_instance_multiple_equivalent_bindings_success(self, intAnnot, intPtrAnnot): 190*a65addddSAndroid Build Coastguard Worker source = ''' 191*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponentForInstanceHelper(int* n) { 192*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 193*a65addddSAndroid Build Coastguard Worker .bindInstance<intAnnot, int>(*n); 194*a65addddSAndroid Build Coastguard Worker } 195*a65addddSAndroid Build Coastguard Worker 196*a65addddSAndroid Build Coastguard Worker fruit::Component<intAnnot> getComponentForInstance(int* n) { 197*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 198*a65addddSAndroid Build Coastguard Worker .install(getComponentForInstanceHelper, n) 199*a65addddSAndroid Build Coastguard Worker .bindInstance<intAnnot, int>(*n); 200*a65addddSAndroid Build Coastguard Worker } 201*a65addddSAndroid Build Coastguard Worker 202*a65addddSAndroid Build Coastguard Worker int main() { 203*a65addddSAndroid Build Coastguard Worker int n = 5; 204*a65addddSAndroid Build Coastguard Worker fruit::Injector<intAnnot> injector(getComponentForInstance, &n); 205*a65addddSAndroid Build Coastguard Worker if (injector.get<intPtrAnnot>() != &n) 206*a65addddSAndroid Build Coastguard Worker abort(); 207*a65addddSAndroid Build Coastguard Worker } 208*a65addddSAndroid Build Coastguard Worker ''' 209*a65addddSAndroid Build Coastguard Worker expect_success( 210*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 211*a65addddSAndroid Build Coastguard Worker source, 212*a65addddSAndroid Build Coastguard Worker locals()) 213*a65addddSAndroid Build Coastguard Worker 214*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 215*a65addddSAndroid Build Coastguard Worker ('int', 'int*'), 216*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, int>', 'fruit::Annotated<Annotation1, int*>'), 217*a65addddSAndroid Build Coastguard Worker ]) 218*a65addddSAndroid Build Coastguard Worker def test_bind_instance_multiple_equivalent_bindings_different_constness_success(self, intAnnot, intPtrAnnot): 219*a65addddSAndroid Build Coastguard Worker source = ''' 220*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponentForInstanceHelper(const int* n) { 221*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 222*a65addddSAndroid Build Coastguard Worker .bindInstance<intAnnot, int>(*n); 223*a65addddSAndroid Build Coastguard Worker } 224*a65addddSAndroid Build Coastguard Worker 225*a65addddSAndroid Build Coastguard Worker fruit::Component<intAnnot> getComponentForInstance(int* n) { 226*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 227*a65addddSAndroid Build Coastguard Worker .install(getComponentForInstanceHelper, n) 228*a65addddSAndroid Build Coastguard Worker .bindInstance<intAnnot, int>(*n); 229*a65addddSAndroid Build Coastguard Worker } 230*a65addddSAndroid Build Coastguard Worker 231*a65addddSAndroid Build Coastguard Worker int main() { 232*a65addddSAndroid Build Coastguard Worker int n = 5; 233*a65addddSAndroid Build Coastguard Worker fruit::Injector<intAnnot> injector(getComponentForInstance, &n); 234*a65addddSAndroid Build Coastguard Worker if (injector.get<intPtrAnnot>() != &n) 235*a65addddSAndroid Build Coastguard Worker abort(); 236*a65addddSAndroid Build Coastguard Worker } 237*a65addddSAndroid Build Coastguard Worker ''' 238*a65addddSAndroid Build Coastguard Worker expect_success( 239*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 240*a65addddSAndroid Build Coastguard Worker source, 241*a65addddSAndroid Build Coastguard Worker locals()) 242*a65addddSAndroid Build Coastguard Worker 243*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 244*a65addddSAndroid Build Coastguard Worker ('int', 'int*'), 245*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, int>', 'fruit::Annotated<Annotation1, int*>'), 246*a65addddSAndroid Build Coastguard Worker ]) 247*a65addddSAndroid Build Coastguard Worker def test_bind_instance_multiple_equivalent_bindings_different_constness_other_order_success(self, intAnnot, intPtrAnnot): 248*a65addddSAndroid Build Coastguard Worker source = ''' 249*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponentForInstanceHelper(const int* n) { 250*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 251*a65addddSAndroid Build Coastguard Worker .bindInstance<intAnnot, int>(*n); 252*a65addddSAndroid Build Coastguard Worker } 253*a65addddSAndroid Build Coastguard Worker 254*a65addddSAndroid Build Coastguard Worker fruit::Component<intAnnot> getComponentForInstance(int* n) { 255*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 256*a65addddSAndroid Build Coastguard Worker .bindInstance<intAnnot, int>(*n) 257*a65addddSAndroid Build Coastguard Worker .install(getComponentForInstanceHelper, n); 258*a65addddSAndroid Build Coastguard Worker } 259*a65addddSAndroid Build Coastguard Worker 260*a65addddSAndroid Build Coastguard Worker int main() { 261*a65addddSAndroid Build Coastguard Worker int n = 5; 262*a65addddSAndroid Build Coastguard Worker fruit::Injector<intAnnot> injector(getComponentForInstance, &n); 263*a65addddSAndroid Build Coastguard Worker if (injector.get<intPtrAnnot>() != &n) 264*a65addddSAndroid Build Coastguard Worker abort(); 265*a65addddSAndroid Build Coastguard Worker } 266*a65addddSAndroid Build Coastguard Worker ''' 267*a65addddSAndroid Build Coastguard Worker expect_success( 268*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 269*a65addddSAndroid Build Coastguard Worker source, 270*a65addddSAndroid Build Coastguard Worker locals()) 271*a65addddSAndroid Build Coastguard Worker 272*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 273*a65addddSAndroid Build Coastguard Worker 'X*', 274*a65addddSAndroid Build Coastguard Worker 'const X*', 275*a65addddSAndroid Build Coastguard Worker 'std::shared_ptr<X>', 276*a65addddSAndroid Build Coastguard Worker ]) 277*a65addddSAndroid Build Coastguard Worker def test_bind_instance_non_normalized_type_error(self, XVariant): 278*a65addddSAndroid Build Coastguard Worker if XVariant.endswith('&'): 279*a65addddSAndroid Build Coastguard Worker XVariantRegexp = escape_regex(XVariant[:-1]) 280*a65addddSAndroid Build Coastguard Worker else: 281*a65addddSAndroid Build Coastguard Worker XVariantRegexp = escape_regex(XVariant) 282*a65addddSAndroid Build Coastguard Worker source = ''' 283*a65addddSAndroid Build Coastguard Worker struct X {}; 284*a65addddSAndroid Build Coastguard Worker 285*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent(XVariant x) { 286*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 287*a65addddSAndroid Build Coastguard Worker .bindInstance(x); 288*a65addddSAndroid Build Coastguard Worker } 289*a65addddSAndroid Build Coastguard Worker ''' 290*a65addddSAndroid Build Coastguard Worker expect_compile_error( 291*a65addddSAndroid Build Coastguard Worker 'NonClassTypeError<XVariantRegexp,X>', 292*a65addddSAndroid Build Coastguard Worker 'A non-class type T was specified. Use C instead.', 293*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 294*a65addddSAndroid Build Coastguard Worker source, 295*a65addddSAndroid Build Coastguard Worker locals()) 296*a65addddSAndroid Build Coastguard Worker 297*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 298*a65addddSAndroid Build Coastguard Worker ('const X', r'const X'), 299*a65addddSAndroid Build Coastguard Worker ('X*', r'X\*'), 300*a65addddSAndroid Build Coastguard Worker ('const X*', r'const X\*'), 301*a65addddSAndroid Build Coastguard Worker ('X&', r'X&'), 302*a65addddSAndroid Build Coastguard Worker ('const X&', r'const X&'), 303*a65addddSAndroid Build Coastguard Worker ('std::shared_ptr<X>', r'std::shared_ptr<X>'), 304*a65addddSAndroid Build Coastguard Worker ]) 305*a65addddSAndroid Build Coastguard Worker def test_bind_instance_non_normalized_type_error_with_annotation(self, XVariant, XVariantRegexp): 306*a65addddSAndroid Build Coastguard Worker source = ''' 307*a65addddSAndroid Build Coastguard Worker struct X {}; 308*a65addddSAndroid Build Coastguard Worker 309*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent(XVariant x) { 310*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 311*a65addddSAndroid Build Coastguard Worker .bindInstance<fruit::Annotated<Annotation1, XVariant>>(x); 312*a65addddSAndroid Build Coastguard Worker } 313*a65addddSAndroid Build Coastguard Worker ''' 314*a65addddSAndroid Build Coastguard Worker expect_compile_error( 315*a65addddSAndroid Build Coastguard Worker 'NonClassTypeError<XVariantRegexp,X>', 316*a65addddSAndroid Build Coastguard Worker 'A non-class type T was specified. Use C instead.', 317*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 318*a65addddSAndroid Build Coastguard Worker source, 319*a65addddSAndroid Build Coastguard Worker locals()) 320*a65addddSAndroid Build Coastguard Worker 321*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 322*a65addddSAndroid Build Coastguard Worker ('const X', 'const X'), 323*a65addddSAndroid Build Coastguard Worker ('X*', 'X*'), 324*a65addddSAndroid Build Coastguard Worker ('const X*', 'const X*'), 325*a65addddSAndroid Build Coastguard Worker ('X&', 'X&'), 326*a65addddSAndroid Build Coastguard Worker ('const X&', 'const X&'), 327*a65addddSAndroid Build Coastguard Worker ('std::shared_ptr<X>', 'std::shared_ptr<X>'), 328*a65addddSAndroid Build Coastguard Worker 329*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, const X>', 'const X'), 330*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X*>', 'X*'), 331*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, const X*>', 'const X*'), 332*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X&>', 'X&'), 333*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, const X&>', 'const X&'), 334*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, std::shared_ptr<X>>', 'std::shared_ptr<X>'), 335*a65addddSAndroid Build Coastguard Worker 336*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'const X'), 337*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'X*'), 338*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'const X*'), 339*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'X&'), 340*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'const X&'), 341*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'std::shared_ptr<X>'), 342*a65addddSAndroid Build Coastguard Worker ]) 343*a65addddSAndroid Build Coastguard Worker def test_bind_instance_non_normalized_type_error_two_explicit_type_arguments(self, XAnnotVariant, XVariant): 344*a65addddSAndroid Build Coastguard Worker XVariantRegexp = escape_regex(XVariant) 345*a65addddSAndroid Build Coastguard Worker source = ''' 346*a65addddSAndroid Build Coastguard Worker struct X {}; 347*a65addddSAndroid Build Coastguard Worker 348*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent(XVariant x) { 349*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 350*a65addddSAndroid Build Coastguard Worker .bindInstance<XAnnotVariant, XVariant>(x); 351*a65addddSAndroid Build Coastguard Worker } 352*a65addddSAndroid Build Coastguard Worker ''' 353*a65addddSAndroid Build Coastguard Worker expect_compile_error( 354*a65addddSAndroid Build Coastguard Worker 'NonClassTypeError<XVariantRegexp,X>', 355*a65addddSAndroid Build Coastguard Worker 'A non-class type T was specified. Use C instead.', 356*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 357*a65addddSAndroid Build Coastguard Worker source, 358*a65addddSAndroid Build Coastguard Worker locals()) 359*a65addddSAndroid Build Coastguard Worker 360*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 361*a65addddSAndroid Build Coastguard Worker ('X*', r'X\*'), 362*a65addddSAndroid Build Coastguard Worker ('const X*', r'const X\*'), 363*a65addddSAndroid Build Coastguard Worker ('std::shared_ptr<X>', r'std::shared_ptr<X>'), 364*a65addddSAndroid Build Coastguard Worker ]) 365*a65addddSAndroid Build Coastguard Worker def test_register_instance_error_must_be_reference(self, XVariant, XVariantRegex): 366*a65addddSAndroid Build Coastguard Worker source = ''' 367*a65addddSAndroid Build Coastguard Worker struct X {}; 368*a65addddSAndroid Build Coastguard Worker 369*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponentForInstance(XVariant x) { 370*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 371*a65addddSAndroid Build Coastguard Worker .bindInstance(x); 372*a65addddSAndroid Build Coastguard Worker } 373*a65addddSAndroid Build Coastguard Worker ''' 374*a65addddSAndroid Build Coastguard Worker expect_compile_error( 375*a65addddSAndroid Build Coastguard Worker 'NonClassTypeError<XVariantRegex,X>', 376*a65addddSAndroid Build Coastguard Worker 'A non-class type T was specified. Use C instead.', 377*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 378*a65addddSAndroid Build Coastguard Worker source, 379*a65addddSAndroid Build Coastguard Worker locals()) 380*a65addddSAndroid Build Coastguard Worker 381*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 382*a65addddSAndroid Build Coastguard Worker ('X*', r'X\*'), 383*a65addddSAndroid Build Coastguard Worker ('const X*', r'const X\*'), 384*a65addddSAndroid Build Coastguard Worker ('std::shared_ptr<X>', r'std::shared_ptr<X>'), 385*a65addddSAndroid Build Coastguard Worker ]) 386*a65addddSAndroid Build Coastguard Worker def test_register_instance_error_must_be_reference_with_annotation(self, XVariant, XVariantRegex): 387*a65addddSAndroid Build Coastguard Worker source = ''' 388*a65addddSAndroid Build Coastguard Worker struct X {}; 389*a65addddSAndroid Build Coastguard Worker 390*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponentForInstance(XVariant x) { 391*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 392*a65addddSAndroid Build Coastguard Worker .bindInstance<fruit::Annotated<Annotation1, X>>(x); 393*a65addddSAndroid Build Coastguard Worker } 394*a65addddSAndroid Build Coastguard Worker ''' 395*a65addddSAndroid Build Coastguard Worker expect_compile_error( 396*a65addddSAndroid Build Coastguard Worker 'NonClassTypeError<XVariantRegex,X>', 397*a65addddSAndroid Build Coastguard Worker 'A non-class type T was specified. Use C instead.', 398*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 399*a65addddSAndroid Build Coastguard Worker source, 400*a65addddSAndroid Build Coastguard Worker locals()) 401*a65addddSAndroid Build Coastguard Worker 402*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 403*a65addddSAndroid Build Coastguard Worker 'X', 404*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 405*a65addddSAndroid Build Coastguard Worker ]) 406*a65addddSAndroid Build Coastguard Worker def test_bind_instance_mismatched_type_arguments(self, XAnnot): 407*a65addddSAndroid Build Coastguard Worker source = ''' 408*a65addddSAndroid Build Coastguard Worker struct X {}; 409*a65addddSAndroid Build Coastguard Worker 410*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent(int* n) { 411*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 412*a65addddSAndroid Build Coastguard Worker .bindInstance<XAnnot, int>(*n); 413*a65addddSAndroid Build Coastguard Worker } 414*a65addddSAndroid Build Coastguard Worker ''' 415*a65addddSAndroid Build Coastguard Worker expect_compile_error( 416*a65addddSAndroid Build Coastguard Worker 'TypeMismatchInBindInstanceError<X,int>', 417*a65addddSAndroid Build Coastguard Worker 'A type parameter was specified in bindInstance.. but it doesn.t match the value type', 418*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 419*a65addddSAndroid Build Coastguard Worker source, 420*a65addddSAndroid Build Coastguard Worker locals()) 421*a65addddSAndroid Build Coastguard Worker 422*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 423*a65addddSAndroid Build Coastguard Worker ('Base', 'Base*'), 424*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, Base>', 'fruit::Annotated<Annotation1, Base*>'), 425*a65addddSAndroid Build Coastguard Worker ]) 426*a65addddSAndroid Build Coastguard Worker def test_bind_instance_to_subclass(self, BaseAnnot, BasePtrAnnot): 427*a65addddSAndroid Build Coastguard Worker source = ''' 428*a65addddSAndroid Build Coastguard Worker struct Base { 429*a65addddSAndroid Build Coastguard Worker virtual void f() = 0; 430*a65addddSAndroid Build Coastguard Worker virtual ~Base() { 431*a65addddSAndroid Build Coastguard Worker } 432*a65addddSAndroid Build Coastguard Worker }; 433*a65addddSAndroid Build Coastguard Worker 434*a65addddSAndroid Build Coastguard Worker struct Derived : public Base { 435*a65addddSAndroid Build Coastguard Worker void f() override { 436*a65addddSAndroid Build Coastguard Worker } 437*a65addddSAndroid Build Coastguard Worker }; 438*a65addddSAndroid Build Coastguard Worker 439*a65addddSAndroid Build Coastguard Worker fruit::Component<BaseAnnot> getComponent(Derived* derived) { 440*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 441*a65addddSAndroid Build Coastguard Worker .bindInstance<BaseAnnot, Base>(*derived); 442*a65addddSAndroid Build Coastguard Worker } 443*a65addddSAndroid Build Coastguard Worker 444*a65addddSAndroid Build Coastguard Worker int main() { 445*a65addddSAndroid Build Coastguard Worker Derived derived; 446*a65addddSAndroid Build Coastguard Worker fruit::Injector<BaseAnnot> injector(getComponent, &derived); 447*a65addddSAndroid Build Coastguard Worker Base* base = injector.get<BasePtrAnnot>(); 448*a65addddSAndroid Build Coastguard Worker base->f(); 449*a65addddSAndroid Build Coastguard Worker } 450*a65addddSAndroid Build Coastguard Worker ''' 451*a65addddSAndroid Build Coastguard Worker expect_success(COMMON_DEFINITIONS, source, locals()) 452*a65addddSAndroid Build Coastguard Worker 453*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 454*a65addddSAndroid Build Coastguard Worker ('X**', r'X\*\*'), 455*a65addddSAndroid Build Coastguard Worker ('std::shared_ptr<X>*', r'std::shared_ptr<X>\*'), 456*a65addddSAndroid Build Coastguard Worker ('X*&', r'X\*&'), 457*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X**>', r'X\*\*'), 458*a65addddSAndroid Build Coastguard Worker ]) 459*a65addddSAndroid Build Coastguard Worker def test_bind_instance_type_not_normalized(self, XVariant, XVariantRegex): 460*a65addddSAndroid Build Coastguard Worker source = ''' 461*a65addddSAndroid Build Coastguard Worker struct X {}; 462*a65addddSAndroid Build Coastguard Worker 463*a65addddSAndroid Build Coastguard Worker using XVariantT = XVariant; 464*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent(XVariantT x) { 465*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 466*a65addddSAndroid Build Coastguard Worker .bindInstance<XVariant, XVariant>(x); 467*a65addddSAndroid Build Coastguard Worker } 468*a65addddSAndroid Build Coastguard Worker ''' 469*a65addddSAndroid Build Coastguard Worker expect_compile_error( 470*a65addddSAndroid Build Coastguard Worker 'NonClassTypeError<XVariantRegex,X>', 471*a65addddSAndroid Build Coastguard Worker 'A non-class type T was specified.', 472*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 473*a65addddSAndroid Build Coastguard Worker source, 474*a65addddSAndroid Build Coastguard Worker locals()) 475*a65addddSAndroid Build Coastguard Worker 476*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 477*a65addddSAndroid Build Coastguard Worker ('X(*)()', r'X(\((__cdecl)?\*\))?\((void)?\)'), 478*a65addddSAndroid Build Coastguard Worker ]) 479*a65addddSAndroid Build Coastguard Worker def test_bind_instance_type_not_injectable_error(self, XVariant, XVariantRegex): 480*a65addddSAndroid Build Coastguard Worker source = ''' 481*a65addddSAndroid Build Coastguard Worker struct X {}; 482*a65addddSAndroid Build Coastguard Worker 483*a65addddSAndroid Build Coastguard Worker using XVariantT = XVariant; 484*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent(XVariantT x) { 485*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 486*a65addddSAndroid Build Coastguard Worker .bindInstance<XVariant, XVariant>(x); 487*a65addddSAndroid Build Coastguard Worker } 488*a65addddSAndroid Build Coastguard Worker ''' 489*a65addddSAndroid Build Coastguard Worker expect_compile_error( 490*a65addddSAndroid Build Coastguard Worker 'NonInjectableTypeError<XVariantRegex>', 491*a65addddSAndroid Build Coastguard Worker 'The type T is not injectable.', 492*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 493*a65addddSAndroid Build Coastguard Worker source, 494*a65addddSAndroid Build Coastguard Worker locals()) 495*a65addddSAndroid Build Coastguard Worker 496*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__': 497*a65addddSAndroid Build Coastguard Worker absltest.main() 498