Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[testing] chai plugins #729

Closed
3 tasks
nweldev opened this issue Aug 13, 2019 · 6 comments · Fixed by #742
Closed
3 tasks

[testing] chai plugins #729

nweldev opened this issue Aug 13, 2019 · 6 comments · Fixed by #742

Comments

@nweldev
Copy link
Contributor

nweldev commented Aug 13, 2019

Using chai plugins with @open-wc/testing is tedious and undocumented.

root cause & context

Chai and most chai plugins aren't exposed as es modules.

This led to the creation of @bundled-es-modules/chai and the following issues:

Thankfully, there still is some Chai Plugins which support ESM:

But these projects don't seem to be actively maintained anymore. So, there isn't any advancement on this right now.

current options

Developers using @open-wc/testing do not have many good options when using chai plugins.

A. esm fork

👉 nathanboktae/chai-dom#38 (comment)

B. define plugins globally

Most chai plugins (chai-dom, sinon-chai, chai-datetime) fall back to using window.chai.use when AMD, CommonJS, etc... aren't available:

Some others, like chai-http, only provide a "global import" syntax. We can use those the same way as showen bellow, by using a static import statement and then calling chai.use.

So, we can:

  1. install the "official" (non esm) packages
    npm i -D chai-dom sinon-chai

  2. import chai from bundled-esm-modules/chai, add it to window.chai, and then dynamically import the plugins packages:

https://github.com/noelmace/devcards/blob/cf0fe84deb338c47699b2aa289100b9834a68e84/test/utils/chai-plugins.js#L1-L6

FYI, window.chai doesn't exist in the imported package if you use static import statements instead, but I don't see any workaround for that.

  1. add this file to karma files:

https://github.com/noelmace/devcards/blob/cf0fe84deb338c47699b2aa289100b9834a68e84/karma.owc.conf.js#L8-L9

proposals for resolution

  1. I feel like option B is the best workaround right now. We could add it to the doc. What do you think?
  2. Regarding option A, as most Chai plugins aren't maintained anymore, and owners don't answer issues, @open-wc / @daKmoR & folks, could provide some esm-modules forks (at least for chai-dom and sinon-chai) and actively maintain those.

BTW, I'm personally concerned about Chai and its plugins maintenance. Even if they are way more popular right now, this is why I tend to favor jasmine for WC testing. Could you explain why Mocha/Chai was chosen for open-wc/testing in the first place?

@daKmoR
Copy link
Member

daKmoR commented Aug 16, 2019

the status of chai plugins is the same as for many other libraries when it comes to es modules... adoption is slow as node is the primary target for many... and node by default still does not support es modules 😭

if there is a simple way to use the "normal" chai and not a bundled-es-modules version then we should totally do and recommend that... 🤗
if we can't do it for chai but somehow we can do it for plugins - that also would be a win 👍

so if you could do a PR for option B that would be awesome 💪

Just to be sure our primary goal is still to test code natively in the browser (e.g. no transformations* or adjustments to the code before it gets shipped to the browser)**.

Could you explain why Mocha/Chai was chosen for open-wc/testing in the first place?

According to our defined goal of using native es modules without any transformations in the browser mocha/chai was our best bet (back then I knew at least how to make es modules work in mocha; while I did not know it for jasmine) how is support for es modules in jasmine nowadays?

* with the exception of bare module
** when testing on older browsers transformations are applied

@nweldev
Copy link
Contributor Author

nweldev commented Aug 16, 2019

The jasmine framework doesn't need any transformation to the code if you use Karma-jasmine with karma-esm, but the CLI doesn't support ESM for now. See my comment on the related issue ☝️

It actually does even less transformation to your source code than Chai/Mocha.

Here is an example:

source file
import { css, html } from '../../utils/tags.js';
import { cardHtml } from '../flashcard/flashcard.js';

/**
 * Web Component representing a stacked flashcard deck
 */
class CardStackComponent extends HTMLElement {
  constructor() {
    super();

    const shadowRoot = this.attachShadow({ mode: 'open' });

    const style = document.createElement('style');

    style.innerText = css`
      .card-wrapper {
        height: 0;
        margin-top: -5px;
      }

      .cards-stack {
        height: calc(var(--card-width) * 1.39);
      }

      dc-flashcard {
        height: 500px;
        width: 300px;
        overflow: scroll;
      }

      .empty-box {
        text-align: center;
      }

      i {
        background-size: contain;
        height: var(--icons-size, 50px);
        width: var(--icons-size, 50px);
        display: inline-block;
      }

      i.reload {
        background-image: url("${new URL('./reload.svg', import.meta.url).toString()}");
      }
    `;

    shadowRoot.appendChild(style);

    this.container = document.createElement('div');
    this.container.classList.add('cards-stack');
    shadowRoot.appendChild(this.container);

    /**
     * the deck of cards currently rendered
     * @private
     * @type {Array.<Card>}
     */
    this.currentDeck = null;

    /**
     * @private
     */
    this._collection = null;

    this.emptyStackEvent = new CustomEvent('empty-stack', {
      bubbles: false,
      cancelable: false,
      composed: true
    });

    this.reloadFromCollectionEvent = new CustomEvent('reload-collection', {
      bubbles: false,
      cancelable: false,
      composed: true
    });

    this.renderNoCollection();
  }

  /**
   * **Immutable** collection of cards
   * Updating this property will cause this component to render **all** its content.
   * Do so **only** if you need to load an entire new collection of cards!
   * @type {Array.<Cards>}
   */
  set collection(collection) {
    this.propertyChangedCallback('collection', this._collection, collection);
  }

  /**
   * @type {Array.<Cards>}
   */
  get collection() {
    return this._collection;
  }

  /**
   * remove the last (top) card from the deck
   * @returns  {{card: Card, element: HTMLElement}} - removed card object and the corresponsing HTMLElement
   */
  pop() {
    const lastCard = this.currentDeck[this.currentDeck.length - 1];
    this.currentDeck = this.currentDeck.slice(0, -1);
    const lastCardElmt = this.container.lastElementChild;
    this.container.removeChild(lastCardElmt);
    if (this.currentDeck.length <= 0) {
      this.dispatchEvent(this.emptyStackEvent);
      this.renderEmptyMsg();
    }
    return { card: lastCard, element: lastCardElmt };
  }

  renderEmptyMsg() {
    const emptyBox = document.createElement('div');
    emptyBox.classList.add('empty-box');
    emptyBox.innerHTML = html`
      <p>You finished this session! Click the reload button to review this collection again.</p>
      <i class="reload"></i>
    `;
    emptyBox.querySelector('.reload').addEventListener('click', () => {
      this.render(this._collection);
      this.dispatchEvent(this.reloadFromCollectionEvent);
    });
    this.container.appendChild(emptyBox);
  }

  renderNoCollection() {
    this.container.innerHTML = `<p>No valid collection</p>`;
  }

  /**
   *
   */
  moveBack() {
    const lastCard = this.currentDeck[this.currentDeck.length - 1];
    this.currentDeck = [lastCard, ...this.currentDeck.slice(0, -1)];
    const elmt = this.container.lastElementChild;
    this.container.prepend(elmt);
    elmt.firstElementChild.removeAttribute('flipped');
  }

  /**
   * @private
   * @param {*} prop
   * @param {*} oldValue
   * @param {*} newValue
   */
  propertyChangedCallback(prop, oldValue, newValue) {
    // cards collections are considered immutable
    if (prop === 'collection' && oldValue !== newValue) {
      if(Array.isArray(newValue) && newValue.length > 0) {
        this.render([...newValue]);
        this._collection = newValue;
      } else {
        this.renderNoCollection();
        this._collection = null;
        this.currentDeck = null;
      }
    }
  }

  render(cards) {
    if (!this.currentDeck || cards.length !== this.currentDeck.length) {
      this.container.style.paddingTop = `${cards.length * 5}px`;
    }
    this.container.innerHTML = cards
      .map(
        card => `
          <div class="card-wrapper">
            ${cardHtml(card)}
          </div>
        `
      )
      .join('');
    this.currentDeck = cards;
  }
}

customElements.define('dc-stack', CardStackComponent);

Using karma-jasmine, I get exactly the same file in the browser, except the link to the source-map is added at the end. But with Mocha, I get:

transformed by Mocha/Chai
var cov_cpzqxydh8 = function () {
  var path = "/home/noel/git/web-on-fire/flashcards-app/src/components/card-stack/card-stack.js";
  var hash = "ee059f4e606dadd64733046accbba36270bd5104";
  var global = new Function("return this")();
  var gcv = "__coverage__";
  var coverageData = {
    path: "/home/noel/git/web-on-fire/flashcards-app/src/components/card-stack/card-stack.js",
    statementMap: {
      "0": {
        start: {
          line: 9,
          column: 4
        },
        end: {
          line: 9,
          column: 12
        }
      },
      "1": {
        start: {
          line: 11,
          column: 23
        },
        end: {
          line: 11,
          column: 58
        }
      },
      "2": {
        start: {
          line: 13,
          column: 18
        },
        end: {
          line: 13,
          column: 49
        }
      },
      "3": {
        start: {
          line: 15,
          column: 4
        },
        end: {
          line: 45,
          column: 6
        }
      },
      "4": {
        start: {
          line: 47,
          column: 4
        },
        end: {
          line: 47,
          column: 34
        }
      },
      "5": {
        start: {
          line: 49,
          column: 4
        },
        end: {
          line: 49,
          column: 51
        }
      },
      "6": {
        start: {
          line: 50,
          column: 4
        },
        end: {
          line: 50,
          column: 48
        }
      },
      "7": {
        start: {
          line: 51,
          column: 4
        },
        end: {
          line: 51,
          column: 43
        }
      },
      "8": {
        start: {
          line: 58,
          column: 4
        },
        end: {
          line: 58,
          column: 28
        }
      },
      "9": {
        start: {
          line: 63,
          column: 4
        },
        end: {
          line: 63,
          column: 28
        }
      },
      "10": {
        start: {
          line: 65,
          column: 4
        },
        end: {
          line: 69,
          column: 7
        }
      },
      "11": {
        start: {
          line: 71,
          column: 4
        },
        end: {
          line: 75,
          column: 7
        }
      },
      "12": {
        start: {
          line: 77,
          column: 4
        },
        end: {
          line: 77,
          column: 30
        }
      },
      "13": {
        start: {
          line: 87,
          column: 4
        },
        end: {
          line: 87,
          column: 77
        }
      },
      "14": {
        start: {
          line: 94,
          column: 4
        },
        end: {
          line: 94,
          column: 28
        }
      },
      "15": {
        start: {
          line: 102,
          column: 21
        },
        end: {
          line: 102,
          column: 66
        }
      },
      "16": {
        start: {
          line: 103,
          column: 4
        },
        end: {
          line: 103,
          column: 53
        }
      },
      "17": {
        start: {
          line: 104,
          column: 25
        },
        end: {
          line: 104,
          column: 56
        }
      },
      "18": {
        start: {
          line: 105,
          column: 4
        },
        end: {
          line: 105,
          column: 45
        }
      },
      "19": {
        start: {
          line: 106,
          column: 4
        },
        end: {
          line: 109,
          column: 5
        }
      },
      "20": {
        start: {
          line: 107,
          column: 6
        },
        end: {
          line: 107,
          column: 47
        }
      },
      "21": {
        start: {
          line: 108,
          column: 6
        },
        end: {
          line: 108,
          column: 28
        }
      },
      "22": {
        start: {
          line: 110,
          column: 4
        },
        end: {
          line: 110,
          column: 53
        }
      },
      "23": {
        start: {
          line: 114,
          column: 21
        },
        end: {
          line: 114,
          column: 50
        }
      },
      "24": {
        start: {
          line: 115,
          column: 4
        },
        end: {
          line: 115,
          column: 40
        }
      },
      "25": {
        start: {
          line: 116,
          column: 4
        },
        end: {
          line: 119,
          column: 6
        }
      },
      "26": {
        start: {
          line: 120,
          column: 4
        },
        end: {
          line: 123,
          column: 7
        }
      },
      "27": {
        start: {
          line: 121,
          column: 6
        },
        end: {
          line: 121,
          column: 36
        }
      },
      "28": {
        start: {
          line: 122,
          column: 6
        },
        end: {
          line: 122,
          column: 57
        }
      },
      "29": {
        start: {
          line: 124,
          column: 4
        },
        end: {
          line: 124,
          column: 41
        }
      },
      "30": {
        start: {
          line: 128,
          column: 4
        },
        end: {
          line: 128,
          column: 60
        }
      },
      "31": {
        start: {
          line: 135,
          column: 21
        },
        end: {
          line: 135,
          column: 66
        }
      },
      "32": {
        start: {
          line: 136,
          column: 4
        },
        end: {
          line: 136,
          column: 68
        }
      },
      "33": {
        start: {
          line: 137,
          column: 17
        },
        end: {
          line: 137,
          column: 48
        }
      },
      "34": {
        start: {
          line: 138,
          column: 4
        },
        end: {
          line: 138,
          column: 33
        }
      },
      "35": {
        start: {
          line: 139,
          column: 4
        },
        end: {
          line: 139,
          column: 54
        }
      },
      "36": {
        start: {
          line: 150,
          column: 4
        },
        end: {
          line: 159,
          column: 5
        }
      },
      "37": {
        start: {
          line: 151,
          column: 6
        },
        end: {
          line: 158,
          column: 7
        }
      },
      "38": {
        start: {
          line: 152,
          column: 8
        },
        end: {
          line: 152,
          column: 35
        }
      },
      "39": {
        start: {
          line: 153,
          column: 8
        },
        end: {
          line: 153,
          column: 36
        }
      },
      "40": {
        start: {
          line: 155,
          column: 8
        },
        end: {
          line: 155,
          column: 34
        }
      },
      "41": {
        start: {
          line: 156,
          column: 8
        },
        end: {
          line: 156,
          column: 32
        }
      },
      "42": {
        start: {
          line: 157,
          column: 8
        },
        end: {
          line: 157,
          column: 32
        }
      },
      "43": {
        start: {
          line: 163,
          column: 4
        },
        end: {
          line: 165,
          column: 5
        }
      },
      "44": {
        start: {
          line: 164,
          column: 6
        },
        end: {
          line: 164,
          column: 64
        }
      },
      "45": {
        start: {
          line: 166,
          column: 4
        },
        end: {
          line: 174,
          column: 16
        }
      },
      "46": {
        start: {
          line: 168,
          column: 16
        },
        end: {
          line: 172,
          column: 9
        }
      },
      "47": {
        start: {
          line: 175,
          column: 4
        },
        end: {
          line: 175,
          column: 29
        }
      },
      "48": {
        start: {
          line: 179,
          column: 0
        },
        end: {
          line: 179,
          column: 54
        }
      }
    },
    fnMap: {
      "0": {
        name: "(anonymous_0)",
        decl: {
          start: {
            line: 8,
            column: 2
          },
          end: {
            line: 8,
            column: 3
          }
        },
        loc: {
          start: {
            line: 8,
            column: 16
          },
          end: {
            line: 78,
            column: 3
          }
        },
        line: 8
      },
      "1": {
        name: "(anonymous_1)",
        decl: {
          start: {
            line: 86,
            column: 2
          },
          end: {
            line: 86,
            column: 3
          }
        },
        loc: {
          start: {
            line: 86,
            column: 29
          },
          end: {
            line: 88,
            column: 3
          }
        },
        line: 86
      },
      "2": {
        name: "(anonymous_2)",
        decl: {
          start: {
            line: 93,
            column: 2
          },
          end: {
            line: 93,
            column: 3
          }
        },
        loc: {
          start: {
            line: 93,
            column: 19
          },
          end: {
            line: 95,
            column: 3
          }
        },
        line: 93
      },
      "3": {
        name: "(anonymous_3)",
        decl: {
          start: {
            line: 101,
            column: 2
          },
          end: {
            line: 101,
            column: 3
          }
        },
        loc: {
          start: {
            line: 101,
            column: 8
          },
          end: {
            line: 111,
            column: 3
          }
        },
        line: 101
      },
      "4": {
        name: "(anonymous_4)",
        decl: {
          start: {
            line: 113,
            column: 2
          },
          end: {
            line: 113,
            column: 3
          }
        },
        loc: {
          start: {
            line: 113,
            column: 19
          },
          end: {
            line: 125,
            column: 3
          }
        },
        line: 113
      },
      "5": {
        name: "(anonymous_5)",
        decl: {
          start: {
            line: 120,
            column: 64
          },
          end: {
            line: 120,
            column: 65
          }
        },
        loc: {
          start: {
            line: 120,
            column: 70
          },
          end: {
            line: 123,
            column: 5
          }
        },
        line: 120
      },
      "6": {
        name: "(anonymous_6)",
        decl: {
          start: {
            line: 127,
            column: 2
          },
          end: {
            line: 127,
            column: 3
          }
        },
        loc: {
          start: {
            line: 127,
            column: 23
          },
          end: {
            line: 129,
            column: 3
          }
        },
        line: 127
      },
      "7": {
        name: "(anonymous_7)",
        decl: {
          start: {
            line: 134,
            column: 2
          },
          end: {
            line: 134,
            column: 3
          }
        },
        loc: {
          start: {
            line: 134,
            column: 13
          },
          end: {
            line: 140,
            column: 3
          }
        },
        line: 134
      },
      "8": {
        name: "(anonymous_8)",
        decl: {
          start: {
            line: 148,
            column: 2
          },
          end: {
            line: 148,
            column: 3
          }
        },
        loc: {
          start: {
            line: 148,
            column: 52
          },
          end: {
            line: 160,
            column: 3
          }
        },
        line: 148
      },
      "9": {
        name: "(anonymous_9)",
        decl: {
          start: {
            line: 162,
            column: 2
          },
          end: {
            line: 162,
            column: 3
          }
        },
        loc: {
          start: {
            line: 162,
            column: 16
          },
          end: {
            line: 176,
            column: 3
          }
        },
        line: 162
      },
      "10": {
        name: "(anonymous_10)",
        decl: {
          start: {
            line: 168,
            column: 8
          },
          end: {
            line: 168,
            column: 9
          }
        },
        loc: {
          start: {
            line: 168,
            column: 16
          },
          end: {
            line: 172,
            column: 9
          }
        },
        line: 168
      }
    },
    branchMap: {
      "0": {
        loc: {
          start: {
            line: 106,
            column: 4
          },
          end: {
            line: 109,
            column: 5
          }
        },
        type: "if",
        locations: [{
          start: {
            line: 106,
            column: 4
          },
          end: {
            line: 109,
            column: 5
          }
        }, {
          start: {
            line: 106,
            column: 4
          },
          end: {
            line: 109,
            column: 5
          }
        }],
        line: 106
      },
      "1": {
        loc: {
          start: {
            line: 150,
            column: 4
          },
          end: {
            line: 159,
            column: 5
          }
        },
        type: "if",
        locations: [{
          start: {
            line: 150,
            column: 4
          },
          end: {
            line: 159,
            column: 5
          }
        }, {
          start: {
            line: 150,
            column: 4
          },
          end: {
            line: 159,
            column: 5
          }
        }],
        line: 150
      },
      "2": {
        loc: {
          start: {
            line: 150,
            column: 8
          },
          end: {
            line: 150,
            column: 54
          }
        },
        type: "binary-expr",
        locations: [{
          start: {
            line: 150,
            column: 8
          },
          end: {
            line: 150,
            column: 29
          }
        }, {
          start: {
            line: 150,
            column: 33
          },
          end: {
            line: 150,
            column: 54
          }
        }],
        line: 150
      },
      "3": {
        loc: {
          start: {
            line: 151,
            column: 6
          },
          end: {
            line: 158,
            column: 7
          }
        },
        type: "if",
        locations: [{
          start: {
            line: 151,
            column: 6
          },
          end: {
            line: 158,
            column: 7
          }
        }, {
          start: {
            line: 151,
            column: 6
          },
          end: {
            line: 158,
            column: 7
          }
        }],
        line: 151
      },
      "4": {
        loc: {
          start: {
            line: 151,
            column: 9
          },
          end: {
            line: 151,
            column: 55
          }
        },
        type: "binary-expr",
        locations: [{
          start: {
            line: 151,
            column: 9
          },
          end: {
            line: 151,
            column: 32
          }
        }, {
          start: {
            line: 151,
            column: 36
          },
          end: {
            line: 151,
            column: 55
          }
        }],
        line: 151
      },
      "5": {
        loc: {
          start: {
            line: 163,
            column: 4
          },
          end: {
            line: 165,
            column: 5
          }
        },
        type: "if",
        locations: [{
          start: {
            line: 163,
            column: 4
          },
          end: {
            line: 165,
            column: 5
          }
        }, {
          start: {
            line: 163,
            column: 4
          },
          end: {
            line: 165,
            column: 5
          }
        }],
        line: 163
      },
      "6": {
        loc: {
          start: {
            line: 163,
            column: 8
          },
          end: {
            line: 163,
            column: 69
          }
        },
        type: "binary-expr",
        locations: [{
          start: {
            line: 163,
            column: 8
          },
          end: {
            line: 163,
            column: 25
          }
        }, {
          start: {
            line: 163,
            column: 29
          },
          end: {
            line: 163,
            column: 69
          }
        }],
        line: 163
      }
    },
    s: {
      "0": 0,
      "1": 0,
      "2": 0,
      "3": 0,
      "4": 0,
      "5": 0,
      "6": 0,
      "7": 0,
      "8": 0,
      "9": 0,
      "10": 0,
      "11": 0,
      "12": 0,
      "13": 0,
      "14": 0,
      "15": 0,
      "16": 0,
      "17": 0,
      "18": 0,
      "19": 0,
      "20": 0,
      "21": 0,
      "22": 0,
      "23": 0,
      "24": 0,
      "25": 0,
      "26": 0,
      "27": 0,
      "28": 0,
      "29": 0,
      "30": 0,
      "31": 0,
      "32": 0,
      "33": 0,
      "34": 0,
      "35": 0,
      "36": 0,
      "37": 0,
      "38": 0,
      "39": 0,
      "40": 0,
      "41": 0,
      "42": 0,
      "43": 0,
      "44": 0,
      "45": 0,
      "46": 0,
      "47": 0,
      "48": 0
    },
    f: {
      "0": 0,
      "1": 0,
      "2": 0,
      "3": 0,
      "4": 0,
      "5": 0,
      "6": 0,
      "7": 0,
      "8": 0,
      "9": 0,
      "10": 0
    },
    b: {
      "0": [0, 0],
      "1": [0, 0],
      "2": [0, 0],
      "3": [0, 0],
      "4": [0, 0],
      "5": [0, 0],
      "6": [0, 0]
    },
    _coverageSchema: "43e27e138ebf9cfc5966b082cf9a028302ed4184",
    hash: "ee059f4e606dadd64733046accbba36270bd5104"
  };
  var coverage = global[gcv] || (global[gcv] = {});

  if (coverage[path] && coverage[path].hash === hash) {
    return coverage[path];
  }

  return coverage[path] = coverageData;
}();

import { css, html } from "../../utils/tags.js";
import { cardHtml } from "../flashcard/flashcard.js";
/**
 * Web Component representing a stacked flashcard deck
 */

class CardStackComponent extends HTMLElement {
  constructor() {
    cov_cpzqxydh8.f[0]++;
    cov_cpzqxydh8.s[0]++;
    super();
    const shadowRoot = (cov_cpzqxydh8.s[1]++, this.attachShadow({
      mode: 'open'
    }));
    const style = (cov_cpzqxydh8.s[2]++, document.createElement('style'));
    cov_cpzqxydh8.s[3]++;
    style.innerText = css`
      .card-wrapper {
        height: 0;
        margin-top: -5px;
      }

      .cards-stack {
        height: calc(var(--card-width) * 1.39);
      }

      dc-flashcard {
        height: 500px;
        width: 300px;
        overflow: scroll;
      }

      .empty-box {
        text-align: center;
      }

      i {
        background-size: contain;
        height: var(--icons-size, 50px);
        width: var(--icons-size, 50px);
        display: inline-block;
      }

      i.reload {
        background-image: url("${new URL('./reload.svg', import.meta.url).toString()}");
      }
    `;
    cov_cpzqxydh8.s[4]++;
    shadowRoot.appendChild(style);
    cov_cpzqxydh8.s[5]++;
    this.container = document.createElement('div');
    cov_cpzqxydh8.s[6]++;
    this.container.classList.add('cards-stack');
    cov_cpzqxydh8.s[7]++;
    shadowRoot.appendChild(this.container);
    /**
     * the deck of cards currently rendered
     * @private
     * @type {Array.<Card>}
     */

    cov_cpzqxydh8.s[8]++;
    this.currentDeck = null;
    /**
     * @private
     */

    cov_cpzqxydh8.s[9]++;
    this._collection = null;
    cov_cpzqxydh8.s[10]++;
    this.emptyStackEvent = new CustomEvent('empty-stack', {
      bubbles: false,
      cancelable: false,
      composed: true
    });
    cov_cpzqxydh8.s[11]++;
    this.reloadFromCollectionEvent = new CustomEvent('reload-collection', {
      bubbles: false,
      cancelable: false,
      composed: true
    });
    cov_cpzqxydh8.s[12]++;
    this.renderNoCollection();
  }
  /**
   * **Immutable** collection of cards
   * Updating this property will cause this component to render **all** its content.
   * Do so **only** if you need to load an entire new collection of cards!
   * @type {Array.<Cards>}
   */


  set collection(collection) {
    cov_cpzqxydh8.f[1]++;
    cov_cpzqxydh8.s[13]++;
    this.propertyChangedCallback('collection', this._collection, collection);
  }
  /**
   * @type {Array.<Cards>}
   */


  get collection() {
    cov_cpzqxydh8.f[2]++;
    cov_cpzqxydh8.s[14]++;
    return this._collection;
  }
  /**
   * remove the last (top) card from the deck
   * @returns  {{card: Card, element: HTMLElement}} - removed card object and the corresponsing HTMLElement
   */


  pop() {
    cov_cpzqxydh8.f[3]++;
    const lastCard = (cov_cpzqxydh8.s[15]++, this.currentDeck[this.currentDeck.length - 1]);
    cov_cpzqxydh8.s[16]++;
    this.currentDeck = this.currentDeck.slice(0, -1);
    const lastCardElmt = (cov_cpzqxydh8.s[17]++, this.container.lastElementChild);
    cov_cpzqxydh8.s[18]++;
    this.container.removeChild(lastCardElmt);
    cov_cpzqxydh8.s[19]++;

    if (this.currentDeck.length <= 0) {
      cov_cpzqxydh8.b[0][0]++;
      cov_cpzqxydh8.s[20]++;
      this.dispatchEvent(this.emptyStackEvent);
      cov_cpzqxydh8.s[21]++;
      this.renderEmptyMsg();
    } else {
      cov_cpzqxydh8.b[0][1]++;
    }

    cov_cpzqxydh8.s[22]++;
    return {
      card: lastCard,
      element: lastCardElmt
    };
  }

  renderEmptyMsg() {
    cov_cpzqxydh8.f[4]++;
    const emptyBox = (cov_cpzqxydh8.s[23]++, document.createElement('div'));
    cov_cpzqxydh8.s[24]++;
    emptyBox.classList.add('empty-box');
    cov_cpzqxydh8.s[25]++;
    emptyBox.innerHTML = html`
      <p>You finished this session! Click the reload button to review this collection again.</p>
      <i class="reload"></i>
    `;
    cov_cpzqxydh8.s[26]++;
    emptyBox.querySelector('.reload').addEventListener('click', () => {
      cov_cpzqxydh8.f[5]++;
      cov_cpzqxydh8.s[27]++;
      this.render(this._collection);
      cov_cpzqxydh8.s[28]++;
      this.dispatchEvent(this.reloadFromCollectionEvent);
    });
    cov_cpzqxydh8.s[29]++;
    this.container.appendChild(emptyBox);
  }

  renderNoCollection() {
    cov_cpzqxydh8.f[6]++;
    cov_cpzqxydh8.s[30]++;
    this.container.innerHTML = `<p>No valid collection</p>`;
  }
  /**
   *
   */


  moveBack() {
    cov_cpzqxydh8.f[7]++;
    const lastCard = (cov_cpzqxydh8.s[31]++, this.currentDeck[this.currentDeck.length - 1]);
    cov_cpzqxydh8.s[32]++;
    this.currentDeck = [lastCard, ...this.currentDeck.slice(0, -1)];
    const elmt = (cov_cpzqxydh8.s[33]++, this.container.lastElementChild);
    cov_cpzqxydh8.s[34]++;
    this.container.prepend(elmt);
    cov_cpzqxydh8.s[35]++;
    elmt.firstElementChild.removeAttribute('flipped');
  }
  /**
   * @private
   * @param {*} prop
   * @param {*} oldValue
   * @param {*} newValue
   */


  propertyChangedCallback(prop, oldValue, newValue) {
    cov_cpzqxydh8.f[8]++;
    cov_cpzqxydh8.s[36]++;

    // cards collections are considered immutable
    if ((cov_cpzqxydh8.b[2][0]++, prop === 'collection') && (cov_cpzqxydh8.b[2][1]++, oldValue !== newValue)) {
      cov_cpzqxydh8.b[1][0]++;
      cov_cpzqxydh8.s[37]++;

      if ((cov_cpzqxydh8.b[4][0]++, Array.isArray(newValue)) && (cov_cpzqxydh8.b[4][1]++, newValue.length > 0)) {
        cov_cpzqxydh8.b[3][0]++;
        cov_cpzqxydh8.s[38]++;
        this.render([...newValue]);
        cov_cpzqxydh8.s[39]++;
        this._collection = newValue;
      } else {
        cov_cpzqxydh8.b[3][1]++;
        cov_cpzqxydh8.s[40]++;
        this.renderNoCollection();
        cov_cpzqxydh8.s[41]++;
        this._collection = null;
        cov_cpzqxydh8.s[42]++;
        this.currentDeck = null;
      }
    } else {
      cov_cpzqxydh8.b[1][1]++;
    }
  }

  render(cards) {
    cov_cpzqxydh8.f[9]++;
    cov_cpzqxydh8.s[43]++;

    if ((cov_cpzqxydh8.b[6][0]++, !this.currentDeck) || (cov_cpzqxydh8.b[6][1]++, cards.length !== this.currentDeck.length)) {
      cov_cpzqxydh8.b[5][0]++;
      cov_cpzqxydh8.s[44]++;
      this.container.style.paddingTop = `${cards.length * 5}px`;
    } else {
      cov_cpzqxydh8.b[5][1]++;
    }

    cov_cpzqxydh8.s[45]++;
    this.container.innerHTML = cards.map(card => {
      cov_cpzqxydh8.f[10]++;
      cov_cpzqxydh8.s[46]++;
      return `
          <div class="card-wrapper">
            ${cardHtml(card)}
          </div>
        `;
    }).join('');
    cov_cpzqxydh8.s[47]++;
    this.currentDeck = cards;
  }

}

cov_cpzqxydh8.s[48]++;
customElements.define('dc-stack', CardStackComponent);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNhcmQtc3RhY2suanMiXSwibmFtZXMiOlsiY3NzIiwiaHRtbCIsImNhcmRIdG1sIiwiQ2FyZFN0YWNrQ29tcG9uZW50IiwiSFRNTEVsZW1lbnQiLCJjb25zdHJ1Y3RvciIsInNoYWRvd1Jvb3QiLCJhdHRhY2hTaGFkb3ciLCJtb2RlIiwic3R5bGUiLCJkb2N1bWVudCIsImNyZWF0ZUVsZW1lbnQiLCJpbm5lclRleHQiLCJVUkwiLCJpbXBvcnQiLCJtZXRhIiwidXJsIiwidG9TdHJpbmciLCJhcHBlbmRDaGlsZCIsImNvbnRhaW5lciIsImNsYXNzTGlzdCIsImFkZCIsImN1cnJlbnREZWNrIiwiX2NvbGxlY3Rpb24iLCJlbXB0eVN0YWNrRXZlbnQiLCJDdXN0b21FdmVudCIsImJ1YmJsZXMiLCJjYW5jZWxhYmxlIiwiY29tcG9zZWQiLCJyZWxvYWRGcm9tQ29sbGVjdGlvbkV2ZW50IiwicmVuZGVyTm9Db2xsZWN0aW9uIiwiY29sbGVjdGlvbiIsInByb3BlcnR5Q2hhbmdlZENhbGxiYWNrIiwicG9wIiwibGFzdENhcmQiLCJsZW5ndGgiLCJzbGljZSIsImxhc3RDYXJkRWxtdCIsImxhc3RFbGVtZW50Q2hpbGQiLCJyZW1vdmVDaGlsZCIsImRpc3BhdGNoRXZlbnQiLCJyZW5kZXJFbXB0eU1zZyIsImNhcmQiLCJlbGVtZW50IiwiZW1wdHlCb3giLCJpbm5lckhUTUwiLCJxdWVyeVNlbGVjdG9yIiwiYWRkRXZlbnRMaXN0ZW5lciIsInJlbmRlciIsIm1vdmVCYWNrIiwiZWxtdCIsInByZXBlbmQiLCJmaXJzdEVsZW1lbnRDaGlsZCIsInJlbW92ZUF0dHJpYnV0ZSIsInByb3AiLCJvbGRWYWx1ZSIsIm5ld1ZhbHVlIiwiQXJyYXkiLCJpc0FycmF5IiwiY2FyZHMiLCJwYWRkaW5nVG9wIiwibWFwIiwiam9pbiIsImN1c3RvbUVsZW1lbnRzIiwiZGVmaW5lIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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RDtBQUNELEtBRkQ7QUFBQTtBQUFBOztBQURZO0FBSVosU0FBS2hCLFNBQUwsQ0FBZTBCLFNBQWYsR0FBMkJjLEtBQUssQ0FDN0JFLEdBRHdCLENBRXZCbkIsSUFBSSxJQUFJO0FBQUE7QUFBQTtBQUFBLGFBQUM7O2NBRUh4QyxRQUFRLENBQUN3QyxJQUFELENBQU87O1NBRmI7QUFJUCxLQU5zQixFQVF4Qm9CLElBUndCLENBUW5CLEVBUm1CLENBQTNCO0FBSlk7QUFhWixTQUFLeEMsV0FBTCxHQUFtQnFDLEtBQW5CO0FBQ0Q7O0FBekswQzs7O0FBNEs3Q0ksY0FBYyxDQUFDQyxNQUFmLENBQXNCLFVBQXRCLEVBQWtDN0Qsa0JBQWxDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3NzLCBodG1sIH0gZnJvbSAnLi4vLi4vdXRpbHMvdGFncy5qcyc7XG5pbXBvcnQgeyBjYXJkSHRtbCB9IGZyb20gJy4uL2ZsYXNoY2FyZC9mbGFzaGNhcmQuanMnO1xuXG4vKipcbiAqIFdlYiBDb21wb25lbnQgcmVwcmVzZW50aW5nIGEgc3RhY2tlZCBmbGFzaGNhcmQgZGVja1xuICovXG5jbGFzcyBDYXJkU3RhY2tDb21wb25lbnQgZXh0ZW5kcyBIVE1MRWxlbWVudCB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb25zdCBzaGFkb3dSb290ID0gdGhpcy5hdHRhY2hTaGFkb3coeyBtb2RlOiAnb3BlbicgfSk7XG5cbiAgICBjb25zdCBzdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG5cbiAgICBzdHlsZS5pbm5lclRleHQgPSBjc3NgXG4gICAgICAuY2FyZC13cmFwcGVyIHtcbiAgICAgICAgaGVpZ2h0OiAwO1xuICAgICAgICBtYXJnaW4tdG9wOiAtNXB4O1xuICAgICAgfVxuXG4gICAgICAuY2FyZHMtc3RhY2sge1xuICAgICAgICBoZWlnaHQ6IGNhbGModmFyKC0tY2FyZC13aWR0aCkgKiAxLjM5KTtcbiAgICAgIH1cblxuICAgICAgZGMtZmxhc2hjYXJkIHtcbiAgICAgICAgaGVpZ2h0OiA1MDBweDtcbiAgICAgICAgd2lkdGg6IDMwMHB4O1xuICAgICAgICBvdmVyZmxvdzogc2Nyb2xsO1xuICAgICAgfVxuXG4gICAgICAuZW1wdHktYm94IHtcbiAgICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgICAgfVxuXG4gICAgICBpIHtcbiAgICAgICAgYmFja2dyb3VuZC1zaXplOiBjb250YWluO1xuICAgICAgICBoZWlnaHQ6IHZhcigtLWljb25zLXNpemUsIDUwcHgpO1xuICAgICAgICB3aWR0aDogdmFyKC0taWNvbnMtc2l6ZSwgNTBweCk7XG4gICAgICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICAgIH1cblxuICAgICAgaS5yZWxvYWQge1xuICAgICAgICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoXCIke25ldyBVUkwoJy4vcmVsb2FkLnN2ZycsIGltcG9ydC5tZXRhLnVybCkudG9TdHJpbmcoKX1cIik7XG4gICAgICB9XG4gICAgYDtcblxuICAgIHNoYWRvd1Jvb3QuYXBwZW5kQ2hpbGQoc3R5bGUpO1xuXG4gICAgdGhpcy5jb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLmNvbnRhaW5lci5jbGFzc0xpc3QuYWRkKCdjYXJkcy1zdGFjaycpO1xuICAgIHNoYWRvd1Jvb3QuYXBwZW5kQ2hpbGQodGhpcy5jb250YWluZXIpO1xuXG4gICAgLyoqXG4gICAgICogdGhlIGRlY2sgb2YgY2FyZHMgY3VycmVudGx5IHJlbmRlcmVkXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXkuPENhcmQ+fVxuICAgICAqL1xuICAgIHRoaXMuY3VycmVudERlY2sgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICB0aGlzLl9jb2xsZWN0aW9uID0gbnVsbDtcblxuICAgIHRoaXMuZW1wdHlTdGFja0V2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KCdlbXB0eS1zdGFjaycsIHtcbiAgICAgIGJ1YmJsZXM6IGZhbHNlLFxuICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICBjb21wb3NlZDogdHJ1ZVxuICAgIH0pO1xuXG4gICAgdGhpcy5yZWxvYWRGcm9tQ29sbGVjdGlvbkV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KCdyZWxvYWQtY29sbGVjdGlvbicsIHtcbiAgICAgIGJ1YmJsZXM6IGZhbHNlLFxuICAgICAgY2FuY2VsYWJsZTogZmFsc2UsXG4gICAgICBjb21wb3NlZDogdHJ1ZVxuICAgIH0pO1xuXG4gICAgdGhpcy5yZW5kZXJOb0NvbGxlY3Rpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAqKkltbXV0YWJsZSoqIGNvbGxlY3Rpb24gb2YgY2FyZHNcbiAgICogVXBkYXRpbmcgdGhpcyBwcm9wZXJ0eSB3aWxsIGNhdXNlIHRoaXMgY29tcG9uZW50IHRvIHJlbmRlciAqKmFsbCoqIGl0cyBjb250ZW50LlxuICAgKiBEbyBzbyAqKm9ubHkqKiBpZiB5b3UgbmVlZCB0byBsb2FkIGFuIGVudGlyZSBuZXcgY29sbGVjdGlvbiBvZiBjYXJkcyFcbiAgICogQHR5cGUge0FycmF5LjxDYXJkcz59XG4gICAqL1xuICBzZXQgY29sbGVjdGlvbihjb2xsZWN0aW9uKSB7XG4gICAgdGhpcy5wcm9wZXJ0eUNoYW5nZWRDYWxsYmFjaygnY29sbGVjdGlvbicsIHRoaXMuX2NvbGxlY3Rpb24sIGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEB0eXBlIHtBcnJheS48Q2FyZHM+fVxuICAgKi9cbiAgZ2V0IGNvbGxlY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbGxlY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogcmVtb3ZlIHRoZSBsYXN0ICh0b3ApIGNhcmQgZnJvbSB0aGUgZGVja1xuICAgKiBAcmV0dXJucyAge3tjYXJkOiBDYXJkLCBlbGVtZW50OiBIVE1MRWxlbWVudH19IC0gcmVtb3ZlZCBjYXJkIG9iamVjdCBhbmQgdGhlIGNvcnJlc3BvbnNpbmcgSFRNTEVsZW1lbnRcbiAgICovXG4gIHBvcCgpIHtcbiAgICBjb25zdCBsYXN0Q2FyZCA9IHRoaXMuY3VycmVudERlY2tbdGhpcy5jdXJyZW50RGVjay5sZW5ndGggLSAxXTtcbiAgICB0aGlzLmN1cnJlbnREZWNrID0gdGhpcy5jdXJyZW50RGVjay5zbGljZSgwLCAtMSk7XG4gICAgY29uc3QgbGFzdENhcmRFbG10ID0gdGhpcy5jb250YWluZXIubGFzdEVsZW1lbnRDaGlsZDtcbiAgICB0aGlzLmNvbnRhaW5lci5yZW1vdmVDaGlsZChsYXN0Q2FyZEVsbXQpO1xuICAgIGlmICh0aGlzLmN1cnJlbnREZWNrLmxlbmd0aCA8PSAwKSB7XG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQodGhpcy5lbXB0eVN0YWNrRXZlbnQpO1xuICAgICAgdGhpcy5yZW5kZXJFbXB0eU1zZygpO1xuICAgIH1cbiAgICByZXR1cm4geyBjYXJkOiBsYXN0Q2FyZCwgZWxlbWVudDogbGFzdENhcmRFbG10IH07XG4gIH1cblxuICByZW5kZXJFbXB0eU1zZygpIHtcbiAgICBjb25zdCBlbXB0eUJveCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGVtcHR5Qm94LmNsYXNzTGlzdC5hZGQoJ2VtcHR5LWJveCcpO1xuICAgIGVtcHR5Qm94LmlubmVySFRNTCA9IGh0bWxgXG4gICAgICA8cD5Zb3UgZmluaXNoZWQgdGhpcyBzZXNzaW9uISBDbGljayB0aGUgcmVsb2FkIGJ1dHRvbiB0byByZXZpZXcgdGhpcyBjb2xsZWN0aW9uIGFnYWluLjwvcD5cbiAgICAgIDxpIGNsYXNzPVwicmVsb2FkXCI+PC9pPlxuICAgIGA7XG4gICAgZW1wdHlCb3gucXVlcnlTZWxlY3RvcignLnJlbG9hZCcpLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgdGhpcy5yZW5kZXIodGhpcy5fY29sbGVjdGlvbik7XG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQodGhpcy5yZWxvYWRGcm9tQ29sbGVjdGlvbkV2ZW50KTtcbiAgICB9KTtcbiAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZChlbXB0eUJveCk7XG4gIH1cblxuICByZW5kZXJOb0NvbGxlY3Rpb24oKSB7XG4gICAgdGhpcy5jb250YWluZXIuaW5uZXJIVE1MID0gYDxwPk5vIHZhbGlkIGNvbGxlY3Rpb248L3A+YDtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKi9cbiAgbW92ZUJhY2soKSB7XG4gICAgY29uc3QgbGFzdENhcmQgPSB0aGlzLmN1cnJlbnREZWNrW3RoaXMuY3VycmVudERlY2subGVuZ3RoIC0gMV07XG4gICAgdGhpcy5jdXJyZW50RGVjayA9IFtsYXN0Q2FyZCwgLi4udGhpcy5jdXJyZW50RGVjay5zbGljZSgwLCAtMSldO1xuICAgIGNvbnN0IGVsbXQgPSB0aGlzLmNvbnRhaW5lci5sYXN0RWxlbWVudENoaWxkO1xuICAgIHRoaXMuY29udGFpbmVyLnByZXBlbmQoZWxtdCk7XG4gICAgZWxtdC5maXJzdEVsZW1lbnRDaGlsZC5yZW1vdmVBdHRyaWJ1dGUoJ2ZsaXBwZWQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0geyp9IHByb3BcbiAgICogQHBhcmFtIHsqfSBvbGRWYWx1ZVxuICAgKiBAcGFyYW0geyp9IG5ld1ZhbHVlXG4gICAqL1xuICBwcm9wZXJ0eUNoYW5nZWRDYWxsYmFjayhwcm9wLCBvbGRWYWx1ZSwgbmV3VmFsdWUpIHtcbiAgICAvLyBjYXJkcyBjb2xsZWN0aW9ucyBhcmUgY29uc2lkZXJlZCBpbW11dGFibGVcbiAgICBpZiAocHJvcCA9PT0gJ2NvbGxlY3Rpb24nICYmIG9sZFZhbHVlICE9PSBuZXdWYWx1ZSkge1xuICAgICAgaWYoQXJyYXkuaXNBcnJheShuZXdWYWx1ZSkgJiYgbmV3VmFsdWUubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLnJlbmRlcihbLi4ubmV3VmFsdWVdKTtcbiAgICAgICAgdGhpcy5fY29sbGVjdGlvbiA9IG5ld1ZhbHVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZW5kZXJOb0NvbGxlY3Rpb24oKTtcbiAgICAgICAgdGhpcy5fY29sbGVjdGlvbiA9IG51bGw7XG4gICAgICAgIHRoaXMuY3VycmVudERlY2sgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJlbmRlcihjYXJkcykge1xuICAgIGlmICghdGhpcy5jdXJyZW50RGVjayB8fCBjYXJkcy5sZW5ndGggIT09IHRoaXMuY3VycmVudERlY2subGVuZ3RoKSB7XG4gICAgICB0aGlzLmNvbnRhaW5lci5zdHlsZS5wYWRkaW5nVG9wID0gYCR7Y2FyZHMubGVuZ3RoICogNX1weGA7XG4gICAgfVxuICAgIHRoaXMuY29udGFpbmVyLmlubmVySFRNTCA9IGNhcmRzXG4gICAgICAubWFwKFxuICAgICAgICBjYXJkID0+IGBcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC13cmFwcGVyXCI+XG4gICAgICAgICAgICAke2NhcmRIdG1sKGNhcmQpfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICBgXG4gICAgICApXG4gICAgICAuam9pbignJyk7XG4gICAgdGhpcy5jdXJyZW50RGVjayA9IGNhcmRzO1xuICB9XG59XG5cbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgnZGMtc3RhY2snLCBDYXJkU3RhY2tDb21wb25lbnQpO1xuIl19

@justinfagnani
Copy link

Jasmine requires the describe/it syntax, which is pretty bad, IMO, in that specs are not tests and tests are not specs. Mocha at least offers a choice.

In the Polymer projects we use mainline Mocha and Chai, and just load any other needed files via script tags. It's more important that library under test and tests are modules, than the test framework for the moment.

@nweldev
Copy link
Contributor Author

nweldev commented Aug 16, 2019

About using Chai directly (answer to #729 (comment)):

This is just a workaround permitting to use chai plugins without any modification. I would be happy to do a PR for that, but I think I would only instructions to the documentation, without modifying anything, because it looks kind of dirty ... except if you think we should provide some Chai plugins by default?

And I get the following error when we add './node_modules/chai/chai.js' to the files array in karma config, so we do need the bundled-es-modules version of Chai.

/node_modules/chai/chai.js?9a923235b425351d1145c8b35681392c3ae3b3b5: Unexpected token, expected ";" (21:48)

  19 | /*!
  20 |  * Assertion Error
> 21 |  */{ pattern: 'test/utils/chai-plugins.js', type: 'module' }
     |                                                 ^
  22 | 
  23 | exports.AssertionError = require('assertion-error');
  24 | 
HeadlessChrome 76.0.3809 (Linux 0.0.0) ERROR: 'failed to load element http://localhost:9876/base/node_modules/chai/chai.js?9a923235b425351d1145c8b35681392c3ae3b3b5'
HeadlessChrome 76.0.3809 (Linux 0.0.0) ERROR: 'failed to load element http://localhost:9876/base/node_modules/chai/chai.js?9a923235b425351d1145c8b35681392c3ae3b3b5'

@nweldev
Copy link
Contributor Author

nweldev commented Aug 16, 2019

And thx for the explanations you provided @justinfagnani & @daKmoR! This will be very useful for my next talk 😃 @daKmoR, are you talking about the "should" syntax? I would love to have a discussion about these topics with you both, but maybe it would be better to do that out of Github, in order to avoid to pollute the issues.

@daKmoR
Copy link
Member

daKmoR commented Aug 16, 2019

Using karma-jasmine, I get exactly the same file in the browser, except the link to the source-map is added at the end. But with Mocha, I get:

the transformation you see is for code coverage... it has "nothing" to with mocha... I assume you would get the same transformations if you apply code coverage and you run it with jasmine

Jasmine requires the describe/it syntax, which is pretty bad, IMO

hehe I see this as another "holy" war - equal to tabs vs spaces or " vs '... let's not open this particular pandora's box here 🙈

In the Polymer projects we use mainline Mocha and Chai, and just load any other needed files via script tags.

something to test out 💪

we will probably need to change our existing plugins or at least load them differently as I assume that is why @noelmace sees the errors when not using the bundles es module version of chai...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants