@digitraffic/common 2022.10.28-2 → 2022.10.31-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 (159) hide show
  1. package/.editorconfig +9 -0
  2. package/.eslintignore +4 -0
  3. package/.eslintrc.json +27 -0
  4. package/.github/CODEOWNERS +2 -0
  5. package/.github/workflows/build.yml +36 -0
  6. package/.github/workflows/eslint.yml +38 -0
  7. package/.github/workflows/mirror.yml +15 -0
  8. package/.gitignore +29 -0
  9. package/.husky/pre-commit +4 -0
  10. package/.prettierrc.json +10 -0
  11. package/dist/aws/infra/stack/lambda-configs.js +8 -8
  12. package/jest.config.js +15 -0
  13. package/package.json +4 -4
  14. package/src/aws/infra/stack/lambda-configs.ts +12 -12
  15. package/src/aws/infra/stack/monitoredfunction.ts +3 -3
  16. package/test/marine/id_utils.test.ts +57 -0
  17. package/test/promise/promise.test.ts +143 -0
  18. package/test/secrets/dbsecret.test.ts +59 -0
  19. package/test/secrets/secret-holder.test.ts +143 -0
  20. package/test/secrets/secret.test.ts +49 -0
  21. package/test/test/httpserver.test.ts +128 -0
  22. package/test/utils/date-utils.test.ts +28 -0
  23. package/test/utils/geometry.test.ts +29 -0
  24. package/test/utils/utils.test.ts +64 -0
  25. package/tsconfig.eslint.json +4 -0
  26. package/tsconfig.json +22 -0
  27. package/yarn.lock +4060 -0
  28. package/dist/aws/infra/api/integration.d.ts +0 -21
  29. package/dist/aws/infra/api/integration.js.map +0 -1
  30. package/dist/aws/infra/api/response.d.ts +0 -22
  31. package/dist/aws/infra/api/response.js.map +0 -1
  32. package/dist/aws/infra/api/responses.d.ts +0 -39
  33. package/dist/aws/infra/api/responses.js.map +0 -1
  34. package/dist/aws/infra/api/static-integration.d.ts +0 -15
  35. package/dist/aws/infra/api/static-integration.js.map +0 -1
  36. package/dist/aws/infra/canaries/canary-alarm.d.ts +0 -6
  37. package/dist/aws/infra/canaries/canary-alarm.js.map +0 -1
  38. package/dist/aws/infra/canaries/canary-keys.d.ts +0 -3
  39. package/dist/aws/infra/canaries/canary-keys.js.map +0 -1
  40. package/dist/aws/infra/canaries/canary-parameters.d.ts +0 -18
  41. package/dist/aws/infra/canaries/canary-parameters.js.map +0 -1
  42. package/dist/aws/infra/canaries/canary-role.d.ts +0 -6
  43. package/dist/aws/infra/canaries/canary-role.js.map +0 -1
  44. package/dist/aws/infra/canaries/canary.d.ts +0 -8
  45. package/dist/aws/infra/canaries/canary.js.map +0 -1
  46. package/dist/aws/infra/canaries/database-canary.d.ts +0 -18
  47. package/dist/aws/infra/canaries/database-canary.js.map +0 -1
  48. package/dist/aws/infra/canaries/database-checker.d.ts +0 -21
  49. package/dist/aws/infra/canaries/database-checker.js.map +0 -1
  50. package/dist/aws/infra/canaries/url-canary.d.ts +0 -16
  51. package/dist/aws/infra/canaries/url-canary.js.map +0 -1
  52. package/dist/aws/infra/canaries/url-checker.d.ts +0 -46
  53. package/dist/aws/infra/canaries/url-checker.js.map +0 -1
  54. package/dist/aws/infra/documentation.d.ts +0 -56
  55. package/dist/aws/infra/documentation.js.map +0 -1
  56. package/dist/aws/infra/scheduler.d.ts +0 -12
  57. package/dist/aws/infra/scheduler.js.map +0 -1
  58. package/dist/aws/infra/security-rule.d.ts +0 -12
  59. package/dist/aws/infra/security-rule.js.map +0 -1
  60. package/dist/aws/infra/sqs-integration.d.ts +0 -7
  61. package/dist/aws/infra/sqs-integration.js.map +0 -1
  62. package/dist/aws/infra/sqs-queue.d.ts +0 -16
  63. package/dist/aws/infra/sqs-queue.js.map +0 -1
  64. package/dist/aws/infra/stack/lambda-configs.d.ts +0 -72
  65. package/dist/aws/infra/stack/lambda-configs.js.map +0 -1
  66. package/dist/aws/infra/stack/monitoredfunction.d.ts +0 -84
  67. package/dist/aws/infra/stack/monitoredfunction.js.map +0 -1
  68. package/dist/aws/infra/stack/rest_apis.d.ts +0 -41
  69. package/dist/aws/infra/stack/rest_apis.js.map +0 -1
  70. package/dist/aws/infra/stack/stack-checking-aspect.d.ts +0 -21
  71. package/dist/aws/infra/stack/stack-checking-aspect.js.map +0 -1
  72. package/dist/aws/infra/stack/stack.d.ts +0 -45
  73. package/dist/aws/infra/stack/stack.js.map +0 -1
  74. package/dist/aws/infra/stack/subscription.d.ts +0 -17
  75. package/dist/aws/infra/stack/subscription.js.map +0 -1
  76. package/dist/aws/infra/usage-plans.d.ts +0 -15
  77. package/dist/aws/infra/usage-plans.js.map +0 -1
  78. package/dist/aws/runtime/apikey.d.ts +0 -2
  79. package/dist/aws/runtime/apikey.js.map +0 -1
  80. package/dist/aws/runtime/digitraffic-integration-response.d.ts +0 -8
  81. package/dist/aws/runtime/digitraffic-integration-response.js.map +0 -1
  82. package/dist/aws/runtime/environment.d.ts +0 -1
  83. package/dist/aws/runtime/environment.js.map +0 -1
  84. package/dist/aws/runtime/messaging.d.ts +0 -10
  85. package/dist/aws/runtime/messaging.js.map +0 -1
  86. package/dist/aws/runtime/s3.d.ts +0 -2
  87. package/dist/aws/runtime/s3.js.map +0 -1
  88. package/dist/aws/runtime/secrets/dbsecret.d.ts +0 -54
  89. package/dist/aws/runtime/secrets/dbsecret.js.map +0 -1
  90. package/dist/aws/runtime/secrets/proxy-holder.d.ts +0 -9
  91. package/dist/aws/runtime/secrets/proxy-holder.js.map +0 -1
  92. package/dist/aws/runtime/secrets/rds-holder.d.ts +0 -9
  93. package/dist/aws/runtime/secrets/rds-holder.js.map +0 -1
  94. package/dist/aws/runtime/secrets/secret-holder.d.ts +0 -26
  95. package/dist/aws/runtime/secrets/secret-holder.js.map +0 -1
  96. package/dist/aws/runtime/secrets/secret.d.ts +0 -8
  97. package/dist/aws/runtime/secrets/secret.js.map +0 -1
  98. package/dist/aws/types/errors.d.ts +0 -8
  99. package/dist/aws/types/errors.js.map +0 -1
  100. package/dist/aws/types/lambda-response.d.ts +0 -13
  101. package/dist/aws/types/lambda-response.js.map +0 -1
  102. package/dist/aws/types/mediatypes.d.ts +0 -10
  103. package/dist/aws/types/mediatypes.js.map +0 -1
  104. package/dist/aws/types/model-with-reference.d.ts +0 -7
  105. package/dist/aws/types/model-with-reference.js.map +0 -1
  106. package/dist/aws/types/proxytypes.d.ts +0 -26
  107. package/dist/aws/types/proxytypes.js.map +0 -1
  108. package/dist/aws/types/tags.d.ts +0 -2
  109. package/dist/aws/types/tags.js.map +0 -1
  110. package/dist/database/cached.d.ts +0 -7
  111. package/dist/database/cached.js.map +0 -1
  112. package/dist/database/database.d.ts +0 -19
  113. package/dist/database/database.js.map +0 -1
  114. package/dist/database/last-updated.d.ts +0 -16
  115. package/dist/database/last-updated.js.map +0 -1
  116. package/dist/database/models.d.ts +0 -6
  117. package/dist/database/models.js.map +0 -1
  118. package/dist/marine/id_utils.d.ts +0 -3
  119. package/dist/marine/id_utils.js.map +0 -1
  120. package/dist/marine/rtz.d.ts +0 -48
  121. package/dist/marine/rtz.js.map +0 -1
  122. package/dist/test/asserter.d.ts +0 -11
  123. package/dist/test/asserter.js.map +0 -1
  124. package/dist/test/db-testutils.d.ts +0 -2
  125. package/dist/test/db-testutils.js.map +0 -1
  126. package/dist/test/httpserver.d.ts +0 -19
  127. package/dist/test/httpserver.js.map +0 -1
  128. package/dist/test/secret.d.ts +0 -3
  129. package/dist/test/secret.js.map +0 -1
  130. package/dist/test/secrets-manager.d.ts +0 -9
  131. package/dist/test/secrets-manager.js.map +0 -1
  132. package/dist/test/testutils.d.ts +0 -12
  133. package/dist/test/testutils.js.map +0 -1
  134. package/dist/types/either.d.ts +0 -9
  135. package/dist/types/either.js.map +0 -1
  136. package/dist/types/input-error.d.ts +0 -2
  137. package/dist/types/input-error.js.map +0 -1
  138. package/dist/types/language.d.ts +0 -5
  139. package/dist/types/language.js.map +0 -1
  140. package/dist/types/traffictype.d.ts +0 -8
  141. package/dist/types/traffictype.js.map +0 -1
  142. package/dist/types/validator.d.ts +0 -4
  143. package/dist/types/validator.js.map +0 -1
  144. package/dist/utils/api-model.d.ts +0 -87
  145. package/dist/utils/api-model.js.map +0 -1
  146. package/dist/utils/base64.d.ts +0 -12
  147. package/dist/utils/base64.js.map +0 -1
  148. package/dist/utils/date-utils.d.ts +0 -17
  149. package/dist/utils/date-utils.js.map +0 -1
  150. package/dist/utils/geojson-types.d.ts +0 -14
  151. package/dist/utils/geojson-types.js.map +0 -1
  152. package/dist/utils/geometry.d.ts +0 -36
  153. package/dist/utils/geometry.js.map +0 -1
  154. package/dist/utils/retry.d.ts +0 -13
  155. package/dist/utils/retry.js.map +0 -1
  156. package/dist/utils/slack.d.ts +0 -5
  157. package/dist/utils/slack.js.map +0 -1
  158. package/dist/utils/utils.d.ts +0 -46
  159. package/dist/utils/utils.js.map +0 -1
@@ -0,0 +1,143 @@
1
+ import { mockSecret, stubSecretsManager } from "../../src/test/secrets-manager";
2
+
3
+ import * as sinon from "sinon";
4
+
5
+ const SECRET_WITH_PREFIX = {
6
+ "prefix.value": "value",
7
+ "prefix.name": "name",
8
+ "wrong.value": "value",
9
+ username: "DB_USER",
10
+ };
11
+ const SECRET_EMPTY = {};
12
+
13
+ const stubSM = stubSecretsManager();
14
+
15
+ import { SecretHolder } from "../../src/aws/runtime/secrets/secret-holder";
16
+ import { DatabaseEnvironmentKeys } from "../../src/aws/runtime/secrets/dbsecret";
17
+
18
+ describe("SecretHolder - tests", () => {
19
+ beforeEach(() => {
20
+ process.env["SECRET_ID"] = "test-id";
21
+ });
22
+
23
+ afterEach(() => {
24
+ sinon.restore();
25
+ sinon.reset();
26
+ delete process.env[DatabaseEnvironmentKeys.DB_USER];
27
+ });
28
+
29
+ test("get - no secret", async () => {
30
+ mockSecret(null);
31
+
32
+ const holder = SecretHolder.create();
33
+ await expect(async () => {
34
+ await holder.get();
35
+ }).rejects.toThrowError("No secret found!");
36
+ });
37
+
38
+ test("get - empty secret", async () => {
39
+ mockSecret(SECRET_EMPTY);
40
+
41
+ const holder = SecretHolder.create();
42
+ const secret = await holder.get();
43
+
44
+ expect(secret).toEqual(SECRET_EMPTY);
45
+ });
46
+
47
+ test("get - no prefix", async () => {
48
+ mockSecret(SECRET_WITH_PREFIX);
49
+
50
+ const holder = SecretHolder.create();
51
+ const secret = await holder.get();
52
+
53
+ expect(secret).toEqual(SECRET_WITH_PREFIX);
54
+ });
55
+
56
+ test("get - check keys - not found", async () => {
57
+ mockSecret(SECRET_WITH_PREFIX);
58
+
59
+ const holder = SecretHolder.create("", ["not_found"]);
60
+ await expect(async () => {
61
+ await holder.get();
62
+ }).rejects.toThrow();
63
+ });
64
+
65
+ test("get - check keys - found", async () => {
66
+ mockSecret(SECRET_WITH_PREFIX);
67
+
68
+ const holder = SecretHolder.create("", ["prefix.value", "username"]);
69
+
70
+ await holder.get();
71
+ });
72
+
73
+ test("setDatabaseCredentials - no prefix", async () => {
74
+ mockSecret(SECRET_WITH_PREFIX);
75
+
76
+ const holder = SecretHolder.create();
77
+ expect(process.env[DatabaseEnvironmentKeys.DB_USER]).toBeUndefined();
78
+
79
+ await holder.setDatabaseCredentials();
80
+ expect(process.env[DatabaseEnvironmentKeys.DB_USER]).toEqual(
81
+ SECRET_WITH_PREFIX.username
82
+ );
83
+ });
84
+
85
+ test("setDatabaseCredentials - with prefix", async () => {
86
+ mockSecret(SECRET_WITH_PREFIX);
87
+
88
+ const holder = SecretHolder.create("prefix");
89
+ expect(process.env[DatabaseEnvironmentKeys.DB_USER]).toBeUndefined();
90
+
91
+ await holder.setDatabaseCredentials();
92
+ expect(process.env[DatabaseEnvironmentKeys.DB_USER]).toEqual(
93
+ SECRET_WITH_PREFIX.username
94
+ );
95
+ });
96
+
97
+ test("getSecret - with prefix", async () => {
98
+ mockSecret(SECRET_WITH_PREFIX);
99
+
100
+ const holder = SecretHolder.create("prefix");
101
+ const secret = await holder.get();
102
+
103
+ expect(secret).toEqual({
104
+ value: "value",
105
+ name: "name",
106
+ });
107
+ });
108
+
109
+ test("get - ttl - do not fetch", async () => {
110
+ mockSecret(SECRET_WITH_PREFIX);
111
+
112
+ const holder = SecretHolder.create();
113
+
114
+ const callCount = stubSM.callCount;
115
+
116
+ await holder.get();
117
+ expect(stubSM.callCount).toEqual(callCount + 1);
118
+
119
+ // gets cached secret
120
+ await holder.get();
121
+ expect(stubSM.callCount).toEqual(callCount + 1);
122
+ });
123
+
124
+ test("get - ttl - fetch", async () => {
125
+ mockSecret(SECRET_WITH_PREFIX);
126
+
127
+ const holder = new SecretHolder("", "", [], {
128
+ ttl: 1,
129
+ });
130
+
131
+ const callCount = stubSM.callCount;
132
+
133
+ await holder.get();
134
+ expect(stubSM.callCount).toEqual(callCount + 1);
135
+
136
+ // cache expires, fetches secret again
137
+ const start = Date.now();
138
+ while (Date.now() < start + 2000);
139
+
140
+ await holder.get();
141
+ expect(stubSM.callCount).toEqual(callCount + 2);
142
+ });
143
+ });
@@ -0,0 +1,49 @@
1
+ import {mockSecret, stubSecretsManager} from "../../src/test/secrets-manager";
2
+
3
+ import * as sinon from 'sinon';
4
+
5
+ const SECRET_ID = "test_secret";
6
+ const SECRET_WITH_PREFIX = {
7
+ "prefix.value" : "value",
8
+ "prefix.name" : "name",
9
+ "wrong.value" : "value",
10
+ };
11
+ const SECRET_EMPTY = {};
12
+
13
+ stubSecretsManager();
14
+
15
+ import {getSecret} from "../../src/aws/runtime/secrets/secret";
16
+
17
+ describe('secret - test', () => {
18
+ afterEach(() => {
19
+ sinon.restore();
20
+ });
21
+
22
+ test('getSecret - no secret', async () => {
23
+ mockSecret(null);
24
+ await expect(async () => {
25
+ await getSecret(SECRET_ID, '');
26
+ }).rejects.toThrowError("No secret found!");
27
+ });
28
+
29
+ test('getSecret - empty secret', async () => {
30
+ mockSecret(SECRET_EMPTY);
31
+ const secret = await getSecret(SECRET_ID, '');
32
+ expect(secret).toEqual(SECRET_EMPTY);
33
+ });
34
+
35
+ test('getSecret - no prefix', async () => {
36
+ mockSecret(SECRET_WITH_PREFIX);
37
+ const secret = await getSecret(SECRET_ID, '');
38
+ expect(secret).toEqual(SECRET_WITH_PREFIX);
39
+ });
40
+
41
+ test('getSecret - with prefix', async () => {
42
+ mockSecret(SECRET_WITH_PREFIX);
43
+ const secret = await getSecret(SECRET_ID, 'prefix');
44
+ expect(secret).toEqual({
45
+ value: "value",
46
+ name: "name",
47
+ });
48
+ });
49
+ });
@@ -0,0 +1,128 @@
1
+ import {
2
+ TestHttpServer,
3
+ ListenProperties,
4
+ ERROR_NO_MATCH,
5
+ ERRORCODE_NOT_FOUND,
6
+ } from "../../src/test/httpserver";
7
+ import { IncomingMessage } from "http";
8
+ import http = require("http");
9
+
10
+ const DEFAULT_PATH = "/";
11
+ const PORT = 8091;
12
+
13
+ const DEFAULT_PROPS = {
14
+ "/": () => "",
15
+ };
16
+
17
+ describe("TestHttpServer - test", () => {
18
+ async function withServer(
19
+ fn: (server: TestHttpServer) => Promise<void>,
20
+ props: ListenProperties = DEFAULT_PROPS,
21
+ statusCode = 200
22
+ ) {
23
+ const server = new TestHttpServer();
24
+
25
+ server.listen(PORT, props, false, statusCode);
26
+
27
+ try {
28
+ await fn(server);
29
+ } finally {
30
+ server.close();
31
+ }
32
+ }
33
+
34
+ function sendGetRequest(path = DEFAULT_PATH): Promise<IncomingMessage> {
35
+ return sendRequest("GET", path);
36
+ }
37
+
38
+ function sendPostRequest(
39
+ path = DEFAULT_PATH,
40
+ body: string
41
+ ): Promise<IncomingMessage> {
42
+ return sendRequest("POST", path, body);
43
+ }
44
+
45
+ function sendRequest(
46
+ method: string,
47
+ path: string,
48
+ body?: string
49
+ ): Promise<IncomingMessage> {
50
+ return new Promise((resolve, reject) => {
51
+ const request = http.request(
52
+ {
53
+ path,
54
+ port: PORT,
55
+ method,
56
+ },
57
+ (response: IncomingMessage) => {
58
+ response.on("data", () => {
59
+ // do nothing
60
+ });
61
+
62
+ //the whole response has been received, so we just print it out here
63
+ response.on("end", () => {
64
+ resolve(response);
65
+ });
66
+
67
+ response.on("error", (error: Error) => {
68
+ reject(error);
69
+ });
70
+ }
71
+ );
72
+
73
+ if (method === "POST") {
74
+ request.write(body);
75
+ }
76
+ request.end();
77
+ });
78
+ }
79
+
80
+ test("no calls", () => {
81
+ return withServer(async (server: TestHttpServer) => {
82
+ await expect(server.getCallCount()).toEqual(0);
83
+ });
84
+ });
85
+
86
+ test("one get", async () => {
87
+ await withServer(async (server: TestHttpServer) => {
88
+ await sendGetRequest();
89
+
90
+ expect(server.getCallCount()).toEqual(1);
91
+ });
92
+ });
93
+
94
+ test("one get - no MATCH", async () => {
95
+ await withServer(async (server: TestHttpServer) => {
96
+ const response = await sendGetRequest("/no-match");
97
+
98
+ expect(server.getCallCount()).toEqual(1);
99
+ expect(server.getRequestBody(0)).toEqual(ERROR_NO_MATCH);
100
+ expect(response.statusCode).toEqual(ERRORCODE_NOT_FOUND);
101
+ });
102
+ });
103
+
104
+ test("get - error 405", async () => {
105
+ const ERROR_CODE = 405;
106
+
107
+ await withServer(
108
+ async (server: TestHttpServer) => {
109
+ const response = await sendGetRequest();
110
+
111
+ expect(server.getCallCount()).toEqual(1);
112
+ expect(response.statusCode).toEqual(ERROR_CODE);
113
+ },
114
+ DEFAULT_PROPS,
115
+ ERROR_CODE
116
+ );
117
+ });
118
+
119
+ test("one post", async () => {
120
+ await withServer(async (server: TestHttpServer) => {
121
+ const testBody = "Testing123!";
122
+ await sendPostRequest(DEFAULT_PATH, testBody);
123
+
124
+ expect(server.getCallCount()).toEqual(1);
125
+ expect(server.getRequestBody(0)).toEqual(testBody);
126
+ });
127
+ });
128
+ });
@@ -0,0 +1,28 @@
1
+ import moment from "moment";
2
+ import * as CommonDateUtils from "../../src/utils/date-utils";
3
+
4
+ const ISO = "2022-01-02T01:02:03.004Z";
5
+
6
+ describe('CommonDateUtilsTest', () => {
7
+
8
+ test('dateFromIsoString', () => {
9
+ const parsed = CommonDateUtils.dateFromIsoString(ISO);
10
+ expect(parsed.toISOString()).toEqual(ISO);
11
+ });
12
+
13
+ test('dateFromIsoString fails', () => {
14
+ expect(() => CommonDateUtils.dateFromIsoString(ISO + "foobar")).toThrowError();
15
+ });
16
+
17
+ test('countDiffMs', () => {
18
+ const start = new Date();
19
+ const end = moment(start).add(1234, 'milliseconds').toDate();
20
+ expect (CommonDateUtils.countDiffMs(start, end)).toEqual(1234);
21
+ });
22
+
23
+ test('countDiffMs', () => {
24
+ const start = new Date();
25
+ const end = moment(start).add(1234, 'seconds').toDate();
26
+ expect (CommonDateUtils.countDiffInSeconds(start, end)).toEqual(1234);
27
+ });
28
+ });
@@ -0,0 +1,29 @@
1
+ import {Asserter} from "../../src/test/asserter";
2
+ import * as Geometry from '../../src/utils/geometry';
3
+
4
+ const TAMPERE_WGS84_X = 23.761290078;
5
+ const TAMPERE_WGS84_Y = 61.497742570;
6
+
7
+ const KUOPIO_WGS84_X = 27.688935;
8
+ const KUOPIO_WGS84_Y = 62.892983;
9
+ const TAMPERE_KUOPIO_DISTANCE_KM = 255.8;
10
+
11
+ describe('CommonGeometryTest', () => {
12
+
13
+ test('distanceBetweenWGS84PointsInKm', () => {
14
+ Asserter.assertToBeCloseTo(Geometry.distanceBetweenPositionsInKm([TAMPERE_WGS84_X, TAMPERE_WGS84_Y], [KUOPIO_WGS84_X, KUOPIO_WGS84_Y]),TAMPERE_KUOPIO_DISTANCE_KM, 0.5);
15
+ console.info(Geometry.distanceBetweenPositionsInKm([TAMPERE_WGS84_X, TAMPERE_WGS84_Y], [KUOPIO_WGS84_X, KUOPIO_WGS84_Y]));
16
+ });
17
+
18
+ test('distanceBetweenWGS84PointsInKm', () => {
19
+ Asserter.assertToBeCloseTo(Geometry.distanceBetweenPositionsInM([TAMPERE_WGS84_X, TAMPERE_WGS84_Y], [KUOPIO_WGS84_X, KUOPIO_WGS84_Y]),TAMPERE_KUOPIO_DISTANCE_KM*1000, 500);
20
+ console.info(Geometry.distanceBetweenPositionsInM([TAMPERE_WGS84_X, TAMPERE_WGS84_Y], [KUOPIO_WGS84_X, KUOPIO_WGS84_Y]));
21
+ });
22
+
23
+ test('areDistinctPositions', () => {
24
+ expect(Geometry.areDistinctPositions([1,2],[1,2])).toBe(false);
25
+ expect(Geometry.areDistinctPositions([1.1,2.2],[1.1,2.2])).toBe(false);
26
+ expect(Geometry.areDistinctPositions([1,2.1],[1,2])).toBe(true);
27
+ expect(Geometry.areDistinctPositions([1,2],[1,2.000000000000001])).toBe(true);
28
+ });
29
+ });
@@ -0,0 +1,64 @@
1
+ import * as ArrayUtils from "../../src/utils/utils";
2
+
3
+ describe("ArrayUtils", () => {
4
+ test("bothArraysHasSameValues", () => {
5
+ expect(ArrayUtils.bothArraysHasSameValues([], [])).toEqual(true);
6
+ expect(ArrayUtils.bothArraysHasSameValues(["a"], ["a"])).toEqual(true);
7
+ expect(ArrayUtils.bothArraysHasSameValues(["a"], ["a", "a"])).toEqual(
8
+ true
9
+ );
10
+ expect(
11
+ ArrayUtils.bothArraysHasSameValues(["a", "a"], ["a", "a"])
12
+ ).toEqual(true);
13
+
14
+ expect(ArrayUtils.bothArraysHasSameValues(null, null)).toEqual(true);
15
+ expect(
16
+ ArrayUtils.bothArraysHasSameValues(undefined, undefined)
17
+ ).toEqual(true);
18
+ expect(ArrayUtils.bothArraysHasSameValues(null, undefined)).toEqual(
19
+ true
20
+ );
21
+ expect(ArrayUtils.bothArraysHasSameValues(["a"], undefined)).toEqual(
22
+ false
23
+ );
24
+ expect(ArrayUtils.bothArraysHasSameValues(["a"], null)).toEqual(false);
25
+ /* eslint-enable */
26
+ expect(
27
+ ArrayUtils.bothArraysHasSameValues(["a", "b"], ["a", "a"])
28
+ ).toEqual(false);
29
+ expect(
30
+ ArrayUtils.bothArraysHasSameValues(["a", "a", "a"], ["a", "b", "c"])
31
+ ).toEqual(false);
32
+
33
+ const o1 = { a: 1, b: 2 };
34
+ const o2 = { a: 1, b: 2 };
35
+ // Objects are references to same
36
+ expect(ArrayUtils.bothArraysHasSameValues([o1], [o1])).toEqual(true);
37
+ // Object's are not the same but the contents are the same
38
+ expect(ArrayUtils.bothArraysHasSameValues([o1], [o2])).toEqual(false);
39
+ });
40
+
41
+ test("getFirst - empty throws", () => {
42
+ expect(() => {
43
+ ArrayUtils.getFirst([]);
44
+ }).toThrow();
45
+ });
46
+
47
+ test("getFirst - two objects", () => {
48
+ expect(ArrayUtils.getFirst([1, 2])).toEqual(1);
49
+ });
50
+
51
+ test("getFirst - two objects with sort function", () => {
52
+ expect(ArrayUtils.getFirst([1, 2], (a) => -a)).toEqual(2);
53
+ });
54
+
55
+ test("getLast - empty throws", () => {
56
+ expect(() => {
57
+ ArrayUtils.getLast([]);
58
+ }).toThrow();
59
+ });
60
+
61
+ test("getLast - two objects", () => {
62
+ expect(ArrayUtils.getLast([1, 2])).toEqual(2);
63
+ });
64
+ });
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "include": ["src/**/*.ts", "test/**/*.ts"],
4
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["es2020"],
6
+ "outDir": "dist",
7
+ "declaration": true,
8
+ "sourceMap": true,
9
+ "moduleResolution": "node",
10
+ "strict": true,
11
+ "exactOptionalPropertyTypes": false,
12
+ "esModuleInterop": true,
13
+ "forceConsistentCasingInFileNames": true,
14
+ "skipLibCheck": true,
15
+
16
+ "noImplicitReturns": true,
17
+ "noFallthroughCasesInSwitch": true,
18
+ "experimentalDecorators": true
19
+ },
20
+ "include": ["src/**/*.ts"],
21
+ "$schema": "https://json.schemastore.org/tsconfig"
22
+ }