notu 0.2.1 → 0.2.2

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.
@@ -1,407 +0,0 @@
1
- import { expect, test } from 'vitest';
2
- import Note from './Note';
3
- import Tag from './Tag';
4
- import Space from './Space';
5
- import Attr from './Attr';
6
-
7
-
8
- function newCleanTag(): Tag {
9
- const tag = new Tag('hello');
10
- tag.id = 123;
11
- tag.clean();
12
- return tag;
13
- }
14
-
15
- function newCleanAttr(): Attr {
16
- const attr = new Attr();
17
- attr.id = 234;
18
- attr.clean();
19
- return attr;
20
- }
21
-
22
-
23
- test('gets initiated with sensible defaults', () => {
24
- const note = new Note();
25
- expect(note.id).toBe(0);
26
- expect(note.date.getTime() / 1000).toBeCloseTo(new Date().getTime() / 1000);
27
- expect(note.text).toBe('');
28
- expect(note.archived).toBe(false);
29
- expect(note.spaceId).toBe(0);
30
- });
31
-
32
- test('can duplicate itself', () => {
33
- const note = new Note().clean();
34
- const space = new Space('hello');
35
- space.id = 123;
36
- note.space = space;
37
- const copy = note.duplicate();
38
- expect(copy.id).toBe(note.id);
39
- expect(copy.date).toBe(note.date);
40
- expect(copy.text).toBe(note.text);
41
- expect(copy.archived).toBe(note.archived);
42
- expect(copy.space).toBe(note.space);
43
- expect(copy.spaceId).toBe(note.spaceId);
44
- expect(copy.state).toBe(note.state);
45
- });
46
-
47
- test('Gets initiated as new', () => {
48
- const note = new Note();
49
- expect(note.isNew).toBe(true);
50
- });
51
-
52
-
53
- test('Set date marks note as dirty if currently clean', () => {
54
- const note = new Note().clean();
55
- note.date = new Date();
56
- expect(note.isDirty).toBe(true);
57
- });
58
-
59
- test('Set date doesnt change note state if new', () => {
60
- const note = new Note().new();
61
- note.date = new Date();
62
- expect(note.isNew).toBe(true);
63
- });
64
-
65
- test('Set date doesnt change note state if value not different', () => {
66
- const note = new Note().clean();
67
- note.date = note.date;
68
- expect(note.isClean).toBe(true);
69
- });
70
-
71
-
72
- test('Set text marks note as dirty if currently clean', () => {
73
- const note = new Note().clean();
74
- note.text = 'asdf';
75
- expect(note.isDirty).toBe(true);
76
- });
77
-
78
- test('Set text doesnt change note state if new', () => {
79
- const note = new Note().new();
80
- note.text = 'asdf';
81
- expect(note.isNew).toBe(true);
82
- });
83
-
84
- test('Set text doesnt change note state if value not different', () => {
85
- const note = new Note().clean();
86
- note.text = '';
87
- expect(note.isClean).toBe(true);
88
- });
89
-
90
-
91
- test('Set archived marks note as dirty if currently clean', () => {
92
- const note = new Note().clean();
93
- note.archived = !note.archived;
94
- expect(note.isDirty).toBe(true);
95
- });
96
-
97
- test('Set archived doesnt change note state if new', () => {
98
- const note = new Note().new();
99
- note.archived = !note.archived;
100
- expect(note.isNew).toBe(true);
101
- });
102
-
103
- test('Set archived doesnt change note state if value not different', () => {
104
- const note = new Note().clean();
105
- note.archived = note.archived;
106
- expect(note.isClean).toBe(true);
107
- });
108
-
109
-
110
- test('Set spaceId marks note as dirty if currently clean', () => {
111
- const note = new Note().clean();
112
- note.spaceId = 123;
113
- expect(note.isDirty).toBe(true);
114
- });
115
-
116
- test('Set spaceId doesnt change note state if new', () => {
117
- const note = new Note().new();
118
- note.spaceId = 123;
119
- expect(note.isNew).toBe(true);
120
- });
121
-
122
- test('Set spaceId doesnt change note state if value not different', () => {
123
- const note = new Note().clean();
124
- note.spaceId = note.spaceId;
125
- expect(note.isClean).toBe(true);
126
- });
127
-
128
- test('setOwnTag doesnt mark note as dirty', () => {
129
- const note = new Note().clean().setOwnTag('hello');
130
- expect(note.isClean).toBe(true);
131
- });
132
-
133
- test('setOwnTag with string creates tag with same id as note', () => {
134
- const note = new Note();
135
- note.id = 123;
136
- note.setOwnTag('hello');
137
- expect(note.ownTag.id).toBe(note.id);
138
- });
139
-
140
- test('setOwnTag can take tag object, rather than just name', () => {
141
- const note = new Note().setOwnTag(new Tag('hello'));
142
- expect(note.ownTag.name).toBe('hello');
143
- });
144
-
145
- test('setOwnTag with tag object will throw error if tag already set', () => {
146
- const note = new Note().setOwnTag('hello');
147
- expect(() => note.setOwnTag(new Tag('goodbye'))).toThrowError();
148
- });
149
-
150
- test('setOwnTag with tag object will throw error if tag id is non-zero and doesnt match note id', () => {
151
- const note = new Note().clean();
152
- note.id = 123;
153
- const tag = new Tag('hello');
154
- tag.id = 57;
155
- expect(() => note.setOwnTag(tag)).toThrowError();
156
- });
157
-
158
- test('removeOwnTag marks existing tag as deleted if clean', () => {
159
- const note = new Note().setOwnTag('hello');
160
- note.ownTag.clean();
161
- note.removeOwnTag();
162
- expect(note.ownTag.isDeleted).toBe(true);
163
- });
164
-
165
- test('removeOwnTag nulls out new tag', () => {
166
- const note = new Note().setOwnTag('hello');
167
- note.removeOwnTag();
168
- expect(note.ownTag).toBeNull();
169
- });
170
-
171
- test('Setting space with id different than current spaceId updates state', () => {
172
- const note = new Note();
173
- note.spaceId = 57;
174
- note.clean();
175
- const space = new Space('hello');
176
- space.id = 60;
177
-
178
- note.space = space;
179
-
180
- expect(note.spaceId).toBe(60);
181
- expect(note.isDirty).toBe(true);
182
- });
183
-
184
- test('Setting space with id same as current spaceId preserves state', () => {
185
- const note = new Note();
186
- note.spaceId = 80;
187
- note.clean();
188
- const space = new Space('hello');
189
- space.id = 80;
190
-
191
- note.space = space;
192
-
193
- expect(note.spaceId).toBe(80);
194
- expect(note.isClean).toBe(true);
195
- });
196
-
197
- test('Setting spaceId to new value removes space object', () => {
198
- const note = new Note();
199
- const space = new Space('hello');
200
- space.id = 80;
201
- note.space = space;
202
-
203
- note.spaceId = 81;
204
-
205
- expect(note.space).toBeNull();
206
- });
207
-
208
- test('Setting spaceId to same as current space id preserves it', () => {
209
- const note = new Note();
210
- const space = new Space('hello');
211
- space.id = 80;
212
- note.space = space;
213
-
214
- note.spaceId = 80;
215
-
216
- expect(note.space.name).toBe('hello');
217
- });
218
-
219
-
220
- test('validate fails if spaceId is 0', () => {
221
- const model = new Note();
222
- model.spaceId = 0;
223
- expect(model.validate()).toBe(false);
224
- });
225
-
226
- test('validate fails if not new and id <= 0', () => {
227
- const model = new Note().clean();
228
- model.id = 0;
229
- model.spaceId = 123;
230
- expect(model.validate()).toBe(false);
231
- });
232
-
233
- test('validate throws error if arg set to true', () => {
234
- const model = new Note();
235
- model.spaceId = 0;
236
- expect(() => model.validate(true)).toThrowError();
237
- });
238
-
239
- test('validate calls validate on ownTag', () => {
240
- const note = new Note().setOwnTag('asdf');
241
- note.spaceId = 123;
242
- expect(note.validate()).toBe(true);
243
- note.ownTag.clean();
244
- expect(note.validate()).toBe(false);
245
- });
246
-
247
- test('validate calls validate on each added tag', () => {
248
- const note = new Note();
249
- note.spaceId = 123;
250
- const nt = note.addTag(newCleanTag());
251
- expect(note.validate()).toBe(true);
252
- nt.tagId = 0;
253
- expect(note.validate()).toBe(false);
254
- });
255
-
256
- test('validate calls validate on each added attr', () => {
257
- const note = new Note();
258
- note.spaceId = 123;
259
- const na = note.addAttr(newCleanAttr());
260
- expect(note.validate()).toBe(true);
261
- na.attrId = 0;
262
- expect(note.validate()).toBe(false);
263
- });
264
-
265
-
266
- test('addTag adds new NoteTag object', () => {
267
- const tag = newCleanTag();
268
- const note = new Note();
269
-
270
- note.addTag(tag);
271
-
272
- expect(note.tags.length).toBe(1);
273
- expect(note.tags[0].note).toBe(note);
274
- expect(note.tags[0].tag).toBe(tag);
275
- });
276
-
277
- test('addTag returns existing NoteTag object if trying to add duplicate tag', () => {
278
- const tag = newCleanTag();
279
- const note = new Note();
280
- note.addTag(tag);
281
-
282
- note.addTag(tag);
283
-
284
- expect(note.tags.length).toBe(1);
285
- expect(note.tags[0].note).toBe(note);
286
- expect(note.tags[0].tag).toBe(tag);
287
- });
288
-
289
- test('addTag undeletes existing NoteTag if trying to add duplicate tag', () => {
290
- const tag = newCleanTag();
291
- const note = new Note();
292
- const nt = note.addTag(tag);
293
- nt.delete();
294
-
295
- note.addTag(tag);
296
-
297
- expect(note.tags.length).toBe(1);
298
- expect(nt.isDirty).toBe(true);
299
- });
300
-
301
- test('addTag throws error if trying to add deleted tag', () => {
302
- const tag = newCleanTag().delete();
303
- const note = new Note();
304
- expect(() => note.addTag(tag)).toThrowError();
305
- });
306
-
307
- test('addTag prevents note from adding its own tag', () => {
308
- const note = new Note();
309
- note.id = 123;
310
- note.setOwnTag('test');
311
-
312
- expect(() => note.addTag(note.ownTag)).toThrowError();
313
- });
314
-
315
- test('addTag prevents note from adding tag that hasnt been saved yet', () => {
316
- const note = new Note();
317
- expect(() => note.addTag(new Tag())).toThrowError();
318
- });
319
-
320
- test('removeTag removes newly added tag from note', () => {
321
- const tag = newCleanTag();
322
- const note = new Note();
323
- note.addTag(tag);
324
-
325
- note.removeTag(tag);
326
-
327
- expect(note.tags.length).toBe(0);
328
- });
329
-
330
- test('removeTag marks existing tag on note as deleted', () => {
331
- const tag = newCleanTag();
332
- const note = new Note();
333
- note.addTag(tag).clean();
334
-
335
- note.removeTag(tag);
336
-
337
- expect(note.tags.length).toBe(1);
338
- expect(note.tags[0].isDeleted).toBe(true);
339
- });
340
-
341
-
342
- test('addAttr adds new NoteAttr object', () => {
343
- const attr = newCleanAttr();
344
- const note = new Note();
345
-
346
- note.addAttr(attr);
347
-
348
- expect(note.attrs.length).toBe(1);
349
- expect(note.attrs[0].note).toBe(note);
350
- expect(note.attrs[0].attr).toBe(attr);
351
- });
352
-
353
- test('addAttr returns existing NoteAttr object if trying to add duplicate attr', () => {
354
- const attr = newCleanAttr();
355
- const note = new Note();
356
- note.addAttr(attr);
357
-
358
- note.addAttr(attr);
359
-
360
- expect(note.attrs.length).toBe(1);
361
- expect(note.attrs[0].note).toBe(note);
362
- expect(note.attrs[0].attr).toBe(attr);
363
- });
364
-
365
- test('addAttr undeletes existing NoteAttr if trying to add duplicate tag', () => {
366
- const attr = newCleanAttr();
367
- const note = new Note();
368
- const na = note.addAttr(attr);
369
- na.delete();
370
-
371
- note.addAttr(attr);
372
-
373
- expect(note.attrs.length).toBe(1);
374
- expect(na.isDirty).toBe(true);
375
- });
376
-
377
- test('addAttr throws error if trying to add deleted attr', () => {
378
- const attr = newCleanAttr().delete();
379
- const note = new Note();
380
- expect(() => note.addAttr(attr)).toThrowError();
381
- });
382
-
383
- test('addAttr prevents note from adding attr that hasnt been saved yet', () => {
384
- const note = new Note();
385
- expect(() => note.addAttr(new Attr())).toThrowError();
386
- });
387
-
388
- test('removeAttr removes newly added attr from note', () => {
389
- const attr = newCleanAttr();
390
- const note = new Note();
391
- note.addAttr(attr);
392
-
393
- note.removeAttr(attr);
394
-
395
- expect(note.attrs.length).toBe(0);
396
- });
397
-
398
- test('removeAttr marks existing attr on note as deleted', () => {
399
- const attr = newCleanAttr();
400
- const note = new Note();
401
- note.addAttr(attr).clean();
402
-
403
- note.removeAttr(attr);
404
-
405
- expect(note.attrs.length).toBe(1);
406
- expect(note.attrs[0].isDeleted).toBe(true);
407
- });
@@ -1,204 +0,0 @@
1
- 'use strict';
2
-
3
- import ModelWithState from './ModelWithState';
4
- import NoteAttr from './NoteAttr';
5
- import NoteTag from './NoteTag';
6
- import Space from './Space';
7
- import Tag from './Tag';
8
- import Attr from './Attr';
9
-
10
-
11
- export default class Note extends ModelWithState<Note> {
12
- id: number = 0;
13
-
14
-
15
- private _date: Date = new Date();
16
- get date(): Date { return this._date; }
17
- set date(value: Date) {
18
- if (value !== this._date) {
19
- this._date = value;
20
- if (this.isClean)
21
- this.dirty();
22
- }
23
- }
24
-
25
-
26
- private _text: string = '';
27
- get text(): string { return this._text; }
28
- set text(value: string) {
29
- if (value !== this._text) {
30
- this._text = value;
31
- if (this.isClean)
32
- this.dirty();
33
- }
34
- }
35
-
36
-
37
- private _archived: boolean = false;
38
- get archived(): boolean { return this._archived; }
39
- set archived(value: boolean) {
40
- if (value !== this._archived) {
41
- this._archived = value;
42
- if (this.isClean)
43
- this.dirty();
44
- }
45
- }
46
-
47
-
48
- private _spaceId: number = 0;
49
- get spaceId(): number { return this._spaceId; }
50
- set spaceId(value: number) {
51
- if (value !== this._spaceId) {
52
- this._spaceId = value;
53
- if (value !== this.space?.id ?? 0)
54
- this._space = null;
55
- if (this.isClean)
56
- this.dirty();
57
- }
58
- }
59
-
60
- private _space: Space = null;
61
- get space(): Space { return this._space; }
62
- set space(value: Space) {
63
- this._space = value;
64
- this.spaceId = value?.id ?? 0;
65
- }
66
-
67
-
68
- private _ownTag: Tag = null;
69
- get ownTag(): Tag { return this._ownTag; }
70
-
71
- setOwnTag(tag: string | Tag): Note {
72
- if (typeof tag === 'string') {
73
- if (this.ownTag == null)
74
- this._ownTag = new Tag();
75
- this.ownTag.name = tag;
76
- this.ownTag.id = this.id;
77
- }
78
- else {
79
- if (!!this.ownTag)
80
- throw new Error('Note has already had its tag set. If you would like to change the tag name, call setTag with just a string specifying the new tag name.');
81
- if (tag.id != 0 && tag.id != this.id)
82
- throw new Error('Attempted to set tag to note with non-matching ID. Added tag id must either match the note id, which indicates that the tag has already been added to the note. Otherwise the tag id must be zero, indicating that the tag still needs to be added.')
83
- this._ownTag = tag;
84
- }
85
- return this;
86
- }
87
-
88
- removeOwnTag(): Note {
89
- if (!this.ownTag)
90
- return;
91
- if (this.ownTag.isNew)
92
- this._ownTag = null;
93
- else
94
- this.ownTag.delete();
95
- }
96
-
97
-
98
- private _tags: Array<NoteTag> = [];
99
- get tags(): Array<NoteTag> { return this._tags; }
100
-
101
- addTag(tag: Tag): NoteTag {
102
- if (tag.isDeleted)
103
- throw Error('Cannot add a tag marked as deleted to a note');
104
- if (tag.isNew)
105
- throw Error('Cannot add a tag that hasn\'t yet been saved to a note');
106
- if (tag.id == this.id)
107
- throw Error('Note cannot add its own tag as a linked tag');
108
- let nt = this.tags.find(x => x.tagId == tag.id);
109
- if (!!nt) {
110
- if (nt.isDeleted)
111
- nt.dirty();
112
- return nt;
113
- }
114
- nt = new NoteTag();
115
- nt.note = this;
116
- nt.tag = tag;
117
- this._tags.push(nt);
118
- return nt;
119
- }
120
-
121
- removeTag(tag: Tag): Note {
122
- const nt = this.tags.find(x => x.tagId == tag.id);
123
- if (!nt)
124
- return this;
125
-
126
- if (nt.isNew)
127
- this._tags = this._tags.filter(x => x !== nt);
128
- else
129
- nt.delete();
130
- return this;
131
- }
132
-
133
-
134
- private _attrs: Array<NoteAttr> = [];
135
- get attrs(): Array<NoteAttr> { return this._attrs; }
136
-
137
- addAttr(attr: Attr): NoteAttr {
138
- if (attr.isDeleted)
139
- throw Error('Cannot add an attribute marked as deleted to a note');
140
- if (attr.isNew)
141
- throw Error('Cannot add an attribute that hasn\'t yet been saved to a note');
142
- let na = this.attrs.find(x => x.attrId == attr.id);
143
- if (!!na) {
144
- if (na.isDeleted)
145
- na.dirty();
146
- return na;
147
- }
148
- na = new NoteAttr();
149
- na.note = this;
150
- na.attr = attr;
151
- this._attrs.push(na);
152
- return na;
153
- }
154
-
155
- removeAttr(attr: Attr): Note {
156
- const na = this.attrs.find(x => x.attrId == attr.id);
157
- if (!na)
158
- return this;
159
-
160
- if (na.isNew)
161
- this._attrs = this._attrs.filter(x => x !== na);
162
- else
163
- na.delete();
164
- return this;
165
- }
166
-
167
-
168
- duplicate(): Note {
169
- const output = new Note();
170
- output.id = this.id;
171
- output.date = this.date;
172
- output.text = this.text;
173
- output.archived = this.archived;
174
- output.space = this.space;
175
- output.state = this.state;
176
- return output;
177
- }
178
-
179
-
180
- validate(throwError: boolean = false): boolean {
181
- let output = null;
182
-
183
- if (this.spaceId <= 0)
184
- output = 'Note spaceId must be greater than zero.';
185
- else if (!this.isNew && this.id <= 0)
186
- output = 'Note id must be greater than zero if in non-new state.';
187
-
188
- if (throwError && output != null)
189
- throw Error(output);
190
-
191
- if (!!this.ownTag && !this.ownTag.validate(throwError))
192
- return false;
193
- for (const nt of this.tags) {
194
- if (!nt.validate(throwError))
195
- return false;
196
- }
197
- for (const na of this.attrs) {
198
- if (!na.validate(throwError))
199
- return false;
200
- }
201
-
202
- return output == null;
203
- }
204
- }