1
+ import * as assert from 'assert' ;
2
+ import * as vsc from 'vscode' ;
3
+ import { getDataTypeContainer , DataType , PythonType } from "../../src/python" ;
4
+ import { TypingHintProvider } from "../../src/typingHintProvider" ;
5
+ import { TypeHintSettings } from '../../src/settings' ;
6
+ import { SetupError , varSearchResult , messageFor , TestCase } from '../common' ;
7
+
8
+ suite ( 'TypingHintProvider' , ( ) => {
9
+
10
+ const importTyping : string = "import x\nimport typing" ;
11
+ const importTypingAsX : string = "import x\nimport typing as x" ;
12
+ const fromTypingImport : string = "import x\nfrom typing import List" ;
13
+ const typeContainer = getDataTypeContainer ( ) ;
14
+
15
+ suite ( 'containsTyping' , ( ) => {
16
+
17
+ test ( "returns true for 'import typing'" , async ( ) => {
18
+ const provider = new TypingHintProvider ( importTyping , typeContainer ) ;
19
+ const actual = await provider . containsTyping ( ) ;
20
+ assert . equal ( actual , true ) ;
21
+ } ) ;
22
+
23
+ test ( "returns true for 'import typing as x'" , async ( ) => {
24
+ const provider = new TypingHintProvider ( importTypingAsX , typeContainer ) ;
25
+ const actual = await provider . containsTyping ( ) ;
26
+ assert . equal ( actual , true ) ;
27
+ } ) ;
28
+
29
+ test ( "returns true for 'from typing import x'" , async ( ) => {
30
+ const provider = new TypingHintProvider ( fromTypingImport , typeContainer ) ;
31
+ const actual = await provider . containsTyping ( ) ;
32
+ assert . equal ( actual , true ) ;
33
+ } ) ;
34
+ } ) ;
35
+
36
+ suite ( "getTypingHint" , ( ) => {
37
+
38
+ test ( "returns typing.Type[" , async ( ) => {
39
+ const provider = new TypingHintProvider ( importTyping , typeContainer ) ;
40
+ const expected = "typing.List[" ;
41
+ providerTest ( getTypingHint , await provider . containsTyping ( ) , provider , expected ) ;
42
+ } ) ;
43
+
44
+ test ( "returns x.Type[ for 'import typing as x'" , async ( ) => {
45
+ const provider = new TypingHintProvider ( importTypingAsX , typeContainer ) ;
46
+ const expected = "x.List[" ;
47
+ providerTest ( getTypingHint , await provider . containsTyping ( ) , provider , expected ) ;
48
+ } ) ;
49
+
50
+ test ( "returns Type[ for 'from typing' import" , async ( ) => {
51
+ const provider = new TypingHintProvider ( fromTypingImport , typeContainer ) ;
52
+ const expected = "List[" ;
53
+ providerTest ( getTypingHint , await provider . containsTyping ( ) , provider , expected ) ;
54
+ } ) ;
55
+
56
+ function getTypingHint ( provider : TypingHintProvider , expected : string ) {
57
+ const actual = provider . getTypingHint ( PythonType . List ) ;
58
+ assert . equal ( actual , expected ) ;
59
+ }
60
+ } ) ;
61
+
62
+ suite ( "getTypingHints" , ( ) => {
63
+
64
+ const provider = new TypingHintProvider ( fromTypingImport , typeContainer ) ;
65
+ let typingImported : boolean ;
66
+
67
+ setup ( async ( ) => {
68
+ typingImported = await provider . containsTyping ( ) ;
69
+ } ) ;
70
+
71
+ test ( "returns Type[ for empty collection" , ( ) => {
72
+ const data = "[]" ;
73
+ const expected = [ "List[" ] ;
74
+ providerTest ( getTypingHints , typingImported , provider , { data, expected } , PythonType . List ) ;
75
+ } ) ;
76
+
77
+ test ( "returns Dict[ and 'Dict[key,' for dicts" , ( ) => {
78
+ let data = "{ 1: 2 }" ;
79
+ let expected = [ "Dict[" , "Dict[int" ] ;
80
+ providerTest ( getTypingHints , typingImported , provider , { data, expected } , PythonType . Dict ) ;
81
+ } ) ;
82
+
83
+ test ( "handles nestled dicts" , ( ) => {
84
+ let data = "[ { 1: 2 } ]" ;
85
+ let expected = [ "List[" , "List[Dict[int" ] ;
86
+ providerTest ( getTypingHints , typingImported , provider , { data, expected } , PythonType . List ) ;
87
+ } ) ;
88
+
89
+ test ( "returns Type[ and Type[type] for non-dicts" , ( ) => {
90
+ let data = "['str']" ;
91
+ let expected = [ "List[" , "List[str]" ] ;
92
+ providerTest ( getTypingHints , typingImported , provider , { data, expected } , PythonType . List ) ;
93
+
94
+ data = "(1, {'ignore': 'this'})" ;
95
+ expected = [ "Tuple[" , "Tuple[int]" ] ;
96
+ providerTest ( getTypingHints , typingImported , provider , { data, expected } , PythonType . Tuple ) ;
97
+
98
+ data = "{ 1, 2 }" ;
99
+ expected = [ "Set[" , "Set[int]" ] ;
100
+ providerTest ( getTypingHints , typingImported , provider , { data, expected } , PythonType . Set ) ;
101
+ } ) ;
102
+
103
+ test ( "adds typing prefixes for 'import typing' imports" , async ( ) => {
104
+ let p = new TypingHintProvider ( importTyping , typeContainer ) ;
105
+ let data = "[ { 1: 2 } ]" ;
106
+ let expected = [ "typing.List[" , "typing.List[typing.Dict[int" ] ;
107
+ providerTest ( getTypingHints , await p . containsTyping ( ) , p , { data, expected } , PythonType . List ) ;
108
+ } ) ;
109
+
110
+ function getTypingHints ( provider : TypingHintProvider , testCase : TestCase , type : PythonType ) {
111
+ const actual = provider . getTypingHints ( varSearchResult ( type , testCase . data ) ) ;
112
+ assert . deepEqual ( actual , testCase . expected , messageFor ( testCase , actual ) ) ;
113
+ }
114
+ } ) ;
115
+
116
+ function providerTest ( test : ( ...params : any ) => void , typingDetected : boolean , ...args : any ) {
117
+ if ( typingDetected ) {
118
+ test ( ...args ) ;
119
+ } else {
120
+ throw new SetupError ( "The provider failed to detect a typing import." ) ;
121
+ }
122
+ }
123
+ } ) ;
0 commit comments