Skip to content

Commit 12eb413

Browse files
author
Matheus Marsiglio
committed
Fixes in NucleoList type
- isolate indexSearch function to its own file - Create more tests to NucleoLists exploring exploits possibilities - Improve indexSearch function to work properly with NucleoList types - Fixes in NucleoList fields validations and serializations
1 parent 18d18ba commit 12eb413

File tree

4 files changed

+175
-31
lines changed

4 files changed

+175
-31
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
{
22
"name": "nucleojs",
3-
"version": "0.2.7",
3+
"version": "0.3.0",
44
"main": "dist/index.js",
55
"author": "Matheus Marsiglio <[email protected]>",
6+
"repository": "git://github.com/mtmr0x/nucleo",
67
"license": "MIT",
78
"repository": "git://github.com/mtmr0x/nucleo",
89
"private": false,

src/indexSearch.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const saveType = (data:any):'rec'|'save' => {
2+
if (typeof data === 'object' && !data.length) {
3+
return 'rec';
4+
}
5+
6+
return 'save';
7+
};
8+
9+
const indexSearch = (storeData: any, data: any, newData:any = {}) => {
10+
const dataKeys = Object.keys(data);
11+
const storeDataKeys = Object.keys(storeData);
12+
13+
for (let i = 0; storeDataKeys.length > i; i++) {
14+
const dataTypeReflection = () => ({
15+
'rec': () => {
16+
const bufferData = data[storeDataKeys[i]] || storeData[storeDataKeys[i]];
17+
newData[storeDataKeys[i]] = {}
18+
return indexSearch(storeData[storeDataKeys[i]], bufferData, newData[storeDataKeys[i]]);
19+
},
20+
'save': () => {
21+
if (data[storeDataKeys[i]]) {
22+
return newData[storeDataKeys[i]] = data[storeDataKeys[i]];
23+
}
24+
return newData[storeDataKeys[i]] = storeData[storeDataKeys[i]];
25+
}
26+
});
27+
28+
dataTypeReflection()[saveType(storeData[storeDataKeys[i]])]();
29+
}
30+
31+
return newData;
32+
}
33+
34+
export default indexSearch;
35+

src/lawyer.ts

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,14 @@ import NucleoObject from './nucleoTypes/NucleoObject';
22
import NucleoList from './nucleoTypes/NucleoList';
33

44
import { NucleoObjectType } from './_types/NucleoObjectType';
5+
import indexSearch from './indexSearch';
56

67
const executeListeners = (contractName: string, listeners: Array<Function>) => {
78
for (let i = 0; i < listeners.length; i++) {
89
listeners[i]({ contractName });
910
}
1011
};
1112

12-
const indexSearch = (contractData: any, data: any, newData:any = {}) => {
13-
const dataKeys = Object.keys(data);
14-
const contractDataKeys = Object.keys(contractData);
15-
16-
for (let i = 0; contractDataKeys.length > i; i++) {
17-
const dataTypeReflection = () => ({
18-
'object': () => {
19-
const bufferData = data[contractDataKeys[i]] || contractData[contractDataKeys[i]];
20-
newData[contractDataKeys[i]] = {}
21-
return indexSearch(contractData[contractDataKeys[i]], bufferData, newData[contractDataKeys[i]]);
22-
},
23-
'primitive': () => {
24-
if (data[contractDataKeys[i]]) {
25-
return newData[contractDataKeys[i]] = data[contractDataKeys[i]];
26-
}
27-
return newData[contractDataKeys[i]] = contractData[contractDataKeys[i]];
28-
}
29-
});
30-
31-
if (typeof contractData[contractDataKeys[i]] === 'object') {
32-
dataTypeReflection()['object']();
33-
continue;
34-
}
35-
36-
dataTypeReflection()['primitive']();
37-
}
38-
39-
return newData;
40-
}
41-
4213
const saveMethodReflection = (store: any, contractName: string) => ({
4314
dispatch: (data: any) => {
4415
return store[contractName] = data;
@@ -73,6 +44,7 @@ export default function lawyer({
7344

7445
for (let i = 0; dataKeys.length > i; i++) {
7546
const currentDataKey = data[dataKeys[i]];
47+
7648
if (contractFields[dataKeys[i]] instanceof NucleoObject) {
7749
lawyer({
7850
contract: contractFields[dataKeys[i]],
@@ -103,6 +75,15 @@ export default function lawyer({
10375
NucleoObject: () => {
10476
if (_NucleoItemType instanceof NucleoObject) {
10577
for (let d = 0; d < currentDataKey.length; d++) {
78+
if (Object.keys(currentDataKey[d]).length !== Object.keys(_NucleoItemType.fields).length) {
79+
__errors__.push({
80+
contract: _NucleoItemType.name,
81+
error: 'You can not update a NucleoList of NucleoObject without its data according to contract in every level'
82+
});
83+
84+
continue;
85+
}
86+
10687
lawyer({
10788
contract: _NucleoItemType,
10889
data: currentDataKey[d],

src/nucleoTypes/NucleoList.spec.ts

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import {
2+
NucleoString,
3+
NucleoNumber,
4+
NucleoBoolean,
5+
NucleoList,
6+
NucleoObject,
7+
createStore
8+
} from './../index'
9+
import { expect } from 'chai';
10+
import 'mocha';
11+
12+
describe('NucleoList', () => {
13+
const userAccountsType = new NucleoObject({
14+
name: 'userAccountsType',
15+
fields: {
16+
accountType: NucleoString,
17+
accountNumber: NucleoNumber
18+
}
19+
});
20+
21+
const personalInfoType = new NucleoObject({
22+
name: 'personalInfo',
23+
fields: {
24+
firstName: NucleoString,
25+
lastName: NucleoString,
26+
items: new NucleoList(NucleoString),
27+
accounts: new NucleoList(userAccountsType)
28+
}
29+
});
30+
31+
const userType = new NucleoObject({
32+
name: 'user',
33+
fields: {
34+
personalInfo: personalInfoType,
35+
age: NucleoNumber
36+
}
37+
});
38+
const contracts = { user: userType };
39+
const store = createStore(contracts);
40+
const { dispatch, update, getStore } = store;
41+
42+
it('should dispatch all data to store', () => {
43+
const data = {
44+
age: 27,
45+
personalInfo: {
46+
firstName: 'Joseph',
47+
lastName: 'Nor',
48+
items: ['a', 'b', 'c'],
49+
accounts: [
50+
{ accountType: 'bank', accountNumber: 1233 },
51+
{ accountType: 'bank', accountNumber: 9876 }
52+
]
53+
}
54+
}
55+
56+
const d = dispatch('user')(data);
57+
expect(d.errors.length).to.equal(0);
58+
});
59+
60+
it('should try to update a NucleoList of primitive values succesfully', () => {
61+
const u = update('user')({ personalInfo: { items: ['g', 'h', 'j', 'k'] } });
62+
63+
const { personalInfo } = getStore().user;
64+
const { items } = personalInfo;
65+
66+
expect(personalInfo.firstName).to.equal('Joseph');
67+
expect(personalInfo.lastName).to.equal('Nor');
68+
expect(items.length).to.equal(4);
69+
expect(personalInfo.accounts.length).to.equal(2);
70+
expect(items[0]).to.equal('g');
71+
});
72+
73+
it('should try to violate a NucleoList of primitive values with update', () => {
74+
const u = update('user')({ personalInfo: { items: ['g', 'h', 'j', 1] } });
75+
76+
const { personalInfo } = getStore().user;
77+
const { items } = personalInfo;
78+
79+
expect(u.errors.length).to.equal(1);
80+
expect(personalInfo.firstName).to.equal('Joseph');
81+
expect(personalInfo.lastName).to.equal('Nor');
82+
expect(items.length).to.equal(4);
83+
expect(personalInfo.accounts.length).to.equal(2);
84+
expect(items[3]).to.equal('k');
85+
});
86+
87+
it('should try to update a NucleoList of object values succesfully', () => {
88+
const obj = {
89+
personalInfo: {
90+
accounts: [
91+
{ accountType: 'service', accountNumber: 1111 },
92+
{ accountType: 'service', accountNumber: 2222 }
93+
]
94+
}
95+
};
96+
97+
const u = update('user')(obj);
98+
const { personalInfo } = getStore().user;
99+
100+
expect(u.errors.length).to.equal(0);
101+
expect(personalInfo.accounts[0].accountType).to.equal('service');
102+
expect(personalInfo.accounts[1].accountType).to.equal('service');
103+
expect(personalInfo.accounts[0].accountNumber).to.equal(1111);
104+
expect(personalInfo.accounts[1].accountNumber).to.equal(2222);
105+
});
106+
107+
it('should try to violate a NucleoList of object values with update', () => {
108+
const obj = {
109+
personalInfo: {
110+
accounts: [
111+
{ accountType: 'service' },
112+
{ accountType: 'service', accountNumber: '2222' }
113+
]
114+
}
115+
};
116+
117+
const u = update('user')(obj);
118+
119+
const { personalInfo } = getStore().user;
120+
expect(u.errors.length).to.equal(2);
121+
expect(personalInfo.accounts[0].accountType).to.equal('service');
122+
expect(personalInfo.accounts[1].accountType).to.equal('service');
123+
expect(personalInfo.accounts[0].accountNumber).to.equal(1111);
124+
expect(personalInfo.accounts[1].accountNumber).to.equal(2222);
125+
});
126+
});
127+

0 commit comments

Comments
 (0)