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 X; 23*a65addddSAndroid Build Coastguard Worker 24*a65addddSAndroid Build Coastguard Worker struct Annotation1 {}; 25*a65addddSAndroid Build Coastguard Worker using XAnnot1 = fruit::Annotated<Annotation1, X>; 26*a65addddSAndroid Build Coastguard Worker 27*a65addddSAndroid Build Coastguard Worker struct Annotation2 {}; 28*a65addddSAndroid Build Coastguard Worker using XAnnot2 = fruit::Annotated<Annotation2, X>; 29*a65addddSAndroid Build Coastguard Worker ''' 30*a65addddSAndroid Build Coastguard Worker 31*a65addddSAndroid Build Coastguard Workerclass TestComponent(parameterized.TestCase): 32*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 33*a65addddSAndroid Build Coastguard Worker 'X', 34*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 35*a65addddSAndroid Build Coastguard Worker ]) 36*a65addddSAndroid Build Coastguard Worker def test_move(self, XAnnot): 37*a65addddSAndroid Build Coastguard Worker source = ''' 38*a65addddSAndroid Build Coastguard Worker struct X { 39*a65addddSAndroid Build Coastguard Worker using Inject = X(); 40*a65addddSAndroid Build Coastguard Worker }; 41*a65addddSAndroid Build Coastguard Worker 42*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> getComponent() { 43*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> c = fruit::createComponent(); 44*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> c2 = std::move(c); 45*a65addddSAndroid Build Coastguard Worker return fruit::Component<XAnnot>(std::move(c2)); 46*a65addddSAndroid Build Coastguard Worker } 47*a65addddSAndroid Build Coastguard Worker 48*a65addddSAndroid Build Coastguard Worker int main() { 49*a65addddSAndroid Build Coastguard Worker fruit::Injector<XAnnot> injector(getComponent); 50*a65addddSAndroid Build Coastguard Worker injector.get<XAnnot>(); 51*a65addddSAndroid Build Coastguard Worker } 52*a65addddSAndroid Build Coastguard Worker ''' 53*a65addddSAndroid Build Coastguard Worker expect_success( 54*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 55*a65addddSAndroid Build Coastguard Worker source, 56*a65addddSAndroid Build Coastguard Worker locals()) 57*a65addddSAndroid Build Coastguard Worker 58*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 59*a65addddSAndroid Build Coastguard Worker 'X', 60*a65addddSAndroid Build Coastguard Worker 'fruit::Annotated<Annotation1, X>', 61*a65addddSAndroid Build Coastguard Worker ]) 62*a65addddSAndroid Build Coastguard Worker def test_move_partial_component(self, XAnnot): 63*a65addddSAndroid Build Coastguard Worker source = ''' 64*a65addddSAndroid Build Coastguard Worker struct X { 65*a65addddSAndroid Build Coastguard Worker using Inject = X(); 66*a65addddSAndroid Build Coastguard Worker }; 67*a65addddSAndroid Build Coastguard Worker 68*a65addddSAndroid Build Coastguard Worker fruit::Component<XAnnot> getComponent() { 69*a65addddSAndroid Build Coastguard Worker auto c = fruit::createComponent(); 70*a65addddSAndroid Build Coastguard Worker auto c1 = std::move(c); 71*a65addddSAndroid Build Coastguard Worker return std::move(c1); 72*a65addddSAndroid Build Coastguard Worker } 73*a65addddSAndroid Build Coastguard Worker 74*a65addddSAndroid Build Coastguard Worker int main() { 75*a65addddSAndroid Build Coastguard Worker fruit::Injector<XAnnot> injector(getComponent); 76*a65addddSAndroid Build Coastguard Worker injector.get<XAnnot>(); 77*a65addddSAndroid Build Coastguard Worker } 78*a65addddSAndroid Build Coastguard Worker ''' 79*a65addddSAndroid Build Coastguard Worker expect_generic_compile_error( 80*a65addddSAndroid Build Coastguard Worker r'error: use of deleted function .fruit::PartialComponent<Bindings>::PartialComponent\(fruit::PartialComponent<Bindings>&&\).' 81*a65addddSAndroid Build Coastguard Worker r'|error: call to deleted constructor of .(fruit::)?PartialComponent<>.' 82*a65addddSAndroid Build Coastguard Worker # MSVC 2017 83*a65addddSAndroid Build Coastguard Worker r'|error C2280: .fruit::PartialComponent<>::PartialComponent\(fruit::PartialComponent<> &&\).: attempting to reference a deleted function' 84*a65addddSAndroid Build Coastguard Worker # MSVC 2015 85*a65addddSAndroid Build Coastguard Worker r'|error C2248: .fruit::PartialComponent<>::PartialComponent.: cannot access private member declared in class .fruit::PartialComponent<>.', 86*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 87*a65addddSAndroid Build Coastguard Worker source, 88*a65addddSAndroid Build Coastguard Worker locals()) 89*a65addddSAndroid Build Coastguard Worker 90*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 91*a65addddSAndroid Build Coastguard Worker ('X', 'X'), 92*a65addddSAndroid Build Coastguard Worker ('X', 'const X'), 93*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>'), 94*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, const X>'), 95*a65addddSAndroid Build Coastguard Worker ]) 96*a65addddSAndroid Build Coastguard Worker def test_error_no_binding_found(self, XAnnot, ConstXAnnot): 97*a65addddSAndroid Build Coastguard Worker source = ''' 98*a65addddSAndroid Build Coastguard Worker struct X {}; 99*a65addddSAndroid Build Coastguard Worker 100*a65addddSAndroid Build Coastguard Worker fruit::Component<ConstXAnnot> getComponent() { 101*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 102*a65addddSAndroid Build Coastguard Worker } 103*a65addddSAndroid Build Coastguard Worker ''' 104*a65addddSAndroid Build Coastguard Worker expect_compile_error( 105*a65addddSAndroid Build Coastguard Worker 'NoBindingFoundError<XAnnot>', 106*a65addddSAndroid Build Coastguard Worker 'No explicit binding nor C::Inject definition was found for T.', 107*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 108*a65addddSAndroid Build Coastguard Worker source, 109*a65addddSAndroid Build Coastguard Worker locals()) 110*a65addddSAndroid Build Coastguard Worker 111*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 112*a65addddSAndroid Build Coastguard Worker ('X', 'X'), 113*a65addddSAndroid Build Coastguard Worker ('X', 'const X'), 114*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>'), 115*a65addddSAndroid Build Coastguard Worker ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, const X>'), 116*a65addddSAndroid Build Coastguard Worker ]) 117*a65addddSAndroid Build Coastguard Worker def test_error_no_binding_found_abstract_class(self, XAnnot, ConstXAnnot): 118*a65addddSAndroid Build Coastguard Worker source = ''' 119*a65addddSAndroid Build Coastguard Worker struct X { 120*a65addddSAndroid Build Coastguard Worker virtual void f() = 0; 121*a65addddSAndroid Build Coastguard Worker }; 122*a65addddSAndroid Build Coastguard Worker 123*a65addddSAndroid Build Coastguard Worker fruit::Component<ConstXAnnot> getComponent() { 124*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 125*a65addddSAndroid Build Coastguard Worker } 126*a65addddSAndroid Build Coastguard Worker ''' 127*a65addddSAndroid Build Coastguard Worker expect_compile_error( 128*a65addddSAndroid Build Coastguard Worker 'NoBindingFoundForAbstractClassError<XAnnot,X>', 129*a65addddSAndroid Build Coastguard Worker 'No explicit binding was found for T, and note that C is an abstract class', 130*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 131*a65addddSAndroid Build Coastguard Worker source, 132*a65addddSAndroid Build Coastguard Worker locals()) 133*a65addddSAndroid Build Coastguard Worker 134*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 135*a65addddSAndroid Build Coastguard Worker '', 136*a65addddSAndroid Build Coastguard Worker 'const', 137*a65addddSAndroid Build Coastguard Worker ]) 138*a65addddSAndroid Build Coastguard Worker def test_error_no_factory_binding_found(self, MaybeConst): 139*a65addddSAndroid Build Coastguard Worker source = ''' 140*a65addddSAndroid Build Coastguard Worker struct X {}; 141*a65addddSAndroid Build Coastguard Worker 142*a65addddSAndroid Build Coastguard Worker fruit::Component<MaybeConst std::function<std::unique_ptr<X>()>> getComponent() { 143*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 144*a65addddSAndroid Build Coastguard Worker } 145*a65addddSAndroid Build Coastguard Worker ''' 146*a65addddSAndroid Build Coastguard Worker expect_compile_error( 147*a65addddSAndroid Build Coastguard Worker r'NoBindingFoundError<std::function<std::unique_ptr<X(,std::default_delete<X>)?>\((void)?\)>', 148*a65addddSAndroid Build Coastguard Worker 'No explicit binding nor C::Inject definition was found for T.', 149*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 150*a65addddSAndroid Build Coastguard Worker source, 151*a65addddSAndroid Build Coastguard Worker locals()) 152*a65addddSAndroid Build Coastguard Worker 153*a65addddSAndroid Build Coastguard Worker @parameterized.parameters([ 154*a65addddSAndroid Build Coastguard Worker '', 155*a65addddSAndroid Build Coastguard Worker 'const', 156*a65addddSAndroid Build Coastguard Worker ]) 157*a65addddSAndroid Build Coastguard Worker def test_error_no_factory_binding_found_with_annotation(self, MaybeConst): 158*a65addddSAndroid Build Coastguard Worker source = ''' 159*a65addddSAndroid Build Coastguard Worker struct X {}; 160*a65addddSAndroid Build Coastguard Worker 161*a65addddSAndroid Build Coastguard Worker fruit::Component<fruit::Annotated<Annotation1, MaybeConst std::function<std::unique_ptr<X>()>>> getComponent() { 162*a65addddSAndroid Build Coastguard Worker return fruit::createComponent(); 163*a65addddSAndroid Build Coastguard Worker } 164*a65addddSAndroid Build Coastguard Worker ''' 165*a65addddSAndroid Build Coastguard Worker expect_compile_error( 166*a65addddSAndroid Build Coastguard Worker r'NoBindingFoundError<fruit::Annotated<Annotation1,std::function<std::unique_ptr<X(,std::default_delete<X>)?>\((void)?\)>>', 167*a65addddSAndroid Build Coastguard Worker 'No explicit binding nor C::Inject definition was found for T.', 168*a65addddSAndroid Build Coastguard Worker COMMON_DEFINITIONS, 169*a65addddSAndroid Build Coastguard Worker source, 170*a65addddSAndroid Build Coastguard Worker locals()) 171*a65addddSAndroid Build Coastguard Worker 172*a65addddSAndroid Build Coastguard Workerif __name__ == '__main__': 173*a65addddSAndroid Build Coastguard Worker absltest.main() 174