Skip to content
This repository was archived by the owner on Feb 18, 2021. It is now read-only.

Commit d9bd996

Browse files
author
stefanwullems
committed
restructured
1 parent 2ebe8f9 commit d9bd996

18 files changed

+177
-266
lines changed

src/CacheObserver/CacheManager.test.ts src/CacheObservable/CacheObservable.test.ts

+6-36
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,10 @@
1-
import Store from '@orbit/store'
2-
import { Dict } from '@orbit/utils'
3-
import { QueryBuilder, Schema, ModelDefinition } from '@orbit/data'
4-
5-
import { CacheManager } from './CacheManager'
6-
7-
const modelDefenition: Dict<ModelDefinition> = {
8-
account: {
9-
attributes: {
10-
test: { type: 'string' }
11-
},
12-
relationships: {
13-
profile: { type: 'hasOne', inverse: 'account', model: 'profile' },
14-
services: { type: 'hasMany', inverse: 'subscribers', model: 'service' }
15-
}
16-
},
17-
profile: {
18-
attributes: {
19-
test: { type: 'string' }
20-
},
21-
relationships: {
22-
account: { type: 'hasOne', inverse: 'profile', model: 'account' }
23-
}
24-
},
25-
service: {
26-
attributes: {
27-
test: { type: 'string' }
28-
},
29-
relationships: {
30-
subscribers: { type: 'hasMany', inverse: 'services', model: 'account' }
31-
}
32-
}
33-
}
1+
import { QueryBuilder } from '@orbit/data'
342

35-
const store = new Store({
36-
schema: new Schema({ models: modelDefenition })
37-
})
3+
import { CacheManager } from './CacheObservable'
4+
5+
import { TestStore } from '../utils/testing/TestStore'
6+
7+
const store = new TestStore()
388

399
let manager: CacheManager
4010
beforeEach(() => {

src/CacheObserver/CacheManager.ts src/CacheObservable/CacheObservable.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import Store from '@orbit/store'
22
import { Record, Transform, RecordOperation } from '@orbit/data'
33

4-
import { Observable } from '../Observer'
4+
import { Observable } from '../Observable'
55

66
import { getTermsOrExpression } from '../utils/parseQuery'
7-
import { getUpdatedRecords, shouldUpdate } from '../helpers'
7+
import { getUpdatedRecords, shouldUpdate } from '../utils/changeManagement'
88
import { Data, Listener, Query, Queries, Term, Expression, RecordData } from '../utils/types'
99

1010
export class CacheManager extends Observable<Data> {

src/CacheObservable/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './CacheObservable'

src/CacheObserver/index.ts

-1
This file was deleted.

src/FetchObserver/FetchManager.test.ts src/FetchObservable/FetchManager.test.ts

+3-34
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,12 @@
1-
import Store from '@orbit/store'
2-
import { Dict } from '@orbit/utils'
3-
import { QueryBuilder, Schema, ModelDefinition } from '@orbit/data'
1+
import { QueryBuilder } from '@orbit/data'
42

53
import { Subscription } from '../Subscription'
64
import { FetchManager } from './FetchManager'
75

6+
import { TestStore } from '../utils/testing/TestStore'
87
import { Expression, Term } from '../utils/types'
98

10-
const modelDefenition: Dict<ModelDefinition> = {
11-
account: {
12-
attributes: {
13-
test: { type: 'string' }
14-
},
15-
relationships: {
16-
profile: { type: 'hasOne', inverse: 'account', model: 'profile' },
17-
services: { type: 'hasMany', inverse: 'subscribers', model: 'service' }
18-
}
19-
},
20-
profile: {
21-
attributes: {
22-
test: { type: 'string' }
23-
},
24-
relationships: {
25-
account: { type: 'hasOne', inverse: 'profile', model: 'account' }
26-
}
27-
},
28-
service: {
29-
attributes: {
30-
test: { type: 'string' }
31-
},
32-
relationships: {
33-
subscribers: { type: 'hasMany', inverse: 'services', model: 'account' }
34-
}
35-
}
36-
}
37-
38-
const store = new Store({
39-
schema: new Schema({ models: modelDefenition })
40-
})
9+
const store = new TestStore()
4110

4211
let manager: FetchManager
4312
beforeEach(() => {

src/FetchObserver/FetchManager.ts src/FetchObservable/FetchManager.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Store from '@orbit/store'
22
import { Record } from '@orbit/data'
33

4-
import { Observable } from '../Observer'
4+
import { Observable } from '../Observable'
55

66
import {
77
Query,
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/QueryObserver/QueryManager.test.ts src/QueryObservable/QueryManager.test.ts

+3-34
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,11 @@
1-
import Store from '@orbit/store'
2-
import { Dict } from '@orbit/utils'
3-
import { QueryBuilder, Schema, ModelDefinition } from '@orbit/data'
1+
import { QueryBuilder } from '@orbit/data'
42

53
import { QueryManager } from './QueryManager'
64

75
import { Expression } from '../utils/types'
6+
import { TestStore } from '../utils/testing/TestStore'
87

9-
const modelDefinition: Dict<ModelDefinition> = {
10-
account: {
11-
attributes: {
12-
test: { type: 'string' }
13-
},
14-
relationships: {
15-
profile: { type: 'hasOne', inverse: 'account', model: 'profile' },
16-
services: { type: 'hasMany', inverse: 'subscribers', model: 'service' }
17-
}
18-
},
19-
profile: {
20-
attributes: {
21-
test: { type: 'string' }
22-
},
23-
relationships: {
24-
account: { type: 'hasOne', inverse: 'profile', model: 'account' }
25-
}
26-
},
27-
service: {
28-
attributes: {
29-
test: { type: 'string' }
30-
},
31-
relationships: {
32-
subscribers: { type: 'hasMany', inverse: 'services', model: 'account' }
33-
}
34-
}
35-
}
36-
37-
const store = new Store({
38-
schema: new Schema({ models: modelDefinition })
39-
})
8+
const store = new TestStore()
409

4110
let manager: QueryManager
4211
beforeEach(() => {

src/QueryObserver/QueryManager.ts src/QueryObservable/QueryManager.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Store from '@orbit/store'
22

3-
import { CacheManager } from '../CacheObserver'
4-
import { FetchManager } from '../FetchObserver'
3+
import { CacheManager } from '../CacheObservable'
4+
import { FetchManager } from '../FetchObservable'
55

66
import { Queries, Query, Options, Data, Listener } from '../utils/types'
77
import { getTermsOrExpression, validateOptions, hashQueryIdentifier } from '../utils/parseQuery'
File renamed without changes.

src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
export * from './QueryObserver/QueryManager'
1+
export * from './QueryObservable/QueryManager'
22
export * from './utils/types'

src/utils/changeManagement.test.ts

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import { RecordOperation } from '@orbit/data'
2+
3+
import { Expression } from './types'
4+
import { hasChanged, getUpdatedRecords, identityIsEqual } from './changeManagement'
5+
6+
7+
describe('getUpdatedRecords(...)', () => {
8+
test('It should put expression.record into the records array', () => {
9+
const account = { type: 'account', id: '1' }
10+
11+
const operation: RecordOperation = { op: 'addRecord', record: account }
12+
13+
const { records } = getUpdatedRecords([operation])
14+
15+
expect(records).toMatchObject([account])
16+
})
17+
18+
test('It should put expression.relatedRecord into the relatedRecords array', () => {
19+
const account = { type: 'account', id: '1' }
20+
const profile = { type: 'profile', id: '1' }
21+
22+
const operation: RecordOperation = {
23+
op: 'replaceRelatedRecord',
24+
record: account,
25+
relationship: 'profile',
26+
relatedRecord: profile
27+
}
28+
29+
const { relatedRecords } = getUpdatedRecords([operation])
30+
31+
expect(relatedRecords).toMatchObject([profile])
32+
})
33+
34+
test('It should put expression.relatedRecords into the relatedRecords array', () => {
35+
const account = { type: 'account', id: '1' }
36+
const service1 = { type: 'service', id: '1' }
37+
const service2 = { type: 'service', id: '2' }
38+
39+
const operation: RecordOperation = {
40+
op: 'replaceRelatedRecords',
41+
record: account,
42+
relationship: 'services',
43+
relatedRecords: [service1, service2]
44+
}
45+
46+
const { relatedRecords } = getUpdatedRecords([operation])
47+
48+
expect(relatedRecords).toMatchObject([service1, service2])
49+
})
50+
})
51+
52+
describe('shouldUpdate(...)', () => {
53+
test('findRecords: It should return true when a record of the listened to type present in records', () => {
54+
const expression: Expression = { op: 'findRecords', type: 'account' }
55+
const changedRecord = { type: 'account', id: '1' }
56+
57+
const shouldUpdateVal = hasChanged(expression, [changedRecord], [])
58+
59+
expect(shouldUpdateVal).toBe(true)
60+
})
61+
62+
test('findRecords: It should return true when a record of the listened to type present in relatedRecords', () => {
63+
const expression: Expression = { op: 'findRecords', type: 'account' }
64+
const changedRelatedRecord = { type: 'account', id: '1' }
65+
66+
const shouldUpdateVal = hasChanged(expression, [], [changedRelatedRecord])
67+
68+
expect(shouldUpdateVal).toBe(true)
69+
})
70+
71+
test('It should return true with any other operation if a record matches an expression', () => {
72+
const expression: Expression = { op: 'findRecord', record: { type: 'account', id: '1' } }
73+
const changedRecord = { type: 'account', id: '1' }
74+
75+
const shouldUpdateVal = hasChanged(expression, [changedRecord], [])
76+
77+
expect(shouldUpdateVal).toBe(true)
78+
})
79+
80+
test('It should return true with any other operation if the type of a relatedRecord matches the expression (hasOne)', () => {
81+
const expression: Expression = { op: 'findRecord', record: { type: 'account', id: '1' } }
82+
const changedRelatedRecord = { type: 'account', id: '1' }
83+
84+
const shouldUpdateVal = hasChanged(expression, [], [changedRelatedRecord])
85+
86+
expect(shouldUpdateVal).toBe(true)
87+
})
88+
89+
test('It should return true with any other operation if the type of a relatedRecord matches the expression (hasMany)', () => {
90+
const expression: Expression = { op: 'findRecord', record: { type: 'account', id: '1' } }
91+
const changedRelatedRecord = { type: 'account', id: '1' }
92+
93+
const shouldUpdateVal = hasChanged(expression, [], [changedRelatedRecord])
94+
95+
expect(shouldUpdateVal).toBe(true)
96+
})
97+
})
98+
99+
describe('identityIsEqual(...)', () => {
100+
test('should return true when identity is equal', () => {
101+
const accountId = { type: 'account', id: '1' }
102+
103+
const result = identityIsEqual(accountId, accountId)
104+
105+
expect(result).toBe(true)
106+
})
107+
108+
test('should return false when identity is not equal', () => {
109+
const accountId1 = { type: 'account', id: '1' }
110+
const accountId2 = { type: 'account', id: '2' }
111+
112+
113+
const result = identityIsEqual(accountId1, accountId2)
114+
115+
expect(result).toBe(false)
116+
})
117+
})

src/helpers.ts src/utils/changeManagement.ts

+2-40
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,5 @@
1-
import { RecordOperation, RecordIdentity, QueryBuilder } from '@orbit/data'
2-
import { Expression, Term, Options, Query, Queries } from './utils/types'
3-
4-
export const getTermsOrExpression = (queryOrQueries: Query | Queries) => {
5-
return typeof queryOrQueries === 'function'
6-
? getExpression(queryOrQueries)
7-
: getTerms(queryOrQueries)
8-
}
9-
10-
export const getTerms = (queries: Queries): Term[] => {
11-
const queryBuilder = new QueryBuilder()
12-
13-
return Object.keys(queries).sort().map((key) =>
14-
({ key, expression: queries[key](queryBuilder).expression as Expression })
15-
)
16-
}
17-
18-
export const getExpression = (query: Query): Expression => {
19-
const queryBuilder = new QueryBuilder()
20-
21-
return query(queryBuilder).expression as Expression
22-
}
23-
24-
export const hashQueryIdentifier = (termsOrExpression: Term[] | Expression, options?: Options) => {
25-
return options
26-
? JSON.stringify({ termsOrExpression, options })
27-
: JSON.stringify(termsOrExpression)
28-
}
29-
30-
export const validateOptions = (termsOrExpression: Term[] | Expression, options?: Options) => {
31-
if (!options) return
32-
if (Array.isArray(termsOrExpression) && !Array.isArray(options)) {
33-
throw new Error(
34-
'Options are invalid. When making multiple queries' +
35-
'the options must be an array of objects with a "queryKey" property that refers to the query to which the options apply'
36-
)
37-
} else if (!Array.isArray(termsOrExpression) && Array.isArray(options)) {
38-
throw new Error('Options are invalid.')
39-
}
40-
}
1+
import { RecordOperation, RecordIdentity } from '@orbit/data'
2+
import { Expression, Term, Options } from './types'
413

424
interface Operation {
435
record: RecordIdentity

0 commit comments

Comments
 (0)