Exemple #1
0
 it('should add router module to client app module', () => {
   const tree = schematicRunner.runSchematic('appShell', defaultOptions, appTree);
   const filePath = '/projects/bar/src/app/app.module.ts';
   const content = tree.readContent(filePath);
   expect(content).toMatch(/import { RouterModule } from \'@angular\/router\';/);
 });
Exemple #2
0
 it('should create the new config file', () => {
   tree.create(oldConfigPath, JSON.stringify(baseConfig, null, 2));
   tree = schematicRunner.runSchematic('migration-01', defaultOptions, tree);
   expect(tree.exists(configPath)).toEqual(true);
 });
Exemple #3
0
 it('should move styleExt to component', () => {
   tree.create(oldConfigPath, JSON.stringify(baseConfig, null, 2));
   tree = schematicRunner.runSchematic('migration-01', defaultOptions, tree);
   const config = getSchematicConfig(tree, 'component');
   expect(config.styleext).toEqual('css');
 });
Exemple #4
0
describe('NgAlainSchematic: plugin', () => {
  let runner: SchematicTestRunner;
  let tree: UnitTestTree;

  describe(`[g2]`, () => {
    beforeEach(() => ({ runner, tree } = createAlainApp({ g2: true })));

    describe('when add', () => {
      it(`should add dependencies`, () => {
        const json = JSON.parse(tree.readContent('package.json'));
        expect(json.dependencies['@antv/g2']).toBeDefined();
      });

      it(`should add scripts`, () => {
        const json = JSON.parse(tree.readContent('angular.json'));
        const scripts: string[] = json.projects.foo.architect.build.options.scripts || [];
        expect(scripts.filter(w => w.includes('g2')).length).toBeGreaterThan(0);
      });
    });

    describe('when remove', () => {
      beforeEach(() =>
        runner.runSchematic('plugin', { name: 'g2', type: 'remove' }, tree));

      it(`should add dependencies`, () => {
        const json = JSON.parse(tree.readContent('package.json'));
        expect(json.dependencies['@antv/g2']).not.toBeDefined();
      });

      it(`should add scripts`, () => {
        const json = JSON.parse(tree.readContent('angular.json'));
        const scripts: string[] = json.projects.foo.architect.build.options.scripts || [];
        expect(scripts.filter(w => w.includes('g2')).length).toBe(0);
      });
    });
  });

  describe(`[codeStyle]`, () => {
    beforeEach(() => ({ runner, tree } = createAlainApp({ codeStyle: true })));

    describe('when add', () => {
      it(`should add precommit`, () => {
        const json = JSON.parse(tree.readContent('package.json'));
        expect(json.scripts.precommit).not.toBeUndefined();
      });
    });

    describe('when remove', () => {
      beforeEach(() =>
        runner.runSchematic(
          'plugin',
          { name: 'codeStyle', type: 'remove' },
          tree,
        ));

      it(`should remove precommit`, () => {
        const json = JSON.parse(tree.readContent('package.json'));
        expect(json.scripts.precommit).toBeUndefined();
      });
    });
  });

  describe(`[npm]`, () => {
    const npmrc = '/.npmrc';

    beforeEach(() => ({ runner, tree } = createAlainApp({ npm: true })));

    describe('when add', () => {
      it(`should add .npmrc`, () => {
        expect(tree.exists(npmrc)).toBe(true);
        expect(tree.readContent(npmrc)).toContain('taobao.org');
      });
    });

    describe('when remove', () => {
      beforeEach(() =>
        runner.runSchematic(
          'plugin',
          { name: 'npm', type: 'remove' },
          tree,
        ));

      it(`should remove .npmrc`, () => {
        expect(tree.exists(npmrc)).toBe(false);
      });
    });
  });

  describe(`[yarn]`, () => {
    beforeEach(() => ({ runner, tree } = createAlainApp({ yarn: true })));

    describe('when add', () => {
      it(`should add devDependencies`, () => {
        const json = JSON.parse(tree.readContent('package.json'));
        expect(json.devDependencies['less']).not.toBeUndefined();
        expect(json.devDependencies['less-loader']).not.toBeUndefined();
      });
    });

    describe('when remove', () => {
      beforeEach(() =>
        runner.runSchematic(
          'plugin',
          { name: 'yarn', type: 'remove' },
          tree,
        ));

      it(`should remove devDependencies`, () => {
        const json = JSON.parse(tree.readContent('package.json'));
        expect(json.devDependencies['less']).toBeUndefined();
        expect(json.devDependencies['less-loader']).toBeUndefined();
      });
    });
  });
});
Exemple #5
0
  it('fails with an invalid version', done => {
    const rule = updatePackageJson(['@angular/core'], 'babababarbaraann');

    schematicRunner.callRule(rule, inputTree)
      .subscribe(() => done.fail('version should not match.'), () => done());
  });
Exemple #6
0
 function runSetupSchematic(options: Partial<NgAddOptions> = {}) {
   return runner.runSchematic('setup', options, appTree);
 }
Exemple #7
0
describe('ng-add-schematic', () => {
  const collectionPath = join(__dirname, '../collection.json');
  const schematicRunner = new SchematicTestRunner('schematics', collectionPath);
  const projectPath = getTestProjectPath();

  let appTree: UnitTestTree;

  beforeEach(() => {
    appTree = createWorkspace(schematicRunner, appTree);
  });

  it('should update package.json', () => {
    const tree = schematicRunner.runSchematic('ng-add', {}, appTree);
    const packageJson = JSON.parse(getFileContent(tree, '/package.json'));

    expect(packageJson.dependencies['@angular/forms']).toBeDefined();
    expect(packageJson.dependencies['@ngx-formly/core']).toBeDefined();
  });

  it('should not add a theme by default to package.json', () => {
    const tree = schematicRunner.runSchematic('ng-add', {}, appTree);
    const packageJson = JSON.parse(getFileContent(tree, '/package.json'));

    // @TODO: list of themes should probably be retrieved from some config file
    ['material', 'bootstrap', 'ionic', 'primeng', 'kendo'].forEach(theme => {
      expect(packageJson.dependencies[`@ngx-formly/${theme}`]).toBeUndefined();
    });
  });

  it('should skip package.json update', () => {
    const options = { skipPackageJson: true } as Schema;
    const tree = schematicRunner.runSchematic('ng-add', options, appTree);
    const packageJson = JSON.parse(getFileContent(tree, '/package.json'));

    expect(packageJson.dependencies['@ngx-formly/core']).toBeUndefined();
  });

  it('should add to root app module', () => {
    const tree = schematicRunner.runSchematic('ng-add', {}, appTree);

    const content = tree.readContent(`${projectPath}/src/app/app.module.ts`);
    expect(content).toMatch(
      // tslint:disable-next-line:trailing-comma
      /import { FormlyModule } from '@ngx-formly\/core';/
    );
    expect(content).toMatch(
      // tslint:disable-next-line:trailing-comma
      /FormlyModule.forRoot\(\)/
    );
    expect(content).toMatch(
      // tslint:disable-next-line:trailing-comma
      /import { ReactiveFormsModule } from '@angular\/forms';/
    );
    expect(content).toMatch(
      // tslint:disable-next-line:trailing-comma
      /ReactiveFormsModule,/
    );
  });

  it('should add UI theme to package.json', () => {
    const tree = schematicRunner.runSchematic('ng-add', {
      uiTheme: 'bootstrap',
    }, appTree);

    const packageJson = JSON.parse(getFileContent(tree, '/package.json'));

    expect(packageJson.dependencies['@ngx-formly/bootstrap']).toBeDefined();
  });

  it('should add UI theme to root app module', () => {
    const tree = schematicRunner.runSchematic('ng-add', {
      uiTheme: 'bootstrap',
    }, appTree);

    const content = tree.readContent(`${projectPath}/src/app/app.module.ts`);
    expect(content).toMatch(
      // tslint:disable-next-line:trailing-comma
      /import { FormlyBootstrapModule } from '@ngx-formly\/bootstrap';/
    );
    expect(content).toMatch(
      // tslint:disable-next-line:trailing-comma
      /FormlyBootstrapModule/
    );
  });

  it('should add to any module', () => {
    const fooModule = `${projectPath}/src/app/foo.module.ts`;

    appTree.create(fooModule, `
      import { NgModule } from '@angular/core';
      import { CommonModule } from '@angular/common';

      @NgModule({
        imports: [],
        declarations: []
      })
      export class FooModule { }
    `);

    const tree = schematicRunner.runSchematic('ng-add', {
      module: 'foo.module.ts',
    }, appTree);

    const content = tree.readContent(fooModule);

    expect(content).toMatch(
      // tslint:disable-next-line:trailing-comma
      /import { FormlyModule } from '@ngx-formly\/core';/
    );
    expect(content).toMatch(
      // tslint:disable-next-line:trailing-comma
      /FormlyModule.forRoot\(\)/
    );
    expect(content).toMatch(
      // tslint:disable-next-line:trailing-comma
      /import { ReactiveFormsModule } from '@angular\/forms';/
    );
    expect(content).toMatch(
      // tslint:disable-next-line:trailing-comma
      /ReactiveFormsModule,/
    );
  });
});
Exemple #8
0
 it('should not create Bazel workspace file', () => {
   host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
   const {files} = host;
   expect(files).not.toContain('/WORKSPACE');
   expect(files).not.toContain('/BUILD.bazel');
 });
Exemple #9
0
describe('ng-add schematic', () => {

  const defaultOptions = {name: 'demo'};
  let host: UnitTestTree;
  let schematicRunner: SchematicTestRunner;

  beforeEach(() => {
    host = new UnitTestTree(new HostTree());
    host.create('package.json', JSON.stringify({
      name: 'demo',
      dependencies: {
        '@angular/core': '1.2.3',
        'rxjs': '~6.3.3',
      },
      devDependencies: {
        'typescript': '3.2.2',
      },
    }));
    host.create('tsconfig.json', JSON.stringify({
      compileOnSave: false,
      compilerOptions: {
        baseUrl: './',
        outDir: './dist/out-tsc',
      }
    }));
    host.create('angular.json', JSON.stringify({
      projects: {
        'demo': {
          architect: {
            build: {},
            serve: {},
            test: {},
            'extract-i18n': {
              builder: '@angular-devkit/build-angular:extract-i18n',
            },
          },
        },
        'demo-e2e': {
          architect: {
            e2e: {},
            lint: {
              builder: '@angular-devkit/build-angular:tslint',
            },
          },
        },
      },
    }));
    schematicRunner =
        new SchematicTestRunner('@angular/bazel', require.resolve('../collection.json'));
  });

  it('throws if package.json is not found', () => {
    expect(host.files).toContain('/package.json');
    host.delete('/package.json');
    expect(() => schematicRunner.runSchematic('ng-add', defaultOptions))
        .toThrowError('Could not find package.json');
  });

  it('throws if angular.json is not found', () => {
    expect(host.files).toContain('/angular.json');
    host.delete('/angular.json');
    expect(() => schematicRunner.runSchematic('ng-add', defaultOptions, host))
        .toThrowError('Could not find angular.json');
  });

  it('should add @angular/bazel to package.json dependencies', () => {
    host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
    const {files} = host;
    expect(files).toContain('/package.json');
    const content = host.readContent('/package.json');
    expect(() => JSON.parse(content)).not.toThrow();
    const json = JSON.parse(content);
    const core = '@angular/core';
    const bazel = '@angular/bazel';
    expect(Object.keys(json)).toContain('dependencies');
    expect(Object.keys(json)).toContain('devDependencies');
    expect(Object.keys(json.dependencies)).toContain(core);
    expect(Object.keys(json.devDependencies)).toContain(bazel);
    expect(json.dependencies[core]).toBe(json.devDependencies[bazel]);
  });

  it('should add @bazel/* dev dependencies', () => {
    host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
    const content = host.readContent('/package.json');
    const json = JSON.parse(content);
    const devDeps = Object.keys(json.devDependencies);
    expect(devDeps).toContain('@bazel/bazel');
    expect(devDeps).toContain('@bazel/ibazel');
    expect(devDeps).toContain('@bazel/karma');
  });

  it('should not create Bazel workspace file', () => {
    host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
    const {files} = host;
    expect(files).not.toContain('/WORKSPACE');
    expect(files).not.toContain('/BUILD.bazel');
  });

  it('should produce main.dev.ts and main.prod.ts for AOT', () => {
    host.create('/src/main.ts', 'generated by CLI');
    host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
    const {files} = host;
    // main.dev.ts and main.prod.ts are used by Bazel for AOT
    expect(files).toContain('/src/main.dev.ts');
    expect(files).toContain('/src/main.prod.ts');
    // main.ts is produced by original ng-add schematics
    // This file should be present for backwards compatibility.
    expect(files).toContain('/src/main.ts');
  });

  it('should not overwrite index.html with script tags', () => {
    host.create('/src/index.html', '<html>Hello World</html>');
    host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
    const {files} = host;
    expect(files).toContain('/src/index.html');
    const content = host.readContent('/src/index.html');
    expect(content).not.toMatch('<script src="/zone.min.js"></script>');
    expect(content).not.toMatch('<script src="/bundle.min.js"></script>');
  });

  it('should generate main.dev.ts and main.prod.ts', () => {
    host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
    const {files} = host;
    expect(files).toContain('/src/main.dev.ts');
    expect(files).toContain('/src/main.prod.ts');
  });

  it('should overwrite .gitignore for bazel-out directory', () => {
    host.create('.gitignore', '\n# compiled output\n');
    host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
    const {files} = host;
    expect(files).toContain('/.gitignore');
    const content = host.readContent('/.gitignore');
    expect(content).toMatch('\n# compiled output\n/bazel-out\n');
  });

  it('should create a backup for original angular.json', () => {
    expect(host.files).toContain('/angular.json');
    const original = host.readContent('/angular.json');
    host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
    expect(host.files).toContain('/angular.json.bak');
    const content = host.readContent('/angular.json.bak');
    expect(content.startsWith('// This is a backup file')).toBe(true);
    expect(content).toMatch(original);
  });

  it('should update angular.json to use Bazel builder', () => {
    host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
    const {files} = host;
    expect(files).toContain('/angular.json');
    const content = host.readContent('/angular.json');
    expect(() => JSON.parse(content)).not.toThrow();
    const json = JSON.parse(content);
    const demo = json.projects.demo;
    const demo_e2e = json.projects['demo-e2e'];
    const {build, serve, test} = demo.architect;
    expect(build.builder).toBe('@angular/bazel:build');
    expect(serve.builder).toBe('@angular/bazel:build');
    expect(test.builder).toBe('@angular/bazel:build');
    const {e2e, lint} = demo_e2e.architect;
    expect(e2e.builder).toBe('@angular/bazel:build');
    // it should leave non-Bazel commands unmodified
    expect(demo.architect['extract-i18n'].builder)
        .toBe('@angular-devkit/build-angular:extract-i18n');
    expect(lint.builder).toBe('@angular-devkit/build-angular:tslint');
  });

  it('should create a backup for original tsconfig.json', () => {
    expect(host.files).toContain('/tsconfig.json');
    const original = host.readContent('/tsconfig.json');
    host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
    expect(host.files).toContain('/tsconfig.json.bak');
    const content = host.readContent('/tsconfig.json.bak');
    expect(content.startsWith('// This is a backup file')).toBe(true);
    expect(content).toMatch(original);
  });

  it('should remove Bazel-controlled options from tsconfig.json', () => {
    host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
    expect(host.files).toContain('/tsconfig.json');
    const content = host.readContent('/tsconfig.json');
    expect(() => JSON.parse(content)).not.toThrow();
    expect(JSON.parse(content)).toEqual({
      compileOnSave: false,
      compilerOptions: {
        outDir: './dist/out-tsc',
      }
    });
  });

  describe('rxjs', () => {
    const cases = [
      // version|upgrade
      ['6.3.3', true],
      ['~6.3.3', true],
      ['^6.3.3', true],
      ['~6.3.11', true],
      ['6.4.0', false],
      ['~6.4.0', false],
      ['~6.4.1', false],
      ['6.5.0', false],
      ['~6.5.0', false],
      ['^6.5.0', false],
      ['~7.0.1', false],
    ];
    for (const [version, upgrade] of cases) {
      it(`should ${upgrade ? '' : 'not '}upgrade v${version}')`, () => {
        host.overwrite('package.json', JSON.stringify({
          name: 'demo',
          dependencies: {
            '@angular/core': '1.2.3',
            'rxjs': version,
          },
          devDependencies: {
            'typescript': '3.2.2',
          },
        }));
        host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
        expect(host.files).toContain('/package.json');
        const content = host.readContent('/package.json');
        const json = JSON.parse(content);
        if (upgrade) {
          expect(json.dependencies.rxjs).toBe('~6.4.0');
        } else {
          expect(json.dependencies.rxjs).toBe(version);
        }
      });
    }
  });

  it('should add a postinstall step to package.json', () => {
    host = schematicRunner.runSchematic('ng-add', defaultOptions, host);
    expect(host.files).toContain('/package.json');
    const content = host.readContent('/package.json');
    const json = JSON.parse(content);
    expect(json.scripts.postinstall).toBe('ngc -p ./angular-metadata.tsconfig.json');
  });
});
 it('requires required option', () => {
   // We test that
   const runner = new SchematicTestRunner('schematics', collectionPath);
   expect(() => runner.runSchematic('my-full-schematic', {}, Tree.empty())).toThrow();
 });