diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index 6fe7f665..53533230 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -33,33 +33,33 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Ruby
- uses: ruby/setup-ruby@0a29871fe2b0200a17a4497bae54fe5df0d973aa # v1.115.3
+ uses: ruby/setup-ruby@v1.229.0
with:
ruby-version: '3.0' # Not needed with a .ruby-version file
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
cache-version: 0 # Increment this number if you need to re-download cached gems
- name: Setup Pages
id: pages
- uses: actions/configure-pages@v2
+ uses: actions/configure-pages@v5
- name: Restore npm cache
- uses: actions/cache@v2
+ uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- - uses: actions/cache@v2
+ - uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-modules-
- name: Use Node.js
- uses: actions/setup-node@v2
+ uses: actions/setup-node@v4
with:
- node-version: '18'
+ node-version: '22'
- name: Install dependencies
run: npm install
- name: Generate Data
@@ -71,7 +71,7 @@ jobs:
JEKYLL_ENV: production
- name: Upload artifact
# Automatically uploads an artifact from the './_site' directory by default
- uses: actions/upload-pages-artifact@v1
+ uses: actions/upload-pages-artifact@v3
# Deployment job
deploy:
@@ -83,4 +83,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
- uses: actions/deploy-pages@v1
+ uses: actions/deploy-pages@v4
diff --git a/Gemfile b/Gemfile
index 29badaec..565426fa 100644
--- a/Gemfile
+++ b/Gemfile
@@ -3,3 +3,5 @@ source "https://rubygems.org"
# gem "rails"
gem 'github-pages'
+
+gem "webrick", "~> 1.8"
diff --git a/Gemfile.lock b/Gemfile.lock
index 767eb462..fee6df6e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,47 +1,55 @@
GEM
remote: https://rubygems.org/
specs:
- activesupport (6.0.6)
+ activesupport (7.1.3.2)
+ base64
+ bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
- i18n (>= 0.7, < 2)
- minitest (~> 5.1)
- tzinfo (~> 1.1)
- zeitwerk (~> 2.2, >= 2.2.2)
- addressable (2.8.1)
+ connection_pool (>= 2.2.5)
+ drb
+ i18n (>= 1.6, < 2)
+ minitest (>= 5.1)
+ mutex_m
+ tzinfo (~> 2.0)
+ addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
+ base64 (0.2.0)
+ bigdecimal (3.1.8)
coffee-script (2.4.1)
coffee-script-source
execjs
- coffee-script-source (1.11.1)
+ coffee-script-source (1.12.2)
colorator (1.1.0)
- commonmarker (0.23.6)
- concurrent-ruby (1.1.10)
- dnsruby (1.61.9)
- simpleidn (~> 0.1)
+ commonmarker (0.23.10)
+ concurrent-ruby (1.2.3)
+ connection_pool (2.4.1)
+ dnsruby (1.72.1)
+ simpleidn (~> 0.2.1)
+ drb (2.2.1)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
ethon (0.16.0)
ffi (>= 1.15.0)
eventmachine (1.2.7)
- execjs (2.8.1)
- faraday (2.7.1)
- faraday-net_http (>= 2.0, < 3.1)
- ruby2_keywords (>= 0.0.4)
- faraday-net_http (3.0.2)
- ffi (1.15.5)
+ execjs (2.9.1)
+ faraday (2.9.0)
+ faraday-net_http (>= 2.0, < 3.2)
+ faraday-net_http (3.1.0)
+ net-http
+ ffi (1.16.3)
forwardable-extended (2.6.0)
- gemoji (3.0.1)
- github-pages (227)
- github-pages-health-check (= 1.17.9)
- jekyll (= 3.9.2)
- jekyll-avatar (= 0.7.0)
- jekyll-coffeescript (= 1.1.1)
- jekyll-commonmark-ghpages (= 0.2.0)
- jekyll-default-layout (= 0.1.4)
- jekyll-feed (= 0.15.1)
+ gemoji (4.1.0)
+ github-pages (231)
+ github-pages-health-check (= 1.18.2)
+ jekyll (= 3.9.5)
+ jekyll-avatar (= 0.8.0)
+ jekyll-coffeescript (= 1.2.2)
+ jekyll-commonmark-ghpages (= 0.4.0)
+ jekyll-default-layout (= 0.1.5)
+ jekyll-feed (= 0.17.0)
jekyll-gist (= 1.5.0)
- jekyll-github-metadata (= 2.13.0)
+ jekyll-github-metadata (= 2.16.1)
jekyll-include-cache (= 0.2.1)
jekyll-mentions (= 1.6.0)
jekyll-optional-front-matter (= 0.3.2)
@@ -68,32 +76,32 @@ GEM
jekyll-theme-tactile (= 0.2.0)
jekyll-theme-time-machine (= 0.2.0)
jekyll-titles-from-headings (= 0.5.3)
- jemoji (= 0.12.0)
- kramdown (= 2.3.2)
+ jemoji (= 0.13.0)
+ kramdown (= 2.4.0)
kramdown-parser-gfm (= 1.1.0)
- liquid (= 4.0.3)
+ liquid (= 4.0.4)
mercenary (~> 0.3)
minima (= 2.5.1)
nokogiri (>= 1.13.6, < 2.0)
- rouge (= 3.26.0)
+ rouge (= 3.30.0)
terminal-table (~> 1.4)
- github-pages-health-check (1.17.9)
+ github-pages-health-check (1.18.2)
addressable (~> 2.3)
dnsruby (~> 1.60)
- octokit (~> 4.0)
- public_suffix (>= 3.0, < 5.0)
+ octokit (>= 4, < 8)
+ public_suffix (>= 3.0, < 6.0)
typhoeus (~> 1.3)
html-pipeline (2.14.3)
activesupport (>= 2)
nokogiri (>= 1.4)
http_parser.rb (0.8.0)
- i18n (0.9.5)
+ i18n (1.14.5)
concurrent-ruby (~> 1.0)
- jekyll (3.9.2)
+ jekyll (3.9.5)
addressable (~> 2.4)
colorator (~> 1.0)
em-websocket (~> 0.5)
- i18n (~> 0.7)
+ i18n (>= 0.7, < 2)
jekyll-sass-converter (~> 1.0)
jekyll-watch (~> 2.0)
kramdown (>= 1.17, < 3)
@@ -102,27 +110,27 @@ GEM
pathutil (~> 0.9)
rouge (>= 1.7, < 4)
safe_yaml (~> 1.0)
- jekyll-avatar (0.7.0)
+ jekyll-avatar (0.8.0)
jekyll (>= 3.0, < 5.0)
- jekyll-coffeescript (1.1.1)
+ jekyll-coffeescript (1.2.2)
coffee-script (~> 2.2)
- coffee-script-source (~> 1.11.1)
+ coffee-script-source (~> 1.12)
jekyll-commonmark (1.4.0)
commonmarker (~> 0.22)
- jekyll-commonmark-ghpages (0.2.0)
- commonmarker (~> 0.23.4)
+ jekyll-commonmark-ghpages (0.4.0)
+ commonmarker (~> 0.23.7)
jekyll (~> 3.9.0)
jekyll-commonmark (~> 1.4.0)
- rouge (>= 2.0, < 4.0)
- jekyll-default-layout (0.1.4)
- jekyll (~> 3.0)
- jekyll-feed (0.15.1)
+ rouge (>= 2.0, < 5.0)
+ jekyll-default-layout (0.1.5)
+ jekyll (>= 3.0, < 5.0)
+ jekyll-feed (0.17.0)
jekyll (>= 3.7, < 5.0)
jekyll-gist (1.5.0)
octokit (~> 4.2)
- jekyll-github-metadata (2.13.0)
+ jekyll-github-metadata (2.16.1)
jekyll (>= 3.4, < 5.0)
- octokit (~> 4.0, != 4.4.0)
+ octokit (>= 4, < 7, != 4.4.0)
jekyll-include-cache (0.2.1)
jekyll (>= 3.7, < 5.0)
jekyll-mentions (1.6.0)
@@ -193,16 +201,16 @@ GEM
jekyll (>= 3.3, < 5.0)
jekyll-watch (2.2.1)
listen (~> 3.0)
- jemoji (0.12.0)
- gemoji (~> 3.0)
+ jemoji (0.13.0)
+ gemoji (>= 3, < 5)
html-pipeline (~> 2.2)
jekyll (>= 3.0, < 5.0)
- kramdown (2.3.2)
+ kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
- liquid (4.0.3)
- listen (3.7.1)
+ liquid (4.0.4)
+ listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
@@ -210,22 +218,26 @@ GEM
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
- minitest (5.16.3)
- nokogiri (1.13.9-x86_64-linux)
+ minitest (5.22.3)
+ mutex_m (0.2.0)
+ net-http (0.4.1)
+ uri
+ nokogiri (1.16.5-arm64-darwin)
+ racc (~> 1.4)
+ nokogiri (1.16.5-x86_64-linux)
racc (~> 1.4)
octokit (4.25.1)
faraday (>= 1, < 3)
sawyer (~> 0.9)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
- public_suffix (4.0.7)
- racc (1.6.0)
+ public_suffix (5.0.5)
+ racc (1.7.3)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
- rexml (3.2.5)
- rouge (3.26.0)
- ruby2_keywords (0.0.5)
+ rexml (3.2.6)
+ rouge (3.30.0)
rubyzip (2.3.2)
safe_yaml (1.0.5)
sass (3.7.4)
@@ -236,26 +248,28 @@ GEM
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
- simpleidn (0.2.1)
+ simpleidn (0.2.2)
unf (~> 0.1.4)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
- thread_safe (0.3.6)
- typhoeus (1.4.0)
+ typhoeus (1.4.1)
ethon (>= 0.9.0)
- tzinfo (1.2.10)
- thread_safe (~> 0.1)
+ tzinfo (2.0.6)
+ concurrent-ruby (~> 1.0)
unf (0.1.4)
unf_ext
- unf_ext (0.0.8.2)
+ unf_ext (0.0.9.1)
unicode-display_width (1.8.0)
- zeitwerk (2.6.6)
+ uri (0.13.0)
+ webrick (1.8.1)
PLATFORMS
+ arm64-darwin-22
x86_64-linux
DEPENDENCIES
github-pages
+ webrick (~> 1.8)
BUNDLED WITH
2.3.21
diff --git a/Makefile b/Makefile
index 92a7ef34..d04d4a89 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ generated_data: plugins releases api-docs chaijs
api-docs: clean-api-docs
@mkdir -p _data
- @npm install chai@latest
+ @npm install chai@4
@node ./node_modules/dox/bin/dox --raw < ./node_modules/chai/chai.js > _data/chai.json
#
diff --git a/_guides/helpers.md b/_guides/helpers.md
index f0ad8712..18acdd31 100644
--- a/_guides/helpers.md
+++ b/_guides/helpers.md
@@ -74,7 +74,7 @@ Hopefully our `Model` class is self explanatory, but as an example,
here we construct a person object.
```javascript
-var arthur = new Model('person');
+const arthur = new Model('person');
arthur.set('name', 'Arthur Dent');
arthur.set('occupation', 'traveller');
console.log(arthur.get('name')); // Arthur Dent
@@ -97,7 +97,7 @@ implementation throughout.
For this example, we want the following test case to pass:
```javascript
-var arthur = new Model('person');
+const arthur = new Model('person');
expect(arthur).to.be.a.model;
```
@@ -141,7 +141,7 @@ expect(arthur).to.be.a.model('person');
// language chain method
Assertion.addMethod('model', function (type) {
- var obj = this._obj;
+ const obj = this._obj;
// first, our instanceof check, shortcut
new Assertion(this._obj).to.be.instanceof(Model);
@@ -176,8 +176,8 @@ To understand when to best use chainable methods we will examine a chainable met
core.
```javascript
-var arr = [ 1, 2, 3 ]
- , obj = { a: 1, b: 2 };
+const arr = [ 1, 2, 3 ];
+const obj = { a: 1, b: 2 };
expect(arr).to.contain(2);
expect(obj).to.contain.key('a');
@@ -241,7 +241,7 @@ function assertModelAge (n) {
new Assertion(this._obj).to.be.instanceof(Model);
// make sure we have an age and its a number
- var age = this._obj.get('age');
+ const age = this._obj.get('age');
new Assertion(age).to.be.a('number');
// do our comparison
@@ -301,7 +301,7 @@ Let's start out with the basic overwrite utility and a basic assertion.
```javascript
chai.overwriteProperty('ok', function (_super) {
return function checkModel () {
- var obj = this._obj;
+ const obj = this._obj;
if (obj && obj instanceof Model) {
new Assertion(obj).to.have.deep.property('_attrs.id').a('number');
} else {
@@ -324,7 +324,7 @@ will serve as the actual assertion.
With this in place, we can write positive assertions.
```javascript
-var arthur = new Model('person');
+const arthur = new Model('person');
arthur.set('id', 42);
expect(arthur).to.be.ok;
expect(true).to.be.ok;
@@ -336,7 +336,7 @@ revert to the original behavior. We will, however, run into a bit of
trouble if we try to negate an `ok` assertion on a model.
```javascript
-var arthur = new Model('person');
+const arthur = new Model('person');
arthur.set('id', 'dont panic');
expect(arthur).to.not.be.ok;
```
@@ -355,10 +355,10 @@ property overwrite would look like this.
```javascript
chai.overwriteProperty('ok', function (_super) {
return function checkModel () {
- var obj = this._obj;
+ const obj = this._obj;
if (obj && obj instanceof Model) {
new Assertion(obj).to.have.deep.property('_attrs.id'); // we always want this
- var assertId = new Assertion(obj._attrs.id);
+ const assertId = new Assertion(obj._attrs.id);
utils.transferFlags(this, assertId, false); // false means don't transfer `object` flag
assertId.is.a('number');
} else {
@@ -380,7 +380,7 @@ for the wrong type of id attribute, we would get an error message that states
test suite, so we will provide it with a bit more information.
```javascript
-var assertId = new Assertion(obj._attrs.id, 'model assert ok id type');
+const assertId = new Assertion(obj._attrs.id, 'model assert ok id type');
```
This will change our error message to be a more informative `model assert ok id type:
@@ -393,7 +393,7 @@ For this example we will be returning to our example of asserting Arthur's
age to be above a minimum threshold.
```javascript
-var arthur = new Model('person');
+const arthur = new Model('person');
arthur.set('age', 27);
expect(arthur).to.have.age.above(17);
```
@@ -405,7 +405,7 @@ so all we have to do is check if that exists.
Assertion.overwriteMethod('above', function (_super) {
return function assertAge (n) {
if (utils.flag(this, 'model.age')) {
- var obj = this._obj;
+ const obj = this._obj;
// first we assert we are actually working with a model
new Assertion(obj).instanceof(Model);
@@ -414,7 +414,7 @@ Assertion.overwriteMethod('above', function (_super) {
new Assertion(obj).to.have.deep.property('_attrs.age').a('number');
// now we compare
- var age = obj.get('age');
+ const age = obj.get('age');
this.assert(
age > n
, "expected #{this} to have an age above #{exp} but got #{act}"
diff --git a/_guides/index.md b/_guides/index.md
index c3578e70..6f96aa7a 100644
--- a/_guides/index.md
+++ b/_guides/index.md
@@ -17,6 +17,7 @@ assertion styles.
- [Install Chai]({{site.github.url}}/guide/installation/) in node, the browser, and other environments.
- [Learn about styles]({{site.github.url}}/guide/styles/) that you can use to define assertions.
+- [Importing Chai, and using plugins]({{site.github.url}}/guide/using-chai-with-esm-and-plugins/) to learn how to use Chai with ESM and plugins.
## Making Plugins
@@ -26,5 +27,76 @@ than what is included, limited only by what you want to achieve. The Plugin API
is also intended as a way to simplify testing by providing users a way to
encapsulate common assertions for repeat use.
+### Exposing Globals in Plugins
+
+When creating a Chai plugin, it's possible to expose globals that can be used across multiple files. Here's how to do it sustainably:
+
+#### Good Practice
+
+Prefer exporting any global in the module record so it can be imported directly instead of adding it as a property in the chai object:
+
+```javascript
+// An example of a good plugin:
+
+export const myGlobal = {...};
+
+export default function myPlugin(chai, utils) {
+}
+```
+
+#### Potential Issues
+
+Avoid exposing globals only through `chai.use()` without making them available for import, as this can lead to issues when trying to use the global across multiple files:
+
+```javascript
+// An example of a plugin which may have issues:
+
+const myGlobal = {...};
+
+export default function myPlugin(chai, utils) {
+ chai.myGlobal = myGlobal;
+}
+```
+
+```javascript
+// Another example of a plugin which may have issues:
+
+export default function myPlugin(chai, utils) {
+ chai.myGlobal = {...};
+}
+```
+
+### Guard against multiple calls to `use(..)`
+
+In certain situations the `use(..)` function could be called multiple times with your plugin. For a lot of plugins this won't be a issue but it's considered best practise to check if the plugin has been applied already.
+
+Here's a contrived example of how you might implement a check in your plugin but the actual implementation is left up to the plugin author.
+
+```js
+import * as chai from 'chai';
+
+let overwritten = false;
+
+function somePlugin(base) {
+ if (!overwritten) {
+ base.util.overwriteMethod(base.Assertion.prototype, "equal", function (_super) {
+ return function(...args) {
+ console.log("Called!"); // log something out
+
+ return _super.call(this, ...args);
+ };
+ });
+ overwritten = true;
+ }
+}
+
+chai.use(somePlugin);
+chai.use(somePlugin);
+
+chai.expect(123).to.equal(123); // Logs `Called!` only once
+```
+
+By following these guidelines, you can create Chai plugins that are easy to use and maintain.
+
- [Core Plugin Concepts]({{site.github.url}}/guide/plugins/) covers the basics of using the Chai Plugin API.
- [Building a Helper]({{site.github.url}}/guide/helpers/) is a walkthrough for writing your first plugin.
diff --git a/_guides/installation.md b/_guides/installation.md
index 167b47e4..e91d95af 100644
--- a/_guides/installation.md
+++ b/_guides/installation.md
@@ -7,7 +7,6 @@
headings:
- Node.js
- Browser
- - Other Platforms
---
# Installation
@@ -21,47 +20,17 @@ that include Chai.
Package is available through [npm](http://npmjs.org):
```bash
-npm install chai
-```
-
-Recommend adding it to `package.json` devDependencies using a `*` as the version tag.
-This will ensure that you always have the most recent version after running `npm install`,
-which can be especially powerful when paired with a continuous integration tool.
-
-```javascript
-"devDependencies": {
- "chai": "*",
- "mocha": "*"
-}, "//": "mocha is our preference, but you can use any test runner you like"
+npm install --save-dev chai
```
### Browser
-Include the chai browser build in your testing suite.
+Include the chai browser build in your testing suite. You can either link to your own self-hosted version of chai or through a NPM CDN like [jsDelivr](https://www.jsdelivr.com/) or [unpkg](https://www.unpkg.com/).
```html
-
-```
-
-This will provide `chai` as a global object, or `define` it if you are using AMD.
-
-The latest tagged version will be available for hot-linking at [http://chaijs.com/chai.js]({{site.github.url}}/chai.js).
-If you prefer to host yourself, use the `chai.js` file from the root of the github project.
-We recommend that you always use a version tag as your starting point, so the
-[tag download list](https://github.com/chaijs/chai/tags) is the best place to start.
+
+```
diff --git a/_guides/plugins.md b/_guides/plugins.md
index 8be2ae32..e634b274 100644
--- a/_guides/plugins.md
+++ b/_guides/plugins.md
@@ -46,7 +46,7 @@ community. A more appropriate pattern for creating helpers is as follows...
For our helper file: `test/helpers/model.js`
```javascript
-module.exports = function (chai, utils) {
+export function chaiModel(chai, utils) {
var Assertion = chai.Assertion;
// your helpers here
@@ -56,9 +56,9 @@ module.exports = function (chai, utils) {
And, for our actual test: `test/person.js`
```javascript
-var chai = require('chai')
- , chaiModel = require('./helpers/model')
- , expect = chai.expect;
+import * as chai from 'chai';
+import {chaiModel} from './helpers/model.js'
+import {expect} from 'chai';
chai.use(chaiModel);
```
@@ -85,9 +85,9 @@ The flag utility is exposed as `utils.flag` from within our `use` function. It c
as either a getter or a setter, depending on the number of arguments passed to it.
```javascript
-var myAssert = new Assertion(obj);
+const myAssert = new Assertion(obj);
utils.flag(myAssert, 'owner', 'me'); // sets key `owner` to `me`
-var owner = utils.flag(myAssert, 'owner'); // get key `owner', returns value
+const owner = utils.flag(myAssert, 'owner'); // get key `owner', returns value
```
### object flag
@@ -96,15 +96,15 @@ The most important of Chai's reserved flags is the `object` flag. This is the su
of an assertion.
```javascript
-var myAssert = new Assertion('Arthur Dent');
-var obj = flag(myAssert, 'object'); // obj === 'Arthur Dent';
+const myAssert = new Assertion('Arthur Dent');
+const obj = flag(myAssert, 'object'); // obj === 'Arthur Dent';
```
This flag is so often used that a shortcut was provided as the `_obj` property of a
constructed assertion.
```javascript
-var obj = myAssert._obj; // obj === `Arthur Dent`
+const obj = myAssert._obj; // obj === `Arthur Dent`
```
The following flags are used by Chai's core assertions. Side effects may occur should you
@@ -135,7 +135,7 @@ negated or not.
To begin, we will construct Arthur again, then we can assert that he is who he says he is.
```javascript
-var arthur = new Assertion('Arthur Dent');
+const arthur = new Assertion('Arthur Dent');
arthur.assert(
arthur._obj === 'Arthur Dent'
diff --git a/_guides/styles.md b/_guides/styles.md
index de9a264d..ad8555f2 100644
--- a/_guides/styles.md
+++ b/_guides/styles.md
@@ -28,9 +28,10 @@ node.js. This assert module, however, provides several additional
tests and is browser compatible.
```js
-var assert = require('chai').assert
- , foo = 'bar'
- , beverages = { tea: [ 'chai', 'matcha', 'oolong' ] };
+import {assert} from 'chai';
+
+const foo = 'bar';
+const beverages = { tea: [ 'chai', 'matcha', 'oolong' ] };
assert.typeOf(foo, 'string'); // without optional message
assert.typeOf(foo, 'string', 'foo is a string'); // with optional message
@@ -59,9 +60,10 @@ The BDD style is exposed through `expect` or `should` interfaces. In both
scenarios, you chain together natural language assertions.
```js
-var expect = require('chai').expect
- , foo = 'bar'
- , beverages = { tea: [ 'chai', 'matcha', 'oolong' ] };
+import {expect} from 'chai';
+
+const foo = 'bar';
+const beverages = { tea: [ 'chai', 'matcha', 'oolong' ] };
expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
@@ -73,7 +75,7 @@ Expect also allows you to include arbitrary messages to prepend to any failed
assertions that might occur.
```js
-var answer = 43;
+const answer = 43;
// AssertionError: expected 43 to equal 42.
expect(answer).to.equal(42);
@@ -94,9 +96,12 @@ property to start your chain. This style has some issues when used with Internet
Explorer, so be aware of browser compatibility.
```js
-var should = require('chai').should() //actually call the function
- , foo = 'bar'
- , beverages = { tea: [ 'chai', 'matcha', 'oolong' ] };
+import {should} from 'chai';
+
+should(); //actually call the function
+
+const foo = 'bar';
+const beverages = { tea: [ 'chai', 'matcha', 'oolong' ] };
foo.should.be.a('string');
foo.should.equal('bar');
@@ -111,9 +116,10 @@ First of all, notice that the `expect` require is just a reference to the
being executed.
```js
-var chai = require('chai')
- , expect = chai.expect
- , should = chai.should();
+import * as chai from 'chai';
+
+const {expect} = chai;
+const should = chai.should();
```
The `expect` interface provides a function as a starting point for chaining
@@ -143,7 +149,10 @@ with a `should` chain starter. As such, the appropriate few assertions
for this scenario are as follows:
```js
-var should = require('chai').should();
+import {should as loadShould} from 'chai';
+
+const should = loadShould();
+
db.get(1234, function (err, doc) {
should.not.exist(err);
should.exist(doc);
@@ -168,7 +177,7 @@ statement – it has to go on its own line, which looks a little
verbose:
```js
-import chai from 'chai';
+import * as chai from 'chai';
chai.should();
```
diff --git a/_guides/using-chai-with-esm-and-plugins.md b/_guides/using-chai-with-esm-and-plugins.md
new file mode 100644
index 00000000..5126792a
--- /dev/null
+++ b/_guides/using-chai-with-esm-and-plugins.md
@@ -0,0 +1,61 @@
+---
+ title: Using Chai with ESM and Plugins
+ layout: guide
+ bodyClass: guide
+ weight: 0
+ order: 20
+ headings:
+ - Importing Chai
+ - Using Plugins
+ - Exposing Globals in Plugins
+---
+
+# Using Chai with ESM and Plugins
+
+This guide provides an overview of how to use Chai with ECMAScript modules (ESM) and plugins, including examples using the `chai-http` plugin.
+
+## Importing Chai
+
+To use Chai with ESM, you can import Chai in your test files using the `import` statement. Here's how you can import the `expect` interface:
+
+```javascript
+import { expect } from 'chai';
+```
+
+## Using Plugins
+
+Chai plugins can extend Chai's capabilities. To use a plugin, you first need to install it, then use the `use` method to load it. Here's how to use the `chai-http` plugin as an example:
+
+```javascript
+import * as chai from 'chai';
+import { request, default as chaiHttp } from 'chai-http';
+
+chai.use(chaiHttp);
+
+// Now you can use `chai-http` using the `request` function.
+```
+
+### chai-http Example
+
+Here's an example of using `chai-http` to test an HTTP GET request:
+
+```javascript
+import * as chai from 'chai';
+import { request, default as chaiHttp } from 'chai-http';
+
+const {expect} = chai;
+
+chai.use(chaiHttp);
+
+describe('GET /user', () => {
+ it('should return the user', done => {
+ request('http://example.com')
+ .get('/user')
+ .end((err, res) => {
+ expect(res).to.have.status(200);
+ expect(res.body).to.be.an('object');
+ done();
+ });
+ });
+});
+```
diff --git a/_layouts/default.html b/_layouts/default.html
index 93e121ee..c30f5730 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -1,5 +1,5 @@
-
+
{% include head.html %}
diff --git a/_sass/_main.scss b/_sass/_main.scss
index b3a7f4ae..a02bc706 100644
--- a/_sass/_main.scss
+++ b/_sass/_main.scss
@@ -282,18 +282,17 @@ h3.fancy {
}
a {
color: #a40802;
- text-decoration: none;
}
h1 {
- color: #784942;
+ color: #744640;
font-size: 3em;
}
h1 > a {
- color: #784942;
+ color: #744640;
}
h2 {
font-size: 28px;
- color: #784942;
+ color: #744640;
}
h3 {
font-weight: bold;
@@ -390,7 +389,7 @@ body.index header .header-wrap {
position: relative;
}
body.index header .header-wrap .installation .site-description {
- color: #784942;
+ color: #744640;
margin-bottom: 1.2em;
margin-top: 8px;
font-size: 22px;
@@ -402,9 +401,9 @@ body.index header .header-wrap .installation .card {
-moz-border-radius: 5px;
border-radius: 5px;
background: #fff;
- -webkit-box-shadow: 0px 0px 1px #784942;
- -moz-box-shadow: 0px 0px 1px #784942;
- box-shadow: 0px 0px 1px #784942;
+ -webkit-box-shadow: 0px 0px 1px #744640;
+ -moz-box-shadow: 0px 0px 1px #744640;
+ box-shadow: 0px 0px 1px #744640;
position: relative;
}
body.index header .header-wrap .installation .card:before,
@@ -656,7 +655,7 @@ body.index header .header-wrap .callouts .call a small {
display: block;
margin-left: 115px;
font-family: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;
- color: #784942;
+ color: #744640;
}
body.index header .header-wrap .callouts .call .bg {
position: absolute;
@@ -669,9 +668,9 @@ body.index header .header-wrap .callouts .call .bg {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
- -webkit-box-shadow: 0px 0px 1px #784942;
- -moz-box-shadow: 0px 0px 1px #784942;
- box-shadow: 0px 0px 1px #784942;
+ -webkit-box-shadow: 0px 0px 1px #744640;
+ -moz-box-shadow: 0px 0px 1px #744640;
+ box-shadow: 0px 0px 1px #744640;
opacity: 0;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
}
@@ -732,7 +731,7 @@ section#content p code {
padding-top: 0px !important;
margin-top: 0px !important;
line-height: 30px;
- color: #784942;
+ color: #744640;
}
.panels pre {
padding: 0px;
@@ -830,9 +829,9 @@ section#content p code {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
- -webkit-box-shadow: 0px 0px 1px #784942;
- -moz-box-shadow: 0px 0px 1px #784942;
- box-shadow: 0px 0px 1px #784942;
+ -webkit-box-shadow: 0px 0px 1px #744640;
+ -moz-box-shadow: 0px 0px 1px #744640;
+ box-shadow: 0px 0px 1px #744640;
}
.panels article.subscribe .rowInside {
margin-top: 0px;
@@ -1070,9 +1069,6 @@ nav#pages ul li a {
text-transform: lowercase;
font-size: 14px;
}
-nav#pages ul li a:hover {
- text-decoration: underline;
-}
footer {
padding-top: 30px;
padding-bottom: 30px;
@@ -1329,7 +1325,7 @@ body.plugin .banner .wrap h2 {
margin-top: 0px !important;
margin-bottom: 20px !important;
padding-top: 0px !important;
- color: #784942;
+ color: #744640;
}
body.plugin .banner .wrap h3.link {
font-size: 20px;
@@ -1434,9 +1430,9 @@ body.plugin .readme {
}
body.plugin .readme .wrap {
background-color: #fff;
- -webkit-box-shadow: 0px 0px 1px #784942;
- -moz-box-shadow: 0px 0px 1px #784942;
- box-shadow: 0px 0px 1px #784942;
+ -webkit-box-shadow: 0px 0px 1px #744640;
+ -moz-box-shadow: 0px 0px 1px #744640;
+ box-shadow: 0px 0px 1px #744640;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
@@ -1553,9 +1549,9 @@ body.guide .documentation {
float: right;
overflow: visible;
background-color: #fff;
- -webkit-box-shadow: 0px 0px 1px #784942;
- -moz-box-shadow: 0px 0px 1px #784942;
- box-shadow: 0px 0px 1px #784942;
+ -webkit-box-shadow: 0px 0px 1px #744640;
+ -moz-box-shadow: 0px 0px 1px #744640;
+ box-shadow: 0px 0px 1px #744640;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
@@ -1632,9 +1628,9 @@ body.api .documentation {
float: right;
overflow: visible;
background-color: #fff;
- -webkit-box-shadow: 0px 0px 1px #784942;
- -moz-box-shadow: 0px 0px 1px #784942;
- box-shadow: 0px 0px 1px #784942;
+ -webkit-box-shadow: 0px 0px 1px #744640;
+ -moz-box-shadow: 0px 0px 1px #744640;
+ box-shadow: 0px 0px 1px #744640;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
diff --git a/_scripts/build-plugin-pages.js b/_scripts/build-plugin-pages.js
index 2e4f6aed..be89c4be 100644
--- a/_scripts/build-plugin-pages.js
+++ b/_scripts/build-plugin-pages.js
@@ -6,7 +6,7 @@ files.filter(function (file) {
try {
var name = file.slice(0, -5);
var pluginJson = JSON.parse(fs.readFileSync('_data/plugins/' + file, 'utf8'));
- var contents = '---\nlayout: plugin\npermalink: plugins/' + pluginJson.name + '/\npluginName: ' + pluginJson.name + '\n---\n\n' + pluginJson.readme;
+ var contents = '---\nlayout: plugin\npermalink: plugins/' + encodeURIComponent(pluginJson.name) + '/\npluginName: ' + encodeURIComponent(pluginJson.name) + '\n---\n\n' + pluginJson.readme;
fs.writeFileSync(__dirname + '/../plugins/' + name + '.md', contents, 'utf8');
console.log('Wrote', 'plugins/' + name + '.md')
} catch(e) {