aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/tests/helpers
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-07-31 14:34:36 +0200
committerChocobozzz <me@florianbigard.com>2023-08-11 15:02:33 +0200
commit3a4992633ee62d5edfbb484d9c6bcb3cf158489d (patch)
treee4510b39bdac9c318fdb4b47018d08f15368b8f0 /server/tests/helpers
parent04d1da5621d25d59bd5fa1543b725c497bf5d9a8 (diff)
downloadPeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.gz
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.zst
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.zip
Migrate server to ESM
Sorry for the very big commit that may lead to git log issues and merge conflicts, but it's a major step forward: * Server can be faster at startup because imports() are async and we can easily lazy import big modules * Angular doesn't seem to support ES import (with .js extension), so we had to correctly organize peertube into a monorepo: * Use yarn workspace feature * Use typescript reference projects for dependencies * Shared projects have been moved into "packages", each one is now a node module (with a dedicated package.json/tsconfig.json) * server/tools have been moved into apps/ and is now a dedicated app bundled and published on NPM so users don't have to build peertube cli tools manually * server/tests have been moved into packages/ so we don't compile them every time we want to run the server * Use isolatedModule option: * Had to move from const enum to const (https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums) * Had to explictely specify "type" imports when used in decorators * Prefer tsx (that uses esbuild under the hood) instead of ts-node to load typescript files (tests with mocha or scripts): * To reduce test complexity as esbuild doesn't support decorator metadata, we only test server files that do not import server models * We still build tests files into js files for a faster CI * Remove unmaintained peertube CLI import script * Removed some barrels to speed up execution (less imports)
Diffstat (limited to 'server/tests/helpers')
-rw-r--r--server/tests/helpers/comment-model.ts24
-rw-r--r--server/tests/helpers/core-utils.ts150
-rw-r--r--server/tests/helpers/crypto.ts33
-rw-r--r--server/tests/helpers/dns.ts16
-rw-r--r--server/tests/helpers/image.ts96
-rw-r--r--server/tests/helpers/index.ts9
-rw-r--r--server/tests/helpers/markdown.ts39
-rw-r--r--server/tests/helpers/request.ts62
-rw-r--r--server/tests/helpers/validator.ts32
-rw-r--r--server/tests/helpers/version.ts36
10 files changed, 0 insertions, 497 deletions
diff --git a/server/tests/helpers/comment-model.ts b/server/tests/helpers/comment-model.ts
deleted file mode 100644
index e39cae442..000000000
--- a/server/tests/helpers/comment-model.ts
+++ /dev/null
@@ -1,24 +0,0 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { VideoCommentModel } from '../../models/video/video-comment'
5
6class CommentMock {
7 text: string
8
9 extractMentions = VideoCommentModel.prototype.extractMentions
10
11 isOwned = () => true
12}
13
14describe('Comment model', function () {
15 it('Should correctly extract mentions', async function () {
16 const comment = new CommentMock()
17
18 comment.text = '@florian @jean@localhost:9000 @flo @another@localhost:9000 @flo2@jean.com hello ' +
19 'email@localhost:9000 coucou.com no? @chocobozzz @chocobozzz @end'
20 const result = comment.extractMentions().sort((a, b) => a.localeCompare(b))
21
22 expect(result).to.deep.equal([ 'another', 'chocobozzz', 'end', 'flo', 'florian', 'jean' ])
23 })
24})
diff --git a/server/tests/helpers/core-utils.ts b/server/tests/helpers/core-utils.ts
deleted file mode 100644
index cd2f07e4a..000000000
--- a/server/tests/helpers/core-utils.ts
+++ /dev/null
@@ -1,150 +0,0 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { snakeCase } from 'lodash'
5import validator from 'validator'
6import { getAverageTheoreticalBitrate, getMaxTheoreticalBitrate } from '@shared/core-utils'
7import { VideoResolution } from '@shared/models'
8import { objectConverter, parseBytes, parseDurationToMs } from '../../helpers/core-utils'
9
10describe('Parse Bytes', function () {
11
12 it('Should pass on valid value', async function () {
13 // just return it
14 expect(parseBytes(-1024)).to.equal(-1024)
15 expect(parseBytes(1024)).to.equal(1024)
16 expect(parseBytes(1048576)).to.equal(1048576)
17 expect(parseBytes('1024')).to.equal(1024)
18 expect(parseBytes('1048576')).to.equal(1048576)
19
20 // sizes
21 expect(parseBytes('1B')).to.equal(1024)
22 expect(parseBytes('1MB')).to.equal(1048576)
23 expect(parseBytes('1GB')).to.equal(1073741824)
24 expect(parseBytes('1TB')).to.equal(1099511627776)
25
26 expect(parseBytes('5GB')).to.equal(5368709120)
27 expect(parseBytes('5TB')).to.equal(5497558138880)
28
29 expect(parseBytes('1024B')).to.equal(1048576)
30 expect(parseBytes('1024MB')).to.equal(1073741824)
31 expect(parseBytes('1024GB')).to.equal(1099511627776)
32 expect(parseBytes('1024TB')).to.equal(1125899906842624)
33
34 // with whitespace
35 expect(parseBytes('1 GB')).to.equal(1073741824)
36 expect(parseBytes('1\tGB')).to.equal(1073741824)
37
38 // sum value
39 expect(parseBytes('1TB 1024MB')).to.equal(1100585369600)
40 expect(parseBytes('4GB 1024MB')).to.equal(5368709120)
41 expect(parseBytes('4TB 1024GB')).to.equal(5497558138880)
42 expect(parseBytes('4TB 1024GB 0MB')).to.equal(5497558138880)
43 expect(parseBytes('1024TB 1024GB 1024MB')).to.equal(1127000492212224)
44 })
45
46 it('Should be invalid when given invalid value', async function () {
47 expect(parseBytes('6GB 1GB')).to.equal(6)
48 })
49})
50
51describe('Parse duration', function () {
52
53 it('Should pass when given valid value', async function () {
54 expect(parseDurationToMs(35)).to.equal(35)
55 expect(parseDurationToMs(-35)).to.equal(-35)
56 expect(parseDurationToMs('35 seconds')).to.equal(35 * 1000)
57 expect(parseDurationToMs('1 minute')).to.equal(60 * 1000)
58 expect(parseDurationToMs('1 hour')).to.equal(3600 * 1000)
59 expect(parseDurationToMs('35 hours')).to.equal(3600 * 35 * 1000)
60 })
61
62 it('Should be invalid when given invalid value', async function () {
63 expect(parseBytes('35m 5s')).to.equal(35)
64 })
65})
66
67describe('Object', function () {
68
69 it('Should convert an object', async function () {
70 function keyConverter (k: string) {
71 return snakeCase(k)
72 }
73
74 function valueConverter (v: any) {
75 if (validator.isNumeric(v + '')) return parseInt('' + v, 10)
76
77 return v
78 }
79
80 const obj = {
81 mySuperKey: 'hello',
82 mySuper2Key: '45',
83 mySuper3Key: {
84 mySuperSubKey: '15',
85 mySuperSub2Key: 'hello',
86 mySuperSub3Key: [ '1', 'hello', 2 ],
87 mySuperSub4Key: 4
88 },
89 mySuper4Key: 45,
90 toto: {
91 super_key: '15',
92 superKey2: 'hello'
93 },
94 super_key: {
95 superKey4: 15
96 }
97 }
98
99 const res = objectConverter(obj, keyConverter, valueConverter)
100
101 expect(res.my_super_key).to.equal('hello')
102 expect(res.my_super_2_key).to.equal(45)
103 expect(res.my_super_3_key.my_super_sub_key).to.equal(15)
104 expect(res.my_super_3_key.my_super_sub_2_key).to.equal('hello')
105 expect(res.my_super_3_key.my_super_sub_3_key).to.deep.equal([ 1, 'hello', 2 ])
106 expect(res.my_super_3_key.my_super_sub_4_key).to.equal(4)
107 expect(res.toto.super_key).to.equal(15)
108 expect(res.toto.super_key_2).to.equal('hello')
109 expect(res.super_key.super_key_4).to.equal(15)
110
111 // Immutable
112 expect(res.mySuperKey).to.be.undefined
113 expect(obj['my_super_key']).to.be.undefined
114 })
115})
116
117describe('Bitrate', function () {
118
119 it('Should get appropriate max bitrate', function () {
120 const tests = [
121 { resolution: VideoResolution.H_144P, ratio: 16 / 9, fps: 24, min: 200, max: 400 },
122 { resolution: VideoResolution.H_240P, ratio: 16 / 9, fps: 24, min: 600, max: 800 },
123 { resolution: VideoResolution.H_360P, ratio: 16 / 9, fps: 24, min: 1200, max: 1600 },
124 { resolution: VideoResolution.H_480P, ratio: 16 / 9, fps: 24, min: 2000, max: 2300 },
125 { resolution: VideoResolution.H_720P, ratio: 16 / 9, fps: 24, min: 4000, max: 4400 },
126 { resolution: VideoResolution.H_1080P, ratio: 16 / 9, fps: 24, min: 8000, max: 10000 },
127 { resolution: VideoResolution.H_4K, ratio: 16 / 9, fps: 24, min: 25000, max: 30000 }
128 ]
129
130 for (const test of tests) {
131 expect(getMaxTheoreticalBitrate(test)).to.be.above(test.min * 1000).and.below(test.max * 1000)
132 }
133 })
134
135 it('Should get appropriate average bitrate', function () {
136 const tests = [
137 { resolution: VideoResolution.H_144P, ratio: 16 / 9, fps: 24, min: 50, max: 300 },
138 { resolution: VideoResolution.H_240P, ratio: 16 / 9, fps: 24, min: 350, max: 450 },
139 { resolution: VideoResolution.H_360P, ratio: 16 / 9, fps: 24, min: 700, max: 900 },
140 { resolution: VideoResolution.H_480P, ratio: 16 / 9, fps: 24, min: 1100, max: 1300 },
141 { resolution: VideoResolution.H_720P, ratio: 16 / 9, fps: 24, min: 2300, max: 2500 },
142 { resolution: VideoResolution.H_1080P, ratio: 16 / 9, fps: 24, min: 4700, max: 5000 },
143 { resolution: VideoResolution.H_4K, ratio: 16 / 9, fps: 24, min: 15000, max: 17000 }
144 ]
145
146 for (const test of tests) {
147 expect(getAverageTheoreticalBitrate(test)).to.be.above(test.min * 1000).and.below(test.max * 1000)
148 }
149 })
150})
diff --git a/server/tests/helpers/crypto.ts b/server/tests/helpers/crypto.ts
deleted file mode 100644
index b508c715b..000000000
--- a/server/tests/helpers/crypto.ts
+++ /dev/null
@@ -1,33 +0,0 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { decrypt, encrypt } from '@server/helpers/peertube-crypto'
5
6describe('Encrypt/Descrypt', function () {
7
8 it('Should encrypt and decrypt the string', async function () {
9 const secret = 'my_secret'
10 const str = 'my super string'
11
12 const encrypted = await encrypt(str, secret)
13 const decrypted = await decrypt(encrypted, secret)
14
15 expect(str).to.equal(decrypted)
16 })
17
18 it('Should not decrypt without the same secret', async function () {
19 const str = 'my super string'
20
21 const encrypted = await encrypt(str, 'my_secret')
22
23 let error = false
24
25 try {
26 await decrypt(encrypted, 'my_sicret')
27 } catch (err) {
28 error = true
29 }
30
31 expect(error).to.be.true
32 })
33})
diff --git a/server/tests/helpers/dns.ts b/server/tests/helpers/dns.ts
deleted file mode 100644
index 49b506e7b..000000000
--- a/server/tests/helpers/dns.ts
+++ /dev/null
@@ -1,16 +0,0 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { isResolvingToUnicastOnly } from '@server/helpers/dns'
5
6describe('DNS helpers', function () {
7
8 it('Should correctly check unicast IPs', async function () {
9 expect(await isResolvingToUnicastOnly('cpy.re')).to.be.true
10 expect(await isResolvingToUnicastOnly('framasoft.org')).to.be.true
11 expect(await isResolvingToUnicastOnly('8.8.8.8')).to.be.true
12
13 expect(await isResolvingToUnicastOnly('127.0.0.1')).to.be.false
14 expect(await isResolvingToUnicastOnly('127.0.0.1.cpy.re')).to.be.false
15 })
16})
diff --git a/server/tests/helpers/image.ts b/server/tests/helpers/image.ts
deleted file mode 100644
index 6021ffc48..000000000
--- a/server/tests/helpers/image.ts
+++ /dev/null
@@ -1,96 +0,0 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { readFile, remove } from 'fs-extra'
5import { join } from 'path'
6import { execPromise } from '@server/helpers/core-utils'
7import { buildAbsoluteFixturePath, root } from '@shared/core-utils'
8import { processImage } from '../../../server/helpers/image-utils'
9
10async function checkBuffers (path1: string, path2: string, equals: boolean) {
11 const [ buf1, buf2 ] = await Promise.all([
12 readFile(path1),
13 readFile(path2)
14 ])
15
16 if (equals) {
17 expect(buf1.equals(buf2)).to.be.true
18 } else {
19 expect(buf1.equals(buf2)).to.be.false
20 }
21}
22
23async function hasTitleExif (path: string) {
24 const result = JSON.parse(await execPromise(`exiftool -json ${path}`))
25
26 return result[0]?.Title === 'should be removed'
27}
28
29describe('Image helpers', function () {
30 const imageDestDir = join(root(), 'test-images')
31
32 const imageDestJPG = join(imageDestDir, 'test.jpg')
33 const imageDestPNG = join(imageDestDir, 'test.png')
34
35 const thumbnailSize = { width: 280, height: 157 }
36
37 it('Should skip processing if the source image is okay', async function () {
38 const input = buildAbsoluteFixturePath('custom-thumbnail.jpg')
39 await processImage({ path: input, destination: imageDestJPG, newSize: thumbnailSize, keepOriginal: true })
40
41 await checkBuffers(input, imageDestJPG, true)
42 })
43
44 it('Should not skip processing if the source image does not have the appropriate extension', async function () {
45 const input = buildAbsoluteFixturePath('custom-thumbnail.png')
46 await processImage({ path: input, destination: imageDestJPG, newSize: thumbnailSize, keepOriginal: true })
47
48 await checkBuffers(input, imageDestJPG, false)
49 })
50
51 it('Should not skip processing if the source image does not have the appropriate size', async function () {
52 const input = buildAbsoluteFixturePath('custom-preview.jpg')
53 await processImage({ path: input, destination: imageDestJPG, newSize: thumbnailSize, keepOriginal: true })
54
55 await checkBuffers(input, imageDestJPG, false)
56 })
57
58 it('Should not skip processing if the source image does not have the appropriate size', async function () {
59 const input = buildAbsoluteFixturePath('custom-thumbnail-big.jpg')
60 await processImage({ path: input, destination: imageDestJPG, newSize: thumbnailSize, keepOriginal: true })
61
62 await checkBuffers(input, imageDestJPG, false)
63 })
64
65 it('Should strip exif for a jpg file that can not be copied', async function () {
66 const input = buildAbsoluteFixturePath('exif.jpg')
67 expect(await hasTitleExif(input)).to.be.true
68
69 await processImage({ path: input, destination: imageDestJPG, newSize: { width: 100, height: 100 }, keepOriginal: true })
70 await checkBuffers(input, imageDestJPG, false)
71
72 expect(await hasTitleExif(imageDestJPG)).to.be.false
73 })
74
75 it('Should strip exif for a jpg file that could be copied', async function () {
76 const input = buildAbsoluteFixturePath('exif.jpg')
77 expect(await hasTitleExif(input)).to.be.true
78
79 await processImage({ path: input, destination: imageDestJPG, newSize: thumbnailSize, keepOriginal: true })
80 await checkBuffers(input, imageDestJPG, false)
81
82 expect(await hasTitleExif(imageDestJPG)).to.be.false
83 })
84
85 it('Should strip exif for png', async function () {
86 const input = buildAbsoluteFixturePath('exif.png')
87 expect(await hasTitleExif(input)).to.be.true
88
89 await processImage({ path: input, destination: imageDestPNG, newSize: thumbnailSize, keepOriginal: true })
90 expect(await hasTitleExif(imageDestPNG)).to.be.false
91 })
92
93 after(async function () {
94 await remove(imageDestDir)
95 })
96})
diff --git a/server/tests/helpers/index.ts b/server/tests/helpers/index.ts
deleted file mode 100644
index 073ae6455..000000000
--- a/server/tests/helpers/index.ts
+++ /dev/null
@@ -1,9 +0,0 @@
1import './comment-model'
2import './core-utils'
3import './crypto'
4import './dns'
5import './image'
6import './markdown'
7import './request'
8import './validator'
9import './version'
diff --git a/server/tests/helpers/markdown.ts b/server/tests/helpers/markdown.ts
deleted file mode 100644
index 6fab31d6f..000000000
--- a/server/tests/helpers/markdown.ts
+++ /dev/null
@@ -1,39 +0,0 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { mdToOneLinePlainText } from '@server/helpers/markdown'
4import { expect } from 'chai'
5
6describe('Markdown helpers', function () {
7
8 describe('Plain text', function () {
9
10 it('Should convert a list to plain text', function () {
11 const result = mdToOneLinePlainText(`* list 1
12* list 2
13* list 3`)
14
15 expect(result).to.equal('list 1, list 2, list 3')
16 })
17
18 it('Should convert a list with indentation to plain text', function () {
19 const result = mdToOneLinePlainText(`Hello:
20 * list 1
21 * list 2
22 * list 3`)
23
24 expect(result).to.equal('Hello: list 1, list 2, list 3')
25 })
26
27 it('Should convert HTML to plain text', function () {
28 const result = mdToOneLinePlainText(`**Hello** <strong>coucou</strong>`)
29
30 expect(result).to.equal('Hello coucou')
31 })
32
33 it('Should convert tags to plain text', function () {
34 const result = mdToOneLinePlainText(`#déconversion\n#newage\n#histoire`)
35
36 expect(result).to.equal('#déconversion #newage #histoire')
37 })
38 })
39})
diff --git a/server/tests/helpers/request.ts b/server/tests/helpers/request.ts
deleted file mode 100644
index 363237df5..000000000
--- a/server/tests/helpers/request.ts
+++ /dev/null
@@ -1,62 +0,0 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { pathExists, remove } from 'fs-extra'
5import { join } from 'path'
6import { root, wait } from '@shared/core-utils'
7import { doRequest, doRequestAndSaveToFile } from '../../helpers/requests'
8import { FIXTURE_URLS, Mock429 } from '../shared'
9
10describe('Request helpers', function () {
11 const destPath1 = join(root(), 'test-output-1.txt')
12 const destPath2 = join(root(), 'test-output-2.txt')
13
14 it('Should throw an error when the bytes limit is exceeded for request', async function () {
15 try {
16 await doRequest(FIXTURE_URLS.file4K, { bodyKBLimit: 3 })
17 } catch {
18 return
19 }
20
21 throw new Error('No error thrown by do request')
22 })
23
24 it('Should throw an error when the bytes limit is exceeded for request and save file', async function () {
25 try {
26 await doRequestAndSaveToFile(FIXTURE_URLS.file4K, destPath1, { bodyKBLimit: 3 })
27 } catch {
28
29 await wait(500)
30 expect(await pathExists(destPath1)).to.be.false
31 return
32 }
33
34 throw new Error('No error thrown by do request and save to file')
35 })
36
37 it('Should correctly retry on 429 error', async function () {
38 this.timeout(25000)
39
40 const mock = new Mock429()
41 const port = await mock.initialize()
42
43 const before = new Date().getTime()
44 await doRequest('http://127.0.0.1:' + port)
45
46 expect(new Date().getTime() - before).to.be.greaterThan(2000)
47
48 await mock.terminate()
49 })
50
51 it('Should succeed if the file is below the limit', async function () {
52 await doRequest(FIXTURE_URLS.file4K, { bodyKBLimit: 5 })
53 await doRequestAndSaveToFile(FIXTURE_URLS.file4K, destPath2, { bodyKBLimit: 5 })
54
55 expect(await pathExists(destPath2)).to.be.true
56 })
57
58 after(async function () {
59 await remove(destPath1)
60 await remove(destPath2)
61 })
62})
diff --git a/server/tests/helpers/validator.ts b/server/tests/helpers/validator.ts
deleted file mode 100644
index f40a3aaae..000000000
--- a/server/tests/helpers/validator.ts
+++ /dev/null
@@ -1,32 +0,0 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { isPluginStableOrUnstableVersionValid, isPluginStableVersionValid } from '@server/helpers/custom-validators/plugins'
5
6describe('Validators', function () {
7
8 it('Should correctly check stable plugin versions', async function () {
9 expect(isPluginStableVersionValid('3.4.0')).to.be.true
10 expect(isPluginStableVersionValid('0.4.0')).to.be.true
11 expect(isPluginStableVersionValid('0.1.0')).to.be.true
12
13 expect(isPluginStableVersionValid('0.1.0-beta-1')).to.be.false
14 expect(isPluginStableVersionValid('hello')).to.be.false
15 expect(isPluginStableVersionValid('0.x.a')).to.be.false
16 })
17
18 it('Should correctly check unstable plugin versions', async function () {
19 expect(isPluginStableOrUnstableVersionValid('3.4.0')).to.be.true
20 expect(isPluginStableOrUnstableVersionValid('0.4.0')).to.be.true
21 expect(isPluginStableOrUnstableVersionValid('0.1.0')).to.be.true
22
23 expect(isPluginStableOrUnstableVersionValid('0.1.0-beta.1')).to.be.true
24 expect(isPluginStableOrUnstableVersionValid('0.1.0-alpha.45')).to.be.true
25 expect(isPluginStableOrUnstableVersionValid('0.1.0-rc.45')).to.be.true
26
27 expect(isPluginStableOrUnstableVersionValid('hello')).to.be.false
28 expect(isPluginStableOrUnstableVersionValid('0.x.a')).to.be.false
29 expect(isPluginStableOrUnstableVersionValid('0.1.0-rc-45')).to.be.false
30 expect(isPluginStableOrUnstableVersionValid('0.1.0-rc.45d')).to.be.false
31 })
32})
diff --git a/server/tests/helpers/version.ts b/server/tests/helpers/version.ts
deleted file mode 100644
index 2a90efba3..000000000
--- a/server/tests/helpers/version.ts
+++ /dev/null
@@ -1,36 +0,0 @@
1/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */
2
3import { expect } from 'chai'
4import { compareSemVer } from '@shared/core-utils'
5
6describe('Version', function () {
7
8 it('Should correctly compare two stable versions', async function () {
9 expect(compareSemVer('3.4.0', '3.5.0')).to.be.below(0)
10 expect(compareSemVer('3.5.0', '3.4.0')).to.be.above(0)
11
12 expect(compareSemVer('3.4.0', '4.1.0')).to.be.below(0)
13 expect(compareSemVer('4.1.0', '3.4.0')).to.be.above(0)
14
15 expect(compareSemVer('3.4.0', '3.4.1')).to.be.below(0)
16 expect(compareSemVer('3.4.1', '3.4.0')).to.be.above(0)
17 })
18
19 it('Should correctly compare two unstable version', async function () {
20 expect(compareSemVer('3.4.0-alpha', '3.4.0-beta.1')).to.be.below(0)
21 expect(compareSemVer('3.4.0-alpha.1', '3.4.0-beta.1')).to.be.below(0)
22 expect(compareSemVer('3.4.0-beta.1', '3.4.0-beta.2')).to.be.below(0)
23 expect(compareSemVer('3.4.0-beta.1', '3.5.0-alpha.1')).to.be.below(0)
24
25 expect(compareSemVer('3.4.0-alpha.1', '3.4.0-nightly.4')).to.be.below(0)
26 expect(compareSemVer('3.4.0-nightly.3', '3.4.0-nightly.4')).to.be.below(0)
27 expect(compareSemVer('3.3.0-nightly.5', '3.4.0-nightly.4')).to.be.below(0)
28 })
29
30 it('Should correctly compare a stable and unstable versions', async function () {
31 expect(compareSemVer('3.4.0', '3.4.1-beta.1')).to.be.below(0)
32 expect(compareSemVer('3.4.0-beta.1', '3.4.0-beta.2')).to.be.below(0)
33 expect(compareSemVer('3.4.0-beta.1', '3.4.0')).to.be.below(0)
34 expect(compareSemVer('3.4.0-nightly.4', '3.4.0')).to.be.below(0)
35 })
36})