JS: Add test

This commit is contained in:
Asger F
2025-04-11 13:03:20 +02:00
parent 4bfb0483a8
commit 1051136c07
26 changed files with 342 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
import * as express from 'express';
function getRequest(): express.Request { }
function t1() {
getRequest(); // $ hasUnderlyingType='express'.Request
}
declare function getRequestAmbient(): express.Request;
function t2() {
getRequestAmbient(); // $ hasUnderlyingType='express'.Request
}
class C {
method(): express.Request { }
}
function t3(c: C) {
c.method(); // $ hasUnderlyingType='express'.Request
new C().method(); // $ hasUnderlyingType='express'.Request
}
function callback(fn: (req: express.Request) => void) { // $ SPURIOUS: hasUnderlyingType='express'.Request // req seems to be a SourceNode
}
function t4() {
callback(function (
req // $ hasUnderlyingType='express'.Request
) { }
);
}

View File

@@ -0,0 +1,5 @@
goog.declareModuleId("closure.es")
const Bar = goog.require('closure.reexported.Bar');
export { Bar }

View File

@@ -0,0 +1,3 @@
goog.module("closure.lib")
exports.Foo = goog.require('closure.reexported.Foo');

View File

@@ -0,0 +1,16 @@
goog.module("closure.use")
const lib = goog.require("closure.lib");
const es = goog.require("closure.es");
/**
* @param {lib.Foo} x
*/
function t1(x) { // $ hasUnderlyingType=closure.reexported.Foo hasUnderlyingType=closure.lib.Foo
}
/**
* @param {es.Bar} x
*/
function t2(x) { // $ hasUnderlyingType=closure.reexported.Bar hasUnderlyingType=closure.es.Bar
}

View File

@@ -0,0 +1,45 @@
import * as express from 'express';
interface Options {
handle(req: express.Request): void; // $ hasUnderlyingType='express'.Request
}
declare function doSomething(options: Options);
function t1() {
doSomething({
handle(req) { // $ hasUnderlyingType='express'.Request
}
});
}
function t2(callback: ((opts: Options) => void) | undefined) {
callback({
handle(req) { } // $ hasUnderlyingType='express'.Request
})
callback!({
handle(req) { } // $ hasUnderlyingType='express'.Request
})
}
function t3(): Options {
return {
handle(req) { } // $ hasUnderlyingType='express'.Request
}
}
function t4(): Options[] {
return [
{
handle(req) { } // $ hasUnderlyingType='express'.Request
}
]
}
async function t5(): Promise<Options> {
return {
handle(req) { // $ hasUnderlyingType='express'.Request
}
}
}

View File

@@ -0,0 +1 @@
export * from 'express';

View File

@@ -0,0 +1,7 @@
import { Request, Response } from './expressBulkExport';
function t1(req: Request) { // $ hasUnderlyingType='express'.Request
}
function t2(res: Response) { // $ hasUnderlyingType='express'.Response
}

View File

@@ -0,0 +1,2 @@
import E = require('express');
export = E;

View File

@@ -0,0 +1,4 @@
import { Request } from "./expressExportAssign";
function t1(req: Request) { // $ hasUnderlyingType='express'.Request
}

View File

@@ -0,0 +1,5 @@
import Express = require('express');
namespace Wrapper {
export import E = Express;
}
export = Wrapper;

View File

@@ -0,0 +1,4 @@
import { E } from "./expressExportAssignWrapper";
function t1(req: E.Request) { // $ hasUnderlyingType='express'.Request
}

View File

@@ -0,0 +1,2 @@
export { Request } from 'express';
export { Response as R } from 'express';

View File

@@ -0,0 +1,10 @@
import { Request, Response, R } from './expressSelectiveExport';
function t1(req: Request) { // $ hasUnderlyingType='express'.Request
}
function t2(res: Response) { // none, not exported
}
function t3(res: R) { // $ hasUnderlyingType='express'.Response
}

View File

@@ -0,0 +1 @@
export * as wrapper from 'express';

View File

@@ -0,0 +1,29 @@
import { Request, Response, wrapper } from './expressWrapperExport';
import * as w from './expressWrapperExport';
function t1(req: Request) { // none
}
function t2(res: Response) { // none
}
function t3(req: wrapper.Request) { // $ hasUnderlyingType='express'.Request
}
function t4(res: wrapper.Response) { // $ hasUnderlyingType='express'.Response
}
function t5(req: w.wrapper.Request) { // $ hasUnderlyingType='express'.Request
}
function t6(res: w.wrapper.Response) { // $ hasUnderlyingType='express'.Response
}
function t7(req: w.Request) { // none
}
function t8(res: w.Response) { // none
}
function t9(e: typeof w.wrapper) { // $ hasUnderlyingType='express'
}

View File

@@ -0,0 +1,10 @@
function t1(el: HTMLElement) { } // $ hasUnderlyingType=HTMLElement
/**
* @param {HTMLInputElement} el
*/
function t2(el) { // $ hasUnderlyingType=HTMLInputElement
}
function t3(req: Express.Request) { // $ hasUnderlyingType=Express.Request
}

View File

@@ -0,0 +1,14 @@
import * as e from 'express';
import { Response } from 'express';
/**
* @param {e.Request} req
*/
function t1(req) { // $ hasUnderlyingType='express'.Request
}
/**
* @param {Response} res
*/
function t2(res) { // $ hasUnderlyingType='express'.Response
}

View File

@@ -0,0 +1,4 @@
import { Request } from 'express';
function t1(req: Request) { // $ hasUnderlyingType='express'.Request
}

View File

@@ -0,0 +1,27 @@
import Express = require('express');
namespace A {
export import E = Express;
}
namespace B {
export import Q = A
}
namespace C {
import E = Express;
export const A = E;
}
function t1(x: A.E.Request) { // $ hasUnderlyingType='express'.Request
}
function t2(x: B.Q.E.Request) { // $ hasUnderlyingType='express'.Request
}
function t3(x: typeof Express) { // $ hasUnderlyingType='express'
}
function t4(x: typeof A.E) { // $ hasUnderlyingType='express'
}
function t5(x: typeof C.A) { // $ hasUnderlyingType='express'
}

View File

@@ -0,0 +1,15 @@
import * as express from 'express';
function t1(e: typeof express) { // $ hasUnderlyingType='express'
}
function t2(req: express.Request) { // $ hasUnderlyingType='express'.Request
}
function t3(req: Request) { // $ hasUnderlyingType=Request // not in scope, refers to a global
}
type E = typeof express;
function t4(e: E) { // $ hasUnderlyingType='express'
}

View File

@@ -0,0 +1,16 @@
import * as express from 'express';
interface Foo {
req: express.Request;
e: typeof express;
}
function t1(f: Foo) {
f.req; // $ hasUnderlyingType='express'.Request
f.e; // $ hasUnderlyingType='express'
const {
req, // $ hasUnderlyingType='express'.Request
e // $ hasUnderlyingType='express'
} = f;
}

View File

@@ -0,0 +1,20 @@
import * as express from 'express';
interface MyRequest extends express.Request {
}
function t1(req: MyRequest) { // $ hasUnderlyingType='express'.Request
}
class MyRequestClass extends express.Request {
}
function t2(req: MyRequestClass) { // $ hasUnderlyingType='express'.Request
}
class MyRequestClass2 implements express.Request {
}
function t3(req: MyRequestClass2) { // $ hasUnderlyingType='express'.Request
}

View File

@@ -0,0 +1,50 @@
| calls.ts:6:5:6:16 | getRequest() | 'express'.Request |
| calls.ts:12:5:12:23 | getRequestAmbient() | 'express'.Request |
| calls.ts:20:5:20:14 | c.method() | 'express'.Request |
| calls.ts:21:5:21:20 | new C().method() | 'express'.Request |
| calls.ts:24:24:24:26 | req | 'express'.Request |
| calls.ts:29:9:29:11 | req | 'express'.Request |
| closure.use.js:9:13:9:13 | x | closure.lib.Foo |
| closure.use.js:9:13:9:13 | x | closure.reexported.Foo |
| closure.use.js:15:13:15:13 | x | closure.es.Bar |
| closure.use.js:15:13:15:13 | x | closure.reexported.Bar |
| contextualTypes.ts:4:12:4:14 | req | 'express'.Request |
| contextualTypes.ts:11:16:11:18 | req | 'express'.Request |
| contextualTypes.ts:18:16:18:18 | req | 'express'.Request |
| contextualTypes.ts:21:16:21:18 | req | 'express'.Request |
| contextualTypes.ts:27:16:27:18 | req | 'express'.Request |
| contextualTypes.ts:34:20:34:22 | req | 'express'.Request |
| contextualTypes.ts:41:16:41:18 | req | 'express'.Request |
| expressBulkExport.use.ts:3:13:3:15 | req | 'express'.Request |
| expressBulkExport.use.ts:6:13:6:15 | res | 'express'.Response |
| expressExportAssign.use.ts:3:13:3:15 | req | 'express'.Request |
| expressExportAssignWrapper.use.ts:3:13:3:15 | req | 'express'.Request |
| expressSelectiveExport.use.ts:3:13:3:15 | req | 'express'.Request |
| expressSelectiveExport.use.ts:9:13:9:15 | res | 'express'.Response |
| expressWrapperExport.use.ts:10:13:10:15 | req | 'express'.Request |
| expressWrapperExport.use.ts:13:13:13:15 | res | 'express'.Response |
| expressWrapperExport.use.ts:16:13:16:15 | req | 'express'.Request |
| expressWrapperExport.use.ts:19:13:19:15 | res | 'express'.Response |
| expressWrapperExport.use.ts:28:13:28:13 | e | 'express' |
| globals.ts:1:13:1:14 | el | HTMLElement |
| globals.ts:6:13:6:14 | el | HTMLInputElement |
| globals.ts:9:13:9:15 | req | Express.Request |
| jsdoc.js:7:13:7:15 | req | 'express'.Request |
| jsdoc.js:13:13:13:15 | res | 'express'.Response |
| namedImport.ts:3:13:3:15 | req | 'express'.Request |
| namespaceDecls.ts:14:13:14:13 | x | 'express'.Request |
| namespaceDecls.ts:17:13:17:13 | x | 'express'.Request |
| namespaceDecls.ts:20:13:20:13 | x | 'express' |
| namespaceDecls.ts:23:13:23:13 | x | 'express' |
| namespaceDecls.ts:26:13:26:13 | x | 'express' |
| namespaceImport.ts:3:13:3:13 | e | 'express' |
| namespaceImport.ts:6:13:6:15 | req | 'express'.Request |
| namespaceImport.ts:9:13:9:15 | req | Request |
| namespaceImport.ts:14:13:14:13 | e | 'express' |
| props.ts:9:5:9:9 | f.req | 'express'.Request |
| props.ts:10:5:10:7 | f.e | 'express' |
| props.ts:13:9:13:11 | req | 'express'.Request |
| props.ts:14:9:14:9 | e | 'express' |
| subtype.ts:7:13:7:15 | req | 'express'.Request |
| subtype.ts:13:13:13:15 | req | 'express'.Request |
| subtype.ts:19:13:19:15 | req | 'express'.Request |

View File

@@ -0,0 +1,15 @@
import javascript
bindingset[x, y]
private string join(string x, string y) {
if x = "" or y = "" then result = x + y else result = x + "." + y
}
query predicate hasUnderlyingType(DataFlow::SourceNode node, string value) {
node.hasUnderlyingType(value)
or
exists(string mod, string name |
node.hasUnderlyingType(mod, name) and
value = join("'" + mod + "'", name)
)
}

View File

@@ -0,0 +1,2 @@
query: test.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -0,0 +1,3 @@
{
"include": ["."]
}