@haskou/value-objects 1.0.1

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 (85) hide show
  1. package/.editorconfig +15 -0
  2. package/.eslintignore +3 -0
  3. package/.eslintrc.json +218 -0
  4. package/.prettierrc.json +13 -0
  5. package/README.md +156 -0
  6. package/TECHNICAL_DOCUMENTATION.md +1091 -0
  7. package/jest.config.ts +30 -0
  8. package/package.json +49 -0
  9. package/src/errors/BaseError.ts +20 -0
  10. package/src/errors/DomainError.ts +12 -0
  11. package/src/errors/InvalidColorError.ts +7 -0
  12. package/src/errors/InvalidDayError.ts +7 -0
  13. package/src/errors/InvalidDayFormatError.ts +7 -0
  14. package/src/errors/InvalidEmailError.ts +7 -0
  15. package/src/errors/InvalidHourError.ts +7 -0
  16. package/src/errors/InvalidIntegerError.ts +7 -0
  17. package/src/errors/InvalidLatitudeError.ts +7 -0
  18. package/src/errors/InvalidLongitudeError.ts +7 -0
  19. package/src/errors/InvalidMinutesError.ts +7 -0
  20. package/src/errors/InvalidNumberError.ts +7 -0
  21. package/src/errors/InvalidPositiveNumberError.ts +7 -0
  22. package/src/errors/InvalidStringLengthError.ts +9 -0
  23. package/src/errors/InvalidTimestampIntervalError.ts +10 -0
  24. package/src/errors/NullObjectError.ts +8 -0
  25. package/src/errors/ValueNotInEnumError.ts +9 -0
  26. package/src/errors/index.ts +17 -0
  27. package/src/index.ts +5 -0
  28. package/src/interfaces/PrimitiveOf.ts +5 -0
  29. package/src/interfaces/index.ts +1 -0
  30. package/src/patterns/Assert.ts +15 -0
  31. package/src/patterns/NullObject.ts +60 -0
  32. package/src/patterns/ValueObject.ts +40 -0
  33. package/src/patterns/index.ts +3 -0
  34. package/src/types/Nullish.ts +1 -0
  35. package/src/types/Primitive.ts +1 -0
  36. package/src/types/index.ts +2 -0
  37. package/src/value-objects/Color.ts +39 -0
  38. package/src/value-objects/Email.ts +23 -0
  39. package/src/value-objects/Enum.ts +31 -0
  40. package/src/value-objects/Integer.ts +22 -0
  41. package/src/value-objects/NumberValueObject.ts +56 -0
  42. package/src/value-objects/PositiveNumber.ts +20 -0
  43. package/src/value-objects/StringValueObject.ts +27 -0
  44. package/src/value-objects/coordinates/Coordinates.ts +30 -0
  45. package/src/value-objects/coordinates/Latitude.ts +22 -0
  46. package/src/value-objects/coordinates/Longitude.ts +25 -0
  47. package/src/value-objects/coordinates/index.ts +3 -0
  48. package/src/value-objects/index.ts +9 -0
  49. package/src/value-objects/time/CalendarDay.ts +91 -0
  50. package/src/value-objects/time/Day.ts +17 -0
  51. package/src/value-objects/time/DayOfWeek.ts +60 -0
  52. package/src/value-objects/time/Duration.ts +142 -0
  53. package/src/value-objects/time/Hour.ts +105 -0
  54. package/src/value-objects/time/Month.ts +39 -0
  55. package/src/value-objects/time/MonthOfYear.ts +52 -0
  56. package/src/value-objects/time/Timestamp.ts +208 -0
  57. package/src/value-objects/time/TimestampInterval.ts +122 -0
  58. package/src/value-objects/time/Year.ts +27 -0
  59. package/src/value-objects/time/index.ts +10 -0
  60. package/tests/errors/BaseError.spec.ts +63 -0
  61. package/tests/errors/DomainError.spec.ts +52 -0
  62. package/tests/patterns/Assert.spec.ts +29 -0
  63. package/tests/patterns/NullObject.spec.ts +55 -0
  64. package/tests/setup.jest.ts +2 -0
  65. package/tests/value-objects/Color.spec.ts +214 -0
  66. package/tests/value-objects/Email.spec.ts +145 -0
  67. package/tests/value-objects/Enum.spec.ts +293 -0
  68. package/tests/value-objects/Integer.spec.ts +38 -0
  69. package/tests/value-objects/NumberValueObject.spec.ts +446 -0
  70. package/tests/value-objects/PositiveNumber.spec.ts +274 -0
  71. package/tests/value-objects/StringValueObject.spec.ts +135 -0
  72. package/tests/value-objects/coordinates/Coordinates.spec.ts +90 -0
  73. package/tests/value-objects/coordinates/Latitude.spec.ts +24 -0
  74. package/tests/value-objects/coordinates/Longitude.spec.ts +24 -0
  75. package/tests/value-objects/time/CalendarDay.spec.ts +182 -0
  76. package/tests/value-objects/time/Day.spec.ts +29 -0
  77. package/tests/value-objects/time/DayOfWeek.spec.ts +71 -0
  78. package/tests/value-objects/time/Duration.spec.ts +278 -0
  79. package/tests/value-objects/time/Hour.spec.ts +197 -0
  80. package/tests/value-objects/time/MonthOfYear.spec.ts +111 -0
  81. package/tests/value-objects/time/Timestamp.spec.ts +497 -0
  82. package/tests/value-objects/time/TimestampInterval.spec.ts +383 -0
  83. package/tests/value-objects/time/Year.spec.ts +48 -0
  84. package/tsconfig.jest.json +33 -0
  85. package/tsconfig.json +42 -0
@@ -0,0 +1,274 @@
1
+ import {
2
+ InvalidPositiveNumberError,
3
+ NullObject,
4
+ NumberValueObject,
5
+ PositiveNumber,
6
+ } from '../../src';
7
+
8
+ describe('PositiveNumber', () => {
9
+ describe('constructor', () => {
10
+ it('should return a NullValueObject when a Nullish is received', () => {
11
+ expect(
12
+ () => new PositiveNumber(undefined as unknown as number),
13
+ ).not.toThrow();
14
+ expect(
15
+ NullObject.isNullObject(
16
+ new PositiveNumber(undefined as unknown as number),
17
+ ),
18
+ ).toBeTrue();
19
+ expect(
20
+ NullObject.isNullObject(new PositiveNumber(null as unknown as number)),
21
+ ).toBeTrue();
22
+ });
23
+ it('should validate is positive number', () => {
24
+ expect(() => new PositiveNumber(-1)).toThrow(
25
+ 'Value must be greater or equal than 0',
26
+ );
27
+ expect(() => new PositiveNumber(-1)).toThrow(InvalidPositiveNumberError);
28
+ });
29
+
30
+ it('should accept positive numbers', () => {
31
+ expect(() => new PositiveNumber(1)).not.toThrow();
32
+ expect(() => new PositiveNumber(0.1)).not.toThrow();
33
+ expect(() => new PositiveNumber(100.5)).not.toThrow();
34
+ });
35
+
36
+ it('should reject negative numbers', () => {
37
+ expect(() => new PositiveNumber(-0.1)).toThrow(
38
+ InvalidPositiveNumberError,
39
+ );
40
+ expect(() => new PositiveNumber(-100)).toThrow(
41
+ InvalidPositiveNumberError,
42
+ );
43
+ });
44
+
45
+ it('should accept another PositiveNumber', () => {
46
+ const original = new PositiveNumber(42);
47
+ const copy = new PositiveNumber(original);
48
+ expect(copy.valueOf()).toBe(42);
49
+ expect(copy.isEqual(original)).toBeTrue();
50
+ });
51
+
52
+ it('should validate when constructed from another NumberValueObject', () => {
53
+ const validNumber = new PositiveNumber(10);
54
+ expect(() => new PositiveNumber(validNumber)).not.toThrow();
55
+
56
+ // Cannot test invalid NumberValueObject directly since NumberValueObject validates NaN
57
+ // But we can test edge cases
58
+ expect(() => new PositiveNumber(0.00001)).not.toThrow();
59
+ });
60
+ });
61
+
62
+ describe('inheritance and NumberValueObject behavior', () => {
63
+ it('should inherit from NumberValueObject', () => {
64
+ const positiveNumber = new PositiveNumber(42);
65
+ expect(positiveNumber).toBeInstanceOf(PositiveNumber);
66
+ expect(positiveNumber).toBeInstanceOf(NumberValueObject);
67
+ expect(positiveNumber.valueOf).toBeDefined();
68
+ expect(positiveNumber.isEqual).toBeDefined();
69
+ expect(positiveNumber.toString).toBeDefined();
70
+ expect(positiveNumber.isZero).toBeDefined();
71
+ expect(positiveNumber.add).toBeDefined();
72
+ expect(positiveNumber.subtract).toBeDefined();
73
+ expect(positiveNumber.multiply).toBeDefined();
74
+ expect(positiveNumber.divide).toBeDefined();
75
+ });
76
+
77
+ it('should implement valueOf() method correctly from NumberValueObject', () => {
78
+ const value = 123.45;
79
+ const positiveNumber = new PositiveNumber(value);
80
+ expect(positiveNumber.valueOf()).toBe(value);
81
+ });
82
+
83
+ it('should implement toString() method correctly from ValueObject', () => {
84
+ const value = 987.654;
85
+ const positiveNumber = new PositiveNumber(value);
86
+ expect(positiveNumber.toString()).toBe(value.toString());
87
+ expect(positiveNumber.toString()).toBe('987.654');
88
+ });
89
+
90
+ it('should implement isEqual() method correctly', () => {
91
+ const value = 100.5;
92
+ const positiveNumber1 = new PositiveNumber(value);
93
+ const positiveNumber2 = new PositiveNumber(value);
94
+ const positiveNumber3 = new PositiveNumber(200.7);
95
+
96
+ expect(positiveNumber1.isEqual(positiveNumber2)).toBeTrue();
97
+ expect(positiveNumber1.isEqual(positiveNumber3)).toBeFalse();
98
+ expect(positiveNumber1.isEqual(value)).toBeTrue();
99
+ expect(positiveNumber1.isEqual(200.7)).toBeFalse();
100
+ });
101
+
102
+ it('should implement isZero() method correctly', () => {
103
+ // PositiveNumber cannot be zero, but method should exist
104
+ const positiveNumber = new PositiveNumber(1);
105
+ expect(positiveNumber.isZero()).toBeFalse();
106
+ expect(typeof positiveNumber.isZero).toBe('function');
107
+ });
108
+
109
+ it('should implement comparison methods correctly', () => {
110
+ const smaller = new PositiveNumber(5);
111
+ const larger = new PositiveNumber(10);
112
+
113
+ expect(larger.isGreaterThan(smaller)).toBeTrue();
114
+ expect(smaller.isLessThan(larger)).toBeTrue();
115
+ expect(larger.isGreaterOrEqualThan(smaller)).toBeTrue();
116
+ expect(smaller.isLessOrEqualThan(larger)).toBeTrue();
117
+
118
+ const equal = new PositiveNumber(5);
119
+ expect(smaller.isGreaterOrEqualThan(equal)).toBeTrue();
120
+ expect(smaller.isLessOrEqualThan(equal)).toBeTrue();
121
+ });
122
+
123
+ it('should implement clone() method correctly', () => {
124
+ const originalValue = 3.14159;
125
+ const original = new PositiveNumber(originalValue);
126
+ const cloned = (original as any).clone();
127
+
128
+ expect(cloned).toBeInstanceOf(PositiveNumber);
129
+ expect(cloned).toBeInstanceOf(NumberValueObject);
130
+ expect(cloned.valueOf()).toBe(originalValue);
131
+ expect(cloned.toString()).toBe(originalValue.toString());
132
+ expect(cloned.isEqual(original)).toBeTrue();
133
+ expect(cloned).not.toBe(original); // Different instances
134
+ });
135
+ });
136
+
137
+ describe('arithmetic operations with positive validation', () => {
138
+ it('should perform addition and maintain positive result', () => {
139
+ const a = new PositiveNumber(5);
140
+ const b = new PositiveNumber(3);
141
+ const result = a.add(b);
142
+
143
+ expect(result).toBeInstanceOf(PositiveNumber);
144
+ expect(result.valueOf()).toBe(8);
145
+ });
146
+
147
+ it('should perform multiplication and maintain positive result', () => {
148
+ const a = new PositiveNumber(4);
149
+ const b = new PositiveNumber(2.5);
150
+ const result = a.multiply(b);
151
+
152
+ expect(result).toBeInstanceOf(PositiveNumber);
153
+ expect(result.valueOf()).toBe(10);
154
+ });
155
+
156
+ it('should perform division and maintain positive result', () => {
157
+ const a = new PositiveNumber(10);
158
+ const b = new PositiveNumber(2);
159
+ const result = a.divide(b);
160
+
161
+ expect(result).toBeInstanceOf(PositiveNumber);
162
+ expect(result.valueOf()).toBe(5);
163
+ });
164
+
165
+ it('should throw an error if a subtraction results in negative number', () => {
166
+ const a = new PositiveNumber(3);
167
+ const b = new PositiveNumber(5);
168
+
169
+ expect(() => a.subtract(b)).toThrow(InvalidPositiveNumberError);
170
+ });
171
+
172
+ it('should work with primitive numbers in operations', () => {
173
+ const positive = new PositiveNumber(15);
174
+
175
+ const addResult = positive.add(5);
176
+ const multiplyResult = positive.multiply(2);
177
+ const divideResult = positive.divide(3);
178
+
179
+ expect(addResult.valueOf()).toBe(20);
180
+ expect(multiplyResult.valueOf()).toBe(30);
181
+ expect(divideResult.valueOf()).toBe(5);
182
+
183
+ // All results should be NumberValueObject instances (not necessarily PositiveNumber)
184
+ expect(addResult.valueOf()).toBeGreaterThan(0);
185
+ expect(multiplyResult.valueOf()).toBeGreaterThan(0);
186
+ expect(divideResult.valueOf()).toBeGreaterThan(0);
187
+ });
188
+ });
189
+
190
+ describe('immutability', () => {
191
+ it('should have immutable value property inherited from NumberValueObject', () => {
192
+ const positiveNumber = new PositiveNumber(42);
193
+
194
+ // Verify immutability through value consistency
195
+ expect(positiveNumber.valueOf()).toBe(42);
196
+ expect((positiveNumber as any).value).toBe(42);
197
+
198
+ const originalValue = positiveNumber.valueOf();
199
+ expect(originalValue).toBe(42);
200
+ });
201
+
202
+ it('should return the same value after creation', () => {
203
+ const originalValue = 3.14159;
204
+ const positiveNumber = new PositiveNumber(originalValue);
205
+
206
+ expect(positiveNumber.valueOf()).toBe(originalValue);
207
+ expect(positiveNumber.toString()).toBe(originalValue.toString());
208
+
209
+ // Value should remain the same
210
+ expect(positiveNumber.valueOf()).toBe(originalValue);
211
+ });
212
+
213
+ it('should create new instances instead of modifying existing ones', () => {
214
+ const value1 = 100.5;
215
+ const value2 = 200.7;
216
+
217
+ const positiveNumber1 = new PositiveNumber(value1);
218
+ const positiveNumber2 = new PositiveNumber(value2);
219
+
220
+ expect(positiveNumber1.valueOf()).toBe(value1);
221
+ expect(positiveNumber2.valueOf()).toBe(value2);
222
+ expect(positiveNumber1.valueOf()).not.toBe(positiveNumber2.valueOf());
223
+ });
224
+
225
+ it('should maintain immutability when constructed from another PositiveNumber', () => {
226
+ const original = new PositiveNumber(987.654);
227
+ const copy = new PositiveNumber(original);
228
+
229
+ expect(copy.valueOf()).toBe(original.valueOf());
230
+ expect(copy.isEqual(original)).toBeTrue();
231
+
232
+ // Both should maintain their values independently
233
+ expect(original.valueOf()).toBe(987.654);
234
+ expect(copy.valueOf()).toBe(987.654);
235
+ });
236
+
237
+ it('should maintain immutability when cloning', () => {
238
+ const original = new PositiveNumber(777.888);
239
+ const cloned = (original as any).clone();
240
+
241
+ expect(original.valueOf()).toBe(777.888);
242
+ expect(cloned.valueOf()).toBe(777.888);
243
+ expect(original.isEqual(cloned)).toBeTrue();
244
+ expect(original).not.toBe(cloned);
245
+
246
+ // Both should remain immutable
247
+ expect(original.valueOf()).toBe(777.888);
248
+ expect(cloned.valueOf()).toBe(777.888);
249
+ });
250
+
251
+ it('should maintain immutability in arithmetic operations', () => {
252
+ const original = new PositiveNumber(10);
253
+ const other = new PositiveNumber(5);
254
+
255
+ const sum = original.add(other);
256
+ const product = original.multiply(other);
257
+ const quotient = original.divide(other);
258
+
259
+ // Original values should remain unchanged
260
+ expect(original.valueOf()).toBe(10);
261
+ expect(other.valueOf()).toBe(5);
262
+
263
+ // Results should be correct
264
+ expect(sum.valueOf()).toBe(15);
265
+ expect(product.valueOf()).toBe(50);
266
+ expect(quotient.valueOf()).toBe(2);
267
+
268
+ // All should be different instances
269
+ expect(sum).not.toBe(original);
270
+ expect(product).not.toBe(original);
271
+ expect(quotient).not.toBe(original);
272
+ });
273
+ });
274
+ });
@@ -0,0 +1,135 @@
1
+ import {
2
+ InvalidStringLengthError,
3
+ NullObject,
4
+ StringValueObject,
5
+ } from '../../src';
6
+
7
+ describe('StringValueObject', () => {
8
+ describe('constructor', () => {
9
+ it('should return a NullValueObject when a Nullish is received', () => {
10
+ expect(
11
+ () => new StringValueObject(undefined as unknown as string),
12
+ ).not.toThrow();
13
+ expect(
14
+ NullObject.isNullObject(
15
+ new StringValueObject(undefined as unknown as string),
16
+ ),
17
+ ).toBeTrue();
18
+ expect(
19
+ NullObject.isNullObject(
20
+ new StringValueObject(null as unknown as string),
21
+ ),
22
+ ).toBeTrue();
23
+ });
24
+
25
+ it('should work when value is a string', () => {
26
+ expect(new StringValueObject('123').toString()).not.toBeEmpty();
27
+ });
28
+
29
+ it('should limit value length', () => {
30
+ expect(() => {
31
+ new StringValueObject('a'.repeat(512));
32
+ }).not.toThrow();
33
+ expect(() => {
34
+ new StringValueObject('a'.repeat(600));
35
+ }).toThrow(InvalidStringLengthError);
36
+ });
37
+
38
+ it('should limit value by custom length', () => {
39
+ expect(() => {
40
+ new StringValueObject('1234567890', 9);
41
+ }).toThrow(InvalidStringLengthError);
42
+ expect(() => {
43
+ new StringValueObject('1234567890', 10);
44
+ }).not.toThrow();
45
+ expect(() => {
46
+ new StringValueObject('1234567890', 11);
47
+ }).not.toThrow();
48
+ });
49
+
50
+ it('should accept another StringValueObject', () => {
51
+ const original = new StringValueObject('hello');
52
+ const copy = new StringValueObject(original);
53
+ expect(copy.toString()).toEqual('hello');
54
+ expect(copy.isEqual(original)).toBeTrue();
55
+ });
56
+
57
+ it('should enforce maxLength when constructed from another StringValueObject', () => {
58
+ const longStr = 'a'.repeat(20);
59
+ const original = new StringValueObject(longStr);
60
+ expect(() => new StringValueObject(original, 10)).toThrow(
61
+ InvalidStringLengthError,
62
+ );
63
+ });
64
+ });
65
+
66
+ describe('isEmpty', () => {
67
+ it('should return true when value is empty', () => {
68
+ expect(new StringValueObject('').isEmpty()).toBeTrue();
69
+ });
70
+
71
+ it('should return false when value is a string', () => {
72
+ expect(new StringValueObject('123').isEmpty()).toBeFalse();
73
+ });
74
+ });
75
+
76
+ describe('inheritance and value object behavior', () => {
77
+ it('should inherit from ValueObject', () => {
78
+ const stringValueObject = new StringValueObject('test');
79
+ expect(stringValueObject).toBeInstanceOf(StringValueObject);
80
+ expect(stringValueObject.valueOf).toBeDefined();
81
+ expect(stringValueObject.isEqual).toBeDefined();
82
+ });
83
+
84
+ it('should implement valueOf() method correctly', () => {
85
+ const value = 'test value';
86
+ const stringValueObject = new StringValueObject(value);
87
+ expect(stringValueObject.valueOf()).toBe(value);
88
+ });
89
+
90
+ it('should implement isEqual() method correctly', () => {
91
+ const value = 'test value';
92
+ const stringValueObject1 = new StringValueObject(value);
93
+ const stringValueObject2 = new StringValueObject(value);
94
+ const stringValueObject3 = new StringValueObject('different value');
95
+
96
+ expect(stringValueObject1.isEqual(stringValueObject2)).toBeTrue();
97
+ expect(stringValueObject1.isEqual(stringValueObject3)).toBeFalse();
98
+ expect(stringValueObject1.isEqual(value)).toBeTrue();
99
+ expect(stringValueObject1.isEqual('different')).toBeFalse();
100
+ });
101
+
102
+ it('should compare with primitive values using isEqual', () => {
103
+ const stringValueObject = new StringValueObject('hello');
104
+ expect(stringValueObject.isEqual('hello')).toBeTrue();
105
+ expect(stringValueObject.isEqual('world')).toBeFalse();
106
+ });
107
+
108
+ it('should implement clone() method correctly', () => {
109
+ const originalValue = 'test value for cloning';
110
+ const original = new StringValueObject(originalValue);
111
+ const cloned = (original as any).clone();
112
+
113
+ expect(cloned).toBeInstanceOf(StringValueObject);
114
+ expect(cloned.valueOf()).toBe(originalValue);
115
+ expect(cloned.toString()).toBe(originalValue);
116
+ expect(cloned.isEqual(original)).toBeTrue();
117
+ expect(cloned).not.toBe(original); // Different instances
118
+ });
119
+
120
+ it('should clone with maxLength preservation', () => {
121
+ const original = new StringValueObject('short', 10);
122
+ const cloned = (original as any).clone();
123
+
124
+ expect(cloned).toBeInstanceOf(StringValueObject);
125
+ expect(cloned.valueOf()).toBe('short');
126
+ expect(cloned.isEqual(original)).toBeTrue();
127
+ expect(cloned).not.toBe(original);
128
+ });
129
+
130
+ it('should implement toString correctly', () => {
131
+ expect(new StringValueObject('').toString()).toBeEmpty();
132
+ expect(new StringValueObject('123').toString()).toEqual('123');
133
+ });
134
+ });
135
+ });
@@ -0,0 +1,90 @@
1
+ import { Latitude, Longitude, Coordinates, PrimitiveOf } from '../../../src';
2
+
3
+ describe('Coordinates', () => {
4
+ let latitude: Latitude;
5
+ let longitude: Longitude;
6
+ let coordinates: Coordinates;
7
+ let stringCoordinates: string;
8
+
9
+ beforeEach(() => {
10
+ latitude = new Latitude(40.7128);
11
+ longitude = new Longitude(-74.006);
12
+ coordinates = new Coordinates(latitude, longitude);
13
+ stringCoordinates = '40.7128,-74.006';
14
+ });
15
+ describe('fromPrimitives', () => {
16
+ it('should create a Coordinates instance from primitives', () => {
17
+ const coordinates = Coordinates.fromString(stringCoordinates);
18
+
19
+ expect(coordinates).toMatchObject({
20
+ latitude,
21
+ longitude,
22
+ });
23
+ });
24
+ });
25
+
26
+ describe('constructor', () => {
27
+ it('should create a Coordinates instance with number inputs', () => {
28
+ const coordinates = new Coordinates(
29
+ latitude.valueOf(),
30
+ longitude.valueOf(),
31
+ );
32
+
33
+ expect(coordinates).toMatchObject({
34
+ latitude,
35
+ longitude,
36
+ });
37
+ });
38
+
39
+ it('should create a Coordinates instance with Latitude and Longitude inputs', () => {
40
+ const coordinates = new Coordinates(latitude, longitude);
41
+
42
+ expect(coordinates).toMatchObject({
43
+ latitude,
44
+ longitude,
45
+ });
46
+ });
47
+ });
48
+
49
+ describe('isEquals', () => {
50
+ it('should return true for equal Coordinates', () => {
51
+ const coordinates2 = new Coordinates(latitude, longitude);
52
+
53
+ expect(coordinates.isEqual(coordinates2)).toBe(true);
54
+ });
55
+
56
+ it('should return false for different Coordinates', () => {
57
+ const latitude2 = new Latitude(34.0522);
58
+ const longitude2 = new Longitude(-118.2437);
59
+ const coordinates2 = new Coordinates(latitude2, longitude2);
60
+
61
+ expect(coordinates.isEqual(coordinates2)).toBe(false);
62
+ });
63
+ });
64
+
65
+ describe('valueOf', () => {
66
+ it('should return valueOf Coordinates', () => {
67
+ expect(coordinates.valueOf()).toEqual(stringCoordinates);
68
+ });
69
+ });
70
+ describe('getLatitude', () => {
71
+ it('should return the latitude instance', () => {
72
+ expect(coordinates.getLatitude()).toEqual(latitude);
73
+ });
74
+
75
+ it('should return correct latitude when constructed with numbers', () => {
76
+ const coords = new Coordinates(51.5074, -0.1278);
77
+ expect(coords.getLatitude().valueOf()).toBe(51.5074);
78
+ });
79
+ });
80
+ describe('getLongitude', () => {
81
+ it('should return the longitude instance', () => {
82
+ expect(coordinates.getLongitude()).toEqual(longitude);
83
+ });
84
+
85
+ it('should return correct longitude when constructed with numbers', () => {
86
+ const coords = new Coordinates(51.5074, -0.1278);
87
+ expect(coords.getLongitude().valueOf()).toBe(-0.1278);
88
+ });
89
+ });
90
+ });
@@ -0,0 +1,24 @@
1
+ import { Latitude, InvalidLatitudeError } from '../../../src';
2
+
3
+ describe('Latitude', () => {
4
+ describe('constructor', () => {
5
+ it('should create a valid Latitude object', () => {
6
+ expect(new Latitude(45)).toMatchObject({ value: 45 });
7
+ expect(new Latitude(0)).toMatchObject({ value: 0 });
8
+ expect(new Latitude(41.3983779)).toMatchObject({ value: 41.3983779 });
9
+ expect(new Latitude(-41.3983779)).toMatchObject({ value: -41.3983779 });
10
+ });
11
+
12
+ it('should throw an InvalidLatitudeError for a value less than -90', () => {
13
+ expect(() => new Latitude(-91)).toThrow(InvalidLatitudeError);
14
+ });
15
+
16
+ it('should throw an InvalidLatitudeError for a value greater than 90', () => {
17
+ expect(() => new Latitude(91)).toThrow(InvalidLatitudeError);
18
+ });
19
+
20
+ it('should throw an InvalidLatitudeError if receives infinity', () => {
21
+ expect(() => new Latitude(Infinity)).toThrow(InvalidLatitudeError);
22
+ });
23
+ });
24
+ });
@@ -0,0 +1,24 @@
1
+ import { Longitude, InvalidLongitudeError } from '../../../src';
2
+
3
+ describe('Longitude', () => {
4
+ describe('constructor', () => {
5
+ it('should create a valid Longitude object', () => {
6
+ expect(new Longitude(45)).toMatchObject({ value: 45 });
7
+ expect(new Longitude(0)).toMatchObject({ value: 0 });
8
+ expect(new Longitude(41.3983779)).toMatchObject({ value: 41.3983779 });
9
+ expect(new Longitude(-41.3983779)).toMatchObject({ value: -41.3983779 });
10
+ });
11
+
12
+ it('should throw an InvalidLongitudeError for a value less than -180', () => {
13
+ expect(() => new Longitude(-181)).toThrow(InvalidLongitudeError);
14
+ });
15
+
16
+ it('should throw an InvalidLongitudeError for a value greater than 180', () => {
17
+ expect(() => new Longitude(181)).toThrow(InvalidLongitudeError);
18
+ });
19
+
20
+ it('should throw an InvalidLongitudeError if receives infinity', () => {
21
+ expect(() => new Longitude(Infinity)).toThrow(InvalidLongitudeError);
22
+ });
23
+ });
24
+ });