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 Workerclass TestMultibindingsBindInstance(parameterized.TestCase): 26*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 27*a65addddSAndroid Build Coastguard Worker 'X', 28*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 29*a65addddSAndroid Build Coastguard Worker ]) 30*a65addddSAndroid Build Coastguard Worker def test_multibindings_bind_instance_ok(self, XAnnot): 31*a65addddSAndroid Build Coastguard Worker source = ''' 32*a65addddSAndroid Build Coastguard Worker struct X {}; 33*a65addddSAndroid Build Coastguard Worker 34*a65addddSAndroid Build Coastguard Worker X x; 35*a65addddSAndroid Build Coastguard Worker 36*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 37*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 38*a65addddSAndroid Build Coastguard Worker .addInstanceMultibinding<XAnnot, X>(x); 39*a65addddSAndroid Build Coastguard Worker } 40*a65addddSAndroid Build Coastguard Worker 41*a65addddSAndroid Build Coastguard Worker int main() { 42*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getComponent); 43*a65addddSAndroid Build Coastguard Worker 44*a65addddSAndroid Build Coastguard Worker std::vector<X*> multibindings = injector.getMultibindings<XAnnot>(); 45*a65addddSAndroid Build Coastguard Worker Assert(multibindings.size() == 1); 46*a65addddSAndroid Build Coastguard Worker Assert(multibindings[0] == &x); 47*a65addddSAndroid Build Coastguard Worker } 48*a65addddSAndroid Build Coastguard Worker ''' 49*a65addddSAndroid Build Coastguard Worker expect_success( 50*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 51*a65addddSAndroid Build Coastguard Worker source, 52*a65addddSAndroid Build Coastguard Worker locals()) 53*a65addddSAndroid Build Coastguard Worker 54*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 55*a65addddSAndroid Build Coastguard Worker 'X', 56*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 57*a65addddSAndroid Build Coastguard Worker ]) 58*a65addddSAndroid Build Coastguard Worker def test_multibindings_bind_const_instance_error(self, XAnnot): 59*a65addddSAndroid Build Coastguard Worker source = ''' 60*a65addddSAndroid Build Coastguard Worker struct X {}; 61*a65addddSAndroid Build Coastguard Worker 62*a65addddSAndroid Build Coastguard Worker const X x{}; 63*a65addddSAndroid Build Coastguard Worker 64*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 65*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 66*a65addddSAndroid Build Coastguard Worker .addInstanceMultibinding<XAnnot, X>(x); 67*a65addddSAndroid Build Coastguard Worker } 68*a65addddSAndroid Build Coastguard Worker ''' 69*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 70*a65addddSAndroid Build Coastguard Worker r'candidate function not viable: 1st argument \(.const X.\) would lose const qualifier' 71*a65addddSAndroid Build Coastguard Worker r'|no matching function for call to .fruit::PartialComponent<.*>::addInstanceMultibinding(<XAnnot,X>)?\(const X&\).' 72*a65addddSAndroid Build Coastguard Worker r'|error: no matching member function for call to .addInstanceMultibinding.' 73*a65addddSAndroid Build Coastguard Worker r'|cannot convert argument 1 from .const X. to .X &.', 74*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 75*a65addddSAndroid Build Coastguard Worker source, 76*a65addddSAndroid Build Coastguard Worker locals()) 77*a65addddSAndroid Build Coastguard Worker 78*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 79*a65addddSAndroid Build Coastguard Worker 'X', 80*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 81*a65addddSAndroid Build Coastguard Worker ]) 82*a65addddSAndroid Build Coastguard Worker def test_multibindings_bind_instance_vector(self, XAnnot): 83*a65addddSAndroid Build Coastguard Worker source = ''' 84*a65addddSAndroid Build Coastguard Worker struct X {}; 85*a65addddSAndroid Build Coastguard Worker 86*a65addddSAndroid Build Coastguard Worker std::vector<X> values = {X(), X()}; 87*a65addddSAndroid Build Coastguard Worker 88*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 89*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 90*a65addddSAndroid Build Coastguard Worker .addInstanceMultibindings<XAnnot, X>(values); 91*a65addddSAndroid Build Coastguard Worker } 92*a65addddSAndroid Build Coastguard Worker 93*a65addddSAndroid Build Coastguard Worker int main() { 94*a65addddSAndroid Build Coastguard Worker fruit::Injector<> injector(getComponent); 95*a65addddSAndroid Build Coastguard Worker 96*a65addddSAndroid Build Coastguard Worker std::vector<X*> multibindings = injector.getMultibindings<XAnnot>(); 97*a65addddSAndroid Build Coastguard Worker Assert(multibindings.size() == 2); 98*a65addddSAndroid Build Coastguard Worker Assert(multibindings[0] == &(values[0])); 99*a65addddSAndroid Build Coastguard Worker Assert(multibindings[1] == &(values[1])); 100*a65addddSAndroid Build Coastguard Worker } 101*a65addddSAndroid Build Coastguard Worker ''' 102*a65addddSAndroid Build Coastguard Worker expect_success( 103*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 104*a65addddSAndroid Build Coastguard Worker source, 105*a65addddSAndroid Build Coastguard Worker locals()) 106*a65addddSAndroid Build Coastguard Worker 107*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 108*a65addddSAndroid Build Coastguard Worker 'X', 109*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 110*a65addddSAndroid Build Coastguard Worker ]) 111*a65addddSAndroid Build Coastguard Worker def test_multibindings_bind_const_instance_vector_error(self, XAnnot): 112*a65addddSAndroid Build Coastguard Worker source = ''' 113*a65addddSAndroid Build Coastguard Worker struct X {}; 114*a65addddSAndroid Build Coastguard Worker 115*a65addddSAndroid Build Coastguard Worker const std::vector<X> values{}; 116*a65addddSAndroid Build Coastguard Worker 117*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 118*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 119*a65addddSAndroid Build Coastguard Worker .addInstanceMultibindings<XAnnot, X>(values); 120*a65addddSAndroid Build Coastguard Worker } 121*a65addddSAndroid Build Coastguard Worker ''' 122*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 123*a65addddSAndroid Build Coastguard Worker r'candidate function not viable: 1st argument \(.const std::vector<X>.\) would lose const qualifier' 124*a65addddSAndroid Build Coastguard Worker r'|cannot convert .values. \(type .const std::(__debug::)?vector<X>.\) to type .std::(__debug::)?vector<X>&.' 125*a65addddSAndroid Build Coastguard Worker r'|no matching .*function for call to .*addInstanceMultibindings' 126*a65addddSAndroid Build Coastguard Worker r'|cannot convert argument 1 from .const std::vector<X,std::allocator<.*>>. to .std::vector<X,std::allocator<.*>> &.', 127*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 128*a65addddSAndroid Build Coastguard Worker source, 129*a65addddSAndroid Build Coastguard Worker locals()) 130*a65addddSAndroid Build Coastguard Worker 131*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 132*a65addddSAndroid Build Coastguard Worker 'X', 133*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 134*a65addddSAndroid Build Coastguard Worker ]) 135*a65addddSAndroid Build Coastguard Worker def test_multibindings_bind_instance_vector_of_consts_error(self, XAnnot): 136*a65addddSAndroid Build Coastguard Worker source = ''' 137*a65addddSAndroid Build Coastguard Worker struct X {}; 138*a65addddSAndroid Build Coastguard Worker 139*a65addddSAndroid Build Coastguard Worker std::vector<const X> values; 140*a65addddSAndroid Build Coastguard Worker 141*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent() { 142*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 143*a65addddSAndroid Build Coastguard Worker .addInstanceMultibindings<XAnnot, X>(values); 144*a65addddSAndroid Build Coastguard Worker } 145*a65addddSAndroid Build Coastguard Worker ''' 146*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 147*a65addddSAndroid Build Coastguard Worker '.*', 148*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 149*a65addddSAndroid Build Coastguard Worker source, 150*a65addddSAndroid Build Coastguard Worker locals()) 151*a65addddSAndroid Build Coastguard Worker 152*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 153*a65addddSAndroid Build Coastguard Worker ('X**', r'X\*\*'), 154*a65addddSAndroid Build Coastguard Worker ('std::shared_ptr<X>*', r'std::shared_ptr<X>\*'), 155*a65addddSAndroid Build Coastguard Worker ('const std::shared_ptr<X>', r'const std::shared_ptr<X>'), 156*a65addddSAndroid Build Coastguard Worker ('X* const', r'X\* const'), 157*a65addddSAndroid Build Coastguard Worker ('const X* const', r'const X\* const'), 158*a65addddSAndroid Build Coastguard Worker ('X*&', r'X\*&'), 159*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X**>', r'X\*\*'), 160*a65addddSAndroid Build Coastguard Worker ]) 161*a65addddSAndroid Build Coastguard Worker def test_multibindings_bind_instance_non_class_type_error(self, XVariant, XVariantRegex): 162*a65addddSAndroid Build Coastguard Worker source = ''' 163*a65addddSAndroid Build Coastguard Worker struct X {}; 164*a65addddSAndroid Build Coastguard Worker 165*a65addddSAndroid Build Coastguard Worker using XVariantT = XVariant; 166*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent(XVariantT x) { 167*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 168*a65addddSAndroid Build Coastguard Worker .addInstanceMultibinding<XVariant, XVariant>(x); 169*a65addddSAndroid Build Coastguard Worker } 170*a65addddSAndroid Build Coastguard Worker ''' 171*a65addddSAndroid Build Coastguard Worker expect_compile_error( 172*a65addddSAndroid Build Coastguard Worker 'NonClassTypeError<XVariantRegex,X>', 173*a65addddSAndroid Build Coastguard Worker 'A non-class type T was specified.', 174*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 175*a65addddSAndroid Build Coastguard Worker source, 176*a65addddSAndroid Build Coastguard Worker locals()) 177*a65addddSAndroid Build Coastguard Worker 178*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 179*a65addddSAndroid Build Coastguard Worker ('std::nullptr_t', r'(std::)?nullptr(_t)?'), 180*a65addddSAndroid Build Coastguard Worker ('X(*)()', r'X(\((__cdecl)?\*\))?\((void)?\)'), 181*a65addddSAndroid Build Coastguard Worker ]) 182*a65addddSAndroid Build Coastguard Worker def test_multibindings_bind_instance_non_injectable_type_error(self, XVariant, XVariantRegex): 183*a65addddSAndroid Build Coastguard Worker source = ''' 184*a65addddSAndroid Build Coastguard Worker struct X {}; 185*a65addddSAndroid Build Coastguard Worker 186*a65addddSAndroid Build Coastguard Worker using XVariantT = XVariant; 187*a65addddSAndroid Build Coastguard Worker fruit::Component<> getComponent(XVariantT x) { 188*a65addddSAndroid Build Coastguard Worker return fruit::createComponent() 189*a65addddSAndroid Build Coastguard Worker .addInstanceMultibinding<XVariant, XVariant>(x); 190*a65addddSAndroid Build Coastguard Worker } 191*a65addddSAndroid Build Coastguard Worker ''' 192*a65addddSAndroid Build Coastguard Worker expect_compile_error( 193*a65addddSAndroid Build Coastguard Worker 'NonInjectableTypeError<XVariantRegex>', 194*a65addddSAndroid Build Coastguard Worker 'The type T is not injectable.', 195*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 196*a65addddSAndroid Build Coastguard Worker source, 197*a65addddSAndroid Build Coastguard Worker locals()) 198*a65addddSAndroid Build Coastguard Worker 199*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__': 200*a65addddSAndroid Build Coastguard Worker absltest.main() 201