"use strict";

require("core-js/modules/es.promise.js");

require("core-js/modules/es.array.slice.js");

require("core-js/modules/es.function.name.js");

require("core-js/modules/es.array.from.js");

require("core-js/modules/es.string.iterator.js");

require("core-js/modules/es.symbol.js");

require("core-js/modules/es.symbol.description.js");

require("core-js/modules/es.symbol.iterator.js");

require("core-js/modules/es.array.iterator.js");

require("core-js/modules/web.dom-collections.iterator.js");

require("regenerator-runtime/runtime.js");

require("core-js/modules/es.array.filter.js");

require("core-js/modules/es.object.to-string.js");

require("core-js/modules/es.array.concat.js");

require("core-js/modules/es.array.join.js");

require("core-js/modules/es.array.map.js");

require("core-js/modules/es.regexp.exec.js");

require("core-js/modules/es.string.replace.js");

require("core-js/modules/es.regexp.to-string.js");

function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.assertCompletion = assertCompletion;
exports.testCompletionFor = testCompletionFor;
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

require("mocha");

var assert = require("assert");

var path = require("path");

var vscode_uri_1 = require("vscode-uri");

var languageModes_1 = require("../modes/languageModes");

var nodeFs_1 = require("../node/nodeFs");

var documentContext_1 = require("../utils/documentContext");

function assertCompletion(completions, expected, document) {
  var matches = completions.items.filter(function (completion) {
    return completion.label === expected.label;
  });

  if (expected.notAvailable) {
    assert.strictEqual(matches.length, 0, "".concat(expected.label, " should not existing is results"));
    return;
  }

  assert.strictEqual(matches.length, 1, "".concat(expected.label, " should only existing once: Actual: ").concat(completions.items.map(function (c) {
    return c.label;
  }).join(', ')));
  var match = matches[0];

  if (expected.documentation) {
    assert.strictEqual(match.documentation, expected.documentation);
  }

  if (expected.kind) {
    assert.strictEqual(match.kind, expected.kind);
  }

  if (expected.resultText && match.textEdit) {
    var edit = languageModes_1.TextEdit.is(match.textEdit) ? match.textEdit : languageModes_1.TextEdit.replace(match.textEdit.replace, match.textEdit.newText);
    assert.strictEqual(languageModes_1.TextDocument.applyEdits(document, [edit]), expected.resultText);
  }

  if (expected.command) {
    assert.deepStrictEqual(match.command, expected.command);
  }
}

var testUri = 'test://test/test.html';

function testCompletionFor(_x, _x2) {
  return _testCompletionFor.apply(this, arguments);
}

function _testCompletionFor() {
  _testCompletionFor = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee14(value, expected) {
    var uri,
        workspaceFolders,
        offset,
        workspace,
        document,
        position,
        context,
        languageModes,
        mode,
        list,
        _iterator,
        _step,
        item,
        _args14 = arguments;

    return regeneratorRuntime.wrap(function _callee14$(_context14) {
      while (1) {
        switch (_context14.prev = _context14.next) {
          case 0:
            uri = _args14.length > 2 && _args14[2] !== undefined ? _args14[2] : testUri;
            workspaceFolders = _args14.length > 3 ? _args14[3] : undefined;
            offset = value.indexOf('|');
            value = value.substr(0, offset) + value.substr(offset + 1);
            workspace = {
              settings: {},
              folders: workspaceFolders || [{
                name: 'x',
                uri: uri.substr(0, uri.lastIndexOf('/'))
              }]
            };
            document = languageModes_1.TextDocument.create(uri, 'html', 0, value);
            position = document.positionAt(offset);
            context = (0, documentContext_1.getDocumentContext)(uri, workspace.folders);
            languageModes = (0, languageModes_1.getLanguageModes)({
              css: true,
              javascript: true
            }, workspace, languageModes_1.ClientCapabilities.LATEST, (0, nodeFs_1.getNodeFileFS)());
            mode = languageModes.getModeAtPosition(document, position);
            _context14.next = 12;
            return mode.doComplete(document, position, context);

          case 12:
            list = _context14.sent;

            if (expected.count) {
              assert.strictEqual(list.items.length, expected.count);
            }

            if (expected.items) {
              _iterator = _createForOfIteratorHelper(expected.items);

              try {
                for (_iterator.s(); !(_step = _iterator.n()).done;) {
                  item = _step.value;
                  assertCompletion(list, item, document);
                }
              } catch (err) {
                _iterator.e(err);
              } finally {
                _iterator.f();
              }
            }

          case 15:
          case "end":
            return _context14.stop();
        }
      }
    }, _callee14);
  }));
  return _testCompletionFor.apply(this, arguments);
}

suite('HTML Completion', function () {
  test('HTML JavaScript Completions', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
    return regeneratorRuntime.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            _context.next = 2;
            return testCompletionFor('<html><script>window.|</script></html>', {
              items: [{
                label: 'location',
                resultText: '<html><script>window.location</script></html>'
              }]
            });

          case 2:
            _context.next = 4;
            return testCompletionFor('<html><script>$.|</script></html>', {
              items: [{
                label: 'getJSON',
                resultText: '<html><script>$.getJSON</script></html>'
              }]
            });

          case 4:
            _context.next = 6;
            return testCompletionFor('<html><script>const x = { a: 1 };</script><script>x.|</script></html>', {
              items: [{
                label: 'a',
                resultText: '<html><script>const x = { a: 1 };</script><script>x.a</script></html>'
              }]
            }, 'test://test/test2.html');

          case 6:
          case "end":
            return _context.stop();
        }
      }
    }, _callee);
  })));
});
suite('HTML Path Completion', function () {
  var triggerSuggestCommand = {
    title: 'Suggest',
    command: 'editor.action.triggerSuggest'
  };
  var fixtureRoot = path.resolve(__dirname, '../../src/test/pathCompletionFixtures');
  var fixtureWorkspace = {
    name: 'fixture',
    uri: vscode_uri_1.URI.file(fixtureRoot).toString()
  };
  var indexHtmlUri = vscode_uri_1.URI.file(path.resolve(fixtureRoot, 'index.html')).toString();
  var aboutHtmlUri = vscode_uri_1.URI.file(path.resolve(fixtureRoot, 'about/about.html')).toString();
  test('Basics - Correct label/kind/result/command', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
    return regeneratorRuntime.wrap(function _callee2$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            _context2.next = 2;
            return testCompletionFor('<script src="./|">', {
              items: [{
                label: 'about/',
                kind: languageModes_1.CompletionItemKind.Folder,
                resultText: '<script src="./about/">',
                command: triggerSuggestCommand
              }, {
                label: 'index.html',
                kind: languageModes_1.CompletionItemKind.File,
                resultText: '<script src="./index.html">'
              }, {
                label: 'src/',
                kind: languageModes_1.CompletionItemKind.Folder,
                resultText: '<script src="./src/">',
                command: triggerSuggestCommand
              }]
            }, indexHtmlUri);

          case 2:
          case "end":
            return _context2.stop();
        }
      }
    }, _callee2);
  })));
  test('Basics - Single Quote', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
    return regeneratorRuntime.wrap(function _callee3$(_context3) {
      while (1) {
        switch (_context3.prev = _context3.next) {
          case 0:
            _context3.next = 2;
            return testCompletionFor("<script src='./|'>", {
              items: [{
                label: 'about/',
                kind: languageModes_1.CompletionItemKind.Folder,
                resultText: "<script src='./about/'>",
                command: triggerSuggestCommand
              }, {
                label: 'index.html',
                kind: languageModes_1.CompletionItemKind.File,
                resultText: "<script src='./index.html'>"
              }, {
                label: 'src/',
                kind: languageModes_1.CompletionItemKind.Folder,
                resultText: "<script src='./src/'>",
                command: triggerSuggestCommand
              }]
            }, indexHtmlUri);

          case 2:
          case "end":
            return _context3.stop();
        }
      }
    }, _callee3);
  })));
  test('No completion for remote paths', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4() {
    return regeneratorRuntime.wrap(function _callee4$(_context4) {
      while (1) {
        switch (_context4.prev = _context4.next) {
          case 0:
            _context4.next = 2;
            return testCompletionFor('<script src="http:">', {
              items: []
            });

          case 2:
            _context4.next = 4;
            return testCompletionFor('<script src="http:/|">', {
              items: []
            });

          case 4:
            _context4.next = 6;
            return testCompletionFor('<script src="http://|">', {
              items: []
            });

          case 6:
            _context4.next = 8;
            return testCompletionFor('<script src="https:|">', {
              items: []
            });

          case 8:
            _context4.next = 10;
            return testCompletionFor('<script src="https:/|">', {
              items: []
            });

          case 10:
            _context4.next = 12;
            return testCompletionFor('<script src="https://|">', {
              items: []
            });

          case 12:
            _context4.next = 14;
            return testCompletionFor('<script src="//|">', {
              items: []
            });

          case 14:
          case "end":
            return _context4.stop();
        }
      }
    }, _callee4);
  })));
  test('Relative Path', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {
    return regeneratorRuntime.wrap(function _callee5$(_context5) {
      while (1) {
        switch (_context5.prev = _context5.next) {
          case 0:
            _context5.next = 2;
            return testCompletionFor('<script src="../|">', {
              items: [{
                label: 'about/',
                resultText: '<script src="../about/">'
              }, {
                label: 'index.html',
                resultText: '<script src="../index.html">'
              }, {
                label: 'src/',
                resultText: '<script src="../src/">'
              }]
            }, aboutHtmlUri);

          case 2:
            _context5.next = 4;
            return testCompletionFor('<script src="../src/|">', {
              items: [{
                label: 'feature.js',
                resultText: '<script src="../src/feature.js">'
              }, {
                label: 'test.js',
                resultText: '<script src="../src/test.js">'
              }]
            }, aboutHtmlUri);

          case 4:
          case "end":
            return _context5.stop();
        }
      }
    }, _callee5);
  })));
  test('Absolute Path', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee6() {
    return regeneratorRuntime.wrap(function _callee6$(_context6) {
      while (1) {
        switch (_context6.prev = _context6.next) {
          case 0:
            _context6.next = 2;
            return testCompletionFor('<script src="/|">', {
              items: [{
                label: 'about/',
                resultText: '<script src="/about/">'
              }, {
                label: 'index.html',
                resultText: '<script src="/index.html">'
              }, {
                label: 'src/',
                resultText: '<script src="/src/">'
              }]
            }, indexHtmlUri);

          case 2:
            _context6.next = 4;
            return testCompletionFor('<script src="/src/|">', {
              items: [{
                label: 'feature.js',
                resultText: '<script src="/src/feature.js">'
              }, {
                label: 'test.js',
                resultText: '<script src="/src/test.js">'
              }]
            }, aboutHtmlUri, [fixtureWorkspace]);

          case 4:
          case "end":
            return _context6.stop();
        }
      }
    }, _callee6);
  })));
  test('Empty Path Value', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee7() {
    return regeneratorRuntime.wrap(function _callee7$(_context7) {
      while (1) {
        switch (_context7.prev = _context7.next) {
          case 0:
            _context7.next = 2;
            return testCompletionFor('<script src="|">', {
              items: [{
                label: 'about/',
                resultText: '<script src="about/">'
              }, {
                label: 'index.html',
                resultText: '<script src="index.html">'
              }, {
                label: 'src/',
                resultText: '<script src="src/">'
              }]
            }, indexHtmlUri);

          case 2:
            _context7.next = 4;
            return testCompletionFor('<script src="|">', {
              items: [{
                label: 'about.css',
                resultText: '<script src="about.css">'
              }, {
                label: 'about.html',
                resultText: '<script src="about.html">'
              }, {
                label: 'media/',
                resultText: '<script src="media/">'
              }]
            }, aboutHtmlUri);

          case 4:
          case "end":
            return _context7.stop();
        }
      }
    }, _callee7);
  })));
  test('Incomplete Path', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee8() {
    return regeneratorRuntime.wrap(function _callee8$(_context8) {
      while (1) {
        switch (_context8.prev = _context8.next) {
          case 0:
            _context8.next = 2;
            return testCompletionFor('<script src="/src/f|">', {
              items: [{
                label: 'feature.js',
                resultText: '<script src="/src/feature.js">'
              }, {
                label: 'test.js',
                resultText: '<script src="/src/test.js">'
              }]
            }, aboutHtmlUri, [fixtureWorkspace]);

          case 2:
            _context8.next = 4;
            return testCompletionFor('<script src="../src/f|">', {
              items: [{
                label: 'feature.js',
                resultText: '<script src="../src/feature.js">'
              }, {
                label: 'test.js',
                resultText: '<script src="../src/test.js">'
              }]
            }, aboutHtmlUri, [fixtureWorkspace]);

          case 4:
          case "end":
            return _context8.stop();
        }
      }
    }, _callee8);
  })));
  test('No leading dot or slash', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee9() {
    return regeneratorRuntime.wrap(function _callee9$(_context9) {
      while (1) {
        switch (_context9.prev = _context9.next) {
          case 0:
            _context9.next = 2;
            return testCompletionFor('<script src="s|">', {
              items: [{
                label: 'about/',
                resultText: '<script src="about/">'
              }, {
                label: 'index.html',
                resultText: '<script src="index.html">'
              }, {
                label: 'src/',
                resultText: '<script src="src/">'
              }]
            }, indexHtmlUri, [fixtureWorkspace]);

          case 2:
            _context9.next = 4;
            return testCompletionFor('<script src="src/|">', {
              items: [{
                label: 'feature.js',
                resultText: '<script src="src/feature.js">'
              }, {
                label: 'test.js',
                resultText: '<script src="src/test.js">'
              }]
            }, indexHtmlUri, [fixtureWorkspace]);

          case 4:
            _context9.next = 6;
            return testCompletionFor('<script src="src/f|">', {
              items: [{
                label: 'feature.js',
                resultText: '<script src="src/feature.js">'
              }, {
                label: 'test.js',
                resultText: '<script src="src/test.js">'
              }]
            }, indexHtmlUri, [fixtureWorkspace]);

          case 6:
            _context9.next = 8;
            return testCompletionFor('<script src="s|">', {
              items: [{
                label: 'about.css',
                resultText: '<script src="about.css">'
              }, {
                label: 'about.html',
                resultText: '<script src="about.html">'
              }, {
                label: 'media/',
                resultText: '<script src="media/">'
              }]
            }, aboutHtmlUri, [fixtureWorkspace]);

          case 8:
            _context9.next = 10;
            return testCompletionFor('<script src="media/|">', {
              items: [{
                label: 'icon.pic',
                resultText: '<script src="media/icon.pic">'
              }]
            }, aboutHtmlUri, [fixtureWorkspace]);

          case 10:
            _context9.next = 12;
            return testCompletionFor('<script src="media/f|">', {
              items: [{
                label: 'icon.pic',
                resultText: '<script src="media/icon.pic">'
              }]
            }, aboutHtmlUri, [fixtureWorkspace]);

          case 12:
          case "end":
            return _context9.stop();
        }
      }
    }, _callee9);
  })));
  test('Trigger completion in middle of path', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee10() {
    return regeneratorRuntime.wrap(function _callee10$(_context10) {
      while (1) {
        switch (_context10.prev = _context10.next) {
          case 0:
            _context10.next = 2;
            return testCompletionFor('<script src="src/f|eature.js">', {
              items: [{
                label: 'feature.js',
                resultText: '<script src="src/feature.js">'
              }, {
                label: 'test.js',
                resultText: '<script src="src/test.js">'
              }]
            }, indexHtmlUri, [fixtureWorkspace]);

          case 2:
            _context10.next = 4;
            return testCompletionFor('<script src="s|rc/feature.js">', {
              items: [{
                label: 'about/',
                resultText: '<script src="about/">'
              }, {
                label: 'index.html',
                resultText: '<script src="index.html">'
              }, {
                label: 'src/',
                resultText: '<script src="src/">'
              }]
            }, indexHtmlUri, [fixtureWorkspace]);

          case 4:
            _context10.next = 6;
            return testCompletionFor('<script src="media/f|eature.js">', {
              items: [{
                label: 'icon.pic',
                resultText: '<script src="media/icon.pic">'
              }]
            }, aboutHtmlUri, [fixtureWorkspace]);

          case 6:
            _context10.next = 8;
            return testCompletionFor('<script src="m|edia/feature.js">', {
              items: [{
                label: 'about.css',
                resultText: '<script src="about.css">'
              }, {
                label: 'about.html',
                resultText: '<script src="about.html">'
              }, {
                label: 'media/',
                resultText: '<script src="media/">'
              }]
            }, aboutHtmlUri, [fixtureWorkspace]);

          case 8:
          case "end":
            return _context10.stop();
        }
      }
    }, _callee10);
  })));
  test('Trigger completion in middle of path and with whitespaces', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee11() {
    return regeneratorRuntime.wrap(function _callee11$(_context11) {
      while (1) {
        switch (_context11.prev = _context11.next) {
          case 0:
            _context11.next = 2;
            return testCompletionFor('<script src="./| about/about.html>', {
              items: [{
                label: 'about/',
                resultText: '<script src="./about/ about/about.html>'
              }, {
                label: 'index.html',
                resultText: '<script src="./index.html about/about.html>'
              }, {
                label: 'src/',
                resultText: '<script src="./src/ about/about.html>'
              }]
            }, indexHtmlUri, [fixtureWorkspace]);

          case 2:
            _context11.next = 4;
            return testCompletionFor('<script src="./a|bout /about.html>', {
              items: [{
                label: 'about/',
                resultText: '<script src="./about/ /about.html>'
              }, {
                label: 'index.html',
                resultText: '<script src="./index.html /about.html>'
              }, {
                label: 'src/',
                resultText: '<script src="./src/ /about.html>'
              }]
            }, indexHtmlUri, [fixtureWorkspace]);

          case 4:
          case "end":
            return _context11.stop();
        }
      }
    }, _callee11);
  })));
  test('Completion should ignore files/folders starting with dot', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee12() {
    return regeneratorRuntime.wrap(function _callee12$(_context12) {
      while (1) {
        switch (_context12.prev = _context12.next) {
          case 0:
            _context12.next = 2;
            return testCompletionFor('<script src="./|"', {
              count: 3
            }, indexHtmlUri, [fixtureWorkspace]);

          case 2:
          case "end":
            return _context12.stop();
        }
      }
    }, _callee12);
  })));
  test('Unquoted Path', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee13() {
    return regeneratorRuntime.wrap(function _callee13$(_context13) {
      while (1) {
        switch (_context13.prev = _context13.next) {
          case 0:
          case "end":
            return _context13.stop();
        }
      }
    }, _callee13);
  })));
});