@media-quest/builder 0.0.25 → 0.0.26

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.
Files changed (44) hide show
  1. package/package.json +15 -15
  2. package/src/Builder-option.ts +64 -64
  3. package/src/Builder-page.spec.ts +2 -160
  4. package/src/Builder-page.ts +6 -83
  5. package/src/Builder-question.spec.ts +68 -68
  6. package/src/Builder-question.ts +102 -102
  7. package/src/Builder-schema.spec.ts +86 -114
  8. package/src/Builder-schema.ts +13 -9
  9. package/src/Builder-text.spec.ts +24 -24
  10. package/src/Builder-text.ts +57 -57
  11. package/src/BuilderObject.ts +30 -29
  12. package/src/BuilderTag.ts +96 -96
  13. package/src/builder-compiler.ts +1 -1
  14. package/src/code-book/codebook-variable.ts +29 -0
  15. package/src/{codebook.ts → code-book/codebook.ts} +72 -72
  16. package/src/primitives/ID.spec.ts +39 -39
  17. package/src/primitives/ID.ts +138 -119
  18. package/src/primitives/page-prefix.ts +59 -59
  19. package/src/primitives/varID.ts +12 -12
  20. package/src/public-api.ts +28 -26
  21. package/src/rulebuilder/Builder-rule.spec.ts +323 -323
  22. package/src/rulebuilder/Builder-rule.ts +191 -191
  23. package/src/rulebuilder/RuleBuilder-test-utils.ts +320 -320
  24. package/src/rulebuilder/RuleInput.ts +30 -30
  25. package/src/rulebuilder/RuleVariable.ts +34 -48
  26. package/src/rulebuilder/SingleSelectItem.ts +9 -8
  27. package/src/rulebuilder/condition/Builder-condition-group.ts +14 -6
  28. package/src/rulebuilder/condition/Builder-condition.spec.ts +12 -12
  29. package/src/rulebuilder/condition/Builder-condition.ts +17 -13
  30. package/src/rulebuilder/index.ts +16 -3
  31. package/src/rulebuilder/page-action-manager.ts +33 -33
  32. package/src/rulebuilder/rule2/Rule2.ts +211 -215
  33. package/src/schema-config.ts +25 -25
  34. package/src/sum-score/sum-score-answer.ts +6 -0
  35. package/src/sum-score/sum-score-manager.spec.ts +189 -0
  36. package/src/sum-score/sum-score-manager.ts +154 -0
  37. package/src/sum-score/sum-score-membership.ts +45 -0
  38. package/src/sum-score/sum-score-variable.spec.ts +151 -0
  39. package/src/sum-score/sum-score-variable.ts +36 -0
  40. package/src/{variable → sum-score}/sum-score.ts +122 -130
  41. package/tsconfig.tsbuildinfo +1 -1
  42. package/src/variable/b-variable.ts +0 -68
  43. package/src/variable/mq-variable.spec.ts +0 -147
  44. package/src/variable/sum-score-variable.ts +0 -50
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
- {
2
- "name": "@media-quest/builder",
3
- "version": "0.0.25",
4
- "description": "Builder library for Media-quest schemas",
5
- "main": "src/public-api.ts",
6
- "license": "MIT",
7
- "scripts": {
8
- "tsc:check:builder": "tsc --watch --noEmit",
9
- "clean": "rimraf dist",
10
- "buildXXX": "npm run clean && tsup src/public-api.ts --sourcemap inline --format cjs,esm --dts"
11
- },
12
- "dependencies": {
13
- "@media-quest/engine": "0.0.25"
14
- }
15
- }
1
+ {
2
+ "name": "@media-quest/builder",
3
+ "version": "0.0.26",
4
+ "description": "Builder library for Media-quest schemas",
5
+ "main": "src/public-api.ts",
6
+ "license": "MIT",
7
+ "scripts": {
8
+ "tsc:check:builder": "tsc --watch --noEmit",
9
+ "clean": "rimraf dist",
10
+ "buildXXX": "npm run clean && tsup src/public-api.ts --sourcemap inline --format cjs,esm --dts"
11
+ },
12
+ "dependencies": {
13
+ "@media-quest/engine": "0.0.26"
14
+ }
15
+ }
@@ -1,64 +1,64 @@
1
- import { BuilderObject } from "./BuilderObject";
2
- import type { BuilderOptionTheme } from "./theme/IDefaultTheme";
3
- import { DefaultTheme } from "./theme/IDefaultTheme";
4
- import { AudioFile } from "./media-files";
5
- import { OptionID } from "./primitives/ID";
6
-
7
- export interface BuilderOptionDto {
8
- readonly id: OptionID;
9
- readonly value: number;
10
- readonly label: string;
11
- readonly labelAudio?: AudioFile;
12
- }
13
-
14
- export class BuilderOption extends BuilderObject<"builder-question-option", BuilderOptionDto> {
15
- readonly objectType = "builder-question-option";
16
- id: OptionID;
17
- value: number;
18
- label = "";
19
- private _labelAudioFile: AudioFile | false = false;
20
- get labelAudioFile() {
21
- return this._labelAudioFile;
22
- }
23
- set labelAudioFile(audioFile: AudioFile | false) {
24
- this._labelAudioFile = audioFile;
25
- }
26
-
27
- private constructor(dto: BuilderOptionDto) {
28
- super(dto);
29
- this.id = dto.id;
30
- this.value = dto.value;
31
- this.label = dto.label;
32
- // this.theme = dto.theme;
33
- }
34
- public static create(value: number, label: string) {
35
- const id = OptionID.create();
36
- const dto: BuilderOptionDto = {
37
- id,
38
- value,
39
- label,
40
- };
41
- const instance = new BuilderOption(dto);
42
- return instance;
43
- }
44
-
45
- public static fromJson(dto: BuilderOptionDto) {
46
- const instance = new BuilderOption(dto);
47
- return instance;
48
- }
49
-
50
- toJson(): BuilderOptionDto {
51
- const dto: BuilderOptionDto = {
52
- id: this.id,
53
- value: this.value,
54
- label: this.label,
55
- };
56
- return dto;
57
- }
58
-
59
- clone(): BuilderOptionDto {
60
- const dto = this.toJson();
61
- const cloneDto: BuilderOptionDto = { ...dto, id: OptionID.create() };
62
- return cloneDto;
63
- }
64
- }
1
+ import { BuilderObject } from "./BuilderObject";
2
+ import type { BuilderOptionTheme } from "./theme/IDefaultTheme";
3
+ import { DefaultTheme } from "./theme/IDefaultTheme";
4
+ import { AudioFile } from "./media-files";
5
+ import { OptionID } from "./primitives/ID";
6
+
7
+ export interface BuilderOptionDto {
8
+ readonly id: OptionID;
9
+ readonly value: number;
10
+ readonly label: string;
11
+ readonly labelAudio?: AudioFile;
12
+ }
13
+
14
+ export class BuilderOption extends BuilderObject<"builder-question-option", BuilderOptionDto> {
15
+ readonly objectType = "builder-question-option";
16
+ id: OptionID;
17
+ value: number;
18
+ label = "";
19
+ private _labelAudioFile: AudioFile | false = false;
20
+ get labelAudioFile() {
21
+ return this._labelAudioFile;
22
+ }
23
+ set labelAudioFile(audioFile: AudioFile | false) {
24
+ this._labelAudioFile = audioFile;
25
+ }
26
+
27
+ private constructor(dto: BuilderOptionDto) {
28
+ super(dto);
29
+ this.id = dto.id;
30
+ this.value = dto.value;
31
+ this.label = dto.label;
32
+ // this.theme = dto.theme;
33
+ }
34
+ public static create(value: number, label: string) {
35
+ const id = OptionID.create();
36
+ const dto: BuilderOptionDto = {
37
+ id,
38
+ value,
39
+ label,
40
+ };
41
+ const instance = new BuilderOption(dto);
42
+ return instance;
43
+ }
44
+
45
+ public static fromJson(dto: BuilderOptionDto) {
46
+ const instance = new BuilderOption(dto);
47
+ return instance;
48
+ }
49
+
50
+ toJson(): BuilderOptionDto {
51
+ const dto: BuilderOptionDto = {
52
+ id: this.id,
53
+ value: this.value,
54
+ label: this.label,
55
+ };
56
+ return dto;
57
+ }
58
+
59
+ clone(): BuilderOptionDto {
60
+ const dto = this.toJson();
61
+ const cloneDto: BuilderOptionDto = { ...dto, id: OptionID.create() };
62
+ return cloneDto;
63
+ }
64
+ }
@@ -16,7 +16,6 @@ const deleteIdsFromPage = (page: BuilderPageDto) => {
16
16
  });
17
17
  };
18
18
  U.deleteProp(page, "id");
19
- page.questions.forEach(deleteIdsFromQuestion);
20
19
  deleteIdsFromQuestion(page.defaultQuestion);
21
20
  return page;
22
21
  };
@@ -64,7 +63,6 @@ const questionPageDto: BuilderPageDto = {
64
63
  // id: "p1" as BuilderObjectId.PageID,
65
64
  id: PageID.create(),
66
65
  prefix: PagePrefix.fromStringOrThrow("pxx"),
67
- questions: [],
68
66
  };
69
67
 
70
68
  const multiQuestionPageDto: BuilderPageDto = {
@@ -92,56 +90,6 @@ const multiQuestionPageDto: BuilderPageDto = {
92
90
 
93
91
  id: PageID.create(),
94
92
  prefix: PagePrefix.fromStringOrThrow("pxx"),
95
- questions: [
96
- {
97
- id: QuestionID.dummy.a,
98
- prefix: "a",
99
- text: "har du..",
100
- _type: "select-one",
101
- // options: []
102
- options: [
103
- {
104
- id: "q3-opt1" as OptionID,
105
- value: 0,
106
- label: "Nei",
107
- },
108
- {
109
- id: "q3-opt2" as OptionID,
110
- value: 1,
111
- label: "Ja",
112
- },
113
- {
114
- id: "q3-opt3" as OptionID,
115
- value: 9,
116
- label: "Vet ikke",
117
- },
118
- ],
119
- },
120
- {
121
- id: QuestionID.create(),
122
- prefix: "a",
123
- text: "har du..",
124
- _type: "select-one",
125
- // options: []
126
- options: [
127
- {
128
- id: OptionID.dummy.a,
129
- value: 0,
130
- label: "Nei",
131
- },
132
- {
133
- id: OptionID.dummy.b,
134
- value: 1,
135
- label: "Ja",
136
- },
137
- {
138
- id: OptionID.dummy.c,
139
- value: 9,
140
- label: "Vet ikke",
141
- },
142
- ],
143
- },
144
- ],
145
93
  };
146
94
 
147
95
  let page = BuilderPage.create("info-page", PagePrefix.fromStringOrThrow("a"));
@@ -160,39 +108,6 @@ describe("Builder Page", () => {
160
108
  expect(multiQuestionPageDto).toStrictEqual(asJson2);
161
109
  // expect(page1.prefix).toBe(pageDto.prefix);
162
110
  });
163
- test("Can change question type", () => {
164
- expect(page.questions.length).toBe(0);
165
- page.addQuestion("select-one");
166
- page.addQuestion("select-one");
167
- expect(page.questions.length).toBe(2);
168
- page.pageType = "question";
169
- expect(page.questions.length).toBe(0);
170
- });
171
- test("Can add and delete questions", () => {
172
- page.pageType = "multi-select";
173
- expect(page.questions.length).toBe(1);
174
- const q1 = page.addQuestion("select-one");
175
- const q2 = page.addQuestion("select-one");
176
- expect(page.questions.length).toBe(3);
177
- page.deleteQuestion(q1);
178
- expect(page.questions.length).toBe(2);
179
- page.deleteQuestion(q2);
180
- expect(page.questions.length).toBe(1);
181
- // page.pageType = 'question';
182
- // expect(page.questions.length).toBe(0);
183
- });
184
- test("Can add question at concrete index. ", () => {
185
- page.pageType = "multi-select";
186
- expect(page.questions.length).toBe(1);
187
- const q1 = page.addQuestion("select-one", 0);
188
- expect(page.questions[0].id).toBe(q1.id);
189
- const q2 = page.addQuestion("select-one", 1);
190
- expect(page.questions[1].id).toBe(q2.id);
191
- expect(page.questions.length).toBe(3);
192
- const q3 = page.addQuestion("email", 2);
193
- expect(page.questions[2]).toBe(q3);
194
- expect(q3.type).toBe("email");
195
- });
196
111
  test("Can clone a page and everything except id is equal ", () => {
197
112
  const page1 = BuilderPage.create("info-page", PagePrefix.fromStringOrThrow("as"));
198
113
  const clone1 = BuilderPage.fromJson(page1.clone());
@@ -220,85 +135,12 @@ describe("Builder Page", () => {
220
135
  const testDtoIds = (dto: BuilderPageDto) => {
221
136
  const instance = BuilderPage.fromJson(dto);
222
137
  const clone = BuilderPage.fromJson(instance.clone());
223
- const p2QuestionIds = instance.questions.map((q) => q.id);
224
- const cloneQuestionIds = clone.questions.map((q) => q.id);
225
138
 
226
- // expect(instance.id).to.not.eq(clone.id);
227
- // expect(instance.defaultQuestion.id).to.not.eq(clone.defaultQuestion.id);
228
- expect(p2QuestionIds.length).toBe(cloneQuestionIds.length);
229
- p2QuestionIds.forEach((id, index) => {
230
- expect(id).not.toBe(cloneQuestionIds[index]);
231
- });
232
-
233
- instance.questions.forEach((q, qIndex) => {
234
- const cloneQ = clone.questions[qIndex];
235
- expect(cloneQ).toBeDefined();
236
- expect(q.id).not.toBe(cloneQ.id);
237
- q.options.forEach((op, opIndex) => {
238
- const cloneOp = cloneQ.options[opIndex];
239
- expect(cloneOp).toBeDefined();
240
- expect(op.id).not.toBe(cloneOp.id);
241
- });
242
- });
243
-
244
- // expect(p)
139
+ testDtoIds(questionPageDto);
140
+ testDtoIds(multiQuestionPageDto);
245
141
  };
246
- testDtoIds(questionPageDto);
247
- testDtoIds(multiQuestionPageDto);
248
- });
249
- test("Can insert a new Question at index", () => {
250
- const page1 = BuilderPage.create("form", pxx);
251
- const q1 = page1.addQuestion("select-one");
252
- const q2 = page1.addQuestion("select-many");
253
- expect(page1.questions.length).toBe(3);
254
- expect(page1.questions[1]).toBe(q1);
255
- const q1Clone = BuilderQuestion.fromJson(q1.clone());
256
- const result10 = page1.insertQuestion(q1Clone, 10);
257
- expect(result10).toBeFalsy();
258
- const result1 = page1.insertQuestion(q1Clone, 1);
259
- expect(result1).toBeTruthy();
260
- expect(page1.questions[1]).toBe(q1Clone);
261
- });
262
- test("Can not insert a duplicate question", () => {
263
- const page1 = BuilderPage.create("form", pxx);
264
- const q1 = page1.addQuestion("select-one");
265
- expect(page1.questions.length).toBe(2);
266
- expect(page1.questions[1]).toBe(q1);
267
- const result1 = page1.insertQuestion(q1, 0);
268
- expect(page1.questions.length).toBe(2);
269
- expect(result1).toBeFalsy();
270
- });
271
-
272
- test("Can move a question", () => {
273
- const page1 = BuilderPage.create("form", pxx);
274
- const q1 = page1.addQuestion("select-many");
275
- const q2 = page1.addQuestion("select-one");
276
- const q3 = page1.addQuestion("select-one");
277
- const q4 = page1.addQuestion("select-one");
278
- expect(page1.questions.length).toBe(5);
279
- const m1 = page1.moveQuestion(q1, 0);
280
- expect(page1.questions.length).toBe(5);
281
- expect(page1.questions[0]).toBe(q1);
282
- expect(m1).toBeTruthy();
283
- const illegalMove = page1.moveQuestion(q2, -1);
284
- expect(illegalMove).toBeFalsy();
285
- expect(page1.questions.length).toBe(5);
286
- const m3 = page1.moveQuestion(q4, 1);
287
- expect(m3).toBe(true);
288
- expect(page1.questions[1]).toBe(q4);
289
142
  });
290
143
 
291
- test("Can not move a question that is not in questions-array", () => {
292
- const prefix = PagePrefix.fromStringOrThrow("as1");
293
- const page1 = BuilderPage.create("form", prefix);
294
- const q1 = page1.addQuestion("select-many");
295
- const q2 = page1.addQuestion("select-one");
296
- expect(page1.questions.length).toBe(3);
297
- const newQuestion = BuilderQuestion.create("select-one");
298
- const m1 = page1.moveQuestion(newQuestion, 0);
299
- expect(page1.questions.length).toBe(3);
300
- expect(m1).toBe(false);
301
- });
302
144
  test("Can get all rule-variables.", () => {
303
145
  const prefix = PagePrefix.fromStringOrThrow("as1");
304
146
  const page = BuilderPage.create("question", prefix);
@@ -7,7 +7,7 @@ import type { BuilderMainVideoDto } from "./BuilderMainVideoDto";
7
7
  import type { BuilderMainImageDto } from "./BuilderMainImageDto";
8
8
  import type { BuilderMainTextDto } from "./BuilderMainText";
9
9
  import { BuilderMainText } from "./BuilderMainText";
10
- import { BuilderVariableOption, QuestionVariable } from "./rulebuilder/RuleVariable";
10
+ import { RuleVariableOption, RuleQuestionVariable } from "./rulebuilder";
11
11
  import { DUtil } from "@media-quest/engine";
12
12
  import { PagePrefix, PagePrefixValue } from "./primitives/page-prefix";
13
13
  import { VarID } from "./primitives/varID";
@@ -24,11 +24,9 @@ export interface BuilderPageDto {
24
24
  mainText: BuilderMainTextDto;
25
25
  nextButton: BuilderOptionDto;
26
26
  defaultQuestion: BuilderQuestionDto;
27
- questions: Array<BuilderQuestionDto>;
28
27
  mainMedia?: BuilderMainImageDto | BuilderMainVideoDto;
29
28
  autoplaySequence: Array<string>;
30
29
  tags: ReadonlyArray<string>;
31
- // sumScoreVariables: Array<BuilderObjectId.SumScoreVariableId>
32
30
  }
33
31
 
34
32
  export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
@@ -36,7 +34,6 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
36
34
  readonly id: PageID;
37
35
  private _pageType: BuilderPageType;
38
36
  private _prefix: PagePrefix;
39
- private _questions: Array<BuilderQuestion> = [];
40
37
  private readonly _tags: Set<string>;
41
38
  private _backgroundColor = "#FFFFFF";
42
39
  mainMedia: BuilderMainVideoDto | BuilderMainImageDto | false = false;
@@ -63,7 +60,7 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
63
60
  nextButton: nextButtonDto,
64
61
  mainText: mainTextDto,
65
62
  prefix: _prefix,
66
- questions: [],
63
+ // questions: [],
67
64
  tags: [],
68
65
  };
69
66
 
@@ -84,74 +81,11 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
84
81
  this.mainText = BuilderMainText.fromJson(dto.mainText);
85
82
  this.nextButton = BuilderOption.fromJson(dto.nextButton);
86
83
  this.defaultQuestion = BuilderQuestion.fromJson(dto.defaultQuestion);
87
- this._questions = dto.questions.map((q) => BuilderQuestion.fromJson(q));
88
84
  const tagList: string[] = Array.isArray(dto.tags) ? dto.tags : [];
89
85
  this._tags = new Set(tagList);
90
86
  if (dto.mainMedia) {
91
87
  this.mainMedia = dto.mainMedia;
92
88
  }
93
- this.updateRows();
94
- }
95
-
96
- insertQuestion(question: BuilderQuestion, atIndex: number): boolean {
97
- const validIndexFn = U.isInRange(0, this._questions.length);
98
- if (!validIndexFn(atIndex)) {
99
- return false;
100
- }
101
- const hasQuestion = !!this._questions.find((q) => q.id === question.id);
102
- if (hasQuestion) {
103
- return false;
104
- }
105
- this._questions.splice(atIndex, 0, question);
106
- return true;
107
- }
108
-
109
- addQuestion(type: BuilderQuestionType, atIndex = -1): BuilderQuestion {
110
- const question = BuilderQuestion.create(type);
111
- if (atIndex < this._questions.length && atIndex >= 0) {
112
- this._questions.splice(atIndex, 0, question);
113
- } else {
114
- this._questions.push(question);
115
- }
116
- return question;
117
- }
118
-
119
- /**
120
- * Move a question in questions-array
121
- * @param question (reference)
122
- * @param toIndex
123
- */
124
- moveQuestion(question: BuilderQuestion, toIndex: number): boolean {
125
- const validToIndexFn = U.isInRange(0, this._questions.length);
126
- if (!validToIndexFn(toIndex)) {
127
- return false;
128
- }
129
- const currentIndex = this._questions.indexOf(question);
130
- if (currentIndex < 0) {
131
- return false;
132
- }
133
- this._questions.splice(currentIndex, 1);
134
- this._questions.splice(toIndex, 0, question);
135
- return true;
136
- }
137
-
138
- deleteQuestion(question: BuilderQuestion) {
139
- this._questions = this._questions.filter((q) => q !== question);
140
- // TODO EMIT DELETED QUESTION.
141
- this.updateRows();
142
- }
143
- private updateRows() {
144
- if (this._pageType === "question" || this._pageType === "info-page") {
145
- this._questions = [];
146
- }
147
- if (this._pageType === "form" && this._questions.length === 0) {
148
- this._questions = [];
149
- this.addQuestion("text");
150
- }
151
- if (this._pageType === "multi-select" && this._questions.length === 0) {
152
- this._questions = [];
153
- this.addQuestion("text");
154
- }
155
89
  }
156
90
 
157
91
  public addTag(tag: string) {
@@ -163,15 +97,13 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
163
97
 
164
98
  set pageType(value: BuilderPageType) {
165
99
  this._pageType = value;
166
- // TODO Emit All questions that are deleted? Listen for removed variables??
167
- this.updateRows();
168
100
  }
169
101
 
170
102
  getQuestionVariables(
171
103
  modulePrefix: SchemaPrefix,
172
104
  pageNumber: number,
173
- ): ReadonlyArray<QuestionVariable> {
174
- const variables: QuestionVariable[] = [];
105
+ ): ReadonlyArray<RuleQuestionVariable> {
106
+ const variables: RuleQuestionVariable[] = [];
175
107
 
176
108
  if (this._pageType === "question") {
177
109
  const pagePrefix = this.prefix;
@@ -180,9 +112,9 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
180
112
  const op = this.defaultQuestion.options.map((o) => {
181
113
  const label = o.label;
182
114
  const value = o.value;
183
- return new BuilderVariableOption(label, value);
115
+ return new RuleVariableOption(label, value);
184
116
  });
185
- const singleVar = new QuestionVariable(varId, label, op, pageNumber);
117
+ const singleVar = new RuleQuestionVariable(varId, label, op, pageNumber);
186
118
  variables.push(singleVar);
187
119
  }
188
120
  return variables;
@@ -204,7 +136,6 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
204
136
  }
205
137
 
206
138
  toJson(): BuilderPageDto {
207
- const questions = this._questions.map((q) => q.toJson());
208
139
  const mainText = this.mainText.toJson();
209
140
  const nextButton = this.nextButton.toJson();
210
141
  const mainMedia = this.mainMedia;
@@ -217,7 +148,6 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
217
148
  tags: [...this.tags],
218
149
  prefix: this._prefix.value,
219
150
  defaultQuestion: this.defaultQuestion.toJson(),
220
- questions,
221
151
  };
222
152
  if (mainMedia) {
223
153
  dto.mainMedia = mainMedia;
@@ -229,15 +159,12 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
229
159
  const dto = this.toJson();
230
160
  const defaultQuestionClone = this.defaultQuestion.clone();
231
161
  const mainTextClone = JSON.parse(JSON.stringify(this.mainText));
232
- // const pagesClone = this
233
- const questionsClone = this.questions.map((q) => q.clone());
234
162
  const newId = PageID.create();
235
163
  const clone: BuilderPageDto = {
236
164
  ...dto,
237
165
  id: newId,
238
166
  defaultQuestion: defaultQuestionClone,
239
167
  mainText: mainTextClone,
240
- questions: questionsClone,
241
168
  };
242
169
  // const cloneDto
243
170
  return clone;
@@ -252,8 +179,4 @@ export class BuilderPage extends BuilderObject<"builder-page", BuilderPageDto> {
252
179
  this._backgroundColor = color;
253
180
  }
254
181
  }
255
-
256
- get questions(): ReadonlyArray<BuilderQuestion> {
257
- return this._questions;
258
- }
259
182
  }
@@ -1,68 +1,68 @@
1
- import type { BuilderQuestionDto } from "./Builder-question";
2
- import { BuilderQuestion } from "./Builder-question";
3
- import { OptionID, QuestionID } from "./primitives/ID";
4
-
5
- const question1: BuilderQuestionDto = {
6
- id: QuestionID.validateOrThrow("id-for-question-1"),
7
- prefix: "q1",
8
- text: "sadf",
9
- options: [],
10
- _type: "select-one",
11
- };
12
-
13
- const question2: BuilderQuestionDto = {
14
- id: QuestionID.validateOrThrow("id-for-question-2"),
15
- prefix: "a",
16
- text: "har du..",
17
- _type: "select-one",
18
- // options: []
19
- options: [
20
- {
21
- id: "q3-opt1" as OptionID,
22
- value: 0,
23
- label: "Nei",
24
- },
25
- {
26
- id: "q3-opt2" as OptionID,
27
- value: 1,
28
- label: "Ja",
29
- },
30
- {
31
- id: "q3-opt3" as OptionID,
32
- value: 9,
33
- label: "Vet ikke",
34
- },
35
- ],
36
- };
37
-
38
- describe("Builder Question", () => {
39
- test("Can create question from json", () => {
40
- const q1 = BuilderQuestion.fromJson(question1);
41
- const q1AsJson = q1.toJson();
42
- expect(question1).toStrictEqual(q1AsJson);
43
- const q2Instance = BuilderQuestion.fromJson(question2);
44
- const q2AsJson = q2Instance.toJson();
45
- expect(question2).toStrictEqual(q2AsJson);
46
- });
47
- test("Can add options", () => {
48
- const q1 = BuilderQuestion.fromJson(question1);
49
- expect(q1.options.length).toBe(0);
50
- q1.addOption("Ja", 1);
51
- expect(q1.options.length).toBe(1);
52
- const nei = q1.addOption("Nei", 0, 0);
53
- expect(q1.options.length).toBe(2);
54
- expect(q1.options[0]).toBe(nei);
55
- const vetIkke = q1.addOption("Vet-ikke", 9);
56
- expect(q1.options.length).toBe(3);
57
- expect(q1.options[2]).toBe(vetIkke);
58
- });
59
- test("Can delete options", () => {
60
- const q = BuilderQuestion.fromJson(question2);
61
- expect(q.options.length).toBe(3);
62
- const o1 = q.options[0];
63
- const o2 = q.options[1];
64
- const o3 = q.options[2];
65
- const didDelete = q.deleteOption(o1);
66
- expect(q.options.length).toBe(2);
67
- });
68
- });
1
+ import type { BuilderQuestionDto } from "./Builder-question";
2
+ import { BuilderQuestion } from "./Builder-question";
3
+ import { OptionID, QuestionID } from "./primitives/ID";
4
+
5
+ const question1: BuilderQuestionDto = {
6
+ id: QuestionID.validateOrThrow("id-for-question-1"),
7
+ prefix: "q1",
8
+ text: "sadf",
9
+ options: [],
10
+ _type: "select-one",
11
+ };
12
+
13
+ const question2: BuilderQuestionDto = {
14
+ id: QuestionID.validateOrThrow("id-for-question-2"),
15
+ prefix: "a",
16
+ text: "har du..",
17
+ _type: "select-one",
18
+ // options: []
19
+ options: [
20
+ {
21
+ id: "q3-opt1" as OptionID,
22
+ value: 0,
23
+ label: "Nei",
24
+ },
25
+ {
26
+ id: "q3-opt2" as OptionID,
27
+ value: 1,
28
+ label: "Ja",
29
+ },
30
+ {
31
+ id: "q3-opt3" as OptionID,
32
+ value: 9,
33
+ label: "Vet ikke",
34
+ },
35
+ ],
36
+ };
37
+
38
+ describe("Builder Question", () => {
39
+ test("Can create question from json", () => {
40
+ const q1 = BuilderQuestion.fromJson(question1);
41
+ const q1AsJson = q1.toJson();
42
+ expect(question1).toStrictEqual(q1AsJson);
43
+ const q2Instance = BuilderQuestion.fromJson(question2);
44
+ const q2AsJson = q2Instance.toJson();
45
+ expect(question2).toStrictEqual(q2AsJson);
46
+ });
47
+ test("Can add options", () => {
48
+ const q1 = BuilderQuestion.fromJson(question1);
49
+ expect(q1.options.length).toBe(0);
50
+ q1.addOption("Ja", 1);
51
+ expect(q1.options.length).toBe(1);
52
+ const nei = q1.addOption("Nei", 0, 0);
53
+ expect(q1.options.length).toBe(2);
54
+ expect(q1.options[0]).toBe(nei);
55
+ const vetIkke = q1.addOption("Vet-ikke", 9);
56
+ expect(q1.options.length).toBe(3);
57
+ expect(q1.options[2]).toBe(vetIkke);
58
+ });
59
+ test("Can delete options", () => {
60
+ const q = BuilderQuestion.fromJson(question2);
61
+ expect(q.options.length).toBe(3);
62
+ const o1 = q.options[0];
63
+ const o2 = q.options[1];
64
+ const o3 = q.options[2];
65
+ const didDelete = q.deleteOption(o1);
66
+ expect(q.options.length).toBe(2);
67
+ });
68
+ });