"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
const testing_1 = require("@angular-devkit/schematics/testing");
const schematics_1 = require("@angular-devkit/schematics");
const test_1 = require("@schematics/angular/utility/test");
const ast_utils_1 = require("@schematics/angular/utility/ast-utils");
const utils_1 = require("../utils");
const test_utils_1 = require("../test-utils");
const ts_utils_1 = require("../ts-utils");
describe('Migrate module Schematic', () => {
    const project = 'some-project';
    const moduleName = 'admin';
    const defaultOptions = {
        name: moduleName,
        project,
        style: true
    };
    const nsModulePath = '/src/app/admin/admin.module.tns.ts';
    const webModulePath = '/src/app/admin/admin.module.ts';
    const schematicRunner = new testing_1.SchematicTestRunner('nativescript-schematics', path_1.join(__dirname, '../collection.json'));
    let appTree;
    beforeEach(() => __awaiter(this, void 0, void 0, function* () {
        appTree = new testing_1.UnitTestTree(new schematics_1.HostTree);
        appTree = yield setupProject(appTree, schematicRunner, project, moduleName);
    }));
    describe('When the name of existing module is provided', () => {
        beforeEach(() => __awaiter(this, void 0, void 0, function* () {
            const options = Object.assign({}, defaultOptions);
            appTree = yield schematicRunner.runSchematicAsync('migrate-module', options, appTree)
                .toPromise();
        }));
        it('should create a mobile module file', () => {
            expect(appTree.files).toContain('/src/app/admin/admin.module.tns.ts');
        });
        it('should create a common file', () => {
            expect(appTree.files).toContain('/src/app/admin/admin.common.ts');
        });
    });
    describe('When a custom mobile extension is provided', () => {
        beforeEach(() => __awaiter(this, void 0, void 0, function* () {
            const options = Object.assign({}, defaultOptions, { nsext: 'mobile' });
            appTree = yield schematicRunner.runSchematicAsync('migrate-module', options, appTree)
                .toPromise();
        }));
        it('should create the module file with that extension', () => {
            expect(appTree.files).toContain('/src/app/admin/admin.module.mobile.ts');
        });
        it('should create a common file without the extension', () => {
            expect(appTree.files).toContain('/src/app/admin/admin.common.ts');
        });
    });
    describe('When the module has a component', () => {
        let originalWebModuleContent;
        beforeEach(() => __awaiter(this, void 0, void 0, function* () {
            appTree = yield schematicRunner.runSchematicAsync('component', {
                name: 'a',
                module: moduleName,
                project,
                nativescript: false,
            }, appTree)
                .toPromise();
            originalWebModuleContent = test_1.getFileContent(appTree, webModulePath);
            const options = Object.assign({}, defaultOptions);
            appTree = yield schematicRunner.runSchematicAsync('migrate-module', options, appTree)
                .toPromise();
        }));
        it('should keep the web module untouched', () => {
            expect(appTree.files).toContain(webModulePath);
            expect(test_1.getFileContent(appTree, webModulePath)).toEqual(originalWebModuleContent);
        });
        it('should declare the component in the mobile module', () => {
            expect(appTree.files).toContain(nsModulePath);
            const content = test_1.getFileContent(appTree, nsModulePath);
            const matcher = test_utils_1.isInModuleMetadata('AdminModule', 'declarations', 'AComponent', true);
            expect(content).toMatch(matcher);
        });
        it('should import the component in the mobile module using @src', () => {
            const source = ts_utils_1.getSourceFile(appTree, nsModulePath);
            const imports = ts_utils_1.findImports('AComponent', source);
            expect(imports.length).toEqual(1);
            expect(imports[0].getFullText()).toContain(`@src/app/a/a.component`);
        });
    });
    describe('When the module has a provider', () => {
        const provider = 'SomeProvider';
        let originalWebModuleContent;
        beforeEach(() => __awaiter(this, void 0, void 0, function* () {
            appTree = insertProviderInMetadata(appTree, webModulePath, provider);
            originalWebModuleContent = test_1.getFileContent(appTree, webModulePath);
            const options = Object.assign({}, defaultOptions);
            appTree = yield schematicRunner.runSchematicAsync('migrate-module', options, appTree)
                .toPromise();
        }));
        it('should keep the web module untouched', () => {
            expect(appTree.files).toContain(webModulePath);
            expect(test_1.getFileContent(appTree, webModulePath)).toEqual(originalWebModuleContent);
        });
        it('should provide the service in the mobile module', () => {
            expect(appTree.files).toContain(nsModulePath);
            const content = test_1.getFileContent(appTree, nsModulePath);
            const matcher = test_utils_1.isInModuleMetadata('AdminModule', 'providers', provider, true);
            expect(content).toMatch(matcher);
        });
    });
});
const setupProject = (appTree, schematicRunner, project, moduleName) => __awaiter(this, void 0, void 0, function* () {
    appTree = yield schematicRunner.runSchematicAsync('shared', {
        name: project,
        prefix: '',
        sourceDir: 'src',
        style: 'css',
        theme: true,
        sample: false,
    }, appTree)
        .toPromise();
    appTree = utils_1.moveToRoot(schematicRunner, appTree, project);
    appTree = yield schematicRunner.runSchematicAsync('module', {
        name: moduleName,
        nativescript: false,
        web: true,
        project,
    }, appTree)
        .toPromise();
    return appTree;
});
const insertProviderInMetadata = (tree, path, providerName) => {
    const source = ts_utils_1.getSourceFile(tree, path);
    const recorder = tree.beginUpdate(path);
    // Insert a provider in the NgModule metadata
    const metadataChange = ast_utils_1.addSymbolToNgModuleMetadata(source, path, 'providers', providerName, 'somepath');
    metadataChange.forEach((change) => recorder.insertRight(change.pos, change.toAdd));
    tree.commitUpdate(recorder);
    return tree;
};
//# sourceMappingURL=index_spec.js.map