22
22
import org .junit .jupiter .params .ParameterizedTest ;
23
23
import org .junit .jupiter .params .provider .Arguments ;
24
24
import org .junit .jupiter .params .provider .MethodSource ;
25
+ import org .sonar .python .tree .TokenImpl ;
26
+ import org .sonar .python .tree .UnaryExpressionImpl ;
25
27
import org .sonar .python .types .v2 .ObjectType ;
26
28
import org .sonar .python .types .v2 .PythonType ;
27
29
import org .sonar .python .types .v2 .TypesTestUtils ;
28
30
29
31
import static org .assertj .core .api .Assertions .assertThat ;
32
+ import static org .mockito .Mockito .mock ;
33
+ import static org .mockito .Mockito .when ;
30
34
import static org .sonar .python .PythonTestUtils .lastExpression ;
31
35
import static org .sonar .python .PythonTestUtils .pythonFile ;
32
36
import static org .sonar .python .types .v2 .TypesTestUtils .PROJECT_LEVEL_TYPE_TABLE ;
@@ -54,15 +58,13 @@ static Stream<Arguments> testSources() {
54
58
Arguments .of ("+(True)" , TypesTestUtils .INT_TYPE ),
55
59
56
60
Arguments .of ("~1" , TypesTestUtils .INT_TYPE ),
57
- Arguments .of ("~1.0" , TypesTestUtils .INT_TYPE ),
58
- Arguments .of ("~(3+2j)" , TypesTestUtils .INT_TYPE ),
59
- Arguments .of ("~(1j)" , TypesTestUtils .INT_TYPE ),
60
61
Arguments .of ("~(True)" , TypesTestUtils .INT_TYPE ),
61
62
62
63
Arguments .of ("not 1" , TypesTestUtils .BOOL_TYPE ),
63
64
Arguments .of ("not 1.0" , TypesTestUtils .BOOL_TYPE ),
64
65
Arguments .of ("not (2j)" , TypesTestUtils .BOOL_TYPE ),
65
- Arguments .of ("not (True)" , TypesTestUtils .BOOL_TYPE )
66
+ Arguments .of ("not (True)" , TypesTestUtils .BOOL_TYPE ),
67
+ Arguments .of ("not x" , TypesTestUtils .BOOL_TYPE )
66
68
);
67
69
}
68
70
@@ -77,12 +79,32 @@ void test(String code, PythonType expectedType) {
77
79
assertThat (objectType .type ()).isEqualTo (expectedType ));
78
80
}
79
81
82
+ static Stream <Arguments > testUnknownReturnSources () {
83
+ return Stream .of (
84
+ Arguments .of ("~x" ),
85
+ Arguments .of ("~1.0" ),
86
+ Arguments .of ("~(1j)" ),
87
+ Arguments .of ("~(3+2j)" ),
88
+ Arguments .of ("-x" ),
89
+ Arguments .of ("+x" )
90
+ );
91
+ }
92
+
93
+ @ ParameterizedTest
94
+ @ MethodSource ("testUnknownReturnSources" )
95
+ void testUnknownReturn (String code ) {
96
+ var expr = lastExpression (code );
97
+ expr .accept (trivialTypeInferenceVisitor );
98
+ expr .accept (trivialTypePropagationVisitor );
99
+ assertThat (expr .typeV2 ()).isEqualTo (PythonType .UNKNOWN );
100
+ }
101
+
80
102
static Stream <Arguments > customNumberClassTestSource () {
81
103
return Stream .of (
82
104
Arguments .of ("+(MyNum())" , PythonType .UNKNOWN ),
83
105
Arguments .of ("-(MyNum())" , PythonType .UNKNOWN ),
84
106
Arguments .of ("not (MyNum())" , new ObjectType (TypesTestUtils .BOOL_TYPE )),
85
- Arguments .of ("~(MyNum())" , new ObjectType ( TypesTestUtils . INT_TYPE ) )
107
+ Arguments .of ("~(MyNum())" , PythonType . UNKNOWN )
86
108
);
87
109
}
88
110
@@ -105,4 +127,16 @@ void testNotOfCustomClass() {
105
127
assertThat (expr .typeV2 ()).isInstanceOfSatisfying (ObjectType .class , objectType ->
106
128
assertThat (objectType .type ()).isEqualTo (TypesTestUtils .BOOL_TYPE ));
107
129
}
130
+
131
+ @ Test
132
+ void testUnknownOperator () {
133
+ var operator = mock (TokenImpl .class );
134
+ when (operator .value ()).thenReturn ("invalid_operator" );
135
+ UnaryExpressionImpl expr = new UnaryExpressionImpl (operator , lastExpression ("1" ));
136
+ expr .typeV2 (TypesTestUtils .INT_TYPE );
137
+
138
+ expr .accept (trivialTypePropagationVisitor );
139
+ assertThat (expr .typeV2 ()).isEqualTo (PythonType .UNKNOWN );
140
+ }
141
+
108
142
}
0 commit comments