@schorts/shared-kernel 1.0.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.
Files changed (88) hide show
  1. package/.idx/airules.md +186 -0
  2. package/.idx/dev.nix +54 -0
  3. package/.vscode/settings.json +7 -0
  4. package/CHANGELOG +0 -0
  5. package/README.md +98 -0
  6. package/__tests__/auth/auth-provider.test.ts +45 -0
  7. package/__tests__/auth/require-auth.decorator.test.ts +88 -0
  8. package/__tests__/criteria/criteria.test.ts +159 -0
  9. package/__tests__/criteria/direction.test.ts +11 -0
  10. package/__tests__/criteria/filter-criterion.test.ts +15 -0
  11. package/__tests__/criteria/operator.test.ts +22 -0
  12. package/__tests__/criteria/order.test.ts +14 -0
  13. package/__tests__/domain-events/domain-event-primitives.test.ts +34 -0
  14. package/__tests__/domain-events/domain-event.test.ts +50 -0
  15. package/__tests__/entities/entity.test.ts +114 -0
  16. package/__tests__/formatters/pascal-camel-to-snake.test.ts +19 -0
  17. package/__tests__/http/fetch-http-provider.test.ts +155 -0
  18. package/__tests__/http/http-provider.test.ts +55 -0
  19. package/__tests__/json-api/json-api-connector.test.ts +78 -0
  20. package/__tests__/json-api/json-api-list.test.ts +24 -0
  21. package/__tests__/json-api/json-api-single.test.ts +24 -0
  22. package/__tests__/json-api/url-criteria-builder.test.ts +74 -0
  23. package/__tests__/messages/message.test.ts +16 -0
  24. package/__tests__/models/base-model.test.ts +10 -0
  25. package/__tests__/state-manager/state-manager.test.ts +101 -0
  26. package/__tests__/utils/url/url-with-params-builder.test.ts +39 -0
  27. package/__tests__/value-objects/coordinates-value.test.ts +68 -0
  28. package/__tests__/value-objects/email-value.test.ts +43 -0
  29. package/__tests__/value-objects/enum-value.test.ts +51 -0
  30. package/__tests__/value-objects/integer-value.test.ts +115 -0
  31. package/__tests__/value-objects/phone-value.test.ts +82 -0
  32. package/__tests__/value-objects/slug-value.test.ts +43 -0
  33. package/__tests__/value-objects/string-value.test.ts +121 -0
  34. package/__tests__/value-objects/uuid-value.test.ts +67 -0
  35. package/__tests__/value-objects/value-object.test.ts +25 -0
  36. package/jest.config.js +25 -0
  37. package/package.json +289 -0
  38. package/src/auth/auth-provider.ts +10 -0
  39. package/src/auth/exceptions/index.ts +1 -0
  40. package/src/auth/exceptions/not-authenticated.ts +1 -0
  41. package/src/auth/index.ts +3 -0
  42. package/src/auth/require-auth.decorator.ts +41 -0
  43. package/src/criteria/criteria.ts +51 -0
  44. package/src/criteria/direction.ts +1 -0
  45. package/src/criteria/exceptions/index.ts +2 -0
  46. package/src/criteria/exceptions/limit-not-valid.ts +1 -0
  47. package/src/criteria/exceptions/offset-not-valid.ts +1 -0
  48. package/src/criteria/filter-criterion.ts +6 -0
  49. package/src/criteria/index.ts +7 -0
  50. package/src/criteria/operator.ts +12 -0
  51. package/src/criteria/order.ts +4 -0
  52. package/src/domain-events/domain-event-primitives.ts +7 -0
  53. package/src/domain-events/domain-event.ts +15 -0
  54. package/src/domain-events/index.ts +2 -0
  55. package/src/entities/entity.ts +22 -0
  56. package/src/entities/index.ts +1 -0
  57. package/src/formatters/index.ts +1 -0
  58. package/src/formatters/pascal-camel-to-snake.ts +8 -0
  59. package/src/http/exceptions/http-exception.ts +8 -0
  60. package/src/http/exceptions/index.ts +1 -0
  61. package/src/http/fetch-http-provider.ts +120 -0
  62. package/src/http/http-provider.ts +7 -0
  63. package/src/http/index.ts +4 -0
  64. package/src/json-api/index.ts +4 -0
  65. package/src/json-api/json-api-connector.ts +56 -0
  66. package/src/json-api/json-api-list.ts +13 -0
  67. package/src/json-api/json-api-single.ts +13 -0
  68. package/src/json-api/url-criteria-builder.ts +49 -0
  69. package/src/messages/index.ts +1 -0
  70. package/src/messages/message.ts +3 -0
  71. package/src/models/base-model.ts +3 -0
  72. package/src/models/index.ts +1 -0
  73. package/src/state-manager/index.ts +1 -0
  74. package/src/state-manager/state-manager.ts +28 -0
  75. package/src/utils/index.ts +1 -0
  76. package/src/utils/url/index.ts +1 -0
  77. package/src/utils/url/url-with-params-builder.ts +19 -0
  78. package/src/value-objects/coordinates-value.ts +50 -0
  79. package/src/value-objects/email-value.ts +25 -0
  80. package/src/value-objects/enum-value.ts +25 -0
  81. package/src/value-objects/index.ts +10 -0
  82. package/src/value-objects/integer-value.ts +29 -0
  83. package/src/value-objects/phone-value.ts +53 -0
  84. package/src/value-objects/slug-value.ts +25 -0
  85. package/src/value-objects/string-value.ts +27 -0
  86. package/src/value-objects/uuid-value.ts +34 -0
  87. package/src/value-objects/value-object.ts +7 -0
  88. package/tsconfig.json +46 -0
@@ -0,0 +1,101 @@
1
+ import { expectTypeOf } from "expect-type";
2
+
3
+ import { StateManager } from "../../src/state-manager";
4
+
5
+ type Schema = {
6
+ name: string;
7
+ };
8
+
9
+ describe("StateManager", () => {
10
+ it('should have a "state" property of the provided Schema', () => {
11
+ expectTypeOf<StateManager<Schema>["state"]>().toEqualTypeOf<Schema>();
12
+ });
13
+
14
+ it('should have a "listeners" property of type Array<(state: Schema) => void>', () => {
15
+ expectTypeOf<StateManager<Schema>["listeners"]>().toEqualTypeOf<Array<(state: Schema) => void>>();
16
+ });
17
+
18
+ describe('#getValue', () => {
19
+ it('should define the function', () => {
20
+ expectTypeOf<StateManager<Schema>["getValue"]>().toBeFunction();
21
+ });
22
+
23
+ it('should receive a key of Schema', () => {
24
+ expectTypeOf<StateManager<Schema>["getValue"]>().parameters.toEqualTypeOf<[keyof Schema]>();
25
+ });
26
+
27
+ it('should return a Promise with a value from the Schema', () => {
28
+ expectTypeOf<StateManager<Schema>["getValue"]>().returns.toEqualTypeOf<Promise<Schema[keyof Schema]>>();
29
+ });
30
+ });
31
+
32
+ describe('#setValue', () => {
33
+ it('should define the function', () => {
34
+ expectTypeOf<StateManager<Schema>["setValue"]>().toBeFunction();
35
+ });
36
+
37
+ it('should receive a key of Schema and the value to set', () => {
38
+ expectTypeOf<StateManager<Schema>["setValue"]>().parameters.toEqualTypeOf<[keyof Schema, Schema[keyof Schema]]>();
39
+ });
40
+
41
+ it('should return a void Promise', () => {
42
+ expectTypeOf<StateManager<Schema>["setValue"]>().returns.toEqualTypeOf<Promise<void>>();
43
+ });
44
+ });
45
+
46
+ describe('#removeValue', () => {
47
+ it('should define the function', () => {
48
+ expectTypeOf<StateManager<Schema>["removeValue"]>().toBeFunction();
49
+ });
50
+
51
+ it('should receive a key of Schema', () => {
52
+ expectTypeOf<StateManager<Schema>["removeValue"]>().parameters.toEqualTypeOf<[keyof Schema]>();
53
+ });
54
+
55
+ it('should return a Promise with a value from the Schema', () => {
56
+ expectTypeOf<StateManager<Schema>["removeValue"]>().returns.toEqualTypeOf<Promise<void>>();
57
+ });
58
+ });
59
+
60
+ describe('#getState', () => {
61
+ it('should define the function', () => {
62
+ expectTypeOf<StateManager<Schema>["getState"]>().toBeFunction();
63
+ });
64
+
65
+ it('should receive no params', () => {
66
+ expectTypeOf<StateManager<Schema>["getState"]>().parameters.toEqualTypeOf<[]>();
67
+ });
68
+
69
+ it('should return the value with Schema as type', () => {
70
+ expectTypeOf<StateManager<Schema>["getState"]>().returns.toEqualTypeOf<Schema>();
71
+ });
72
+ });
73
+
74
+ describe('#subscribe', () => {
75
+ it('should define the function', () => {
76
+ expectTypeOf<StateManager<Schema>["subscribe"]>().toBeFunction();
77
+ });
78
+
79
+ it('should receive a function of type (state: Schema) => void', () => {
80
+ expectTypeOf<StateManager<Schema>["subscribe"]>().parameters.toEqualTypeOf<[(state: Schema) => void]>();
81
+ });
82
+
83
+ it('should return a void function', () => {
84
+ expectTypeOf<StateManager<Schema>["subscribe"]>().returns.toEqualTypeOf<() => void>();
85
+ });
86
+ });
87
+
88
+ describe('#notifyListeners', () => {
89
+ it('should define the function', () => {
90
+ expectTypeOf<StateManager<Schema>["notifyListeners"]>().toBeFunction();
91
+ });
92
+
93
+ it('should receive no params', () => {
94
+ expectTypeOf<StateManager<Schema>["notifyListeners"]>().parameters.toEqualTypeOf<[]>();
95
+ });
96
+
97
+ it('should return a void function', () => {
98
+ expectTypeOf<StateManager<Schema>["notifyListeners"]>().returns.toEqualTypeOf<void>();
99
+ });
100
+ });
101
+ });
@@ -0,0 +1,39 @@
1
+ import { expectTypeOf } from "expect-type";
2
+
3
+ import { URLWithParamsBuilder } from "../../../src/utils";
4
+
5
+ const baseURL = 'https://github.com/schorts';
6
+ const url = new URL(baseURL);
7
+
8
+ describe('URLWithParamsBuilder', () => {
9
+ it('should have a "base" property of type URL', () => {
10
+ expectTypeOf<URLWithParamsBuilder["base"]>().toEqualTypeOf<URL>();
11
+ });
12
+
13
+ describe('#with', () => {
14
+ it('should receive a params with type Record<string, string | number | boolean | string[] | number[]>', () => {
15
+ expectTypeOf<URLWithParamsBuilder["with"]>().parameters.toEqualTypeOf<[Record<string, string | number | boolean | string[] | number[]>]>();
16
+ });
17
+
18
+ it('should return the same instance', () => {
19
+ const uRLWithParamsBuilder = new URLWithParamsBuilder(url);
20
+ const result = uRLWithParamsBuilder.with({ page: 1 });
21
+
22
+ expect(result).toEqual(uRLWithParamsBuilder);
23
+ });
24
+ });
25
+
26
+ describe('#build', () => {
27
+ it('should receive no params', () => {
28
+ expectTypeOf<URLWithParamsBuilder["build"]>().parameters.toEqualTypeOf<[]>();
29
+ });
30
+
31
+ it('should return the updated url', () => {
32
+ const uRLWithParamsBuilder = new URLWithParamsBuilder(url);
33
+ const expectedURL = new URL(`${baseURL}?page=1`);
34
+ const result = uRLWithParamsBuilder.with({ page: 1 }).build();
35
+
36
+ expect(result.href).toEqual(expectedURL.href);
37
+ });
38
+ });
39
+ });
@@ -0,0 +1,68 @@
1
+ import { expectTypeOf } from "expect-type";
2
+
3
+ import { ValueObject, CoordinatesValue } from "../../src/value-objects";
4
+
5
+ class TestCoordinatesValue extends CoordinatesValue {
6
+ readonly attributeName = "test";
7
+ }
8
+
9
+ describe("CoordinatesValue", () => {
10
+ it('should implement "ValueObject" interface', () => {
11
+ expectTypeOf<CoordinatesValue>().toExtend<ValueObject>();
12
+ });
13
+
14
+ it('should have a "valueType" with "Coordinates" as value', () => {
15
+ const testCoordinatesValue = new TestCoordinatesValue({ latitude: 0, longitude: 0 });
16
+
17
+ expect(testCoordinatesValue.valueType).toEqual("Coordinates");
18
+ });
19
+
20
+ it('should have a "value" property of type { latitude: number, longitude: number }', () => {
21
+ expectTypeOf<CoordinatesValue["value"]>().toMatchObjectType<{ latitude: number, longitude: number }>();
22
+ });
23
+
24
+ it('should have a "latitude" property of type number or null', () => {
25
+ expectTypeOf<CoordinatesValue["latitude"]>().toEqualTypeOf<number | null>();
26
+ });
27
+
28
+ it('should have a "longitude" property of type number or null', () => {
29
+ expectTypeOf<CoordinatesValue["longitude"]>().toEqualTypeOf<number | null>();
30
+ });
31
+
32
+ it('should define the "equals" method', () => {
33
+ expectTypeOf<CoordinatesValue["equals"]>().toEqualTypeOf<(valueObject: unknown) => boolean>();
34
+ });
35
+
36
+ describe('when "value" is a valid coordinate', () => {
37
+ const coordinates = { latitude: 0, longitude: 0 };
38
+ const testCoordinatesValue = new TestCoordinatesValue(coordinates);
39
+
40
+ it('should return true the "isValid" getter', () => {
41
+ expect(testCoordinatesValue.isValid).toBeTruthy();
42
+ });
43
+
44
+ it('should return the latitude value', () => {
45
+ expect(testCoordinatesValue.latitude).toEqual(coordinates.latitude);
46
+ });
47
+
48
+ it('should return the longitude value', () => {
49
+ expect(testCoordinatesValue.longitude).toEqual(coordinates.longitude);
50
+ });
51
+ });
52
+
53
+ describe('when "value" is not a valid coordinate', () => {
54
+ const testCoordinatesValue = new TestCoordinatesValue({ latitude: -200, longitude: 500 });
55
+
56
+ it('should return false the "isValid" getter', () => {
57
+ expect(testCoordinatesValue.isValid).toBeFalsy();
58
+ });
59
+
60
+ it('should return null as the latitude value', () => {
61
+ expect(testCoordinatesValue.latitude).toBeNull();
62
+ });
63
+
64
+ it('should return null as the longitude value', () => {
65
+ expect(testCoordinatesValue.longitude).toBeNull();
66
+ });
67
+ });
68
+ });
@@ -0,0 +1,43 @@
1
+ import { expectTypeOf } from "expect-type";
2
+
3
+ import { ValueObject, EmailValue } from "../../src/value-objects";
4
+
5
+ class TestEmailValue extends EmailValue {
6
+ readonly attributeName = "test";
7
+ }
8
+
9
+ describe("EmailValue", () => {
10
+ it('should implement "ValueObject" interface', () => {
11
+ expectTypeOf<EmailValue>().toExtend<ValueObject>();
12
+ });
13
+
14
+ it('should have a "valueType" with "Email" as value', () => {
15
+ const testEmailValue = new TestEmailValue("");
16
+
17
+ expect(testEmailValue.valueType).toEqual("Email");
18
+ });
19
+
20
+ it('should have a "value" property of type string', () => {
21
+ expectTypeOf<EmailValue["value"]>().toBeString();
22
+ });
23
+
24
+ it('should define the "equals" method', () => {
25
+ expectTypeOf<EmailValue["equals"]>().toEqualTypeOf<(valueObject: unknown) => boolean>();
26
+ });
27
+
28
+ describe('when "value" is an email', () => {
29
+ it('should return true the "isValid" getter', () => {
30
+ const testEmailValue = new TestEmailValue("test@example.com");
31
+
32
+ expect(testEmailValue.isValid).toBeTruthy();
33
+ });
34
+ });
35
+
36
+ describe('when "value" is not an email', () => {
37
+ it('should return false the "isValid" getter', () => {
38
+ const testEmailValue = new TestEmailValue("test@com");
39
+
40
+ expect(testEmailValue.isValid).toBeFalsy();
41
+ });
42
+ });
43
+ });
@@ -0,0 +1,51 @@
1
+ import { expectTypeOf } from "expect-type";
2
+
3
+ import { ValueObject, EnumValue } from "../../src/value-objects";
4
+
5
+ class TestEnumValue extends EnumValue {
6
+ readonly attributeName = "test";
7
+ }
8
+
9
+ describe("EnumValue", () => {
10
+ it('should implement "ValueObject" interface', () => {
11
+ expectTypeOf<TestEnumValue>().toExtend<ValueObject>();
12
+ });
13
+
14
+ it('should have a "valueType" with "Enum" as value', () => {
15
+ const testEnumValue = new TestEnumValue([], "");
16
+
17
+ expect(testEnumValue.valueType).toEqual("Enum");
18
+ });
19
+
20
+ it('should have a "value" property of type string', () => {
21
+ expectTypeOf<EnumValue["value"]>().toBeString();
22
+ });
23
+
24
+ it('should have a "allowedValues" property of type string[]', () => {
25
+ expectTypeOf<EnumValue["allowedValues"]>().toBeArray();
26
+ });
27
+
28
+ it('should have a "allowedTypes" property of type string', () => {
29
+ expectTypeOf<EnumValue["attributeName"]>().toBeString;
30
+ });
31
+
32
+ it('should define the "equals" method', () => {
33
+ expectTypeOf<EnumValue["equals"]>().toEqualTypeOf<(valueObject: unknown) => boolean>();
34
+ });
35
+
36
+ describe('when value is in the "allowedTypes" property', () => {
37
+ it('should return true on the "isValid" getter', () => {
38
+ const testEnumValue = new TestEnumValue(["test"], "test");
39
+
40
+ expect(testEnumValue.isValid).toBeTruthy();
41
+ });
42
+ });
43
+
44
+ describe('when value is not in the "allowedTypes" property', () => {
45
+ it('should return true on the "isValid" getter', () => {
46
+ const testEnumValue = new TestEnumValue(["test"], "test2");
47
+
48
+ expect(testEnumValue.isValid).toBeFalsy();
49
+ });
50
+ });
51
+ });
@@ -0,0 +1,115 @@
1
+ import { expectTypeOf } from "expect-type";
2
+
3
+ import { ValueObject, IntegerValue } from "../../src/value-objects";
4
+
5
+ class TestIntegerValue extends IntegerValue {
6
+ readonly attributeName = "test";
7
+ }
8
+
9
+ describe("IntegerValue", () => {
10
+ it('should implement "ValueObject" interface', () => {
11
+ expectTypeOf<IntegerValue>().toExtend<ValueObject>();
12
+ });
13
+
14
+ it('should have a "valueType" with "Integer" as value', () => {
15
+ const testIntegerValue = new TestIntegerValue(0);
16
+
17
+ expect(testIntegerValue.valueType).toEqual("Integer");
18
+ });
19
+
20
+ it('should have a "value" property of type number', () => {
21
+ expectTypeOf<IntegerValue["value"]>().toBeNumber();
22
+ });
23
+
24
+ it('should have a "min" property of type number or undefined', () => {
25
+ expectTypeOf<IntegerValue["min"]>().toEqualTypeOf<number | undefined>();
26
+ });
27
+
28
+ it('should have a "max" property of type number or undefined', () => {
29
+ expectTypeOf<IntegerValue["max"]>().toEqualTypeOf<number | undefined>()
30
+ });
31
+
32
+ it('should define the "equals" method', () => {
33
+ expectTypeOf<IntegerValue["equals"]>().toEqualTypeOf<(valueObject: unknown) => boolean>();
34
+ });
35
+
36
+ describe('when "min" is not present', () => {
37
+ it('should allow any negative integer as valid', () => {
38
+ const testIntegerValue = new TestIntegerValue(-1);
39
+
40
+ expect(testIntegerValue.isValid).toBeTruthy();
41
+ });
42
+ });
43
+
44
+ describe('when "min" is present', () => {
45
+ it('should assign the provided value', () => {
46
+ const min = 1;
47
+ const testIntegerValue = new TestIntegerValue(0, min);
48
+
49
+ expect(testIntegerValue.min).toEqual(min);
50
+ });
51
+
52
+ it('should return false if the value provided is less than the "min"', () => {
53
+ const min = 1;
54
+ const testIntegerValue = new TestIntegerValue(-1, min);
55
+
56
+ expect(testIntegerValue.isValid).toBeFalsy();
57
+ });
58
+
59
+ it('should return true if the value provided is greather or equal than the "min', () => {
60
+ const min = 1;
61
+ const testIntegerValue = new TestIntegerValue(1, min);
62
+
63
+ expect(testIntegerValue.isValid).toBeTruthy();
64
+ });
65
+ });
66
+
67
+ describe('when "max" is not present', () => {
68
+ it('should assign a default value of undefined', () => {
69
+ const testIntegerValue = new TestIntegerValue(0);
70
+
71
+ expect(testIntegerValue.max).toBeUndefined();
72
+ });
73
+ });
74
+
75
+ describe('when "max" is present', () => {
76
+ it('should assign the provided value', () => {
77
+ const max = 1;
78
+ const testIntegerValue = new TestIntegerValue(0, undefined, max);
79
+
80
+ expect(testIntegerValue.max).toEqual(max);
81
+ });
82
+
83
+ it('should return false if the value provided is greather than the "max"', () => {
84
+ const max = 1;
85
+ const testIntegerValue = new TestIntegerValue(2, undefined, max);
86
+
87
+ expect(testIntegerValue.isValid).toBeFalsy();
88
+ });
89
+
90
+ it('should return true if the value provided is less or equal than the "max', () => {
91
+ const max = 1;
92
+ const testIntegerValue = new TestIntegerValue(1, undefined, max);
93
+
94
+ expect(testIntegerValue.isValid).toBeTruthy();
95
+ });
96
+ });
97
+
98
+ describe('when "min" and "max" is present', () => {
99
+ it('should return false if the value provided is not between the "min" and "max"', () => {
100
+ const min = -1;
101
+ const max = 1;
102
+ const testIntegerValue = new TestIntegerValue(2, min, max);
103
+
104
+ expect(testIntegerValue.isValid).toBeFalsy();
105
+ });
106
+
107
+ it('should return true if the value provided is not between the "min" and "max"', () => {
108
+ const min = -1;
109
+ const max = 1;
110
+ const testIntegerValue = new TestIntegerValue(0, min, max);
111
+
112
+ expect(testIntegerValue.isValid).toBeTruthy();
113
+ });
114
+ });
115
+ });
@@ -0,0 +1,82 @@
1
+ import { expectTypeOf } from "expect-type";
2
+
3
+ import { ValueObject, PhoneValue } from "../../src/value-objects";
4
+
5
+ class TestPhoneValue extends PhoneValue {
6
+ readonly attributeName = "test";
7
+ }
8
+
9
+ describe("PhoneValue", () => {
10
+ it('should implement "ValueObject" interface', () => {
11
+ expectTypeOf<PhoneValue>().toExtend<ValueObject>();
12
+ });
13
+
14
+ it('should have a "valueType" with "Phone" as value', () => {
15
+ const testPhoneValue = new TestPhoneValue("");
16
+
17
+ expect(testPhoneValue.valueType).toEqual("Phone");
18
+ });
19
+
20
+ it('should have a "value" property of type string', () => {
21
+ expectTypeOf<PhoneValue["value"]>().toBeString();
22
+ });
23
+
24
+ it('should have a "countryCode" property of type string', () => {
25
+ expectTypeOf<PhoneValue["countryCode"]>().toEqualTypeOf<string | null>();
26
+ });
27
+
28
+ it('should have a "phoneNumber" property of type string', () => {
29
+ expectTypeOf<PhoneValue["phoneNumber"]>().toEqualTypeOf<string | null>();
30
+ });
31
+
32
+ it('should have a "formattedPhone" property of type string', () => {
33
+ expectTypeOf<PhoneValue["formattedPhone"]>().toEqualTypeOf<string | null>();
34
+ });
35
+
36
+ it('should define the "equals" method', () => {
37
+ expectTypeOf<PhoneValue["equals"]>().toEqualTypeOf<(valueObject: unknown) => boolean>();
38
+ });
39
+
40
+ describe('when "value" is a phone', () => {
41
+ const countryCode = "+52";
42
+ const phoneNumber = "1234567890";
43
+ const formattedPhone = `${countryCode} (123) 456-7890`;
44
+ const testPhoneValue = new TestPhoneValue(`${countryCode}${phoneNumber}`);
45
+
46
+ it('should return true the "isValid" getter', () => {
47
+ expect(testPhoneValue.isValid).toBeTruthy();
48
+ });
49
+
50
+ it('should return the "countryCode" property', () => {
51
+ expect(testPhoneValue.countryCode).toEqual(countryCode);
52
+ });
53
+
54
+ it('should return the "phoneNumber" property', () => {
55
+ expect(testPhoneValue.phoneNumber).toEqual(phoneNumber);
56
+ });
57
+
58
+ it('should return the "formattedPhone" property', () => {
59
+ expect(testPhoneValue.formattedPhone).toEqual(formattedPhone);
60
+ });
61
+ });
62
+
63
+ describe('when "value" is not a phone', () => {
64
+ const testPhoneValue = new TestPhoneValue("+112345678901241");
65
+
66
+ it('should return false the "isValid" getter', () => {
67
+ expect(testPhoneValue.isValid).toBeFalsy();
68
+ });
69
+
70
+ it('should return null for the "countryCode" property', () => {
71
+ expect(testPhoneValue.countryCode).toBeNull();
72
+ });
73
+
74
+ it('should return null for the "phoneNumber" property', () => {
75
+ expect(testPhoneValue.phoneNumber).toBeNull();
76
+ });
77
+
78
+ it('should return null for the "formattedPhone" property', () => {
79
+ expect(testPhoneValue.formattedPhone).toBeNull();
80
+ });
81
+ });
82
+ });
@@ -0,0 +1,43 @@
1
+ import { expectTypeOf } from "expect-type";
2
+
3
+ import { ValueObject, SlugValue } from "../../src/value-objects";
4
+
5
+ class TestSlugValue extends SlugValue {
6
+ readonly attributeName = "test";
7
+ }
8
+
9
+ describe("SlugValue", () => {
10
+ it('should implement "ValueObject" interface', () => {
11
+ expectTypeOf<TestSlugValue>().toExtend<ValueObject>();
12
+ });
13
+
14
+ it('should have a "valueType" with "Slug" as value', () => {
15
+ const testSlugValue = new TestSlugValue("");
16
+
17
+ expect(testSlugValue.valueType).toEqual("Slug");
18
+ });
19
+
20
+ it('should have a "value" property of type string', () => {
21
+ expectTypeOf<SlugValue["value"]>().toBeString();
22
+ });
23
+
24
+ it('should define the "equals" method', () => {
25
+ expectTypeOf<SlugValue["equals"]>().toEqualTypeOf<(valueObject: unknown) => boolean>();
26
+ });
27
+
28
+ describe('when "value" is an slug', () => {
29
+ it('should return true the "isValid" getter', () => {
30
+ const testSlugValue = new TestSlugValue("schorts");
31
+
32
+ expect(testSlugValue.isValid).toBeTruthy();
33
+ });
34
+ });
35
+
36
+ describe('when "value" is not an slug', () => {
37
+ it('should return false the "isValid" getter', () => {
38
+ const testSlugValue = new TestSlugValue("-schorts");
39
+
40
+ expect(testSlugValue.isValid).toBeFalsy();
41
+ });
42
+ });
43
+ });
@@ -0,0 +1,121 @@
1
+ import { expectTypeOf } from "expect-type";
2
+
3
+ import { ValueObject, StringValue } from "../../src/value-objects";
4
+
5
+ class TestStringalue extends StringValue {
6
+ readonly attributeName = "test";
7
+ }
8
+
9
+ describe("StringValue", () => {
10
+ it('should implement "ValueObject" interface', () => {
11
+ expectTypeOf<TestStringalue>().toExtend<ValueObject>();
12
+ });
13
+
14
+ it('should have a "valueType" with "String" as value', () => {
15
+ const testStringValue = new TestStringalue("");
16
+
17
+ expect(testStringValue.valueType).toEqual("String");
18
+ });
19
+
20
+ it('should have a "value" property of type string', () => {
21
+ expectTypeOf<StringValue["value"]>().toBeString();
22
+ });
23
+
24
+ it('should have a "minLength" property of type number', () => {
25
+ expectTypeOf<StringValue["minLength"]>().toBeNumber();
26
+ });
27
+
28
+ it('should have a "maxLength" property of type number or undefined', () => {
29
+ expectTypeOf<StringValue["maxLength"]>().toEqualTypeOf<number | undefined>()
30
+ });
31
+
32
+ it('should define the "equals" method', () => {
33
+ expectTypeOf<StringValue["equals"]>().toEqualTypeOf<(valueObject: unknown) => boolean>();
34
+ });
35
+
36
+ describe('when "minLength" is not present', () => {
37
+ it('should assign a default value of 0', () => {
38
+ const testStringValue = new TestStringalue("");
39
+
40
+ expect(testStringValue.minLength).toEqual(0);
41
+ });
42
+
43
+ it('should allow an empty string as valid', () => {
44
+ const testStringValue = new TestStringalue("");
45
+
46
+ expect(testStringValue.isValid).toBeTruthy();
47
+ });
48
+ });
49
+
50
+ describe('when "minLength" is present', () => {
51
+ it('should assign the provided value', () => {
52
+ const minLength = 1;
53
+ const testStringValue = new TestStringalue("", minLength);
54
+
55
+ expect(testStringValue.minLength).toEqual(minLength);
56
+ });
57
+
58
+ it('should return false if the value provided length is less than the "minLength"', () => {
59
+ const minLength = 1;
60
+ const testStringValue = new TestStringalue("", minLength);
61
+
62
+ expect(testStringValue.isValid).toBeFalsy();
63
+ });
64
+
65
+ it('should return true if the value provided length is greather or equal than the "minLength', () => {
66
+ const minLength = 1;
67
+ const testStringValue = new TestStringalue("1", minLength);
68
+
69
+ expect(testStringValue.isValid).toBeTruthy();
70
+ });
71
+ });
72
+
73
+ describe('when "maxLength" is not present', () => {
74
+ it('should assign a default value of undefined', () => {
75
+ const testStringValue = new TestStringalue("");
76
+
77
+ expect(testStringValue.maxLength).toBeUndefined();
78
+ });
79
+ });
80
+
81
+ describe('when "maxLength" is present', () => {
82
+ it('should assign the provided value', () => {
83
+ const maxLength = 1;
84
+ const testStringValue = new TestStringalue("", 0, maxLength);
85
+
86
+ expect(testStringValue.maxLength).toEqual(maxLength);
87
+ });
88
+
89
+ it('should return false if the value provided length is greather than the "maxLength"', () => {
90
+ const maxLength = 1;
91
+ const testStringValue = new TestStringalue("12", 0, maxLength);
92
+
93
+ expect(testStringValue.isValid).toBeFalsy();
94
+ });
95
+
96
+ it('should return true if the value provided length is less or equal than the "maxLength', () => {
97
+ const maxLength = 2;
98
+ const testStringValue = new TestStringalue("1", 0, maxLength);
99
+
100
+ expect(testStringValue.isValid).toBeTruthy();
101
+ });
102
+ });
103
+
104
+ describe('when "minLength" and "maxLength" is present', () => {
105
+ it('should return false if the value provided length is not between the "minLength" and "maxLength"', () => {
106
+ const minLength = 1;
107
+ const maxLength = 2;
108
+ const testStringValue = new TestStringalue("123", minLength, maxLength);
109
+
110
+ expect(testStringValue.isValid).toBeFalsy();
111
+ });
112
+
113
+ it('should return true if the value provided length is not between the "minLength" and "maxLength"', () => {
114
+ const minLength = 1;
115
+ const maxLength = 2;
116
+ const testStringValue = new TestStringalue("12", minLength, maxLength);
117
+
118
+ expect(testStringValue.isValid).toBeTruthy();
119
+ });
120
+ });
121
+ });