Skip to content

Commit a682e24

Browse files
authored
fix postgres@500 resolving to postgres@latest (#36)
insidious JS arrays are reference-based bug
1 parent 8709531 commit a682e24

4 files changed

Lines changed: 86 additions & 4 deletions

File tree

src/hooks/useCellar.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { assertEquals } from "deno/testing/asserts.ts"
1+
import { assertEquals, assertRejects } from "deno/testing/asserts.ts"
22
import SemVer, * as semver from "../utils/semver.ts"
33
import { useTestConfig } from "./useTestConfig.ts"
44
import install from "../plumbing/install.ts"
@@ -14,6 +14,8 @@ Deno.test("useCellar.resolve()", async () => {
1414
await useCellar().resolve(installation.pkg)
1515
await useCellar().resolve({ project: "python.org", constraint: new semver.Range("^3") })
1616
await useCellar().resolve(installation.path)
17+
18+
assertRejects(() => useCellar().resolve({ project: "python.org", constraint: new semver.Range("@300")}))
1719
})
1820

1921
Deno.test("useCellar.has()", async () => {

src/plumbing/resolve.test.ts

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { assert, assertEquals, fail, assertRejects } from "deno/testing/asserts.ts"
12
import { Installation, Package, PackageRequirement } from "../types.ts"
2-
import { assert, assertEquals, fail } from "deno/testing/asserts.ts"
33
import { useTestConfig } from "../hooks/useTestConfig.ts"
4+
import useInventory from "../hooks/useInventory.ts"
45
import resolve, { _internals } from "./resolve.ts"
56
import useCellar from "../hooks/useCellar.ts"
7+
import * as semver from "../utils/semver.ts"
68
import { stub } from "deno/testing/mock.ts"
79
import SemVer from "../utils/semver.ts"
810
import Path from "../utils/Path.ts"
@@ -58,7 +60,7 @@ Deno.test("resolve cellar.has", async runner => {
5860
assert(errord)
5961
})
6062

61-
await runner.step("uses existing version if even if update set", async () => {
63+
await runner.step("uses existing version if even if update set", async () => {
6264
const stub1 = stub(_internals, "useInventory", () => ({
6365
get: () => fail(),
6466
select: () => Promise.resolve(pkg.version),
@@ -77,3 +79,73 @@ Deno.test("resolve cellar.has", async runner => {
7779
}
7880
})
7981
})
82+
83+
const permissions = { net: false, read: true, env: ["TMPDIR", "HOME", "TMP", "TEMP"], write: true /*FIXME*/ }
84+
85+
// https://github.com/teaxyz/cli/issues/655
86+
Deno.test("postgres@500 fails", { permissions }, async () => {
87+
useTestConfig()
88+
89+
const pkg = {
90+
project: "posqtgres.org",
91+
version: new SemVer("15.0.1")
92+
}
93+
94+
const select = useInventory().select
95+
const stub1 = stub(_internals, "useInventory", () => ({
96+
get: () => Promise.resolve([pkg.version]),
97+
select,
98+
}))
99+
100+
const pkgs = [
101+
{ project: pkg.project, constraint: new semver.Range('@500') }
102+
]
103+
104+
try {
105+
// https://github.com/teaxyz/cli/issues/655
106+
await assertRejects(() => resolve(pkgs))
107+
} finally {
108+
stub1.restore()
109+
}
110+
})
111+
112+
// https://github.com/teaxyz/cli/issues/655
113+
Deno.test("postgres@500 fails if installed", { permissions }, async () => {
114+
const pkg = {
115+
project: "posqtgres.org",
116+
version: new SemVer("15.0.1")
117+
}
118+
const prefix = useTestConfig().prefix
119+
120+
const cellar = useCellar()
121+
const has = (b: Path | Package | PackageRequirement) => {
122+
if ("constraint" in b && b.constraint.satisfies(pkg.version)) {
123+
const a: Installation = {pkg, path: prefix.join(pkg.project, `v${pkg.version}`) }
124+
return Promise.resolve(a)
125+
} else {
126+
return Promise.resolve(undefined)
127+
}
128+
}
129+
130+
const select = useInventory().select
131+
const stub1 = stub(_internals, "useInventory", () => ({
132+
get: () => Promise.resolve([pkg.version]),
133+
select,
134+
}))
135+
const stub2 = stub(_internals, "useCellar", () => ({
136+
...cellar,
137+
has
138+
}))
139+
140+
const pkgs = [
141+
{ project: pkg.project, constraint: new semver.Range('@500') }
142+
]
143+
144+
try {
145+
// https://github.com/teaxyz/cli/issues/655
146+
await assertRejects(() => resolve(pkgs))
147+
} finally {
148+
stub1.restore()
149+
stub2.restore()
150+
}
151+
})

src/utils/semver.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ Deno.test("semver", async test => {
4545

4646
await test.step("satisfies", () => {
4747
assertEquals(new semver.Range("=3.1.0").max([new SemVer("3.1.0")]), new SemVer("3.1.0"))
48+
49+
// the following two test for https://github.com/teaxyz/lib/pull/36
50+
assertEquals(new semver.Range("^300").max([new SemVer("3.1.0")]), undefined)
51+
assertEquals(new semver.Range("@300").max([new SemVer("3.1.0")]), undefined)
4852
})
4953

5054
await test.step("constructor", () => {
@@ -153,6 +157,10 @@ Deno.test("semver", async test => {
153157
assertThrows(() => new semver.Range("1.2"))
154158
assertThrows(() => new semver.Range("1.2.3"))
155159
assertThrows(() => new semver.Range("1.2.3.4"))
160+
161+
assertEquals(new semver.Range("@300").toString(), "^300")
162+
assertEquals(new semver.Range("@300.1").toString(), "~300.1")
163+
assertEquals(new semver.Range("@300.1.0").toString(), ">=300.1<300.1.1")
156164
})
157165

158166
await test.step("intersection", async test => {

src/utils/semver.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export default class SemVer {
5353
this.raw = v.raw
5454
this.pretty = v.pretty
5555
} else {
56-
this.components = input
56+
this.components = [...input]
5757
this.raw = input.join('.')
5858
}
5959

0 commit comments

Comments
 (0)