Skip to content
This repository has been archived by the owner on Apr 1, 2020. It is now read-only.

Commit

Permalink
Change mount signature and only allow components with one-way bound p…
Browse files Browse the repository at this point in the history
…rops
  • Loading branch information
oliverviljamaa committed Dec 5, 2018
1 parent a572205 commit 9a1a7fd
Show file tree
Hide file tree
Showing 25 changed files with 447 additions and 166 deletions.
6 changes: 2 additions & 4 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
"rules": {
"no-underscore-dangle": "off",
"no-use-before-define": "off",
"no-param-reassign": "off"
},
"globals": {
"angular": false
"no-param-reassign": "off",
"import/prefer-default-export": "off"
}
}
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# v2.0.0
## Change `mount` signature and only allow components with one-way bound props

Breaking:
* `mount` now takes a `tagName` as the first argument rather than a `template`
* only components with onw-way bound props are allowed (bear in mind that this affects all callbacks previously bound with `&`)

See [README](README.md#mounttagname-props-options--testelementwrapper).

# v1.2.2
## Expose `mock._template` and `mock._name` for custom matchers

Expand Down
118 changes: 64 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Therefore, it is well suited for organisations and individuals **moving from Ang
[**An example showing the utility in use can be found here.**](example.test.js)

Available methods:
[`mount`](#mounttemplate-props--testelementwrapper)
[`mount`](#mounttagname-props--testelementwrapper)
[`mockComponent`](#mockcomponentname--mock)

Returned classes:
Expand All @@ -34,28 +34,29 @@ import { mount, mockComponent } from 'angularjs-enzyme';

## API

### `mount(template[, props]) => TestElementWrapper`
### `mount(tagName[, props]) => TestElementWrapper`

Mounts the `template` (`String`) with optional `props` (`Object`) and returns a [`TestElementWrapper`](#testelementwrapper-api) with numerous helper methods. The props are attached to the `$ctrl` available in the template scope.
Mounts the component with `tagName` (`String`) and optional `props` (`Object`) and returns a [`TestElementWrapper`](#testelementwrapper-api) with numerous helper methods. The props are attached to the `$ctrl` available in the template scope. Only components with one-way bound props (`<`) can be mounted.

<details>
<summary>Example</summary>

*some-component.html*
```html
<h1>{{ $ctrl.title }}</h1>
<p>{{ $ctrl.text }}</p>
```

```js
import 'angular';
import 'angular-mocks';
import { mount } from 'angularjs-enzyme';

describe('Component under test', () => {
const TEMPLATE = `
<h1>{{ $ctrl.title }}</h1>
<p>{{ $ctrl.text }}</p>
`;

let component;
beforeEach(() => {
angular.mock.module('moduleOfComponentUnderTest');
component = mount(TEMPLATE, { title: 'A title', text: 'Some text' });
component = mount('some-component', { title: 'A title', text: 'Some text' });
});
});
```
Expand Down Expand Up @@ -94,6 +95,7 @@ The number of elements in the wrapper.
<details>
<summary>Example</summary>

*some-component.html*
```html
<ul>
<li>1</li>
Expand All @@ -117,6 +119,7 @@ Returns HTML of the wrapper. It should only be used for logging purposes, in tes
<details>
<summary>Example</summary>

*some-component.html*
```html
<h1>Some title</h1>
```
Expand All @@ -134,6 +137,7 @@ it('renders title as html', () => {
<details>
<summary>Example</summary>

*some-component.html*
```html
<h1>Some title</h1>
<p>Some text</p>
Expand All @@ -154,6 +158,7 @@ Returns whether the wrapper has a class with `className` (`String`) or not.
<details>
<summary>Example</summary>

*some-component.html*
```html
<button class="success">Pay</button>
```
Expand All @@ -177,6 +182,7 @@ Returns whether or not the wrapper contains any elements.
<details>
<summary>Example</summary>

*some-component.html*
```html
<button>Pay</button>
```
Expand All @@ -200,6 +206,7 @@ Returns a [`TestElementWrapper`](#testelementwrapper-api) (for chaining) with ev
<details>
<summary>Example</summary>

*some-component.html*
```html
<div class="left">
<a href="https://neopets.com">Wrong</a>
Expand Down Expand Up @@ -229,6 +236,7 @@ Returns a [`TestElementWrapper`](#testelementwrapper-api) (for chaining) for the
<details>
<summary>Example</summary>

*some-component.html*
```html
<button class="btn btn-primary">Balance</button>
<button class="btn btn-primary">Bank transfer</button>
Expand All @@ -251,6 +259,7 @@ Returns a [`TestElementWrapper`](#testelementwrapper-api) (for chaining) for ele
<details>
<summary>Example</summary>

*some-component.html*
```html
<button class="btn btn-primary">Balance</button>
<button class="btn btn-primary">Bank transfer</button>
Expand All @@ -273,6 +282,7 @@ Maps the nodes in the wrapper to another array using `fn` (`Function`).
<details>
<summary>Example</summary>

*some-component.html*
```html
<ul>
<li>One</li>
Expand All @@ -298,6 +308,7 @@ Returns all wrapper props/attributes.
<details>
<summary>Example</summary>

*some-component.html*
```html
<a href="https://transferwise.com" target="_blank">Send money</a>
```
Expand All @@ -320,6 +331,7 @@ Returns wrapper prop/attribute value with provided `key` (`String`).
<details>
<summary>Example</summary>

*some-component.html*
```html
<a href="https://transferwise.com">Send money</a>
```
Expand All @@ -341,26 +353,19 @@ NOTE: `event` should be written in camelCase and without the `on` present in the
<details>
<summary>Example</summary>

*some-component.html*
```html
<input ng-model="$ctrl.text" />
<p>{{ $ctrl.text }}</p>
<button ng-click="$ctrl.onClick({ $event: $ctrl.text })">Click me</button>
<button ng-click="$ctrl.onClick($ctrl.text)">Click me</button>
```

```js
let component;
let onClick;
beforeEach(() => {
onClick = jest.fn();
component = mount(
`
<some-component
text="$ctrl.text"
on-click="$ctrl.onClick($event)"
></some-component>
`,
{ text: 'Original text', onClick },
);
component = mount('some-component', { text: 'Original text', onClick });
});

it('calls click handler on button click', () => {
Expand Down Expand Up @@ -391,22 +396,18 @@ Merges `props` (`Object`) with existing props and updates view to reflect them,
<details>
<summary>Example</summary>

*some-component.html*
```html
<h1>{{ $ctrl.title }}</h1>
<p>{{ $ctrl.text }}</p>
```

```js
it('changes title and text when props change', () => {
const component = mount(
`
<some-component
title="$ctrl.title"
text="$ctrl.text"
></some-component>
`,
{ title: 'Original title', text: 'Original text' },
);
const component = mount('some-component', {
title: 'Original title',
text: 'Original text',
});

const title = () => component.find('h1').text();
const text = () => component.find('p').text();
Expand All @@ -430,15 +431,18 @@ Returns whether or not the mocked component exists in the rendered template.
<details>
<summary>Example</summary>

*some-component.html*
```html
<button ng-click="$ctrl.show = !$ctrl.show">
Show child
</button>
<child-component ng-if="$ctrl.show"></child-component>
```

```js
let component;
beforeEach(() => {
component = mount(`
<button ng-click="$ctrl.show = !$ctrl.show">
Show child
</button>
<child-component ng-if="$ctrl.show"></child-component>
`);
component = mount('some-component');
});

it('allows toggling child component', () => {
Expand All @@ -461,16 +465,19 @@ Returns all mocked component props.
<details>
<summary>Example</summary>

*some-component.html*
```html
<div>Something else</div>
<child-component
some-prop="'A string'",
some-other-prop="12345"
></child-component>
```

```js
let component;
beforeEach(() => {
component = mount(`
<div>Something else</div>
<child-component
some-prop="'A string'",
some-other-prop="12345"
></child-component>
`);
component = mount('some-component');
});

it('passes props to child component', () => {
Expand All @@ -490,13 +497,16 @@ Returns mocked component prop value with the provided `key` (`String`).
<details>
<summary>Example</summary>

*some-component.html*
```html
<div>Something else</div>
<child-component some-prop="'A string'"></child-component>
```

```js
let component;
beforeEach(() => {
component = mount(`
<div>Something else</div>
<child-component some-prop="'A string'"></child-component>
`);
component = mount('some-component');
});

it('passes some prop to child component', () => {
Expand All @@ -515,18 +525,18 @@ NOTE: `event` should be written in camelCase and without the `on` present in the
<details>
<summary>Example</summary>

*some-component.html*
```html
<div>Something else</div>
<child-component
on-some-prop-change="onSomePropChange"
></child-component>
```

```js
it('calls parent component with data when child component is called', () => {
const onSomePropChange = jest.fn();
mount(
`
<div>Something else</div>
<child-component
on-some-prop-change="onSomePropChange($event)"
></child-component>
`,
{ onSomePropChange }, // ⇦ props for component under test
);
mount('some-component', { onSomePropChange });

expect(onSomePropChange).not.toBeCalled();
childComponent.simulate('somePropChange', 'New value');
Expand Down
11 changes: 2 additions & 9 deletions example.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'angular';
import angular from 'angular';
import 'angular-mocks';

import { mount } from './src/main';
Expand All @@ -25,14 +25,7 @@ describe('Shopping list', () => {
beforeEach(() => {
angular.mock.module('shoppingList');

component = mount(
`
<shopping-list
items="$ctrl.items"
on-add-item="$ctrl.onAddItem"
></shopping-list>
`,
);
component = mount('shopping-list');
});

it('has no list when no items are passed', () => {
Expand Down
6 changes: 2 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "angularjs-enzyme",
"version": "1.2.2",
"version": "2.0.0",
"main": "index.js",
"files": [
"dist/"
Expand Down Expand Up @@ -33,8 +33,6 @@
"@babel/core": "^7.1.5",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/preset-env": "^7.1.5",
"angular": "^1.7.5",
"angular-mocks": "^1.7.5",
"babel-core": "^7.0.0-bridge.0",
"eslint": "^5.8.0",
"eslint-config-airbnb-base": "^13.1.0",
Expand All @@ -60,6 +58,8 @@
]
},
"dependencies": {
"angular": "^1.7.5",
"angular-mocks": "^1.7.5",
"core-js": "^2.5.7",
"lodash": "^4.17.11"
},
Expand Down
3 changes: 3 additions & 0 deletions src/common/utils/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ export const compose = (...functions) => functions.reduce((f, g) => (...args) =>

export const convertKebabCaseToCamelCase = string =>
string.replace(/(-\w)/g, m => m[1].toUpperCase());

export const convertCamelCaseToKebabCase = string =>
string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
Loading

0 comments on commit 9a1a7fd

Please sign in to comment.