-
Notifications
You must be signed in to change notification settings - Fork 2
/
node.test.js
166 lines (147 loc) · 5.3 KB
/
node.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import { jest } from "@jest/globals"
import fs from "fs"
import nock from "nock"
import {
createNodeVersion,
runAction,
runActionExpectError,
ignoreInstalled,
cleanPath,
Cleaner,
Mute,
} from "./testutil"
Mute.all()
const nodeVersions = [
createNodeVersion({ version: "v55.4.0" }),
createNodeVersion({ version: "v54.0.0", lts: "latest" }),
createNodeVersion({ version: "v52.0.0", lts: "test" }),
createNodeVersion({ version: "v51.3.1" }),
createNodeVersion({ version: "v51.0.0" }),
]
// Mock the node-version-data library so we can play with a controlled set of node versions
// and write predictable expectations in the tests
jest.unstable_mockModule("./node-version-data.js", () => {
return {
nodeVersions: [
...nodeVersions,
createNodeVersion({ version: "v49.0.0" }),
],
}
})
// Jest has issues when mocking entire modules in the ESM world
// This is a workaround for that. See https://github.com/facebook/jest/issues/10025#issuecomment-1147776145
const Node = (await import("./node.js")).default
describe("runAction node", () => {
const cleaner = new Cleaner(Node)
afterEach(cleaner.clean)
it("works", async () => {
const desiredVersion = "16.13.2"
const env = {
INPUT_NODE: desiredVersion,
...ignoreInstalled(),
}
return runAction("index", env).then((proc) => {
expect(proc.stderr.toString()).toBe("")
expect(proc.stdout).toContain(`node --version: ${desiredVersion}`)
expect(proc.stdout).toContain("nodenv update-version-defs")
expect(proc.stdout).toContain("node success!")
})
})
it("fails with bad NODENV_ROOT", () => {
let env = {
INPUT_NODE: "16.13.2",
NODENV_ROOT: "/tmp/.nodenv",
PATH: cleanPath("nodenv"),
...ignoreInstalled(),
}
return expect(
runActionExpectError("index", env).catch((err) => {
throw new Error(err.stdout)
}),
).rejects.toThrow(/::error::NODENV_ROOT misconfigured/)
})
})
describe("install", () => {
const cleaner = new Cleaner(Node)
afterEach(cleaner.clean)
it("works", async () => {
cleaner.root = await new Node().install(Node.tempRoot())
expect(cleaner.root).toMatch(/\/\.node/)
})
})
describe("setup", () => {
const cleaner = new Cleaner(Node)
afterEach(() => {
jest.resetAllMocks()
jest.clearAllMocks()
jest.restoreAllMocks()
cleaner.clean()
})
/**
* Mock the filesystem when trying to read a node version file
* @param fileName File that is being mocked
* @param version Content of the file, aka the node version
*/
const mockNodeVersionFile = (fileName, version) => {
// TODO This should not be done like this but mocking an ESM module is a bit more complicated
// Also mocking FS like this breaks inline snapshots
const exists = jest.fn().mockImplementation((file) => file === fileName)
const readFile = jest.fn().mockReturnValue(version)
jest.spyOn(fs, "existsSync").mockImplementation(exists)
jest.spyOn(fs, "readFileSync").mockImplementation(readFile)
}
const mockNodeVersionsApiCall = (shouldThrowError) => {
const api = nock("https://nodejs.org")
const method = api.get("/download/release/index.json")
if (shouldThrowError) {
method.reply(500)
} else {
method.reply(200, nodeVersions)
}
return api
}
it.each([
{
fileName: ".node-version",
content: "55.4.0",
expectedVersion: "55.4.0",
},
{ fileName: ".nvmrc", content: "lts/*", expectedVersion: "54.0.0" },
{ fileName: ".node-version", content: "51", expectedVersion: "51.3.1" },
{
fileName: ".node-version",
content: "lts/test",
expectedVersion: "52.0.0",
},
])(
`parses node versions correctly for: %o`,
async ({ fileName, content, expectedVersion }) => {
const api = mockNodeVersionsApiCall()
mockNodeVersionFile(fileName, content)
// Can't call setup here yet, as the fs mock breaks other inner calls
const [version] = await new Node().getNodeVersion()
expect(api.isDone()).toBeTruthy()
expect(version).toEqual(expectedVersion)
},
)
it("falls back to local node version cache when it fails to fetch it", async () => {
mockNodeVersionsApiCall(true)
mockNodeVersionFile(".node-version", "49")
const [version] = await new Node().getNodeVersion()
expect(version).toEqual("49.0.0")
})
it("throws an error when the version cannot be parsed", () => {
mockNodeVersionFile(".node-version", "invalid")
expect(new Node().setup()).rejects.toThrow(
/Could not parse Node version/,
)
})
it("works with an override version", async () => {
return new Node().setup("16.13.2")
})
it("is harmless if there's no versions", async () => {
const exists = jest.fn().mockImplementation(() => false)
jest.spyOn(fs, "existsSync").mockImplementation(exists)
return new Node().setup()
})
})