"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());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __spreadArrays = (this && this.__spreadArrays) || function () {
    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
    for (var r = Array(s), k = 0, i = 0; i < il; i++)
        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
            r[k] = a[j];
    return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
var chai_1 = require("chai");
var paperclip_utils_1 = require("paperclip-utils");
var utils_1 = require("../utils");
describe(__filename + "#", function () {
    [
        // basic parsing
        [
            {
                "/entry.pc": "Hello World"
            },
            {},
            "<style></style>Hello World"
        ],
        [
            {
                "/entry.pc": "<span>more text</span>"
            },
            {},
            "<style></style><span data-pc-80f4925f>more text</span>"
        ],
        // styles
        [
            {
                "/entry.pc": "\n          <style>\n            span {\n              color: red;\n            }\n          </style>\n          <span>more text</span>\n        "
            },
            {},
            "\n      <style>span[data-pc-80f4925f] { color:red; }</style><span data-pc-80f4925f>more text</span> \n      "
        ],
        // components
        [
            {
                "/button.pc": "\n          <style>\n            span {\n              color: red;\n            }\n          </style>\n          <span export component as=\"default\">{children}!</span>\n\n        ",
                "/entry.pc": "\n          <import as=\"something\" src=\"./button.pc\"  />\n          <something>hello world</something>\n        "
            },
            {},
            "\n      <style>span[data-pc-1d7dbc06] { color:red; }</style><span data-pc-1d7dbc06>hello world!</span>"
        ],
        // basic css
        [
            {
                "/button.pc": "\n          <style>\n            /* indivisual selectors */\n            .class {\n              color: blue;\n            }\n            .a1.b1 {color: blue;}\n            .a.b.c {color: blue;}\n            .a.b {color: blue;}\n\n            .class[a] {color: blue;}\n            .class1.class2 {color: blue;}\n            .class1 .class2 {color: blue;}\n            #id {color: blue;}\n            * {color: blue;}\n            element {color: blue;}\n            element.class {color: blue;}\n            [attribute] {color: blue;}\n            [attribute=value]  {color: blue;}\n            [attribute=\"value\"]  {color: blue;}\n            [attribute='value']  {color: blue;}\n            /*[attribute~='value']  {color: blue;}\n            [attribute^='value']  {color: blue;}\n            [attribute$='value']  {color: blue;}\n            [attribute$='value']  {color: blue;}\n            [attribute*='value']  {}*/\n            div[attr1][attr1]  {color: blue;}\n            :active {color: blue;}\n            ::active {color: blue;}\n            element::active {color: blue;}\n            ::after {color: blue;}\n\n            /* functions */\n            ::lang(it) {color: blue;}\n            p::lang(it) {color: blue;}\n            :not(p) {color: blue;}\n            :nth-child(5) {color: blue;}\n            :placeholder {color: blue;}\n\n            /* groups */\n            element1, element2 {color: blue;}\n            element, .class, #id.class {color: blue;}\n\n            /* descendent */\n            element1 element2 {color: blue;}\n            element1.class element2[attr][attr2] {color: blue;}\n            element1.class element2[attr], #id.group {color: blue;}\n\n            /* children */\n            element1 > element2 {color: blue;}\n            element1 > .child .descendent {color: blue;}\n            element1 > .child .descendent, [group-attr=\"something\"] {color: blue;}\n\n            /* next sibling */\n            element1 + element2 {color: blue;}\n\n            /* sibling */\n            element1 ~ element2 {color: blue;}\n\n            /* media queries */\n            @media only screen and (max-width: 600px) {\n              div {\n                color: red;\n              }\n            }\n\n            /* keyframes */\n            @keyframes mymove {\n              from {top: 0px;}\n              to {top: 200px;}\n            }\n            \n          </style>\n          <span export component as=\"default\">{children}!</span>\n\n        ",
                "/entry.pc": "\n          <import as=\"something\" src=\"./button.pc\"  />\n          <something>hello world</something>\n        "
            },
            {},
            "<style>[class]._1d7dbc06_class { color:blue; } [class]._1d7dbc06_a1[class]._1d7dbc06_b1 { color:blue; } [class]._1d7dbc06_a[class]._1d7dbc06_b[class]._1d7dbc06_c { color:blue; } [class]._1d7dbc06_a[class]._1d7dbc06_b { color:blue; } [class]._1d7dbc06_class[a] { color:blue; } [class]._1d7dbc06_class1[class]._1d7dbc06_class2 { color:blue; } [class]._1d7dbc06_class1 [class]._1d7dbc06_class2 { color:blue; } #id[data-pc-1d7dbc06] { color:blue; } [data-pc-1d7dbc06] { color:blue; } element[data-pc-1d7dbc06] { color:blue; } element[class]._1d7dbc06_class { color:blue; } [attribute][data-pc-1d7dbc06] { color:blue; } [attribute=value][data-pc-1d7dbc06] { color:blue; } [attribute=\"value\"][data-pc-1d7dbc06] { color:blue; } [attribute='value'][data-pc-1d7dbc06] { color:blue; } div[attr1][attr1][data-pc-1d7dbc06] { color:blue; } [data-pc-1d7dbc06]:active { color:blue; } [data-pc-1d7dbc06]::active { color:blue; } element::active[data-pc-1d7dbc06] { color:blue; } [data-pc-1d7dbc06]::after { color:blue; } [data-pc-1d7dbc06]:lang(it) { color:blue; } p:lang(it)[data-pc-1d7dbc06] { color:blue; } [data-pc-1d7dbc06]:not(p[data-pc-1d7dbc06]) { color:blue; } [data-pc-1d7dbc06]:nth-child(5) { color:blue; } [data-pc-1d7dbc06]:placeholder { color:blue; } element1[data-pc-1d7dbc06] { color:blue; } element2[data-pc-1d7dbc06] { color:blue; } element[data-pc-1d7dbc06] { color:blue; } [class]._1d7dbc06_class { color:blue; } #id[class]._1d7dbc06_class { color:blue; } element1[data-pc-1d7dbc06] element2[data-pc-1d7dbc06] { color:blue; } element1[class]._1d7dbc06_class element2[attr][attr2][data-pc-1d7dbc06] { color:blue; } element1[class]._1d7dbc06_class element2[attr][data-pc-1d7dbc06] { color:blue; } #id[class]._1d7dbc06_group { color:blue; } element1[data-pc-1d7dbc06] > element2[data-pc-1d7dbc06] { color:blue; } element1[data-pc-1d7dbc06] > [class]._1d7dbc06_child [class]._1d7dbc06_descendent { color:blue; } element1[data-pc-1d7dbc06] > [class]._1d7dbc06_child [class]._1d7dbc06_descendent { color:blue; } [group-attr=\"something\"][data-pc-1d7dbc06] { color:blue; } element1[data-pc-1d7dbc06] + element2[data-pc-1d7dbc06] { color:blue; } element1[data-pc-1d7dbc06] ~ element2[data-pc-1d7dbc06] { color:blue; } @media only screen and (max-width: 600px) { div[data-pc-1d7dbc06] { color:red; } } @keyframes _1d7dbc06_mymove { from { top:0px; } to { top:200px; } }</style><span data-pc-1d7dbc06>hello world!</span>"
            // TODO - import css
        ],
        [
            // parse different tag names
            {
                "/entry.pc": "\n          <span component as=\"test\">\n          {_someRef}\n          {_some5ref}\n          {_ref}\n          {$$ref}\n          </span>\n\n          <test \n            _someRef=\"a\" \n            _some5ref=\"b\" \n            _ref=\"c\"\n            $$ref=\"d\"\n          />\n        "
            },
            {},
            "<style></style><span data-pc-80f4925f>abcd</span>"
        ],
        [
            // parse different tag names
            {
                "/entry.pc": "\n          <span component as=\"test\">{a} b</span>\n          <test a=\"c\" />\n        "
            },
            {},
            "<style></style><span data-pc-80f4925f>c b</span>"
        ],
        [
            // class names prefixed with scope
            {
                "/entry.pc": "\n          <span component as=\"test\" class=\"something something2\">\n          </span>\n          <test />\n        "
            },
            {},
            "<style></style><span class=\"_80f4925f_something something _80f4925f_something2 something2\" data-pc-80f4925f></span>"
        ],
        [
            // class name isn't used if not explicitly defined in component
            {
                "/entry.pc": "\n          <import as=\"Message\" src=\"./message.pc\" />\n          <Message class=\"red\" />\n        ",
                // ensure that root is span
                "/message.pc": "<span export component as=\"default\" class=\"blue\">\n            message\n          </span>"
            },
            {},
            "<style></style><span class=\"_1acb798_blue blue\" data-pc-1acb798>message </span>"
        ],
        [
            // class piercing
            {
                "/entry.pc": "\n          <import as=\"Message\" src=\"./message.pc\" />\n          <Message class=\"$red\" />\n        ",
                // ensure that root is span
                "/message.pc": "<span export component as=\"default\" {class}>\n            message\n          </span>"
            },
            {},
            "<style></style><span class=\"_80f4925f_red red\" data-pc-1acb798>message </span>"
        ],
        [
            // no class mod for components if shadow pierce operator is not defined
            {
                "/entry.pc": "\n          <import as=\"Message\" src=\"./message.pc\" />\n          <Message class=\"red\" />\n        ",
                // ensure that root is span
                "/message.pc": "<span export component as=\"default\" {class}>\n            message\n          </span>"
            },
            {},
            "<style></style><span class=\"_1acb798_red red\" data-pc-1acb798>message </span>"
        ],
        [
            // style classes prefixed with scope
            {
                "/entry.pc": "\n          <style>\n            .something > .something2 {\n              color: blue;\n            }\n          </style>\n          <span component as=\"test\" class=\"something2\">\n          </span>\n          <test />\n        "
            },
            {},
            "<style>[class]._80f4925f_something > [class]._80f4925f_something2 { color:blue; }</style><span class=\"_80f4925f_something2 something2\" data-pc-80f4925f></span>"
        ],
        [
            // no class mod for components if shadow pierce operator is not defined
            {
                "/entry.pc": "\n          <import as=\"Message\" src=\"./message.pc\" />\n          <Message class=\"$red\" />\n          <span />\n        ",
                // ensure that root is span
                "/message.pc": "<span export component as=\"default\" class=\"blue {class}\">\n            message\n          </span>"
            },
            {},
            "<style></style><span class=\"_1acb798_blue blue _80f4925f_red red\" data-pc-1acb798>message </span><span data-pc-80f4925f></span>"
        ],
        // [
        //   // nexted style declarations
        //   {
        //     "/entry.pc": `
        //       <style>
        //         :global(.a) {
        //           .b {
        //           }
        //         }
        //       </style>
        //       <div>ok</div>
        //     `
        //   },
        //   {},
        //   `<style>.a { color:blue; display:block; } .a--secondary { } .a--secondary--thirdly { color:blue; } .a.c { } .a ._80f4925f_d { } .a > .e { color:blue; } .a > .e-f { color:red; }</style><div data-pc-80f4925f>ok</div>`
        // ],
        [
            // nexted style declarations
            {
                "/entry.pc": "\n          <style>\n            :global(.a) {\n              &--secondary {\n                &--thirdly {\n                  color: blue;\n                }\n              }\n              color: blue;\n              &.c {\n\n              }\n              display: block;\n              & .d {\n\n              }\n              & > :global(.e) {\n                &-f {\n                  color: red;\n                }\n                color: blue;\n              }\n            }\n          </style>\n          <div>ok</div>\n        "
            },
            {},
            "<style>[class].a { color:blue; display:block; } [class].a--secondary--thirdly { color:blue; } [class].a > [class].e { color:blue; } [class].a > [class].e-f { color:red; }</style><div data-pc-80f4925f>ok</div>"
        ],
        [
            // no class mod for components if shadow pierce operator is not defined
            {
                "/entry.pc": "\n          <import as=\"Message\" src=\"./message.pc\" />\n          <Message component as=\"test\">\n            {children}!\n          </Message>\n          <test>child</test>\n        ",
                // ensure that root is span
                "/message.pc": "<span export component as=\"default\">\n            {children}\n          </span>"
            },
            {},
            "<style></style><span data-pc-1acb798>child! </span>"
        ],
        [
            // no class mod for components if shadow pierce operator is not defined
            {
                "/entry.pc": "\n          <style>\n            .a, .b {\n              &--c {\n                color: blue;\n              }\n            }\n          </style>\n        "
            },
            {},
            "<style>[class]._80f4925f_a--c { color:blue; } [class]._80f4925f_b--c { color:blue; }</style>"
        ],
        [
            // no class mod for components if shadow pierce operator is not defined
            {
                "/entry.pc": "\n          <style>\n            :global(.a, .b) {\n              &--c {\n                color: blue;\n              }\n            }\n          </style>\n        "
            },
            {},
            "<style>[class].a--c { color:blue; } [class].b--c { color:blue; }</style>"
        ],
        [
            // no class mod for components if shadow pierce operator is not defined
            {
                "/entry.pc": "\n          <style>\n            :global(.a, .b) {\n              &--c {\n                color: blue;\n              }\n            }\n          </style>\n        "
            },
            {},
            "<style>[class].a--c { color:blue; } [class].b--c { color:blue; }</style>"
        ],
        [
            // no class mod for components if shadow pierce operator is not defined
            {
                "/entry.pc": "\n          <style>\n            .a {\n              &--c {\n                color: blue;\n              }\n            }\n          </style>\n        "
            },
            {},
            "<style>[class]._80f4925f_a--c { color:blue; }</style>"
        ],
        [
            // no class mod for components if shadow pierce operator is not defined
            {
                "/entry.pc": "\n          <style>\n            :global(.a, .b) {\n              &--c {\n                color: blue;\n              }\n            }\n          </style>\n        "
            },
            {},
            "<style>[class].a--c { color:blue; } [class].b--c { color:blue; }</style>"
        ],
        [
            {
                "/entry.pc": "\n          <style>\n            @mixin a {\n              color: b;\n            }\n            \n            .a {\n              @include a;\n              background: c;\n            }\n          </style>\n        "
            },
            {},
            "<style>[class]._80f4925f_a { color:b; background:c; }</style>"
        ],
        [
            {
                "/entry.pc": "\n          <style>\n            @mixin a {\n              color: b;\n            }\n            @mixin b {\n              @include a;\n              color: c;\n            }\n            \n            .c {\n              @include b;\n              background: c;\n            }\n          </style>\n        "
            },
            {},
            "<style>[class]._80f4925f_c { color:b; color:c; background:c; }</style>"
        ],
        [
            {
                "/entry.pc": "\n          <import as=\"a\" src=\"./module.pc\" />\n          <style>\n            @export {\n              .c {\n                @include a.b;\n                background: c;\n              }\n            }\n          </style>\n        ",
                "/module.pc": "\n          <import as=\"a\" src=\"./module2.pc\" />\n          <style>\n            @export {\n              @mixin b {\n                @include a.b;\n                color: blue;\n              }\n            }          \n          </style>\n        ",
                "/module2.pc": "\n          <style>\n            @export {\n              @mixin b {\n                color: orange;\n              }\n            }          \n          </style>\n        "
            },
            {},
            "<style>[class]._80f4925f_c { color:orange; color:blue; background:c; }</style>"
        ],
        [
            {
                "/entry.pc": "\n          <import as=\"mod\" src=\"./module.pc\" />\n          <mod>\n            <mod.item>a</mod.item>\n            <mod.item>b</mod.item>\n            <mod.item>c</mod.item>\n          </mod>\n        ",
                "/module.pc": "\n          <div export component as=\"default\">\n            {children}\n          </div>\n          <span export component as=\"item\">\n            {children}\n          </span>\n        "
            },
            {},
            "<style></style><div data-pc-139cec8e><span data-pc-139cec8e>a</span><span data-pc-139cec8e>b</span><span data-pc-139cec8e>c</span></div>"
        ],
        [
            {
                "/entry.pc": "\n          <style>\n            div {\n              &[b] {\n                color: blue;\n              }\n            }\n          </style>\n\n        "
            },
            {},
            "<style>div[data-pc-80f4925f][b] { color:blue; }</style>"
        ],
        [
            {
                "/entry.pc": "\n          <style>\n            div {\n              &[data-hover], &:hover {\n                color: orange;\n              }\n              & [data-hover], :hover {\n                color: blue;\n              }\n            }\n          </style>\n        "
            },
            {},
            "<style>div[data-pc-80f4925f][data-hover] { color:orange; } div[data-pc-80f4925f]:hover { color:orange; } div[data-pc-80f4925f] [data-hover][data-pc-80f4925f] { color:blue; } div[data-pc-80f4925f] [data-pc-80f4925f]:hover { color:blue; }</style>"
        ],
        [
            {
                "/entry.pc": "\n          <style>\n            a {\n              &-b, &-b2 {\n                &-c, &-c2 {\n                  color: blue;\n                }\n              }\n            }\n          </style>\n        "
            },
            {},
            "<style>a[data-pc-80f4925f]-b-c { color:blue; } a[data-pc-80f4925f]-b-c2 { color:blue; } a[data-pc-80f4925f]-b2-c { color:blue; } a[data-pc-80f4925f]-b2-c2 { color:blue; }</style>"
        ],
        // & + &
        [
            {
                "/entry.pc": "\n          <style>\n            div {\n              & + & {\n                color: blue;\n              }\n            }\n          </style>\n        "
            },
            {},
            "<style>div[data-pc-80f4925f] + div[data-pc-80f4925f] { color:blue; }</style>"
        ],
        [
            {
                "/entry.pc": "\n          <style>\n            a::before {\n              content: \"blue\";\n            }\n          </style>\n        "
            },
            {},
            "<style>a::before[data-pc-80f4925f] { content:\"blue\"; }</style>"
        ],
        [
            {
                "/entry.pc": "\n          <style>\n            @keyframes example {\n              0% {background-color: red;}\n              100% {background-color: yellow;}\n            }\n\n            div {\n              animation-name: example;\n              animation: example 5s infinite;\n            }\n          </style>\n        "
            },
            {},
            "<style>@keyframes _80f4925f_example { 0% { background-color:red; } 100% { background-color:yellow; } } div[data-pc-80f4925f] { animation-name:_80f4925f_example; animation:_80f4925f_example 5s infinite; }</style>"
        ],
        [
            {
                "/entry.pc": "\n          <style>\n            @mixin a {\n              color: red;\n            }\n            @mixin b {\n              color: blue;\n            }\n\n            div {\n              @include a;\n              @include b;\n            }\n          </style>\n        "
            },
            {},
            "<style>div[data-pc-80f4925f] { color:red; color:blue; }</style>"
        ],
        [
            {
                "/entry.pc": "\n          <import as=\"test\" src=\"./module.pc\" />\n          <div className=\"$test.button\"></div>\n        ",
                "/module.pc": "\n          <style>\n            @export {\n              .button {\n                color: red;\n              }\n            }\n          </style>\n        "
            },
            {},
            "<style>[class]._139cec8e_button { color:red; }</style><div className=\"_139cec8e_button button\" data-pc-80f4925f></div>"
        ],
        [
            {
                "/entry.pc": "\n          <style>\n            [a=\"b\"] {\n              color: blue;\n            }\n            [a~=\"c\"] {\n              color: purple;\n            }\n            [a^=\"c2\"] {\n              color: black;\n            }\n            [a$=\"c3\"] {\n              color: orange;\n            }\n          </style>\n        "
            },
            {},
            "<style>[a=\"b\"][data-pc-80f4925f] { color:blue; } [a~=\"c\"][data-pc-80f4925f] { color:purple; } [a^=\"c2\"][data-pc-80f4925f] { color:black; } [a$=\"c3\"][data-pc-80f4925f] { color:orange; }</style>"
        ],
        [
            {
                "/entry.pc": "\n          <style>\n            .a {\n              & + b {\n                &:hover:active:test {\n                  color: blue;\n                }\n              }\n            }\n          </style>\n        "
            },
            {},
            "<style>[class]._80f4925f_a + b[data-pc-80f4925f]:hover:active:test { color:blue; }</style>"
        ]
    ].forEach(function (_a) {
        var graph = _a[0], expectedHTML = _a[2];
        it("can render \"" + JSON.stringify(graph) + "\"", function () { return __awaiter(void 0, void 0, void 0, function () {
            var engine, _a, sheet, preview, sheets, sheetText, buffer;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0: return [4 /*yield*/, utils_1.createMockEngine(graph)];
                    case 1:
                        engine = _b.sent();
                        return [4 /*yield*/, engine.run("/entry.pc")];
                    case 2:
                        _a = _b.sent(), sheet = _a.sheet, preview = _a.preview, sheets = _a.importedSheets;
                        sheetText = __spreadArrays(sheets.map(function (_a) {
                            var sheet = _a.sheet;
                            return sheet;
                        }), [sheet]).map(function (sheet) {
                            return paperclip_utils_1.stringifyCSSSheet(sheet, { protocol: "" });
                        })
                            .join("\n")
                            .trim();
                        buffer = "<style>" + sheetText + "</style>" + paperclip_utils_1.stringifyVirtualNode(preview);
                        chai_1.expect(buffer.replace(/[\r\n\t\s]+/g, " ").trim()).to.eql(String(expectedHTML)
                            .replace(/[\r\n\t\s]+/g, " ")
                            .trim());
                        return [2 /*return*/];
                }
            });
        }); });
    });
});
