"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
const assert = __importStar(require("assert"));
const vscode_languageserver_1 = require("vscode-languageserver");
const documents_1 = require("../../../src/lib/documents");
const plugins_1 = require("../../../src/plugins");
const ls_config_1 = require("../../../src/ls-config");
const service_1 = require("../../../src/plugins/css/service");
const utils_1 = require("../../../src/utils");
const vscode_css_languageservice_1 = require("vscode-css-languageservice");
describe('CSS Plugin', () => {
    function setup(content, lsOptions) {
        const document = new documents_1.Document('file:///hello.svelte', content);
        const docManager = new documents_1.DocumentManager(() => document);
        const pluginManager = new ls_config_1.LSConfigManager();
        const plugin = new plugins_1.CSSPlugin(docManager, pluginManager, [
            {
                name: '',
                uri: (0, utils_1.pathToUrl)(process.cwd())
            }
        ], (0, service_1.createLanguageServices)(lsOptions));
        docManager.openClientDocument('some doc');
        return { plugin, document };
    }
    describe('provides hover info', () => {
        it('for normal css', () => {
            const { plugin, document } = setup('<style>h1 {}</style>');
            assert.deepStrictEqual(plugin.doHover(document, vscode_languageserver_1.Position.create(0, 8)), {
                contents: [
                    { language: 'html', value: '<h1>' },
                    '[Selector Specificity](https://developer.mozilla.org/docs/Web/CSS/Specificity): (0, 0, 1)'
                ],
                range: vscode_languageserver_1.Range.create(0, 7, 0, 9)
            });
            assert.strictEqual(plugin.doHover(document, vscode_languageserver_1.Position.create(0, 10)), null);
        });
        it('not for SASS', () => {
            const { plugin, document } = setup('<style lang="sass">h1 {}</style>');
            assert.deepStrictEqual(plugin.doHover(document, vscode_languageserver_1.Position.create(0, 20)), null);
        });
        it('not for stylus', () => {
            const { plugin, document } = setup('<style lang="stylus">h1 {}</style>');
            assert.deepStrictEqual(plugin.doHover(document, vscode_languageserver_1.Position.create(0, 22)), null);
        });
        it('for style attribute', () => {
            const { plugin, document } = setup('<div style="height: auto;"></div>');
            assert.deepStrictEqual(plugin.doHover(document, vscode_languageserver_1.Position.create(0, 13)), {
                contents: {
                    kind: 'markdown',
                    value: "Specifies the height of the content area, padding area or border area \\(depending on 'box\\-sizing'\\) of certain boxes\\.\n\n" +
                        '(Edge 12, Firefox 1, Safari 1, Chrome 1, IE 4, Opera 7)\n\n' +
                        'Syntax: auto | &lt;length&gt; | &lt;percentage&gt; | min\\-content | max\\-content | fit\\-content | fit\\-content\\(&lt;length\\-percentage&gt;\\)\n\n' +
                        '[MDN Reference](https://developer.mozilla.org/docs/Web/CSS/height)'
                },
                range: vscode_languageserver_1.Range.create(0, 12, 0, 24)
            });
        });
        it('not for style attribute with interpolation', () => {
            const { plugin, document } = setup('<div style="height: {}"></div>');
            assert.deepStrictEqual(plugin.doHover(document, vscode_languageserver_1.Position.create(0, 13)), null);
        });
    });
    describe('provides completions', () => {
        it('for normal css', async () => {
            const { plugin, document } = setup('<style></style>');
            const completions = await plugin.getCompletions(document, vscode_languageserver_1.Position.create(0, 7), {
                triggerCharacter: '.'
            });
            assert.ok(Array.isArray(completions && completions.items), 'Expected completion items to be an array');
            assert.ok(completions.items.length > 0, 'Expected completions to have length');
            assert.deepStrictEqual(completions.items[0], {
                label: '@charset',
                kind: vscode_languageserver_1.CompletionItemKind.Keyword,
                documentation: {
                    kind: 'markdown',
                    value: 'Defines character set of the document\\.\n\n(Edge 12, Firefox 1, Safari 4, Chrome 2, IE 5, Opera 9)\n\n' +
                        '[MDN Reference](https://developer.mozilla.org/docs/Web/CSS/@charset)'
                },
                textEdit: vscode_languageserver_1.TextEdit.insert(vscode_languageserver_1.Position.create(0, 7), '@charset'),
                tags: []
            });
        });
        it('for :global modifier', async () => {
            const { plugin, document } = setup('<style>:g</style>');
            const completions = await plugin.getCompletions(document, vscode_languageserver_1.Position.create(0, 9), {
                triggerCharacter: ':'
            });
            const globalCompletion = completions?.items.find((item) => item.label === ':global()');
            assert.ok(globalCompletion);
        });
        it('not for stylus', async () => {
            const { plugin, document } = setup('<style lang="stylus"></style>');
            const completions = await plugin.getCompletions(document, vscode_languageserver_1.Position.create(0, 21), {
                triggerCharacter: '.'
            });
            assert.deepStrictEqual(completions, null);
        });
        it('for style attribute', async () => {
            const { plugin, document } = setup('<div style="display: n"></div>');
            const completions = await plugin.getCompletions(document, vscode_languageserver_1.Position.create(0, 22), {
                triggerKind: vscode_languageserver_1.CompletionTriggerKind.Invoked
            });
            assert.deepStrictEqual(completions?.items.find((item) => item.label === 'none'), {
                insertTextFormat: undefined,
                kind: 12,
                label: 'none',
                documentation: {
                    kind: 'markdown',
                    value: 'The element and its descendants generates no boxes\\.'
                },
                sortText: ' ',
                tags: [],
                textEdit: {
                    newText: 'none',
                    range: {
                        start: {
                            line: 0,
                            character: 21
                        },
                        end: {
                            line: 0,
                            character: 22
                        }
                    }
                }
            });
        });
        it('not for style attribute with interpolation', async () => {
            const { plugin, document } = setup('<div style="height: {}"></div>');
            assert.deepStrictEqual(await plugin.getCompletions(document, vscode_languageserver_1.Position.create(0, 21)), null);
        });
        it('for path completion', async () => {
            const { plugin, document } = setup('<style>@import "./"</style>', {
                fileSystemProvider: {
                    stat: () => Promise.resolve({
                        ctime: Date.now(),
                        mtime: Date.now(),
                        size: 0,
                        type: vscode_css_languageservice_1.FileType.File
                    }),
                    readDirectory: () => Promise.resolve([['foo.css', vscode_css_languageservice_1.FileType.File]])
                }
            });
            const completions = await plugin.getCompletions(document, vscode_languageserver_1.Position.create(0, 16));
            assert.deepStrictEqual(completions?.items.find((item) => item.label === 'foo.css'), {
                label: 'foo.css',
                kind: 17,
                textEdit: {
                    newText: 'foo.css',
                    range: {
                        end: {
                            character: 18,
                            line: 0
                        },
                        start: {
                            character: 16,
                            line: 0
                        }
                    }
                }
            });
        });
    });
    describe('provides diagnostics', () => {
        it('- everything ok', () => {
            const { plugin, document } = setup('<style>h1 {color:blue;}</style>');
            const diagnostics = plugin.getDiagnostics(document);
            assert.deepStrictEqual(diagnostics, []);
        });
        it('- has error', () => {
            const { plugin, document } = setup('<style>h1 {iDunnoDisProperty:blue;}</style>');
            const diagnostics = plugin.getDiagnostics(document);
            assert.deepStrictEqual(diagnostics, [
                {
                    code: 'unknownProperties',
                    message: "Unknown property: 'iDunnoDisProperty'",
                    range: {
                        end: {
                            character: 28,
                            line: 0
                        },
                        start: {
                            character: 11,
                            line: 0
                        }
                    },
                    severity: 2,
                    source: 'css'
                }
            ]);
        });
        it('- no diagnostics for sass', () => {
            const { plugin, document } = setup(`<style lang="sass">
                h1
                    iDunnoDisProperty:blue
                </style>`);
            const diagnostics = plugin.getDiagnostics(document);
            assert.deepStrictEqual(diagnostics, []);
        });
        it('- no diagnostics for stylus', () => {
            const { plugin, document } = setup(`<style lang="sass">
                h1
                    iDunnoDisProperty:blue
                </style>`);
            const diagnostics = plugin.getDiagnostics(document);
            assert.deepStrictEqual(diagnostics, []);
        });
    });
    describe('provides document colors', () => {
        it('for normal css', () => {
            const { plugin, document } = setup('<style>h1 {color:blue;}</style>');
            const colors = plugin.getColorPresentations(document, {
                start: { line: 0, character: 17 },
                end: { line: 0, character: 21 }
            }, { alpha: 1, blue: 255, green: 0, red: 0 });
            assert.deepStrictEqual(colors, [
                {
                    label: 'rgb(0, 0, 65025)',
                    textEdit: {
                        range: {
                            end: {
                                character: 21,
                                line: 0
                            },
                            start: {
                                character: 17,
                                line: 0
                            }
                        },
                        newText: 'rgb(0, 0, 65025)'
                    }
                },
                {
                    label: '#00000fe01',
                    textEdit: {
                        range: {
                            end: {
                                character: 21,
                                line: 0
                            },
                            start: {
                                character: 17,
                                line: 0
                            }
                        },
                        newText: '#00000fe01'
                    }
                },
                {
                    label: 'hsl(240, -101%, 12750%)',
                    textEdit: {
                        range: {
                            end: {
                                character: 21,
                                line: 0
                            },
                            start: {
                                character: 17,
                                line: 0
                            }
                        },
                        newText: 'hsl(240, -101%, 12750%)'
                    }
                },
                {
                    label: 'hwb(240 0% -25400%)',
                    textEdit: {
                        range: {
                            end: {
                                character: 21,
                                line: 0
                            },
                            start: {
                                character: 17,
                                line: 0
                            }
                        },
                        newText: 'hwb(240 0% -25400%)'
                    }
                }
            ]);
        });
        it('not for SASS', () => {
            const { plugin, document } = setup(`<style lang="sass">
            h1
                color:blue
            </style>`);
            assert.deepStrictEqual(plugin.getColorPresentations(document, {
                start: { line: 2, character: 22 },
                end: { line: 2, character: 26 }
            }, { alpha: 1, blue: 255, green: 0, red: 0 }), []);
            assert.deepStrictEqual(plugin.getDocumentColors(document), []);
        });
        it('not for stylus', () => {
            const { plugin, document } = setup(`<style lang="stylus">
            h1
                color:blue
            </style>`);
            assert.deepStrictEqual(plugin.getColorPresentations(document, {
                start: { line: 2, character: 22 },
                end: { line: 2, character: 26 }
            }, { alpha: 1, blue: 255, green: 0, red: 0 }), []);
            assert.deepStrictEqual(plugin.getDocumentColors(document), []);
        });
    });
    describe('provides document symbols', () => {
        it('for normal css', () => {
            const { plugin, document } = setup('<style>h1 {color:blue;}</style>');
            const symbols = plugin.getDocumentSymbols(document);
            assert.deepStrictEqual(symbols, [
                {
                    containerName: 'style',
                    kind: 5,
                    location: {
                        range: {
                            end: {
                                character: 23,
                                line: 0
                            },
                            start: {
                                character: 7,
                                line: 0
                            }
                        },
                        uri: 'file:///hello.svelte'
                    },
                    name: 'h1'
                }
            ]);
        });
        it('not for SASS', () => {
            const { plugin, document } = setup('<style lang="sass">h1 {color:blue;}</style>');
            assert.deepStrictEqual(plugin.getDocumentSymbols(document), []);
        });
        it('not for stylus', () => {
            const { plugin, document } = setup('<style lang="stylus">h1 {color:blue;}</style>');
            assert.deepStrictEqual(plugin.getDocumentSymbols(document), []);
        });
    });
    it('provides selection range', () => {
        const { plugin, document } = setup('<style>h1 {}</style>');
        const selectionRange = plugin.getSelectionRange(document, vscode_languageserver_1.Position.create(0, 11));
        assert.deepStrictEqual(selectionRange, {
            parent: {
                parent: {
                    parent: undefined,
                    range: {
                        end: {
                            character: 12,
                            line: 0
                        },
                        start: {
                            character: 7,
                            line: 0
                        }
                    }
                },
                range: {
                    end: {
                        character: 12,
                        line: 0
                    },
                    start: {
                        character: 10,
                        line: 0
                    }
                }
            },
            range: {
                end: {
                    character: 11,
                    line: 0
                },
                start: {
                    character: 11,
                    line: 0
                }
            }
        });
    });
    it('return null for selection range when not in style', () => {
        const { plugin, document } = setup('<script></script>');
        const selectionRange = plugin.getSelectionRange(document, vscode_languageserver_1.Position.create(0, 10));
        assert.equal(selectionRange, null);
    });
    describe('folding ranges', () => {
        it('provides folding ranges', () => {
            const { plugin, document } = setup('<style>\n.hi {\ndisplay:none;\n}\n</style>');
            const foldingRanges = plugin.getFoldingRanges(document);
            assert.deepStrictEqual(foldingRanges, [{ startLine: 1, endLine: 2, kind: undefined }]);
        });
        it('provides folding ranges for known indent style', () => {
            const { plugin, document } = setup('<style lang="sass">\n/*#region*/\n.hi\n  display:none\n.hi2\n  display: none\n/*#endregion*/\n</style>');
            const foldingRanges = plugin.getFoldingRanges(document);
            assert.deepStrictEqual(foldingRanges, [
                { startLine: 1, endLine: 6, kind: vscode_languageserver_1.FoldingRangeKind.Region },
                { startLine: 2, endLine: 3 },
                { startLine: 4, endLine: 5 }
            ]);
        });
    });
    describe('document highlight', () => {
        it('provide document highlight', () => {
            const { plugin, document } = setup('<style>.hi {} button.hi {}</style>');
            const highlight = plugin.findDocumentHighlight(document, vscode_languageserver_1.Position.create(0, 9));
            assert.deepStrictEqual(highlight, [
                {
                    range: {
                        start: {
                            line: 0,
                            character: 7
                        },
                        end: {
                            line: 0,
                            character: 10
                        }
                    },
                    kind: vscode_languageserver_1.DocumentHighlightKind.Write
                },
                {
                    range: {
                        start: {
                            line: 0,
                            character: 20
                        },
                        end: {
                            line: 0,
                            character: 23
                        }
                    },
                    kind: vscode_languageserver_1.DocumentHighlightKind.Read
                }
            ]);
        });
        it('provide document highlight for style attribute', () => {
            const { plugin, document } = setup('<div style="position: relative"></div>');
            const highlight = plugin.findDocumentHighlight(document, vscode_languageserver_1.Position.create(0, 13));
            assert.deepStrictEqual(highlight, [
                {
                    range: {
                        start: {
                            line: 0,
                            character: 12
                        },
                        end: {
                            line: 0,
                            character: 20
                        }
                    },
                    kind: vscode_languageserver_1.DocumentHighlightKind.Read
                }
            ]);
        });
        it('provide word highlight for unsupported languages', () => {
            const { plugin, document } = setup('<style lang="postcss">.hi {}</style>');
            const highlight = plugin.findDocumentHighlight(document, vscode_languageserver_1.Position.create(0, 25));
            assert.deepStrictEqual(highlight, [
                {
                    range: {
                        start: {
                            line: 0,
                            character: 22
                        },
                        end: {
                            line: 0,
                            character: 25
                        }
                    },
                    kind: vscode_languageserver_1.DocumentHighlightKind.Text
                }
            ]);
        });
    });
});
//# sourceMappingURL=CSSPlugin.test.js.map