Skip to content

Instantly share code, notes, and snippets.

@mathieueveillard
Created June 26, 2023 18:20
Show Gist options
  • Save mathieueveillard/adb3c39ad0cef9861ee70d01695779a9 to your computer and use it in GitHub Desktop.
Save mathieueveillard/adb3c39ad0cef9861ee70d01695779a9 to your computer and use it in GitHub Desktop.
/*
* This code snippet is an extract of a private codebase. Though it relies on many dependencies to
* the rest of the codebase, I believe that the code carries enough intension so that one can get
* the overall idea (see: https://blog.mathieueveillard.com/monkey-testing-et-property-based-testing-une-exploration)
*/
import fc from "fast-check";
const ALL_REDUCERS: HasName<Reducer<ApplicationState>>[] = [
withName("selectPhotograph")(pickRandomIndex(getNumberOfPhotographs)(selectionReducers.selectPhotograph)),
withName("selectPreviousPhotograph")(selectionReducers.selectPreviousPhotograph),
withName("selectNextPhotograph")(selectionReducers.selectNextPhotograph),
withName("selectLowerPhotograph")(selectionReducers.selectLowerPhotograph),
withName("selectUpperPhotograph")(selectionReducers.selectUpperPhotograph),
withName("selectFirstPhotograph")(selectionReducers.selectFirstPhotograph),
withName("selectLastPhotograph")(selectionReducers.selectLastPhotograph),
withName("resetSelection")(selectionReducers.resetSelection),
withName("selectDeletedPhotograph")(pickRandomIndex(getNumberOfDeletedPhotographs)(trashBinSelectionReducers.selectDeletedPhotograph)),
withName("selectPreviousDeletedPhotograph")(trashBinSelectionReducers.selectPreviousDeletedPhotograph),
withName("selectNextDeletedPhotograph")(trashBinSelectionReducers.selectNextDeletedPhotograph),
withName("selectFirstDeletedPhotograph")(trashBinSelectionReducers.selectFirstDeletedPhotograph),
withName("selectLastDeletedPhotograph")(trashBinSelectionReducers.selectLastDeletedPhotograph),
withName("resetDeletedPhotographsSelection")(trashBinSelectionReducers.resetDeletedPhotographsSelection),
withName("moveDown")(photographReducers.moveDown),
withName("moveUp")(photographReducers.moveUp),
withName("moveToFirst")(photographReducers.moveToFirst),
withName("moveToLast")(photographReducers.moveToLast),
withName("deleteSelection")(photographReducers.deleteSelection),
withName("cancel")(cancellationReducers.cancel),
withName("restorePhotograph")(trashBinReducers.restorePhotograph),
withName("zoomIn")(zoomReducers.zoomIn),
withName("zoomOut")(zoomReducers.zoomOut),
withName("zoomMin")(zoomReducers.zoomMin),
withName("zoomMax")(zoomReducers.zoomMax),
withName("resetZoom")(zoomReducers.resetZoom),
withName("enterSlideshow")(focusReducers.enterSlideshow),
withName("exitSlideshow")(focusReducers.exitSlideshow),
withName("enterSlideshowAtIndex")(pickRandomIndex(getNumberOfPhotographs)(focusReducers.enterSlideshowAtIndex)),
withName("toggleSlideshow")(focusReducers.toggleSlideshow),
withName("toggleTrashBin")(focusReducers.toggleTrashBin),
];
describe("Monkey testing", () => {
test("Random actions that preserve the overall number of photographs", () => {
fc.assert(
fc.property(
fc.nat({ max: 10 }),
fc.nat({ max: 10 }),
(numberOfPhotographs, numberOfDeletedPhotographs) => {
// GIVEN
const state = mockState<ApplicationState>({
photographs: arrayOfPhotographs(numberOfPhotographs),
trashBin: arrayOfPhotographs(numberOfDeletedPhotographs),
selection: "NO_INDEX",
trashBinSelection: "NO_INDEX",
cancellation: "NOTHING_TO_CANCEL",
focus: "THUMBNAILS",
zoom: 5,
});
const numberOfActions = 100;
// WHEN
const nextState = repeat<ApplicationState>(numberOfActions)(
pickRandomReducer(ALL_REDUCERS)
)(state);
// THEN
return (
getNumberOfPhotographs(nextState) +
getNumberOfDeletedPhotographs(nextState) ===
getNumberOfPhotographs(state) + //
getNumberOfDeletedPhotographs(state)
);
}
)
);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment