import * as assert from 'assert' ; import * as vscode from 'vscode' ; import * as path from 'path' ; import { PLSQLDefinitionProvider } from '../src/provider/plsqlDefinition.provider' ; interface ICase { curTextLine : string ; curText : string ; curChar : number ; expTextLine : string ; expChar : number ; expFile : string ; } suite ( 'PLSQL Definition' , ( ) => { const provider = new PLSQLDefinitionProvider ( ) ; function runTest ( file , cases , done ) { const uri = vscode . Uri . file ( path . join ( vscode . workspace . rootPath , file ) ) ; vscode . workspace . openTextDocument ( uri ) . then ( textDocument => { return Promise . all ( cases . map ( ( test , index ) => { const found = new RegExp ( test . curTextLine , 'i' ) . exec ( textDocument . getText ( ) ) ; assert . notEqual ( found , null , `curText: ${ test . curTextLine } not found` ) ; const curPos = textDocument . positionAt ( found . index + test . curChar ) ; const num = `(${ index }) ` ; let result ; return provider . provideDefinition ( textDocument , curPos , null ) . then ( r => { result = r ; const text = textDocument . getText ( textDocument . getWordRangeAtPosition ( curPos ) ) ; assert . equal ( text , test . curText , num + text ) ; assert . notEqual ( result , null , num + 'return is null' ) ; assert . equal ( path . basename ( result . uri . fsPath ) , test . expFile , num + 'uri: ' + JSON . stringify ( result . uri ) ) ; return vscode . workspace . openTextDocument ( result . uri ) ; } ) . then ( document => { const match = new RegExp ( test . expTextLine , 'i' ) . exec ( document . getText ( ) ) ; assert . notEqual ( match , null , `expText: ${ test . expTextLine } not found` ) ; const expPos = document . positionAt ( match . index + test . expChar ) ; assert . equal ( result . range . start . line , expPos . line , num + 'line: ' + JSON . stringify ( result . range ) ) ; assert . equal ( result . range . start . character , expPos . character , num + 'char: ' + JSON . stringify ( result . range ) ) ; } ) ; } ) ) ; } , err => assert . ok ( false , `error in OpenTextDocument ${ err }` ) ) . then ( ( ) => done ( ) , done ) ; } function buildCase ( curTextLine , curChar , curText , expTextLine , expChar , expFile ) { return { curChar : curChar , curTextLine : curTextLine , curText : curText , expChar : expChar , expTextLine : expTextLine , expFile : expFile } ; } test ( 'Package I' , ( done ) => { let testCases = [ buildCase ( 'function get_myValue\\(param1 in varchar2\\)\\s*return varchar2\\s*is' , 14 , 'get_myValue' , 'function get_myValue\\(param1 in varchar2\\)\\s*return varchar2;' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'procedure set_myValue\\(param1 in varchar2\\);' , 14 , 'set_myValue' , 'procedure set_myValue\\(param1 in varchar2\\)\\s*is' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'function get_myValue\\(param1 in varchar2\\)\\s*return varchar2\\s*is' , 4 , 'function' , 'function get_myValue\\(param1 in varchar2\\)\\s*return varchar2;' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'procedure set_myValue\\(param1 in varchar2\\);' , 4 , 'procedure' , 'procedure set_myValue\\(param1 in varchar2\\)\\s*is' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'MyPackage.myCall\\(\'test\'\\);' , 14 , 'myCall' , 'procedure myCall\\(param1 in varchar2\\)\\s*is' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'schema.MyPackage.myCall\\(\'test2\'\\);' , 22 , 'myCall' , 'procedure myCall\\(param1 in varchar2\\)\\s*is' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'pCallInternal\\(\'test3\'\\);' , 5 , 'pCallInternal' , 'procedure pCallInternal\\(param1 in varchar2\\)\\s*is' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'MyPackage2.myCall\\(\'Test\'\\);' , 14 , 'myCall' , 'procedure myCall\\(param1 in varchar2\\)\\s*is' , 0 , 'xyz_myPackage2.pkb' ) , buildCase ( 'MyFunc\\(\'Test\'\\);' , 3 , 'MyFunc' , 'CREATE OR REPLACE FUNCTION MyFunc\\(param1 varchar2\\) return varchar2' , 0 , 'xyz_myFunc.sql' ) , buildCase ( 'if x = schema.MyPackage.myConst' , 26 , 'myConst' , 'myConst constant char\\(2\\) := \'10\';' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'if y = myGlobalVar' , 15 , 'myGlobalVar' , 'myGlobalVar number := 10;' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'xyz MyPackage2.txyz_myType;' , 20 , 'txyz_myType' , 'type txyz_myType is record' , 0 , 'xyz_myPackage2.pks' ) , buildCase ( 'abc ttxyz_myType;' , 13 , 'ttxyz_myType' , 'type ttxyz_myType is table of txyz_myType;' , 0 , 'xyz_myPackage.sql' ) ] ; runTest ( 'xyz_myPackage.sql' , testCases , done ) ; } ) ; test ( 'Package II' , ( done ) => { let testCases = [ buildCase ( 'function pForward\\(param1 in varchar2\\)\\s*return varchar2\\s*is' , 13 , 'pForward' , 'function pForward\\(param1 in varchar2\\)\\s*return varchar2;' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'function pForward\\(param1 in varchar2\\)\\s*return varchar2;' , 13 , 'pForward' , 'function pForward\\(param1 in varchar2\\)\\s*return varchar2\\s*is' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'function pForward\\(param1 in varchar2\\)\\s*return varchar2\\s*is' , 4 , 'function' , 'function pForward\\(param1 in varchar2\\)\\s*return varchar2;' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'function pForward\\(param1 in varchar2\\)\\s*return varchar2;' , 4 , 'function' , 'function pForward\\(param1 in varchar2\\)\\s*return varchar2\\s*is' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'pForward\\(\'test3\'\\);' , 5 , 'pForward' , 'function pForward\\(param1 in varchar2\\)\\s*return varchar2\\s*is' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'x = pSubFunction\\(2\\);' , 8 , 'pSubFunction' , 'function pSubFunction\\(param1 in number\\)\\s*is' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'if x = myConst2' , 12 , 'myConst2' , 'myConst2 constant char\\(2\\) := \'10\';' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'if y = myGlobalVar2' , 15 , 'myGlobalVar2' , 'myGlobalVar2 number := 10;' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'abc ttxyz_myType2;' , 13 , 'ttxyz_myType2' , 'type ttxyz_myType2 is table of txyz_myType2;' , 0 , 'xyz_myPackage.sql' ) ] ; runTest ( 'xyz_myPackage.sql' , testCases , done ) ; } ) ; test ( 'Separate package spec' , ( done ) => { let testCases = [ buildCase ( 'procedure set_myValue\\(param1 in varchar2\\);' , 14 , 'set_myValue' , 'procedure set_myValue\\(param1 in varchar2\\)\\s*is' , 0 , 'xyz_myPackage2.pkb' ) , ] ; runTest ( 'xyz_myPackage2.pks' , testCases , done ) ; } ) ; test ( 'Separate package body I' , ( done ) => { let testCases = [ buildCase ( 'function get_myValue\\(param1 in varchar2\\)\\s*return varchar2\\s*is' , 13 , 'get_myValue' , 'function get_myValue\\(param1 in varchar2\\)\\s*return varchar2;' , 0 , 'xyz_myPackage2.pks' ) , buildCase ( 'MyPackage2.myCall\\(\'test\'\\);' , 13 , 'myCall' , 'procedure myCall\\(param1 in varchar2\\)\\s*is' , 0 , 'xyz_myPackage2.pkb' ) , buildCase ( 'pCallInternal\\(\'test2\'\\);' , 5 , 'pCallInternal' , 'procedure pCallInternal\\(param1 in varchar2\\)\\s*is' , 0 , 'xyz_myPackage2.pkb' ) , buildCase ( 'MyPackage.myCall\\(\'Test\'\\);' , 12 , 'myCall' , 'procedure myCall\\(param1 in varchar2\\)\\s*is' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'MyFunc\\(\'Test\'\\);' , 2 , 'MyFunc' , 'CREATE OR REPLACE FUNCTION MyFunc\\(param1 varchar2\\) return varchar2\\s*is' , 0 , 'xyz_myFunc.sql' ) , buildCase ( 'MyProc\\(\'Test\'\\);' , 2 , 'MyProc' , 'CREATE OR REPLACE PROCEDURE "schema"."MyProc"\\(param1 varchar2\\)\\s*is' , 0 , 'xyz_myProc.sql' ) , buildCase ( 'schema.MyProc\\(\'Test\'\\);' , 9 , 'MyProc' , 'CREATE OR REPLACE PROCEDURE "schema"."MyProc"\\(param1 varchar2\\)\\s*is' , 0 , 'xyz_myProc.sql' ) , ] ; runTest ( 'xyz_myPackage2.pkb' , testCases , done ) ; } ) ; test ( 'Separate package body II' , ( done ) => { let testCases = [ buildCase ( 'if x = schema.MyPackage2.myConst' , 27 , 'myConst' , 'myConst constant char\\(2\\) := \'10\';' , 0 , 'xyz_myPackage2.pks' ) , buildCase ( 'if y = myGlobalVar' , 9 , 'myGlobalVar' , 'myGlobalVar number := 10;' , 0 , 'xyz_myPackage2.pks' ) , buildCase ( 'xyz MyPackage.txyz_myType;' , 18 , 'txyz_myType' , 'type txyz_myType is record\\(' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'abc ttxyz_myType;' , 10 , 'ttxyz_myType' , 'type ttxyz_myType is table of txyz_myType;' , 0 , 'xyz_myPackage2.pks' ) ] ; runTest ( 'xyz_myPackage2.pkb' , testCases , done ) ; } ) ; test ( 'Function' , ( done ) => { let testCases = [ buildCase ( 'myPackage.myCall\\(param1\\);' , 12 , 'myCall' , 'procedure myCall\\(param1 in varchar2\\)\\s*is' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'schema.MyProc\\(param1\\);' , 9 , 'MyProc' , 'CREATE OR REPLACE PROCEDURE "schema"."MyProc"\\(param1 varchar2\\)' , 0 , 'xyz_myProc.sql' ) , buildCase ( 'return myNestedFunc\\(param1\\);' , 9 , 'myNestedFunc' , 'function myNestedFunc\\(param1 varchar2\\)' , 0 , 'xyz_myFunc.sql' ) , buildCase ( 'if x = schema.MyPackage.myConst' , 26 , 'myConst' , 'myConst constant char\\(2\\) := \'10\';' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'if y = MyPackage2.myGlobalVar' , 20 , 'myGlobalVar' , 'myGlobalVar number := 10;' , 0 , 'xyz_myPackage2.pks' ) , buildCase ( 'xyz MyPackage2.txyz_myType;' , 19 , 'txyz_myType' , 'type txyz_myType is record\\(' , 0 , 'xyz_myPackage2.pks' ) , buildCase ( 'abc MyPackage.ttxyz_myType;' , 19 , 'ttxyz_myType' , 'type ttxyz_myType is table of txyz_myType;' , 0 , 'xyz_myPackage.sql' ) ] ; runTest ( 'xyz_myFunc.sql' , testCases , done ) ; } ) ; test ( 'Procedure' , ( done ) => { let testCases = [ buildCase ( 'myPackage.myCall\\(param1\\);' , 12 , 'myCall' , 'procedure myCall\\(param1 in varchar2\\)\\s*is' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'x := schema.MyFunc\\(param1\\);' , 14 , 'MyFunc' , 'CREATE OR REPLACE FUNCTION MyFunc\\(param1 varchar2\\) return varchar2' , 0 , 'xyz_myFunc.sql' ) , buildCase ( 'myNestedProc\\(param1\\);' , 2 , 'myNestedProc' , 'function myNestedProc\\(param1 varchar2\\)' , 0 , 'xyz_myProc.sql' ) , ] ; runTest ( 'xyz_myProc.sql' , testCases , done ) ; } ) ; test ( 'Dml' , ( done ) => { let testCases = [ buildCase ( 'set myField = MyPackage.set_myValue\\(\'toto\'\\)' , 28 , 'set_myValue' , 'procedure set_myValue\\(param1 in varchar2\\)\\s*is' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'if x = schema.MyPackage.myConst' , 26 , 'myConst' , 'myConst constant char\\(2\\) := \'10\';' , 0 , 'xyz_myPackage.sql' ) , buildCase ( 'if y = MyPackage2.myGlobalVar' , 20 , 'myGlobalVar' , 'myGlobalVar number := 10;' , 0 , 'xyz_myPackage2.pks' ) , buildCase ( 'xyz MyPackage2.txyz_myType;' , 20 , 'txyz_myType' , 'type txyz_myType is record\\(' , 0 , 'xyz_myPackage2.pks' ) , buildCase ( 'abc MyPackage.ttxyz_myType;' , 20 , 'ttxyz_myType' , 'type ttxyz_myType is table of txyz_myType;' , 0 , 'xyz_myPackage.sql' ) ] ; runTest ( 'xyz_myDml.sql' , testCases , done ) ; } ) ; } ) ;