"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
const schematics_1 = require("@angular-devkit/schematics");
const testing_1 = require("@angular-devkit/schematics/testing");
const test_1 = require("@schematics/angular/utility/test");
describe('Add {N} schematic', () => {
    const schematicRunner = new testing_1.SchematicTestRunner('@nativescript/schematics', path_1.resolve(__dirname, '../collection.json'));
    const project = 'foo';
    const defaultOptions = {
        project,
        nsExtension: 'tns',
        webExtension: '',
        sample: false,
        skipAutoGeneratedComponent: false,
    };
    let appTree;
    beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
        appTree = new testing_1.UnitTestTree(new schematics_1.HostTree());
        appTree = yield setupProject(appTree, schematicRunner, project);
    }));
    describe('when using the default options', () => {
        beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
            appTree = yield schematicRunner.runSchematicAsync('add-ns', defaultOptions, appTree)
                .toPromise();
        }));
        it('should add dependency to NativeScript schematics', () => {
            const configFile = '/angular.json';
            expect(appTree.files).toContain(configFile);
            const configFileContent = JSON.parse(test_1.getFileContent(appTree, configFile));
            expect(configFileContent.cli.defaultCollection).toEqual('@nativescript/schematics');
        });
        it('should add {N} specific files', () => {
            const files = appTree.files;
            expect(files).toContain('/ngcc.config.js');
            expect(files).toContain('/nsconfig.json');
            expect(files).toContain('/tsconfig.tns.json');
            expect(files).toContain('/src/app.css');
            expect(files).toContain('/src/main.tns.ts');
            expect(files).toContain('/src/package.json');
            expect(files).toContain('/src/app/app.module.tns.ts');
            expect(files).toContain('/src/app/app.component.tns.ts');
            expect(files).toContain('/src/app/app.component.tns.html');
        });
        it('should add native app resources', () => {
            expect(appTree.files).toContain('/App_Resources/Android/app.gradle');
            expect(appTree.files).toContain('/App_Resources/iOS/Info.plist');
        });
        it('should add {N} specifics to gitignore', () => {
            const gitignorePath = '/.gitignore';
            expect(appTree.files).toContain(gitignorePath);
            const gitignore = test_1.getFileContent(appTree, gitignorePath);
            expect(gitignore.includes('node_modules/')).toBeTruthy();
            expect(gitignore.includes('platforms/')).toBeTruthy();
            expect(gitignore.includes('hooks/')).toBeTruthy();
            expect(gitignore.includes('src/**/*.js')).toBeTruthy();
        });
        it('should add all required dependencies to the package.json', () => {
            const packageJsonPath = '/package.json';
            expect(appTree.files).toContain(packageJsonPath);
            const packageJson = JSON.parse(test_1.getFileContent(appTree, packageJsonPath));
            const { dependencies, devDependencies } = packageJson;
            expect(dependencies).toBeDefined();
            expect(dependencies['@nativescript/angular']).toBeDefined();
            expect(dependencies['@nativescript/theme']).toBeDefined();
            expect(dependencies['@nativescript/core']).toBeDefined();
            expect(dependencies['reflect-metadata']).toBeDefined();
            expect(devDependencies['nativescript-dev-webpack']).toBeDefined();
            expect(devDependencies['@nativescript/schematics']).toBeDefined();
            expect(devDependencies['@nativescript/tslint-rules']).toBeDefined();
        });
        it('should add run scripts to the package json', () => {
            const packageJsonPath = '/package.json';
            expect(appTree.files).toContain(packageJsonPath);
            const packageJson = JSON.parse(test_1.getFileContent(appTree, packageJsonPath));
            const { scripts } = packageJson;
            expect(scripts).toBeDefined();
            expect(scripts.android).toEqual('tns run android --env.aot');
            expect(scripts.ios).toEqual('tns run ios --env.aot');
            expect(scripts.ngcc).toEqual('ngcc --properties es2015 module main --first-only');
            expect(scripts.postinstall).toEqual('npm run ngcc');
        });
        it('should add NativeScript key to the package json', () => {
            const packageJsonPath = '/package.json';
            expect(appTree.files).toContain(packageJsonPath);
            const packageJson = JSON.parse(test_1.getFileContent(appTree, packageJsonPath));
            const { nativescript } = packageJson;
            expect(nativescript).toBeDefined();
            expect(nativescript.id).toEqual('org.nativescript.ngsample');
        });
        it('should modify the tsconfig.app.json (web) to include files and path mappings', () => {
            const webTsConfigPath = '/tsconfig.app.json';
            expect(appTree.files).toContain(webTsConfigPath);
            const webTsconfig = JSON.parse(test_1.getFileContent(appTree, webTsConfigPath));
            const files = webTsconfig.files;
            expect(files).toBeDefined();
            expect(files.includes('src/main.ts')).toBeTruthy();
            expect(files.includes('src/polyfills.ts')).toBeTruthy();
            const paths = webTsconfig.compilerOptions.paths;
            expect(paths).toBeDefined();
            expect(paths['@src/*']).toBeDefined();
            const maps = paths['@src/*'];
            expect(maps).toContain('src/*.web');
            expect(maps).toContain('src/*');
        });
        it('should create the tsconfig.tns.json with files and path mappings', () => {
            const nsTsConfigPath = '/tsconfig.tns.json';
            expect(appTree.files).toContain(nsTsConfigPath);
            const nsTsConfig = JSON.parse(test_1.getFileContent(appTree, nsTsConfigPath));
            const files = nsTsConfig.files;
            expect(files).toBeDefined();
            expect(files).toContain('src/main.tns.ts');
            const paths = nsTsConfig.compilerOptions.paths;
            expect(paths).toBeDefined();
            expect(paths['@src/*']).toBeDefined();
            const maps = paths['@src/*'];
            expect(maps).toContain('src/*.tns.ts');
            expect(maps).toContain('src/*.ts');
        });
        it('should create the tsconfig.spec.json (web) with files', () => {
            const specTsConfigPath = '/tsconfig.spec.json';
            expect(appTree.files).toContain(specTsConfigPath);
            const specTsConfig = JSON.parse(test_1.getFileContent(appTree, specTsConfigPath));
            const files = specTsConfig.files;
            expect(files).toBeDefined();
            expect(files.includes('src/test.ts')).toBeTruthy();
            expect(files.includes('src/polyfills.ts')).toBeTruthy();
        });
        it('should modify the base tsconfig.json to include path mappings', () => {
            const baseTsConfigPath = '/tsconfig.json';
            expect(appTree.files).toContain(baseTsConfigPath);
            const baseTsConfig = JSON.parse(test_1.getFileContent(appTree, baseTsConfigPath));
            const paths = baseTsConfig.compilerOptions.paths;
            expect(paths).toBeDefined();
            expect(paths['@src/*']).toBeDefined();
            const maps = paths['@src/*'];
            expect(maps).toContain('src/*.android.ts');
            expect(maps).toContain('src/*.ios.ts');
            expect(maps).toContain('src/*.tns.ts');
            expect(maps).toContain('src/*.web.ts');
            expect(maps).toContain('src/*');
        });
        it('should modify tslint.json to include rule for using remapped imports', () => {
            const tsLintConfigPath = '/tslint.json';
            expect(appTree.files).toContain(tsLintConfigPath);
            const tsLintConfig = JSON.parse(test_1.getFileContent(appTree, tsLintConfigPath));
            const { extends: tsLintExtends, rules: tsLintRules } = tsLintConfig;
            expect(tsLintExtends).toEqual(jasmine.any(Array));
            expect(tsLintExtends).toContain('@nativescript/tslint-rules');
            expect(tsLintRules).toEqual(jasmine.any(Object));
            expect(Object.keys(tsLintRules)).toContain('prefer-mapped-imports');
            const rule = tsLintRules['prefer-mapped-imports'];
            const ruleOptions = rule[1];
            const actualBaseUrl = ruleOptions['base-url'];
            expect(actualBaseUrl).toEqual('./');
        });
        it('should generate a sample shared component', () => {
            const { files } = appTree;
            const appRoutingModuleContent = appTree.readContent('/src/app/app-routing.module.tns.ts');
            const appComponentTemplate = appTree.readContent('/src/app/app.component.tns.html');
            expect(files).toContain('/src/app/auto-generated/auto-generated.component.ts');
            expect(files).toContain('/src/app/auto-generated/auto-generated.component.html');
            expect(files).toContain('/src/app/auto-generated/auto-generated.component.tns.html');
            expect(appRoutingModuleContent).toMatch(/import { AutoGeneratedComponent } from '@src\/app\/auto-generated\/auto-generated.component'/);
            expect(appRoutingModuleContent).toMatch(/{\s+path: 'auto-generated',\s+component: AutoGeneratedComponent,\s+},/g);
            expect(appComponentTemplate).not.toContain('<Label text="Entry Component works" textWrap="true"></Label>');
        });
    });
    describe('when the skipAutoGeneratedComponent flag is raised', () => {
        beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
            const options = Object.assign(Object.assign({}, defaultOptions), { skipAutoGeneratedComponent: true });
            appTree = yield schematicRunner.runSchematicAsync('add-ns', options, appTree).toPromise();
        }));
        it('should not add a sample shared component', () => {
            const { files } = appTree;
            const appRoutingModuleContent = appTree.readContent('/src/app/app-routing.module.tns.ts');
            const appComponentTemplate = appTree.readContent('/src/app/app.component.tns.html');
            expect(files).not.toContain('/src/app/auto-generated/auto-generated.component.css');
            expect(files).not.toContain('/src/app/auto-generated/auto-generated.component.html');
            expect(files).not.toContain('/src/app/auto-generated/auto-generated.component.ts');
            expect(appRoutingModuleContent).not.toMatch(/import { AutoGeneratedComponent } from '.\/auto-generated\/auto-generated.component'/);
            expect(appRoutingModuleContent).toContain('export const routes: Routes = []');
            expect(appComponentTemplate).toContain('<Label text="Entry Component works" textWrap="true"></Label>');
        });
    });
    describe('when the sample flag is raised', () => {
        beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
            const options = Object.assign(Object.assign({}, defaultOptions), { sample: true });
            appTree = yield schematicRunner.runSchematicAsync('add-ns', options, appTree).toPromise();
        }));
        it('should generate sample files', () => {
            const { files } = appTree;
            expect(files).toContain('/src/app/barcelona/barcelona.common.ts');
            expect(files).toContain('/src/app/barcelona/barcelona.module.ts');
            expect(files).toContain('/src/app/barcelona/barcelona.module.tns.ts');
            expect(files).toContain('/src/app/barcelona/player.service.ts');
            expect(files).toContain('/src/app/barcelona/player.model.ts');
            expect(files).toContain('/src/app/barcelona/players/players.component.ts');
            expect(files).toContain('/src/app/barcelona/players/players.component.html');
            expect(files).toContain('/src/app/barcelona/players/players.component.tns.html');
            expect(files).toContain('/src/app/barcelona/player-detail/player-detail.component.ts');
            expect(files).toContain('/src/app/barcelona/player-detail/player-detail.component.html');
            expect(files).toContain('/src/app/barcelona/player-detail/player-detail.component.tns.html');
        });
        it('should configure routing for redirection', () => {
            const appRoutingModuleContent = appTree.readContent('/src/app/app-routing.module.tns.ts');
            expect(appRoutingModuleContent).toMatch(/{\s+path: '',\s+redirectTo: '\/players',\s+pathMatch: 'full',\s+},/g);
        });
    });
});
function setupProject(tree, schematicRunner, name) {
    return __awaiter(this, void 0, void 0, function* () {
        tree = yield schematicRunner.runExternalSchematicAsync('@schematics/angular', 'workspace', {
            name: 'workspace',
            version: '8.0.0',
            newProjectRoot: '',
        }).toPromise();
        tree = yield schematicRunner.runExternalSchematicAsync('@schematics/angular', 'application', {
            name,
            projectRoot: '',
        }, tree).toPromise();
        return tree;
    });
}
//# sourceMappingURL=index_spec.js.map