Skip to content

Commit

Permalink
Reorg some templates and add tests (react-boilerplate#1414)
Browse files Browse the repository at this point in the history
* Reorg some templates and add tests

- Also make sure that we keep LanguageProvider tests after clean

* Move to container structure for internals

* Remove old filename ref

* Actually remove folders, thanks @Dattaya
  • Loading branch information
outdooricon authored and Dattaya committed Jan 10, 2017
1 parent 239d8b0 commit e660697
Show file tree
Hide file tree
Showing 24 changed files with 160 additions and 66 deletions.
2 changes: 1 addition & 1 deletion app/containers/App/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
*
* App.react.js
* App
*
* This component is the skeleton around the actual pages, and should only
* contain code that should be seen on all pages. (e.g. navigation bar)
Expand Down
37 changes: 25 additions & 12 deletions app/containers/LanguageProvider/tests/index.test.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,47 @@
import React from 'react';
import { shallow } from 'enzyme';
import { shallow, mount } from 'enzyme';
import { FormattedMessage, defineMessages } from 'react-intl';
import { Provider } from 'react-redux';
import { browserHistory } from 'react-router';

import LanguageProvider from '../index';

import ConnectedLanguageProvider, { LanguageProvider } from '../index';
import configureStore from '../../../store';

import { translationMessages } from '../../../i18n';

const messages = defineMessages({
someMessage: {
id: 'some.id',
defaultMessage: 'This is some default message',
en: 'This is some en message',
},
});

describe('<LanguageProvider />', () => {
it('should render its children', () => {
const children = (<h1>Test</h1>);
const renderedComponent = shallow(
<LanguageProvider messages={messages} locale="en">
{children}
</LanguageProvider>
);
expect(renderedComponent.contains(children)).toBe(true);
});
});

describe('<ConnectedLanguageProvider />', () => {
let store;

beforeAll(() => {
store = configureStore({}, browserHistory);
});

it('should render the default language messages', () => {
const messages = defineMessages({
someMessage: {
id: 'some.id',
defaultMessage: 'This is some default message',
},
});
const renderedComponent = shallow(
const renderedComponent = mount(
<Provider store={store}>
<LanguageProvider messages={translationMessages}>
<ConnectedLanguageProvider messages={translationMessages}>
<FormattedMessage {...messages.someMessage} />
</LanguageProvider>
</ConnectedLanguageProvider>
</Provider>
);
expect(renderedComponent.contains(<FormattedMessage {...messages.someMessage} />)).toBe(true);
Expand Down
32 changes: 32 additions & 0 deletions app/tests/i18n.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { DEFAULT_LOCALE } from '../containers/App/constants';
import { formatTranslationMessages } from '../i18n';

jest.mock('../translations/en.json', () => (
{
message1: 'default message',
message2: 'default message 2',
}
));

const esTranslationMessages = {
message1: 'mensaje predeterminado',
message2: '',
};

describe('formatTranslationMessages', () => {
it('should build only defaults when DEFAULT_LOCALE', () => {
const result = formatTranslationMessages(DEFAULT_LOCALE, { a: 'a' });

expect(result).toEqual({ a: 'a' });
});


it('should combine default locale and current locale when not DEFAULT_LOCALE', () => {
const result = formatTranslationMessages('', esTranslationMessages);

expect(result).toEqual({
message1: 'mensaje predeterminado',
message2: 'default message 2',
});
});
});
9 changes: 9 additions & 0 deletions app/utils/tests/asyncInjectors.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ describe('asyncInjectors', () => {
expect(actual.toJS()).toEqual(expected.toJS());
});

it('should not assign reducer if already existing', () => {
const injectReducer = injectAsyncReducer(store);

injectReducer('test', reducer);
injectReducer('test', () => {});

expect(store.asyncReducers.test.toString()).toEqual(reducer.toString());
});

it('should throw if passed invalid name', () => {
let result = false;

Expand Down
66 changes: 17 additions & 49 deletions internals/scripts/clean.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,68 +13,36 @@ if (!test('-e', 'internals/templates')) {

process.stdout.write('Cleanup started...');

// Cleanup components folder
rm('-rf', 'app/components/*');

// Cleanup containers folder
rm('-rf', 'app/containers/*');
mkdir('-p', 'app/containers/App');
mkdir('-p', 'app/containers/NotFoundPage');
mkdir('-p', 'app/containers/HomePage');
cp('internals/templates/appContainer.js', 'app/containers/App/index.js');
cp('internals/templates/constants.js', 'app/containers/App/constants.js');
cp('internals/templates/notFoundPage/notFoundPage.js', 'app/containers/NotFoundPage/index.js');
cp('internals/templates/notFoundPage/messages.js', 'app/containers/NotFoundPage/messages.js');
cp('internals/templates/homePage/homePage.js', 'app/containers/HomePage/index.js');
cp('internals/templates/homePage/messages.js', 'app/containers/HomePage/messages.js');
// Reuse existing LanguageProvider and i18n tests
mv('app/containers/LanguageProvider/tests', 'internals/templates/containers/LanguageProvider');
cp('app/tests/i18n.test.js', 'internals/templates/tests/i18n.test.js');

// Handle Translations
rm('-rf', 'app/translations/*')
mkdir('-p', 'app/translations');
cp('internals/templates/translations/en.json',
'app/translations/en.json');
// Cleanup components/
rm('-rf', 'app/components/*');

// move i18n file
cp('internals/templates/i18n.js',
'app/i18n.js');
// Handle containers/
rm('-rf', 'app/containers');
mv('internals/templates/containers', 'app');

// Copy LanguageProvider
mkdir('-p', 'app/containers/LanguageProvider');
mkdir('-p', 'app/containers/LanguageProvider/tests');
cp('internals/templates/languageProvider/actions.js',
'app/containers/LanguageProvider/actions.js');
cp('internals/templates/languageProvider/constants.js',
'app/containers/LanguageProvider/constants.js');
cp('internals/templates/languageProvider/languageProvider.js',
'app/containers/LanguageProvider/index.js');
cp('internals/templates/languageProvider/reducer.js',
'app/containers/LanguageProvider/reducer.js');
cp('internals/templates/languageProvider/selectors.js',
'app/containers/LanguageProvider/selectors.js');
// Handle tests/
mv('internals/templates/tests', 'app');

// Copy selectors
mkdir('app/containers/App/tests');
cp('internals/templates/selectors.js',
'app/containers/App/selectors.js');
cp('internals/templates/selectors.test.js',
'app/containers/App/tests/selectors.test.js');
// Handle translations/
rm('-rf', 'app/translations')
mv('internals/templates/translations', 'app');

// Utils
// Handle utils/
rm('-rf', 'app/utils');
mkdir('app/utils');
mkdir('app/utils/tests');
cp('internals/templates/asyncInjectors.js',
'app/utils/asyncInjectors.js');
cp('internals/templates/asyncInjectors.test.js',
'app/utils/tests/asyncInjectors.test.js');
mv('internals/templates/utils', 'app')

// Replace the files in the root app/ folder
cp('internals/templates/app.js', 'app/app.js');
cp('internals/templates/global-styles.js', 'app/global-styles.js');
cp('internals/templates/i18n.js', 'app/i18n.js');
cp('internals/templates/index.html', 'app/index.html');
cp('internals/templates/reducers.js', 'app/reducers.js');
cp('internals/templates/routes.js', 'app/routes.js');
cp('internals/templates/store.js', 'app/store.js');
cp('internals/templates/store.test.js', 'app/tests/store.test.js');

// Remove the templates folder
rm('-rf', 'internals/templates');
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
16 changes: 16 additions & 0 deletions internals/templates/containers/App/tests/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { shallow } from 'enzyme';

import App from '../index';

describe('<App />', () => {
it('should render its children', () => {
const children = (<h1>Test</h1>);
const renderedComponent = shallow(
<App>
{children}
</App>
);
expect(renderedComponent.contains(children)).toBe(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,17 @@ describe('makeSelectLocationState', () => {
});
expect(makeSelectLocationState()(mockedState)).toEqual(route.toJS());
});

it('should return cached js routeState for same concurrent calls', () => {
const route = fromJS({
locationBeforeTransitions: null,
});
const mockedState = fromJS({
route,
});
const selectLocationState = makeSelectLocationState();

const firstRouteStateJS = selectLocationState(mockedState);
expect(selectLocationState(mockedState)).toBe(firstRouteStateJS);
});
});
File renamed without changes.
File renamed without changes.
17 changes: 17 additions & 0 deletions internals/templates/containers/HomePage/tests/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import { shallow } from 'enzyme';

import HomePage from '../index';
import messages from '../messages';

describe('<HomePage />', () => {
it('should render the page message', () => {
const renderedComponent = shallow(
<HomePage />
);
expect(renderedComponent.contains(
<FormattedMessage {...messages.header} />
)).toEqual(true);
});
});
17 changes: 17 additions & 0 deletions internals/templates/containers/NotFoundPage/tests/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import { shallow } from 'enzyme';

import NotFoundPage from '../index';
import messages from '../messages';

describe('<NotFoundPage />', () => {
it('should render the page message', () => {
const renderedComponent = shallow(
<NotFoundPage />
);
expect(renderedComponent.contains(
<FormattedMessage {...messages.header} />
)).toEqual(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/

import { browserHistory } from 'react-router';
import configureStore from '../store'; // eslint-disable-line
import configureStore from '../store';

describe('configureStore', () => {
let store;
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
* Test async injectors
*/


import configureStore from 'store';
import { memoryHistory } from 'react-router';
import { put } from 'redux-saga/effects';
import { fromJS } from 'immutable';

import configureStore from 'store';

import {
injectAsyncReducer,
injectAsyncSagas,
getAsyncInjectors,
} from 'utils/asyncInjectors';
} from '../asyncInjectors';

// Fixtures

Expand Down Expand Up @@ -87,6 +87,15 @@ describe('asyncInjectors', () => {
expect(actual.toJS()).toEqual(expected.toJS());
});

it('should not assign reducer if already existing', () => {
const injectReducer = injectAsyncReducer(store);

injectReducer('test', reducer);
injectReducer('test', () => {});

expect(store.asyncReducers.test.toString()).toEqual(reducer.toString());
});

it('should throw if passed invalid name', () => {
let result = false;

Expand Down

0 comments on commit e660697

Please sign in to comment.