Skip to content

Commit 11b74bd

Browse files
author
Maier, Martin
committed
* improved test classes
* renamed getProperty --> property * renamed replaceProperty --> replaceValueOf * renamed andDo --> withCloneAndDo
1 parent 0f07699 commit 11b74bd

File tree

5 files changed

+114
-126
lines changed

5 files changed

+114
-126
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "typescript-immutable-helper",
3-
"version": "0.5.0",
3+
"version": "0.6.0",
44
"description": "Helpers for handling immutable objects with typescript",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

src/replicator.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as _ from 'lodash'
22
import {deepFreeze, isDeepFrozen} from './deepFreeze'
33

44
/**
5-
* Class that helps to replicate a new object by encapsulating a deep copy of the source object
5+
* Class that helps to replaceValueOf a new object by encapsulating a deep copy of the source object
66
* If input object is frozen by (@link Object.freeze()} or {@link deepFreeze} then the replica will be produced frozen
77
* freeze in --> deep freeze out
88
* Warns if source object is just frozen, not deep frozen
@@ -29,30 +29,30 @@ export class ReplicationBuilder<T> {
2929

3030
/**
3131
* @deprecated since 0.4.1
32-
* use getProperty instead
32+
* use property instead
3333
*/
3434
public getChild<K extends keyof T>(childNode: K): ReplicaChildOperator<T, T[K]> {
35-
return this.getProperty(childNode);
35+
return this.property(childNode);
3636
}
3737

3838
/** switch to child node
3939
* @param {K} childNode of the root node
4040
* @returns {ReplicaChildOperator<T, T[K]>} operator of child node
4141
**/
42-
public getProperty<K extends keyof T>(childNode: K): ReplicaChildOperator<T, T[K]> {
42+
public property<K extends keyof T>(childNode: K): ReplicaChildOperator<T, T[K]> {
4343
let node = this.replica[childNode];
4444
return new ReplicaChildOperator((() => this.build()), this.replica, node, childNode)
4545
}
4646

4747
/**
4848
* @deprecated since 0.4.1
49-
* use replaceProperty instead
49+
* use replaceValueOf instead
5050
*/
5151
public modify<K extends keyof T>(childNode: K): PropertyModifier<ReplicationBuilder<T>, T[K]> {
52-
return this.replaceProperty(childNode);
52+
return this.replaceValueOf(childNode);
5353
}
5454

55-
public replaceProperty<K extends keyof T>(childNode: K): PropertyModifier<ReplicationBuilder<T>, T[K]> {
55+
public replaceValueOf<K extends keyof T>(childNode: K): PropertyModifier<ReplicationBuilder<T>, T[K]> {
5656
return new PropertyModifier<ReplicationBuilder<T>, T[K]>(this, childNode, this.replica)
5757
}
5858

@@ -103,31 +103,31 @@ export class ReplicaChildOperator<RT, T> {
103103

104104
/**
105105
* @deprecated since 0.4.1
106-
* use getProperty instead
106+
* use property instead
107107
*/
108108
getChild<K extends keyof T>(childNode: K): ReplicaChildOperator<RT, T[K]> {
109-
return this.getProperty(childNode);
109+
return this.property(childNode);
110110
}
111111

112112

113113
/** switch to child node
114114
* @param {K} childNode of this node
115115
* @returns {ReplicaChildOperator<RT, N[K]>} traversable child node
116116
**/
117-
getProperty<K extends keyof T>(childNode: K): ReplicaChildOperator<RT, T[K]> {
117+
property<K extends keyof T>(childNode: K): ReplicaChildOperator<RT, T[K]> {
118118
let branch = this.node[childNode];
119119
return new ReplicaChildOperator(this.buildFunction, this.replica, branch, this.relativePath + '.' + childNode)
120120
}
121121

122122
/**
123123
* @deprecated since 0.4.1
124-
* use replaceProperty instead
124+
* use replaceValueOf instead
125125
*/
126126
modify<K extends keyof T>(childNode: K): PropertyModifier<ReplicaChildOperator<RT, T>, T[K]> {
127-
return this.replaceProperty(childNode);
127+
return this.replaceValueOf(childNode);
128128
}
129129

130-
replaceProperty<K extends keyof T>(childNode: K): PropertyModifier<ReplicaChildOperator<RT, T>, T[K]> {
130+
replaceValueOf<K extends keyof T>(childNode: K): PropertyModifier<ReplicaChildOperator<RT, T>, T[K]> {
131131
return new PropertyModifier<ReplicaChildOperator<RT, T>, T[K]>(this, this.relativePath + '.' + childNode, this.replica)
132132
}
133133

@@ -201,7 +201,7 @@ export class PropertyModifier<PT, VT> {
201201
* @param {(VT) => void} executeOnCloneFunction function that is executed
202202
* @returns {PT}
203203
*/
204-
andDo(executeOnCloneFunction: (VT) => void): PT {
204+
withCloneAndDo(executeOnCloneFunction: (VT) => void): PT {
205205
let currentvalue = _.get(this.replica, this.relativePathToRoot);
206206
executeOnCloneFunction(currentvalue);
207207
return this.parent;

src/tests/replicator.deprecated.spec.ts

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,76 @@
11
import {expect} from 'chai'
2-
import {ClassorientedTeststate, SimpleTeststate, SubTypeA} from './testobjects'
2+
import {Concert, Rockband, SimpleBand} from './testobjects'
33
import {ReplicationBuilder} from '../replicator'
44
import {deepFreeze, isDeepFrozen} from '../deepFreeze'
55

66
describe('Deprecated API of ReplicationBuilder', () => {
77

88
it('Inputstate must not be modified, output must be modified', () => {
9-
let rootState = new ClassorientedTeststate();
10-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('subTypeA').getChild('subTypeB').modify('subTypeBAttribute').to('Test').build();
9+
let rootState = new Concert();
10+
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('band').getChild('homeland').modify('name').to('Test').build();
1111

12-
expect(rootState.subTypeA.subTypeB.subTypeBAttribute).to.null;
13-
expect(manipulatedRoot.subTypeA.subTypeB.subTypeBAttribute).to.equal('Test')
12+
expect(rootState.band.homeland.name).to.null;
13+
expect(manipulatedRoot.band.homeland.name).to.equal('Test')
1414
});
1515

1616
it('Inputstate must not be modified, output must be modified', () => {
17-
let rootState = new ClassorientedTeststate();
18-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('subTypeA').getChild('subTypeB').modify('subTypeBAttribute').to('Test').build();
17+
let rootState = new Concert();
18+
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('band').getChild('homeland').modify('name').to('Test').build();
1919

20-
expect(rootState.subTypeA.subTypeB.subTypeBAttribute).to.null;
21-
expect(manipulatedRoot.subTypeA.subTypeB.subTypeBAttribute).to.equal('Test')
20+
expect(rootState.band.homeland.name).to.null;
21+
expect(manipulatedRoot.band.homeland.name).to.equal('Test')
2222
});
2323

2424
it('Inputstate must not be modified, output node must be deleted', () => {
25-
let rootState = new ClassorientedTeststate();
26-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).delete('subTypeA').build();
25+
let rootState = new Concert();
26+
let manipulatedRoot = ReplicationBuilder.forObject(rootState).delete('band').build();
2727

28-
expect(rootState.subTypeA).to.exist;
29-
expect(manipulatedRoot.subTypeA).to.not.exist
28+
expect(rootState.band).to.exist;
29+
expect(manipulatedRoot.band).to.not.exist
3030
});
3131

3232
it('Inputstate must not be modified, output child node must be deleted', () => {
33-
let rootState = new ClassorientedTeststate();
34-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('subTypeA').delete('subTypeB').build();
33+
let rootState = new Concert();
34+
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('band').delete('homeland').build();
3535

36-
expect(rootState.subTypeA.subTypeB).to.exist;
37-
expect(manipulatedRoot.subTypeA.subTypeB).to.not.exist
36+
expect(rootState.band.homeland).to.exist;
37+
expect(manipulatedRoot.band.homeland).to.not.exist
3838
});
3939

4040
it('to untyped structure: Inputstate must not be modified, output must be modified', () => {
41-
let rootState = SimpleTeststate;
42-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('subTypeB').modify('subtypeBAttribute').to('Test').build();
41+
let rootState = SimpleBand;
42+
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('genre').modify('name').to('Test').build();
4343

44-
expect(rootState.subTypeB.subtypeBAttribute).to.equal('initial');
45-
expect(manipulatedRoot.subTypeB.subtypeBAttribute).to.equal('Test')
44+
expect(rootState.genre.name).to.equal('initial');
45+
expect(manipulatedRoot.genre.name).to.equal('Test')
4646
});
4747

4848
it('if input state is deep frozen --> output state must be deep frozen', () => {
49-
let rootState = new ClassorientedTeststate();
49+
let rootState = new Concert();
5050
deepFreeze(rootState);
51-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('subTypeA').getChild('subTypeB').modify('subTypeBAttribute').to('Test').build();
51+
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('band').getChild('homeland').modify('name').to('Test').build();
5252

53-
expect(rootState.subTypeA.subTypeB.subTypeBAttribute).to.null;
54-
expect(manipulatedRoot.subTypeA.subTypeB.subTypeBAttribute).to.equal('Test');
53+
expect(rootState.band.homeland.name).to.null;
54+
expect(manipulatedRoot.band.homeland.name).to.equal('Test');
5555
expect(isDeepFrozen(manipulatedRoot)).true
5656
});
5757

5858
it('redux like root state --> if input state is deep frozen --> output state must be deep frozen', () => {
5959
let rootState = {
60-
subTypeA: new SubTypeA()
60+
band: new Rockband()
6161
};
6262
deepFreeze(rootState);
63-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('subTypeA').getChild('subTypeB').modify('subTypeBArray')
64-
.by((oldArray) => [...oldArray, 'Test']).build();
63+
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('band').modify('members')
64+
.by((oldMembers) => [...oldMembers, 'Test']).build();
6565

66-
expect(rootState.subTypeA.subTypeB.subTypeBArray.length).to.equal(0);
67-
expect(manipulatedRoot.subTypeA.subTypeB.subTypeBArray[0]).to.equal('Test');
66+
expect(rootState.band.members.length).to.equal(0);
67+
expect(manipulatedRoot.band.members[0]).to.equal('Test');
6868
expect(isDeepFrozen(manipulatedRoot)).true
6969
});
7070

7171
it('if input state is NOT frozen --> output state must NOT be frozen', () => {
72-
let rootState = new ClassorientedTeststate();
73-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('subTypeA').getChild('subTypeB').modify('subTypeBAttribute').to('Test').build();
72+
let rootState = new Concert();
73+
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getChild('band').getChild('homeland').modify('name').to('Test').build();
7474

7575
expect(Object.isFrozen(manipulatedRoot)).false
7676
});

src/tests/replicator.spec.ts

Lines changed: 41 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,85 @@
11
import {expect} from 'chai'
2-
import {ClassorientedTeststate, ObjectArray, SimpleTeststate, SubTypeA} from './testobjects'
2+
import {Concert, ObjectArray, Rockband, SimpleBand} from './testobjects'
33
import {ReplicationBuilder} from '../replicator'
44
import {deepFreeze, isDeepFrozen} from '../deepFreeze'
55

66
describe('ReplicationBuilder', () => {
77

88
it('should clone a property and execute function on the clone ', function () {
9-
let rootState = new ClassorientedTeststate();
10-
let someNewValue = 'someNewValue';
11-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).replaceProperty('subTypeA').andDo((clonedSubTypeA) => {
12-
clonedSubTypeA.setSubTypeAAttribute(someNewValue)
9+
let concert = new Concert();
10+
let newBandName = 'someNewName';
11+
let manipulatedRoot = ReplicationBuilder.forObject(concert).replaceValueOf('band').withCloneAndDo((band) => {
12+
band.changeNameTo(newBandName)
1313
}).build();
14-
expect(manipulatedRoot.subTypeA.subTypeAAttribute).to.equal(someNewValue);
14+
expect(manipulatedRoot.band.name).to.equal(newBandName);
1515
});
1616

1717
it('Inputstate must not be modified, output must be modified', () => {
18-
let rootState = new ClassorientedTeststate();
19-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getProperty('subTypeA').getProperty('subTypeB').replaceProperty('subTypeBAttribute').with('Test').build();
18+
let concert = new Concert();
19+
let manipulatedRoot = ReplicationBuilder.forObject(concert).property('band').property('homeland').replaceValueOf('name').with('Spain').build();
2020

21-
expect(rootState.subTypeA.subTypeB.subTypeBAttribute).to.null;
22-
expect(manipulatedRoot.subTypeA.subTypeB.subTypeBAttribute).to.equal('Test')
21+
expect(concert.band.homeland.name).to.null;
22+
expect(manipulatedRoot.band.homeland.name).to.equal('Spain')
2323
});
2424

2525
it('Inputstate must not be modified, output must be modified', () => {
26-
let rootState = new ClassorientedTeststate();
27-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getProperty('subTypeA').getProperty('subTypeB').replaceProperty('subTypeBAttribute').with('Test').build();
26+
let rootState = new Concert();
27+
let manipulatedRoot = ReplicationBuilder.forObject(rootState).property('band').property('homeland').replaceValueOf('name').with('Russia').build();
2828

29-
expect(rootState.subTypeA.subTypeB.subTypeBAttribute).to.null;
30-
expect(manipulatedRoot.subTypeA.subTypeB.subTypeBAttribute).to.equal('Test')
29+
expect(rootState.band.homeland.name).to.null;
30+
expect(manipulatedRoot.band.homeland.name).to.equal('Russia')
3131
});
3232

3333
it('Inputstate must not be modified, output node must be deleted', () => {
34-
let rootState = new ClassorientedTeststate();
35-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).removeProperty('subTypeA').build();
34+
let rootState = new Concert();
35+
let manipulatedRoot = ReplicationBuilder.forObject(rootState).removeProperty('band').build();
3636

37-
expect(rootState.subTypeA).to.exist;
38-
expect(manipulatedRoot.subTypeA).to.not.exist
37+
expect(rootState.band).to.exist;
38+
expect(manipulatedRoot.band).to.not.exist
3939
});
4040

4141
it('Inputstate must not be modified, output child node must be deleted', () => {
42-
let rootState = new ClassorientedTeststate();
43-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getProperty('subTypeA').removeProperty('subTypeB').build();
42+
let rootState = new Concert();
43+
let manipulatedRoot = ReplicationBuilder.forObject(rootState).property('band').removeProperty('homeland').build();
4444

45-
expect(rootState.subTypeA.subTypeB).to.exist;
46-
expect(manipulatedRoot.subTypeA.subTypeB).to.not.exist
45+
expect(rootState.band.homeland).to.exist;
46+
expect(manipulatedRoot.band.homeland).to.not.exist
4747
});
4848

4949
it('with untyped structure: Inputstate must not be modified, output must be modified', () => {
50-
let rootState = SimpleTeststate;
51-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getProperty('subTypeB').replaceProperty('subtypeBAttribute').with('Test').build();
50+
let simpleBand = SimpleBand;
51+
let manipulatedRoot = ReplicationBuilder.forObject(simpleBand).property('genre').replaceValueOf('name').with('Test').build();
5252

53-
expect(rootState.subTypeB.subtypeBAttribute).to.equal('initial');
54-
expect(manipulatedRoot.subTypeB.subtypeBAttribute).to.equal('Test')
53+
expect(simpleBand.genre.name).to.equal('initial');
54+
expect(manipulatedRoot.genre.name).to.equal('Test')
5555
});
5656

5757
it('if input state is deep frozen --> output state must be deep frozen', () => {
58-
let rootState = new ClassorientedTeststate();
59-
deepFreeze(rootState);
60-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getProperty('subTypeA').getProperty('subTypeB').replaceProperty('subTypeBAttribute').with('Test').build();
58+
let concert = new Concert();
59+
deepFreeze(concert);
60+
let manipulatedRoot = ReplicationBuilder.forObject(concert).property('band').property('homeland').replaceValueOf('name').with('Test').build();
6161

62-
expect(rootState.subTypeA.subTypeB.subTypeBAttribute).to.null;
63-
expect(manipulatedRoot.subTypeA.subTypeB.subTypeBAttribute).to.equal('Test');
62+
expect(concert.band.homeland.name).to.null;
63+
expect(manipulatedRoot.band.homeland.name).to.equal('Test');
6464
expect(isDeepFrozen(manipulatedRoot)).true
6565
});
6666

6767
it('redux like root state --> if input state is deep frozen --> output state must be deep frozen', () => {
68-
let rootState = {
69-
subTypeA: new SubTypeA()
68+
let festival = {
69+
band: new Rockband()
7070
};
71-
deepFreeze(rootState);
72-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getProperty('subTypeA').getProperty('subTypeB').replaceProperty('subTypeBArray')
73-
.by((oldArray) => [...oldArray, 'Test']).build();
71+
deepFreeze(festival);
72+
let newFestival = ReplicationBuilder.forObject(festival).property('band').replaceValueOf('members')
73+
.by((oldMembers) => [...oldMembers, 'NewRocker']).build();
7474

75-
expect(rootState.subTypeA.subTypeB.subTypeBArray.length).to.equal(0);
76-
expect(manipulatedRoot.subTypeA.subTypeB.subTypeBArray[0]).to.equal('Test');
77-
expect(isDeepFrozen(manipulatedRoot)).true
75+
expect(festival.band.members.length).to.equal(0);
76+
expect(newFestival.band.members[0]).to.equal('NewRocker');
77+
expect(isDeepFrozen(newFestival)).true
7878
});
7979

8080
it('if input state is NOT frozen --> output state must NOT be frozen', () => {
81-
let rootState = new ClassorientedTeststate();
82-
let manipulatedRoot = ReplicationBuilder.forObject(rootState).getProperty('subTypeA').getProperty('subTypeB').replaceProperty('subTypeBAttribute').with('Test').build();
83-
81+
let concert = new Concert();
82+
let manipulatedRoot = ReplicationBuilder.forObject(concert).property('band').property('homeland').replaceValueOf('name').with('USA').build();
8483
expect(Object.isFrozen(manipulatedRoot)).false
8584
});
8685

0 commit comments

Comments
 (0)