chore: approach Node.js' "suites and tests" way of testing (#328)

8e3c26c · Paulo F. Oliveira · 2025-04-26 22:54

5 files +800 -867

Files changed

modified .github/workflows/ubuntu.yml
+2 −38
@@ -69,47 +69,11 @@ jobs:
69 69 - otp-version: '26'
70 70 rebar3-version: 'nightly'
71 71 os: 'ubuntu-latest'
72 - elixir-version: 'v1.6'
73 otp-version: '21'
74 rebar3-version: '3.12'
75 os: 'ubuntu-20.04'
76 - elixir-version: 'v1.7'
77 otp-version: '22'
78 rebar3-version: '3.13'
79 os: 'ubuntu-20.04'
80 - elixir-version: 'v1.10'
81 otp-version: '23'
82 rebar3-version: '3.14'
83 os: 'ubuntu-20.04'
84 - elixir-version: 'v1.13.4'
85 otp-version: '25.0.2'
86 rebar3-version: '3.19'
87 os: 'ubuntu-20.04'
88 - elixir-version: 'v1.12'
89 otp-version: '24'
90 rebar3-version: '3.15'
91 os: 'ubuntu-20.04'
92 - elixir-version: 'v1.11.0'
93 otp-version: '22.3.4.2'
94 os: 'ubuntu-20.04'
95 version-type: 'strict'
96 - elixir-version: '1.10.3'
97 otp-version: '22.3.4.1'
98 os: 'ubuntu-20.04'
99 version-type: 'strict'
100 - elixir-version: 'main'
101 otp-version: '23.1'
102 os: 'ubuntu-20.04'
103 version-type: 'strict'
104 - elixir-version: 'main'
105 otp-version: '25'
106 os: 'ubuntu-20.04'
107 version-type: 'strict'
108 - gleam-version: '1.5.1'
72 + - gleam-version: '1.9.0'
109 73 otp-version: '27'
110 74 os: 'ubuntu-latest'
111 75 disable_problem_matchers: true
112 - gleam-version: '1.5.1'
76 + - gleam-version: '1.9.0'
113 77 otp-version: false
114 78 os: 'ubuntu-latest'
115 79 disable_problem_matchers: true
modified .github/workflows/windows.yml
+1 −1
@@ -58,7 +58,7 @@ jobs:
58 58 otp-version: '24'
59 59 rebar3-version: '3.15'
60 60 os: 'windows-latest'
61 - gleam-version: '1.5.1'
61 + - gleam-version: '1.9.0'
62 62 otp-version: '27'
63 63 os: 'windows-latest'
64 64 - elixir-version: 'v1.13'
modified README.md
+9 −9
@@ -106,7 +106,7 @@ jobs:
106 106 test:
107 107 runs-on: self-hosted
108 108 env:
109 ImageOS: ubuntu20 # equivalent to runs-on ubuntu-20.04
109 + ImageOS: ubuntu24 # equivalent to runs-on ubuntu-24.04
110 110 steps:
111 111 - uses: actions/checkout@v4
112 112 - uses: erlef/setup-beam@v1
@@ -241,12 +241,12 @@ on: push
241 241
242 242 jobs:
243 243 test:
244 runs-on: ubuntu-20.04
244 + runs-on: ubuntu-24.04
245 245 name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}
246 246 strategy:
247 247 matrix:
248 otp: ['21.1', '22.2', '23.3']
249 elixir: ['1.8.2', '1.9.4']
248 + otp: ['25.3.2', '26.2.5', '27.3.3']
249 + elixir: ['1.17.3', '1.18.3']
250 250 steps:
251 251 - uses: actions/checkout@v4
252 252 - uses: erlef/setup-beam@v1
@@ -265,12 +265,12 @@ on: push
265 265
266 266 jobs:
267 267 test:
268 runs-on: ubuntu-20.04
268 + runs-on: ubuntu-24.04
269 269 name: Erlang/OTP ${{matrix.otp}} / rebar3 ${{matrix.rebar3}}
270 270 strategy:
271 271 matrix:
272 otp: ['21.1', '22.2', '23.3']
273 rebar3: ['3.14.1', '3.14.3']
272 + otp: ['25.3.2', '26.2.5', '27.3.3']
273 + rebar3: ['3.23.0', '3.24.0']
274 274 steps:
275 275 - uses: actions/checkout@v4
276 276 - uses: erlef/setup-beam@v1
@@ -312,7 +312,7 @@ jobs:
312 312 - uses: erlef/setup-beam@v1
313 313 with:
314 314 otp-version: '27'
315 gleam-version: '1.5.1'
315 + gleam-version: '1.9.0'
316 316 - run: gleam test
317 317 ```
318 318
@@ -330,7 +330,7 @@ jobs:
330 330 - uses: erlef/setup-beam@v1
331 331 with:
332 332 otp-version: false
333 gleam-version: '1.5.1'
333 + gleam-version: '1.9.0'
334 334 - run: gleam check
335 335 ```
336 336
modified package.json
+1 −1
@@ -9,7 +9,7 @@
9 9 "licenses": "yarn licenses generate-disclaimer > 3RD_PARTY_LICENSES",
10 10 "markdownlint": "markdownlint *.md ./github/**/*.md",
11 11 "shellcheck": "shellcheck .github/workflows/*.sh",
12 "test": "node test/setup-beam.test.js",
12 + "test": "node --test --test-reporter=spec",
13 13 "yamllint": "yamllint .github/workflows/**.yml && yamllint .*.yml && yamllint *.yml",
14 14 "clean-dist": "rm -rf ./dist",
15 15 "lint": "npm run markdownlint && npm run shellcheck && npm run yamllint && npm run jslint",
modified test/setup-beam.test.js
+787 −818
@@ -12,9 +12,9 @@ const http = require('http')
12 12 const fs = require('fs')
13 13 const os = require('os')
14 14 const path = require('path')
15 const core = require('@actions/core')
16 15 const setupBeam = require('../src/setup-beam')
17 16 const { problemMatcher } = require('../matchers/elixir-matchers.json')
17 +const { describe, it } = require('node:test')
18 18
19 19 const matrix = {
20 20 otp: {
@@ -58,112 +58,97 @@ function parseReleases(version) {
58 58 }
59 59 }
60 60
61 async function all() {
62 await testFailInstallOTP()
63 await testFailInstallElixir()
64 await testFailInstallGleam()
65 await testFailInstallRebar3()
66 await testFailGetOTPVersion()
67
68 await testOTPVersions()
69 await testLinuxARM64OTPVersions()
70 await testLinuxAMD64OTPVersions()
71 await testElixirVersions()
72 await testGleamVersions()
73 await testRebar3Versions()
74
75 await testGetVersionFromSpec()
76 await testParseVersionFile()
77 await testGetRetry()
78
79 await testElixirMixCompileError()
80 await testElixirMixCompileWarning()
81 await testElixirMixTestFailure()
82 await testElixirCredoOutputDefault()
83 }
84
85 async function testFailInstallOTP() {
86 const otpOSVersion = 'ubuntu-08.04'
87 const otpVersion = 'OTP-23.2'
88 assert.rejects(
89 async () => {
90 await setupBeam.install('otp', {
91 hexMirror: 'https://builds.hex.pm',
92 otpOSVersion,
93 otpVersion,
94 })
95 },
96 (err) => {
97 assert.ok(err instanceof Error)
98 return true
99 },
100 `Installing Erlang/OTP ${otpVersion} over ${otpOSVersion} is supposed to fail`,
101 )
102 }
61 +describe('OTP install', () => {
62 + it('fails for invalid OS version', async () => {
63 + const otpOSVersion = 'ubuntu-08.04'
64 + const otpVersion = 'OTP-23.2'
103 65
104 async function testFailInstallElixir() {
105 let exVersion
66 + assert.rejects(
67 + async () => {
68 + await setupBeam.install('otp', {
69 + hexMirror: 'https://builds.hex.pm',
70 + otpOSVersion,
71 + otpVersion,
72 + })
73 + },
74 + (err) => {
75 + assert.ok(err instanceof Error)
76 + return true
77 + },
78 + `Installing Erlang/OTP ${otpVersion} over ${otpOSVersion} is supposed to fail`,
79 + )
80 + })
81 +})
106 82
107 exVersion = '0.11'
108 assert.rejects(
109 async () => {
110 await setupBeam.install('elixir', {
111 hexMirror: 'https://builds.hex.pm',
112 exVersion,
113 })
114 },
115 (err) => {
116 assert.ok(err instanceof Error)
117 return true
118 },
119 `Installing Elixir ${exVersion} is supposed to fail`,
120 )
83 +describe('Elixir install', () => {
84 + it('fails for version 0.11 without OTP', async () => {
85 + const exVersion = '0.11'
86 + assert.rejects(
87 + async () => {
88 + await setupBeam.install('elixir', {
89 + hexMirror: 'https://builds.hex.pm',
90 + exVersion,
91 + })
92 + },
93 + (err) => {
94 + assert.ok(err instanceof Error)
95 + return true
96 + },
97 + `Installing Elixir ${exVersion} is supposed to fail`,
98 + )
99 + })
121 100
122 exVersion = 'v1.0.0-otp-17'
123 assert.rejects(
124 async () => {
125 await setupBeam.install('elixir', {
126 hexMirror: 'https://builds.hex.pm',
127 exVersion,
128 })
129 },
130 (err) => {
131 assert.ok(err instanceof Error)
132 return true
133 },
134 `Installing Elixir ${exVersion} is supposed to fail`,
135 )
136 }
101 + it('fails for version 1.0.0 on OTP 17 (without OTP)', async () => {
102 + const exVersion = 'v1.0.0-otp-17'
103 + assert.rejects(
104 + async () => {
105 + await setupBeam.install('elixir', {
106 + hexMirror: 'https://builds.hex.pm',
107 + exVersion,
108 + })
109 + },
110 + (err) => {
111 + assert.ok(err instanceof Error)
112 + return true
113 + },
114 + `Installing Elixir ${exVersion} is supposed to fail`,
115 + )
116 + })
117 +})
137 118
138 async function testFailInstallGleam() {
139 const gleamVersion = '0.1.3'
140 assert.rejects(
141 async () => {
142 await setupBeam.install('gleam', { gleamVersion })
143 },
144 (err) => {
145 assert.ok(err instanceof Error)
146 return true
147 },
148 `Installing Gleam ${gleamVersion} is supposed to fail`,
149 )
150 }
119 +describe('Gleam install', () => {
120 + it('fails for unknown OTP', async () => {
121 + const gleamVersion = '0.1.3'
122 + assert.rejects(
123 + async () => {
124 + await setupBeam.install('gleam', { gleamVersion })
125 + },
126 + (err) => {
127 + assert.ok(err instanceof Error)
128 + return true
129 + },
130 + `Installing Gleam ${gleamVersion} is supposed to fail`,
131 + )
132 + })
133 +})
151 134
152 async function testFailInstallRebar3() {
153 const r3Version = '0.14.4'
154 assert.rejects(
155 async () => {
156 await setupBeam.install('rebar3', { r3Version })
157 },
158 (err) => {
159 assert.ok(err instanceof Error)
160 return true
161 },
162 `Installing rebar3 ${r3Version} is supposed to fail`,
163 )
164 }
135 +describe('rebar3 install', () => {
136 + it('fails for unknown OTP', async () => {
137 + const r3Version = '0.14.4'
138 + assert.rejects(
139 + async () => {
140 + await setupBeam.install('rebar3', { r3Version })
141 + },
142 + (err) => {
143 + assert.ok(err instanceof Error)
144 + return true
145 + },
146 + `Installing rebar3 ${r3Version} is supposed to fail`,
147 + )
148 + })
149 +})
165 150
166 async function testOTPVersions() {
151 +describe('.getOTPVersion(_) - Erlang', () => {
167 152 let got
168 153 let expected
169 154 let spec
@@ -174,856 +159,847 @@ async function testOTPVersions() {
174 159 'https://repo.hex.pm, https://cdn.jsdelivr.net/hex',
175 160 { multiline: true },
176 161 )
162 + const previousRunnerArch = process.env.RUNNER_ARCH
177 163
178 164 if (process.platform === 'linux') {
179 const previousRunnerArch = process.env.RUNNER_ARCH
180 165 process.env.RUNNER_ARCH = 'X64'
181 166
182 before = simulateInput('version-type', 'strict')
183 spec = '26'
184 osVersion = 'ubuntu-24.04'
185 expected = 'maint-26'
186 got = await setupBeam.getOTPVersion(spec, osVersion)
187 assert.deepStrictEqual(got, expected)
188 simulateInput('version-type', before)
167 + it('is Ok for known linux version', async () => {
168 + before = simulateInput('version-type', 'strict')
169 + spec = '26'
170 + osVersion = 'ubuntu-24.04'
171 + expected = 'maint-26'
172 + got = await setupBeam.getOTPVersion(spec, osVersion)
173 + assert.deepStrictEqual(got, expected)
174 + simulateInput('version-type', before)
175 +
176 + before = simulateInput('version-type', 'strict')
177 + spec = '27.0'
178 + osVersion = 'ubuntu-24.04'
179 + expected = 'OTP-27.0'
180 + got = await setupBeam.getOTPVersion(spec, osVersion)
181 + assert.deepStrictEqual(got, expected)
182 + simulateInput('version-type', before)
183 +
184 + before = simulateInput('version-type', 'strict')
185 + spec = '25.3.2.1'
186 + osVersion = 'ubuntu-20.04'
187 + expected = 'OTP-25.3.2.1'
188 + got = await setupBeam.getOTPVersion(spec, osVersion)
189 + assert.deepStrictEqual(got, expected)
190 + simulateInput('version-type', before)
191 +
192 + spec = '19.3.x'
193 + osVersion = 'ubuntu-16.04'
194 + expected = 'OTP-19.3.6.13'
195 + got = await setupBeam.getOTPVersion(spec, osVersion)
196 + assert.deepStrictEqual(got, expected)
197 +
198 + spec = '^19.3.6'
199 + osVersion = 'ubuntu-16.04'
200 + expected = 'OTP-19.3.6.13'
201 + got = await setupBeam.getOTPVersion(spec, osVersion)
202 + assert.deepStrictEqual(got, expected)
203 +
204 + spec = '^19.3'
205 + osVersion = 'ubuntu-18.04'
206 + expected = 'OTP-19.3.6.13'
207 + got = await setupBeam.getOTPVersion(spec, osVersion)
208 + assert.deepStrictEqual(got, expected)
209 +
210 + spec = '20'
211 + osVersion = 'ubuntu-20.04'
212 + expected = 'OTP-20.3.8.26'
213 + got = await setupBeam.getOTPVersion(spec, osVersion)
214 + assert.deepStrictEqual(got, expected)
215 +
216 + spec = '20.3.8.26'
217 + osVersion = 'ubuntu-20.04'
218 + expected = 'OTP-20.3.8.26'
219 + got = await setupBeam.getOTPVersion(spec, osVersion)
220 + assert.deepStrictEqual(got, expected)
221 +
222 + spec = '20.x'
223 + osVersion = 'ubuntu-20.04'
224 + expected = 'OTP-20.3.8.26'
225 + got = await setupBeam.getOTPVersion(spec, osVersion)
226 + assert.deepStrictEqual(got, expected)
227 +
228 + spec = '20.0'
229 + osVersion = 'ubuntu-20.04'
230 + expected = 'OTP-20.0.5'
231 + got = await setupBeam.getOTPVersion(spec, osVersion)
232 + assert.deepStrictEqual(got, expected)
233 +
234 + spec = '20.0.x'
235 + osVersion = 'ubuntu-20.04'
236 + expected = 'OTP-20.0.5'
237 + got = await setupBeam.getOTPVersion(spec, osVersion)
238 + assert.deepStrictEqual(got, expected)
239 +
240 + spec = 'maint'
241 + osVersion = 'ubuntu-22.04'
242 + expected = 'maint'
243 + got = await setupBeam.getOTPVersion(spec, osVersion)
244 + assert.deepStrictEqual(got, expected)
245 +
246 + spec = 'master'
247 + osVersion = 'ubuntu-22.04'
248 + expected = 'master'
249 + got = await setupBeam.getOTPVersion(spec, osVersion)
250 + assert.deepStrictEqual(got, expected)
251 + })
252 + }
189 253
190 before = simulateInput('version-type', 'strict')
191 spec = '27.0'
192 osVersion = 'ubuntu-24.04'
193 expected = 'OTP-27.0'
194 got = await setupBeam.getOTPVersion(spec, osVersion)
195 assert.deepStrictEqual(got, expected)
196 simulateInput('version-type', before)
254 + if (process.platform === 'win32') {
255 + it('is Ok for known win32 version', async () => {
256 + spec = '24.0.1'
257 + osVersion = 'windows-latest'
258 + expected = '24.0.1'
259 + got = await setupBeam.getOTPVersion(spec, osVersion)
260 + assert.deepStrictEqual(got, expected)
261 +
262 + spec = '23.2.x'
263 + osVersion = 'windows-2016'
264 + expected = '23.2.7'
265 + got = await setupBeam.getOTPVersion(spec, osVersion)
266 + assert.deepStrictEqual(got, expected)
267 +
268 + spec = '23.0'
269 + osVersion = 'windows-2019'
270 + expected = '23.0.4'
271 + got = await setupBeam.getOTPVersion(spec, osVersion)
272 + assert.deepStrictEqual(got, expected)
273 +
274 + // Check we get the same results for 32-bit OTP
275 + before = simulateInput('otp-architecture', '32')
276 +
277 + spec = '24.0.1'
278 + osVersion = 'windows-latest'
279 + expected = '24.0.1'
280 + got = await setupBeam.getOTPVersion(spec, osVersion)
281 + assert.deepStrictEqual(got, expected)
282 +
283 + spec = '23.2.x'
284 + osVersion = 'windows-2016'
285 + expected = '23.2.7'
286 + got = await setupBeam.getOTPVersion(spec, osVersion)
287 + assert.deepStrictEqual(got, expected)
288 +
289 + spec = '23.0'
290 + osVersion = 'windows-2019'
291 + expected = '23.0.4'
292 + got = await setupBeam.getOTPVersion(spec, osVersion)
293 + assert.deepStrictEqual(got, expected)
294 +
295 + simulateInput('otp-architecture', before)
296 + })
297 + }
197 298
198 before = simulateInput('version-type', 'strict')
199 spec = '25.3.2.1'
200 osVersion = 'ubuntu-20.04'
201 expected = 'OTP-25.3.2.1'
202 got = await setupBeam.getOTPVersion(spec, osVersion)
203 assert.deepStrictEqual(got, expected)
204 simulateInput('version-type', before)
299 + if (process.platform === 'linux') {
300 + it('is Ok for known linux ARM64 version', async () => {
301 + const arm64Options = setupBeam.githubARMRunnerArchs()
302 + process.env.RUNNER_ARCH =
303 + arm64Options[Math.floor(Math.random() * arm64Options.length)]
304 +
305 + before = simulateInput('version-type', 'strict')
306 + spec = '26'
307 + osVersion = 'ubuntu-24.04'
308 + expected = 'maint-26'
309 + got = await setupBeam.getOTPVersion(spec, osVersion)
310 + assert.deepStrictEqual(got, expected)
311 + simulateInput('version-type', before)
312 +
313 + before = simulateInput('version-type', 'strict')
314 + spec = '27.0'
315 + osVersion = 'ubuntu-24.04'
316 + expected = 'OTP-27.0'
317 + got = await setupBeam.getOTPVersion(spec, osVersion)
318 + assert.deepStrictEqual(got, expected)
319 + simulateInput('version-type', before)
320 +
321 + before = simulateInput('version-type', 'strict')
322 + spec = '25.3.2.1'
323 + osVersion = 'ubuntu-20.04'
324 + expected = 'OTP-25.3.2.1'
325 + got = await setupBeam.getOTPVersion(spec, osVersion)
326 + assert.deepStrictEqual(got, expected)
327 + simulateInput('version-type', before)
328 +
329 + spec = '20'
330 + osVersion = 'ubuntu-20.04'
331 + expected = 'OTP-20.3.8.26'
332 + got = await setupBeam.getOTPVersion(spec, osVersion)
333 + assert.deepStrictEqual(got, expected)
334 +
335 + spec = '20.3.8.26'
336 + osVersion = 'ubuntu-20.04'
337 + expected = 'OTP-20.3.8.26'
338 + got = await setupBeam.getOTPVersion(spec, osVersion)
339 + assert.deepStrictEqual(got, expected)
340 +
341 + spec = '20.x'
342 + osVersion = 'ubuntu-20.04'
343 + expected = 'OTP-20.3.8.26'
344 + got = await setupBeam.getOTPVersion(spec, osVersion)
345 + assert.deepStrictEqual(got, expected)
346 +
347 + spec = '20.0'
348 + osVersion = 'ubuntu-20.04'
349 + expected = 'OTP-20.0.5'
350 + got = await setupBeam.getOTPVersion(spec, osVersion)
351 + assert.deepStrictEqual(got, expected)
352 +
353 + spec = '20.0.x'
354 + osVersion = 'ubuntu-20.04'
355 + expected = 'OTP-20.0.5'
356 + got = await setupBeam.getOTPVersion(spec, osVersion)
357 + assert.deepStrictEqual(got, expected)
358 +
359 + spec = 'maint'
360 + osVersion = 'ubuntu-22.04'
361 + expected = 'maint'
362 + got = await setupBeam.getOTPVersion(spec, osVersion)
363 + assert.deepStrictEqual(got, expected)
364 +
365 + spec = 'master'
366 + osVersion = 'ubuntu-22.04'
367 + expected = 'master'
368 + got = await setupBeam.getOTPVersion(spec, osVersion)
369 + assert.deepStrictEqual(got, expected)
370 + })
371 +
372 + it('is Ok for known linux AMD64 version', async () => {
373 + const amd64Options = setupBeam.githubAMDRunnerArchs()
374 + process.env.RUNNER_ARCH =
375 + amd64Options[Math.floor(Math.random() * amd64Options.length)]
376 +
377 + before = simulateInput('version-type', 'strict')
378 + spec = '26'
379 + osVersion = 'ubuntu-24.04'
380 + expected = 'maint-26'
381 + got = await setupBeam.getOTPVersion(spec, osVersion)
382 + assert.deepStrictEqual(got, expected)
383 + simulateInput('version-type', before)
384 +
385 + before = simulateInput('version-type', 'strict')
386 + spec = '27.0'
387 + osVersion = 'ubuntu-24.04'
388 + expected = 'OTP-27.0'
389 + got = await setupBeam.getOTPVersion(spec, osVersion)
390 + assert.deepStrictEqual(got, expected)
391 + simulateInput('version-type', before)
392 +
393 + before = simulateInput('version-type', 'strict')
394 + spec = '25.3.2.1'
395 + osVersion = 'ubuntu-20.04'
396 + expected = 'OTP-25.3.2.1'
397 + got = await setupBeam.getOTPVersion(spec, osVersion)
398 + assert.deepStrictEqual(got, expected)
399 + simulateInput('version-type', before)
400 +
401 + spec = '19.3.x'
402 + osVersion = 'ubuntu-16.04'
403 + expected = 'OTP-19.3.6.13'
404 + got = await setupBeam.getOTPVersion(spec, osVersion)
405 + assert.deepStrictEqual(got, expected)
406 +
407 + spec = '^19.3.6'
408 + osVersion = 'ubuntu-16.04'
409 + expected = 'OTP-19.3.6.13'
410 + got = await setupBeam.getOTPVersion(spec, osVersion)
411 + assert.deepStrictEqual(got, expected)
412 +
413 + spec = '^19.3'
414 + osVersion = 'ubuntu-18.04'
415 + expected = 'OTP-19.3.6.13'
416 + got = await setupBeam.getOTPVersion(spec, osVersion)
417 + assert.deepStrictEqual(got, expected)
418 +
419 + spec = '20'
420 + osVersion = 'ubuntu-20.04'
421 + expected = 'OTP-20.3.8.26'
422 + got = await setupBeam.getOTPVersion(spec, osVersion)
423 + assert.deepStrictEqual(got, expected)
424 +
425 + spec = '20.3.8.26'
426 + osVersion = 'ubuntu-20.04'
427 + expected = 'OTP-20.3.8.26'
428 + got = await setupBeam.getOTPVersion(spec, osVersion)
429 + assert.deepStrictEqual(got, expected)
430 +
431 + spec = '20.x'
432 + osVersion = 'ubuntu-20.04'
433 + expected = 'OTP-20.3.8.26'
434 + got = await setupBeam.getOTPVersion(spec, osVersion)
435 + assert.deepStrictEqual(got, expected)
436 +
437 + spec = '20.0'
438 + osVersion = 'ubuntu-20.04'
439 + expected = 'OTP-20.0.5'
440 + got = await setupBeam.getOTPVersion(spec, osVersion)
441 + assert.deepStrictEqual(got, expected)
442 +
443 + spec = '20.0.x'
444 + osVersion = 'ubuntu-20.04'
445 + expected = 'OTP-20.0.5'
446 + got = await setupBeam.getOTPVersion(spec, osVersion)
447 + assert.deepStrictEqual(got, expected)
448 +
449 + spec = 'maint'
450 + osVersion = 'ubuntu-22.04'
451 + expected = 'maint'
452 + got = await setupBeam.getOTPVersion(spec, osVersion)
453 + assert.deepStrictEqual(got, expected)
454 +
455 + spec = 'master'
456 + osVersion = 'ubuntu-22.04'
457 + expected = 'master'
458 + got = await setupBeam.getOTPVersion(spec, osVersion)
459 + assert.deepStrictEqual(got, expected)
460 + })
461 + }
205 462
206 spec = '19.3.x'
207 osVersion = 'ubuntu-16.04'
208 expected = 'OTP-19.3.6.13'
209 got = await setupBeam.getOTPVersion(spec, osVersion)
210 assert.deepStrictEqual(got, expected)
463 + simulateInput('hexpm-mirrors', hexMirrors, { multiline: true })
464 + process.env.RUNNER_ARCH = previousRunnerArch
465 +})
211 466
212 spec = '^19.3.6'
213 osVersion = 'ubuntu-16.04'
214 expected = 'OTP-19.3.6.13'
215 got = await setupBeam.getOTPVersion(spec, osVersion)
216 assert.deepStrictEqual(got, expected)
467 +describe('OTP arch-specific install', () => {
468 + it('fails for invalid GitHub runner arch.', async () => {
469 + const previousRunnerArch = process.env.RUNNER_ARCH
470 + process.env.RUNNER_ARCH = 'invalid'
471 +
472 + if (process.platform === 'linux') {
473 + const spec = '26'
474 + const osVersion = 'ubuntu-24.04'
475 +
476 + assert.rejects(
477 + async () => {
478 + await setupBeam.getOTPVersion(spec, osVersion)
479 + },
480 + (err) => {
481 + assert.ok(err instanceof Error)
482 + return true
483 + },
484 + `Fetching OTP Version with invalid Github runner architecture is supposed to fail`,
485 + )
486 + }
487 + process.env.RUNNER_ARCH = previousRunnerArch
488 + })
489 +})
490 +
491 +describe('.getOTPVersion(_) - Elixir', () => {
492 + let got
493 + let expected
494 + let spec
495 + let otpVersion
496 + let before
497 + const hexMirrors = simulateInput('hexpm-mirrors', 'https://repo.hex.pm', {
498 + multiline: true,
499 + })
217 500
218 spec = '^19.3'
219 osVersion = 'ubuntu-18.04'
220 expected = 'OTP-19.3.6.13'
221 got = await setupBeam.getOTPVersion(spec, osVersion)
501 + it('returns the expected value', async () => {
502 + spec = '1.1.x'
503 + otpVersion = 'OTP-17'
504 + expected = 'v1.1.1-otp-17'
505 + got = await setupBeam.getElixirVersion(spec, otpVersion)
222 506 assert.deepStrictEqual(got, expected)
223 507
224 spec = '20'
225 osVersion = 'ubuntu-20.04'
226 expected = 'OTP-20.3.8.26'
227 got = await setupBeam.getOTPVersion(spec, osVersion)
508 + spec = '1.10.4'
509 + otpVersion = 'OTP-23'
510 + expected = 'v1.10.4-otp-23'
511 + got = await setupBeam.getElixirVersion(spec, otpVersion)
228 512 assert.deepStrictEqual(got, expected)
229 513
230 spec = '20.3.8.26'
231 osVersion = 'ubuntu-20.04'
232 expected = 'OTP-20.3.8.26'
233 got = await setupBeam.getOTPVersion(spec, osVersion)
514 + spec = '1.12.1'
515 + otpVersion = 'OTP-24.0.2'
516 + expected = 'v1.12.1-otp-24'
517 + got = await setupBeam.getElixirVersion(spec, otpVersion)
234 518 assert.deepStrictEqual(got, expected)
235 519
236 spec = '20.x'
237 osVersion = 'ubuntu-20.04'
238 expected = 'OTP-20.3.8.26'
239 got = await setupBeam.getOTPVersion(spec, osVersion)
520 + before = simulateInput('version-type', 'strict')
521 + spec = '1.14.0'
522 + otpVersion = 'main'
523 + expected = 'v1.14.0'
524 + got = await setupBeam.getElixirVersion(spec, otpVersion)
240 525 assert.deepStrictEqual(got, expected)
526 + simulateInput('version-type', before)
241 527
242 spec = '20.0'
243 osVersion = 'ubuntu-20.04'
244 expected = 'OTP-20.0.5'
245 got = await setupBeam.getOTPVersion(spec, osVersion)
528 + before = simulateInput('version-type', 'strict')
529 + spec = 'v1.11.0-rc.0'
530 + otpVersion = 'OTP-23'
531 + expected = 'v1.11.0-rc.0-otp-23'
532 + got = await setupBeam.getElixirVersion(spec, otpVersion)
246 533 assert.deepStrictEqual(got, expected)
534 + simulateInput('version-type', before)
247 535
248 spec = '20.0.x'
249 osVersion = 'ubuntu-20.04'
250 expected = 'OTP-20.0.5'
251 got = await setupBeam.getOTPVersion(spec, osVersion)
536 + before = simulateInput('version-type', 'strict')
537 + spec = 'v1.11.0-rc.0-otp-23'
538 + otpVersion = 'OTP-23'
539 + expected = 'v1.11.0-rc.0-otp-23'
540 + got = await setupBeam.getElixirVersion(spec, otpVersion)
252 541 assert.deepStrictEqual(got, expected)
542 + simulateInput('version-type', before)
253 543
254 spec = 'maint'
255 osVersion = 'ubuntu-22.04'
256 expected = 'maint'
257 got = await setupBeam.getOTPVersion(spec, osVersion)
544 + before = simulateInput('version-type', 'strict')
545 + spec = 'v1.11.0'
546 + otpVersion = '22.3.4.2'
547 + expected = 'v1.11.0-otp-22'
548 + got = await setupBeam.getElixirVersion(spec, otpVersion)
258 549 assert.deepStrictEqual(got, expected)
550 + simulateInput('version-type', before)
259 551
260 spec = 'master'
261 osVersion = 'ubuntu-22.04'
262 expected = 'master'
263 got = await setupBeam.getOTPVersion(spec, osVersion)
552 + before = simulateInput('version-type', 'strict')
553 + spec = 'main'
554 + otpVersion = '23.1'
555 + expected = 'main-otp-23'
556 + got = await setupBeam.getElixirVersion(spec, otpVersion)
264 557 assert.deepStrictEqual(got, expected)
558 + simulateInput('version-type', before)
559 + })
265 560
266 process.env.RUNNER_ARCH = previousRunnerArch
267 }
561 + simulateInput('hexpm-mirrors', hexMirrors, { multiline: true })
562 +})
268 563
269 if (process.platform === 'win32') {
270 spec = '24.0.1'
271 osVersion = 'windows-latest'
272 expected = '24.0.1'
273 got = await setupBeam.getOTPVersion(spec, osVersion)
564 +describe('.getOTPVersion(_) - Gleam', () => {
565 + let got
566 + let expected
567 + let spec
568 + let otpVersion
569 +
570 + it('returns the expected value', async () => {
571 + spec = 'v0.3.0'
572 + otpVersion = 'OTP-23'
573 + expected = 'v0.3.0'
574 + got = await setupBeam.getGleamVersion(spec, otpVersion)
274 575 assert.deepStrictEqual(got, expected)
275 576
276 spec = '23.2.x'
277 osVersion = 'windows-2016'
278 expected = '23.2.7'
279 got = await setupBeam.getOTPVersion(spec, osVersion)
577 + spec = '0.13.2'
578 + otpVersion = 'OTP-24'
579 + expected = 'v0.13.2'
580 + got = await setupBeam.getGleamVersion(spec, otpVersion)
280 581 assert.deepStrictEqual(got, expected)
281 582
282 spec = '23.0'
283 osVersion = 'windows-2019'
284 expected = '23.0.4'
285 got = await setupBeam.getOTPVersion(spec, osVersion)
583 + const before = simulateInput('version-type', 'strict')
584 + spec = 'v0.14.0-rc2'
585 + otpVersion = 'OTP-22'
586 + expected = 'v0.14.0-rc2'
587 + got = await setupBeam.getGleamVersion(spec, otpVersion)
286 588 assert.deepStrictEqual(got, expected)
589 + simulateInput('version-type', before)
590 + })
591 +})
287 592
288 // Check we get the same results for 32-bit OTP
289 before = simulateInput('otp-architecture', '32')
593 +describe('.getOTPVersion(_) - rebar3', () => {
594 + let got
595 + let expected
596 + let spec
290 597
291 spec = '24.0.1'
292 osVersion = 'windows-latest'
293 expected = '24.0.1'
294 got = await setupBeam.getOTPVersion(spec, osVersion)
598 + it('returns the expected value', async () => {
599 + spec = '3.10.x'
600 + expected = '3.10.0'
601 + got = await setupBeam.getRebar3Version(spec)
295 602 assert.deepStrictEqual(got, expected)
296 603
297 spec = '23.2.x'
298 osVersion = 'windows-2016'
299 expected = '23.2.7'
300 got = await setupBeam.getOTPVersion(spec, osVersion)
604 + spec = '3.11'
605 + expected = '3.11.1'
606 + got = await setupBeam.getRebar3Version(spec)
301 607 assert.deepStrictEqual(got, expected)
302 608
303 spec = '23.0'
304 osVersion = 'windows-2019'
305 expected = '23.0.4'
306 got = await setupBeam.getOTPVersion(spec, osVersion)
609 + spec = '3.10'
610 + expected = '3.10.0'
611 + got = await setupBeam.getRebar3Version(spec)
307 612 assert.deepStrictEqual(got, expected)
613 + })
614 +})
308 615
309 simulateInput('otp-architecture', before)
310 }
311
312 simulateInput('hexpm-mirrors', hexMirrors, { multiline: true })
313 }
314
315 async function testLinuxARM64OTPVersions() {
616 +describe('.getVersionFromSpec(_)', () => {
316 617 let got
317 618 let expected
318 619 let spec
319 let osVersion
320 620 let before
321 const hexMirrors = simulateInput(
322 'hexpm-mirrors',
323 'https://repo.hex.pm, https://cdn.jsdelivr.net/hex',
324 { multiline: true },
325 )
621 + const versions0 = [
622 + '3.2.30.5',
623 + '3.2.3.5',
624 + '1',
625 + '2',
626 + '3.2.3.4.1',
627 + '1.0.9',
628 + '3.2.3.40.1',
629 + '1.0.2',
630 + '2.0',
631 + '2.10',
632 + '2.9',
633 + '1.0',
634 + '3.2.3.4.2',
635 + '1.1.0',
636 + '3.4.5.4',
637 + '3.4.5.3',
638 + '3.4.5.4.1',
639 + '24.0-rc3',
640 + '24.0-rc2',
641 + '24.0',
642 + '23.3.4',
643 + '23.3.3',
644 + '22.3.4.9.1',
645 + '22.3.4.12.1',
646 + '22.3.4.10.1',
647 + '22.3.4.2',
648 + 'main',
649 + 'v11.11.0-rc.0-otp-23',
650 + '22.3.4.2.1.0',
651 + '12.1.2.2',
652 + '12.1.2.4',
653 + '12.1.2.0',
654 + '12.1.2.3',
655 + '12.1.2.3.0',
656 + ]
657 + let versions = {}
658 + versions0.forEach((version) => {
659 + versions[version] = version
660 + })
326 661
327 const arm64Options = setupBeam.githubARMRunnerArchs()
328 process.env.RUNNER_ARCH =
329 arm64Options[Math.floor(Math.random() * arm64Options.length)]
662 + it('returns the expected value', async () => {
663 + spec = '1'
664 + expected = '1.1.0'
665 + got = setupBeam.getVersionFromSpec(spec, versions)
666 + assert.deepStrictEqual(got, expected)
330 667
331 if (process.platform === 'linux') {
332 before = simulateInput('version-type', 'strict')
333 spec = '26'
334 osVersion = 'ubuntu-24.04'
335 expected = 'maint-26'
336 got = await setupBeam.getOTPVersion(spec, osVersion)
668 + spec = '1.0'
669 + expected = '1.0.9'
670 + got = setupBeam.getVersionFromSpec(spec, versions)
337 671 assert.deepStrictEqual(got, expected)
338 simulateInput('version-type', before)
339 672
340 673 before = simulateInput('version-type', 'strict')
341 spec = '27.0'
342 osVersion = 'ubuntu-24.04'
343 expected = 'OTP-27.0'
344 got = await setupBeam.getOTPVersion(spec, osVersion)
674 + spec = '1'
675 + expected = '1'
676 + got = setupBeam.getVersionFromSpec(spec, versions)
345 677 assert.deepStrictEqual(got, expected)
346 678 simulateInput('version-type', before)
347 679
348 680 before = simulateInput('version-type', 'strict')
349 spec = '25.3.2.1'
350 osVersion = 'ubuntu-20.04'
351 expected = 'OTP-25.3.2.1'
352 got = await setupBeam.getOTPVersion(spec, osVersion)
681 + spec = '1.0'
682 + expected = '1.0'
683 + got = setupBeam.getVersionFromSpec(spec, versions)
353 684 assert.deepStrictEqual(got, expected)
354 685 simulateInput('version-type', before)
355 686
356 spec = '20'
357 osVersion = 'ubuntu-20.04'
358 expected = 'OTP-20.3.8.26'
359 got = await setupBeam.getOTPVersion(spec, osVersion)
687 + spec = '2'
688 + expected = '2.10'
689 + got = setupBeam.getVersionFromSpec(spec, versions)
360 690 assert.deepStrictEqual(got, expected)
361 691
362 spec = '20.3.8.26'
363 osVersion = 'ubuntu-20.04'
364 expected = 'OTP-20.3.8.26'
365 got = await setupBeam.getOTPVersion(spec, osVersion)
692 + spec = '3'
693 + expected = '3.4.5.4.1'
694 + got = setupBeam.getVersionFromSpec(spec, versions)
366 695 assert.deepStrictEqual(got, expected)
367 696
368 spec = '20.x'
369 osVersion = 'ubuntu-20.04'
370 expected = 'OTP-20.3.8.26'
371 got = await setupBeam.getOTPVersion(spec, osVersion)
697 + spec = '3.2'
698 + expected = '3.2.30.5'
699 + got = setupBeam.getVersionFromSpec(spec, versions)
372 700 assert.deepStrictEqual(got, expected)
373 701
374 spec = '20.0'
375 osVersion = 'ubuntu-20.04'
376 expected = 'OTP-20.0.5'
377 got = await setupBeam.getOTPVersion(spec, osVersion)
702 + spec = '>20'
703 + expected = '24.0'
704 + got = setupBeam.getVersionFromSpec(spec, versions)
378 705 assert.deepStrictEqual(got, expected)
379 706
380 spec = '20.0.x'
381 osVersion = 'ubuntu-20.04'
382 expected = 'OTP-20.0.5'
383 got = await setupBeam.getOTPVersion(spec, osVersion)
707 + spec = '24.0'
708 + expected = '24.0'
709 + got = setupBeam.getVersionFromSpec(spec, versions)
384 710 assert.deepStrictEqual(got, expected)
385 711
386 spec = 'maint'
387 osVersion = 'ubuntu-22.04'
388 expected = 'maint'
389 got = await setupBeam.getOTPVersion(spec, osVersion)
712 + before = simulateInput('version-type', 'strict')
713 + spec = '24.0-rc3'
714 + expected = '24.0-rc3'
715 + got = setupBeam.getVersionFromSpec(spec, versions)
390 716 assert.deepStrictEqual(got, expected)
717 + simulateInput('version-type', before)
391 718
392 spec = 'master'
393 osVersion = 'ubuntu-22.04'
394 expected = 'master'
395 got = await setupBeam.getOTPVersion(spec, osVersion)
719 + spec = '24.0-rc2'
720 + expected = '24.0-rc2'
721 + got = setupBeam.getVersionFromSpec(spec, versions)
396 722 assert.deepStrictEqual(got, expected)
397 }
398 723
399 simulateInput('hexpm-mirrors', hexMirrors, { multiline: true })
400 }
724 + spec = '22.3'
725 + expected = '22.3.4.12.1'
726 + got = setupBeam.getVersionFromSpec(spec, versions)
727 + assert.deepStrictEqual(got, expected)
401 728
402 async function testLinuxAMD64OTPVersions() {
403 let got
404 let expected
405 let spec
406 let osVersion
407 let before
408 const hexMirrors = simulateInput(
409 'hexpm-mirrors',
410 'https://repo.hex.pm, https://cdn.jsdelivr.net/hex',
411 { multiline: true },
412 )
729 + spec = '23.3.3'
730 + expected = '23.3.3'
731 + got = setupBeam.getVersionFromSpec(spec, versions)
732 + assert.deepStrictEqual(got, expected)
413 733
414 const amd64Options = setupBeam.githubAMDRunnerArchs()
415 process.env.RUNNER_ARCH =
416 amd64Options[Math.floor(Math.random() * amd64Options.length)]
734 + spec = '24'
735 + expected = '24.0'
736 + got = setupBeam.getVersionFromSpec(spec, versions)
737 + assert.deepStrictEqual(got, expected)
417 738
418 if (process.platform === 'linux') {
419 before = simulateInput('version-type', 'strict')
420 spec = '26'
421 osVersion = 'ubuntu-24.04'
422 expected = 'maint-26'
423 got = await setupBeam.getOTPVersion(spec, osVersion)
739 + spec = '23.3'
740 + expected = '23.3.4'
741 + got = setupBeam.getVersionFromSpec(spec, versions)
424 742 assert.deepStrictEqual(got, expected)
425 simulateInput('version-type', before)
426 743
427 744 before = simulateInput('version-type', 'strict')
428 spec = '27.0'
429 osVersion = 'ubuntu-24.04'
430 expected = 'OTP-27.0'
431 got = await setupBeam.getOTPVersion(spec, osVersion)
745 + spec = 'main'
746 + expected = 'main'
747 + got = setupBeam.getVersionFromSpec(spec, versions)
432 748 assert.deepStrictEqual(got, expected)
433 749 simulateInput('version-type', before)
434 750
435 751 before = simulateInput('version-type', 'strict')
436 spec = '25.3.2.1'
437 osVersion = 'ubuntu-20.04'
438 expected = 'OTP-25.3.2.1'
439 got = await setupBeam.getOTPVersion(spec, osVersion)
752 + spec = '22.3.4.2'
753 + expected = '22.3.4.2'
754 + got = setupBeam.getVersionFromSpec(spec, versions)
440 755 assert.deepStrictEqual(got, expected)
441 756 simulateInput('version-type', before)
442 757
443 spec = '19.3.x'
444 osVersion = 'ubuntu-16.04'
445 expected = 'OTP-19.3.6.13'
446 got = await setupBeam.getOTPVersion(spec, osVersion)
758 + spec = '22.3.4.2'
759 + expected = '22.3.4.2.1.0'
760 + got = setupBeam.getVersionFromSpec(spec, versions)
447 761 assert.deepStrictEqual(got, expected)
448 762
449 spec = '^19.3.6'
450 osVersion = 'ubuntu-16.04'
451 expected = 'OTP-19.3.6.13'
452 got = await setupBeam.getOTPVersion(spec, osVersion)
763 + spec = '22.3.4.2.1'
764 + expected = '22.3.4.2.1.0'
765 + got = setupBeam.getVersionFromSpec(spec, versions)
453 766 assert.deepStrictEqual(got, expected)
454 767
455 spec = '^19.3'
456 osVersion = 'ubuntu-18.04'
457 expected = 'OTP-19.3.6.13'
458 got = await setupBeam.getOTPVersion(spec, osVersion)
768 + spec = '22.3.4.2.1.0'
769 + expected = '22.3.4.2.1.0'
770 + got = setupBeam.getVersionFromSpec(spec, versions)
459 771 assert.deepStrictEqual(got, expected)
460 772
461 spec = '20'
462 osVersion = 'ubuntu-20.04'
463 expected = 'OTP-20.3.8.26'
464 got = await setupBeam.getOTPVersion(spec, osVersion)
773 + spec = '12.1.2.3'
774 + expected = '12.1.2.3.0'
775 + got = setupBeam.getVersionFromSpec(spec, versions)
465 776 assert.deepStrictEqual(got, expected)
466 777
467 spec = '20.3.8.26'
468 osVersion = 'ubuntu-20.04'
469 expected = 'OTP-20.3.8.26'
470 got = await setupBeam.getOTPVersion(spec, osVersion)
778 + spec = '22.3.4.2.1.0.1'
779 + expected = null
780 + got = setupBeam.getVersionFromSpec(spec, versions)
471 781 assert.deepStrictEqual(got, expected)
472 782
473 spec = '20.x'
474 osVersion = 'ubuntu-20.04'
475 expected = 'OTP-20.3.8.26'
476 got = await setupBeam.getOTPVersion(spec, osVersion)
783 + before = simulateInput('version-type', 'strict')
784 + spec = '22.3.4.3'
785 + expected = null
786 + got = setupBeam.getVersionFromSpec(spec, versions)
477 787 assert.deepStrictEqual(got, expected)
788 + simulateInput('version-type', before)
478 789
479 spec = '20.0'
480 osVersion = 'ubuntu-20.04'
481 expected = 'OTP-20.0.5'
482 got = await setupBeam.getOTPVersion(spec, osVersion)
790 + spec = 'latest'
791 + expected = '24.0'
792 + got = setupBeam.getVersionFromSpec(spec, versions)
483 793 assert.deepStrictEqual(got, expected)
484 794
485 spec = '20.0.x'
486 osVersion = 'ubuntu-20.04'
487 expected = 'OTP-20.0.5'
488 got = await setupBeam.getOTPVersion(spec, osVersion)
795 + versions = {
796 + '27.0.0-rc3': '27.0.0-rc3',
797 + '27.0.0-rc2': '27.0.0-rc2',
798 + }
799 + spec = 'latest'
800 + expected = '27.0.0-rc3'
801 + got = setupBeam.getVersionFromSpec(spec, versions)
489 802 assert.deepStrictEqual(got, expected)
490 803
491 spec = 'maint'
492 osVersion = 'ubuntu-22.04'
493 expected = 'maint'
494 got = await setupBeam.getOTPVersion(spec, osVersion)
804 + versions = {
805 + '27.0.0-rc3': '27.0.0-rc3',
806 + '27.0.0-rc2': '27.0.0-rc2',
807 + '27.0.0': '27.0.0',
808 + }
809 + spec = 'latest'
810 + expected = '27.0.0'
811 + got = setupBeam.getVersionFromSpec(spec, versions)
495 812 assert.deepStrictEqual(got, expected)
496 813
497 spec = 'master'
498 osVersion = 'ubuntu-22.04'
499 expected = 'master'
500 got = await setupBeam.getOTPVersion(spec, osVersion)
814 + versions = { '25.3.2.8': '25.3.2.8', '25.3.2.12': '25.3.2.12' }
815 + spec = 'latest'
816 + expected = '25.3.2.12'
817 + got = setupBeam.getVersionFromSpec(spec, versions)
501 818 assert.deepStrictEqual(got, expected)
502 }
503
504 simulateInput('hexpm-mirrors', hexMirrors, { multiline: true })
505 }
506
507 async function testFailGetOTPVersion() {
508 const previousRunnerArch = process.env.RUNNER_ARCH
509 process.env.RUNNER_ARCH = 'invalid'
510
511 if (process.platform === 'linux') {
512 const spec = '26'
513 const osVersion = 'ubuntu-24.04'
514
515 assert.rejects(
516 async () => {
517 await setupBeam.getOTPVersion(spec, osVersion)
518 },
519 (err) => {
520 assert.ok(err instanceof Error)
521 return true
522 },
523 `Fetching OTP Version with invalid Github runner architecture is supposed to fail`,
524 )
525 }
526 process.env.RUNNER_ARCH = previousRunnerArch
527 }
528 819
529 async function testElixirVersions() {
530 let got
531 let expected
532 let spec
533 let otpVersion
534 let before
535 const hexMirrors = simulateInput('hexpm-mirrors', 'https://repo.hex.pm', {
536 multiline: true,
537 })
538
539 spec = '1.1.x'
540 otpVersion = 'OTP-17'
541 expected = 'v1.1.1-otp-17'
542 got = await setupBeam.getElixirVersion(spec, otpVersion)
543 assert.deepStrictEqual(got, expected)
544
545 spec = '1.10.4'
546 otpVersion = 'OTP-23'
547 expected = 'v1.10.4-otp-23'
548 got = await setupBeam.getElixirVersion(spec, otpVersion)
549 assert.deepStrictEqual(got, expected)
550
551 spec = '1.12.1'
552 otpVersion = 'OTP-24.0.2'
553 expected = 'v1.12.1-otp-24'
554 got = await setupBeam.getElixirVersion(spec, otpVersion)
555 assert.deepStrictEqual(got, expected)
556
557 before = simulateInput('version-type', 'strict')
558 spec = '1.14.0'
559 otpVersion = 'main'
560 expected = 'v1.14.0'
561 got = await setupBeam.getElixirVersion(spec, otpVersion)
562 assert.deepStrictEqual(got, expected)
563 simulateInput('version-type', before)
564
565 before = simulateInput('version-type', 'strict')
566 spec = 'v1.11.0-rc.0'
567 otpVersion = 'OTP-23'
568 expected = 'v1.11.0-rc.0-otp-23'
569 got = await setupBeam.getElixirVersion(spec, otpVersion)
570 assert.deepStrictEqual(got, expected)
571 simulateInput('version-type', before)
572
573 before = simulateInput('version-type', 'strict')
574 spec = 'v1.11.0-rc.0-otp-23'
575 otpVersion = 'OTP-23'
576 expected = 'v1.11.0-rc.0-otp-23'
577 got = await setupBeam.getElixirVersion(spec, otpVersion)
578 assert.deepStrictEqual(got, expected)
579 simulateInput('version-type', before)
580
581 before = simulateInput('version-type', 'strict')
582 spec = 'v1.11.0'
583 otpVersion = '22.3.4.2'
584 expected = 'v1.11.0-otp-22'
585 got = await setupBeam.getElixirVersion(spec, otpVersion)
586 assert.deepStrictEqual(got, expected)
587 simulateInput('version-type', before)
588
589 before = simulateInput('version-type', 'strict')
590 spec = 'main'
591 otpVersion = '23.1'
592 expected = 'main-otp-23'
593 got = await setupBeam.getElixirVersion(spec, otpVersion)
594 assert.deepStrictEqual(got, expected)
595 simulateInput('version-type', before)
596
597 simulateInput('hexpm-mirrors', hexMirrors, { multiline: true })
598 }
820 + spec = 'latest'
821 + expected = 'OTP-26.2.1'
822 + got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-18.04'])
823 + assert.deepStrictEqual(got, expected)
599 824
600 async function testGleamVersions() {
601 let got
602 let expected
603 let spec
604 let otpVersion
825 + spec = 'latest'
826 + expected = 'OTP-27.0-rc3'
827 + got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-20.04'])
828 + assert.deepStrictEqual(got, expected)
605 829
606 spec = 'v0.3.0'
607 otpVersion = 'OTP-23'
608 expected = 'v0.3.0'
609 got = await setupBeam.getGleamVersion(spec, otpVersion)
610 assert.deepStrictEqual(got, expected)
611
612 spec = '0.13.2'
613 otpVersion = 'OTP-24'
614 expected = 'v0.13.2'
615 got = await setupBeam.getGleamVersion(spec, otpVersion)
616 assert.deepStrictEqual(got, expected)
617
618 const before = simulateInput('version-type', 'strict')
619 spec = 'v0.14.0-rc2'
620 otpVersion = 'OTP-22'
621 expected = 'v0.14.0-rc2'
622 got = await setupBeam.getGleamVersion(spec, otpVersion)
623 assert.deepStrictEqual(got, expected)
624 simulateInput('version-type', before)
625 }
830 + spec = 'latest'
831 + expected = 'OTP-27.0-rc3'
832 + got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-22.04'])
833 + assert.deepStrictEqual(got, expected)
626 834
627 async function testRebar3Versions() {
628 let got
629 let expected
630 let spec
835 + spec = 'latest'
836 + expected = 'OTP-27.0'
837 + got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-24.04'])
838 + assert.deepStrictEqual(got, expected)
631 839
632 spec = '3.10.x'
633 expected = '3.10.0'
634 got = await setupBeam.getRebar3Version(spec)
635 assert.deepStrictEqual(got, expected)
840 + spec = 'latest'
841 + expected = '27.0-rc3'
842 + got = setupBeam.getVersionFromSpec(spec, matrix.otp.windows)
843 + assert.deepStrictEqual(got, expected)
636 844
637 spec = '3.11'
638 expected = '3.11.1'
639 got = await setupBeam.getRebar3Version(spec)
640 assert.deepStrictEqual(got, expected)
845 + spec = 'latest'
846 + expected = 'v1.16.2'
847 + got = setupBeam.getVersionFromSpec(spec, matrix.elixir)
848 + assert.deepStrictEqual(got, expected)
641 849
642 spec = '3.10'
643 expected = '3.10.0'
644 got = await setupBeam.getRebar3Version(spec)
645 assert.deepStrictEqual(got, expected)
646 }
850 + spec = 'latest'
851 + expected = 'v1.1.0'
852 + got = setupBeam.getVersionFromSpec(spec, matrix.gleam)
853 + assert.deepStrictEqual(got, expected)
647 854
648 async function testGetVersionFromSpec() {
649 let got
650 let expected
651 let spec
652 let before
653 const versions0 = [
654 '3.2.30.5',
655 '3.2.3.5',
656 '1',
657 '2',
658 '3.2.3.4.1',
659 '1.0.9',
660 '3.2.3.40.1',
661 '1.0.2',
662 '2.0',
663 '2.10',
664 '2.9',
665 '1.0',
666 '3.2.3.4.2',
667 '1.1.0',
668 '3.4.5.4',
669 '3.4.5.3',
670 '3.4.5.4.1',
671 '24.0-rc3',
672 '24.0-rc2',
673 '24.0',
674 '23.3.4',
675 '23.3.3',
676 '22.3.4.9.1',
677 '22.3.4.12.1',
678 '22.3.4.10.1',
679 '22.3.4.2',
680 'main',
681 'v11.11.0-rc.0-otp-23',
682 '22.3.4.2.1.0',
683 '12.1.2.2',
684 '12.1.2.4',
685 '12.1.2.0',
686 '12.1.2.3',
687 '12.1.2.3.0',
688 ]
689 let versions = {}
690 versions0.forEach((version) => {
691 versions[version] = version
855 + spec = 'latest'
856 + expected = '3.23.0'
857 + got = setupBeam.getVersionFromSpec(spec, matrix.rebar3)
858 + assert.deepStrictEqual(got, expected)
692 859 })
860 +})
693 861
694 spec = '1'
695 expected = '1.1.0'
696 got = setupBeam.getVersionFromSpec(spec, versions)
697 assert.deepStrictEqual(got, expected)
698
699 spec = '1.0'
700 expected = '1.0.9'
701 got = setupBeam.getVersionFromSpec(spec, versions)
702 assert.deepStrictEqual(got, expected)
703
704 before = simulateInput('version-type', 'strict')
705 spec = '1'
706 expected = '1'
707 got = setupBeam.getVersionFromSpec(spec, versions)
708 assert.deepStrictEqual(got, expected)
709 simulateInput('version-type', before)
710
711 before = simulateInput('version-type', 'strict')
712 spec = '1.0'
713 expected = '1.0'
714 got = setupBeam.getVersionFromSpec(spec, versions)
715 assert.deepStrictEqual(got, expected)
716 simulateInput('version-type', before)
717
718 spec = '2'
719 expected = '2.10'
720 got = setupBeam.getVersionFromSpec(spec, versions)
721 assert.deepStrictEqual(got, expected)
722
723 spec = '3'
724 expected = '3.4.5.4.1'
725 got = setupBeam.getVersionFromSpec(spec, versions)
726 assert.deepStrictEqual(got, expected)
727
728 spec = '3.2'
729 expected = '3.2.30.5'
730 got = setupBeam.getVersionFromSpec(spec, versions)
731 assert.deepStrictEqual(got, expected)
732
733 spec = '>20'
734 expected = '24.0'
735 got = setupBeam.getVersionFromSpec(spec, versions)
736 assert.deepStrictEqual(got, expected)
737
738 spec = '24.0'
739 expected = '24.0'
740 got = setupBeam.getVersionFromSpec(spec, versions)
741 assert.deepStrictEqual(got, expected)
742
743 before = simulateInput('version-type', 'strict')
744 spec = '24.0-rc3'
745 expected = '24.0-rc3'
746 got = setupBeam.getVersionFromSpec(spec, versions)
747 assert.deepStrictEqual(got, expected)
748 simulateInput('version-type', before)
749
750 spec = '24.0-rc2'
751 expected = '24.0-rc2'
752 got = setupBeam.getVersionFromSpec(spec, versions)
753 assert.deepStrictEqual(got, expected)
754
755 spec = '22.3'
756 expected = '22.3.4.12.1'
757 got = setupBeam.getVersionFromSpec(spec, versions)
758 assert.deepStrictEqual(got, expected)
759
760 spec = '23.3.3'
761 expected = '23.3.3'
762 got = setupBeam.getVersionFromSpec(spec, versions)
763 assert.deepStrictEqual(got, expected)
764
765 spec = '24'
766 expected = '24.0'
767 got = setupBeam.getVersionFromSpec(spec, versions)
768 assert.deepStrictEqual(got, expected)
769
770 spec = '23.3'
771 expected = '23.3.4'
772 got = setupBeam.getVersionFromSpec(spec, versions)
773 assert.deepStrictEqual(got, expected)
774
775 before = simulateInput('version-type', 'strict')
776 spec = 'main'
777 expected = 'main'
778 got = setupBeam.getVersionFromSpec(spec, versions)
779 assert.deepStrictEqual(got, expected)
780 simulateInput('version-type', before)
781
782 before = simulateInput('version-type', 'strict')
783 spec = '22.3.4.2'
784 expected = '22.3.4.2'
785 got = setupBeam.getVersionFromSpec(spec, versions)
786 assert.deepStrictEqual(got, expected)
787 simulateInput('version-type', before)
788
789 spec = '22.3.4.2'
790 expected = '22.3.4.2.1.0'
791 got = setupBeam.getVersionFromSpec(spec, versions)
792 assert.deepStrictEqual(got, expected)
793
794 spec = '22.3.4.2.1'
795 expected = '22.3.4.2.1.0'
796 got = setupBeam.getVersionFromSpec(spec, versions)
797 assert.deepStrictEqual(got, expected)
798
799 spec = '22.3.4.2.1.0'
800 expected = '22.3.4.2.1.0'
801 got = setupBeam.getVersionFromSpec(spec, versions)
802 assert.deepStrictEqual(got, expected)
803
804 spec = '12.1.2.3'
805 expected = '12.1.2.3.0'
806 got = setupBeam.getVersionFromSpec(spec, versions)
807 assert.deepStrictEqual(got, expected)
808
809 spec = '22.3.4.2.1.0.1'
810 expected = null
811 got = setupBeam.getVersionFromSpec(spec, versions)
812 assert.deepStrictEqual(got, expected)
813
814 before = simulateInput('version-type', 'strict')
815 spec = '22.3.4.3'
816 expected = null
817 got = setupBeam.getVersionFromSpec(spec, versions)
818 assert.deepStrictEqual(got, expected)
819 simulateInput('version-type', before)
820
821 spec = 'latest'
822 expected = '24.0'
823 got = setupBeam.getVersionFromSpec(spec, versions)
824 assert.deepStrictEqual(got, expected)
825
826 versions = {
827 '27.0.0-rc3': '27.0.0-rc3',
828 '27.0.0-rc2': '27.0.0-rc2',
829 }
830 spec = 'latest'
831 expected = '27.0.0-rc3'
832 got = setupBeam.getVersionFromSpec(spec, versions)
833 assert.deepStrictEqual(got, expected)
834
835 versions = {
836 '27.0.0-rc3': '27.0.0-rc3',
837 '27.0.0-rc2': '27.0.0-rc2',
838 '27.0.0': '27.0.0',
839 }
840 spec = 'latest'
841 expected = '27.0.0'
842 got = setupBeam.getVersionFromSpec(spec, versions)
843 assert.deepStrictEqual(got, expected)
844
845 versions = { '25.3.2.8': '25.3.2.8', '25.3.2.12': '25.3.2.12' }
846 spec = 'latest'
847 expected = '25.3.2.12'
848 got = setupBeam.getVersionFromSpec(spec, versions)
849 assert.deepStrictEqual(got, expected)
850
851 spec = 'latest'
852 expected = 'OTP-26.2.1'
853 got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-18.04'])
854 assert.deepStrictEqual(got, expected)
855
856 spec = 'latest'
857 expected = 'OTP-27.0-rc3'
858 got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-20.04'])
859 assert.deepStrictEqual(got, expected)
860
861 spec = 'latest'
862 expected = 'OTP-27.0-rc3'
863 got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-22.04'])
864 assert.deepStrictEqual(got, expected)
865
866 spec = 'latest'
867 expected = 'OTP-27.0'
868 got = setupBeam.getVersionFromSpec(spec, matrix.otp['ubuntu-24.04'])
869 assert.deepStrictEqual(got, expected)
870
871 spec = 'latest'
872 expected = '27.0-rc3'
873 got = setupBeam.getVersionFromSpec(spec, matrix.otp.windows)
874 assert.deepStrictEqual(got, expected)
875
876 spec = 'latest'
877 expected = 'v1.16.2'
878 got = setupBeam.getVersionFromSpec(spec, matrix.elixir)
879 assert.deepStrictEqual(got, expected)
880
881 spec = 'latest'
882 expected = 'v1.1.0'
883 got = setupBeam.getVersionFromSpec(spec, matrix.gleam)
884 assert.deepStrictEqual(got, expected)
885
886 spec = 'latest'
887 expected = '3.23.0'
888 got = setupBeam.getVersionFromSpec(spec, matrix.rebar3)
889 assert.deepStrictEqual(got, expected)
890 }
891
892 async function testParseVersionFile() {
862 +describe('version file', () => {
893 863 const otpVersion = unsimulateInput('otp-version')
894 864 const elixirVersion = unsimulateInput('elixir-version')
895 865 const gleamVersion = unsimulateInput('gleam-version')
896 866 const rebar3Version = unsimulateInput('rebar3-version')
897 867
898 const erlang = '27'
899 const elixir = '1.17.0'
900 const gleam = '0.23.0'
901 const rebar3 = '3.24.0'
902 const toolVersions = `# a comment
868 + it('is parsed correctly', async () => {
869 + const erlang = '27'
870 + const elixir = '1.17.0'
871 + const gleam = '0.23.0'
872 + const rebar3 = '3.24.0'
873 + const toolVersions = `# a comment
903 874 erlang ref:v${erlang}# comment, no space, and ref:v
904 875 elixir ref:${elixir} # comment, with space and ref:
905 876 not-gleam 0.23 # not picked up
906 877 gleam ${gleam} \nrebar ${rebar3}`
907 const filename = 'test/.tool-versions'
908 fs.writeFileSync(filename, toolVersions)
909 process.env.GITHUB_WORKSPACE = ''
910 const appVersions = setupBeam.parseVersionFile(filename)
911 assert.strictEqual(appVersions.get('erlang'), erlang)
912 assert.strictEqual(appVersions.get('elixir'), elixir)
913
914 const absoluteFilename = path.join(os.tmpdir(), '.tool-versions')
915 fs.writeFileSync(absoluteFilename, toolVersions)
916
917 process.env.GITHUB_WORKSPACE = process.cwd()
918 const absoluteAppVersions = setupBeam.parseVersionFile(absoluteFilename)
919 assert.strictEqual(absoluteAppVersions.get('erlang'), erlang)
920 assert.strictEqual(absoluteAppVersions.get('elixir'), elixir)
921
922 assert.ok(async () => {
923 await setupBeam.install('otp', { toolVersion: erlang })
924 })
925 assert.ok(async () => {
926 await setupBeam.install('elixir', { toolVersion: elixir })
927 })
928 assert.ok(async () => {
929 await setupBeam.install('gleam', { toolVersion: gleam })
930 })
931 assert.ok(async () => {
932 await setupBeam.install('rebar3', { toolVersion: rebar3 })
878 + const filename = 'test/.tool-versions'
879 + fs.writeFileSync(filename, toolVersions)
880 + process.env.GITHUB_WORKSPACE = ''
881 + const appVersions = setupBeam.parseVersionFile(filename)
882 + assert.strictEqual(appVersions.get('erlang'), erlang)
883 + assert.strictEqual(appVersions.get('elixir'), elixir)
884 +
885 + const absoluteFilename = path.join(os.tmpdir(), '.tool-versions')
886 + fs.writeFileSync(absoluteFilename, toolVersions)
887 +
888 + process.env.GITHUB_WORKSPACE = process.cwd()
889 + const absoluteAppVersions = setupBeam.parseVersionFile(absoluteFilename)
890 + assert.strictEqual(absoluteAppVersions.get('erlang'), erlang)
891 + assert.strictEqual(absoluteAppVersions.get('elixir'), elixir)
892 +
893 + assert.ok(async () => {
894 + await setupBeam.install('otp', { toolVersion: erlang })
895 + })
896 + assert.ok(async () => {
897 + await setupBeam.install('elixir', { toolVersion: elixir })
898 + })
899 + assert.ok(async () => {
900 + await setupBeam.install('gleam', { toolVersion: gleam })
901 + })
902 + assert.ok(async () => {
903 + await setupBeam.install('rebar3', { toolVersion: rebar3 })
904 + })
933 905 })
934 906
935 907 simulateInput('otp-version', otpVersion)
936 908 simulateInput('elixir-version', elixirVersion)
937 909 simulateInput('gleam-version', gleamVersion)
938 910 simulateInput('rebar3-version', rebar3Version)
939 }
940
941 async function testGetRetry() {
942 let attempt = 0
943 const server = http.createServer((req, res) => {
944 attempt++
945 if (attempt == 2) {
946 res.write('correct!')
947 res.end()
911 +})
912 +
913 +describe('.get(_)', () => {
914 + it('retries as expected', async () => {
915 + let attempt = 0
916 + const server = http.createServer((req, res) => {
917 + attempt++
918 + if (attempt == 2) {
919 + res.write('correct!')
920 + res.end()
921 + }
922 + })
923 +
924 + try {
925 + server.listen(0)
926 + const port = server.address().port
927 +
928 + const response = await setupBeam.get(`http://localhost:${port}`, [])
929 + assert.equal(response, 'correct!')
930 + assert.equal(attempt, 2)
931 + } finally {
932 + server.close()
948 933 }
949 934 })
935 +})
936 +
937 +describe("Elixir Mix matcher's", () => {
938 + it('errors are properly matched', async () => {
939 + const [matcher] = problemMatcher.find(
940 + ({ owner }) => owner === 'elixir-mixCompileError',
941 + ).pattern
942 +
943 + const output = '** (CompileError) lib/test.ex:16: undefined function err/0'
944 + const [message, , file, line] = output.match(matcher.regexp)
945 + assert.equal(file, 'lib/test.ex')
946 + assert.equal(line, '16')
947 + assert.equal(message, output)
948 + })
950 949
951 try {
952 server.listen(0)
953 const port = server.address().port
954
955 const response = await setupBeam.get(`http://localhost:${port}`, [])
956 assert.equal(response, 'correct!')
957 assert.equal(attempt, 2)
958 } finally {
959 server.close()
960 }
961 }
962
963 async function testElixirMixCompileError() {
964 const [matcher] = problemMatcher.find(
965 ({ owner }) => owner === 'elixir-mixCompileError',
966 ).pattern
967
968 const output = '** (CompileError) lib/test.ex:16: undefined function err/0'
969 const [message, , file, line] = output.match(matcher.regexp)
970 assert.equal(file, 'lib/test.ex')
971 assert.equal(line, '16')
972 assert.equal(message, output)
973 }
974
975 async function testElixirMixCompileWarning() {
976 const [messagePattern, filePattern] = problemMatcher.find(
977 ({ owner }) => owner === 'elixir-mixCompileWarning',
978 ).pattern
950 + it('warnings are properly matched', async () => {
951 + const [messagePattern, filePattern] = problemMatcher.find(
952 + ({ owner }) => owner === 'elixir-mixCompileWarning',
953 + ).pattern
979 954
980 const firstOutput =
981 'warning: variable "err" does not exist and is being expanded to "err()"'
982 const secondOutput = ' lib/test.ex:16: Test.hello/0'
955 + const firstOutput =
956 + 'warning: variable "err" does not exist and is being expanded to "err()"'
957 + const secondOutput = ' lib/test.ex:16: Test.hello/0'
983 958
984 const [, message] = firstOutput.match(messagePattern.regexp)
985 assert.equal(
986 message,
987 'variable "err" does not exist and is being expanded to "err()"',
988 )
959 + const [, message] = firstOutput.match(messagePattern.regexp)
960 + assert.equal(
961 + message,
962 + 'variable "err" does not exist and is being expanded to "err()"',
963 + )
989 964
990 const [, file, line] = secondOutput.match(filePattern.regexp)
991 assert.equal(file, 'lib/test.ex')
992 assert.equal(line, '16')
993 }
965 + const [, file, line] = secondOutput.match(filePattern.regexp)
966 + assert.equal(file, 'lib/test.ex')
967 + assert.equal(line, '16')
968 + })
994 969
995 async function testElixirMixTestFailure() {
996 const [messagePattern, filePattern] = problemMatcher.find(
997 ({ owner }) => owner === 'elixir-mixTestFailure',
998 ).pattern
970 + it('failures are properly matched', async () => {
971 + const [messagePattern, filePattern] = problemMatcher.find(
972 + ({ owner }) => owner === 'elixir-mixTestFailure',
973 + ).pattern
999 974
1000 const firstOutput = '1) test throws (TestTest)'
1001 const secondOutput = ' test/test_test.exs:9'
975 + const firstOutput = '1) test throws (TestTest)'
976 + const secondOutput = ' test/test_test.exs:9'
1002 977
1003 const [, message] = firstOutput.match(messagePattern.regexp)
1004 assert.equal(message, 'test throws (TestTest)')
978 + const [, message] = firstOutput.match(messagePattern.regexp)
979 + assert.equal(message, 'test throws (TestTest)')
1005 980
1006 const [, file, line] = secondOutput.match(filePattern.regexp)
1007 assert.equal(file, 'test/test_test.exs')
1008 assert.equal(line, '9')
1009 }
981 + const [, file, line] = secondOutput.match(filePattern.regexp)
982 + assert.equal(file, 'test/test_test.exs')
983 + assert.equal(line, '9')
984 + })
1010 985
1011 async function testElixirCredoOutputDefault() {
1012 const [messagePattern, filePattern] = problemMatcher.find(
1013 ({ owner }) => owner === 'elixir-credoOutputDefault',
1014 ).pattern
986 + it('Credo output is properly matched', async () => {
987 + const [messagePattern, filePattern] = problemMatcher.find(
988 + ({ owner }) => owner === 'elixir-credoOutputDefault',
989 + ).pattern
1015 990
1016 const firstOutput = '┃ [F] → Function is too complex (CC is 29, max is 9).'
1017 const secondOutput = '┃ lib/test.ex:15:7 #(Test.hello)'
991 + const firstOutput = '┃ [F] → Function is too complex (CC is 29, max is 9).'
992 + const secondOutput = '┃ lib/test.ex:15:7 #(Test.hello)'
1018 993
1019 const [, message] = firstOutput.match(messagePattern.regexp)
1020 assert.equal(message, 'Function is too complex (CC is 29, max is 9).')
994 + const [, message] = firstOutput.match(messagePattern.regexp)
995 + assert.equal(message, 'Function is too complex (CC is 29, max is 9).')
1021 996
1022 const [, file, line, column] = secondOutput.match(filePattern.regexp)
1023 assert.equal(file, 'lib/test.ex')
1024 assert.equal(line, '15')
1025 assert.equal(column, '7')
1026 }
997 + const [, file, line, column] = secondOutput.match(filePattern.regexp)
998 + assert.equal(file, 'lib/test.ex')
999 + assert.equal(line, '15')
1000 + assert.equal(column, '7')
1001 + })
1002 +})
1027 1003
1028 1004 function unsimulateInput(key) {
1029 1005 return simulateInput(key, '')
@@ -1047,10 +1023,3 @@ function simulateInput(key, value0, opts) {
1047 1023 function input(key) {
1048 1024 return `INPUT_${key.replace(/ /g, '_').toUpperCase()}`
1049 1025 }
1050
1051 all()
1052 .then(() => process.exit(0))
1053 .catch((err) => {
1054 core.error(err)
1055 process.exit(1)
1056 })

Parents: 4b97eea