Skip to content

Commit

Permalink
Merge pull request #49 from shoutem/release/0.12.0
Browse files Browse the repository at this point in the history
Release/0.12.0
  • Loading branch information
Definitely-Not-Vlad authored Jan 14, 2021
2 parents f0acf45 + a54d15c commit 573a0ae
Show file tree
Hide file tree
Showing 28 changed files with 9,732 additions and 511 deletions.
8 changes: 2 additions & 6 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
**/dist/*
**/node_modules/*
**/server.js
**/webpack.config*.js
**/test-utils/setup.js

_tests_
test-utils
22 changes: 0 additions & 22 deletions .eslintrc

This file was deleted.

1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ node_modules

# Ignore test folders
*_tests_
test-utils

# Ignore local/config files
.editorconfig
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,18 @@ Finally, run the app!
$ react-native run-ios
```

## Automated Testing

Jest has been set up to provide the ability to test `@shoutem/theme` after any changes.

To run tests, first add the following to `dependencies` in `package.json`:
- `"react-native": "0.63.2"`
- `"react": "16.13.1"`
- `"react-dom": "16.13.1"`

Or whichever version is relevant after your changes. Then run `npm i && npm run test` and see if you broke anything.


## UI Toolkit

Shoutem UI is a part of the Shoutem UI Toolkit that enables you to build professionally looking React Native apps with ease.
Expand Down
25 changes: 12 additions & 13 deletions _tests_/StyleNormalizer.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { assert } from 'chai';
import StyleNormalizer from '../src/StyleNormalizer/StyleNormalizer';
import {
SIDES,
Expand All @@ -13,54 +12,54 @@ describe('StyleNormalizer', () => {
const styleNormalizer = new StyleNormalizer();
styleNormalizer.createNormalizers('test', [SIDES]);

assert.isOk(styleNormalizer.normalizers.test, 'normalizer not created');
expect(styleNormalizer.normalizers.test).toBeTruthy();
});
it('creates proper horizontal normalizers', () => {
const styleNormalizer = new StyleNormalizer();
styleNormalizer.createNormalizers('test', [HORIZONTAL]);

assert.isOk(styleNormalizer.normalizers.testHorizontal, 'normalizer not created');
expect(styleNormalizer.normalizers.testHorizontal).toBeTruthy();
});
it('creates proper vertical normalizers', () => {
const styleNormalizer = new StyleNormalizer();
styleNormalizer.createNormalizers('test', [VERTICAL]);

assert.isOk(styleNormalizer.normalizers.testVertical, 'normalizer not created');
expect(styleNormalizer.normalizers.testVertical).toBeTruthy();
});
it('creates proper horizontal normalizers', () => {
const styleNormalizer = new StyleNormalizer();
styleNormalizer.createNormalizers('test', [CORNERS]);

assert.isOk(styleNormalizer.normalizers.test, 'normalizer not created');
expect(styleNormalizer.normalizers.test).toBeTruthy();
});
it('creates multiple normalizers', () => {
const styleNormalizer = new StyleNormalizer();
styleNormalizer.createNormalizers('test', [SIDES, HORIZONTAL, VERTICAL]);

assert.isOk(styleNormalizer.normalizers.test, 'normalizer not created');
assert.isOk(styleNormalizer.normalizers.testHorizontal, 'normalizer not created');
assert.isOk(styleNormalizer.normalizers.testVertical, 'normalizer not created');
expect(styleNormalizer.normalizers.test).toBeTruthy();
expect(styleNormalizer.normalizers.testHorizontal).toBeTruthy();
expect(styleNormalizer.normalizers.testVertical).toBeTruthy();
});
it('throws error if normalizer for shorthand already exists', () => {
const styleNormalizer = new StyleNormalizer();
assert.throws(() => {
expect(() => {
styleNormalizer.createNormalizers('test', [SIDES, CORNERS]);
}, 'Normalizer for \'test\' shorthand already exists');
}).toThrow();
});
});
describe('normalizers creation with suffix', () => {
it('creates proper normalizers with suffix', () => {
const styleNormalizer = new StyleNormalizer();
styleNormalizer.createNormalizers('test', [SIDES], 'Suffix');

assert.isOk(styleNormalizer.normalizers.testSuffix, 'normalizer not created');
expect(styleNormalizer.normalizers.testSuffix).toBeTruthy();
});
it('creates proper normalizers with suffix', () => {
const styleNormalizer = new StyleNormalizer();
styleNormalizer.createNormalizers('test', [SIDES, VERTICAL], 'Suffix');

assert.isOk(styleNormalizer.normalizers.testSuffix, 'normalizer not created');
assert.isOk(styleNormalizer.normalizers.testVerticalSuffix, 'normalizer not created');
expect(styleNormalizer.normalizers.testSuffix).toBeTruthy();
expect(styleNormalizer.normalizers.testVerticalSuffix).toBeTruthy();
});
});
});
15 changes: 9 additions & 6 deletions _tests_/StyleProvider.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react-native';
import { assert } from 'chai';
import React from 'react';
import { mount } from 'enzyme';
import { Theme } from '../';

import Theme from '../src/Theme';
import StyleProviderTestAppComponent from './mocks/StyleProviderTestAppComponent';
import StyleProviderTestComponent from './mocks/StyleProviderTestComponent';

Expand All @@ -10,10 +10,13 @@ describe('StyleProvider', () => {
const demo = mount(
<StyleProviderTestAppComponent>
<StyleProviderTestComponent />
</StyleProviderTestAppComponent>
</StyleProviderTestAppComponent>,
);
const passedTheme = demo.find(StyleProviderTestComponent).nodes[0].getThemeStyle();
const passedTheme = demo
.find(StyleProviderTestComponent)
.instance()
.getThemeStyle();

assert.isTrue(passedTheme instanceof Theme, 'theme not available in context');
expect(passedTheme instanceof Theme).toBe(true);
});
});
101 changes: 36 additions & 65 deletions _tests_/connectStyle.spec.js
Original file line number Diff line number Diff line change
@@ -1,89 +1,72 @@
import React, { Component } from 'react';
import { assert } from 'chai';
import React, { PureComponent } from 'react';
import { mount } from 'enzyme';
import { TEST_PROPERTY } from './mocks/ThemeTest';
import StyleProviderTestAppComponent,
{
TEST_VARIABLE,
} from './mocks/StyleProviderTestAppComponent';
import StyleProviderTestAppComponent from './mocks/StyleProviderTestAppComponent';
import {
ConnectedClassComponent,
ConnectedStatelessComponent,
componentName,
} from './mocks/ConnectStyleTestComponents';

describe('connectStyle', () => {
it('provides proper style to component', () => {
it('does not provide irrelevant style to component', () => {
const demo = mount(
<StyleProviderTestAppComponent>
<ConnectedClassComponent />
</StyleProviderTestAppComponent>
</StyleProviderTestAppComponent>,
);
const passedStyle = demo.find(ConnectedClassComponent)
.nodes[0].refs.wrappedInstance.props.style;
const passedStyle = demo.find(ConnectedClassComponent).instance().props
.style;

assert.equal(
passedStyle.testStyle.testProperty,
TEST_PROPERTY,
'style different then defined at theme'
);
assert.equal(
passedStyle.testStyle.variableProperty,
TEST_VARIABLE,
'style different then variable value (as defined at theme)'
);
expect(passedStyle.testStyle).toBe(undefined);
});

it('provides normalized style ', () => {
const denormalizedStyle = { denormalized: { padding: 5 } };
const demo = mount(
<StyleProviderTestAppComponent>
<ConnectedClassComponent style={denormalizedStyle} />
</StyleProviderTestAppComponent>
</StyleProviderTestAppComponent>,
);

const passedStyle = demo.find(ConnectedClassComponent)
.nodes[0].refs.wrappedInstance.props.style;

// Weird enzyme magic, in this scenario, instead of props, it ends up in state.
// Props end up containing the denormalized style (padding: 5).
// If logged in ConnectStyleTestClassComponent as this.props.style, you end up
// with normalizedStyle, as expected.
const passedStyle = demo.find(ConnectedClassComponent).instance().state
.style;
const normalizedStyle = {
paddingTop: 5,
paddingBottom: 5,
paddingLeft: 5,
paddingRight: 5,
paddingTop: 5,
};

assert.deepEqual(
passedStyle.denormalized,
normalizedStyle,
'style different then defined at theme'
);
assert.equal(
passedStyle.testStyle.variableProperty,
TEST_VARIABLE,
'style different then variable value (as defined at theme)'
);
expect(passedStyle.denormalized).toEqual(normalizedStyle);
expect(passedStyle.testStyle).toBe(undefined);
});

it('creates ref for react Component component', () => {
const demo = mount(
<StyleProviderTestAppComponent>
<ConnectedClassComponent />
</StyleProviderTestAppComponent>
</StyleProviderTestAppComponent>,
);
const instance = demo.find(ConnectedClassComponent)
.nodes[0].refs.wrappedInstance;
const instance = demo.find(ConnectedClassComponent).instance();

assert.isOk(instance instanceof Component, 'instance doesn\'t exists at class component');
expect(instance instanceof PureComponent).toBeTruthy();
});
it('doesn\'t create ref for stateless component', () => {

it("doesn't create ref for stateless component", () => {
const demo = mount(
<StyleProviderTestAppComponent>
<ConnectedStatelessComponent />
</StyleProviderTestAppComponent>
</StyleProviderTestAppComponent>,
);
const instance = demo.find(ConnectedStatelessComponent)
.nodes[0].refs.wrappedInstance;
const instance = demo.find(ConnectedStatelessComponent).instance().props
.ref;

assert.isNotOk(instance, 'instance exists on stateless component');
expect(instance).toBeFalsy();
});

describe('virtual', () => {
it('pass parent style to child component as parent style', () => {
const context = {
Expand All @@ -94,15 +77,13 @@ describe('connectStyle', () => {
test: 1,
},
};
const demo = mount(<ConnectedClassComponent virtual/>, { context });
const demo = mount(<ConnectedClassComponent virtual />, { context });
const instanceContext = demo.instance().getChildContext();

assert.strictEqual(
instanceContext.parentStyle,
context.parentStyle,
'doesn\'t pass correct style');
expect(instanceContext.parentStyle).toBe(context.parentStyle);
});
it('doesn\'t pass parent style to child component as parent style', () => {

it("doesn't pass parent style to child component as parent style", () => {
const context = {
parentStyle: {
[componentName]: {
Expand All @@ -119,19 +100,9 @@ describe('connectStyle', () => {
const demo = mount(<ConnectedClassComponent />, { context });
const instanceContext = demo.instance().getChildContext();

const expectedParentStyle = {
'some.child.component': {
flex: 1,
},
'some.child.component1': {
flex: 2,
},
};
assert.deepEqual(
instanceContext.parentStyle,
expectedParentStyle,
'pass correct style'
);
const expectedParentStyle = {};

expect(instanceContext.parentStyle).toEqual(expectedParentStyle);
});
});
});
46 changes: 24 additions & 22 deletions _tests_/mocks/ConnectStyleTestComponents.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,45 @@
import React, {
Component,
Text,
} from 'react-native';
import React, { Component } from 'react';
import PropTypes from 'prop-types';

import { connectStyle } from '../../';
import { Text } from 'react-native';
import { ThemeShape } from '../../src/Theme';
import connectStyle from '../../src/connectStyle';

class ConnectStyleTestClassComponent extends Component {
static propTypes = {
style: PropTypes.object,
};

constructor(props, context) {
super(props, context);

this.state = { text: 'Testing StyleProvider' };
}

render() {
return <Text>{this.state.text}</Text>;
const { text } = this.state;

return <Text>{text}</Text>;
}
}

function ConnectStyleTestStatelessComponent() {
return <Text>Stateless Component</Text>;
}

const style = {
testStyle: {},
};

const options = { withRef: true };
const style = { testStyle: {} };
const options = {};
export const componentName = 'test.component.TestComponent';

const componentName = 'test.component.TestComponent';

const ConnectedClassComponent =
connectStyle(componentName, style, undefined, options)(ConnectStyleTestClassComponent);
const ConnectedStatelessComponent =
connectStyle(componentName, style, undefined, options)(ConnectStyleTestStatelessComponent);
export const ConnectedClassComponent = connectStyle(
componentName,
style,
undefined,
options,
)(ConnectStyleTestClassComponent);

export {
ConnectedClassComponent,
ConnectedStatelessComponent,
export const ConnectedStatelessComponent = connectStyle(
componentName,
};
style,
undefined,
options,
)(ConnectStyleTestStatelessComponent);
Loading

0 comments on commit 573a0ae

Please sign in to comment.