Skip to content

Commit 6e17388

Browse files
Mohammad Hunan ChughtaiMohammad Hunan Chughtaimongodben
authored
(DOCSP-26984): @realm/reactify: Mixed - React Native SDK (#2411)
## Pull Request Info ### Jira - https://jira.mongodb.org/browse/DOCSP-26984 ### Staged Changes - [Mixed - React Native SDK](https://docs-mongodbcom-staging.corp.mongodb.com/realm/docsworker-xlarge/mixed-object/sdk/react-native/realm-database/schemas/mixed/) ### Reminder Checklist If your PR modifies the docs, you might need to also update some corresponding pages. Check if completed or N/A. - [N/A] Create Jira ticket for corresponding docs-app-services update(s), if any - [N/A] Checked/updated Admin API - [N/A] Checked/updated CLI reference ### Review Guidelines [REVIEWING.md](https://github.com/mongodb/docs-realm/blob/master/REVIEWING.md) Co-authored-by: Mohammad Hunan Chughtai <[email protected]> Co-authored-by: Ben Perlmutter <[email protected]>
1 parent 7992990 commit 6e17388

File tree

13 files changed

+552
-18
lines changed

13 files changed

+552
-18
lines changed

examples/react-native/.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = {
1212
'no-undef': 'off',
1313
'no-new': 'off',
1414
'jsx-quotes': 0, // do not remove this line, this removes the requirement for double quotes in jsx/tsx. The single quotes in jsx help bluehawk replace testIDs in the generated snippets for the docs
15+
'react-hooks/exhaustive-deps': 0,
1516
'react/jsx-max-props-per-line': [0, {'maximum': 4, 'when': 'multiline'}],
1617
},
1718
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import Realm from 'realm';
2+
// :snippet-start: js-cat-schema
3+
class Cat extends Realm.Object {
4+
static schema = {
5+
name: 'Cat',
6+
properties: {
7+
name: 'string',
8+
birthDate: 'mixed',
9+
},
10+
};
11+
}
12+
// :snippet-end:
13+
export default Cat;
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import React, {useEffect} from 'react';
2+
import {Text, View} from 'react-native';
3+
import {render, waitFor} from '@testing-library/react-native';
4+
import Realm from 'realm';
5+
import {createRealmContext} from '@realm/react';
6+
import Cat from '../../models/Cat';
7+
8+
jest.setTimeout(30000);
9+
10+
const realmConfig = {
11+
schema: [Cat],
12+
deleteRealmIfMigrationNeeded: true,
13+
};
14+
15+
const {RealmProvider, useRealm, useQuery} = createRealmContext(realmConfig);
16+
17+
let assertionRealm;
18+
19+
describe('Mixed Tests', () => {
20+
beforeEach(async () => {
21+
// we will use this Realm for assertions to access Realm Objects outside of a Functional Component (like required by @realm/react)
22+
assertionRealm = await Realm.open(realmConfig);
23+
24+
// delete every object in the realmConfig in the Realm to make test idempotent
25+
assertionRealm.write(() => {
26+
assertionRealm.delete(assertionRealm.objects(Cat));
27+
28+
new Cat(assertionRealm, {
29+
name: 'Clover',
30+
birthDate: new Date('January 21, 2016'),
31+
});
32+
});
33+
});
34+
afterAll(() => {
35+
if (!assertionRealm.isClosed) {
36+
assertionRealm.close();
37+
}
38+
});
39+
it('should create an object with a mixed value', async () => {
40+
// :snippet-start: create-mixed-object
41+
// :replace-start: {
42+
// "terms": {
43+
// " testID='catItem'": ""
44+
// }
45+
// }
46+
const CreateCatsInput = () => {
47+
const realm = useRealm();
48+
49+
useEffect(() => {
50+
// Add data to the Realm when the component mounts
51+
realm.write(() => {
52+
// create a Cat with a birthDate value of type string
53+
new Cat(realm, {
54+
name: 'Euler',
55+
birthDate: 'December 25th, 2017',
56+
});
57+
// create a Cat with a birthDate value of type date
58+
new Cat(realm, {
59+
name: 'Blaise',
60+
birthDate: new Date('August 17, 2020'),
61+
});
62+
63+
// create a Cat with a birthDate value of type int
64+
new Cat(realm, {name: 'Euclid', birthDate: 10152021});
65+
66+
// create a Cat with a birthDate value of type null
67+
new Cat(realm, {name: 'Pythagoras', birthDate: null});
68+
});
69+
}, []);
70+
71+
// retrieve all cats
72+
const cats = useQuery(Cat);
73+
74+
return (
75+
<>
76+
{cats.map(cat => (
77+
<View testID='catItem'>
78+
<Text>{cat.name}</Text>
79+
<Text>{String(cat.birthDate)}</Text>
80+
</View>
81+
))}
82+
</>
83+
);
84+
};
85+
// :replace-end:
86+
// :snippet-end:
87+
88+
const App = () => (
89+
<RealmProvider>
90+
<CreateCatsInput />
91+
</RealmProvider>
92+
);
93+
94+
const {getAllByTestId} = render(<App />);
95+
96+
const catItems = await waitFor(() => getAllByTestId('catItem'), {
97+
timeout: 5000,
98+
});
99+
100+
// Test that 5 Cat Items have been added to the UI,
101+
// and 5 matching Cat objects have been created in the assertionRealm
102+
// (since there was already 1 cat object 'clover' created in the beforeEach)
103+
// + the 4 new Cats
104+
setTimeout(() => {
105+
expect(catItems.length).toBe(5);
106+
const cats = assertionRealm.objects(Cat);
107+
expect(cats.length).toBe(5);
108+
}, 5500);
109+
});
110+
it('should query for objects with a mixed value', async () => {
111+
// :snippet-start: query-mixed-object
112+
// :replace-start: {
113+
// "terms": {
114+
// " testID='catBirthDate'": ""
115+
// }
116+
// }
117+
const CatInfoCard = ({catName}) => {
118+
// To query for the cat's birthDate, filter for their name to retrieve the realm object.
119+
// Use dot notation to access the birthDate property.
120+
const cat = useQuery(Cat).filtered(`name = '${catName}'`)[0];
121+
const catBirthDate = cat.birthDate;
122+
123+
if (cat) {
124+
return (
125+
<>
126+
<Text>{catName}</Text>
127+
<Text testID='catBirthDate'>{String(catBirthDate)}</Text>
128+
</>
129+
);
130+
} else {
131+
return <Text>Cat not found</Text>;
132+
}
133+
};
134+
// :replace-end:
135+
// :snippet-end:
136+
137+
const App = () => (
138+
<RealmProvider>
139+
<CatInfoCard catName='Clover' />
140+
</RealmProvider>
141+
);
142+
const {getByTestId} = render(<App />);
143+
const catBirthDate = await waitFor(() => getByTestId('catBirthDate'));
144+
// Expect catBirthDate in the UI to be the same value we set in the beforeEach (which is clover's birthday 'January 21, 2016')
145+
expect(new Date(catBirthDate.props.children)).toStrictEqual(
146+
new Date('January 21, 2016'),
147+
);
148+
});
149+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Realm from 'realm';
2+
// TODO: Replace `static schema` with TS-first models + realm-babel-plugin (https://www.npmjs.com/package/@realm/babel-plugin) approach once realm-babel-plugin version 0.1.2 releases with bug fixes
3+
// :snippet-start: ts-cat-schema
4+
class Cat extends Realm.Object<Cat> {
5+
name!: string;
6+
birthDate?: Realm.Mixed;
7+
8+
static schema = {
9+
name: 'Cat',
10+
properties: {
11+
name: 'string',
12+
birthDate: 'mixed',
13+
},
14+
};
15+
}
16+
// :snippet-end:
17+
export default Cat;
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import React, {useEffect} from 'react';
2+
import {Text, View} from 'react-native';
3+
import {render, waitFor} from '@testing-library/react-native';
4+
import Realm from 'realm';
5+
import {createRealmContext} from '@realm/react';
6+
import Cat from '../../models/Cat';
7+
8+
jest.setTimeout(30000);
9+
10+
const realmConfig = {
11+
schema: [Cat],
12+
deleteRealmIfMigrationNeeded: true,
13+
};
14+
15+
const {RealmProvider, useRealm, useQuery} = createRealmContext(realmConfig);
16+
17+
let assertionRealm: Realm;
18+
19+
describe('Mixed Tests', () => {
20+
beforeEach(async () => {
21+
// we will use this Realm for assertions to access Realm Objects outside of a Functional Component (like required by @realm/react)
22+
assertionRealm = await Realm.open(realmConfig);
23+
24+
// delete every object in the realmConfig in the Realm to make test idempotent
25+
assertionRealm.write(() => {
26+
assertionRealm.delete(assertionRealm.objects(Cat));
27+
28+
new Cat(assertionRealm, {
29+
name: 'Clover',
30+
birthDate: new Date('January 21, 2016'),
31+
});
32+
});
33+
});
34+
afterAll(() => {
35+
if (!assertionRealm.isClosed) {
36+
assertionRealm.close();
37+
}
38+
});
39+
it('should create an object with a mixed value', async () => {
40+
// :snippet-start: create-mixed-object
41+
// :replace-start: {
42+
// "terms": {
43+
// " testID='catItem'": ""
44+
// }
45+
// }
46+
const CreateCatsInput = () => {
47+
const realm = useRealm();
48+
49+
useEffect(() => {
50+
// Add data to the Realm when the component mounts
51+
realm.write(() => {
52+
// create a Cat with a birthDate value of type string
53+
new Cat(realm, {
54+
name: 'Euler',
55+
birthDate: 'December 25th, 2017',
56+
});
57+
// create a Cat with a birthDate value of type date
58+
new Cat(realm, {
59+
name: 'Blaise',
60+
birthDate: new Date('August 17, 2020'),
61+
});
62+
63+
// create a Cat with a birthDate value of type int
64+
new Cat(realm, {name: 'Euclid', birthDate: 10152021});
65+
66+
// create a Cat with a birthDate value of type null
67+
new Cat(realm, {name: 'Pythagoras', birthDate: null});
68+
});
69+
}, []);
70+
71+
// retrieve all cats
72+
const cats = useQuery(Cat);
73+
74+
return (
75+
<>
76+
{cats.map(cat => (
77+
<View testID='catItem'>
78+
<Text>{cat.name}</Text>
79+
<Text>{String(cat.birthDate)}</Text>
80+
</View>
81+
))}
82+
</>
83+
);
84+
};
85+
// :replace-end:
86+
// :snippet-end:
87+
88+
const App = () => (
89+
<RealmProvider>
90+
<CreateCatsInput />
91+
</RealmProvider>
92+
);
93+
94+
const {getAllByTestId} = render(<App />);
95+
96+
const catItems = await waitFor(() => getAllByTestId('catItem'), {
97+
timeout: 5000,
98+
});
99+
100+
// Test that 5 Cat Items have been added to the UI,
101+
// and 5 matching Cat objects have been created in the assertionRealm
102+
// (since there was already 1 cat object 'clover' created in the beforeEach)
103+
// + the 4 new Cats
104+
setTimeout(() => {
105+
expect(catItems.length).toBe(5);
106+
const cats = assertionRealm.objects(Cat);
107+
expect(cats.length).toBe(5);
108+
}, 5500);
109+
});
110+
it('should query for objects with a mixed value', async () => {
111+
// :snippet-start: query-mixed-object
112+
// :replace-start: {
113+
// "terms": {
114+
// " testID='catBirthDate'": ""
115+
// }
116+
// }
117+
const CatInfoCard = ({catName}: {catName: string}) => {
118+
// To query for the cat's birthDate, filter for their name to retrieve the realm object.
119+
// Use dot notation to access the birthDate property.
120+
const cat = useQuery(Cat).filtered(`name = '${catName}'`)[0];
121+
const catBirthDate = cat.birthDate;
122+
123+
if (cat) {
124+
return (
125+
<>
126+
<Text>{catName}</Text>
127+
<Text testID='catBirthDate'>{String(catBirthDate)}</Text>
128+
</>
129+
);
130+
} else {
131+
return <Text>Cat not found</Text>;
132+
}
133+
};
134+
// :replace-end:
135+
// :snippet-end:
136+
137+
const App = () => (
138+
<RealmProvider>
139+
<CatInfoCard catName='Clover' />
140+
</RealmProvider>
141+
);
142+
const {getByTestId} = render(<App />);
143+
const catBirthDate = await waitFor(() => getByTestId('catBirthDate'));
144+
// Expect catBirthDate in the UI to be the same value we set in the beforeEach (which is clover's birthday 'January 21, 2016')
145+
expect(new Date(catBirthDate.props.children)).toStrictEqual(
146+
new Date('January 21, 2016'),
147+
);
148+
});
149+
});

examples/react-native/testSetup.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ global.console = {
77
error: jest.fn(),
88
warn: jest.fn(),
99
};
10+
11+
jest.setTimeout(30000);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Cat extends Realm.Object {
2+
static schema = {
3+
name: 'Cat',
4+
properties: {
5+
name: 'string',
6+
birthDate: 'mixed',
7+
},
8+
};
9+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const CreateCatsInput = () => {
2+
const realm = useRealm();
3+
4+
useEffect(() => {
5+
// Add data to the Realm when the component mounts
6+
realm.write(() => {
7+
// create a Cat with a birthDate value of type string
8+
new Cat(realm, {
9+
name: 'Euler',
10+
birthDate: 'December 25th, 2017',
11+
});
12+
// create a Cat with a birthDate value of type date
13+
new Cat(realm, {
14+
name: 'Blaise',
15+
birthDate: new Date('August 17, 2020'),
16+
});
17+
18+
// create a Cat with a birthDate value of type int
19+
new Cat(realm, {name: 'Euclid', birthDate: 10152021});
20+
21+
// create a Cat with a birthDate value of type null
22+
new Cat(realm, {name: 'Pythagoras', birthDate: null});
23+
});
24+
}, []);
25+
26+
// retrieve all cats
27+
const cats = useQuery(Cat);
28+
29+
return (
30+
<>
31+
{cats.map(cat => (
32+
<View>
33+
<Text>{cat.name}</Text>
34+
<Text>{String(cat.birthDate)}</Text>
35+
</View>
36+
))}
37+
</>
38+
);
39+
};

0 commit comments

Comments
 (0)