Skip to content

Commit

Permalink
chore(starter): Test CLI more thoroughly for dep installation failure (
Browse files Browse the repository at this point in the history
…#1207)

We had an issue with some peer deps not being marked as optional that
started causing the npm install to fail (see
#1205).

Despite that because the starter cli does not return a non zero exit
code if it fails at the dep installation phase, some tests were passing
- I've modified them to check explicitly that the dep installation error
is not shown.

Until we upgrade the electric-sql package with the optional peer dep
flag, I've added the `--legacy-peer-deps` to `npm install` calls to work
around this issue. I will roll this back immediately after release after
confirming that the individual examples work correctly as well.
  • Loading branch information
msfstef authored Apr 29, 2024
1 parent ca53955 commit 1b79344
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 42 deletions.
5 changes: 5 additions & 0 deletions .changeset/lazy-rocks-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"create-electric-app": patch
---

Install with `--legacy-peer-deps` to circumvent temporary issue with `electric-sql` package.
63 changes: 28 additions & 35 deletions examples/starter/e2e/create-project.e2e.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ const testAppDisplayName = 'Test App'
const testAppDir = path.join(tempDir, testAppName)
const envFilePath = path.join(testAppDir, '.env.local')

async function runCli(t, cliArgs) {
return await t.notThrowsAsync(() =>
runCommand(
`npx create-electric-app ${testAppName} ${cliArgs}`,
tempDir,
[],
(output) => {
t.notRegex(output, /Could not install project dependencies./)
},
),
)
}

async function assertPackageJson(t) {
const packageJsonPath = path.join(testAppDir, 'package.json')

Expand Down Expand Up @@ -62,34 +75,19 @@ test.serial.afterEach.always(async () => {
})

test.serial('should create React project', async (t) => {
await t.notThrowsAsync(() =>
runCommand(`npx create-electric-app ${testAppName}`, tempDir),
)

await runCli(t, '')
await assertPackageJson(t)
await assertEnvFile(t)
})

test.serial('should create Vue.js project', async (t) => {
await t.notThrowsAsync(() =>
runCommand(
`npx create-electric-app ${testAppName} --template vue`,
tempDir,
),
)

await runCli(t, '--template vue')
await assertPackageJson(t)
await assertEnvFile(t)
})

test.serial('should create Expo project', async (t) => {
await t.notThrowsAsync(() =>
runCommand(
`npx create-electric-app ${testAppName} --template expo`,
tempDir,
),
)

await runCli(t, '--template expo')
await assertPackageJson(t)
await assertEnvFile(t)

Expand All @@ -101,12 +99,7 @@ test.serial('should create Expo project', async (t) => {
})

test.serial('should create React Native project', async (t) => {
await t.notThrowsAsync(() =>
runCommand(
`npx create-electric-app ${testAppName} --template react-native`,
tempDir,
),
)
await runCli(t, '--template react-native')

await assertPackageJson(t)
await assertEnvFile(t)
Expand All @@ -128,23 +121,23 @@ test.serial('should create React Native project', async (t) => {
test.serial('should set environment variables for project', async (t) => {
const electricPort = 1234
const electricProxyPort = 12345
await t.notThrowsAsync(() =>
runCommand(
`npx create-electric-app ${testAppName} --electric-port ${electricPort} --electric-proxy-port ${electricProxyPort}`,
tempDir,
),
await runCli(
t,
`--electric-port ${electricPort} --electric-proxy-port ${electricProxyPort}`,
)
await assertEnvFile(t, electricPort, electricProxyPort)
})

test.serial('should be able to use interactive prompt', async (t) => {
await t.notThrowsAsync(() =>
runCommand(`npx create-electric-app`, tempDir, [
testAppName,
'react',
'1234',
'12345',
]),
runCommand(
`npx create-electric-app`,
tempDir,
[testAppName, 'react', '1234', '12345'],
(output) => {
t.notRegex(output, /Could not install project dependencies./)
},
),
)

await assertPackageJson(t)
Expand Down
6 changes: 5 additions & 1 deletion examples/starter/e2e/test-utils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { spawn } from 'child_process'
import * as fs from 'fs/promises'

export function runCommand(command, cwd, inputArgs = []) {
export function runCommand(command, cwd, inputArgs = [], outputListener) {
const inputs = [...inputArgs]
return new Promise((res, rej) => {
const proc = spawn(command, [], {
Expand All @@ -18,6 +18,9 @@ export function runCommand(command, cwd, inputArgs = []) {
let timer = null
proc.stdin.setEncoding('utf-8')
proc.stdout.on('data', (data) => {
if (outputListener) {
outputListener(Buffer.from(data).toString())
}
if (inputs.length > 0) {
if (timer === null) {
console.log('Received:', Buffer.from(data).toString())
Expand All @@ -42,6 +45,7 @@ export function runCommand(command, cwd, inputArgs = []) {
res()
} else {
const errStr = Buffer.concat(errors).toString()
console.error(errStr)
rej(errStr)
}
})
Expand Down
16 changes: 10 additions & 6 deletions examples/starter/src/file-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,15 @@ export async function installDependencies(projectDir: string): Promise<void> {
// Run `npm install` in the project directory to install the dependencies
// Also run `npm upgrade` to replace `electric-sql: latest` by `electric-sql: x.y.z`
// where `x.y.z` corresponds to the latest version.
const proc = spawn('npm install && npm upgrade --caret electric-sql', [], {
stdio: ['ignore', 'ignore', 'pipe'],
cwd: projectDir,
shell: true,
})
const proc = spawn(
'npm install --legacy-peer-deps && npm upgrade --legacy-peer-deps --caret electric-sql',
[],
{
stdio: ['ignore', 'ignore', 'pipe'],
cwd: projectDir,
shell: true,
},
)

let errors: Uint8Array[] = []
proc.stderr.on('data', (data) => {
Expand Down Expand Up @@ -247,7 +251,7 @@ export async function regenerateReactNativePlatformProjects(
// recreate a react native project from scratch
await new Promise<void>((res, rej) => {
const proc = spawn(
`npm install -D react-native-eject && npx react-native eject`,
`npm install -D --legacy-peer-deps react-native-eject && npx react-native eject`,
[],
{
stdio: ['ignore', 'ignore', 'pipe'],
Expand Down

0 comments on commit 1b79344

Please sign in to comment.