-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
307 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* @since 2024-11-14 23:00:43 | ||
* @author junbao <[email protected]> | ||
*/ | ||
|
||
import { createStore } from 'amos-core'; | ||
import { Map } from 'amos-shapes'; | ||
import { runMutations } from 'amos-testing'; | ||
import { toJS } from 'amos-utils'; | ||
import { mapMapBox } from './mapMapBox'; | ||
|
||
const accountDirtyPostMapBox = mapMapBox('unit.posts.accountDirtyMap', 0, 0, 0); | ||
|
||
describe('MapMapBox', () => { | ||
it('should create mutations', () => { | ||
expect( | ||
runMutations( | ||
accountDirtyPostMapBox.getInitialState().setAll({ | ||
1: [ | ||
[1, 2], | ||
[3, 4], | ||
], | ||
2: { 2: 3, 4: 5 }, | ||
}), | ||
[ | ||
accountDirtyPostMapBox.setItem(1, [[2, 3]]), | ||
accountDirtyPostMapBox.setItem(1, new Map<number, number>(0).setAll([[2, 3]])), | ||
accountDirtyPostMapBox.setAll({ 0: [], 1: [[2, 3]] }), | ||
accountDirtyPostMapBox.setAll([ | ||
[0, [[1, 2]]], | ||
[1, { 2: 3 }], | ||
]), | ||
accountDirtyPostMapBox.setItemIn(1, 2, 3), | ||
accountDirtyPostMapBox.deleteItemIn(1, 3), | ||
accountDirtyPostMapBox.mergeItemIn(1, 2, 3), | ||
accountDirtyPostMapBox.updateItemIn(1, 2, (v) => v + 1), | ||
accountDirtyPostMapBox.clearIn(1), | ||
accountDirtyPostMapBox.resetIn(1, { 2: 3 }), | ||
], | ||
).map((v) => toJS(v)), | ||
).toEqual([ | ||
{ 1: { 2: 3 }, 2: { 2: 3, 4: 5 } }, | ||
{ 1: { 2: 3 }, 2: { 2: 3, 4: 5 } }, | ||
{ 0: {}, 1: { 2: 3 }, 2: { 2: 3, 4: 5 } }, | ||
{ 0: { 1: 2 }, 1: { 2: 3 }, 2: { 2: 3, 4: 5 } }, | ||
{ 1: { 1: 2, 2: 3, 3: 4 }, 2: { 2: 3, 4: 5 } }, | ||
{ 1: { 1: 2 }, 2: { 2: 3, 4: 5 } }, | ||
{ 1: { 1: 2, 2: 3, 3: 4 }, 2: { 2: 3, 4: 5 } }, | ||
{ 1: { 1: 2, 2: 1, 3: 4 }, 2: { 2: 3, 4: 5 } }, | ||
{ 1: {}, 2: { 2: 3, 4: 5 } }, | ||
{ 1: { 2: 3 }, 2: { 2: 3, 4: 5 } }, | ||
]); | ||
}); | ||
it('should create selectors', () => { | ||
const store = createStore(); | ||
store.dispatch( | ||
accountDirtyPostMapBox.setAll({ | ||
1: [ | ||
[1, 2], | ||
[3, 4], | ||
], | ||
2: { 2: 3, 4: 5 }, | ||
}), | ||
); | ||
expect( | ||
store.select([ | ||
accountDirtyPostMapBox.getItem(1), | ||
accountDirtyPostMapBox.getItemIn(1, 1), | ||
accountDirtyPostMapBox.hasItem(0), | ||
accountDirtyPostMapBox.hasItemIn(1, 2), | ||
accountDirtyPostMapBox.hasItemIn(1, 3), | ||
accountDirtyPostMapBox.sizeIn(2), | ||
accountDirtyPostMapBox.size(), | ||
]), | ||
).toEqual([ | ||
new Map(0).setAll([ | ||
[1, 2], | ||
[3, 4], | ||
]), | ||
2, | ||
false, | ||
false, | ||
true, | ||
2, | ||
2, | ||
]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* @since 2024-11-14 23:00:43 | ||
* @author junbao <[email protected]> | ||
*/ | ||
|
||
import { ShapeBox } from 'amos-core'; | ||
import { Map, MapMap } from 'amos-shapes'; | ||
import { type ID, IDOf, once } from 'amos-utils'; | ||
import { MapBox } from './mapBox'; | ||
|
||
export interface MapMapBox<LM extends MapMap<any, any>> | ||
extends MapBox<LM>, | ||
ShapeBox< | ||
LM, | ||
| 'setItem' | ||
| 'setAll' | ||
| 'setItemIn' | ||
| 'setAllIn' | ||
| 'mergeItemIn' | ||
| 'mergeAllIn' | ||
| 'updateItemIn' | ||
| 'updateAllIn' | ||
| 'deleteItemIn' | ||
| 'deleteAllIn' | ||
| 'clearIn' | ||
| 'resetIn', | ||
'hasItemIn' | 'getItemIn' | 'sizeIn', | ||
MapMap<any, any> | ||
> {} | ||
|
||
export const MapMapBox = MapBox.extends<MapMapBox<any>>({ | ||
name: 'MapMap', | ||
mutations: { | ||
setItemIn: null, | ||
setAllIn: null, | ||
mergeItemIn: null, | ||
mergeAllIn: null, | ||
updateItemIn: null, | ||
updateAllIn: null, | ||
deleteItemIn: null, | ||
deleteAllIn: null, | ||
clearIn: null, | ||
resetIn: null, | ||
}, | ||
selectors: { | ||
getItemIn: null, | ||
hasItemIn: null, | ||
sizeIn: null, | ||
}, | ||
}); | ||
|
||
export function mapMapBox<KO, KI, V>( | ||
key: string, | ||
outerKey: KO & ID, | ||
innerKey: KI & ID, | ||
defaultValue: V, | ||
): MapMapBox<MapMap<IDOf<KO>, Map<IDOf<KI>, V>>> { | ||
return new MapMapBox( | ||
key, | ||
once(() => new MapMap(new Map(defaultValue))), | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* @since 2024-11-14 22:38:52 | ||
* @author junbao <[email protected]> | ||
*/ | ||
|
||
import { TodoStatus } from 'amos-testing'; | ||
import { Map } from './Map'; | ||
import { MapMap } from './MapMap'; | ||
|
||
describe('MapMap', () => { | ||
it('should create MapMap', () => { | ||
// default list map | ||
const foo = new MapMap<number, Map<string, number>>(new Map(0)); | ||
// @ts-expect-error | ||
foo.getItem(''); | ||
foo.setItemIn(1, '', 1); | ||
foo.setItem(0, { '': 1 }); | ||
foo.getItem(0); | ||
foo.getItem(0).getItem('').toExponential(); | ||
foo.getItemIn(1, ''); | ||
foo.hasItemIn(1, ''); | ||
// with value type limit | ||
const bar = new MapMap<number, Map<TodoStatus, string>>(new Map('')); | ||
// @ts-expect-error | ||
expect(bar.getItem(0).getItem(0) === '10').toBeFalsy(); | ||
|
||
class EMap<T> extends Map<number, T> { | ||
fine() { | ||
return this.size() > 1; | ||
} | ||
} | ||
|
||
expect( | ||
new EMap(TodoStatus.created) | ||
.setAll([ | ||
[1, 1], | ||
[2, 2], | ||
]) | ||
.size(), | ||
).toBe(2); | ||
|
||
const l1 = new MapMap<number, EMap<TodoStatus>>(new EMap(TodoStatus.created)); | ||
expect(l1.getItem(0).fine()).toBe(false); | ||
expect( | ||
l1 | ||
.setAllIn(1, [ | ||
[1, 1], | ||
[2, 2], | ||
]) | ||
.getItem(1) | ||
.fine(), | ||
).toBe(true); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* @since 2024-11-14 22:38:52 | ||
* @author junbao <[email protected]> | ||
*/ | ||
|
||
import { type ArraySource, Entry, ID, isIterable, type PartialDictionary } from 'amos-utils'; | ||
import { | ||
implementMapDelegations, | ||
Map, | ||
MapDelegateOperations, | ||
type MapEntry, | ||
type MapKey, | ||
type MapValue, | ||
} from './Map'; | ||
|
||
export interface MapMap<K extends ID, M extends Map<any, any>> | ||
extends MapDelegateOperations< | ||
K, | ||
M, | ||
| 'setItem' | ||
| 'setAll' | ||
| 'mergeItem' | ||
| 'mergeAll' | ||
| 'updateItem' | ||
| 'updateAll' | ||
| 'deleteItem' | ||
| 'deleteAll' | ||
| 'clear' | ||
| 'reset', | ||
'hasItem' | 'getItem' | 'size' | 'entries' | 'keys' | 'values', | ||
Map<any, any> | ||
> {} | ||
|
||
export class MapMap<K extends ID, M extends Map<any, any>> extends Map<K, M> { | ||
constructor(defaultValue: M) { | ||
super(defaultValue); | ||
} | ||
|
||
override setItem( | ||
key: K, | ||
value: M | PartialDictionary<MapKey<M>, MapValue<M>> | readonly MapEntry<M>[], | ||
): this { | ||
return super.setItem( | ||
key, | ||
value instanceof Map | ||
? value | ||
: this.defaultValue.reset(Array.isArray(value) ? Object.fromEntries(value) : value), | ||
); | ||
} | ||
|
||
override setAll( | ||
items: | ||
| PartialDictionary<K, M | PartialDictionary<MapKey<M>, MapValue<M>> | readonly MapEntry<M>[]> | ||
| ArraySource< | ||
Entry<K, M | PartialDictionary<MapKey<M>, MapValue<M>> | readonly MapEntry<M>[]> | ||
>, | ||
): this { | ||
const data = Array.isArray(items) | ||
? items | ||
: isIterable(items) | ||
? Array.from(items) | ||
: Object.entries(items); | ||
data.forEach((d) => { | ||
if (Array.isArray(d[1])) { | ||
d[1] = this.defaultValue.reset(Object.fromEntries(d[1])); | ||
} else if (!(d[1] instanceof Map)) { | ||
d[1] = this.defaultValue.reset(d[1]); | ||
} | ||
}); | ||
return super.setAll(data); | ||
} | ||
} | ||
|
||
implementMapDelegations(MapMap, { | ||
setItem: 'set', | ||
setAll: 'set', | ||
mergeItem: 'set', | ||
mergeAll: 'set', | ||
updateItem: 'set', | ||
updateAll: 'set', | ||
deleteItem: 'set', | ||
deleteAll: 'set', | ||
clear: 'set', | ||
reset: 'set', | ||
getItem: 'get', | ||
hasItem: 'get', | ||
size: 'get', | ||
entries: 'get', | ||
keys: 'get', | ||
values: 'get', | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters