feat: add toInclude() function (#2234)
Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
This commit is contained in:
@@ -9,7 +9,8 @@
|
|||||||
"toBeLevel4xx": "fn()",
|
"toBeLevel4xx": "fn()",
|
||||||
"toBeLevel5xx": "fn()",
|
"toBeLevel5xx": "fn()",
|
||||||
"toBeType": "fn(type: string)",
|
"toBeType": "fn(type: string)",
|
||||||
"toHaveLength": "fn(length: number)"
|
"toHaveLength": "fn(length: number)",
|
||||||
|
"toInclude": "fn(value: ?)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"pw": {
|
"pw": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@hoppscotch/cli",
|
"name": "@hoppscotch/cli",
|
||||||
"version": "0.1.12",
|
"version": "0.1.13",
|
||||||
"description": "A CLI to run Hoppscotch test scripts in CI environments.",
|
"description": "A CLI to run Hoppscotch test scripts in CI environments.",
|
||||||
"homepage": "https://hoppscotch.io",
|
"homepage": "https://hoppscotch.io",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@hoppscotch/js-sandbox",
|
"name": "@hoppscotch/js-sandbox",
|
||||||
"version": "2.0.0",
|
"version": "2.1.0",
|
||||||
"description": "JavaScript sandboxes for running external scripts used by Hoppscotch clients",
|
"description": "JavaScript sandboxes for running external scripts used by Hoppscotch clients",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"module": "./lib/index.mjs",
|
"module": "./lib/index.mjs",
|
||||||
|
|||||||
@@ -0,0 +1,183 @@
|
|||||||
|
import * as TE from "fp-ts/TaskEither"
|
||||||
|
import { pipe } from "fp-ts/function"
|
||||||
|
import { execTestScript, TestResponse } from "../../../test-runner"
|
||||||
|
|
||||||
|
const fakeResponse: TestResponse = {
|
||||||
|
status: 200,
|
||||||
|
body: "hoi",
|
||||||
|
headers: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
const func = (script: string, res: TestResponse) =>
|
||||||
|
pipe(
|
||||||
|
execTestScript(script, { global: [], selected: [] }, res),
|
||||||
|
TE.map((x) => x.tests)
|
||||||
|
)
|
||||||
|
|
||||||
|
describe("toInclude", () => {
|
||||||
|
test("asserts true for collections with matching values", () => {
|
||||||
|
return expect(
|
||||||
|
func(
|
||||||
|
`
|
||||||
|
pw.expect([1, 2, 3]).toInclude(1)
|
||||||
|
pw.expect("123").toInclude(1)
|
||||||
|
`,
|
||||||
|
fakeResponse
|
||||||
|
)()
|
||||||
|
).resolves.toEqualRight([
|
||||||
|
expect.objectContaining({
|
||||||
|
expectResults: [
|
||||||
|
{ status: "pass", message: "Expected [1,2,3] to include 1" },
|
||||||
|
{ status: "pass", message: 'Expected "123" to include 1' },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("asserts false for collections without matching values", () => {
|
||||||
|
return expect(
|
||||||
|
func(
|
||||||
|
`
|
||||||
|
pw.expect([1, 2, 3]).toInclude(4)
|
||||||
|
pw.expect("123").toInclude(4)
|
||||||
|
`,
|
||||||
|
fakeResponse
|
||||||
|
)()
|
||||||
|
).resolves.toEqualRight([
|
||||||
|
expect.objectContaining({
|
||||||
|
expectResults: [
|
||||||
|
{ status: "fail", message: "Expected [1,2,3] to include 4" },
|
||||||
|
{ status: "fail", message: 'Expected "123" to include 4' },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("asserts false for empty collections", () => {
|
||||||
|
return expect(
|
||||||
|
func(
|
||||||
|
`
|
||||||
|
pw.expect([]).not.toInclude(0)
|
||||||
|
pw.expect("").not.toInclude(0)
|
||||||
|
`,
|
||||||
|
fakeResponse
|
||||||
|
)()
|
||||||
|
).resolves.toEqualRight([
|
||||||
|
expect.objectContaining({
|
||||||
|
expectResults: [
|
||||||
|
{
|
||||||
|
status: "pass",
|
||||||
|
message: "Expected [] to not include 0",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: "pass",
|
||||||
|
message: 'Expected "" to not include 0',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("asserts false for [number array].includes(string)", () => {
|
||||||
|
return expect(
|
||||||
|
func(
|
||||||
|
`
|
||||||
|
pw.expect([1]).not.toInclude("1")
|
||||||
|
`,
|
||||||
|
fakeResponse
|
||||||
|
)()
|
||||||
|
).resolves.toEqualRight([
|
||||||
|
expect.objectContaining({
|
||||||
|
expectResults: [
|
||||||
|
{
|
||||||
|
status: "pass",
|
||||||
|
message: 'Expected [1] to not include "1"',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("asserts true for [string].includes(number)", () => {
|
||||||
|
// This is a Node.js quirk.
|
||||||
|
// (`"123".includes(123)` returns `True` in Node.js v14.19.1)
|
||||||
|
// See https://tc39.es/ecma262/multipage/text-processing.html#sec-string.prototype.includes
|
||||||
|
return expect(
|
||||||
|
func(`pw.expect("123").toInclude(123)`, fakeResponse)()
|
||||||
|
).resolves.toEqualRight([
|
||||||
|
expect.objectContaining({
|
||||||
|
expectResults: [
|
||||||
|
{
|
||||||
|
status: "pass",
|
||||||
|
message: 'Expected "123" to include 123',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("gives error if not called on an array or string", () => {
|
||||||
|
return expect(
|
||||||
|
func(
|
||||||
|
`
|
||||||
|
pw.expect(5).not.toInclude(0)
|
||||||
|
pw.expect(true).not.toInclude(0)
|
||||||
|
`,
|
||||||
|
fakeResponse
|
||||||
|
)()
|
||||||
|
).resolves.toEqualRight([
|
||||||
|
expect.objectContaining({
|
||||||
|
expectResults: [
|
||||||
|
{
|
||||||
|
status: "error",
|
||||||
|
message: "Expected toInclude to be called for an array or string",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: "error",
|
||||||
|
message: "Expected toInclude to be called for an array or string",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("gives an error if toInclude parameter is null", () => {
|
||||||
|
return expect(
|
||||||
|
func(
|
||||||
|
`
|
||||||
|
pw.expect([1, 2, 3, 4]).not.toInclude(null)
|
||||||
|
`,
|
||||||
|
fakeResponse
|
||||||
|
)()
|
||||||
|
).resolves.toEqualRight([
|
||||||
|
expect.objectContaining({
|
||||||
|
expectResults: [
|
||||||
|
{
|
||||||
|
status: "error",
|
||||||
|
message: "Argument for toInclude should not be null",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("gives an error if toInclude parameter is undefined", () => {
|
||||||
|
return expect(
|
||||||
|
func(
|
||||||
|
`
|
||||||
|
pw.expect([1, 2, 3, 4]).not.toInclude(undefined)
|
||||||
|
`,
|
||||||
|
fakeResponse
|
||||||
|
)()
|
||||||
|
).resolves.toEqualRight([
|
||||||
|
expect.objectContaining({
|
||||||
|
expectResults: [
|
||||||
|
{
|
||||||
|
status: "error",
|
||||||
|
message: "Argument for toInclude should not be undefined",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -312,6 +312,61 @@ function createExpectation(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const toIncludeHandle = vm.newFunction("toInclude", (needleHandle) => {
|
||||||
|
const expectedVal = vm.dump(needleHandle)
|
||||||
|
|
||||||
|
if (!(Array.isArray(expectVal) || typeof expectVal === "string")) {
|
||||||
|
currTestStack[currTestStack.length - 1].expectResults.push({
|
||||||
|
status: "error",
|
||||||
|
message: `Expected toInclude to be called for an array or string`,
|
||||||
|
})
|
||||||
|
|
||||||
|
return { value: vm.undefined }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expectedVal === null) {
|
||||||
|
currTestStack[currTestStack.length - 1].expectResults.push({
|
||||||
|
status: "error",
|
||||||
|
message: `Argument for toInclude should not be null`,
|
||||||
|
})
|
||||||
|
|
||||||
|
return { value: vm.undefined }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expectedVal === undefined) {
|
||||||
|
currTestStack[currTestStack.length - 1].expectResults.push({
|
||||||
|
status: "error",
|
||||||
|
message: `Argument for toInclude should not be undefined`,
|
||||||
|
})
|
||||||
|
|
||||||
|
return { value: vm.undefined }
|
||||||
|
}
|
||||||
|
|
||||||
|
let assertion = expectVal.includes(expectedVal)
|
||||||
|
if (negated) assertion = !assertion
|
||||||
|
|
||||||
|
const expectValPretty = JSON.stringify(expectVal)
|
||||||
|
const expectedValPretty = JSON.stringify(expectedVal)
|
||||||
|
|
||||||
|
if (assertion) {
|
||||||
|
currTestStack[currTestStack.length - 1].expectResults.push({
|
||||||
|
status: "pass",
|
||||||
|
message: `Expected ${expectValPretty} to${
|
||||||
|
negated ? " not" : ""
|
||||||
|
} include ${expectedValPretty}`,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
currTestStack[currTestStack.length - 1].expectResults.push({
|
||||||
|
status: "fail",
|
||||||
|
message: `Expected ${expectValPretty} to${
|
||||||
|
negated ? " not" : ""
|
||||||
|
} include ${expectedValPretty}`,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return { value: vm.undefined }
|
||||||
|
})
|
||||||
|
|
||||||
vm.setProp(resultHandle, "toBe", toBeFnHandle)
|
vm.setProp(resultHandle, "toBe", toBeFnHandle)
|
||||||
vm.setProp(resultHandle, "toBeLevel2xx", toBeLevel2xxHandle)
|
vm.setProp(resultHandle, "toBeLevel2xx", toBeLevel2xxHandle)
|
||||||
vm.setProp(resultHandle, "toBeLevel3xx", toBeLevel3xxHandle)
|
vm.setProp(resultHandle, "toBeLevel3xx", toBeLevel3xxHandle)
|
||||||
@@ -319,6 +374,7 @@ function createExpectation(
|
|||||||
vm.setProp(resultHandle, "toBeLevel5xx", toBeLevel5xxHandle)
|
vm.setProp(resultHandle, "toBeLevel5xx", toBeLevel5xxHandle)
|
||||||
vm.setProp(resultHandle, "toBeType", toBeTypeHandle)
|
vm.setProp(resultHandle, "toBeType", toBeTypeHandle)
|
||||||
vm.setProp(resultHandle, "toHaveLength", toHaveLengthHandle)
|
vm.setProp(resultHandle, "toHaveLength", toHaveLengthHandle)
|
||||||
|
vm.setProp(resultHandle, "toInclude", toIncludeHandle)
|
||||||
|
|
||||||
vm.defineProp(resultHandle, "not", {
|
vm.defineProp(resultHandle, "not", {
|
||||||
get: () => {
|
get: () => {
|
||||||
@@ -333,6 +389,7 @@ function createExpectation(
|
|||||||
toBeLevel5xxHandle.dispose()
|
toBeLevel5xxHandle.dispose()
|
||||||
toBeTypeHandle.dispose()
|
toBeTypeHandle.dispose()
|
||||||
toHaveLengthHandle.dispose()
|
toHaveLengthHandle.dispose()
|
||||||
|
toIncludeHandle.dispose()
|
||||||
|
|
||||||
return resultHandle
|
return resultHandle
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user