Skip to content

Commit

Permalink
Update Ember, drop support for node 12, Ember < 3.28
Browse files Browse the repository at this point in the history
  • Loading branch information
simonihmig committed Jan 7, 2023
1 parent f248b86 commit aa886f0
Show file tree
Hide file tree
Showing 18 changed files with 1,021 additions and 1,861 deletions.
8 changes: 7 additions & 1 deletion .ember-cli
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@

Setting `disableAnalytics` to true will prevent any data from being sent.
*/
"disableAnalytics": false
"disableAnalytics": false,

/**
Setting `isTypeScriptProject` to true will force the blueprint generators to generate TypeScript
rather than JavaScript by default, when a TypeScript version of a given blueprint is available.
*/
"isTypeScriptProject": false
}
17 changes: 10 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@ on:
pull_request: {}

concurrency:
group: ci-${{ github.head_ref || github.ref }}
cancel-in-progress: true
group: ci-${{ github.head_ref || github.ref }}
cancel-in-progress: true

jobs:
test:
name: "Tests"
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- uses: actions/checkout@v3
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: 12.x
node-version: 14.x
cache: yarn
- name: Install Dependencies
run: yarn install --frozen-lockfile
Expand All @@ -34,12 +35,13 @@ jobs:
floating:
name: "Floating Dependencies"
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 12.x
node-version: 14.x
cache: yarn
- name: Install Dependencies
run: yarn install --no-lockfile
Expand All @@ -49,14 +51,15 @@ jobs:
try-scenarios:
name: ${{ matrix.try-scenario }}
runs-on: ubuntu-latest
needs: 'test'
needs: "test"
timeout-minutes: 10

strategy:
fail-fast: false
matrix:
try-scenario:
- ember-lts-3.24
- ember-lts-3.28
- ember-lts-4.4
- ember-release
- ember-beta
- ember-canary
Expand All @@ -69,7 +72,7 @@ jobs:
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: 12.x
node-version: 14.x
cache: yarn
- name: Install Dependencies
run: yarn install --frozen-lockfile
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@
/package.json.ember-try
/package-lock.json.ember-try
/yarn.lock.ember-try

# broccoli-debug
/DEBUG/
1 change: 0 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
/.travis.yml
/.watchmanconfig
/bower.json
/config/ember-try.js
/CONTRIBUTING.md
/ember-cli-build.js
/testem.js
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
* `ember serve`
* Visit the dummy application at [http://localhost:4200](http://localhost:4200).

For more information on using ember-cli, visit [https://ember-cli.com/](https://ember-cli.com/).
For more information on using ember-cli, visit [https://cli.emberjs.com/release/](https://cli.emberjs.com/release/).
101 changes: 48 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,28 @@
[![npm version](https://badge.fury.io/js/ember-window-mock.svg)](https://badge.fury.io/js/ember-window-mock)

This Ember CLI addon provides the `window` global as an ES6 module import that you can use in any component or controller where
you need `window`. But some of its properties and functions are prohibitive to be used
you need `window`. But some of its properties and functions are prohibitive to be used
in tests as they will break the test run:
* you cannot set `window.location.href` to trigger a redirect, as that will leave your test page
* `alert`, `confirm` and `prompt` are blocking calls, and cannot be closed without user interaction, so they will just
suspend your test run

So when running tests this import will be replaced with one that mocks these critical parts.

- you cannot set `window.location.href` to trigger a redirect, as that will leave your test page
- `alert`, `confirm` and `prompt` are blocking calls, and cannot be closed without user interaction, so they will just
suspend your test run

Compatibility
------------------------------------------------------------------------------
So when running tests this import will be replaced with one that mocks these critical parts.

* Ember.js v3.24 or above
* Ember CLI v3.24 or above
* Node.js v12 or above
## Compatibility

- Ember.js v3.28 or above
- Ember CLI v3.28 or above
- Node.js v14 or above

Installation
------------------------------------------------------------------------------
## Installation

```
ember install ember-window-mock
```

Usage
------------------------------------------------------------------------------
## Usage

### How to use it in your app

Expand All @@ -46,7 +42,7 @@ export default class IndexController extends Controller {
window.location.href = url;
}
}
```
```

With this addon, you can just import `window` instead of using the global:

Expand All @@ -61,46 +57,49 @@ export default class IndexController extends Controller {
window.location.href = url;
}
}
```
```

Everything else works as you would expect, since the import is exactly the same as the global, when not running tests.
Everything else works as you would expect, since the import is exactly the same as the global, when not running tests.

### The window mock

When running in the test environment, the import will be replaced with a mock. It is a proxy to `window`, so all of the
non-critical properties and functions just use the normal `window` global. But the critical parts are replaced suitable
When running in the test environment, the import will be replaced with a mock. It is a proxy to `window`, so all of the
non-critical properties and functions just use the normal `window` global. But the critical parts are replaced suitable
for tests:
* `window.location` is mocked with an object with the same API (members like `.href` or `.host`), but setting
`location.href` will just do nothing. Still reading from `location.href` will return the value that was previously set,
so you can run assertions against that value to check if you app tried to redirect to the expected URL.
* `window.localStorage` is also mocked with an object with the same API (`getItem`, `setItem`, `removeItem`, `clear`, `key`, and `length`). Storage is not persistent and does not affect your browser's `localStorage` object.
* `window.sessionStorage` is mocked similar to `window.localStorage`.
* `alert`, `confirm` and `prompt` are replaced by simple noop functions (they do nothing). You can use a mocking library
like [Sinon.js](http://sinonjs.org/) to replace them with spies or stubs to assert that they have been called or to
return some predefined value (e.g. `true` for `confirm`).

- `window.location` is mocked with an object with the same API (members like `.href` or `.host`), but setting
`location.href` will just do nothing. Still reading from `location.href` will return the value that was previously set,
so you can run assertions against that value to check if you app tried to redirect to the expected URL.
- `window.localStorage` is also mocked with an object with the same API (`getItem`, `setItem`, `removeItem`, `clear`, `key`, and `length`). Storage is not persistent and does not affect your browser's `localStorage` object.
- `window.sessionStorage` is mocked similar to `window.localStorage`.
- `alert`, `confirm` and `prompt` are replaced by simple noop functions (they do nothing). You can use a mocking library
like [Sinon.js](http://sinonjs.org/) to replace them with spies or stubs to assert that they have been called or to
return some predefined value (e.g. `true` for `confirm`).

Moreover it allows you to set any (nested) properties, even if they are defined as read only. This way you can pretend
different environments in your tests. For example you can fake different devices by changing
* `window.navigator.userAgent` when you do user agent detection in your app.
* `window.screen.width` to test responsive layouts when your components render differently based on it.

- `window.navigator.userAgent` when you do user agent detection in your app.
- `window.screen.width` to test responsive layouts when your components render differently based on it.

See below for some examples.

**Important:**
* The window mock works by using an ES6 `Proxy`, so **your development environment and tests need to run in a browser like Chrome that
supports `Proxy` natively** (as it cannot be transpiled by Babel)
* Note that this will only work when you use these function through the import, and not by using the global directly.

- The window mock works by using an ES6 `Proxy`, so **your development environment and tests need to run in a browser like Chrome that
supports `Proxy` natively** (as it cannot be transpiled by Babel)
- Note that this will only work when you use these function through the import, and not by using the global directly.

### Resetting the state in tests

It is possible to leak some state on the window mock between tests. For example when your app sets `location.href` in a
It is possible to leak some state on the window mock between tests. For example when your app sets `location.href` in a
test like this:

```js
```js
window.location.href = 'http://www.example.com';
```

For the following test `window.location.href` will still be `'http://www.example.com'`, but instead it should have a
For the following test `window.location.href` will still be `'http://www.example.com'`, but instead it should have a
fresh instance of the window mock. Therefore this addon exports a `setupWindowMock` function to kill all changed state on `window`:

```js
Expand All @@ -126,22 +125,22 @@ import { setupApplicationTest } from 'ember-qunit';
import window from 'ember-window-mock';
import { setupWindowMock } from 'ember-window-mock/test-support';

module('Acceptance | redirect', function(hooks) {
module('Acceptance | redirect', function (hooks) {
setupApplicationTest(hooks);
setupWindowMock(hooks);

test('it redirects when clicking the button', async function(assert) {
test('it redirects when clicking the button', async function (assert) {
await visit('/');
await click('button');

assert.equal(window.location.href, 'http://www.example.com');
});
});
```

#### Mocking `confirm()`

Here is an example that uses [ember-sinon-qunit](https://github.com/elwayman02/ember-sinon-qunit) to replace `confirm`,
Here is an example that uses [ember-sinon-qunit](https://github.com/elwayman02/ember-sinon-qunit) to replace `confirm`,
so you can easily check if it has been called, and to return some defined value:

```js
Expand All @@ -152,22 +151,22 @@ import window from 'ember-window-mock';
import { setupWindowMock } from 'ember-window-mock/test-support';
import sinon from 'sinon';

module('Acceptance | redirect', function(hooks) {
module('Acceptance | redirect', function (hooks) {
setupApplicationTest(hooks);
setupWindowMock(hooks);

test('it deletes an item', async function(assert) {
test('it deletes an item', async function (assert) {
let stub = sinon.stub(window, 'confirm');
stub.returns(true);

await visit('/');
await click('[data-test-delete]');

assert.ok(stub.calledOnce);
assert.ok(stub.calledWith('Are you sure?'));
});
});
```
```

#### Mocking `open()`

Expand All @@ -181,11 +180,11 @@ import { setupApplicationTest } from 'ember-qunit';
import window from 'ember-window-mock';
import { setupWindowMock } from 'ember-window-mock/test-support';

module('Acceptance | new window', function(hooks) {
module('Acceptance | new window', function (hooks) {
setupApplicationTest(hooks);
setupWindowMock(hooks);

test('it opens a new window when clicking the button', async function(assert) {
test('it opens a new window when clicking the button', async function (assert) {
await visit('/');
window.open = (urlToOpen) => {
assert.equal(urlToOpen, 'http://www.example.com/some-file.jpg');
Expand All @@ -195,14 +194,10 @@ module('Acceptance | new window', function(hooks) {
});
```

Contributing
------------------------------------------------------------------------------
## Contributing

See the [Contributing](CONTRIBUTING.md) guide for details.


License
------------------------------------------------------------------------------
## License

This project is licensed under the [MIT License](LICENSE.md).

5 changes: 0 additions & 5 deletions config/environment.js

This file was deleted.

2 changes: 1 addition & 1 deletion ember-cli-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const EmberAddon = require('ember-cli/lib/broccoli/ember-addon');

module.exports = function (defaults) {
let app = new EmberAddon(defaults, {
const app = new EmberAddon(defaults, {
// Add options here
});

Expand Down
Loading

0 comments on commit aa886f0

Please sign in to comment.