-
Notifications
You must be signed in to change notification settings - Fork 0
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
1 parent
e364b9b
commit 203093f
Showing
6 changed files
with
309 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/** | ||
* @typedef {import("./FileListActions.mjs").FileListAction} FileListAction | ||
* @typedef {import("./FileListState.mjs").FileListState} FileListState | ||
*/ | ||
import FileListActions from "./FileListActions.mjs"; | ||
|
||
/** | ||
* @typedef {(a: any) => void} Dispatch | ||
*/ | ||
|
||
/** | ||
* @typedef {{ | ||
* readonly dispatch: Dispatch; | ||
* readonly actions: FileListActions; | ||
* readonly state: FileListState; | ||
* }} FileListData | ||
*/ | ||
|
||
/** | ||
* @param {Dispatch} dispatch | ||
* @param {FileListActions} actions | ||
* @param {FileListState} state | ||
* @returns {FileListData} | ||
*/ | ||
function FileListData(dispatch, actions, state) { | ||
return { dispatch, actions, state }; | ||
} | ||
|
||
export default FileListData; |
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,76 @@ | ||
/** | ||
* @typedef {import("../FileListData.mjs").Dispatch} Dispatch | ||
* @typedef {import("../FileListData.mjs").FileListData} FileListData | ||
*/ | ||
import React from "react"; | ||
import FileListData from "../FileListData.mjs"; | ||
import FileListState from "../FileListState.mjs"; | ||
import FileListActions from "../FileListActions.mjs"; | ||
|
||
/** | ||
* @template T | ||
*/ | ||
class PanelStackItem { | ||
/** | ||
* @param {React.FunctionComponent<any> | React.ComponentClass<any>} component | ||
* @param {Dispatch} [dispatch] | ||
* @param {FileListActions} [actions] | ||
* @param {T} [state] | ||
*/ | ||
constructor(component, dispatch, actions, state) { | ||
/** @readonly @type {React.FunctionComponent<any> | React.ComponentClass<any>} */ | ||
this.component = component; | ||
|
||
/** @readonly @type {Dispatch | undefined} */ | ||
this.dispatch = dispatch; | ||
|
||
/** @readonly @type {FileListActions | undefined} */ | ||
this.actions = actions; | ||
|
||
/** @readonly @type {T | undefined} */ | ||
this.state = state; | ||
} | ||
|
||
/** | ||
* @param {T} s | ||
* @returns {PanelStackItem<T>} | ||
*/ | ||
withState(s) { | ||
return new PanelStackItem(this.component, this.dispatch, this.actions, s); | ||
} | ||
|
||
/** | ||
* @param {(s: T) => T} f | ||
* @returns {PanelStackItem<T>} | ||
*/ | ||
updateState(f) { | ||
return new PanelStackItem( | ||
this.component, | ||
this.dispatch, | ||
this.actions, | ||
this.state ? f(this.state) : this.state | ||
); | ||
} | ||
|
||
/** | ||
* @returns {FileListData | undefined} | ||
*/ | ||
getData() { | ||
if ( | ||
this.dispatch && | ||
this.actions && | ||
this.state && | ||
FileListState.isFileListState(this.state) | ||
) { | ||
return FileListData( | ||
this.dispatch, | ||
this.actions, | ||
/** @type {any} */ (this.state) | ||
); | ||
} | ||
|
||
return undefined; | ||
} | ||
} | ||
|
||
export default PanelStackItem; |
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,135 @@ | ||
import assert from "node:assert/strict"; | ||
import mockFunction from "mock-fn"; | ||
import MockFileListApi from "../../src/api/MockFileListApi.mjs"; | ||
import FileListState from "../../src/FileListState.mjs"; | ||
import FileListActions from "../../src/FileListActions.mjs"; | ||
import PanelStackItem from "../../src/stack/PanelStackItem.mjs"; | ||
|
||
const { describe, it } = await (async () => { | ||
// @ts-ignore | ||
const module = process.isBun ? "bun:test" : "node:test"; | ||
// @ts-ignore | ||
return process.isBun // @ts-ignore | ||
? Promise.resolve({ describe: (_, fn) => fn(), it: test }) | ||
: import(module); | ||
})(); | ||
|
||
const Component = () => { | ||
return null; | ||
}; | ||
const dispatch = () => {}; | ||
const actions = new FileListActions(new MockFileListApi()); | ||
const state = FileListState(); | ||
|
||
describe("PanelStackItem.test.mjs", () => { | ||
it("should create new item with component only", () => { | ||
//when | ||
const result = new PanelStackItem(Component); | ||
|
||
//then | ||
assert.deepEqual(result.component == Component, true); | ||
assert.deepEqual(result.dispatch, undefined); | ||
assert.deepEqual(result.actions, undefined); | ||
assert.deepEqual(result.state, undefined); | ||
}); | ||
|
||
it("should create new item with all data", () => { | ||
//when | ||
const result = new PanelStackItem(Component, dispatch, actions, state); | ||
|
||
//then | ||
assert.deepEqual(result.component == Component, true); | ||
assert.deepEqual(result.dispatch == dispatch, true); | ||
assert.deepEqual(result.actions == actions, true); | ||
assert.deepEqual(result.state == state, true); | ||
}); | ||
|
||
it("should return new item with updated state when withState", () => { | ||
//given | ||
const item = new PanelStackItem(Component, dispatch, actions); | ||
assert.deepEqual(item.state, undefined); | ||
|
||
//when | ||
const result = item.withState(state); | ||
|
||
//then | ||
assert.deepEqual(item.state, undefined); | ||
assert.deepEqual(result !== item, true); | ||
assert.deepEqual(result.dispatch == dispatch, true); | ||
assert.deepEqual(result.actions == actions, true); | ||
assert.deepEqual(result.state == state, true); | ||
}); | ||
|
||
it("should return new item with undefined state when updateState", () => { | ||
//given | ||
const onState = mockFunction(); | ||
const item = new PanelStackItem(Component, dispatch, actions); | ||
assert.deepEqual(item.state, undefined); | ||
|
||
//when | ||
const result = item.updateState(onState); | ||
|
||
//then | ||
assert.deepEqual(onState.times, 0); | ||
assert.deepEqual(item.state, undefined); | ||
assert.deepEqual(result !== item, true); | ||
assert.deepEqual(result.dispatch == dispatch, true); | ||
assert.deepEqual(result.actions == actions, true); | ||
assert.deepEqual(result.state, undefined); | ||
}); | ||
|
||
it("should return new item with updated state when updateState", () => { | ||
//given | ||
const item = new PanelStackItem(Component, dispatch, actions, state); | ||
const newState = FileListState(); | ||
let capturedState = null; | ||
const onState = mockFunction((s) => { | ||
capturedState = s; | ||
return newState; | ||
}); | ||
|
||
//when | ||
const result = item.updateState(onState); | ||
|
||
//then | ||
assert.deepEqual(onState.times, 1); | ||
assert.deepEqual(capturedState == state, true); | ||
assert.deepEqual(item.state == state, true); | ||
assert.deepEqual(result !== item, true); | ||
assert.deepEqual(result.dispatch == dispatch, true); | ||
assert.deepEqual(result.actions == actions, true); | ||
assert.deepEqual(result.state == newState, true); | ||
}); | ||
|
||
it("should return undefined when getData", () => { | ||
//when & then | ||
assert.deepEqual(new PanelStackItem(Component).getData(), undefined); | ||
assert.deepEqual( | ||
new PanelStackItem(Component, undefined, actions, state).getData(), | ||
undefined | ||
); | ||
assert.deepEqual( | ||
new PanelStackItem(Component, dispatch, undefined, state).getData(), | ||
undefined | ||
); | ||
assert.deepEqual( | ||
new PanelStackItem(Component, dispatch, actions, undefined).getData(), | ||
undefined | ||
); | ||
assert.deepEqual( | ||
new PanelStackItem(Component, dispatch, actions, {}).getData(), | ||
undefined | ||
); | ||
}); | ||
|
||
it("should return FileListData if FileListState when getData", () => { | ||
//given | ||
const item = new PanelStackItem(Component, dispatch, actions, state); | ||
|
||
//when | ||
const result = item.getData(); | ||
|
||
//then | ||
assert.deepEqual(result, { dispatch, actions, state }); | ||
}); | ||
}); |
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,27 @@ | ||
export default FileListData; | ||
export type Dispatch = (a: any) => void; | ||
export type FileListData = { | ||
readonly dispatch: Dispatch; | ||
readonly actions: FileListActions; | ||
readonly state: FileListState; | ||
}; | ||
export type FileListAction = import("./FileListActions.mjs").FileListAction; | ||
export type FileListState = import("./FileListState.mjs").FileListState; | ||
/** | ||
* @typedef {(a: any) => void} Dispatch | ||
*/ | ||
/** | ||
* @typedef {{ | ||
* readonly dispatch: Dispatch; | ||
* readonly actions: FileListActions; | ||
* readonly state: FileListState; | ||
* }} FileListData | ||
*/ | ||
/** | ||
* @param {Dispatch} dispatch | ||
* @param {FileListActions} actions | ||
* @param {FileListState} state | ||
* @returns {FileListData} | ||
*/ | ||
declare function FileListData(dispatch: Dispatch, actions: FileListActions, state: FileListState): FileListData; | ||
import FileListActions from "./FileListActions.mjs"; |
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,40 @@ | ||
export default PanelStackItem; | ||
export type Dispatch = import("../FileListData.mjs").Dispatch; | ||
export type FileListData = import("../FileListData.mjs").FileListData; | ||
/** | ||
* @template T | ||
*/ | ||
declare class PanelStackItem<T> { | ||
/** | ||
* @param {React.FunctionComponent<any> | React.ComponentClass<any>} component | ||
* @param {Dispatch} [dispatch] | ||
* @param {FileListActions} [actions] | ||
* @param {T} [state] | ||
*/ | ||
constructor(component: React.FunctionComponent<any> | React.ComponentClass<any>, dispatch?: import("../FileListData.mjs").Dispatch | undefined, actions?: FileListActions | undefined, state?: T | undefined); | ||
/** @readonly @type {React.FunctionComponent<any> | React.ComponentClass<any>} */ | ||
readonly component: React.FunctionComponent<any> | React.ComponentClass<any>; | ||
/** @readonly @type {Dispatch | undefined} */ | ||
readonly dispatch: Dispatch | undefined; | ||
/** @readonly @type {FileListActions | undefined} */ | ||
readonly actions: FileListActions | undefined; | ||
/** @readonly @type {T | undefined} */ | ||
readonly state: T | undefined; | ||
/** | ||
* @param {T} s | ||
* @returns {PanelStackItem<T>} | ||
*/ | ||
withState(s: T): PanelStackItem<T>; | ||
/** | ||
* @param {(s: T) => T} f | ||
* @returns {PanelStackItem<T>} | ||
*/ | ||
updateState(f: (s: T) => T): PanelStackItem<T>; | ||
/** | ||
* @returns {FileListData | undefined} | ||
*/ | ||
getData(): FileListData | undefined; | ||
} | ||
import React from "react"; | ||
import FileListActions from "../FileListActions.mjs"; | ||
import FileListData from "../FileListData.mjs"; |