"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
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 internal_1 = require("../../internal");
const Storage_1 = require("../../Storage");
const testHelper_1 = require("../testHelper");
/**
 * Testing loading imports on a cdm file
 */
// tslint:disable-next-line: max-func-body-length
describe('Cdm/ImportsTest', () => {
    const testsSubpath = 'Cdm/Imports';
    /**
     * Does not fail with a missing import
     */
    it('TestEntityWithMissingImport', () => __awaiter(void 0, void 0, void 0, function* () {
        const expectedLogCodes = new Set([internal_1.cdmLogCode.ErrPersistFileReadFailure, internal_1.cdmLogCode.WarnResolveImportFailed, internal_1.cdmLogCode.WarnDocImportNotLoaded]);
        const cdmCorpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestEntityWithMissingImport', undefined, false, expectedLogCodes);
        const resOpt = new internal_1.resolveOptions();
        resOpt.importsLoadStrategy = internal_1.importsLoadStrategy.load;
        const doc = yield cdmCorpus.fetchObjectAsync('local:/missingImport.cdm.json', null, resOpt);
        expect(doc)
            .not
            .toBeUndefined();
        expect(doc.imports.length)
            .toBe(1);
        expect(doc.imports.allItems[0].corpusPath)
            .toBe('missing.cdm.json');
        expect((doc.imports.allItems[0]).document)
            .toBeUndefined();
    }));
    /**
     * Does not fail with a missing nested import
     */
    it('TestEntityWithMissingNestedImportsAsync', () => __awaiter(void 0, void 0, void 0, function* () {
        const expectedLogCodes = new Set([internal_1.cdmLogCode.ErrPersistFileReadFailure, internal_1.cdmLogCode.WarnResolveImportFailed, internal_1.cdmLogCode.WarnDocImportNotLoaded]);
        const cdmCorpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestEntityWithMissingNestedImportsAsync', undefined, false, expectedLogCodes);
        const resOpt = new internal_1.resolveOptions();
        resOpt.importsLoadStrategy = internal_1.importsLoadStrategy.load;
        const doc = yield cdmCorpus.fetchObjectAsync('local:/missingNestedImport.cdm.json', null, resOpt);
        expect(doc)
            .not
            .toBeUndefined();
        expect(doc.imports.length)
            .toBe(1);
        const firstImport = (doc.imports.allItems[0]).document;
        expect(firstImport.imports.length)
            .toBe(1);
        expect(firstImport.name)
            .toBe('notMissing.cdm.json');
        const nestedImport = (firstImport.imports.allItems[0]).document;
        expect(nestedImport)
            .toBeUndefined();
    }));
    /**
     * Testing loading where import is listed multiple times in different files
     */
    it('TestEntityWithSameImportsAsync', () => __awaiter(void 0, void 0, void 0, function* () {
        const expectedLogCodes = new Set([internal_1.cdmLogCode.ErrPersistFileReadFailure, internal_1.cdmLogCode.WarnResolveImportFailed, internal_1.cdmLogCode.WarnDocImportNotLoaded]);
        const cdmCorpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestEntityWithSameImportsAsync', undefined, false, expectedLogCodes);
        const resOpt = new internal_1.resolveOptions();
        resOpt.importsLoadStrategy = internal_1.importsLoadStrategy.load;
        const doc = yield cdmCorpus.fetchObjectAsync('local:/multipleImports.cdm.json', null, resOpt);
        expect(doc)
            .not
            .toBeUndefined();
        expect(doc.imports.length)
            .toBe(2);
        const firstImport = (doc.imports.allItems[0]).document;
        expect(firstImport.name)
            .toBe('missingImport.cdm.json');
        expect(firstImport.imports.length)
            .toBe(1);
        const secondImport = (doc.imports.allItems[1]).document;
        expect(secondImport.name)
            .toBe('notMissing.cdm.json');
    }));
    /**
     * Testing an import with a non-existing namespace name.
     */
    it('TestNonExistingAdapterNamespace', () => __awaiter(void 0, void 0, void 0, function* () {
        const expectedLogCodes = new Set([internal_1.cdmLogCode.ErrPersistFileReadFailure]);
        const cdmCorpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestNonExistingAdapterNamespace', undefined, false, expectedLogCodes);
        cdmCorpus.storage.mount('erp', new Storage_1.LocalAdapter(testHelper_1.testHelper.getInputFolderPath(testsSubpath, 'TestNonExistingAdapterNamespace')));
        // Set local as our default.
        cdmCorpus.storage.defaultNamespace = 'erp';
        const manifestPath = cdmCorpus.storage.createAbsoluteCorpusPath('erp.missingImportManifest.cdm');
        // Load a manifest that is trying to import from 'cdm' namespace.
        // The manifest does't exist since the import couldn't get resolved,
        // so the error message will be logged and the null value will be propagated back to a user.
        expect(yield cdmCorpus.fetchObjectAsync('erp.missingImportManifest.cdm', null, null))
            .toBeUndefined();
    }));
    /**
     * Testing docs that load the same import
     */
    it('TestLoadingSameImportsAsync', () => __awaiter(void 0, void 0, void 0, function* () {
        const cdmCorpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestLoadingSameImportsAsync');
        const resOpt = new internal_1.resolveOptions();
        resOpt.importsLoadStrategy = internal_1.importsLoadStrategy.load;
        const mainDoc = yield cdmCorpus.fetchObjectAsync('mainEntity.cdm.json', null, resOpt);
        expect(mainDoc)
            .not
            .toBeUndefined();
        expect(mainDoc.imports.length)
            .toBe(2);
        const firstImport = mainDoc.imports.allItems[0].document;
        const secondImport = mainDoc.imports.allItems[1].document;
        // since these two imports are loaded asyncronously, we need to make sure that
        // the import that they share (targetImport) was loaded, and that the
        // targetImport doc is attached to both of these import objects
        expect(firstImport.imports.length)
            .toBe(1);
        expect(firstImport.imports.allItems[0].document)
            .toBeDefined();
        expect(secondImport.imports.length)
            .toBe(1);
        expect(secondImport.imports.allItems[0].document)
            .toBeDefined();
    }));
    /**
     * Testing docs that load the same import of which, the file cannot be found
     */
    it('TestLoadingSameMissingImportsAsync', () => __awaiter(void 0, void 0, void 0, function* () {
        const expectedLogCodes = new Set([internal_1.cdmLogCode.ErrPersistFileReadFailure, internal_1.cdmLogCode.WarnResolveImportFailed, internal_1.cdmLogCode.WarnDocImportNotLoaded]);
        const cdmCorpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestLoadingSameMissingImportsAsync', undefined, false, expectedLogCodes);
        const resOpt = new internal_1.resolveOptions();
        resOpt.importsLoadStrategy = internal_1.importsLoadStrategy.load;
        const mainDoc = yield cdmCorpus.fetchObjectAsync('mainEntity.cdm.json', null, resOpt);
        expect(mainDoc)
            .not
            .toBeUndefined();
        expect(mainDoc.imports.length)
            .toBe(2);
        // make sure imports loaded correctly, despite them missing imports
        const firstImport = (mainDoc.imports.allItems[0]).document;
        const secondImport = (mainDoc.imports.allItems[1]).document;
        expect(firstImport.imports.length)
            .toBe(1);
        expect(firstImport.imports.allItems[0].document)
            .toBeUndefined();
        expect(secondImport.imports.length)
            .toBe(1);
        expect(firstImport.imports.allItems[0].document)
            .toBeUndefined();
    }));
    /**
     * Testing doc that loads an import that has already been loaded before
     */
    it('TestLoadingAlreadyPresentImportsAsync', () => __awaiter(void 0, void 0, void 0, function* () {
        const cdmCorpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestLoadingAlreadyPresentImportsAsync');
        const resOpt = new internal_1.resolveOptions();
        resOpt.importsLoadStrategy = internal_1.importsLoadStrategy.load;
        // load the first doc
        const mainDoc = yield cdmCorpus.fetchObjectAsync('mainEntity.cdm.json', null, resOpt);
        expect(mainDoc)
            .not
            .toBeUndefined();
        expect(mainDoc.imports.length)
            .toBe(1);
        const importDoc = (mainDoc.imports.allItems[0]).document;
        expect(importDoc)
            .toBeDefined();
        // now load the second doc, which uses the same import
        // the import should not be loaded again, it should be the same object
        const secondDoc = yield cdmCorpus.fetchObjectAsync('secondEntity.cdm.json', null, resOpt);
        expect(secondDoc)
            .not
            .toBeUndefined();
        expect(secondDoc.imports.length)
            .toBe(1);
        const secondImportDoc = (mainDoc.imports.allItems[0]).document;
        expect(secondImportDoc)
            .toBeDefined();
        expect(importDoc)
            .toBe(secondImportDoc);
    }));
    /**
     * Testing that import priorites update correctly when imports are changed
     */
    it('TestPrioritizingImportsAfterEdit', () => __awaiter(void 0, void 0, void 0, function* () {
        const corpus = testHelper_1.testHelper.getLocalCorpus(testsSubpath, 'TestPrioritizingImportsAfterEdit');
        var document = yield corpus.fetchObjectAsync('local:/mainDoc.cdm.json');
        yield document.refreshAsync(new internal_1.resolveOptions(document));
        expect(document.imports.length)
            .toEqual(0);
        // the current doc itself is added to the list of priorities
        expect(document.importPriorities.importPriority.size)
            .toEqual(1);
        document.imports.push('importDoc.cdm.json', true);
        yield document.refreshAsync(new internal_1.resolveOptions(document));
        expect(document.imports.length)
            .toEqual(1);
        expect(document.importPriorities.importPriority.size)
            .toEqual(2);
    }));
});
//# sourceMappingURL=Imports.test.js.map