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

feat: adds schematics for service #9945

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ tmp/
**/*.snap
**/.nvmrc
**/.browserslistrc
**/schematics/
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ tmp/
**/*.sh
**/*.snap
**/.nvmrc
**/schematics/
10 changes: 10 additions & 0 deletions libs/ng-mocks/schematics/src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

# Outputs
**/*.js
**/*.js.map
**/*.d.ts
package-lock.json

# Misc
node_modules/

28 changes: 28 additions & 0 deletions libs/ng-mocks/schematics/src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Getting Started With Schematics

This repository is a basic Schematic implementation that serves as a starting point to create and publish Schematics to NPM.

### Testing

To test locally, install `@angular-devkit/schematics-cli` globally and use the `schematics` command line tool. That tool acts the same as the `generate` command of the Angular CLI, but also has a debug mode.

Check the documentation with

```bash
schematics --help
```

### Unit Testing

`npm run test` will run the unit tests, using Jasmine as a runner and test framework.

### Publishing

To publish, simply do:

```bash
npm run build
npm publish
```

That's it!
11 changes: 11 additions & 0 deletions libs/ng-mocks/schematics/src/collection.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
"extends": ["@schematics/angular"],
"schematics": {
"ng-mocks-service": {
"description": "ngMocks service schematic",
"factory": "./ng-mocks/index#ngMocksServiceSchematic",
"schema": "./ng-mocks/service-schema.json"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { MockBuilder,MockedComponentFixture, MockInstance, MockRender, } from 'ng-mocks';

import { <%= classify(name)%>Service } from './<%= dasherize(name)%>.service';

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Identifier expected.

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Type expected.

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Expression expected.

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Declaration or statement expected.

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Unexpected keyword or identifier.

describe('<%= classify(name)%>Service', () => {
let service: <%= classify(name)%>Service;

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Type parameter declaration expected.

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: '>' expected.

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: '=>' expected.

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Expression expected.
let fixture: MockedComponentFixture<<%= classify(name)%>Service>;

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Type parameter declaration expected.

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: ',' expected.

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Expression expected.

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Expression expected.

MockInstance.scope();

beforeEach(() => MockBuilder(<%= classify(name)%>Service));

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Type expected.

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Expression expected.

beforeEach(() => {
fixture = MockRender(<%= classify(name)%>Service);

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Type expected.

Check notice

Code scanning / CodeQL

Syntax error Note test

Error: Expression expected.
service = fixture.point.componentInstance;
})

it('should be created', () => {
expect(service).toBeTruthy();
});
});
45 changes: 45 additions & 0 deletions libs/ng-mocks/schematics/src/ng-mocks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
apply,
chain,
externalSchematic,
mergeWith,
move,
template,
url,
MergeStrategy,
Rule,
SchematicContext,
Tree,
noop,
} from '@angular-devkit/schematics';
import {strings, normalize } from '@angular-devkit/core';

import { ServiceOptions } from './schema';
import { ensurePath } from './utils/ensure-path.helper';

export function ngMocksServiceSchematic(options: ServiceOptions): Rule {
return chain([
externalSchematic(
'@schematics/angular',
'service',
{ ...options, skipTests: true }
),
async(tree: Tree, _context: SchematicContext): Promise<Rule> => {
if (options.skipTests) {
return noop;
}

await ensurePath(tree, options);
const movePath = normalize(options.path || '');
const specTemplateRule = apply(url('./files/service'), [
template({
...strings,
...options,
}),
move(movePath),
]);

return mergeWith(specTemplateRule, MergeStrategy.Default);
}
]);
}
14 changes: 14 additions & 0 deletions libs/ng-mocks/schematics/src/ng-mocks/index_spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Tree } from '@angular-devkit/schematics';
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
import * as path from 'path';

const collectionPath = path.join(__dirname, '../collection.json');

describe('ng-mocks-service', () => {
it('works', async () => {
const runner = new SchematicTestRunner('schematics', collectionPath);
const tree = await runner.runSchematic('ng-mocks-service', {}, Tree.empty());

expect(tree.files).toEqual([]);
});
});
9 changes: 9 additions & 0 deletions libs/ng-mocks/schematics/src/ng-mocks/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface ServiceOptions {
// -------------------- START of Angular schematics default options --------------------
name: string;
path?: string;
project?: string;
skipTests?: boolean;
flat?: boolean;
// -------------------- END of Angular schematics default options --------------------
}
39 changes: 39 additions & 0 deletions libs/ng-mocks/schematics/src/ng-mocks/service-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"$schema": "http://json-schema.org/schema",
"$id": "ngMocksSchematicsAngularService",
"title": "Angular Service with ngMocks schema",
"type": "object",
"description": "Creates a new generic service in the given or default project",
"properties": {
"name": {
"description": "The name of the service.",
"type": "string"
},
"path": {
"type": "string",
"format": "path",
"description": "The path to create the service.",
"visible": false
},
"project": {
"type": "string",
"description": "The name of the project.",
"$default": {
"$source": "projectName"
}
},
"skipTests": {
"type": "boolean",
"description": "When true, does not create \"spec.ts\" test files for the new service.",
"default": false
},
"flat": {
"type": "boolean",
"default": true,
"description": "When true (the default), creates files at the top level of the project."
}
},
"required": [
"name"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Tree } from '@angular-devkit/schematics';
import { buildDefaultPath, getWorkspace } from '@schematics/angular/utility/workspace';
import { parseName } from '@schematics/angular/utility/parse-name';

export async function ensurePath(tree: Tree, options: any): Promise<void> {
const workspace = await getWorkspace(tree);

if (!options.project) {
options.project = workspace.projects.keys().next().value;
}

const project = workspace.projects.get(options.project as string);

if (options.path === undefined && project) {
options.path = buildDefaultPath(project);
}

const parsedPath = parseName(options.path as string, options.name);
options.name = parsedPath.name;
options.path = parsedPath.path;
}
27 changes: 27 additions & 0 deletions libs/ng-mocks/schematics/src/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "ng-mocks-schematics",
"version": "0.0.0",
"description": "A blank schematics",
"scripts": {
"build": "tsc -p tsconfig.json",
"build:watch": "tsc -p tsconfig.json --watch",
"test": "npm run build && jasmine src/**/*_spec.js"
},
"keywords": [
"schematics"
],
"author": "",
"license": "MIT",
"schematics": "./src/collection.json",
"dependencies": {
"@angular-devkit/core": "^18.2.3",
"@angular-devkit/schematics": "^18.2.3",
"@schematics/angular": "^18.2.3",
"typescript": "~5.5.2"
},
"devDependencies": {
"@types/jasmine": "~5.1.0",
"@types/node": "^18.18.0",
"jasmine": "^5.0.0"
}
}
24 changes: 24 additions & 0 deletions libs/ng-mocks/schematics/src/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"baseUrl": "tsconfig",
"lib": ["es2018", "dom"],
"declaration": true,
"module": "commonjs",
"moduleResolution": "node",
"noEmitOnError": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitThis": true,
"noUnusedParameters": true,
"noUnusedLocals": true,
"rootDir": "src/",
"skipDefaultLibCheck": true,
"skipLibCheck": true,
"sourceMap": true,
"strictNullChecks": true,
"target": "es6",
"types": ["jasmine", "node"]
},
"include": ["src/**/*"],
"exclude": ["src/*/files/**/*"]
}