weechatRN

Weechat relay client for iOS using websockets https://github.com/mhoran/weechatRN
git clone http://git.hanabi.in/repos/weechatRN.git
Log | Files | Refs | README | LICENSE

commit fe0d6872fc72376891972e3573302b34e33fc5b6
parent 02140c68cda347e863724f875033f8ea8da36bea
Author: Matthew Horan <matt@matthoran.com>
Date:   Sun, 27 Sep 2020 21:58:27 -0400

Add snapshot test for App

Diffstat:
M__tests__/App.js | 28+++++++++++++++++++++-------
A__tests__/__snapshots__/App.js.snap | 339+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackage.json | 3++-
Msrc/store/index.ts | 34++++++++++++++++------------------
Asrc/test-utils.js | 26++++++++++++++++++++++++++
Myarn.lock | 32+++++++++++++-------------------
6 files changed, 417 insertions(+), 45 deletions(-)

diff --git a/__tests__/App.js b/__tests__/App.js @@ -1,10 +1,24 @@ -import "react-native"; -import React from "react"; -import App from "../src/usecase/App"; +import 'react-native'; +import React from 'react'; +import App from '../src/usecase/App'; -// Note: test renderer must be required after react-native. -import renderer from "react-test-renderer"; +import { render } from '../src/test-utils'; -it("renders correctly", () => { - const tree = renderer.create(<App />); +it('renders correctly', () => { + jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper'); + + const tree = render(<App />, { + initialState: { + buffers: { + 1: { + id: '1', + full_name: 'irc.freenode.#weechat', + short_name: '#weechat', + local_variables: { type: 'channel' } + } + } + } + }); + + expect(tree).toMatchSnapshot(); }); diff --git a/__tests__/__snapshots__/App.js.snap b/__tests__/__snapshots__/App.js.snap @@ -0,0 +1,339 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` +<View + style={ + Object { + "backgroundColor": "#333", + "flex": 1, + } + } +> + <View + onMoveShouldSetResponder={[Function]} + onMoveShouldSetResponderCapture={[Function]} + onResponderEnd={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderReject={[Function]} + onResponderRelease={[Function]} + onResponderStart={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + onStartShouldSetResponderCapture={[Function]} + style={ + Object { + "backgroundColor": "transparent", + "flex": 1, + } + } + > + <View + style={ + Object { + "flex": 1, + "zIndex": 0, + } + } + > + <RCTSafeAreaView + emulateUnlessSupported={true} + style={ + Object { + "backgroundColor": "#333", + "flex": 1, + } + } + > + <View + style={ + Object { + "alignItems": "center", + "backgroundColor": "#333", + "flexDirection": "row", + "justifyContent": "space-between", + "paddingBottom": 10, + } + } + > + <View + style={ + Object { + "paddingHorizontal": 5, + } + } + > + <View + accessible={true} + focusable={true} + onClick={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + Object { + "opacity": 1, + "paddingHorizontal": 10, + "paddingVertical": 5, + "width": 40, + } + } + > + <Text + style={ + Array [ + Object { + "color": "#eee", + "fontFamily": "Gill Sans", + "fontSize": 20, + "fontWeight": "bold", + "textAlign": "center", + }, + false, + ] + } + > + # + </Text> + </View> + </View> + <View + accessible={true} + focusable={true} + onClick={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + Object { + "opacity": 1, + } + } + > + <Text + style={ + Object { + "color": "#eee", + "fontFamily": "Thonburi", + "fontSize": 15, + "fontWeight": "bold", + } + } + /> + </View> + <View + style={ + Object { + "paddingHorizontal": 5, + } + } + > + <View + accessible={true} + focusable={false} + onClick={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + Object { + "opacity": 1, + "paddingHorizontal": 10, + "paddingVertical": 5, + "width": 40, + } + } + > + <Image + source={1} + /> + </View> + </View> + </View> + <View + style={ + Object { + "backgroundColor": "#222", + "flex": 1, + } + } + /> + </RCTSafeAreaView> + </View> + <View + accessible={true} + focusable={true} + onClick={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + pointerEvents="none" + style={ + Object { + "backgroundColor": "#000", + "bottom": 0, + "left": 0, + "opacity": 0, + "position": "absolute", + "right": 0, + "top": 0, + "zIndex": 1000, + } + } + /> + <View + accessibilityViewIsModal={false} + style={ + Object { + "backgroundColor": undefined, + "bottom": 0, + "left": 0, + "position": "absolute", + "right": null, + "top": 0, + "transform": Array [ + Object { + "translateX": -320, + }, + ], + "width": 320, + "zIndex": 1001, + } + } + > + <View + style={ + Object { + "backgroundColor": "#121212", + "flex": 1, + } + } + > + <View + style={ + Object { + "height": 30, + } + } + /> + <RCTScrollView + data={ + Array [ + Object { + "full_name": "irc.freenode.#weechat", + "id": "1", + "local_variables": Object { + "type": "channel", + }, + "short_name": "#weechat", + }, + ] + } + disableVirtualization={false} + getItem={[Function]} + getItemCount={[Function]} + horizontal={false} + initialNumToRender={10} + keyExtractor={[Function]} + maxToRenderPerBatch={10} + onContentSizeChange={[Function]} + onEndReachedThreshold={2} + onLayout={[Function]} + onMomentumScrollEnd={[Function]} + onScroll={[Function]} + onScrollBeginDrag={[Function]} + onScrollEndDrag={[Function]} + removeClippedSubviews={false} + renderItem={[Function]} + scrollEventThrottle={50} + stickyHeaderIndices={Array []} + style={ + Object { + "backgroundColor": "#121212", + "flex": 1, + } + } + updateCellsBatchingPeriod={50} + viewabilityConfigCallbackPairs={Array []} + windowSize={21} + > + <View> + <View + onLayout={[Function]} + style={null} + > + <View + accessible={true} + focusable={true} + onClick={[Function]} + onResponderGrant={[Function]} + onResponderMove={[Function]} + onResponderRelease={[Function]} + onResponderTerminate={[Function]} + onResponderTerminationRequest={[Function]} + onStartShouldSetResponder={[Function]} + style={ + Array [ + Object { + "flex": 1, + "height": 40, + "justifyContent": "center", + "paddingHorizontal": 20, + }, + null, + ] + } + > + <View + style={ + Object { + "flexDirection": "row", + } + } + > + <View + style={ + Object { + "flex": 1, + } + } + > + <Text + style={ + Array [ + Object { + "color": "#eee", + "fontFamily": "Thonburi", + "fontSize": 15, + "fontWeight": "bold", + }, + null, + ] + } + > + #weechat + </Text> + </View> + </View> + </View> + </View> + </View> + </RCTScrollView> + </View> + </View> + </View> +</View> +`; diff --git a/package.json b/package.json @@ -25,6 +25,7 @@ }, "devDependencies": { "@babel/core": "^7.2.2", + "@testing-library/react-native": "^7.0.2", "@types/jest": "^25.2.1", "@types/lodash": "^4.14.106", "@types/react": "~16.9.35", @@ -40,7 +41,7 @@ "jest": "^26.4.2", "jest-expo": "^39.0.0", "prettier": "^2.1.2", - "react-test-renderer": "~16.9.0", + "redux-devtools-extension": "^2.13.8", "ts-jest": "^26.4.0", "tslib": "^2.0.1", "typescript": "~4.0.3" diff --git a/src/store/index.ts b/src/store/index.ts @@ -1,13 +1,14 @@ -import { compose, combineReducers, createStore, applyMiddleware } from "redux"; -import thunk from "redux-thunk"; -import { persistStore, persistReducer } from "redux-persist"; -import storage from "redux-persist/lib/storage"; +import { combineReducers, createStore, applyMiddleware } from 'redux'; +import { composeWithDevTools } from 'redux-devtools-extension'; +import thunk from 'redux-thunk'; +import { persistStore, persistReducer } from 'redux-persist'; +import storage from 'redux-persist/lib/storage'; -import buffers, { BufferState } from "./buffers"; -import lines, { LineState } from "./lines"; -import hotlists, { HotListState } from "./hotlists"; -import connection, { ConnectionInfo } from "./connection-info"; -import nicklists, { NicklistState } from "./nicklists"; +import buffers, { BufferState } from './buffers'; +import lines, { LineState } from './lines'; +import hotlists, { HotListState } from './hotlists'; +import connection, { ConnectionInfo } from './connection-info'; +import nicklists, { NicklistState } from './nicklists'; type AppState = { connected: boolean; @@ -30,17 +31,17 @@ const initialState: AppState = { const app = (state: AppState = initialState, action) => { switch (action.type) { - case "DISCONNECT": + case 'DISCONNECT': return { ...state, connected: false }; - case "FETCH_VERSION": + case 'FETCH_VERSION': return { ...state, connected: true }; - case "CHANGE_CURRENT_BUFFER": + case 'CHANGE_CURRENT_BUFFER': return { ...state, currentBufferId: action.bufferId @@ -50,7 +51,7 @@ const app = (state: AppState = initialState, action) => { } }; -const reducer = combineReducers({ +export const reducer = combineReducers({ app, buffers, lines, @@ -59,12 +60,9 @@ const reducer = combineReducers({ nicklists }); -const composeEnhancers = - (<any>window).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; - export const store = createStore( - persistReducer({ storage, key: "state", whitelist: ["connection"] }, reducer), - composeEnhancers(applyMiddleware(thunk)) + persistReducer({ storage, key: 'state', whitelist: ['connection'] }, reducer), + composeWithDevTools(applyMiddleware(thunk)) ); export const persistor = persistStore(store); diff --git a/src/test-utils.js b/src/test-utils.js @@ -0,0 +1,26 @@ +// test-utils.js +import React from 'react'; +import { render as rtlRender } from '@testing-library/react-native'; +import { createStore } from 'redux'; +import { Provider } from 'react-redux'; + +import { reducer } from '../src/store'; + +function render( + ui, + { + initialState, + store = createStore(reducer, initialState), + ...renderOptions + } = {} +) { + function Wrapper({ children }) { + return <Provider store={store}>{children}</Provider>; + } + return rtlRender(ui, { wrapper: Wrapper, ...renderOptions }); +} + +// re-export everything +export * from '@testing-library/react-native'; +// override render method +export { render }; diff --git a/yarn.lock b/yarn.lock @@ -2209,6 +2209,13 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@testing-library/react-native@^7.0.2": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@testing-library/react-native/-/react-native-7.0.2.tgz#fd00b4c5639f606a07b20d0fec5a4cbfc3851efa" + integrity sha512-mOnsEgdbIvXa2cpZz+DTWiqtgObHRICujBGVXHVc1Wr9HbD7mMXIVPiOaUZPL6Wufw23FTy1pqAUIuQydtBc1Q== + dependencies: + pretty-format "^26.0.1" + "@types/babel__core@^7.0.0": version "7.1.10" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.10.tgz#ca58fc195dd9734e77e57c6f2df565623636ab40" @@ -7987,7 +7994,7 @@ pretty-format@^25.2.0, pretty-format@^25.5.0: ansi-styles "^4.0.0" react-is "^16.12.0" -pretty-format@^26.4.2: +pretty-format@^26.0.1, pretty-format@^26.4.2: version "26.4.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.4.2.tgz#d081d032b398e801e2012af2df1214ef75a81237" integrity sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA== @@ -8185,16 +8192,6 @@ react-test-renderer@~16.11.0: react-is "^16.8.6" scheduler "^0.17.0" -react-test-renderer@~16.9.0: - version "16.9.0" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.9.0.tgz#7ed657a374af47af88f66f33a3ef99c9610c8ae9" - integrity sha512-R62stB73qZyhrJo7wmCW9jgl/07ai+YzvouvCXIJLBkRlRqLx4j9RqcLEAfNfU3OxTGucqR2Whmn3/Aad6L3hQ== - dependencies: - object-assign "^4.1.1" - prop-types "^15.6.2" - react-is "^16.9.0" - scheduler "^0.15.0" - react@16.13.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" @@ -8241,6 +8238,11 @@ realpath-native@^2.0.0: resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-2.0.0.tgz#7377ac429b6e1fd599dc38d08ed942d0d7beb866" integrity sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q== +redux-devtools-extension@^2.13.8: + version "2.13.8" + resolved "https://registry.yarnpkg.com/redux-devtools-extension/-/redux-devtools-extension-2.13.8.tgz#37b982688626e5e4993ff87220c9bbb7cd2d96e1" + integrity sha512-8qlpooP2QqPtZHQZRhx3x3OP5skEV1py/zUdMY28WNAocbafxdG2tRD1MWE7sp8obGMNYuLWanhhQ7EQvT1FBg== + redux-persist@^5.9.1: version "5.10.0" resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-5.10.0.tgz#5d8d802c5571e55924efc1c3a9b23575283be62b" @@ -8617,14 +8619,6 @@ scheduler@0.19.1: loose-envify "^1.1.0" object-assign "^4.1.1" -scheduler@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.15.0.tgz#6bfcf80ff850b280fed4aeecc6513bc0b4f17f8e" - integrity sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - scheduler@^0.17.0: version "0.17.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.17.0.tgz#7c9c673e4ec781fac853927916d1c426b6f3ddfe"