-
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.
Merge pull request #5 from 21GramConsulting/bug/3
Bug/3
- Loading branch information
Showing
18 changed files
with
1,434 additions
and
23 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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
28 changes: 28 additions & 0 deletions
28
test/regression/3-hook-reevaluation-due-to-task-recreation/3-hook-reevaluation.test.tsx
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,28 @@ | ||
/** | ||
* @jest-environment jsdom | ||
*/ | ||
import {descriptors} from '#consistencyGuard'; | ||
import {render, screen} from '@testing-library/react'; | ||
import '@testing-library/jest-dom'; | ||
import ReproApp from './ReproApp'; | ||
import userEvent from '@testing-library/user-event'; | ||
|
||
beforeEach(() => { | ||
descriptors.clear(); | ||
}); | ||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
describe('Hook Reevaluation due to task recreation:', () => { | ||
test("shouldn't end up in an infinite loop when a failure occurs.", async () => { | ||
render(<ReproApp />); | ||
let repetition = 50; | ||
while (repetition--) { | ||
await userEvent.click(screen.getByText('Reproduce Bug')); | ||
} | ||
await screen.findByTestId('output'); | ||
|
||
expect(screen.getByTestId('output')).toHaveTextContent('For an input'); | ||
}); | ||
}); |
44 changes: 44 additions & 0 deletions
44
test/regression/3-hook-reevaluation-due-to-task-recreation/OngoingTasks.tsx
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,44 @@ | ||
import {useReproContext} from './ReproContext'; | ||
import {FunctionComponent} from 'react'; | ||
import {TaskQueueHook} from '@21gram-consulting/use-task-queue'; | ||
import Task1 from './Task1'; | ||
import Task2 from './Task2'; | ||
import Task3 from './Task3'; | ||
|
||
const OngoingTasks: FunctionComponent = function OngoingTasks() { | ||
const context = useReproContext(); | ||
return ( | ||
<div> | ||
<h1>Ongoing Tasks</h1> | ||
<div> | ||
<h2>{subTitle(context.task1)}</h2> | ||
<Task1 /> | ||
</div> | ||
<div> | ||
<h2>{subTitle(context.task2)}</h2> | ||
<Task2 /> | ||
</div> | ||
<div> | ||
<h2>{subTitle(context.task3)}</h2> | ||
<Task3 /> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
const subTitle = <A, B>({ | ||
input, | ||
process, | ||
error, | ||
output, | ||
}: TaskQueueHook<A, B>): string => | ||
[ | ||
`${input.length} waiting to be picked up`, | ||
`${process.length} is processed.`, | ||
`${error.length} resolved as error`, | ||
`${output.length} result ready for pickup`, | ||
] | ||
.join(', ') | ||
.concat('.'); | ||
|
||
export default OngoingTasks; |
15 changes: 15 additions & 0 deletions
15
test/regression/3-hook-reevaluation-due-to-task-recreation/ReproApp.tsx
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,15 @@ | ||
import {FunctionComponent} from 'react'; | ||
import {ReproProvider} from './ReproContext'; | ||
import OngoingTasks from './OngoingTasks'; | ||
import Reproduce from './Reproduce'; | ||
|
||
const ReproApp: FunctionComponent = function ReproApp() { | ||
return ( | ||
<ReproProvider> | ||
<OngoingTasks /> | ||
<Reproduce /> | ||
</ReproProvider> | ||
); | ||
}; | ||
|
||
export default ReproApp; |
38 changes: 38 additions & 0 deletions
38
test/regression/3-hook-reevaluation-due-to-task-recreation/ReproContext.tsx
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,38 @@ | ||
import { | ||
FunctionComponent, | ||
PropsWithChildren, | ||
createContext, | ||
useContext, | ||
} from 'react'; | ||
import {nullTaskQueue, TaskQueueHook} from '@21gram-consulting/use-task-queue'; | ||
import useTask1 from './useTask1'; | ||
import useTask2 from './useTask2'; | ||
import useTask3 from './useTask3'; | ||
|
||
type Props = PropsWithChildren<unknown>; | ||
export type ContextValue = { | ||
task1: TaskQueueHook<number, number>; | ||
task2: TaskQueueHook<number, string>; | ||
task3: TaskQueueHook<string, string[]>; | ||
}; | ||
|
||
const ReproContext = createContext<ContextValue>({ | ||
task1: nullTaskQueue(), | ||
task2: nullTaskQueue(), | ||
task3: nullTaskQueue(), | ||
}); | ||
|
||
export function useReproContext(): ContextValue { | ||
return useContext(ReproContext); | ||
} | ||
|
||
export const ReproProvider: FunctionComponent<Props> = props => { | ||
const task1 = useTask1(); | ||
const task2 = useTask2(task1); | ||
const task3 = useTask3(task2); | ||
return ( | ||
<ReproContext.Provider value={{task1, task2, task3}}> | ||
{props.children} | ||
</ReproContext.Provider> | ||
); | ||
}; |
32 changes: 32 additions & 0 deletions
32
test/regression/3-hook-reevaluation-due-to-task-recreation/Reproduce.tsx
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,32 @@ | ||
import {FunctionComponent, useState} from 'react'; | ||
import {useReproContext} from './ReproContext'; | ||
|
||
const Reproduce: FunctionComponent = () => { | ||
const context = useReproContext(); | ||
const [input, setInput] = useState(10); | ||
const reproduce = () => { | ||
context.task1.push(input); | ||
setInput(v => v + 1); | ||
}; | ||
return ( | ||
<> | ||
<button onClick={reproduce}>Reproduce Bug</button> | ||
<output data-testid="output"> | ||
<ul> | ||
{context.task3.output.map((output, index) => ( | ||
<li key={index}> | ||
For an input of {output.input}, the outputs are: | ||
<ul> | ||
{output.output.map((output, index) => ( | ||
<li key={index}>{output}</li> | ||
))} | ||
</ul> | ||
</li> | ||
))} | ||
</ul> | ||
</output> | ||
</> | ||
); | ||
}; | ||
|
||
export default Reproduce; |
36 changes: 36 additions & 0 deletions
36
test/regression/3-hook-reevaluation-due-to-task-recreation/Task1.tsx
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,36 @@ | ||
import {FunctionComponent} from 'react'; | ||
import {TaskProcess} from '@21gram-consulting/use-task-queue'; | ||
import {useReproContext} from './ReproContext'; | ||
|
||
const Task1: FunctionComponent = function Task1() { | ||
const context = useReproContext(); | ||
return ( | ||
<div> | ||
<h3>Task 1</h3> | ||
<div> | ||
{context.task1.process.map((process, index) => ( | ||
<TaskItem | ||
{...process} | ||
key={index} | ||
cancel={() => context.task1.kill(process)} | ||
/> | ||
))} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
type TaskItemProps = TaskProcess<number, number> & { | ||
cancel: () => void; | ||
}; | ||
const TaskItem: FunctionComponent<TaskItemProps> = props => { | ||
return ( | ||
<div> | ||
<h4>Task Item</h4> | ||
<p>Processing input: {props.input}</p> | ||
<button onClick={props.cancel}>Cancel</button> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Task1; |
36 changes: 36 additions & 0 deletions
36
test/regression/3-hook-reevaluation-due-to-task-recreation/Task2.tsx
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,36 @@ | ||
import {FunctionComponent} from 'react'; | ||
import {TaskProcess} from '@21gram-consulting/use-task-queue'; | ||
import {useReproContext} from './ReproContext'; | ||
|
||
const Task2: FunctionComponent = function Task2() { | ||
const context = useReproContext(); | ||
return ( | ||
<div> | ||
<h3>Task 1</h3> | ||
<div> | ||
{context.task2.process.map((process, index) => ( | ||
<TaskItem | ||
{...process} | ||
key={index} | ||
cancel={() => context.task2.kill(process)} | ||
/> | ||
))} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
type TaskItemProps = TaskProcess<number, string> & { | ||
cancel: () => void; | ||
}; | ||
const TaskItem: FunctionComponent<TaskItemProps> = props => { | ||
return ( | ||
<div> | ||
<h4>Task Item</h4> | ||
<p>Processing input: {props.input}</p> | ||
<button onClick={props.cancel}>Cancel</button> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Task2; |
36 changes: 36 additions & 0 deletions
36
test/regression/3-hook-reevaluation-due-to-task-recreation/Task3.tsx
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,36 @@ | ||
import {FunctionComponent} from 'react'; | ||
import {TaskProcess} from '@21gram-consulting/use-task-queue'; | ||
import {useReproContext} from './ReproContext'; | ||
|
||
const Task3: FunctionComponent = function Task3() { | ||
const context = useReproContext(); | ||
return ( | ||
<div> | ||
<h3>Task 1</h3> | ||
<div> | ||
{context.task3.process.map((process, index) => ( | ||
<TaskItem | ||
{...process} | ||
key={index} | ||
cancel={() => context.task3.kill(process)} | ||
/> | ||
))} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
type TaskItemProps = TaskProcess<string, string[]> & { | ||
cancel: () => void; | ||
}; | ||
const TaskItem: FunctionComponent<TaskItemProps> = props => { | ||
return ( | ||
<div> | ||
<h4>Task Item</h4> | ||
<p>Processing input: {props.input}</p> | ||
<button onClick={props.cancel}>Cancel</button> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Task3; |
13 changes: 13 additions & 0 deletions
13
test/regression/3-hook-reevaluation-due-to-task-recreation/useTask1.ts
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,13 @@ | ||
import {TaskQueueHook, useTaskQueue} from '@21gram-consulting/use-task-queue'; | ||
import {json} from '@21gram-consulting/ts-codec'; | ||
|
||
export default function useTask1(): TaskQueueHook<number, number> { | ||
return useTaskQueue({ | ||
name: 'task1', | ||
codec: json.number, | ||
task: v => { | ||
if (v % 3 === 0) throw new Error('Stub task execution error.'); | ||
return [v, v * 2, v * 3]; | ||
}, | ||
}); | ||
} |
14 changes: 14 additions & 0 deletions
14
test/regression/3-hook-reevaluation-due-to-task-recreation/useTask2.ts
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,14 @@ | ||
import {TaskQueueHook, useTaskQueue} from '@21gram-consulting/use-task-queue'; | ||
import {json} from '@21gram-consulting/ts-codec'; | ||
|
||
export default function useTask2( | ||
input: TaskQueueHook<any, number> | ||
): TaskQueueHook<number, string> { | ||
return useTaskQueue({ | ||
name: 'task2', | ||
codec: json.number, | ||
input: input, | ||
task: v => [v.toString()], | ||
precondition: v => v % 2 === 0, | ||
}); | ||
} |
14 changes: 14 additions & 0 deletions
14
test/regression/3-hook-reevaluation-due-to-task-recreation/useTask3.ts
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,14 @@ | ||
import {TaskQueueHook, useTaskQueue} from '@21gram-consulting/use-task-queue'; | ||
import {json} from '@21gram-consulting/ts-codec'; | ||
|
||
export default function useTask3( | ||
input: TaskQueueHook<any, string> | ||
): TaskQueueHook<string, string[]> { | ||
return useTaskQueue({ | ||
name: 'task3', | ||
codec: json.string, | ||
input: input, | ||
task: v => [v.split('')], | ||
postcondition: v => v.length === 2, | ||
}); | ||
} |
Oops, something went wrong.