Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prisma command tests #5444

Merged
merged 5 commits into from
Apr 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/clever-bears-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@keystone-next/keystone': patch
---

Fixed an error being printed to the console when the Prisma CLI exited with a non-zero exit code when running `keystone-next prisma`
8 changes: 6 additions & 2 deletions packages-next/keystone/src/scripts/prisma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createSystem } from '../lib/createSystem';
import { generateNodeModulesArtifacts, validateCommittedArtifacts } from '../artifacts';
import { requireSource } from '../lib/requireSource';
import { initConfig } from '../lib/initConfig';
import { getConfigPath } from './utils';
import { ExitError, getConfigPath } from './utils';

export async function prisma(cwd: string, args: string[]) {
const config = initConfig(requireSource(getConfigPath(cwd)).default);
Expand All @@ -13,12 +13,16 @@ export async function prisma(cwd: string, args: string[]) {
await validateCommittedArtifacts(graphQLSchema, keystone, cwd);
await generateNodeModulesArtifacts(graphQLSchema, keystone, config, cwd);

await execa('node', [require.resolve('prisma'), ...args], {
const result = await execa('node', [require.resolve('prisma'), ...args], {
cwd,
stdio: 'inherit',
reject: false,
env: {
...process.env,
DATABASE_URL: config.db.url,
},
});
if (result.exitCode !== 0) {
throw new ExitError(result.exitCode);
}
}
15 changes: 8 additions & 7 deletions packages-next/keystone/src/scripts/tests/artifacts.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import fs from 'fs-extra';
import { text } from '@keystone-next/fields';
import { config, list } from '../../schema';
import { ExitError } from '../utils';
import { getFiles, recordConsole, runCommand, symlinkKeystoneDeps, testdir } from './utils';
import {
getFiles,
recordConsole,
runCommand,
schemas,
symlinkKeystoneDeps,
testdir,
} from './utils';

const basicKeystoneConfig = {
kind: 'config' as const,
Expand All @@ -18,11 +24,6 @@ const basicKeystoneConfig = {
}),
};

const schemas = {
'schema.graphql': fs.readFileSync(`${__dirname}/fixtures/basic-project/schema.graphql`, 'utf8'),
'schema.prisma': fs.readFileSync(`${__dirname}/fixtures/basic-project/schema.prisma`, 'utf8'),
};

describe.each(['postinstall', 'build', 'prisma migrate status'])('%s', command => {
test('logs an error and exits with 1 when the schemas do not exist and the terminal is non-interactive', async () => {
const tmp = await testdir({
Expand Down
85 changes: 85 additions & 0 deletions packages-next/keystone/src/scripts/tests/prisma.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import execa from 'execa';
import stripAnsi from 'strip-ansi';
import { basicKeystoneConfig, cliBinPath, schemas, symlinkKeystoneDeps, testdir } from './utils';

// testing erroring when the schemas are not up to date is in artifacts.test.ts

test('keystone-next prisma exits with the same code as the prisma child process exits with', async () => {
const tmp = await testdir({
...symlinkKeystoneDeps,
...schemas,
'keystone.js': basicKeystoneConfig,
});
const result = await execa('node', [cliBinPath, 'prisma', 'bad-thing'], {
reject: false,
all: true,
cwd: tmp,
});
expect(result.exitCode).toBe(1);
expect(stripAnsi(result.all!)).toMatchInlineSnapshot(`
"
! Unknown command \\"bad-thing\\"
◭ Prisma is a modern DB toolkit to query, migrate and model your database (https://prisma.io)
Usage
$ prisma [command]
Commands
init Setup Prisma for your app
generate Generate artifacts (e.g. Prisma Client)
db Manage your database schema and lifecycle
migrate Migrate your database
studio Browse your data with Prisma Studio
format Format your schema
Flags
--preview-feature Run Preview Prisma commands
Examples
Setup a new Prisma project
$ prisma init
Generate artifacts (e.g. Prisma Client)
$ prisma generate
Browse your data
$ prisma studio
Create migrations from your Prisma schema, apply them to the database, generate artifacts (e.g. Prisma Client)
$ prisma migrate dev
Pull the schema from an existing database, updating the Prisma schema
$ prisma db pull
Push the Prisma schema state to the database
$ prisma db push --preview-feature
"
`);
});

test('keystone-next prisma uses the db url in the keystone config', async () => {
const tmp = await testdir({
...symlinkKeystoneDeps,
...schemas,
'keystone.js': basicKeystoneConfig,
});
const result = await execa('node', [cliBinPath, 'prisma', 'migrate', 'status'], {
reject: false,
all: true,
cwd: tmp,
});
expect(result.exitCode).toBe(0);
expect(stripAnsi(result.all!)).toMatchInlineSnapshot(`
"Prisma schema loaded from schema.prisma
Datasource \\"sqlite\\": SQLite database \\"app.db\\" at \\"file:./app.db\\"
Database connection error:
P1003: SQLite database file doesn't exist"
`);
});
33 changes: 28 additions & 5 deletions packages-next/keystone/src/scripts/tests/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,34 @@ import { IntrospectionEngine, uriToCredentials } from '@prisma/sdk';
import { cli } from '../cli';
import { mockPrompts } from '../../lib/prompts';

export const cliBinPath = require.resolve('@keystone-next/keystone/bin/cli.js');

export const js = outdent;
export const ts = outdent;
export const tsx = outdent;
export const graphql = outdent;

export const basicKeystoneConfig = js`
import { config, list } from "@keystone-next/keystone/schema";
import { text } from "@keystone-next/fields";
export default config({
db: { provider: "sqlite", url: "file:./app.db" },
lists: {
Todo: list({
fields: {
title: text(),
},
}),
},
});
`;

export const schemas = {
'schema.graphql': fs.readFileSync(`${__dirname}/fixtures/basic-project/schema.graphql`, 'utf8'),
'schema.prisma': fs.readFileSync(`${__dirname}/fixtures/basic-project/schema.prisma`, 'utf8'),
};

export function recordConsole(promptResponses?: Record<string, string | boolean>) {
let oldConsole = { ...console };
let contents = '';
Expand Down Expand Up @@ -83,11 +111,6 @@ export function recordConsole(promptResponses?: Record<string, string | boolean>

let f = fixturez(__dirname);

export const js = outdent;
export const ts = outdent;
export const tsx = outdent;
export const graphql = outdent;

export const symlinkKeystoneDeps = Object.fromEntries(
[
'@keystone-next/keystone',
Expand Down