1#!/usr/bin/env python3 2# Copyright 2016 Google Inc. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS-IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15import pytest 16 17from fruit_test_common import * 18 19COMMON_DEFINITIONS = ''' 20 #include "test_common.h" 21 22 struct X; 23 24 struct Annotation1 {}; 25 using XAnnot1 = fruit::Annotated<Annotation1, X>; 26 27 struct Annotation2 {}; 28 using XAnnot2 = fruit::Annotated<Annotation2, X>; 29 ''' 30 31@pytest.mark.parametrize('XAnnot', [ 32 'X', 33 'fruit::Annotated<Annotation1, X>', 34]) 35def test_move(XAnnot): 36 source = ''' 37 struct X { 38 using Inject = X(); 39 }; 40 41 fruit::Component<XAnnot> getComponent() { 42 fruit::Component<XAnnot> c = fruit::createComponent(); 43 fruit::Component<XAnnot> c2 = std::move(c); 44 return fruit::Component<XAnnot>(std::move(c2)); 45 } 46 47 int main() { 48 fruit::Injector<XAnnot> injector(getComponent); 49 injector.get<XAnnot>(); 50 } 51 ''' 52 expect_success( 53 COMMON_DEFINITIONS, 54 source, 55 locals()) 56 57@pytest.mark.parametrize('XAnnot', [ 58 'X', 59 'fruit::Annotated<Annotation1, X>', 60]) 61def test_move_partial_component(XAnnot): 62 source = ''' 63 struct X { 64 using Inject = X(); 65 }; 66 67 fruit::Component<XAnnot> getComponent() { 68 auto c = fruit::createComponent(); 69 auto c1 = std::move(c); 70 return std::move(c1); 71 } 72 73 int main() { 74 fruit::Injector<XAnnot> injector(getComponent); 75 injector.get<XAnnot>(); 76 } 77 ''' 78 expect_generic_compile_error( 79 'error: use of deleted function .fruit::PartialComponent<Bindings>::PartialComponent\(fruit::PartialComponent<Bindings>&&\).' 80 + '|error: call to deleted constructor of .fruit::PartialComponent<>.' 81 # MSVC 2017 82 + '|error C2280: .fruit::PartialComponent<>::PartialComponent\(fruit::PartialComponent<> &&\).: attempting to reference a deleted function' 83 # MSVC 2015 84 + '|error C2248: .fruit::PartialComponent<>::PartialComponent.: cannot access private member declared in class .fruit::PartialComponent<>.', 85 COMMON_DEFINITIONS, 86 source, 87 locals()) 88 89@pytest.mark.parametrize('XAnnot,ConstXAnnot', [ 90 ('X', 'X'), 91 ('X', 'const X'), 92 ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>'), 93 ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, const X>'), 94]) 95def test_error_no_binding_found(XAnnot, ConstXAnnot): 96 source = ''' 97 struct X {}; 98 99 fruit::Component<ConstXAnnot> getComponent() { 100 return fruit::createComponent(); 101 } 102 ''' 103 expect_compile_error( 104 'NoBindingFoundError<XAnnot>', 105 'No explicit binding nor C::Inject definition was found for T.', 106 COMMON_DEFINITIONS, 107 source, 108 locals()) 109 110@pytest.mark.parametrize('XAnnot,ConstXAnnot', [ 111 ('X', 'X'), 112 ('X', 'const X'), 113 ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, X>'), 114 ('fruit::Annotated<Annotation1, X>', 'fruit::Annotated<Annotation1, const X>'), 115]) 116def test_error_no_binding_found_abstract_class(XAnnot, ConstXAnnot): 117 source = ''' 118 struct X { 119 virtual void f() = 0; 120 }; 121 122 fruit::Component<ConstXAnnot> getComponent() { 123 return fruit::createComponent(); 124 } 125 ''' 126 expect_compile_error( 127 'NoBindingFoundForAbstractClassError<XAnnot,X>', 128 'No explicit binding was found for T, and note that C is an abstract class', 129 COMMON_DEFINITIONS, 130 source, 131 locals()) 132 133@pytest.mark.parametrize('MaybeConst', [ 134 '', 135 'const', 136]) 137def test_error_no_factory_binding_found(MaybeConst): 138 source = ''' 139 struct X {}; 140 141 fruit::Component<MaybeConst std::function<std::unique_ptr<X>()>> getComponent() { 142 return fruit::createComponent(); 143 } 144 ''' 145 expect_compile_error( 146 'NoBindingFoundError<std::function<std::unique_ptr<X(,std::default_delete<X>)?>\((void)?\)>', 147 'No explicit binding nor C::Inject definition was found for T.', 148 COMMON_DEFINITIONS, 149 source, 150 locals()) 151 152@pytest.mark.parametrize('MaybeConst', [ 153 '', 154 'const', 155]) 156def test_error_no_factory_binding_found_with_annotation(MaybeConst): 157 source = ''' 158 struct X {}; 159 160 fruit::Component<fruit::Annotated<Annotation1, MaybeConst std::function<std::unique_ptr<X>()>>> getComponent() { 161 return fruit::createComponent(); 162 } 163 ''' 164 expect_compile_error( 165 'NoBindingFoundError<fruit::Annotated<Annotation1,std::function<std::unique_ptr<X(,std::default_delete<X>)?>\((void)?\)>>', 166 'No explicit binding nor C::Inject definition was found for T.', 167 COMMON_DEFINITIONS, 168 source, 169 locals()) 170 171if __name__== '__main__': 172 main(__file__) 173