Skip to content

Commit

Permalink
[WIP] Run tests in ESM mode instead of CJS
Browse files Browse the repository at this point in the history
  • Loading branch information
jvasseur committed Jan 19, 2023
1 parent a452baa commit e537d3c
Show file tree
Hide file tree
Showing 23 changed files with 442 additions and 274 deletions.
122 changes: 52 additions & 70 deletions generators/app/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
import fs from 'fs';
import path from 'path';
import { existsSync } from 'fs';
import { readFile } from 'fs/promises';
import { resolve } from 'path';
import YAML from 'yaml';
import helpers from 'yeoman-test';
import helpers, { RunResult } from 'yeoman-test';
import * as CircleCI from '../../utils/circleci';
import AppGenerator from '.';

describe('When running the generator with React', () => {
let root: string;
let result: RunResult<AppGenerator>;

beforeAll(async () => {
const result = await helpers.run(__dirname)
.withPrompts({
result = await helpers.create<AppGenerator>(AppGenerator)
.withAnswers({
backend: 'express',
contactEmail: 'test@example.com',
type: 'react',
});

root = result.cwd;
})
.run();
});

afterAll(async () => {
await fs.promises.rm(root, { recursive: true });
afterAll(() => {
result.cleanup();
});

test('It generates an Express backend', async () => {
const config = JSON.parse(await fs.promises.readFile(path.resolve(root, 'backend', 'package.json'), 'utf8'));
const config = JSON.parse(await readFile(resolve(result.cwd, 'backend', 'package.json'), 'utf8'));

expect(config.dependencies.express).toBeDefined();
});

test('It generates a React frontend', async () => {
const config = JSON.parse(await fs.promises.readFile(path.resolve(root, 'frontend', 'package.json'), 'utf8'));
const config = JSON.parse(await readFile(resolve(result.cwd, 'frontend', 'package.json'), 'utf8'));

expect(config.devDependencies['react-scripts']).toBeDefined();
});

test('It add the right dependencies to the deploy job', async () => {
const content = await fs.promises.readFile(path.resolve(root, '.circleci', 'config.yml'), 'utf8');
const content = await readFile(resolve(result.cwd, '.circleci', 'config.yml'), 'utf8');
const config = CircleCI.Config.fromRaw(YAML.parse(content));

expect(config.workflows.build.jobs.deploy.requires).toEqual([
Expand All @@ -46,37 +47,36 @@ describe('When running the generator with React', () => {
});

describe('When running the generator with Next.js', () => {
let root: string;
let result: RunResult<AppGenerator>;

beforeAll(async () => {
const result = await helpers.run(__dirname)
.withPrompts({
result = await helpers.create<AppGenerator>(AppGenerator)
.withAnswers({
backend: 'express',
contactEmail: 'test@example.com',
type: 'next-js',
});

root = result.cwd;
})
.run();
});

afterAll(async () => {
await fs.promises.rm(root, { recursive: true });
result.cleanup();
});

test('It generates an Express backend', async () => {
const config = JSON.parse(await fs.promises.readFile(path.resolve(root, 'backend', 'package.json'), 'utf8'));
const config = JSON.parse(await readFile(resolve(result.cwd, 'backend', 'package.json'), 'utf8'));

expect(config.dependencies.express).toBeDefined();
});

test('It generates an Next.js frontend', async () => {
const config = JSON.parse(await fs.promises.readFile(path.resolve(root, 'frontend', 'package.json'), 'utf8'));
const config = JSON.parse(await readFile(resolve(result.cwd, 'frontend', 'package.json'), 'utf8'));

expect(config.dependencies.next).toBeDefined();
});

test('It add the right dependencies to the deploy job', async () => {
const content = await fs.promises.readFile(path.resolve(root, '.circleci', 'config.yml'), 'utf8');
const content = await readFile(resolve(result.cwd, '.circleci', 'config.yml'), 'utf8');
const config = CircleCI.Config.fromRaw(YAML.parse(content));

expect(config.workflows.build.jobs.deploy.requires).toEqual([
Expand All @@ -87,26 +87,25 @@ describe('When running the generator with Next.js', () => {
});

describe('When running the generator with Symfony', () => {
let root: string;
let result: RunResult<AppGenerator>;

beforeAll(async () => {
const result = await helpers.run(__dirname)
.withPrompts({
result = await helpers.create<AppGenerator>(AppGenerator)
.withAnswers({
backend: 'symfony',
contactEmail: 'test@example.com',
add: false,
twig: true,
});

root = result.cwd;
})
.run();
});

afterAll(async () => {
await fs.promises.rm(root, { recursive: true });
result.cleanup()
});

test('It add the right dependencies to the deploy job', async () => {
const content = await fs.promises.readFile(path.resolve(root, '.circleci', 'config.yml'), 'utf8');
const content = await readFile(resolve(result.cwd, '.circleci', 'config.yml'), 'utf8');
const config = CircleCI.Config.fromRaw(YAML.parse(content));

expect(config.workflows.build.jobs.deploy.requires).toEqual([
Expand All @@ -116,94 +115,77 @@ describe('When running the generator with Symfony', () => {
});

describe('When running the generator with Flutter', () => {
let root: string;
let result: RunResult<AppGenerator>;

beforeAll(async () => {
const result = await helpers.run(__dirname)
.withPrompts({
result = await helpers.create<AppGenerator>(AppGenerator)
.withAnswers({
projectName: 'my_project',
backend: 'express',
contactEmail: 'test@example.com',
type: 'flutter',
applicationPrefix: 'com.example',
applicationDisplayName: 'My Project',
});

root = result.cwd;
})
.run();
});

afterAll(async () => {
await fs.promises.rm(root, { recursive: true });
result.cleanup();
});

it('It generates a Flutter mobile app', async () => {
const config = YAML.parse(await fs.promises.readFile(
path.resolve(
root,
'mobile',
'pubspec.yaml',
),
'utf8',
));
const config = YAML.parse(await readFile(resolve(result.cwd, 'mobile', 'pubspec.yaml'), 'utf8'));

expect(config).toBeDefined();
});
});

describe('When running the generator with React-Native', () => {
let root: string;
let result: RunResult<AppGenerator>;

beforeAll(async () => {
const result = await helpers.run(__dirname)
.withPrompts({
result = await helpers.create<AppGenerator>(AppGenerator)
.withAnswers({
projectName: 'my_project',
backend: 'express',
contactEmail: 'test@example.com',
type: 'react-native',
applicationPrefix: 'com.example',
applicationDisplayName: 'My Project',
});

root = result.cwd;
})
.run();
});

afterAll(async () => {
await fs.promises.rm(root, { recursive: true });
result.cleanup();
});

it('It generates a React-Native mobile app', async () => {
const config = YAML.parse(await fs.promises.readFile(
path.resolve(
root,
'mobile',
'package.json',
),
'utf8',
));
const config = YAML.parse(await readFile(resolve(result.cwd, 'mobile', 'package.json'), 'utf8'));

expect(config).toBeDefined();
});
});

describe('When running the generator without a Backend', () => {
let root: string;
let result: RunResult<AppGenerator>;

beforeAll(async () => {
const result = await helpers.run(__dirname)
.withPrompts({
result = await helpers.create<AppGenerator>(AppGenerator)
.withAnswers({
backend: null,
contactEmail: 'test@example.com',
type: 'create-react-app',
});

root = result.cwd;
})
.run();
});

afterAll(async () => {
await fs.promises.rm(root, { recursive: true });
result.cleanup();
});

it('It doesn\'t create a backend directory', async () => {
expect(fs.existsSync(path.resolve(root, 'backend'))).toBe(false);
expect(existsSync(resolve(result.cwd, 'backend'))).toBe(false);
});
});
21 changes: 12 additions & 9 deletions generators/app/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { Question } from 'yeoman-generator';
import createResolve from '../../utils/createResolve';
import BaseGenerator from '../../utils/BaseGenerator';
import validateFrontendName from '../../utils/validation/validateFrontendName';

const resolve = createResolve(import.meta);

enum BackendChoice {
Express = 'express',
Symfony = 'symfony',
Expand Down Expand Up @@ -73,7 +76,7 @@ class AppGenerator extends BaseGenerator {
const { backend }: BackendPrompt = await this.promptConfig<BackendPrompt>(backendPrompt);
const frontends = await this.#promptFrontends();

this.composeWith(require.resolve('../root'));
this.composeWith(resolve('../root'));

if (backend) {
// We suppose that the backend will sit at the root if there is no frontend.
Expand All @@ -82,13 +85,13 @@ class AppGenerator extends BaseGenerator {

switch (backend) {
case BackendChoice.Express:
this.composeWith(require.resolve('../express'), options);
this.composeWith(resolve('../express'), options);
break;
case BackendChoice.FastAPI:
this.composeWith(require.resolve('../fast-api'), options);
this.composeWith(resolve('../fast-api'), options);
break;
case BackendChoice.Symfony: {
this.composeWith(require.resolve('../symfony'), options);
this.composeWith(resolve('../symfony'), options);
break;
}
}
Expand All @@ -97,19 +100,19 @@ class AppGenerator extends BaseGenerator {
for (const { type, name } of frontends) {
switch (type) {
case FrontendType.React:
this.composeWith(require.resolve('../react'), { arguments: [name, '--http-path=/'] });
this.composeWith(resolve('../react'), { arguments: [name, '--http-path=/'] });
break;
case FrontendType.NextJS:
this.composeWith(require.resolve('../next-js'), { arguments: [name, '--http-path=/'] });
this.composeWith(resolve('../next-js'), { arguments: [name, '--http-path=/'] });
break;
case FrontendType.ReactAdmin:
this.composeWith(require.resolve('../react-admin'), [name, '--http-path=/admin/']);
this.composeWith(resolve('../react-admin'), [name, '--http-path=/admin/']);
break;
case FrontendType.Flutter:
this.composeWith(require.resolve('../flutter-mobile'), [name]);
this.composeWith(resolve('../flutter-mobile'), [name]);
break;
case FrontendType.ReactNative:
this.composeWith(require.resolve('../react-native-mobile'), [name]);
this.composeWith(resolve('../react-native-mobile'), [name]);
break;
}
}
Expand Down
5 changes: 4 additions & 1 deletion generators/express/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import fs from 'fs';
import path from 'path';
import path, { dirname } from 'path';
import { fileURLToPath } from 'url';
import execa from 'execa';
import YAML from 'yaml';
import helpers from 'yeoman-test';
import { Config } from '../../utils/circleci';

const __dirname = dirname(fileURLToPath(import.meta.url));

describe('When running the generator', () => {
let root: string;
const packageName = 'test';
Expand Down
7 changes: 5 additions & 2 deletions generators/express/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import cryptoRandomString from 'crypto-random-string';
import indent from 'indent-tag';
import { createEncrypt } from '../../utils/ansible';
import createResolve from '../../utils/createResolve';
import PackageGenerator from '../../utils/PackageGenerator';
import varName from '../../utils/varName';
import { DeploymentChoice } from '../root';

const resolve = createResolve(import.meta);

class ExpressGenerator extends PackageGenerator {
initializing(): void {
const { 'http-path': httpPath, packageName } = this.options;

this.composeWith(require.resolve('../utils/database'), [packageName]);
this.composeWith(require.resolve('../utils/http'), [packageName, httpPath, 3000]);
this.composeWith(resolve('../utils/database'), [packageName]);
this.composeWith(resolve('../utils/http'), [packageName, httpPath, 3000]);
}

writing(): void {
Expand Down
5 changes: 4 additions & 1 deletion generators/fast-api/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import createResolve from '../../utils/createResolve';
import PackageGenerator from '../../utils/PackageGenerator';

const resolve = createResolve(import.meta);

class FastApiGenerator extends PackageGenerator {
initializing(): void {
const { packageName } = this.options;

this.composeWith(require.resolve('../utils/database'), [packageName]);
this.composeWith(resolve('../utils/database'), [packageName]);
}

writing(): void {
Expand Down
5 changes: 4 additions & 1 deletion generators/flutter-mobile/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import fs from 'fs';
import path from 'path';
import path, { dirname } from 'path';
import { fileURLToPath } from 'url';
import * as PLIST from 'fast-plist';
import * as XML from 'xml2js';
import YAML from 'yaml';

import helpers from 'yeoman-test';

const __dirname = dirname(fileURLToPath(import.meta.url));

describe('When running the generator with valid options', () => {
let root: string;

Expand Down
5 changes: 4 additions & 1 deletion generators/next-js/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import fs from 'fs';
import path from 'path';
import path, { dirname } from 'path';
import { fileURLToPath } from 'url';
import execa from 'execa';
import YAML from 'yaml';
import helpers from 'yeoman-test';
import { Config } from '../../utils/circleci';

const __dirname = dirname(fileURLToPath(import.meta.url));

describe('When running the generator', () => {
let root: string;
const packageName = 'test';
Expand Down
Loading

0 comments on commit e537d3c

Please sign in to comment.