#!/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. import pytest from fruit_test_common import * COMMON_DEFINITIONS = ''' #include "test_common.h" struct X; struct Annotation1 {}; using XAnnot1 = fruit::Annotated; struct Annotation2 {}; using XAnnot2 = fruit::Annotated; ''' @pytest.mark.parametrize('XAnnot', [ 'X', 'fruit::Annotated', ]) def test_move(XAnnot): source = ''' struct X { using Inject = X(); }; fruit::Component getComponent() { fruit::Component c = fruit::createComponent(); fruit::Component c2 = std::move(c); return fruit::Component(std::move(c2)); } int main() { fruit::Injector injector(getComponent); injector.get(); } ''' expect_success( COMMON_DEFINITIONS, source, locals()) @pytest.mark.parametrize('XAnnot', [ 'X', 'fruit::Annotated', ]) def test_move_partial_component(XAnnot): source = ''' struct X { using Inject = X(); }; fruit::Component getComponent() { auto c = fruit::createComponent(); auto c1 = std::move(c); return std::move(c1); } int main() { fruit::Injector injector(getComponent); injector.get(); } ''' expect_generic_compile_error( 'error: use of deleted function .fruit::PartialComponent::PartialComponent\(fruit::PartialComponent&&\).' + '|error: call to deleted constructor of .fruit::PartialComponent<>.' # MSVC 2017 + '|error C2280: .fruit::PartialComponent<>::PartialComponent\(fruit::PartialComponent<> &&\).: attempting to reference a deleted function' # MSVC 2015 + '|error C2248: .fruit::PartialComponent<>::PartialComponent.: cannot access private member declared in class .fruit::PartialComponent<>.', COMMON_DEFINITIONS, source, locals()) @pytest.mark.parametrize('XAnnot,ConstXAnnot', [ ('X', 'X'), ('X', 'const X'), ('fruit::Annotated', 'fruit::Annotated'), ('fruit::Annotated', 'fruit::Annotated'), ]) def test_error_no_binding_found(XAnnot, ConstXAnnot): source = ''' struct X {}; fruit::Component getComponent() { return fruit::createComponent(); } ''' expect_compile_error( 'NoBindingFoundError', 'No explicit binding nor C::Inject definition was found for T.', COMMON_DEFINITIONS, source, locals()) @pytest.mark.parametrize('XAnnot,ConstXAnnot', [ ('X', 'X'), ('X', 'const X'), ('fruit::Annotated', 'fruit::Annotated'), ('fruit::Annotated', 'fruit::Annotated'), ]) def test_error_no_binding_found_abstract_class(XAnnot, ConstXAnnot): source = ''' struct X { virtual void f() = 0; }; fruit::Component getComponent() { return fruit::createComponent(); } ''' expect_compile_error( 'NoBindingFoundForAbstractClassError', 'No explicit binding was found for T, and note that C is an abstract class', COMMON_DEFINITIONS, source, locals()) @pytest.mark.parametrize('MaybeConst', [ '', 'const', ]) def test_error_no_factory_binding_found(MaybeConst): source = ''' struct X {}; fruit::Component()>> getComponent() { return fruit::createComponent(); } ''' expect_compile_error( 'NoBindingFoundError)?>\((void)?\)>', 'No explicit binding nor C::Inject definition was found for T.', COMMON_DEFINITIONS, source, locals()) @pytest.mark.parametrize('MaybeConst', [ '', 'const', ]) def test_error_no_factory_binding_found_with_annotation(MaybeConst): source = ''' struct X {}; fruit::Component()>>> getComponent() { return fruit::createComponent(); } ''' expect_compile_error( 'NoBindingFoundError)?>\((void)?\)>>', 'No explicit binding nor C::Inject definition was found for T.', COMMON_DEFINITIONS, source, locals()) if __name__== '__main__': main(__file__)