@vived/app 6.5.0 → 6.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/LabelDrop/Factories/LabelDropFeatureFactory.js +1 -0
- package/dist/cjs/LabelDrop/Factories/LabelDropFeatureFactory.js.map +1 -1
- package/dist/cjs/LabelDrop/UseCases/SubmitLabelDropResultUC.js +80 -0
- package/dist/cjs/LabelDrop/UseCases/SubmitLabelDropResultUC.js.map +1 -0
- package/dist/cjs/LabelDrop/UseCases/SubmitLabelDropResultUC.test.js +46 -0
- package/dist/cjs/LabelDrop/UseCases/SubmitLabelDropResultUC.test.js.map +1 -0
- package/dist/cjs/LabelDrop/UseCases/index.js +1 -0
- package/dist/cjs/LabelDrop/UseCases/index.js.map +1 -1
- package/dist/cjs/TestUtils/index.js +18 -0
- package/dist/cjs/TestUtils/index.js.map +1 -0
- package/dist/cjs/TestUtils/setupFeatureForTesting.js +60 -0
- package/dist/cjs/TestUtils/setupFeatureForTesting.js.map +1 -0
- package/dist/esm/LabelDrop/Factories/LabelDropFeatureFactory.js +2 -1
- package/dist/esm/LabelDrop/Factories/LabelDropFeatureFactory.js.map +1 -1
- package/dist/esm/LabelDrop/UseCases/SubmitLabelDropResultUC.js +75 -0
- package/dist/esm/LabelDrop/UseCases/SubmitLabelDropResultUC.js.map +1 -0
- package/dist/esm/LabelDrop/UseCases/SubmitLabelDropResultUC.test.js +44 -0
- package/dist/esm/LabelDrop/UseCases/SubmitLabelDropResultUC.test.js.map +1 -0
- package/dist/esm/LabelDrop/UseCases/index.js +1 -0
- package/dist/esm/LabelDrop/UseCases/index.js.map +1 -1
- package/dist/esm/TestUtils/index.js +2 -0
- package/dist/esm/TestUtils/index.js.map +1 -0
- package/dist/esm/TestUtils/setupFeatureForTesting.js +57 -0
- package/dist/esm/TestUtils/setupFeatureForTesting.js.map +1 -0
- package/dist/types/LabelDrop/Factories/LabelDropFeatureFactory.d.ts.map +1 -1
- package/dist/types/LabelDrop/UseCases/SubmitLabelDropResultUC.d.ts +21 -0
- package/dist/types/LabelDrop/UseCases/SubmitLabelDropResultUC.d.ts.map +1 -0
- package/dist/types/LabelDrop/UseCases/SubmitLabelDropResultUC.test.d.ts +2 -0
- package/dist/types/LabelDrop/UseCases/SubmitLabelDropResultUC.test.d.ts.map +1 -0
- package/dist/types/LabelDrop/UseCases/index.d.ts +1 -0
- package/dist/types/LabelDrop/UseCases/index.d.ts.map +1 -1
- package/dist/types/TestUtils/index.d.ts +2 -0
- package/dist/types/TestUtils/index.d.ts.map +1 -0
- package/dist/types/TestUtils/setupFeatureForTesting.d.ts +48 -0
- package/dist/types/TestUtils/setupFeatureForTesting.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -84,6 +84,7 @@ class LabelDropFeatureFactory extends core_1.DomainFactory {
|
|
|
84
84
|
(0, UseCases_1.makeLabelDropOnNothingAnimationUC)(this.appObject);
|
|
85
85
|
(0, UseCases_1.makeLabelDropIncorrectAnimationUC)(this.appObject);
|
|
86
86
|
(0, UseCases_1.makeValidateLabelDrop)(this.appObject);
|
|
87
|
+
(0, UseCases_1.makeSubmitLabelDropResultUC)(this.appObject);
|
|
87
88
|
}
|
|
88
89
|
/**
|
|
89
90
|
* Sets up all presentation models for the LabelDrop Feature.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LabelDropFeatureFactory.js","sourceRoot":"","sources":["../../../../src/LabelDrop/Factories/LabelDropFeatureFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DomainFactory,\n AppObject,\n AppObjectRepo,\n Quaternion,\n Vector3,\n} from \"@vived/core\";\nimport { StylusEntity } from \"../../Stylus\";\nimport { makeTransform3DPM } from \"../../Transform3D\";\nimport { ZSpaceEntity } from \"../../zSpace\";\nimport {\n makeMouseLabelDropAuthor,\n makeStylusLabelDrop,\n makeTouchLabelDropAuthor,\n} from \"../Controller\";\nimport { makeLabelDropRepo } from \"../Entities\";\nimport {\n makeLabelDropDragItemPM,\n makeLabelDropEditingIDPM,\n makeLabelDropListPM,\n makeLabelDropReviewPM,\n makeRemainingLabelDropListPM,\n} from \"../PM\";\nimport {\n ClearEditingLabelDropUCHook,\n makeDeleteAllLabelDropUC,\n makeDeleteLabelDropUC,\n makeDragLabelDropUC,\n makeDragLabelDropWorldUC,\n makeEditLabelDropUC,\n makeLabelDropCorrectAnimationUC,\n makeLabelDropIncorrectAnimationUC,\n makeLabelDropOnNothingAnimationUC,\n makeToggleLabelDropTargetUC,\n makeValidateLabelDrop,\n SerializeLabelDrop,\n} from \"../UseCases\";\nimport { makeLabelDropItemFactory } from \"./labelDropItemFactory\";\nimport { LabelDropRepo } from \"../Entities\";\nimport { ChallengeEntity } from \"../../Challenge\";\n\n/**\n * Factory responsible for setting up the LabelDrop Feature domain components.\n *\n * This factory initializes all entities, use cases, presentation models, and controllers\n * required for the LabelDrop Feature functionality. It follows the domain-driven\n * design pattern by organizing components into their respective layers. This factory\n * replaces the complex setupLabelDrop function while maintaining backwards compatibility.\n *\n * The factory creates and configures:\n * - 1 LabelDropRepo entity with labelDropItemFactory configuration\n * - 12 Use Cases for label drop operations including serialization, editing, dragging, and validation\n * - 6 Presentation Models for UI state management and data presentation\n * - 3 Controllers for mouse, touch, and stylus interactions\n * - External dependency management for StylusEntity and ZSpaceEntity\n * - Transform hierarchy setup with proper positioning and scaling\n *\n * @extends DomainFactory\n */\nexport class LabelDropFeatureFactory extends DomainFactory {\n factoryName = \"LabelDropFeatureFactory\";\n\n private labelDropEntity: LabelDropRepo | null = null;\n\n /**\n * Sets up all entities required for the LabelDrop Feature.\n *\n * Initializes the LabelDropRepo entity and configures it with the\n * labelDropItemFactory for creating individual label drop items.\n * Uses the \"LabelDrop\" AppObject that was passed to the factory constructor.\n */\n setupEntities(): void {\n // Create the main LabelDropRepo entity\n this.labelDropEntity = makeLabelDropRepo(this.appObject);\n\n // Configure the entity with the item factory\n this.labelDropEntity.labelDropItemFactory = makeLabelDropItemFactory(\n this.appObject.appObjectRepo,\n );\n }\n\n /**\n * Sets up all use cases for the LabelDrop Feature.\n *\n * Initializes all 12 use cases that define the business operations and\n * workflows available in the label drop feature. The use cases are created\n * in the same order as the original setupLabelDrop function to maintain\n * functional equivalence.\n *\n * Use Cases created:\n * - SerializeLabelDrop: Handles serialization of label drop data\n * - ClearEditingLabelDropUCHook: Manages clearing editing state\n * - EditLabelDropUC: Handles label drop editing operations\n * - DragLabelDropUC: Manages label drop dragging in screen space\n * - DragLabelDropWorldUC: Manages label drop dragging in world space\n * - DeleteLabelDropUC: Handles individual label drop deletion\n * - DeleteAllLabelDropUC: Handles deletion of all label drops\n * - ToggleLabelDropTargetUC: Manages target toggle operations\n * - LabelDropCorrectAnimationUC: Handles correct drop animations\n * - LabelDropOnNothingAnimationUC: Handles drop-on-nothing animations\n * - LabelDropIncorrectAnimationUC: Handles incorrect drop animations\n * - ValidateLabelDrop: Handles label drop validation logic\n */\n setupUCs(): void {\n // Create all Use Cases in the same order as original\n new SerializeLabelDrop(this.appObject);\n new ClearEditingLabelDropUCHook(this.appObject);\n makeEditLabelDropUC(this.appObject);\n makeDragLabelDropUC(this.appObject);\n makeDragLabelDropWorldUC(this.appObject);\n makeDeleteLabelDropUC(this.appObject);\n makeDeleteAllLabelDropUC(this.appObject);\n makeToggleLabelDropTargetUC(this.appObject);\n makeLabelDropCorrectAnimationUC(this.appObject);\n makeLabelDropOnNothingAnimationUC(this.appObject);\n makeLabelDropIncorrectAnimationUC(this.appObject);\n makeValidateLabelDrop(this.appObject);\n }\n\n /**\n * Sets up all presentation models for the LabelDrop Feature.\n *\n * Initializes all 6 presentation models that handle the view logic and\n * state management for UI components related to the label drop feature.\n * These PMs manage the reactive data flow between the domain layer and UI.\n *\n * Presentation Models created:\n * - LabelDropEditingIDPM: Manages the currently editing label drop ID\n * - RemainingLabelDropListPM: Tracks remaining label drops to be placed\n * - LabelDropReviewPM: Handles review mode presentation logic\n * - Transform3DPM: Manages 3D transform presentation for the feature\n * - LabelDropDragItemPM: Handles drag item presentation state\n * - LabelDropListPM: Manages the overall list of label drops\n */\n setupPMs(): void {\n // Create all Presentation Models in the same order as original\n makeLabelDropEditingIDPM(this.appObject);\n makeRemainingLabelDropListPM(this.appObject);\n makeLabelDropReviewPM(this.appObject);\n makeTransform3DPM(this.appObject);\n makeLabelDropDragItemPM(this.appObject);\n makeLabelDropListPM(this.appObject);\n }\n\n /**\n * Performs final setup operations after all components are initialized.\n *\n * This method handles:\n * - Creation of the 3 Controllers (Mouse, Touch, Stylus)\n * - External dependency resolution and configuration\n * - Transform hierarchy setup for drag operations\n * - Error handling for missing dependencies\n *\n * Controllers created:\n * - MouseLabelDropAuthor: Handles mouse-based label drop interactions\n * - TouchLabelDropAuthor: Handles touch-based label drop interactions\n * - StylusLabelDrop: Handles stylus-based label drop interactions\n *\n * External dependencies:\n * - StylusEntity: Required for stylus-based interactions and drag helper positioning\n * - ZSpaceEntity: Required for zSpace display integration and drag label positioning\n */\n finalSetup(): void {\n const challengeEntity = ChallengeEntity.get(this.appObjects);\n if (challengeEntity && this.labelDropEntity) {\n challengeEntity.registerChallenge(this.labelDropEntity);\n }\n\n // Create Controllers\n makeMouseLabelDropAuthor(this.appObject);\n makeTouchLabelDropAuthor(this.appObject);\n\n if (this.appObjects.hasSingleton(StylusEntity.type)) {\n makeStylusLabelDrop(this.appObject);\n }\n }\n}\n\n/**\n * Factory function to create a new LabelDropFeatureFactory.\n *\n * This function follows the same pattern as the original setupLabelDrop function\n * by taking an AppObjectRepo and creating the \"LabelDrop\" AppObject internally.\n * The factory provides the same functionality as the original setupLabelDrop function\n * but follows the Clean Architecture pattern and can be composed with other factories.\n *\n * @param appObjectRepo The AppObjectRepo to create the LabelDrop AppObject from\n * @returns A new LabelDropFeatureFactory instance\n */\nexport function makeLabelDropFeatureFactory(\n appObjectRepo: AppObjectRepo,\n): LabelDropFeatureFactory {\n const appObject = appObjectRepo.getOrCreate(\"LabelDrop\");\n return new LabelDropFeatureFactory(appObject);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"LabelDropFeatureFactory.js","sourceRoot":"","sources":["../../../../src/LabelDrop/Factories/LabelDropFeatureFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n DomainFactory,\r\n AppObject,\r\n AppObjectRepo,\r\n Quaternion,\r\n Vector3,\r\n} from \"@vived/core\";\r\nimport { StylusEntity } from \"../../Stylus\";\r\nimport { makeTransform3DPM } from \"../../Transform3D\";\r\nimport { ZSpaceEntity } from \"../../zSpace\";\r\nimport {\r\n makeMouseLabelDropAuthor,\r\n makeStylusLabelDrop,\r\n makeTouchLabelDropAuthor,\r\n} from \"../Controller\";\r\nimport { makeLabelDropRepo } from \"../Entities\";\r\nimport {\r\n makeLabelDropDragItemPM,\r\n makeLabelDropEditingIDPM,\r\n makeLabelDropListPM,\r\n makeLabelDropReviewPM,\r\n makeRemainingLabelDropListPM,\r\n} from \"../PM\";\r\nimport {\r\n ClearEditingLabelDropUCHook,\r\n makeDeleteAllLabelDropUC,\r\n makeDeleteLabelDropUC,\r\n makeDragLabelDropUC,\r\n makeDragLabelDropWorldUC,\r\n makeEditLabelDropUC,\r\n makeLabelDropCorrectAnimationUC,\r\n makeLabelDropIncorrectAnimationUC,\r\n makeLabelDropOnNothingAnimationUC,\r\n makeSubmitLabelDropResultUC,\r\n makeToggleLabelDropTargetUC,\r\n makeValidateLabelDrop,\r\n SerializeLabelDrop,\r\n} from \"../UseCases\";\r\nimport { makeLabelDropItemFactory } from \"./labelDropItemFactory\";\r\nimport { LabelDropRepo } from \"../Entities\";\r\nimport { ChallengeEntity } from \"../../Challenge\";\r\n\r\n/**\r\n * Factory responsible for setting up the LabelDrop Feature domain components.\r\n *\r\n * This factory initializes all entities, use cases, presentation models, and controllers\r\n * required for the LabelDrop Feature functionality. It follows the domain-driven\r\n * design pattern by organizing components into their respective layers. This factory\r\n * replaces the complex setupLabelDrop function while maintaining backwards compatibility.\r\n *\r\n * The factory creates and configures:\r\n * - 1 LabelDropRepo entity with labelDropItemFactory configuration\r\n * - 12 Use Cases for label drop operations including serialization, editing, dragging, and validation\r\n * - 6 Presentation Models for UI state management and data presentation\r\n * - 3 Controllers for mouse, touch, and stylus interactions\r\n * - External dependency management for StylusEntity and ZSpaceEntity\r\n * - Transform hierarchy setup with proper positioning and scaling\r\n *\r\n * @extends DomainFactory\r\n */\r\nexport class LabelDropFeatureFactory extends DomainFactory {\r\n factoryName = \"LabelDropFeatureFactory\";\r\n\r\n private labelDropEntity: LabelDropRepo | null = null;\r\n\r\n /**\r\n * Sets up all entities required for the LabelDrop Feature.\r\n *\r\n * Initializes the LabelDropRepo entity and configures it with the\r\n * labelDropItemFactory for creating individual label drop items.\r\n * Uses the \"LabelDrop\" AppObject that was passed to the factory constructor.\r\n */\r\n setupEntities(): void {\r\n // Create the main LabelDropRepo entity\r\n this.labelDropEntity = makeLabelDropRepo(this.appObject);\r\n\r\n // Configure the entity with the item factory\r\n this.labelDropEntity.labelDropItemFactory = makeLabelDropItemFactory(\r\n this.appObject.appObjectRepo,\r\n );\r\n }\r\n\r\n /**\r\n * Sets up all use cases for the LabelDrop Feature.\r\n *\r\n * Initializes all 12 use cases that define the business operations and\r\n * workflows available in the label drop feature. The use cases are created\r\n * in the same order as the original setupLabelDrop function to maintain\r\n * functional equivalence.\r\n *\r\n * Use Cases created:\r\n * - SerializeLabelDrop: Handles serialization of label drop data\r\n * - ClearEditingLabelDropUCHook: Manages clearing editing state\r\n * - EditLabelDropUC: Handles label drop editing operations\r\n * - DragLabelDropUC: Manages label drop dragging in screen space\r\n * - DragLabelDropWorldUC: Manages label drop dragging in world space\r\n * - DeleteLabelDropUC: Handles individual label drop deletion\r\n * - DeleteAllLabelDropUC: Handles deletion of all label drops\r\n * - ToggleLabelDropTargetUC: Manages target toggle operations\r\n * - LabelDropCorrectAnimationUC: Handles correct drop animations\r\n * - LabelDropOnNothingAnimationUC: Handles drop-on-nothing animations\r\n * - LabelDropIncorrectAnimationUC: Handles incorrect drop animations\r\n * - ValidateLabelDrop: Handles label drop validation logic\r\n */\r\n setupUCs(): void {\r\n // Create all Use Cases in the same order as original\r\n new SerializeLabelDrop(this.appObject);\r\n new ClearEditingLabelDropUCHook(this.appObject);\r\n makeEditLabelDropUC(this.appObject);\r\n makeDragLabelDropUC(this.appObject);\r\n makeDragLabelDropWorldUC(this.appObject);\r\n makeDeleteLabelDropUC(this.appObject);\r\n makeDeleteAllLabelDropUC(this.appObject);\r\n makeToggleLabelDropTargetUC(this.appObject);\r\n makeLabelDropCorrectAnimationUC(this.appObject);\r\n makeLabelDropOnNothingAnimationUC(this.appObject);\r\n makeLabelDropIncorrectAnimationUC(this.appObject);\r\n makeValidateLabelDrop(this.appObject);\r\n makeSubmitLabelDropResultUC(this.appObject);\r\n }\r\n\r\n /**\r\n * Sets up all presentation models for the LabelDrop Feature.\r\n *\r\n * Initializes all 6 presentation models that handle the view logic and\r\n * state management for UI components related to the label drop feature.\r\n * These PMs manage the reactive data flow between the domain layer and UI.\r\n *\r\n * Presentation Models created:\r\n * - LabelDropEditingIDPM: Manages the currently editing label drop ID\r\n * - RemainingLabelDropListPM: Tracks remaining label drops to be placed\r\n * - LabelDropReviewPM: Handles review mode presentation logic\r\n * - Transform3DPM: Manages 3D transform presentation for the feature\r\n * - LabelDropDragItemPM: Handles drag item presentation state\r\n * - LabelDropListPM: Manages the overall list of label drops\r\n */\r\n setupPMs(): void {\r\n // Create all Presentation Models in the same order as original\r\n makeLabelDropEditingIDPM(this.appObject);\r\n makeRemainingLabelDropListPM(this.appObject);\r\n makeLabelDropReviewPM(this.appObject);\r\n makeTransform3DPM(this.appObject);\r\n makeLabelDropDragItemPM(this.appObject);\r\n makeLabelDropListPM(this.appObject);\r\n }\r\n\r\n /**\r\n * Performs final setup operations after all components are initialized.\r\n *\r\n * This method handles:\r\n * - Creation of the 3 Controllers (Mouse, Touch, Stylus)\r\n * - External dependency resolution and configuration\r\n * - Transform hierarchy setup for drag operations\r\n * - Error handling for missing dependencies\r\n *\r\n * Controllers created:\r\n * - MouseLabelDropAuthor: Handles mouse-based label drop interactions\r\n * - TouchLabelDropAuthor: Handles touch-based label drop interactions\r\n * - StylusLabelDrop: Handles stylus-based label drop interactions\r\n *\r\n * External dependencies:\r\n * - StylusEntity: Required for stylus-based interactions and drag helper positioning\r\n * - ZSpaceEntity: Required for zSpace display integration and drag label positioning\r\n */\r\n finalSetup(): void {\r\n const challengeEntity = ChallengeEntity.get(this.appObjects);\r\n if (challengeEntity && this.labelDropEntity) {\r\n challengeEntity.registerChallenge(this.labelDropEntity);\r\n }\r\n\r\n // Create Controllers\r\n makeMouseLabelDropAuthor(this.appObject);\r\n makeTouchLabelDropAuthor(this.appObject);\r\n\r\n if (this.appObjects.hasSingleton(StylusEntity.type)) {\r\n makeStylusLabelDrop(this.appObject);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create a new LabelDropFeatureFactory.\r\n *\r\n * This function follows the same pattern as the original setupLabelDrop function\r\n * by taking an AppObjectRepo and creating the \"LabelDrop\" AppObject internally.\r\n * The factory provides the same functionality as the original setupLabelDrop function\r\n * but follows the Clean Architecture pattern and can be composed with other factories.\r\n *\r\n * @param appObjectRepo The AppObjectRepo to create the LabelDrop AppObject from\r\n * @returns A new LabelDropFeatureFactory instance\r\n */\r\nexport function makeLabelDropFeatureFactory(\r\n appObjectRepo: AppObjectRepo,\r\n): LabelDropFeatureFactory {\r\n const appObject = appObjectRepo.getOrCreate(\"LabelDrop\");\r\n return new LabelDropFeatureFactory(appObject);\r\n}\r\n"]}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SubmitLabelDropResultUC = void 0;
|
|
4
|
+
exports.makeSubmitLabelDropResultUC = makeSubmitLabelDropResultUC;
|
|
5
|
+
const core_1 = require("@vived/core");
|
|
6
|
+
const BaseApp_1 = require("../../BaseApp");
|
|
7
|
+
const Challenge_1 = require("../../Challenge");
|
|
8
|
+
const Dispatcher_1 = require("../../Dispatcher");
|
|
9
|
+
const Entities_1 = require("../Entities");
|
|
10
|
+
/**
|
|
11
|
+
* Submits a Label Drop challenge result to the Host as a MULTIHIT result.
|
|
12
|
+
*
|
|
13
|
+
* Mirrors the other challenge submitters (TrySubmitObjectPickUC, SubmitQuestionAnswerUC):
|
|
14
|
+
* consumption-mode only, and only while Label Drop is the selected challenge. It observes
|
|
15
|
+
* every Label Drop submission and reports the running tally, so a partial attempt is scored
|
|
16
|
+
* on slide exit (the Host's MULTIHIT best-hits rule keeps the strongest result). See
|
|
17
|
+
* docs/prd/label-drop-result.md.
|
|
18
|
+
*
|
|
19
|
+
* Tally: hits = items answered correctly; unanswered = items not yet correct
|
|
20
|
+
* (getRemainingLabelDrops); misses = total tries - hits (each hit's final try is the one
|
|
21
|
+
* correct drop, so every other object-drop was wrong); description = the slide's text.
|
|
22
|
+
*/
|
|
23
|
+
class SubmitLabelDropResultUC extends core_1.AppObjectUC {
|
|
24
|
+
static get(appObjects) {
|
|
25
|
+
return (0, core_1.getSingletonComponent)(SubmitLabelDropResultUC.type, appObjects);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.SubmitLabelDropResultUC = SubmitLabelDropResultUC;
|
|
29
|
+
SubmitLabelDropResultUC.type = "SubmitLabelDropResultUC";
|
|
30
|
+
function makeSubmitLabelDropResultUC(appObject) {
|
|
31
|
+
return new SubmitLabelDropResultUCImp(appObject);
|
|
32
|
+
}
|
|
33
|
+
class SubmitLabelDropResultUCImp extends SubmitLabelDropResultUC {
|
|
34
|
+
get repo() {
|
|
35
|
+
return this.getCachedSingleton(Entities_1.LabelDropRepo.type);
|
|
36
|
+
}
|
|
37
|
+
get baseApp() {
|
|
38
|
+
return this.getCachedSingleton(BaseApp_1.BaseAppState.type);
|
|
39
|
+
}
|
|
40
|
+
get challenge() {
|
|
41
|
+
return this.getCachedSingleton(Challenge_1.ChallengeEntity.type);
|
|
42
|
+
}
|
|
43
|
+
constructor(appObject) {
|
|
44
|
+
super(appObject, SubmitLabelDropResultUC.type);
|
|
45
|
+
this.onSubmission = () => {
|
|
46
|
+
this.submitResult();
|
|
47
|
+
};
|
|
48
|
+
this.submitResult = () => {
|
|
49
|
+
const repo = this.repo;
|
|
50
|
+
const baseApp = this.baseApp;
|
|
51
|
+
const challenge = this.challenge;
|
|
52
|
+
if (!repo || !baseApp || !challenge)
|
|
53
|
+
return;
|
|
54
|
+
if (baseApp.isAuthoring)
|
|
55
|
+
return;
|
|
56
|
+
if (challenge.selectedChallenge !== "LABEL_DROP")
|
|
57
|
+
return;
|
|
58
|
+
const items = repo.getAll();
|
|
59
|
+
const hits = items.filter((item) => item.answeredCorrectly === true).length;
|
|
60
|
+
const unanswered = repo.getRemainingLabelDrops().length;
|
|
61
|
+
const totalTries = items.reduce((sum, item) => sum + item.tries, 0);
|
|
62
|
+
const misses = totalTries - hits;
|
|
63
|
+
(0, Dispatcher_1.submitMultiHitResult)({
|
|
64
|
+
hits,
|
|
65
|
+
misses,
|
|
66
|
+
unanswered,
|
|
67
|
+
description: baseApp.slideText,
|
|
68
|
+
}, this.appObjects);
|
|
69
|
+
};
|
|
70
|
+
this.appObjects.registerSingleton(this);
|
|
71
|
+
const repo = Entities_1.LabelDropRepo.get(this.appObjects);
|
|
72
|
+
if (repo) {
|
|
73
|
+
repo.addLabelDropSubmissionObserver(this.onSubmission);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
this.warn("SubmitLabelDropResultUC has been set up without a LabelDropRepo to observe");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=SubmitLabelDropResultUC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubmitLabelDropResultUC.js","sourceRoot":"","sources":["../../../../src/LabelDrop/UseCases/SubmitLabelDropResultUC.ts"],"names":[],"mappings":";;;AAqCA,kEAIC;AAzCD,sCAKqB;AACrB,2CAA6C;AAC7C,+CAAkD;AAClD,iDAAwD;AACxD,0CAA4C;AAE5C;;;;;;;;;;;;GAYG;AACH,MAAsB,uBAAwB,SAAQ,kBAAW;IAK/D,MAAM,CAAC,GAAG,CAAC,UAAyB;QAClC,OAAO,IAAA,4BAAqB,EAC1B,uBAAuB,CAAC,IAAI,EAC5B,UAAU,CACX,CAAC;IACJ,CAAC;;AAVH,0DAWC;AAViB,4BAAI,GAAG,yBAAyB,CAAC;AAYnD,SAAgB,2BAA2B,CACzC,SAAoB;IAEpB,OAAO,IAAI,0BAA0B,CAAC,SAAS,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,0BAA2B,SAAQ,uBAAuB;IAC9D,IAAY,IAAI;QACd,OAAO,IAAI,CAAC,kBAAkB,CAAgB,wBAAa,CAAC,IAAI,CAAC,CAAC;IACpE,CAAC;IAED,IAAY,OAAO;QACjB,OAAO,IAAI,CAAC,kBAAkB,CAAe,sBAAY,CAAC,IAAI,CAAC,CAAC;IAClE,CAAC;IAED,IAAY,SAAS;QACnB,OAAO,IAAI,CAAC,kBAAkB,CAAkB,2BAAe,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC;IAkCD,YAAY,SAAoB;QAC9B,KAAK,CAAC,SAAS,EAAE,uBAAuB,CAAC,IAAI,CAAC,CAAC;QAjCzC,iBAAY,GAAG,GAAS,EAAE;YAChC,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC,CAAC;QAEF,iBAAY,GAAG,GAAS,EAAE;YACxB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YACvB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;YAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;YACjC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS;gBAAE,OAAO;YAE5C,IAAI,OAAO,CAAC,WAAW;gBAAE,OAAO;YAChC,IAAI,SAAS,CAAC,iBAAiB,KAAK,YAAY;gBAAE,OAAO;YAEzD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CACvB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,KAAK,IAAI,CAC1C,CAAC,MAAM,CAAC;YACT,MAAM,UAAU,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC,MAAM,CAAC;YACxD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACpE,MAAM,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;YAEjC,IAAA,iCAAoB,EAClB;gBACE,IAAI;gBACJ,MAAM;gBACN,UAAU;gBACV,WAAW,EAAE,OAAO,CAAC,SAAS;aAC/B,EACD,IAAI,CAAC,UAAU,CAChB,CAAC;QACJ,CAAC,CAAC;QAIA,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAExC,MAAM,IAAI,GAAG,wBAAa,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CACP,4EAA4E,CAC7E,CAAC;QACJ,CAAC;IACH,CAAC;CACF","sourcesContent":["import {\r\n AppObject,\r\n AppObjectRepo,\r\n AppObjectUC,\r\n getSingletonComponent,\r\n} from \"@vived/core\";\r\nimport { BaseAppState } from \"../../BaseApp\";\r\nimport { ChallengeEntity } from \"../../Challenge\";\r\nimport { submitMultiHitResult } from \"../../Dispatcher\";\r\nimport { LabelDropRepo } from \"../Entities\";\r\n\r\n/**\r\n * Submits a Label Drop challenge result to the Host as a MULTIHIT result.\r\n *\r\n * Mirrors the other challenge submitters (TrySubmitObjectPickUC, SubmitQuestionAnswerUC):\r\n * consumption-mode only, and only while Label Drop is the selected challenge. It observes\r\n * every Label Drop submission and reports the running tally, so a partial attempt is scored\r\n * on slide exit (the Host's MULTIHIT best-hits rule keeps the strongest result). See\r\n * docs/prd/label-drop-result.md.\r\n *\r\n * Tally: hits = items answered correctly; unanswered = items not yet correct\r\n * (getRemainingLabelDrops); misses = total tries - hits (each hit's final try is the one\r\n * correct drop, so every other object-drop was wrong); description = the slide's text.\r\n */\r\nexport abstract class SubmitLabelDropResultUC extends AppObjectUC {\r\n static readonly type = \"SubmitLabelDropResultUC\";\r\n\r\n abstract submitResult(): void;\r\n\r\n static get(appObjects: AppObjectRepo) {\r\n return getSingletonComponent<SubmitLabelDropResultUC>(\r\n SubmitLabelDropResultUC.type,\r\n appObjects,\r\n );\r\n }\r\n}\r\n\r\nexport function makeSubmitLabelDropResultUC(\r\n appObject: AppObject,\r\n): SubmitLabelDropResultUC {\r\n return new SubmitLabelDropResultUCImp(appObject);\r\n}\r\n\r\nclass SubmitLabelDropResultUCImp extends SubmitLabelDropResultUC {\r\n private get repo() {\r\n return this.getCachedSingleton<LabelDropRepo>(LabelDropRepo.type);\r\n }\r\n\r\n private get baseApp() {\r\n return this.getCachedSingleton<BaseAppState>(BaseAppState.type);\r\n }\r\n\r\n private get challenge() {\r\n return this.getCachedSingleton<ChallengeEntity>(ChallengeEntity.type);\r\n }\r\n\r\n private onSubmission = (): void => {\r\n this.submitResult();\r\n };\r\n\r\n submitResult = (): void => {\r\n const repo = this.repo;\r\n const baseApp = this.baseApp;\r\n const challenge = this.challenge;\r\n if (!repo || !baseApp || !challenge) return;\r\n\r\n if (baseApp.isAuthoring) return;\r\n if (challenge.selectedChallenge !== \"LABEL_DROP\") return;\r\n\r\n const items = repo.getAll();\r\n const hits = items.filter(\r\n (item) => item.answeredCorrectly === true,\r\n ).length;\r\n const unanswered = repo.getRemainingLabelDrops().length;\r\n const totalTries = items.reduce((sum, item) => sum + item.tries, 0);\r\n const misses = totalTries - hits;\r\n\r\n submitMultiHitResult(\r\n {\r\n hits,\r\n misses,\r\n unanswered,\r\n description: baseApp.slideText,\r\n },\r\n this.appObjects,\r\n );\r\n };\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, SubmitLabelDropResultUC.type);\r\n this.appObjects.registerSingleton(this);\r\n\r\n const repo = LabelDropRepo.get(this.appObjects);\r\n if (repo) {\r\n repo.addLabelDropSubmissionObserver(this.onSubmission);\r\n } else {\r\n this.warn(\r\n \"SubmitLabelDropResultUC has been set up without a LabelDropRepo to observe\",\r\n );\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@vived/core");
|
|
4
|
+
const BaseAppState_1 = require("../../BaseApp/Entity/BaseAppState");
|
|
5
|
+
const Challenge_1 = require("../../Challenge");
|
|
6
|
+
const Dispatcher_1 = require("../../Dispatcher");
|
|
7
|
+
const Entities_1 = require("../Entities");
|
|
8
|
+
const LabelDropFeatureFactory_1 = require("../Factories/LabelDropFeatureFactory");
|
|
9
|
+
const SubmitLabelDropResultUC_1 = require("./SubmitLabelDropResultUC");
|
|
10
|
+
describe("SubmitLabelDropResultUC", () => {
|
|
11
|
+
it("Registers as the singleton", () => {
|
|
12
|
+
const appObjects = (0, core_1.makeAppObjectRepo)();
|
|
13
|
+
(0, Entities_1.makeLabelDropRepo)(appObjects.getOrCreate("LabelDrop"));
|
|
14
|
+
const uc = (0, SubmitLabelDropResultUC_1.makeSubmitLabelDropResultUC)(appObjects.getOrCreate("LabelDrop"));
|
|
15
|
+
expect(SubmitLabelDropResultUC_1.SubmitLabelDropResultUC.get(appObjects)).toBe(uc);
|
|
16
|
+
});
|
|
17
|
+
// Wiring / lifecycle: prove the real LabelDropFeatureFactory constructs the UC and hooks
|
|
18
|
+
// the drop observer. Uses the repo's factory-test idiom (drive the phases directly) rather
|
|
19
|
+
// than a full setupDomain — finalSetup wires pointer controllers that pull in the input /
|
|
20
|
+
// framework cluster, which is irrelevant to this UC's wiring.
|
|
21
|
+
it("is wired by LabelDropFeatureFactory.setupUCs so a drop reports a result to the Host", () => {
|
|
22
|
+
const appObjects = (0, core_1.makeAppObjectRepo)();
|
|
23
|
+
// Boundary singletons the feature's UCs read at construction time.
|
|
24
|
+
const baseApp = (0, BaseAppState_1.makeBaseAppState)(appObjects.getOrCreate("App"));
|
|
25
|
+
baseApp.isAuthoring = false;
|
|
26
|
+
baseApp.slideText = "Slide text";
|
|
27
|
+
const challenge = (0, Challenge_1.makeChallengeEntityMock)(appObjects);
|
|
28
|
+
challenge.selectedChallenge = "LABEL_DROP";
|
|
29
|
+
const mockSubmitResult = (0, Dispatcher_1.makeMockSubmitResult)(appObjects);
|
|
30
|
+
mockSubmitResult.submitMultiHitResult = jest.fn();
|
|
31
|
+
const factory = (0, LabelDropFeatureFactory_1.makeLabelDropFeatureFactory)(appObjects);
|
|
32
|
+
factory.setupEntities(); // creates LabelDropRepo
|
|
33
|
+
factory.setupUCs(); // creates SubmitLabelDropResultUC, which subscribes to the repo
|
|
34
|
+
const repo = Entities_1.LabelDropRepo.get(appObjects);
|
|
35
|
+
const item = repo.makeLabelDropItem("a");
|
|
36
|
+
item.targetIds = ["objA"];
|
|
37
|
+
repo.submitLabelDrop("a", "objA");
|
|
38
|
+
expect(mockSubmitResult.submitMultiHitResult).toHaveBeenCalledWith({
|
|
39
|
+
hits: 1,
|
|
40
|
+
misses: 0,
|
|
41
|
+
unanswered: 0,
|
|
42
|
+
description: "Slide text",
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=SubmitLabelDropResultUC.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubmitLabelDropResultUC.test.js","sourceRoot":"","sources":["../../../../src/LabelDrop/UseCases/SubmitLabelDropResultUC.test.ts"],"names":[],"mappings":";;AAAA,sCAAgD;AAChD,oEAAqE;AACrE,+CAA0D;AAC1D,iDAAwD;AACxD,0CAA+D;AAC/D,kFAAmF;AACnF,uEAGmC;AAEnC,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,UAAU,GAAG,IAAA,wBAAiB,GAAE,CAAC;QACvC,IAAA,4BAAiB,EAAC,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;QACvD,MAAM,EAAE,GAAG,IAAA,qDAA2B,EAAC,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;QAE5E,MAAM,CAAC,iDAAuB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,yFAAyF;IACzF,2FAA2F;IAC3F,0FAA0F;IAC1F,8DAA8D;IAC9D,EAAE,CAAC,qFAAqF,EAAE,GAAG,EAAE;QAC7F,MAAM,UAAU,GAAG,IAAA,wBAAiB,GAAE,CAAC;QAEvC,mEAAmE;QACnE,MAAM,OAAO,GAAG,IAAA,+BAAgB,EAAC,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC;QAC5B,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC;QAEjC,MAAM,SAAS,GAAG,IAAA,mCAAuB,EAAC,UAAU,CAAC,CAAC;QACtD,SAAS,CAAC,iBAAiB,GAAG,YAAY,CAAC;QAE3C,MAAM,gBAAgB,GAAG,IAAA,iCAAoB,EAAC,UAAU,CAAC,CAAC;QAC1D,gBAAgB,CAAC,oBAAoB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAElD,MAAM,OAAO,GAAG,IAAA,qDAA2B,EAAC,UAAU,CAAC,CAAC;QACxD,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,wBAAwB;QACjD,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,gEAAgE;QAEpF,MAAM,IAAI,GAAG,wBAAa,CAAC,GAAG,CAAC,UAAU,CAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,CAAC;QAE1B,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAElC,MAAM,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAAC,oBAAoB,CAAC;YACjE,IAAI,EAAE,CAAC;YACP,MAAM,EAAE,CAAC;YACT,UAAU,EAAE,CAAC;YACb,WAAW,EAAE,YAAY;SAC1B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { makeAppObjectRepo } from \"@vived/core\";\r\nimport { makeBaseAppState } from \"../../BaseApp/Entity/BaseAppState\";\r\nimport { makeChallengeEntityMock } from \"../../Challenge\";\r\nimport { makeMockSubmitResult } from \"../../Dispatcher\";\r\nimport { LabelDropRepo, makeLabelDropRepo } from \"../Entities\";\r\nimport { makeLabelDropFeatureFactory } from \"../Factories/LabelDropFeatureFactory\";\r\nimport {\r\n makeSubmitLabelDropResultUC,\r\n SubmitLabelDropResultUC,\r\n} from \"./SubmitLabelDropResultUC\";\r\n\r\ndescribe(\"SubmitLabelDropResultUC\", () => {\r\n it(\"Registers as the singleton\", () => {\r\n const appObjects = makeAppObjectRepo();\r\n makeLabelDropRepo(appObjects.getOrCreate(\"LabelDrop\"));\r\n const uc = makeSubmitLabelDropResultUC(appObjects.getOrCreate(\"LabelDrop\"));\r\n\r\n expect(SubmitLabelDropResultUC.get(appObjects)).toBe(uc);\r\n });\r\n\r\n // Wiring / lifecycle: prove the real LabelDropFeatureFactory constructs the UC and hooks\r\n // the drop observer. Uses the repo's factory-test idiom (drive the phases directly) rather\r\n // than a full setupDomain — finalSetup wires pointer controllers that pull in the input /\r\n // framework cluster, which is irrelevant to this UC's wiring.\r\n it(\"is wired by LabelDropFeatureFactory.setupUCs so a drop reports a result to the Host\", () => {\r\n const appObjects = makeAppObjectRepo();\r\n\r\n // Boundary singletons the feature's UCs read at construction time.\r\n const baseApp = makeBaseAppState(appObjects.getOrCreate(\"App\"));\r\n baseApp.isAuthoring = false;\r\n baseApp.slideText = \"Slide text\";\r\n\r\n const challenge = makeChallengeEntityMock(appObjects);\r\n challenge.selectedChallenge = \"LABEL_DROP\";\r\n\r\n const mockSubmitResult = makeMockSubmitResult(appObjects);\r\n mockSubmitResult.submitMultiHitResult = jest.fn();\r\n\r\n const factory = makeLabelDropFeatureFactory(appObjects);\r\n factory.setupEntities(); // creates LabelDropRepo\r\n factory.setupUCs(); // creates SubmitLabelDropResultUC, which subscribes to the repo\r\n\r\n const repo = LabelDropRepo.get(appObjects)!;\r\n const item = repo.makeLabelDropItem(\"a\");\r\n item.targetIds = [\"objA\"];\r\n\r\n repo.submitLabelDrop(\"a\", \"objA\");\r\n\r\n expect(mockSubmitResult.submitMultiHitResult).toHaveBeenCalledWith({\r\n hits: 1,\r\n misses: 0,\r\n unanswered: 0,\r\n description: \"Slide text\",\r\n });\r\n });\r\n});\r\n"]}
|
|
@@ -26,6 +26,7 @@ __exportStar(require("./IncorrectAnimationUC"), exports);
|
|
|
26
26
|
__exportStar(require("./InitializeLabelDropLabelHook"), exports);
|
|
27
27
|
__exportStar(require("./LabelDropAnimation"), exports);
|
|
28
28
|
__exportStar(require("./SerializeLabelDrop"), exports);
|
|
29
|
+
__exportStar(require("./SubmitLabelDropResultUC"), exports);
|
|
29
30
|
__exportStar(require("./ToggleLabelDropTargetUC"), exports);
|
|
30
31
|
__exportStar(require("./ValidateLabelDrop"), exports);
|
|
31
32
|
__exportStar(require("./labelDropLabelValidator"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/LabelDrop/UseCases/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gEAA8C;AAC9C,uDAAqC;AACrC,yDAAuC;AACvC,sDAAoC;AACpC,oDAAkC;AAClC,yDAAuC;AACvC,6DAA2C;AAC3C,oDAAkC;AAClC,yDAAuC;AACvC,iEAA+C;AAC/C,uDAAqC;AACrC,uDAAqC;AACrC,4DAA0C;AAC1C,sDAAoC;AACpC,4DAA0C","sourcesContent":["export * from \"./ClearEditingLabelDropUCHook\";\nexport * from \"./CorrectAnimationUC\";\nexport * from \"./DeleteAllLabelDropUC\";\nexport * from \"./DeleteLabelDropUC\";\nexport * from \"./DragLabelDropUC\";\nexport * from \"./DragLabelDropWorldUC\";\nexport * from \"./DropOnNothingAnimationUC\";\nexport * from \"./EditLabelDropUC\";\nexport * from \"./IncorrectAnimationUC\";\nexport * from \"./InitializeLabelDropLabelHook\";\nexport * from \"./LabelDropAnimation\";\nexport * from \"./SerializeLabelDrop\";\nexport * from \"./ToggleLabelDropTargetUC\";\nexport * from \"./ValidateLabelDrop\";\nexport * from \"./labelDropLabelValidator\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/LabelDrop/UseCases/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gEAA8C;AAC9C,uDAAqC;AACrC,yDAAuC;AACvC,sDAAoC;AACpC,oDAAkC;AAClC,yDAAuC;AACvC,6DAA2C;AAC3C,oDAAkC;AAClC,yDAAuC;AACvC,iEAA+C;AAC/C,uDAAqC;AACrC,uDAAqC;AACrC,4DAA0C;AAC1C,4DAA0C;AAC1C,sDAAoC;AACpC,4DAA0C","sourcesContent":["export * from \"./ClearEditingLabelDropUCHook\";\r\nexport * from \"./CorrectAnimationUC\";\r\nexport * from \"./DeleteAllLabelDropUC\";\r\nexport * from \"./DeleteLabelDropUC\";\r\nexport * from \"./DragLabelDropUC\";\r\nexport * from \"./DragLabelDropWorldUC\";\r\nexport * from \"./DropOnNothingAnimationUC\";\r\nexport * from \"./EditLabelDropUC\";\r\nexport * from \"./IncorrectAnimationUC\";\r\nexport * from \"./InitializeLabelDropLabelHook\";\r\nexport * from \"./LabelDropAnimation\";\r\nexport * from \"./SerializeLabelDrop\";\r\nexport * from \"./SubmitLabelDropResultUC\";\r\nexport * from \"./ToggleLabelDropTargetUC\";\r\nexport * from \"./ValidateLabelDrop\";\r\nexport * from \"./labelDropLabelValidator\";\r\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./setupFeatureForTesting"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/TestUtils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2DAAyC","sourcesContent":["export * from \"./setupFeatureForTesting\";\r\n"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* setupFeatureForTesting.ts
|
|
4
|
+
*
|
|
5
|
+
* The feature-context test harness for this Feature Library.
|
|
6
|
+
*
|
|
7
|
+
* This package has no app-level domain (no `makeDomain`, no single repo), so there is no
|
|
8
|
+
* global "make the domain" harness. The unit of test context is a **Feature** (or a small
|
|
9
|
+
* cluster of Features), wired the way a Slide App wires it — through each Feature's
|
|
10
|
+
* `FeatureFactory` (the current standard), using the same phased orchestration production
|
|
11
|
+
* uses. See `CLAUDE.md` and `docs/agents/domain.md`.
|
|
12
|
+
*
|
|
13
|
+
* Use this for **wiring / lifecycle** tests — proving that a Feature, once really wired,
|
|
14
|
+
* behaves end-to-end (e.g. a Challenge submits its result when the student leaves the slide).
|
|
15
|
+
* For pure **logic** tests of a single UC or PM, a hand-wired `makeAppObjectRepo()` rig with
|
|
16
|
+
* the collaborators mocked at the boundary is lighter and still preferred — see
|
|
17
|
+
* `src/ObjectPick/UseCases/TrySubmitObjectPickUC.test.ts` as the reference.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // LabelDrop's submit path depends on Challenge (for `selectedChallenge`) and the
|
|
21
|
+
* // Dispatcher (the Host boundary). List dependencies first, exactly as a Slide App would.
|
|
22
|
+
* const { appObjects } = setupFeatureForTesting([
|
|
23
|
+
* makeDispatcherFeatureFactory,
|
|
24
|
+
* makeChallengeFeatureFactory,
|
|
25
|
+
* makeLabelDropFeatureFactory,
|
|
26
|
+
* ]);
|
|
27
|
+
* // Then act through a Controller / navigation seam and assert through an Adapter VM or a
|
|
28
|
+
* // dispatcher mock registered before setup.
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.setupFeatureForTesting = setupFeatureForTesting;
|
|
32
|
+
const core_1 = require("@vived/core");
|
|
33
|
+
/**
|
|
34
|
+
* Wire one or more Features into a fresh repo for a feature-context test.
|
|
35
|
+
*
|
|
36
|
+
* @param featureFactories The `make<Feature>FeatureFactory` functions to wire, in the order a
|
|
37
|
+
* Slide App would compose them — a Feature whose `finalSetup` depends on another Feature's
|
|
38
|
+
* entities must be listed *after* that Feature.
|
|
39
|
+
* @param seed Optional callback run *before* the factories are constructed. Use it to stand up
|
|
40
|
+
* the boundary singletons a Feature reads at construction time (many Feature UCs resolve
|
|
41
|
+
* siblings via `getCachedSingleton`, which THROWS when absent — e.g. `BaseAppState`,
|
|
42
|
+
* `ChallengeEntity`). Seed real entities or their Mocks here instead of pulling every
|
|
43
|
+
* dependency Feature's factory into the cluster.
|
|
44
|
+
* @returns `{ appObjects }` — resolve Controllers and Adapters from it to act and assert.
|
|
45
|
+
*/
|
|
46
|
+
function setupFeatureForTesting(featureFactories, seed) {
|
|
47
|
+
const appObjects = (0, core_1.makeAppObjectRepo)();
|
|
48
|
+
// The DomainFactoryRepo must exist before the factories are constructed: each
|
|
49
|
+
// FeatureFactory auto-registers with it in its constructor.
|
|
50
|
+
const factoryRepo = (0, core_1.makeDomainFactoryRepo)(appObjects);
|
|
51
|
+
// Stand up boundary singletons the Features read at construction time.
|
|
52
|
+
if (seed)
|
|
53
|
+
seed(appObjects);
|
|
54
|
+
featureFactories.forEach((makeFactory) => makeFactory(appObjects));
|
|
55
|
+
// Run the same phased orchestration as production — all setupEntities, then all setupUCs,
|
|
56
|
+
// then all setupPMs, then all finalSetup — so cross-Feature dependencies resolve correctly.
|
|
57
|
+
factoryRepo.setupDomain();
|
|
58
|
+
return { appObjects };
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=setupFeatureForTesting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupFeatureForTesting.js","sourceRoot":"","sources":["../../../src/TestUtils/setupFeatureForTesting.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;AA2BH,wDAoBC;AA7CD,sCAKqB;AAOrB;;;;;;;;;;;;GAYG;AACH,SAAgB,sBAAsB,CACpC,gBAAkE,EAClE,IAA0C;IAE1C,MAAM,UAAU,GAAG,IAAA,wBAAiB,GAAE,CAAC;IAEvC,8EAA8E;IAC9E,4DAA4D;IAC5D,MAAM,WAAW,GAAG,IAAA,4BAAqB,EAAC,UAAU,CAAC,CAAC;IAEtD,uEAAuE;IACvE,IAAI,IAAI;QAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAE3B,gBAAgB,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;IAEnE,0FAA0F;IAC1F,4FAA4F;IAC5F,WAAW,CAAC,WAAW,EAAE,CAAC;IAE1B,OAAO,EAAE,UAAU,EAAE,CAAC;AACxB,CAAC","sourcesContent":["/**\r\n * setupFeatureForTesting.ts\r\n *\r\n * The feature-context test harness for this Feature Library.\r\n *\r\n * This package has no app-level domain (no `makeDomain`, no single repo), so there is no\r\n * global \"make the domain\" harness. The unit of test context is a **Feature** (or a small\r\n * cluster of Features), wired the way a Slide App wires it — through each Feature's\r\n * `FeatureFactory` (the current standard), using the same phased orchestration production\r\n * uses. See `CLAUDE.md` and `docs/agents/domain.md`.\r\n *\r\n * Use this for **wiring / lifecycle** tests — proving that a Feature, once really wired,\r\n * behaves end-to-end (e.g. a Challenge submits its result when the student leaves the slide).\r\n * For pure **logic** tests of a single UC or PM, a hand-wired `makeAppObjectRepo()` rig with\r\n * the collaborators mocked at the boundary is lighter and still preferred — see\r\n * `src/ObjectPick/UseCases/TrySubmitObjectPickUC.test.ts` as the reference.\r\n *\r\n * @example\r\n * // LabelDrop's submit path depends on Challenge (for `selectedChallenge`) and the\r\n * // Dispatcher (the Host boundary). List dependencies first, exactly as a Slide App would.\r\n * const { appObjects } = setupFeatureForTesting([\r\n * makeDispatcherFeatureFactory,\r\n * makeChallengeFeatureFactory,\r\n * makeLabelDropFeatureFactory,\r\n * ]);\r\n * // Then act through a Controller / navigation seam and assert through an Adapter VM or a\r\n * // dispatcher mock registered before setup.\r\n */\r\n\r\nimport {\r\n AppObjectRepo,\r\n DomainFactory,\r\n makeAppObjectRepo,\r\n makeDomainFactoryRepo,\r\n} from \"@vived/core\";\r\n\r\nexport interface FeatureTestContext {\r\n /** The live repo, wired through the given FeatureFactories exactly as production does. */\r\n appObjects: AppObjectRepo;\r\n}\r\n\r\n/**\r\n * Wire one or more Features into a fresh repo for a feature-context test.\r\n *\r\n * @param featureFactories The `make<Feature>FeatureFactory` functions to wire, in the order a\r\n * Slide App would compose them — a Feature whose `finalSetup` depends on another Feature's\r\n * entities must be listed *after* that Feature.\r\n * @param seed Optional callback run *before* the factories are constructed. Use it to stand up\r\n * the boundary singletons a Feature reads at construction time (many Feature UCs resolve\r\n * siblings via `getCachedSingleton`, which THROWS when absent — e.g. `BaseAppState`,\r\n * `ChallengeEntity`). Seed real entities or their Mocks here instead of pulling every\r\n * dependency Feature's factory into the cluster.\r\n * @returns `{ appObjects }` — resolve Controllers and Adapters from it to act and assert.\r\n */\r\nexport function setupFeatureForTesting(\r\n featureFactories: ((appObjects: AppObjectRepo) => DomainFactory)[],\r\n seed?: (appObjects: AppObjectRepo) => void,\r\n): FeatureTestContext {\r\n const appObjects = makeAppObjectRepo();\r\n\r\n // The DomainFactoryRepo must exist before the factories are constructed: each\r\n // FeatureFactory auto-registers with it in its constructor.\r\n const factoryRepo = makeDomainFactoryRepo(appObjects);\r\n\r\n // Stand up boundary singletons the Features read at construction time.\r\n if (seed) seed(appObjects);\r\n\r\n featureFactories.forEach((makeFactory) => makeFactory(appObjects));\r\n\r\n // Run the same phased orchestration as production — all setupEntities, then all setupUCs,\r\n // then all setupPMs, then all finalSetup — so cross-Feature dependencies resolve correctly.\r\n factoryRepo.setupDomain();\r\n\r\n return { appObjects };\r\n}\r\n"]}
|
|
@@ -4,7 +4,7 @@ import { makeTransform3DPM } from "../../Transform3D";
|
|
|
4
4
|
import { makeMouseLabelDropAuthor, makeStylusLabelDrop, makeTouchLabelDropAuthor, } from "../Controller";
|
|
5
5
|
import { makeLabelDropRepo } from "../Entities";
|
|
6
6
|
import { makeLabelDropDragItemPM, makeLabelDropEditingIDPM, makeLabelDropListPM, makeLabelDropReviewPM, makeRemainingLabelDropListPM, } from "../PM";
|
|
7
|
-
import { ClearEditingLabelDropUCHook, makeDeleteAllLabelDropUC, makeDeleteLabelDropUC, makeDragLabelDropUC, makeDragLabelDropWorldUC, makeEditLabelDropUC, makeLabelDropCorrectAnimationUC, makeLabelDropIncorrectAnimationUC, makeLabelDropOnNothingAnimationUC, makeToggleLabelDropTargetUC, makeValidateLabelDrop, SerializeLabelDrop, } from "../UseCases";
|
|
7
|
+
import { ClearEditingLabelDropUCHook, makeDeleteAllLabelDropUC, makeDeleteLabelDropUC, makeDragLabelDropUC, makeDragLabelDropWorldUC, makeEditLabelDropUC, makeLabelDropCorrectAnimationUC, makeLabelDropIncorrectAnimationUC, makeLabelDropOnNothingAnimationUC, makeSubmitLabelDropResultUC, makeToggleLabelDropTargetUC, makeValidateLabelDrop, SerializeLabelDrop, } from "../UseCases";
|
|
8
8
|
import { makeLabelDropItemFactory } from "./labelDropItemFactory";
|
|
9
9
|
import { ChallengeEntity } from "../../Challenge";
|
|
10
10
|
/**
|
|
@@ -80,6 +80,7 @@ export class LabelDropFeatureFactory extends DomainFactory {
|
|
|
80
80
|
makeLabelDropOnNothingAnimationUC(this.appObject);
|
|
81
81
|
makeLabelDropIncorrectAnimationUC(this.appObject);
|
|
82
82
|
makeValidateLabelDrop(this.appObject);
|
|
83
|
+
makeSubmitLabelDropResultUC(this.appObject);
|
|
83
84
|
}
|
|
84
85
|
/**
|
|
85
86
|
* Sets up all presentation models for the LabelDrop Feature.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LabelDropFeatureFactory.js","sourceRoot":"","sources":["../../../../src/LabelDrop/Factories/LabelDropFeatureFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DomainFactory,\n AppObject,\n AppObjectRepo,\n Quaternion,\n Vector3,\n} from \"@vived/core\";\nimport { StylusEntity } from \"../../Stylus\";\nimport { makeTransform3DPM } from \"../../Transform3D\";\nimport { ZSpaceEntity } from \"../../zSpace\";\nimport {\n makeMouseLabelDropAuthor,\n makeStylusLabelDrop,\n makeTouchLabelDropAuthor,\n} from \"../Controller\";\nimport { makeLabelDropRepo } from \"../Entities\";\nimport {\n makeLabelDropDragItemPM,\n makeLabelDropEditingIDPM,\n makeLabelDropListPM,\n makeLabelDropReviewPM,\n makeRemainingLabelDropListPM,\n} from \"../PM\";\nimport {\n ClearEditingLabelDropUCHook,\n makeDeleteAllLabelDropUC,\n makeDeleteLabelDropUC,\n makeDragLabelDropUC,\n makeDragLabelDropWorldUC,\n makeEditLabelDropUC,\n makeLabelDropCorrectAnimationUC,\n makeLabelDropIncorrectAnimationUC,\n makeLabelDropOnNothingAnimationUC,\n makeToggleLabelDropTargetUC,\n makeValidateLabelDrop,\n SerializeLabelDrop,\n} from \"../UseCases\";\nimport { makeLabelDropItemFactory } from \"./labelDropItemFactory\";\nimport { LabelDropRepo } from \"../Entities\";\nimport { ChallengeEntity } from \"../../Challenge\";\n\n/**\n * Factory responsible for setting up the LabelDrop Feature domain components.\n *\n * This factory initializes all entities, use cases, presentation models, and controllers\n * required for the LabelDrop Feature functionality. It follows the domain-driven\n * design pattern by organizing components into their respective layers. This factory\n * replaces the complex setupLabelDrop function while maintaining backwards compatibility.\n *\n * The factory creates and configures:\n * - 1 LabelDropRepo entity with labelDropItemFactory configuration\n * - 12 Use Cases for label drop operations including serialization, editing, dragging, and validation\n * - 6 Presentation Models for UI state management and data presentation\n * - 3 Controllers for mouse, touch, and stylus interactions\n * - External dependency management for StylusEntity and ZSpaceEntity\n * - Transform hierarchy setup with proper positioning and scaling\n *\n * @extends DomainFactory\n */\nexport class LabelDropFeatureFactory extends DomainFactory {\n factoryName = \"LabelDropFeatureFactory\";\n\n private labelDropEntity: LabelDropRepo | null = null;\n\n /**\n * Sets up all entities required for the LabelDrop Feature.\n *\n * Initializes the LabelDropRepo entity and configures it with the\n * labelDropItemFactory for creating individual label drop items.\n * Uses the \"LabelDrop\" AppObject that was passed to the factory constructor.\n */\n setupEntities(): void {\n // Create the main LabelDropRepo entity\n this.labelDropEntity = makeLabelDropRepo(this.appObject);\n\n // Configure the entity with the item factory\n this.labelDropEntity.labelDropItemFactory = makeLabelDropItemFactory(\n this.appObject.appObjectRepo,\n );\n }\n\n /**\n * Sets up all use cases for the LabelDrop Feature.\n *\n * Initializes all 12 use cases that define the business operations and\n * workflows available in the label drop feature. The use cases are created\n * in the same order as the original setupLabelDrop function to maintain\n * functional equivalence.\n *\n * Use Cases created:\n * - SerializeLabelDrop: Handles serialization of label drop data\n * - ClearEditingLabelDropUCHook: Manages clearing editing state\n * - EditLabelDropUC: Handles label drop editing operations\n * - DragLabelDropUC: Manages label drop dragging in screen space\n * - DragLabelDropWorldUC: Manages label drop dragging in world space\n * - DeleteLabelDropUC: Handles individual label drop deletion\n * - DeleteAllLabelDropUC: Handles deletion of all label drops\n * - ToggleLabelDropTargetUC: Manages target toggle operations\n * - LabelDropCorrectAnimationUC: Handles correct drop animations\n * - LabelDropOnNothingAnimationUC: Handles drop-on-nothing animations\n * - LabelDropIncorrectAnimationUC: Handles incorrect drop animations\n * - ValidateLabelDrop: Handles label drop validation logic\n */\n setupUCs(): void {\n // Create all Use Cases in the same order as original\n new SerializeLabelDrop(this.appObject);\n new ClearEditingLabelDropUCHook(this.appObject);\n makeEditLabelDropUC(this.appObject);\n makeDragLabelDropUC(this.appObject);\n makeDragLabelDropWorldUC(this.appObject);\n makeDeleteLabelDropUC(this.appObject);\n makeDeleteAllLabelDropUC(this.appObject);\n makeToggleLabelDropTargetUC(this.appObject);\n makeLabelDropCorrectAnimationUC(this.appObject);\n makeLabelDropOnNothingAnimationUC(this.appObject);\n makeLabelDropIncorrectAnimationUC(this.appObject);\n makeValidateLabelDrop(this.appObject);\n }\n\n /**\n * Sets up all presentation models for the LabelDrop Feature.\n *\n * Initializes all 6 presentation models that handle the view logic and\n * state management for UI components related to the label drop feature.\n * These PMs manage the reactive data flow between the domain layer and UI.\n *\n * Presentation Models created:\n * - LabelDropEditingIDPM: Manages the currently editing label drop ID\n * - RemainingLabelDropListPM: Tracks remaining label drops to be placed\n * - LabelDropReviewPM: Handles review mode presentation logic\n * - Transform3DPM: Manages 3D transform presentation for the feature\n * - LabelDropDragItemPM: Handles drag item presentation state\n * - LabelDropListPM: Manages the overall list of label drops\n */\n setupPMs(): void {\n // Create all Presentation Models in the same order as original\n makeLabelDropEditingIDPM(this.appObject);\n makeRemainingLabelDropListPM(this.appObject);\n makeLabelDropReviewPM(this.appObject);\n makeTransform3DPM(this.appObject);\n makeLabelDropDragItemPM(this.appObject);\n makeLabelDropListPM(this.appObject);\n }\n\n /**\n * Performs final setup operations after all components are initialized.\n *\n * This method handles:\n * - Creation of the 3 Controllers (Mouse, Touch, Stylus)\n * - External dependency resolution and configuration\n * - Transform hierarchy setup for drag operations\n * - Error handling for missing dependencies\n *\n * Controllers created:\n * - MouseLabelDropAuthor: Handles mouse-based label drop interactions\n * - TouchLabelDropAuthor: Handles touch-based label drop interactions\n * - StylusLabelDrop: Handles stylus-based label drop interactions\n *\n * External dependencies:\n * - StylusEntity: Required for stylus-based interactions and drag helper positioning\n * - ZSpaceEntity: Required for zSpace display integration and drag label positioning\n */\n finalSetup(): void {\n const challengeEntity = ChallengeEntity.get(this.appObjects);\n if (challengeEntity && this.labelDropEntity) {\n challengeEntity.registerChallenge(this.labelDropEntity);\n }\n\n // Create Controllers\n makeMouseLabelDropAuthor(this.appObject);\n makeTouchLabelDropAuthor(this.appObject);\n\n if (this.appObjects.hasSingleton(StylusEntity.type)) {\n makeStylusLabelDrop(this.appObject);\n }\n }\n}\n\n/**\n * Factory function to create a new LabelDropFeatureFactory.\n *\n * This function follows the same pattern as the original setupLabelDrop function\n * by taking an AppObjectRepo and creating the \"LabelDrop\" AppObject internally.\n * The factory provides the same functionality as the original setupLabelDrop function\n * but follows the Clean Architecture pattern and can be composed with other factories.\n *\n * @param appObjectRepo The AppObjectRepo to create the LabelDrop AppObject from\n * @returns A new LabelDropFeatureFactory instance\n */\nexport function makeLabelDropFeatureFactory(\n appObjectRepo: AppObjectRepo,\n): LabelDropFeatureFactory {\n const appObject = appObjectRepo.getOrCreate(\"LabelDrop\");\n return new LabelDropFeatureFactory(appObject);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"LabelDropFeatureFactory.js","sourceRoot":"","sources":["../../../../src/LabelDrop/Factories/LabelDropFeatureFactory.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n DomainFactory,\r\n AppObject,\r\n AppObjectRepo,\r\n Quaternion,\r\n Vector3,\r\n} from \"@vived/core\";\r\nimport { StylusEntity } from \"../../Stylus\";\r\nimport { makeTransform3DPM } from \"../../Transform3D\";\r\nimport { ZSpaceEntity } from \"../../zSpace\";\r\nimport {\r\n makeMouseLabelDropAuthor,\r\n makeStylusLabelDrop,\r\n makeTouchLabelDropAuthor,\r\n} from \"../Controller\";\r\nimport { makeLabelDropRepo } from \"../Entities\";\r\nimport {\r\n makeLabelDropDragItemPM,\r\n makeLabelDropEditingIDPM,\r\n makeLabelDropListPM,\r\n makeLabelDropReviewPM,\r\n makeRemainingLabelDropListPM,\r\n} from \"../PM\";\r\nimport {\r\n ClearEditingLabelDropUCHook,\r\n makeDeleteAllLabelDropUC,\r\n makeDeleteLabelDropUC,\r\n makeDragLabelDropUC,\r\n makeDragLabelDropWorldUC,\r\n makeEditLabelDropUC,\r\n makeLabelDropCorrectAnimationUC,\r\n makeLabelDropIncorrectAnimationUC,\r\n makeLabelDropOnNothingAnimationUC,\r\n makeSubmitLabelDropResultUC,\r\n makeToggleLabelDropTargetUC,\r\n makeValidateLabelDrop,\r\n SerializeLabelDrop,\r\n} from \"../UseCases\";\r\nimport { makeLabelDropItemFactory } from \"./labelDropItemFactory\";\r\nimport { LabelDropRepo } from \"../Entities\";\r\nimport { ChallengeEntity } from \"../../Challenge\";\r\n\r\n/**\r\n * Factory responsible for setting up the LabelDrop Feature domain components.\r\n *\r\n * This factory initializes all entities, use cases, presentation models, and controllers\r\n * required for the LabelDrop Feature functionality. It follows the domain-driven\r\n * design pattern by organizing components into their respective layers. This factory\r\n * replaces the complex setupLabelDrop function while maintaining backwards compatibility.\r\n *\r\n * The factory creates and configures:\r\n * - 1 LabelDropRepo entity with labelDropItemFactory configuration\r\n * - 12 Use Cases for label drop operations including serialization, editing, dragging, and validation\r\n * - 6 Presentation Models for UI state management and data presentation\r\n * - 3 Controllers for mouse, touch, and stylus interactions\r\n * - External dependency management for StylusEntity and ZSpaceEntity\r\n * - Transform hierarchy setup with proper positioning and scaling\r\n *\r\n * @extends DomainFactory\r\n */\r\nexport class LabelDropFeatureFactory extends DomainFactory {\r\n factoryName = \"LabelDropFeatureFactory\";\r\n\r\n private labelDropEntity: LabelDropRepo | null = null;\r\n\r\n /**\r\n * Sets up all entities required for the LabelDrop Feature.\r\n *\r\n * Initializes the LabelDropRepo entity and configures it with the\r\n * labelDropItemFactory for creating individual label drop items.\r\n * Uses the \"LabelDrop\" AppObject that was passed to the factory constructor.\r\n */\r\n setupEntities(): void {\r\n // Create the main LabelDropRepo entity\r\n this.labelDropEntity = makeLabelDropRepo(this.appObject);\r\n\r\n // Configure the entity with the item factory\r\n this.labelDropEntity.labelDropItemFactory = makeLabelDropItemFactory(\r\n this.appObject.appObjectRepo,\r\n );\r\n }\r\n\r\n /**\r\n * Sets up all use cases for the LabelDrop Feature.\r\n *\r\n * Initializes all 12 use cases that define the business operations and\r\n * workflows available in the label drop feature. The use cases are created\r\n * in the same order as the original setupLabelDrop function to maintain\r\n * functional equivalence.\r\n *\r\n * Use Cases created:\r\n * - SerializeLabelDrop: Handles serialization of label drop data\r\n * - ClearEditingLabelDropUCHook: Manages clearing editing state\r\n * - EditLabelDropUC: Handles label drop editing operations\r\n * - DragLabelDropUC: Manages label drop dragging in screen space\r\n * - DragLabelDropWorldUC: Manages label drop dragging in world space\r\n * - DeleteLabelDropUC: Handles individual label drop deletion\r\n * - DeleteAllLabelDropUC: Handles deletion of all label drops\r\n * - ToggleLabelDropTargetUC: Manages target toggle operations\r\n * - LabelDropCorrectAnimationUC: Handles correct drop animations\r\n * - LabelDropOnNothingAnimationUC: Handles drop-on-nothing animations\r\n * - LabelDropIncorrectAnimationUC: Handles incorrect drop animations\r\n * - ValidateLabelDrop: Handles label drop validation logic\r\n */\r\n setupUCs(): void {\r\n // Create all Use Cases in the same order as original\r\n new SerializeLabelDrop(this.appObject);\r\n new ClearEditingLabelDropUCHook(this.appObject);\r\n makeEditLabelDropUC(this.appObject);\r\n makeDragLabelDropUC(this.appObject);\r\n makeDragLabelDropWorldUC(this.appObject);\r\n makeDeleteLabelDropUC(this.appObject);\r\n makeDeleteAllLabelDropUC(this.appObject);\r\n makeToggleLabelDropTargetUC(this.appObject);\r\n makeLabelDropCorrectAnimationUC(this.appObject);\r\n makeLabelDropOnNothingAnimationUC(this.appObject);\r\n makeLabelDropIncorrectAnimationUC(this.appObject);\r\n makeValidateLabelDrop(this.appObject);\r\n makeSubmitLabelDropResultUC(this.appObject);\r\n }\r\n\r\n /**\r\n * Sets up all presentation models for the LabelDrop Feature.\r\n *\r\n * Initializes all 6 presentation models that handle the view logic and\r\n * state management for UI components related to the label drop feature.\r\n * These PMs manage the reactive data flow between the domain layer and UI.\r\n *\r\n * Presentation Models created:\r\n * - LabelDropEditingIDPM: Manages the currently editing label drop ID\r\n * - RemainingLabelDropListPM: Tracks remaining label drops to be placed\r\n * - LabelDropReviewPM: Handles review mode presentation logic\r\n * - Transform3DPM: Manages 3D transform presentation for the feature\r\n * - LabelDropDragItemPM: Handles drag item presentation state\r\n * - LabelDropListPM: Manages the overall list of label drops\r\n */\r\n setupPMs(): void {\r\n // Create all Presentation Models in the same order as original\r\n makeLabelDropEditingIDPM(this.appObject);\r\n makeRemainingLabelDropListPM(this.appObject);\r\n makeLabelDropReviewPM(this.appObject);\r\n makeTransform3DPM(this.appObject);\r\n makeLabelDropDragItemPM(this.appObject);\r\n makeLabelDropListPM(this.appObject);\r\n }\r\n\r\n /**\r\n * Performs final setup operations after all components are initialized.\r\n *\r\n * This method handles:\r\n * - Creation of the 3 Controllers (Mouse, Touch, Stylus)\r\n * - External dependency resolution and configuration\r\n * - Transform hierarchy setup for drag operations\r\n * - Error handling for missing dependencies\r\n *\r\n * Controllers created:\r\n * - MouseLabelDropAuthor: Handles mouse-based label drop interactions\r\n * - TouchLabelDropAuthor: Handles touch-based label drop interactions\r\n * - StylusLabelDrop: Handles stylus-based label drop interactions\r\n *\r\n * External dependencies:\r\n * - StylusEntity: Required for stylus-based interactions and drag helper positioning\r\n * - ZSpaceEntity: Required for zSpace display integration and drag label positioning\r\n */\r\n finalSetup(): void {\r\n const challengeEntity = ChallengeEntity.get(this.appObjects);\r\n if (challengeEntity && this.labelDropEntity) {\r\n challengeEntity.registerChallenge(this.labelDropEntity);\r\n }\r\n\r\n // Create Controllers\r\n makeMouseLabelDropAuthor(this.appObject);\r\n makeTouchLabelDropAuthor(this.appObject);\r\n\r\n if (this.appObjects.hasSingleton(StylusEntity.type)) {\r\n makeStylusLabelDrop(this.appObject);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create a new LabelDropFeatureFactory.\r\n *\r\n * This function follows the same pattern as the original setupLabelDrop function\r\n * by taking an AppObjectRepo and creating the \"LabelDrop\" AppObject internally.\r\n * The factory provides the same functionality as the original setupLabelDrop function\r\n * but follows the Clean Architecture pattern and can be composed with other factories.\r\n *\r\n * @param appObjectRepo The AppObjectRepo to create the LabelDrop AppObject from\r\n * @returns A new LabelDropFeatureFactory instance\r\n */\r\nexport function makeLabelDropFeatureFactory(\r\n appObjectRepo: AppObjectRepo,\r\n): LabelDropFeatureFactory {\r\n const appObject = appObjectRepo.getOrCreate(\"LabelDrop\");\r\n return new LabelDropFeatureFactory(appObject);\r\n}\r\n"]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { AppObjectUC, getSingletonComponent, } from "@vived/core";
|
|
2
|
+
import { BaseAppState } from "../../BaseApp";
|
|
3
|
+
import { ChallengeEntity } from "../../Challenge";
|
|
4
|
+
import { submitMultiHitResult } from "../../Dispatcher";
|
|
5
|
+
import { LabelDropRepo } from "../Entities";
|
|
6
|
+
/**
|
|
7
|
+
* Submits a Label Drop challenge result to the Host as a MULTIHIT result.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors the other challenge submitters (TrySubmitObjectPickUC, SubmitQuestionAnswerUC):
|
|
10
|
+
* consumption-mode only, and only while Label Drop is the selected challenge. It observes
|
|
11
|
+
* every Label Drop submission and reports the running tally, so a partial attempt is scored
|
|
12
|
+
* on slide exit (the Host's MULTIHIT best-hits rule keeps the strongest result). See
|
|
13
|
+
* docs/prd/label-drop-result.md.
|
|
14
|
+
*
|
|
15
|
+
* Tally: hits = items answered correctly; unanswered = items not yet correct
|
|
16
|
+
* (getRemainingLabelDrops); misses = total tries - hits (each hit's final try is the one
|
|
17
|
+
* correct drop, so every other object-drop was wrong); description = the slide's text.
|
|
18
|
+
*/
|
|
19
|
+
export class SubmitLabelDropResultUC extends AppObjectUC {
|
|
20
|
+
static get(appObjects) {
|
|
21
|
+
return getSingletonComponent(SubmitLabelDropResultUC.type, appObjects);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
SubmitLabelDropResultUC.type = "SubmitLabelDropResultUC";
|
|
25
|
+
export function makeSubmitLabelDropResultUC(appObject) {
|
|
26
|
+
return new SubmitLabelDropResultUCImp(appObject);
|
|
27
|
+
}
|
|
28
|
+
class SubmitLabelDropResultUCImp extends SubmitLabelDropResultUC {
|
|
29
|
+
get repo() {
|
|
30
|
+
return this.getCachedSingleton(LabelDropRepo.type);
|
|
31
|
+
}
|
|
32
|
+
get baseApp() {
|
|
33
|
+
return this.getCachedSingleton(BaseAppState.type);
|
|
34
|
+
}
|
|
35
|
+
get challenge() {
|
|
36
|
+
return this.getCachedSingleton(ChallengeEntity.type);
|
|
37
|
+
}
|
|
38
|
+
constructor(appObject) {
|
|
39
|
+
super(appObject, SubmitLabelDropResultUC.type);
|
|
40
|
+
this.onSubmission = () => {
|
|
41
|
+
this.submitResult();
|
|
42
|
+
};
|
|
43
|
+
this.submitResult = () => {
|
|
44
|
+
const repo = this.repo;
|
|
45
|
+
const baseApp = this.baseApp;
|
|
46
|
+
const challenge = this.challenge;
|
|
47
|
+
if (!repo || !baseApp || !challenge)
|
|
48
|
+
return;
|
|
49
|
+
if (baseApp.isAuthoring)
|
|
50
|
+
return;
|
|
51
|
+
if (challenge.selectedChallenge !== "LABEL_DROP")
|
|
52
|
+
return;
|
|
53
|
+
const items = repo.getAll();
|
|
54
|
+
const hits = items.filter((item) => item.answeredCorrectly === true).length;
|
|
55
|
+
const unanswered = repo.getRemainingLabelDrops().length;
|
|
56
|
+
const totalTries = items.reduce((sum, item) => sum + item.tries, 0);
|
|
57
|
+
const misses = totalTries - hits;
|
|
58
|
+
submitMultiHitResult({
|
|
59
|
+
hits,
|
|
60
|
+
misses,
|
|
61
|
+
unanswered,
|
|
62
|
+
description: baseApp.slideText,
|
|
63
|
+
}, this.appObjects);
|
|
64
|
+
};
|
|
65
|
+
this.appObjects.registerSingleton(this);
|
|
66
|
+
const repo = LabelDropRepo.get(this.appObjects);
|
|
67
|
+
if (repo) {
|
|
68
|
+
repo.addLabelDropSubmissionObserver(this.onSubmission);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
this.warn("SubmitLabelDropResultUC has been set up without a LabelDropRepo to observe");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=SubmitLabelDropResultUC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubmitLabelDropResultUC.js","sourceRoot":"","sources":["../../../../src/LabelDrop/UseCases/SubmitLabelDropResultUC.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n AppObject,\r\n AppObjectRepo,\r\n AppObjectUC,\r\n getSingletonComponent,\r\n} from \"@vived/core\";\r\nimport { BaseAppState } from \"../../BaseApp\";\r\nimport { ChallengeEntity } from \"../../Challenge\";\r\nimport { submitMultiHitResult } from \"../../Dispatcher\";\r\nimport { LabelDropRepo } from \"../Entities\";\r\n\r\n/**\r\n * Submits a Label Drop challenge result to the Host as a MULTIHIT result.\r\n *\r\n * Mirrors the other challenge submitters (TrySubmitObjectPickUC, SubmitQuestionAnswerUC):\r\n * consumption-mode only, and only while Label Drop is the selected challenge. It observes\r\n * every Label Drop submission and reports the running tally, so a partial attempt is scored\r\n * on slide exit (the Host's MULTIHIT best-hits rule keeps the strongest result). See\r\n * docs/prd/label-drop-result.md.\r\n *\r\n * Tally: hits = items answered correctly; unanswered = items not yet correct\r\n * (getRemainingLabelDrops); misses = total tries - hits (each hit's final try is the one\r\n * correct drop, so every other object-drop was wrong); description = the slide's text.\r\n */\r\nexport abstract class SubmitLabelDropResultUC extends AppObjectUC {\r\n static readonly type = \"SubmitLabelDropResultUC\";\r\n\r\n abstract submitResult(): void;\r\n\r\n static get(appObjects: AppObjectRepo) {\r\n return getSingletonComponent<SubmitLabelDropResultUC>(\r\n SubmitLabelDropResultUC.type,\r\n appObjects,\r\n );\r\n }\r\n}\r\n\r\nexport function makeSubmitLabelDropResultUC(\r\n appObject: AppObject,\r\n): SubmitLabelDropResultUC {\r\n return new SubmitLabelDropResultUCImp(appObject);\r\n}\r\n\r\nclass SubmitLabelDropResultUCImp extends SubmitLabelDropResultUC {\r\n private get repo() {\r\n return this.getCachedSingleton<LabelDropRepo>(LabelDropRepo.type);\r\n }\r\n\r\n private get baseApp() {\r\n return this.getCachedSingleton<BaseAppState>(BaseAppState.type);\r\n }\r\n\r\n private get challenge() {\r\n return this.getCachedSingleton<ChallengeEntity>(ChallengeEntity.type);\r\n }\r\n\r\n private onSubmission = (): void => {\r\n this.submitResult();\r\n };\r\n\r\n submitResult = (): void => {\r\n const repo = this.repo;\r\n const baseApp = this.baseApp;\r\n const challenge = this.challenge;\r\n if (!repo || !baseApp || !challenge) return;\r\n\r\n if (baseApp.isAuthoring) return;\r\n if (challenge.selectedChallenge !== \"LABEL_DROP\") return;\r\n\r\n const items = repo.getAll();\r\n const hits = items.filter(\r\n (item) => item.answeredCorrectly === true,\r\n ).length;\r\n const unanswered = repo.getRemainingLabelDrops().length;\r\n const totalTries = items.reduce((sum, item) => sum + item.tries, 0);\r\n const misses = totalTries - hits;\r\n\r\n submitMultiHitResult(\r\n {\r\n hits,\r\n misses,\r\n unanswered,\r\n description: baseApp.slideText,\r\n },\r\n this.appObjects,\r\n );\r\n };\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, SubmitLabelDropResultUC.type);\r\n this.appObjects.registerSingleton(this);\r\n\r\n const repo = LabelDropRepo.get(this.appObjects);\r\n if (repo) {\r\n repo.addLabelDropSubmissionObserver(this.onSubmission);\r\n } else {\r\n this.warn(\r\n \"SubmitLabelDropResultUC has been set up without a LabelDropRepo to observe\",\r\n );\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { makeAppObjectRepo } from "@vived/core";
|
|
2
|
+
import { makeBaseAppState } from "../../BaseApp/Entity/BaseAppState";
|
|
3
|
+
import { makeChallengeEntityMock } from "../../Challenge";
|
|
4
|
+
import { makeMockSubmitResult } from "../../Dispatcher";
|
|
5
|
+
import { LabelDropRepo, makeLabelDropRepo } from "../Entities";
|
|
6
|
+
import { makeLabelDropFeatureFactory } from "../Factories/LabelDropFeatureFactory";
|
|
7
|
+
import { makeSubmitLabelDropResultUC, SubmitLabelDropResultUC, } from "./SubmitLabelDropResultUC";
|
|
8
|
+
describe("SubmitLabelDropResultUC", () => {
|
|
9
|
+
it("Registers as the singleton", () => {
|
|
10
|
+
const appObjects = makeAppObjectRepo();
|
|
11
|
+
makeLabelDropRepo(appObjects.getOrCreate("LabelDrop"));
|
|
12
|
+
const uc = makeSubmitLabelDropResultUC(appObjects.getOrCreate("LabelDrop"));
|
|
13
|
+
expect(SubmitLabelDropResultUC.get(appObjects)).toBe(uc);
|
|
14
|
+
});
|
|
15
|
+
// Wiring / lifecycle: prove the real LabelDropFeatureFactory constructs the UC and hooks
|
|
16
|
+
// the drop observer. Uses the repo's factory-test idiom (drive the phases directly) rather
|
|
17
|
+
// than a full setupDomain — finalSetup wires pointer controllers that pull in the input /
|
|
18
|
+
// framework cluster, which is irrelevant to this UC's wiring.
|
|
19
|
+
it("is wired by LabelDropFeatureFactory.setupUCs so a drop reports a result to the Host", () => {
|
|
20
|
+
const appObjects = makeAppObjectRepo();
|
|
21
|
+
// Boundary singletons the feature's UCs read at construction time.
|
|
22
|
+
const baseApp = makeBaseAppState(appObjects.getOrCreate("App"));
|
|
23
|
+
baseApp.isAuthoring = false;
|
|
24
|
+
baseApp.slideText = "Slide text";
|
|
25
|
+
const challenge = makeChallengeEntityMock(appObjects);
|
|
26
|
+
challenge.selectedChallenge = "LABEL_DROP";
|
|
27
|
+
const mockSubmitResult = makeMockSubmitResult(appObjects);
|
|
28
|
+
mockSubmitResult.submitMultiHitResult = jest.fn();
|
|
29
|
+
const factory = makeLabelDropFeatureFactory(appObjects);
|
|
30
|
+
factory.setupEntities(); // creates LabelDropRepo
|
|
31
|
+
factory.setupUCs(); // creates SubmitLabelDropResultUC, which subscribes to the repo
|
|
32
|
+
const repo = LabelDropRepo.get(appObjects);
|
|
33
|
+
const item = repo.makeLabelDropItem("a");
|
|
34
|
+
item.targetIds = ["objA"];
|
|
35
|
+
repo.submitLabelDrop("a", "objA");
|
|
36
|
+
expect(mockSubmitResult.submitMultiHitResult).toHaveBeenCalledWith({
|
|
37
|
+
hits: 1,
|
|
38
|
+
misses: 0,
|
|
39
|
+
unanswered: 0,
|
|
40
|
+
description: "Slide text",
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=SubmitLabelDropResultUC.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubmitLabelDropResultUC.test.js","sourceRoot":"","sources":["../../../../src/LabelDrop/UseCases/SubmitLabelDropResultUC.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EACL,2BAA2B,EAC3B,uBAAuB,GACxB,MAAM,2BAA2B,CAAC;AAEnC,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;QACvC,iBAAiB,CAAC,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;QACvD,MAAM,EAAE,GAAG,2BAA2B,CAAC,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;QAE5E,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,yFAAyF;IACzF,2FAA2F;IAC3F,0FAA0F;IAC1F,8DAA8D;IAC9D,EAAE,CAAC,qFAAqF,EAAE,GAAG,EAAE;QAC7F,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;QAEvC,mEAAmE;QACnE,MAAM,OAAO,GAAG,gBAAgB,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC;QAC5B,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC;QAEjC,MAAM,SAAS,GAAG,uBAAuB,CAAC,UAAU,CAAC,CAAC;QACtD,SAAS,CAAC,iBAAiB,GAAG,YAAY,CAAC;QAE3C,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAC1D,gBAAgB,CAAC,oBAAoB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAElD,MAAM,OAAO,GAAG,2BAA2B,CAAC,UAAU,CAAC,CAAC;QACxD,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,wBAAwB;QACjD,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,gEAAgE;QAEpF,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,CAAC;QAE1B,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAElC,MAAM,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAAC,oBAAoB,CAAC;YACjE,IAAI,EAAE,CAAC;YACP,MAAM,EAAE,CAAC;YACT,UAAU,EAAE,CAAC;YACb,WAAW,EAAE,YAAY;SAC1B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { makeAppObjectRepo } from \"@vived/core\";\r\nimport { makeBaseAppState } from \"../../BaseApp/Entity/BaseAppState\";\r\nimport { makeChallengeEntityMock } from \"../../Challenge\";\r\nimport { makeMockSubmitResult } from \"../../Dispatcher\";\r\nimport { LabelDropRepo, makeLabelDropRepo } from \"../Entities\";\r\nimport { makeLabelDropFeatureFactory } from \"../Factories/LabelDropFeatureFactory\";\r\nimport {\r\n makeSubmitLabelDropResultUC,\r\n SubmitLabelDropResultUC,\r\n} from \"./SubmitLabelDropResultUC\";\r\n\r\ndescribe(\"SubmitLabelDropResultUC\", () => {\r\n it(\"Registers as the singleton\", () => {\r\n const appObjects = makeAppObjectRepo();\r\n makeLabelDropRepo(appObjects.getOrCreate(\"LabelDrop\"));\r\n const uc = makeSubmitLabelDropResultUC(appObjects.getOrCreate(\"LabelDrop\"));\r\n\r\n expect(SubmitLabelDropResultUC.get(appObjects)).toBe(uc);\r\n });\r\n\r\n // Wiring / lifecycle: prove the real LabelDropFeatureFactory constructs the UC and hooks\r\n // the drop observer. Uses the repo's factory-test idiom (drive the phases directly) rather\r\n // than a full setupDomain — finalSetup wires pointer controllers that pull in the input /\r\n // framework cluster, which is irrelevant to this UC's wiring.\r\n it(\"is wired by LabelDropFeatureFactory.setupUCs so a drop reports a result to the Host\", () => {\r\n const appObjects = makeAppObjectRepo();\r\n\r\n // Boundary singletons the feature's UCs read at construction time.\r\n const baseApp = makeBaseAppState(appObjects.getOrCreate(\"App\"));\r\n baseApp.isAuthoring = false;\r\n baseApp.slideText = \"Slide text\";\r\n\r\n const challenge = makeChallengeEntityMock(appObjects);\r\n challenge.selectedChallenge = \"LABEL_DROP\";\r\n\r\n const mockSubmitResult = makeMockSubmitResult(appObjects);\r\n mockSubmitResult.submitMultiHitResult = jest.fn();\r\n\r\n const factory = makeLabelDropFeatureFactory(appObjects);\r\n factory.setupEntities(); // creates LabelDropRepo\r\n factory.setupUCs(); // creates SubmitLabelDropResultUC, which subscribes to the repo\r\n\r\n const repo = LabelDropRepo.get(appObjects)!;\r\n const item = repo.makeLabelDropItem(\"a\");\r\n item.targetIds = [\"objA\"];\r\n\r\n repo.submitLabelDrop(\"a\", \"objA\");\r\n\r\n expect(mockSubmitResult.submitMultiHitResult).toHaveBeenCalledWith({\r\n hits: 1,\r\n misses: 0,\r\n unanswered: 0,\r\n description: \"Slide text\",\r\n });\r\n });\r\n});\r\n"]}
|
|
@@ -10,6 +10,7 @@ export * from "./IncorrectAnimationUC";
|
|
|
10
10
|
export * from "./InitializeLabelDropLabelHook";
|
|
11
11
|
export * from "./LabelDropAnimation";
|
|
12
12
|
export * from "./SerializeLabelDrop";
|
|
13
|
+
export * from "./SubmitLabelDropResultUC";
|
|
13
14
|
export * from "./ToggleLabelDropTargetUC";
|
|
14
15
|
export * from "./ValidateLabelDrop";
|
|
15
16
|
export * from "./labelDropLabelValidator";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/LabelDrop/UseCases/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC","sourcesContent":["export * from \"./ClearEditingLabelDropUCHook\";\nexport * from \"./CorrectAnimationUC\";\nexport * from \"./DeleteAllLabelDropUC\";\nexport * from \"./DeleteLabelDropUC\";\nexport * from \"./DragLabelDropUC\";\nexport * from \"./DragLabelDropWorldUC\";\nexport * from \"./DropOnNothingAnimationUC\";\nexport * from \"./EditLabelDropUC\";\nexport * from \"./IncorrectAnimationUC\";\nexport * from \"./InitializeLabelDropLabelHook\";\nexport * from \"./LabelDropAnimation\";\nexport * from \"./SerializeLabelDrop\";\nexport * from \"./ToggleLabelDropTargetUC\";\nexport * from \"./ValidateLabelDrop\";\nexport * from \"./labelDropLabelValidator\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/LabelDrop/UseCases/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC","sourcesContent":["export * from \"./ClearEditingLabelDropUCHook\";\r\nexport * from \"./CorrectAnimationUC\";\r\nexport * from \"./DeleteAllLabelDropUC\";\r\nexport * from \"./DeleteLabelDropUC\";\r\nexport * from \"./DragLabelDropUC\";\r\nexport * from \"./DragLabelDropWorldUC\";\r\nexport * from \"./DropOnNothingAnimationUC\";\r\nexport * from \"./EditLabelDropUC\";\r\nexport * from \"./IncorrectAnimationUC\";\r\nexport * from \"./InitializeLabelDropLabelHook\";\r\nexport * from \"./LabelDropAnimation\";\r\nexport * from \"./SerializeLabelDrop\";\r\nexport * from \"./SubmitLabelDropResultUC\";\r\nexport * from \"./ToggleLabelDropTargetUC\";\r\nexport * from \"./ValidateLabelDrop\";\r\nexport * from \"./labelDropLabelValidator\";\r\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/TestUtils/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC","sourcesContent":["export * from \"./setupFeatureForTesting\";\r\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* setupFeatureForTesting.ts
|
|
3
|
+
*
|
|
4
|
+
* The feature-context test harness for this Feature Library.
|
|
5
|
+
*
|
|
6
|
+
* This package has no app-level domain (no `makeDomain`, no single repo), so there is no
|
|
7
|
+
* global "make the domain" harness. The unit of test context is a **Feature** (or a small
|
|
8
|
+
* cluster of Features), wired the way a Slide App wires it — through each Feature's
|
|
9
|
+
* `FeatureFactory` (the current standard), using the same phased orchestration production
|
|
10
|
+
* uses. See `CLAUDE.md` and `docs/agents/domain.md`.
|
|
11
|
+
*
|
|
12
|
+
* Use this for **wiring / lifecycle** tests — proving that a Feature, once really wired,
|
|
13
|
+
* behaves end-to-end (e.g. a Challenge submits its result when the student leaves the slide).
|
|
14
|
+
* For pure **logic** tests of a single UC or PM, a hand-wired `makeAppObjectRepo()` rig with
|
|
15
|
+
* the collaborators mocked at the boundary is lighter and still preferred — see
|
|
16
|
+
* `src/ObjectPick/UseCases/TrySubmitObjectPickUC.test.ts` as the reference.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // LabelDrop's submit path depends on Challenge (for `selectedChallenge`) and the
|
|
20
|
+
* // Dispatcher (the Host boundary). List dependencies first, exactly as a Slide App would.
|
|
21
|
+
* const { appObjects } = setupFeatureForTesting([
|
|
22
|
+
* makeDispatcherFeatureFactory,
|
|
23
|
+
* makeChallengeFeatureFactory,
|
|
24
|
+
* makeLabelDropFeatureFactory,
|
|
25
|
+
* ]);
|
|
26
|
+
* // Then act through a Controller / navigation seam and assert through an Adapter VM or a
|
|
27
|
+
* // dispatcher mock registered before setup.
|
|
28
|
+
*/
|
|
29
|
+
import { makeAppObjectRepo, makeDomainFactoryRepo, } from "@vived/core";
|
|
30
|
+
/**
|
|
31
|
+
* Wire one or more Features into a fresh repo for a feature-context test.
|
|
32
|
+
*
|
|
33
|
+
* @param featureFactories The `make<Feature>FeatureFactory` functions to wire, in the order a
|
|
34
|
+
* Slide App would compose them — a Feature whose `finalSetup` depends on another Feature's
|
|
35
|
+
* entities must be listed *after* that Feature.
|
|
36
|
+
* @param seed Optional callback run *before* the factories are constructed. Use it to stand up
|
|
37
|
+
* the boundary singletons a Feature reads at construction time (many Feature UCs resolve
|
|
38
|
+
* siblings via `getCachedSingleton`, which THROWS when absent — e.g. `BaseAppState`,
|
|
39
|
+
* `ChallengeEntity`). Seed real entities or their Mocks here instead of pulling every
|
|
40
|
+
* dependency Feature's factory into the cluster.
|
|
41
|
+
* @returns `{ appObjects }` — resolve Controllers and Adapters from it to act and assert.
|
|
42
|
+
*/
|
|
43
|
+
export function setupFeatureForTesting(featureFactories, seed) {
|
|
44
|
+
const appObjects = makeAppObjectRepo();
|
|
45
|
+
// The DomainFactoryRepo must exist before the factories are constructed: each
|
|
46
|
+
// FeatureFactory auto-registers with it in its constructor.
|
|
47
|
+
const factoryRepo = makeDomainFactoryRepo(appObjects);
|
|
48
|
+
// Stand up boundary singletons the Features read at construction time.
|
|
49
|
+
if (seed)
|
|
50
|
+
seed(appObjects);
|
|
51
|
+
featureFactories.forEach((makeFactory) => makeFactory(appObjects));
|
|
52
|
+
// Run the same phased orchestration as production — all setupEntities, then all setupUCs,
|
|
53
|
+
// then all setupPMs, then all finalSetup — so cross-Feature dependencies resolve correctly.
|
|
54
|
+
factoryRepo.setupDomain();
|
|
55
|
+
return { appObjects };
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=setupFeatureForTesting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupFeatureForTesting.js","sourceRoot":"","sources":["../../../src/TestUtils/setupFeatureForTesting.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAGL,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AAOrB;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CACpC,gBAAkE,EAClE,IAA0C;IAE1C,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;IAEvC,8EAA8E;IAC9E,4DAA4D;IAC5D,MAAM,WAAW,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAEtD,uEAAuE;IACvE,IAAI,IAAI;QAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAE3B,gBAAgB,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;IAEnE,0FAA0F;IAC1F,4FAA4F;IAC5F,WAAW,CAAC,WAAW,EAAE,CAAC;IAE1B,OAAO,EAAE,UAAU,EAAE,CAAC;AACxB,CAAC","sourcesContent":["/**\r\n * setupFeatureForTesting.ts\r\n *\r\n * The feature-context test harness for this Feature Library.\r\n *\r\n * This package has no app-level domain (no `makeDomain`, no single repo), so there is no\r\n * global \"make the domain\" harness. The unit of test context is a **Feature** (or a small\r\n * cluster of Features), wired the way a Slide App wires it — through each Feature's\r\n * `FeatureFactory` (the current standard), using the same phased orchestration production\r\n * uses. See `CLAUDE.md` and `docs/agents/domain.md`.\r\n *\r\n * Use this for **wiring / lifecycle** tests — proving that a Feature, once really wired,\r\n * behaves end-to-end (e.g. a Challenge submits its result when the student leaves the slide).\r\n * For pure **logic** tests of a single UC or PM, a hand-wired `makeAppObjectRepo()` rig with\r\n * the collaborators mocked at the boundary is lighter and still preferred — see\r\n * `src/ObjectPick/UseCases/TrySubmitObjectPickUC.test.ts` as the reference.\r\n *\r\n * @example\r\n * // LabelDrop's submit path depends on Challenge (for `selectedChallenge`) and the\r\n * // Dispatcher (the Host boundary). List dependencies first, exactly as a Slide App would.\r\n * const { appObjects } = setupFeatureForTesting([\r\n * makeDispatcherFeatureFactory,\r\n * makeChallengeFeatureFactory,\r\n * makeLabelDropFeatureFactory,\r\n * ]);\r\n * // Then act through a Controller / navigation seam and assert through an Adapter VM or a\r\n * // dispatcher mock registered before setup.\r\n */\r\n\r\nimport {\r\n AppObjectRepo,\r\n DomainFactory,\r\n makeAppObjectRepo,\r\n makeDomainFactoryRepo,\r\n} from \"@vived/core\";\r\n\r\nexport interface FeatureTestContext {\r\n /** The live repo, wired through the given FeatureFactories exactly as production does. */\r\n appObjects: AppObjectRepo;\r\n}\r\n\r\n/**\r\n * Wire one or more Features into a fresh repo for a feature-context test.\r\n *\r\n * @param featureFactories The `make<Feature>FeatureFactory` functions to wire, in the order a\r\n * Slide App would compose them — a Feature whose `finalSetup` depends on another Feature's\r\n * entities must be listed *after* that Feature.\r\n * @param seed Optional callback run *before* the factories are constructed. Use it to stand up\r\n * the boundary singletons a Feature reads at construction time (many Feature UCs resolve\r\n * siblings via `getCachedSingleton`, which THROWS when absent — e.g. `BaseAppState`,\r\n * `ChallengeEntity`). Seed real entities or their Mocks here instead of pulling every\r\n * dependency Feature's factory into the cluster.\r\n * @returns `{ appObjects }` — resolve Controllers and Adapters from it to act and assert.\r\n */\r\nexport function setupFeatureForTesting(\r\n featureFactories: ((appObjects: AppObjectRepo) => DomainFactory)[],\r\n seed?: (appObjects: AppObjectRepo) => void,\r\n): FeatureTestContext {\r\n const appObjects = makeAppObjectRepo();\r\n\r\n // The DomainFactoryRepo must exist before the factories are constructed: each\r\n // FeatureFactory auto-registers with it in its constructor.\r\n const factoryRepo = makeDomainFactoryRepo(appObjects);\r\n\r\n // Stand up boundary singletons the Features read at construction time.\r\n if (seed) seed(appObjects);\r\n\r\n featureFactories.forEach((makeFactory) => makeFactory(appObjects));\r\n\r\n // Run the same phased orchestration as production — all setupEntities, then all setupUCs,\r\n // then all setupPMs, then all finalSetup — so cross-Feature dependencies resolve correctly.\r\n factoryRepo.setupDomain();\r\n\r\n return { appObjects };\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LabelDropFeatureFactory.d.ts","sourceRoot":"","sources":["../../../../src/LabelDrop/Factories/LabelDropFeatureFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAEb,aAAa,EAGd,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"LabelDropFeatureFactory.d.ts","sourceRoot":"","sources":["../../../../src/LabelDrop/Factories/LabelDropFeatureFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAEb,aAAa,EAGd,MAAM,aAAa,CAAC;AAoCrB;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,uBAAwB,SAAQ,aAAa;IACxD,WAAW,SAA6B;IAExC,OAAO,CAAC,eAAe,CAA8B;IAErD;;;;;;OAMG;IACH,aAAa,IAAI,IAAI;IAUrB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,QAAQ,IAAI,IAAI;IAiBhB;;;;;;;;;;;;;;OAcG;IACH,QAAQ,IAAI,IAAI;IAUhB;;;;;;;;;;;;;;;;;OAiBG;IACH,UAAU,IAAI,IAAI;CAcnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,aAAa,GAC3B,uBAAuB,CAGzB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { AppObject, AppObjectRepo, AppObjectUC } from "@vived/core";
|
|
2
|
+
/**
|
|
3
|
+
* Submits a Label Drop challenge result to the Host as a MULTIHIT result.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors the other challenge submitters (TrySubmitObjectPickUC, SubmitQuestionAnswerUC):
|
|
6
|
+
* consumption-mode only, and only while Label Drop is the selected challenge. It observes
|
|
7
|
+
* every Label Drop submission and reports the running tally, so a partial attempt is scored
|
|
8
|
+
* on slide exit (the Host's MULTIHIT best-hits rule keeps the strongest result). See
|
|
9
|
+
* docs/prd/label-drop-result.md.
|
|
10
|
+
*
|
|
11
|
+
* Tally: hits = items answered correctly; unanswered = items not yet correct
|
|
12
|
+
* (getRemainingLabelDrops); misses = total tries - hits (each hit's final try is the one
|
|
13
|
+
* correct drop, so every other object-drop was wrong); description = the slide's text.
|
|
14
|
+
*/
|
|
15
|
+
export declare abstract class SubmitLabelDropResultUC extends AppObjectUC {
|
|
16
|
+
static readonly type = "SubmitLabelDropResultUC";
|
|
17
|
+
abstract submitResult(): void;
|
|
18
|
+
static get(appObjects: AppObjectRepo): SubmitLabelDropResultUC | undefined;
|
|
19
|
+
}
|
|
20
|
+
export declare function makeSubmitLabelDropResultUC(appObject: AppObject): SubmitLabelDropResultUC;
|
|
21
|
+
//# sourceMappingURL=SubmitLabelDropResultUC.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubmitLabelDropResultUC.d.ts","sourceRoot":"","sources":["../../../../src/LabelDrop/UseCases/SubmitLabelDropResultUC.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,aAAa,EACb,WAAW,EAEZ,MAAM,aAAa,CAAC;AAMrB;;;;;;;;;;;;GAYG;AACH,8BAAsB,uBAAwB,SAAQ,WAAW;IAC/D,MAAM,CAAC,QAAQ,CAAC,IAAI,6BAA6B;IAEjD,QAAQ,CAAC,YAAY,IAAI,IAAI;IAE7B,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,aAAa;CAMrC;AAED,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,SAAS,GACnB,uBAAuB,CAEzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubmitLabelDropResultUC.test.d.ts","sourceRoot":"","sources":["../../../../src/LabelDrop/UseCases/SubmitLabelDropResultUC.test.ts"],"names":[],"mappings":""}
|
|
@@ -10,6 +10,7 @@ export * from "./IncorrectAnimationUC";
|
|
|
10
10
|
export * from "./InitializeLabelDropLabelHook";
|
|
11
11
|
export * from "./LabelDropAnimation";
|
|
12
12
|
export * from "./SerializeLabelDrop";
|
|
13
|
+
export * from "./SubmitLabelDropResultUC";
|
|
13
14
|
export * from "./ToggleLabelDropTargetUC";
|
|
14
15
|
export * from "./ValidateLabelDrop";
|
|
15
16
|
export * from "./labelDropLabelValidator";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/LabelDrop/UseCases/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/LabelDrop/UseCases/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/TestUtils/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* setupFeatureForTesting.ts
|
|
3
|
+
*
|
|
4
|
+
* The feature-context test harness for this Feature Library.
|
|
5
|
+
*
|
|
6
|
+
* This package has no app-level domain (no `makeDomain`, no single repo), so there is no
|
|
7
|
+
* global "make the domain" harness. The unit of test context is a **Feature** (or a small
|
|
8
|
+
* cluster of Features), wired the way a Slide App wires it — through each Feature's
|
|
9
|
+
* `FeatureFactory` (the current standard), using the same phased orchestration production
|
|
10
|
+
* uses. See `CLAUDE.md` and `docs/agents/domain.md`.
|
|
11
|
+
*
|
|
12
|
+
* Use this for **wiring / lifecycle** tests — proving that a Feature, once really wired,
|
|
13
|
+
* behaves end-to-end (e.g. a Challenge submits its result when the student leaves the slide).
|
|
14
|
+
* For pure **logic** tests of a single UC or PM, a hand-wired `makeAppObjectRepo()` rig with
|
|
15
|
+
* the collaborators mocked at the boundary is lighter and still preferred — see
|
|
16
|
+
* `src/ObjectPick/UseCases/TrySubmitObjectPickUC.test.ts` as the reference.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // LabelDrop's submit path depends on Challenge (for `selectedChallenge`) and the
|
|
20
|
+
* // Dispatcher (the Host boundary). List dependencies first, exactly as a Slide App would.
|
|
21
|
+
* const { appObjects } = setupFeatureForTesting([
|
|
22
|
+
* makeDispatcherFeatureFactory,
|
|
23
|
+
* makeChallengeFeatureFactory,
|
|
24
|
+
* makeLabelDropFeatureFactory,
|
|
25
|
+
* ]);
|
|
26
|
+
* // Then act through a Controller / navigation seam and assert through an Adapter VM or a
|
|
27
|
+
* // dispatcher mock registered before setup.
|
|
28
|
+
*/
|
|
29
|
+
import { AppObjectRepo, DomainFactory } from "@vived/core";
|
|
30
|
+
export interface FeatureTestContext {
|
|
31
|
+
/** The live repo, wired through the given FeatureFactories exactly as production does. */
|
|
32
|
+
appObjects: AppObjectRepo;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Wire one or more Features into a fresh repo for a feature-context test.
|
|
36
|
+
*
|
|
37
|
+
* @param featureFactories The `make<Feature>FeatureFactory` functions to wire, in the order a
|
|
38
|
+
* Slide App would compose them — a Feature whose `finalSetup` depends on another Feature's
|
|
39
|
+
* entities must be listed *after* that Feature.
|
|
40
|
+
* @param seed Optional callback run *before* the factories are constructed. Use it to stand up
|
|
41
|
+
* the boundary singletons a Feature reads at construction time (many Feature UCs resolve
|
|
42
|
+
* siblings via `getCachedSingleton`, which THROWS when absent — e.g. `BaseAppState`,
|
|
43
|
+
* `ChallengeEntity`). Seed real entities or their Mocks here instead of pulling every
|
|
44
|
+
* dependency Feature's factory into the cluster.
|
|
45
|
+
* @returns `{ appObjects }` — resolve Controllers and Adapters from it to act and assert.
|
|
46
|
+
*/
|
|
47
|
+
export declare function setupFeatureForTesting(featureFactories: ((appObjects: AppObjectRepo) => DomainFactory)[], seed?: (appObjects: AppObjectRepo) => void): FeatureTestContext;
|
|
48
|
+
//# sourceMappingURL=setupFeatureForTesting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupFeatureForTesting.d.ts","sourceRoot":"","sources":["../../../src/TestUtils/setupFeatureForTesting.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EACL,aAAa,EACb,aAAa,EAGd,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,kBAAkB;IACjC,0FAA0F;IAC1F,UAAU,EAAE,aAAa,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,gBAAgB,EAAE,CAAC,CAAC,UAAU,EAAE,aAAa,KAAK,aAAa,CAAC,EAAE,EAClE,IAAI,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,KAAK,IAAI,GACzC,kBAAkB,CAiBpB"}
|