#!/usr/bin/env python3 # Copyright 2016 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS-IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from fruit_test_common import * COMMON_DEFINITIONS = ''' #include "test_common.h" struct X; struct Annotation1 {}; using XAnnot1 = fruit::Annotated; ''' def test_required_success(): source = ''' struct X { virtual void foo() = 0; virtual ~X() = default; }; using XFactory = std::function()>; struct Y { XFactory xFactory; INJECT(Y(XFactory xFactory)) : xFactory(xFactory) { } void doStuff() { xFactory()->foo(); } }; fruit::Component, Y> getYComponent() { return fruit::createComponent(); } struct XImpl : public X { INJECT(XImpl()) = default; void foo() override {} }; fruit::Component getXFactoryComponent() { return fruit::createComponent() .bind(); } fruit::Component getComponent() { return fruit::createComponent() .install(getYComponent) .install(getXFactoryComponent); } int main() { fruit::Injector injector(getComponent); Y* y(injector); y->doStuff(); } ''' expect_success(COMMON_DEFINITIONS, source) def test_required_annotated_success(): source = ''' struct X { virtual void foo() = 0; virtual ~X() = default; }; using XFactory = std::function()>; using XFactoryAnnot = fruit::Annotated; struct Y { XFactory xFactory; INJECT(Y(ANNOTATED(Annotation1, XFactory) xFactory)) : xFactory(xFactory) { } void doStuff() { xFactory()->foo(); } }; fruit::Component, Y> getYComponent() { return fruit::createComponent(); } struct XImpl : public X { INJECT(XImpl()) = default; void foo() override {} }; fruit::Component getXFactoryComponent() { return fruit::createComponent() .bind, fruit::Annotated>(); } fruit::Component getComponent() { return fruit::createComponent() .install(getYComponent) .install(getXFactoryComponent); } int main() { fruit::Injector injector(getComponent); Y* y(injector); y->doStuff(); } ''' expect_success(COMMON_DEFINITIONS, source) def test_required_forward_declared_success(): source = ''' struct X; using XFactory = std::function()>; struct Y { XFactory xFactory; INJECT(Y(XFactory xFactory)) : xFactory(xFactory) { } void doStuff(); }; fruit::Component, Y> getYComponent() { return fruit::createComponent(); } fruit::Component getXFactoryComponent(); fruit::Component getComponent() { return fruit::createComponent() .install(getYComponent) .install(getXFactoryComponent); } int main() { fruit::Injector injector(getComponent); Y* y(injector); y->doStuff(); } // We define X as late as possible, to make sure that all the above compiles even if X is only forward-declared. struct X { virtual void foo() = 0; virtual ~X() = default; }; void Y::doStuff() { xFactory()->foo(); } struct XImpl : public X { INJECT(XImpl()) = default; void foo() override {} }; fruit::Component getXFactoryComponent() { return fruit::createComponent() .bind(); } ''' expect_success(COMMON_DEFINITIONS, source) def test_required_annotated_forward_declared_success(): source = ''' struct X; using XFactory = std::function()>; using XFactoryAnnot = fruit::Annotated; struct Y { XFactory xFactory; INJECT(Y(ANNOTATED(Annotation1, XFactory) xFactory)) : xFactory(xFactory) { } void doStuff(); }; fruit::Component, Y> getYComponent() { return fruit::createComponent(); } fruit::Component getXFactoryComponent(); fruit::Component getComponent() { return fruit::createComponent() .install(getYComponent) .install(getXFactoryComponent); } int main() { fruit::Injector injector(getComponent); Y* y(injector); y->doStuff(); } // We define X as late as possible, to make sure that all the above compiles even if X is only forward-declared. struct X { virtual void foo() = 0; virtual ~X() = default; }; void Y::doStuff() { xFactory()->foo(); } struct XImpl : public X { INJECT(XImpl()) = default; void foo() override {} }; fruit::Component getXFactoryComponent() { return fruit::createComponent() .bind, fruit::Annotated>(); } ''' expect_success(COMMON_DEFINITIONS, source) def test_required_const_forward_declared_success(): source = ''' struct X; using XFactory = std::function()>; struct Y { XFactory xFactory; INJECT(Y(XFactory xFactory)) : xFactory(xFactory) { } void doStuff(); }; fruit::Component, Y> getYComponent() { return fruit::createComponent(); } fruit::Component getXFactoryComponent(); fruit::Component getComponent() { return fruit::createComponent() .install(getYComponent) .install(getXFactoryComponent); } int main() { fruit::Injector injector(getComponent); Y* y(injector); y->doStuff(); } // We define X as late as possible, to make sure that all the above compiles even if X is only forward-declared. struct X { virtual void foo() = 0; virtual ~X() = default; }; void Y::doStuff() { xFactory()->foo(); } struct XImpl : public X { INJECT(XImpl()) = default; void foo() override {} }; fruit::Component getXFactoryComponent() { return fruit::createComponent() .bind(); } ''' expect_success(COMMON_DEFINITIONS, source) def test_required_const_annotated_forward_declared_success(): source = ''' struct X; using XFactory = std::function()>; using ConstXFactoryAnnot = fruit::Annotated; struct Y { XFactory xFactory; INJECT(Y(ANNOTATED(Annotation1, XFactory) xFactory)) : xFactory(xFactory) { } void doStuff(); }; fruit::Component, Y> getYComponent() { return fruit::createComponent(); } fruit::Component getXFactoryComponent(); fruit::Component getComponent() { return fruit::createComponent() .install(getYComponent) .install(getXFactoryComponent); } int main() { fruit::Injector injector(getComponent); Y* y(injector); y->doStuff(); } // We define X as late as possible, to make sure that all the above compiles even if X is only forward-declared. struct X { virtual void foo() = 0; virtual ~X() = default; }; void Y::doStuff() { xFactory()->foo(); } struct XImpl : public X { INJECT(XImpl()) = default; void foo() override {} }; fruit::Component getXFactoryComponent() { return fruit::createComponent() .bind, fruit::Annotated>(); } ''' expect_success(COMMON_DEFINITIONS, source) if __name__== '__main__': main(__file__)