Skip to content

Commit 7ac0e06

Browse files
committed
Add integration test to verify publishing into a registry
1 parent 0e2e5da commit 7ac0e06

26 files changed

+3146
-269
lines changed

cspell.config.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"packtory",
1111
"subrecord",
1212
"kleur",
13-
"cmds"
13+
"cmds",
14+
"htpasswd"
1415
]
1516
}

eslint.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default [
1515
},
1616
{
1717
...avaConfig,
18-
files: ['**/*.test.ts', 'source/test-libraries/**/*.ts']
18+
files: ['**/*.test.ts', 'source/test-libraries/**/*.ts', 'integration-tests/**/*.ts']
1919
},
2020
{
2121
...nodeConfigFileConfig,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "test-fixture",
3+
"version": "0.0.0-dev",
4+
"dependencies": {
5+
"dep-a": "42.0.0",
6+
"dep-b": "21.0.0"
7+
},
8+
"type": "module"
9+
}

integration-tests/fixtures/multiple-packages-with-substitution-slightly-modified/src/bar.js

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/fixtures/multiple-packages-with-substitution-slightly-modified/src/bar.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export type Baz = number;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export declare const foo: import('./foo.js').Foo;

integration-tests/fixtures/multiple-packages-with-substitution-slightly-modified/src/entry1.js

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/fixtures/multiple-packages-with-substitution-slightly-modified/src/entry1.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export declare const foo: import('./foo.js').Foo;

integration-tests/fixtures/multiple-packages-with-substitution-slightly-modified/src/entry2.js

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/fixtures/multiple-packages-with-substitution-slightly-modified/src/entry2.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export declare const foo: import('./foo.js').Foo;

integration-tests/fixtures/multiple-packages-with-substitution-slightly-modified/src/entry3.js

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/fixtures/multiple-packages-with-substitution-slightly-modified/src/entry3.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import { Baz } from './baz.js';
2+
export type Foo = string;

integration-tests/fixtures/multiple-packages-with-substitution-slightly-modified/src/foo.js

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/fixtures/multiple-packages-with-substitution-slightly-modified/src/foo.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/fixtures/multiple-packages-with-substitution-slightly-modified/src/qux.js

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/fixtures/multiple-packages-with-substitution-slightly-modified/src/qux.js.map

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
foo:$2y$10$FF/Sly7LDOyXPyMeW1dhmu/QxN/TfdaN8yThK5qWP4QfnbAuxceg2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
foo:pZvIBPhhdvkq6:autocreated 2024-02-01T21:38:01.013Z
+208
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
import path from 'node:path';
2+
import test from 'ava';
3+
import npmFetch from 'npm-registry-fetch';
4+
import { publish } from 'libnpmpublish';
5+
import { loadPackageJson } from '../load-package-json.js';
6+
import { checkWithRegistry, type RegistryDetails } from '../registry.js';
7+
import { buildAndPublishAll, type PublishAllResult } from '../../source/packages/packtory/packtory.entry-point.js';
8+
import { createRegistryClient } from '../../source/publisher/registry-client.js';
9+
// eslint-disable-next-line import/max-dependencies -- maybe we can extract some of the setup functions to bundle dependencies
10+
import { extractPackageTarball } from '../../source/publisher/extract-package-tarball.js';
11+
12+
const registryClient = createRegistryClient({ npmFetch, publish });
13+
14+
async function publishPackagesFromFixtures(
15+
fixturePath: string,
16+
registryDetails: RegistryDetails
17+
): Promise<PublishAllResult> {
18+
return buildAndPublishAll(
19+
{
20+
registrySettings: {
21+
registryUrl: registryDetails.registryUrl,
22+
token: registryDetails.token
23+
},
24+
commonPackageSettings: {
25+
sourcesFolder: path.join(fixturePath, 'src'),
26+
mainPackageJson: await loadPackageJson(fixturePath)
27+
},
28+
packages: [
29+
{
30+
name: 'first',
31+
entryPoints: [
32+
{
33+
js: path.join(fixturePath, 'src/entry1.js'),
34+
declarationFile: path.join(fixturePath, 'src/entry1.d.ts')
35+
}
36+
]
37+
},
38+
{
39+
name: 'second',
40+
entryPoints: [
41+
{
42+
js: path.join(fixturePath, 'src/entry2.js'),
43+
declarationFile: path.join(fixturePath, 'src/entry2.d.ts')
44+
}
45+
],
46+
bundleDependencies: ['first']
47+
}
48+
]
49+
},
50+
{ dryRun: false }
51+
);
52+
}
53+
54+
async function fetchLatestVersion(
55+
packageName: string,
56+
registryDetails: RegistryDetails
57+
): Promise<Record<string, unknown>> {
58+
const versionDetails = await registryClient.fetchLatestVersion(packageName, registryDetails);
59+
if (versionDetails.isJust) {
60+
const { version, tarballUrl, shasum } = versionDetails.value;
61+
const tarballData = await registryClient.fetchTarball(tarballUrl, shasum);
62+
const files = await extractPackageTarball(tarballData);
63+
64+
return {
65+
version,
66+
files
67+
};
68+
}
69+
70+
return {};
71+
}
72+
73+
test(
74+
'publishes the initial version of two packages in the first run and updates one of the two packages in the second run because the other did not change',
75+
checkWithRegistry,
76+
// eslint-disable-next-line max-statements -- no idea how to make this smaller
77+
async (t, registryDetails) => {
78+
const firstRunFixture = path.join(
79+
process.cwd(),
80+
'integration-tests/fixtures/multiple-packages-with-substitution'
81+
);
82+
83+
const result = await publishPackagesFromFixtures(firstRunFixture, registryDetails);
84+
t.is(result.isOk, true);
85+
86+
const latestVersionOfFirstPackage = await fetchLatestVersion('first', registryDetails);
87+
const latestVersionOfSecondPackage = await fetchLatestVersion('second', registryDetails);
88+
89+
t.deepEqual(latestVersionOfFirstPackage, {
90+
version: '0.0.1',
91+
files: [
92+
{
93+
content:
94+
'{\n "dependencies": {},\n "main": "entry1.js",\n "name": "first",\n "type": "module",\n "types": "entry1.d.ts",\n "version": "0.0.1"\n}',
95+
filePath: 'package/package.json'
96+
},
97+
{
98+
content: "import { qux } from './qux.js';\n//# sourceMappingURL=entry1.js.map\n",
99+
filePath: 'package/entry1.js'
100+
},
101+
{
102+
content: "export const qux = 'qux';\n//# sourceMappingURL=qux.js.map\n",
103+
filePath: 'package/qux.js'
104+
},
105+
{
106+
content: "export declare const foo: import('./foo.js').Foo;\n",
107+
filePath: 'package/entry1.d.ts'
108+
},
109+
{
110+
content: "import { Baz } from './baz.js';\nexport type Foo = string;\n",
111+
filePath: 'package/foo.d.ts'
112+
},
113+
{
114+
content: 'export type Baz = number;\n',
115+
filePath: 'package/baz.d.ts'
116+
}
117+
]
118+
});
119+
t.deepEqual(latestVersionOfSecondPackage, {
120+
version: '0.0.1',
121+
files: [
122+
{
123+
content:
124+
'{\n "dependencies": {\n "first": "0.0.1"\n },\n "main": "entry2.js",\n "name": "second",\n "type": "module",\n "types": "entry2.d.ts",\n "version": "0.0.1"\n}',
125+
filePath: 'package/package.json'
126+
},
127+
{
128+
content: "import { bar } from './bar.js';\n//# sourceMappingURL=entry2.js.map\n",
129+
filePath: 'package/entry2.js'
130+
},
131+
{
132+
content:
133+
"import { qux } from 'first/qux.js';\nexport const bar = 'bar';\n//# sourceMappingURL=bar.js.map\n",
134+
filePath: 'package/bar.js'
135+
},
136+
{
137+
content: "export declare const foo: import('first/foo.d.ts').Foo;\n",
138+
filePath: 'package/entry2.d.ts'
139+
}
140+
]
141+
});
142+
143+
const secondRunFixture = path.join(
144+
process.cwd(),
145+
'integration-tests/fixtures/multiple-packages-with-substitution-slightly-modified'
146+
);
147+
148+
const secondRunResult = await publishPackagesFromFixtures(secondRunFixture, registryDetails);
149+
t.is(secondRunResult.isOk, true);
150+
151+
const latestVersionOfFirstPackageSecondRun = await fetchLatestVersion('first', registryDetails);
152+
const latestVersionOfSecondPackageSecondRun = await fetchLatestVersion('second', registryDetails);
153+
154+
t.deepEqual(latestVersionOfFirstPackageSecondRun, {
155+
version: '0.0.1',
156+
files: [
157+
{
158+
content:
159+
'{\n "dependencies": {},\n "main": "entry1.js",\n "name": "first",\n "type": "module",\n "types": "entry1.d.ts",\n "version": "0.0.1"\n}',
160+
filePath: 'package/package.json'
161+
},
162+
{
163+
content: "import { qux } from './qux.js';\n//# sourceMappingURL=entry1.js.map\n",
164+
filePath: 'package/entry1.js'
165+
},
166+
{
167+
content: "export const qux = 'qux';\n//# sourceMappingURL=qux.js.map\n",
168+
filePath: 'package/qux.js'
169+
},
170+
{
171+
content: "export declare const foo: import('./foo.js').Foo;\n",
172+
filePath: 'package/entry1.d.ts'
173+
},
174+
{
175+
content: "import { Baz } from './baz.js';\nexport type Foo = string;\n",
176+
filePath: 'package/foo.d.ts'
177+
},
178+
{
179+
content: 'export type Baz = number;\n',
180+
filePath: 'package/baz.d.ts'
181+
}
182+
]
183+
});
184+
t.deepEqual(latestVersionOfSecondPackageSecondRun, {
185+
version: '0.0.2',
186+
files: [
187+
{
188+
content:
189+
'{\n "dependencies": {\n "first": "0.0.1"\n },\n "main": "entry2.js",\n "name": "second",\n "type": "module",\n "types": "entry2.d.ts",\n "version": "0.0.2"\n}',
190+
filePath: 'package/package.json'
191+
},
192+
{
193+
content: "import { bar } from './bar.js';\n//# sourceMappingURL=entry2.js.map\n",
194+
filePath: 'package/entry2.js'
195+
},
196+
{
197+
content:
198+
"import { qux } from 'first/qux.js';\nexport const bar = 'bar-changed';\n//# sourceMappingURL=bar.js.map\n",
199+
filePath: 'package/bar.js'
200+
},
201+
{
202+
content: "export declare const foo: import('first/foo.d.ts').Foo;\n",
203+
filePath: 'package/entry2.d.ts'
204+
}
205+
]
206+
});
207+
}
208+
);

0 commit comments

Comments
 (0)