blob: ab375f6c1611ce3c3660591e4ec881a2bc3e601d [file] [log] [blame]
#!/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<Annotation1, X>;
'''
def test_required_success():
source = '''
struct X {
virtual void foo() = 0;
virtual ~X() = default;
};
using XFactory = std::function<std::unique_ptr<X>()>;
struct Y {
XFactory xFactory;
INJECT(Y(XFactory xFactory))
: xFactory(xFactory) {
}
void doStuff() {
xFactory()->foo();
}
};
fruit::Component<fruit::Required<XFactory>, Y> getYComponent() {
return fruit::createComponent();
}
struct XImpl : public X {
INJECT(XImpl()) = default;
void foo() override {}
};
fruit::Component<XFactory> getXFactoryComponent() {
return fruit::createComponent()
.bind<X, XImpl>();
}
fruit::Component<Y> getComponent() {
return fruit::createComponent()
.install(getYComponent)
.install(getXFactoryComponent);
}
int main() {
fruit::Injector<Y> 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<std::unique_ptr<X>()>;
using XFactoryAnnot = fruit::Annotated<Annotation1, XFactory>;
struct Y {
XFactory xFactory;
INJECT(Y(ANNOTATED(Annotation1, XFactory) xFactory))
: xFactory(xFactory) {
}
void doStuff() {
xFactory()->foo();
}
};
fruit::Component<fruit::Required<XFactoryAnnot>, Y> getYComponent() {
return fruit::createComponent();
}
struct XImpl : public X {
INJECT(XImpl()) = default;
void foo() override {}
};
fruit::Component<XFactoryAnnot> getXFactoryComponent() {
return fruit::createComponent()
.bind<fruit::Annotated<Annotation1, X>, fruit::Annotated<Annotation1, XImpl>>();
}
fruit::Component<Y> getComponent() {
return fruit::createComponent()
.install(getYComponent)
.install(getXFactoryComponent);
}
int main() {
fruit::Injector<Y> 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<std::unique_ptr<X>()>;
struct Y {
XFactory xFactory;
INJECT(Y(XFactory xFactory))
: xFactory(xFactory) {
}
void doStuff();
};
fruit::Component<fruit::Required<XFactory>, Y> getYComponent() {
return fruit::createComponent();
}
fruit::Component<XFactory> getXFactoryComponent();
fruit::Component<Y> getComponent() {
return fruit::createComponent()
.install(getYComponent)
.install(getXFactoryComponent);
}
int main() {
fruit::Injector<Y> 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<XFactory> getXFactoryComponent() {
return fruit::createComponent()
.bind<X, XImpl>();
}
'''
expect_success(COMMON_DEFINITIONS, source)
def test_required_annotated_forward_declared_success():
source = '''
struct X;
using XFactory = std::function<std::unique_ptr<X>()>;
using XFactoryAnnot = fruit::Annotated<Annotation1, XFactory>;
struct Y {
XFactory xFactory;
INJECT(Y(ANNOTATED(Annotation1, XFactory) xFactory))
: xFactory(xFactory) {
}
void doStuff();
};
fruit::Component<fruit::Required<XFactoryAnnot>, Y> getYComponent() {
return fruit::createComponent();
}
fruit::Component<XFactoryAnnot> getXFactoryComponent();
fruit::Component<Y> getComponent() {
return fruit::createComponent()
.install(getYComponent)
.install(getXFactoryComponent);
}
int main() {
fruit::Injector<Y> 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<XFactoryAnnot> getXFactoryComponent() {
return fruit::createComponent()
.bind<fruit::Annotated<Annotation1, X>, fruit::Annotated<Annotation1, XImpl>>();
}
'''
expect_success(COMMON_DEFINITIONS, source)
def test_required_const_forward_declared_success():
source = '''
struct X;
using XFactory = std::function<std::unique_ptr<X>()>;
struct Y {
XFactory xFactory;
INJECT(Y(XFactory xFactory))
: xFactory(xFactory) {
}
void doStuff();
};
fruit::Component<fruit::Required<const XFactory>, Y> getYComponent() {
return fruit::createComponent();
}
fruit::Component<const XFactory> getXFactoryComponent();
fruit::Component<Y> getComponent() {
return fruit::createComponent()
.install(getYComponent)
.install(getXFactoryComponent);
}
int main() {
fruit::Injector<Y> 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<const XFactory> getXFactoryComponent() {
return fruit::createComponent()
.bind<X, XImpl>();
}
'''
expect_success(COMMON_DEFINITIONS, source)
def test_required_const_annotated_forward_declared_success():
source = '''
struct X;
using XFactory = std::function<std::unique_ptr<X>()>;
using ConstXFactoryAnnot = fruit::Annotated<Annotation1, const XFactory>;
struct Y {
XFactory xFactory;
INJECT(Y(ANNOTATED(Annotation1, XFactory) xFactory))
: xFactory(xFactory) {
}
void doStuff();
};
fruit::Component<fruit::Required<ConstXFactoryAnnot>, Y> getYComponent() {
return fruit::createComponent();
}
fruit::Component<ConstXFactoryAnnot> getXFactoryComponent();
fruit::Component<Y> getComponent() {
return fruit::createComponent()
.install(getYComponent)
.install(getXFactoryComponent);
}
int main() {
fruit::Injector<Y> 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<ConstXFactoryAnnot> getXFactoryComponent() {
return fruit::createComponent()
.bind<fruit::Annotated<Annotation1, X>, fruit::Annotated<Annotation1, XImpl>>();
}
'''
expect_success(COMMON_DEFINITIONS, source)
if __name__== '__main__':
main(__file__)