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

fix: remove deprecated JSON parser, use workspace helpers #139

Merged
merged 2 commits into from
Nov 19, 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
72 changes: 72 additions & 0 deletions src/__snapshots__/ng-add.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ng-add generating files generates new files if starting from scratch 1`] = `
"{
\\"version\\": 1,
\\"defaultProject\\": \\"THEPROJECT\\",
\\"projects\\": {
\\"THEPROJECT\\": {
\\"projectType\\": \\"application\\",
\\"root\\": \\"PROJECTROOT\\",
\\"architect\\": {
\\"build\\": {
\\"options\\": {
\\"outputPath\\": \\"dist/THEPROJECT\\"
}
},
\\"deploy\\": {
\\"builder\\": \\"angular-cli-ghpages:deploy\\"
}
}
},
\\"OTHERPROJECT\\": {
\\"projectType\\": \\"application\\",
\\"root\\": \\"PROJECTROOT\\",
\\"architect\\": {
\\"build\\": {
\\"options\\": {
\\"outputPath\\": \\"dist/OTHERPROJECT\\"
}
}
}
}
}
}"
`;

exports[`ng-add generating files overrides existing files 1`] = `
"{
\\"version\\": 1,
\\"defaultProject\\": \\"THEPROJECT\\",
\\"projects\\": {
\\"THEPROJECT\\": {
\\"projectType\\": \\"application\\",
\\"root\\": \\"PROJECTROOT\\",
\\"architect\\": {
\\"build\\": {
\\"options\\": {
\\"outputPath\\": \\"dist/THEPROJECT\\"
}
},
\\"deploy\\": {
\\"builder\\": \\"angular-cli-ghpages:deploy\\"
}
}
},
\\"OTHERPROJECT\\": {
\\"projectType\\": \\"application\\",
\\"root\\": \\"PROJECTROOT\\",
\\"architect\\": {
\\"build\\": {
\\"options\\": {
\\"outputPath\\": \\"dist/OTHERPROJECT\\"
}
},
\\"deploy\\": {
\\"builder\\": \\"angular-cli-ghpages:deploy\\"
}
}
}
}
}"
`;
2 changes: 1 addition & 1 deletion src/deploy/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
BuilderContext,
targetFromTargetString
} from '@angular-devkit/architect';
import { json, logging } from '@angular-devkit/core';
import { logging } from '@angular-devkit/core';

import { Schema } from './schema';
import { BuildTarget } from '../interfaces';
Expand Down
141 changes: 39 additions & 102 deletions src/ng-add.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import { SchematicContext, Tree } from '@angular-devkit/schematics';

import { ngAdd } from './ng-add';

const PROJECT_NAME = 'pie-ka-chu';
const PROJECT_ROOT = 'pirojok';

const OTHER_PROJECT_NAME = 'pi-catch-you';
const PROJECT_NAME = 'THEPROJECT';
const PROJECT_ROOT = 'PROJECTROOT';
const OTHER_PROJECT_NAME = 'OTHERPROJECT';

describe('ng-add', () => {
describe('generating files', () => {
Expand All @@ -17,118 +16,124 @@ describe('ng-add', () => {
});

it('generates new files if starting from scratch', async () => {
const result = ngAdd({
const result = await ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext);

expect(result.read('angular.json')!.toString()).toEqual(
initialAngularJson
);
const actual = result.read('angular.json')!.toString();
expect(prettifyJSON(actual)).toMatchSnapshot();
});

it('overrides existing files', async () => {
const tempTree = ngAdd({
const tempTree = await ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext);

const result = ngAdd({
const result = await ngAdd({
project: OTHER_PROJECT_NAME
})(tempTree, {} as SchematicContext);

const actual = result.read('angular.json')!.toString();

expect(actual).toEqual(overwriteAngularJson);
expect(prettifyJSON(actual)).toMatchSnapshot();
});
});

describe('error handling', () => {
it('fails if project not defined', () => {
it('should fail if project not defined', async () => {
const tree = Tree.empty();
const angularJSON = generateAngularJson();
delete angularJSON.defaultProject;
tree.create('angular.json', JSON.stringify(angularJSON));

expect(() =>
await expect(
ngAdd({
project: ''
})(tree, {} as SchematicContext)
).toThrowError(
).rejects.toThrowError(
'No Angular project selected and no default project in the workspace'
);
});

it('Should throw if angular.json not found', async () => {
expect(() =>
it('should throw if angular.json not found', async () => {
await expect(
ngAdd({
project: PROJECT_NAME
})(Tree.empty(), {} as SchematicContext)
).toThrowError('Could not find angular.json');
).rejects.toThrowError('Unable to determine format for workspace path.');
});

it('Should throw if angular.json can not be parsed', async () => {
it('should throw if angular.json can not be parsed', async () => {
const tree = Tree.empty();
tree.create('angular.json', 'hi');

expect(() =>
await expect(
ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext)
).toThrowError('Could not parse angular.json');
).rejects.toThrowError('Invalid JSON character: "h" at 0:0.');
});

it('Should throw if specified project does not exist ', async () => {
it('should throw if specified project does not exist', async () => {
const tree = Tree.empty();
tree.create('angular.json', JSON.stringify({ projects: {} }));
tree.create('angular.json', JSON.stringify({ version: 1, projects: {} }));

expect(() =>
await expect(
ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext)
).toThrowError(
).rejects.toThrowError(
'The specified Angular project is not defined in this workspace'
);
});

it('Should throw if specified project is not application', async () => {
it('should throw if specified project is not application', async () => {
const tree = Tree.empty();
tree.create(
'angular.json',
JSON.stringify({
projects: { [PROJECT_NAME]: { projectType: 'pokemon' } }
version: 1,
projects: { [PROJECT_NAME]: { projectType: 'invalid' } }
})
);

expect(() =>
await expect(
ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext)
).toThrowError(
).rejects.toThrowError(
'Deploy requires an Angular project type of "application" in angular.json'
);
});

it('Should throw if app does not have architect configured', async () => {
it('should throw if app does not have architect configured', async () => {
const tree = Tree.empty();
tree.create(
'angular.json',
JSON.stringify({
version: 1,
projects: { [PROJECT_NAME]: { projectType: 'application' } }
})
);

expect(() =>
await expect(
ngAdd({
project: PROJECT_NAME
})(tree, {} as SchematicContext)
).toThrowError(
'Cannot read the output path (architect.build.options.outputPath) of the Angular project "pie-ka-chu" in angular.json'
).rejects.toThrowError(
'Cannot read the output path (architect.build.options.outputPath) of the Angular project "THEPROJECT" in angular.json'
);
});
});
});

function prettifyJSON(json: string) {
return JSON.stringify(JSON.parse(json), null, 2);
}

function generateAngularJson() {
return {
version: 1,
defaultProject: PROJECT_NAME as string | undefined,
projects: {
[PROJECT_NAME]: {
Expand All @@ -137,7 +142,7 @@ function generateAngularJson() {
architect: {
build: {
options: {
outputPath: 'dist/ikachu'
outputPath: 'dist/' + PROJECT_NAME
}
}
}
Expand All @@ -148,79 +153,11 @@ function generateAngularJson() {
architect: {
build: {
options: {
outputPath: 'dist/ikachu'
outputPath: 'dist/' + OTHER_PROJECT_NAME
}
}
}
}
}
};
}

const initialAngularJson = `{
"defaultProject": "pie-ka-chu",
"projects": {
"pie-ka-chu": {
"projectType": "application",
"root": "pirojok",
"architect": {
"build": {
"options": {
"outputPath": "dist/ikachu"
}
},
"deploy": {
\"builder\": \"angular-cli-ghpages:deploy\",
"options": {}
}
}
},
"pi-catch-you": {
"projectType": "application",
"root": "pirojok",
"architect": {
"build": {
"options": {
"outputPath": "dist/ikachu"
}
}
}
}
}
}`;

const overwriteAngularJson = `{
"defaultProject": "pie-ka-chu",
"projects": {
"pie-ka-chu": {
"projectType": "application",
"root": "pirojok",
"architect": {
"build": {
"options": {
"outputPath": "dist/ikachu"
}
},
"deploy": {
\"builder\": \"angular-cli-ghpages:deploy\",
"options": {}
}
}
},
"pi-catch-you": {
"projectType": "application",
"root": "pirojok",
"architect": {
"build": {
"options": {
"outputPath": "dist/ikachu"
}
},
"deploy": {
"builder": "angular-cli-ghpages:deploy",
"options": {}
}
}
}
}
}`;
Loading