Allowing non-connected views and components; Adding tests
This commit is contained in:
3
babel.config.js
Executable file
3
babel.config.js
Executable file
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: ['@babel/preset-env', '@babel/preset-react'],
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -98,7 +98,7 @@
|
||||
|
||||
// Release details
|
||||
// These are automatically injected to built HTML
|
||||
var build = "1552983069";
|
||||
var build = "1553051875";
|
||||
var version = "3.33.0";
|
||||
|
||||
// Construct the script tag
|
||||
|
||||
14
package.json
14
package.json
@ -16,7 +16,10 @@
|
||||
"react-router": "^4.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.4.0",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"babel-core": "^6",
|
||||
"babel-jest": "^24.5.0",
|
||||
"babel-loader": "^7.1.5",
|
||||
"babel-preset-es2015": "^6",
|
||||
"babel-preset-react": "^6",
|
||||
@ -24,10 +27,13 @@
|
||||
"babel-preset-stage-2": "^6",
|
||||
"copy-dir": "^0.3.0",
|
||||
"css-loader": "^0.28.11",
|
||||
"enzyme": "^3.9.0",
|
||||
"enzyme-adapter-react-16": "^1.11.2",
|
||||
"expose-loader": "0.7.3",
|
||||
"extract-text-webpack-plugin": "^3.0.2",
|
||||
"file-loader": "^0.11.2",
|
||||
"fs-copy-file": "2.1.2",
|
||||
"jest": "^24.5.0",
|
||||
"js-sha256": "^0.9.0",
|
||||
"node-sass": "^4.11.0",
|
||||
"react": "^16.8.1",
|
||||
@ -38,6 +44,7 @@
|
||||
"react-redux": "^6",
|
||||
"react-router-dom": "^4",
|
||||
"react-sortablejs": "^1.5.0",
|
||||
"react-test-renderer": "^16.8.4",
|
||||
"redux": "^4",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"sass-loader": "^6",
|
||||
@ -48,9 +55,16 @@
|
||||
"webpack-strip": "0.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"build": "node build_tools/build.js",
|
||||
"dev": "node build_tools/build.js && NODE_ENV=development webpack --watch",
|
||||
"prod": "node build_tools/build.js && NODE_ENV=development webpack && NODE_ENV=production webpack --watch",
|
||||
"release": "node build_tools/build.js && NODE_ENV=development webpack && NODE_ENV=production webpack && python setup.py sdist upload -r pypi && build_tools/release.sh"
|
||||
},
|
||||
"jest": {
|
||||
"verbose": true,
|
||||
"setupFilesAfterEnv": [
|
||||
"./tests/setup.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ import * as lastfmActions from './services/lastfm/actions';
|
||||
import * as geniusActions from './services/genius/actions';
|
||||
import * as snapcastActions from './services/snapcast/actions';
|
||||
|
||||
class App extends React.Component{
|
||||
export class App extends React.Component{
|
||||
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
||||
@ -13,7 +13,7 @@ export default class Dater extends React.Component{
|
||||
* @param milliseconds int
|
||||
* @return string (HH:mm:ss)
|
||||
**/
|
||||
durationTime(milliseconds = false){
|
||||
durationTime(milliseconds = null){
|
||||
if (!milliseconds ) return null
|
||||
|
||||
var string = '';
|
||||
@ -47,7 +47,7 @@ export default class Dater extends React.Component{
|
||||
* @param milliseconds int
|
||||
* @return string (eg 2+ hours)
|
||||
**/
|
||||
durationSentence(milliseconds = false){
|
||||
durationSentence(milliseconds = null){
|
||||
if (!milliseconds ) return null
|
||||
|
||||
var string = '';
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
|
||||
import createBrowserHistory from 'history/createBrowserHistory'
|
||||
|
||||
const customHistory = createBrowserHistory();
|
||||
export default customHistory;
|
||||
@ -5,11 +5,11 @@ import { Provider } from 'react-redux';
|
||||
import { createStore } from 'redux';
|
||||
import { BrowserRouter, Route, IndexRoute } from "react-router-dom";
|
||||
|
||||
import store from './bootstrap.js';
|
||||
require('../scss/app.scss');
|
||||
|
||||
import store from './store';
|
||||
import App from './App';
|
||||
|
||||
require('../scss/app.scss');
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<BrowserRouter basename="/iris">
|
||||
|
||||
@ -109,8 +109,6 @@ initialState.genius = Object.assign({}, initialState.genius, helpers.getStorage(
|
||||
initialState.google = Object.assign({}, initialState.google, helpers.getStorage('google'));
|
||||
initialState.snapcast = Object.assign({}, initialState.snapcast, helpers.getStorage('snapcast'));
|
||||
|
||||
console.log('Bootstrapping', initialState);
|
||||
|
||||
var reducers = combineReducers({
|
||||
core,
|
||||
ui,
|
||||
@ -24,7 +24,7 @@ import * as mopidyActions from '../services/mopidy/actions';
|
||||
import * as spotifyActions from '../services/spotify/actions';
|
||||
import * as lastfmActions from '../services/lastfm/actions';
|
||||
|
||||
class Album extends React.Component{
|
||||
export class Album extends React.Component{
|
||||
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
||||
45
tests/App.test.js
Executable file
45
tests/App.test.js
Executable file
@ -0,0 +1,45 @@
|
||||
|
||||
import React from 'react';;
|
||||
import ReactDOM from 'react-dom';;
|
||||
import { Provider } from 'react-redux';
|
||||
import { createStore } from 'redux';
|
||||
import { BrowserRouter, Route, IndexRoute } from "react-router-dom";
|
||||
|
||||
// Testing-specific
|
||||
import renderer from 'react-test-renderer';
|
||||
import { shallow, mount, render } from 'enzyme';
|
||||
|
||||
// Test subjects
|
||||
import store from '../src/js/store';
|
||||
import * as coreActions from '../src/js/services/core/actions';
|
||||
import * as uiActions from '../src/js/services/ui/actions';
|
||||
import * as pusherActions from '../src/js/services/pusher/actions';
|
||||
import * as mopidyActions from '../src/js/services/mopidy/actions';
|
||||
import * as spotifyActions from '../src/js/services/spotify/actions';
|
||||
import * as lastfmActions from '../src/js/services/lastfm/actions';
|
||||
import * as geniusActions from '../src/js/services/genius/actions';
|
||||
import * as snapcastActions from '../src/js/services/snapcast/actions';
|
||||
import { App } from '../src/js/App';
|
||||
|
||||
describe('<App />', () => {
|
||||
|
||||
it('should render', () => {
|
||||
const dom = shallow(
|
||||
<App
|
||||
history={[]}
|
||||
location={{}}
|
||||
uiActions={uiActions}
|
||||
coreActions={coreActions}
|
||||
pusherActions={pusherActions}
|
||||
mopidyActions={mopidyActions}
|
||||
spotifyActions={spotifyActions}
|
||||
lastfmActions={lastfmActions}
|
||||
geniusActions={geniusActions}
|
||||
snapcastActions={snapcastActions}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
68
tests/components/Dater.test.js
Executable file
68
tests/components/Dater.test.js
Executable file
@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
|
||||
// Testing-specific
|
||||
import { shallow, mount, render } from 'enzyme';
|
||||
|
||||
// Test subjects
|
||||
import Dater from '../../src/js/components/Dater';
|
||||
|
||||
describe('<Dater />', () => {
|
||||
|
||||
it('should handle milliseconds', () => {
|
||||
const dom = shallow(<Dater type="length" data={30000} />);
|
||||
expect(dom.text()).toEqual('0:30');
|
||||
});
|
||||
|
||||
it('should handle date (yyyy-mm-dd)', () => {
|
||||
const dom = shallow(<Dater type="date" data="2015-10-23" />);
|
||||
expect(dom.text()).toEqual("23/10/2015");
|
||||
});
|
||||
|
||||
it('should handle date (mm/dd/yyyy)', () => {
|
||||
const dom = shallow(<Dater type="date" data="10/23/2015" />);
|
||||
expect(dom.text()).toEqual("23/10/2015");
|
||||
});
|
||||
|
||||
it('should handle ago (days)', () => {
|
||||
var date = new Date();
|
||||
date.setDate( date.getDate() - 3 );
|
||||
|
||||
const dom = shallow(<Dater type="ago" data={date} />);
|
||||
expect(dom.text()).toEqual('3 days');
|
||||
});
|
||||
|
||||
it('should handle ago (hours)', () => {
|
||||
var date = new Date();
|
||||
date.setTime( date.getTime() - 3 * 3600000 );
|
||||
|
||||
const dom = shallow(<Dater type="ago" data={date} />);
|
||||
expect(dom.text()).toEqual('3 hours');
|
||||
});
|
||||
|
||||
it('should handle ago (minutes)', () => {
|
||||
var date = new Date();
|
||||
date.setTime( date.getTime() - 3 * 60000 );
|
||||
|
||||
const dom = shallow(<Dater type="ago" data={date} />);
|
||||
expect(dom.text()).toEqual('3 minutes');
|
||||
});
|
||||
|
||||
it('should handle total time', () => {
|
||||
var data = {
|
||||
tracks: [
|
||||
{
|
||||
duration: 5 * 60000
|
||||
},
|
||||
{
|
||||
duration: 5 * 60000
|
||||
},
|
||||
{
|
||||
duration: 5 * 60000
|
||||
}
|
||||
]
|
||||
}
|
||||
const dom = shallow(<Dater type="total-time" data={data} />);
|
||||
expect(dom.text()).toEqual('15 mins');
|
||||
});
|
||||
});
|
||||
28
tests/components/Link.test.js
Executable file
28
tests/components/Link.test.js
Executable file
@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
|
||||
// Testing-specific
|
||||
import { shallow, mount, render } from 'enzyme';
|
||||
|
||||
// Test subjects
|
||||
import Link from '../../src/js/components/Link';
|
||||
|
||||
describe('<Link />', () => {
|
||||
|
||||
const dom = mount(
|
||||
<BrowserRouter>
|
||||
<Link to="test" className="test-classname">Link contents</Link>
|
||||
</BrowserRouter>
|
||||
);
|
||||
|
||||
it('should render a valid <a> tag', () => {
|
||||
const a = dom.find('a');
|
||||
expect(a.length).toBe(1);
|
||||
expect(a.find('[href]').length).toBe(1);
|
||||
expect(a.text()).toEqual('Link contents');
|
||||
});
|
||||
|
||||
it('should handle className prop', () => {
|
||||
expect(dom.find('a').hasClass('test-classname')).toBe(true);
|
||||
});
|
||||
});
|
||||
4
tests/setup.js
Executable file
4
tests/setup.js
Executable file
@ -0,0 +1,4 @@
|
||||
import Enzyme from 'enzyme';
|
||||
import Adapter from 'enzyme-adapter-react-16';
|
||||
|
||||
Enzyme.configure({ adapter: new Adapter() });
|
||||
38
tests/views/Album.test.js
Executable file
38
tests/views/Album.test.js
Executable file
@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import { BrowserRouter, Route, IndexRoute } from "react-router-dom";
|
||||
|
||||
// Testing-specific
|
||||
import renderer from 'react-test-renderer';
|
||||
import { shallow, mount, render } from 'enzyme';
|
||||
|
||||
// Test subjects
|
||||
import { Album } from '../../src/js/views/Album';
|
||||
import store from '../../src/js/store';
|
||||
import * as helpers from '../../src/js/helpers';
|
||||
import * as uiActions from '../../src/js/services/ui/actions';
|
||||
import * as coreActions from '../../src/js/services/core/actions';
|
||||
|
||||
|
||||
describe('<Album />', () => {
|
||||
|
||||
var album = {
|
||||
uri: 'jest:album:test',
|
||||
name: 'Test album',
|
||||
tracks: {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
it('should render', () => {
|
||||
const dom = shallow(
|
||||
<Album
|
||||
album={album}
|
||||
uiActions={uiActions}
|
||||
coreActions={coreActions}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(dom.find('.album-view').length).toBe(1);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user