Skip to content
This repository was archived by the owner on Nov 3, 2025. It is now read-only.

Commit 13a1b34

Browse files
committed
🚧 (createCanal) Type canal creator
1 parent 477c227 commit 13a1b34

11 files changed

Lines changed: 153 additions & 44 deletions

File tree

example/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"start": "node ../node_modules/react-native/local-cli/cli.js start",
77
"test:lint": "cd .. && yarn tslint example/src/**/*.ts{,x} && cd example",
88
"test:unit": "cd .. && yarn jest --config=example/jest.config.js && cd example",
9+
"test:unit:u": "cd .. && yarn jest --config=example/jest.config.js -u && cd example",
910
"test:unit:ci": "cd .. && yarn jest --config=example/jest.config.js --runInBand && cd example",
1011
"test:type": "tsc --noEmit",
1112
"test": "yarn test:lint && yarn test:unit && yarn test:type",

example/src/App.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import React, { Component } from 'react';
2-
import { StyleSheet } from 'react-native';
32
import { SignIn } from './canals/SignIn';
43

54
interface IProps {}
65
export default class App extends Component<IProps> {
76
render() {
8-
return <SignIn style={StyleSheet.absoluteFill} />;
7+
return <SignIn />;
98
}
109
}
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import React, { Component } from 'react';
2-
import { StyleSheet, Text, View } from 'react-native';
2+
import { StyleSheet, Text, View, Button, TextInput } from 'react-native';
33

44
interface IProps {}
55
export class FirstName extends Component<IProps> {
66
render() {
77
return (
88
<View style={styles.container}>
9-
<Text>FirstName</Text>
9+
<Text>Waht is your first name ?</Text>
10+
<TextInput placeholder="Type here" />
11+
<Button title="Next" onPress={() => true} />
1012
</View>
1113
);
1214
}
@@ -17,6 +19,6 @@ const styles = StyleSheet.create({
1719
alignItems: 'center',
1820
backgroundColor: '#FFAAAA',
1921
flex: 1,
20-
justifyContent: 'center',
22+
justifyContent: 'space-around',
2123
},
2224
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react';
2+
import { createCanal } from 'react-gondola';
3+
import { FirstName } from './FirstName';
4+
import { LastName } from './LastName';
5+
6+
// @ts-ignore
7+
const SignInCanal = createCanal(
8+
{ name: 'firstName', Component: FirstName },
9+
{ name: 'lastName', Component: LastName }
10+
);
11+
12+
export const SignIn = () => {
13+
return <SignInCanal />;
14+
};

example/src/canals/SignIn/__tests__/__snapshots__/FirstName.test.tsx.snap

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,58 @@ exports[`FirstName renders correctly 1`] = `
77
"alignItems": "center",
88
"backgroundColor": "#FFAAAA",
99
"flex": 1,
10-
"justifyContent": "center",
10+
"justifyContent": "space-around",
1111
}
1212
}
1313
>
1414
<Text>
15-
FirstName
15+
Waht is your first name ?
1616
</Text>
17+
<TextInput
18+
allowFontScaling={true}
19+
placeholder="Type here"
20+
rejectResponderTermination={true}
21+
underlineColorAndroid="transparent"
22+
/>
23+
<View
24+
accessibilityRole="button"
25+
accessibilityStates={Array []}
26+
accessible={true}
27+
isTVSelectable={true}
28+
onResponderGrant={[Function]}
29+
onResponderMove={[Function]}
30+
onResponderRelease={[Function]}
31+
onResponderTerminate={[Function]}
32+
onResponderTerminationRequest={[Function]}
33+
onStartShouldSetResponder={[Function]}
34+
style={
35+
Object {
36+
"opacity": 1,
37+
}
38+
}
39+
>
40+
<View
41+
style={
42+
Array [
43+
Object {},
44+
]
45+
}
46+
>
47+
<Text
48+
style={
49+
Array [
50+
Object {
51+
"color": "#007AFF",
52+
"fontSize": 18,
53+
"padding": 8,
54+
"textAlign": "center",
55+
},
56+
]
57+
}
58+
>
59+
Next
60+
</Text>
61+
</View>
62+
</View>
1763
</View>
1864
`;

example/src/canals/SignIn/index.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1 @@
1-
import { createCanal } from 'react-gondola';
2-
import { FirstName } from './FirstName';
3-
import { LastName } from './LastName';
4-
5-
// @ts-ignore
6-
export const SignIn = createCanal(FirstName, LastName);
1+
export { SignIn } from './SignIn';

src/Navigation.store.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { observable, computed, action } from 'mobx';
22
import { Subject } from 'rxjs';
3-
import { Canal, IStop } from 'Canal';
3+
import { Canal, IStop } from './Canal';
44

55
interface INavigationEvent {
66
canalId: Canal['id'];

src/__tests__/__snapshots__/createCanal.test.tsx.snap

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

33
exports[`createCanal renders the first page when mounted 1`] = `
4-
<View>
4+
<View
5+
style={
6+
Object {
7+
"bottom": 0,
8+
"left": 0,
9+
"position": "absolute",
10+
"right": 0,
11+
"top": 0,
12+
}
13+
}
14+
>
515
<View
616
style={
717
Object {

src/__tests__/createCanal.test.tsx

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,28 @@ describe('createCanal', () => {
1010
it('throws an error if first arg is not a Component', () => {
1111
try {
1212
// @ts-ignore
13-
createCanal('aaa');
13+
createCanal({ name: 'a', Component: 'aaa' });
1414
} catch (error) {
1515
expect(error.message).toBe(
16-
'`createCanal` expects its arguments to be React components. Received type for argument 1: string'
16+
'`createCanal` could not find a valid `Component` key for argument 1. Received: {"name":"a","Component":"aaa"}'
1717
);
1818
}
1919
expect.assertions(1);
2020
});
2121

2222
it('renders the first page when mounted', () => {
23-
const Transitioner = createCanal(View);
23+
const Transitioner = createCanal({ name: 'a', Component: View });
2424
const testRenderer = TestRenderer.create(<Transitioner />);
2525
expect(testRenderer.toJSON()).toMatchSnapshot();
2626
});
2727

2828
it('throws an error if any arg is not a Component', () => {
2929
try {
3030
// @ts-ignore
31-
createCanal(View, 'aaa');
31+
createCanal({ name: 'a', Component: View }, { name: 'b', Component: 'aaa' });
3232
} catch (error) {
3333
expect(error.message).toBe(
34-
'`createCanal` expects its arguments to be React components. Received type for argument 2: string'
34+
'`createCanal` could not find a valid `Component` key for argument 2. Received: {"name":"b","Component":"aaa"}'
3535
);
3636
}
3737
expect.assertions(1);
@@ -40,8 +40,14 @@ describe('createCanal', () => {
4040
it('emits the new canal to the navigation store', () => {
4141
const PageOne = () => <View />;
4242
const PageTwo = () => <View />;
43-
const Transitioner = createCanal(PageOne, PageTwo);
44-
const expectedCanal = new Canal([PageOne, PageTwo]);
43+
const Transitioner = createCanal(
44+
{ name: 'pageOne', Component: PageOne },
45+
{ name: 'pageTwo', Component: PageTwo }
46+
);
47+
const expectedCanal = new Canal([
48+
{ name: 'pageOne', Component: PageOne },
49+
{ name: 'pageTwo', Component: PageTwo },
50+
]);
4551
Navigation.getInstance().canalsSubject.subscribe({
4652
next: canal => {
4753
expect(canal).toEqual(expectedCanal);
@@ -50,4 +56,27 @@ describe('createCanal', () => {
5056
TestRenderer.create(<Transitioner />);
5157
expect.assertions(1);
5258
});
59+
60+
it('throws an error if name is missing', () => {
61+
try {
62+
// @ts-ignore
63+
createCanal({ Component: View });
64+
} catch (error) {
65+
expect(error.message).toBe(
66+
'`createCanal` could not find a valid `name` key for argument 1. Received: {}'
67+
);
68+
}
69+
expect.assertions(1);
70+
});
71+
72+
// @TODO 19-08-01 Pass this test
73+
xit('throws an error some names are duplicated', () => {
74+
try {
75+
// @ts-ignore
76+
createCanal({ name: 'a', Component: View }, { name: 'a', Component: View });
77+
} catch (error) {
78+
expect(error.message).toBe('`createCanal` found duplicated `name: a` key.');
79+
}
80+
expect.assertions(1);
81+
});
5382
});

src/canal.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@ export interface IStop {
88
export class Canal {
99
id: number = Date.now();
1010
stopsList: IStop[] = [];
11-
constructor(PagesList: ComponentType[]) {
12-
this.stopsList = PagesList.map(Page => ({
13-
Component: Page,
14-
name: Page.displayName || 'UntitledPage',
15-
}));
11+
constructor(StopsList: IStop[]) {
12+
this.stopsList = StopsList;
1613
}
1714
}

0 commit comments

Comments
 (0)