@rosen-bridge/abstract-extractor 0.3.0 → 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 (49) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/ergo/AbstractErgoExtractor.d.ts +31 -8
  3. package/dist/ergo/AbstractErgoExtractor.d.ts.map +1 -1
  4. package/dist/ergo/AbstractErgoExtractor.js +73 -8
  5. package/dist/ergo/AbstractErgoExtractorAction.d.ts +38 -10
  6. package/dist/ergo/AbstractErgoExtractorAction.d.ts.map +1 -1
  7. package/dist/ergo/AbstractErgoExtractorAction.js +134 -1
  8. package/dist/ergo/AbstractErgoExtractorEntity.d.ts +11 -0
  9. package/dist/ergo/AbstractErgoExtractorEntity.d.ts.map +1 -0
  10. package/dist/ergo/AbstractErgoExtractorEntity.js +57 -0
  11. package/dist/ergo/index.d.ts +1 -0
  12. package/dist/ergo/index.d.ts.map +1 -1
  13. package/dist/ergo/index.js +2 -1
  14. package/dist/ergo/initializable/AbstractInitializable.d.ts +4 -3
  15. package/dist/ergo/initializable/AbstractInitializable.d.ts.map +1 -1
  16. package/dist/ergo/initializable/AbstractInitializable.js +9 -5
  17. package/dist/ergo/initializable/AbstractInitializableAction.d.ts +7 -2
  18. package/dist/ergo/initializable/AbstractInitializableAction.d.ts.map +1 -1
  19. package/dist/ergo/initializable/AbstractInitializableAction.js +11 -1
  20. package/dist/ergo/interfaces.d.ts +21 -7
  21. package/dist/ergo/interfaces.d.ts.map +1 -1
  22. package/dist/ergo/interfaces.js +8 -1
  23. package/lib/ergo/AbstractErgoExtractor.ts +107 -23
  24. package/lib/ergo/AbstractErgoExtractorAction.ts +187 -18
  25. package/lib/ergo/AbstractErgoExtractorEntity.ts +28 -0
  26. package/lib/ergo/index.ts +1 -0
  27. package/lib/ergo/initializable/AbstractInitializable.ts +22 -9
  28. package/lib/ergo/initializable/AbstractInitializableAction.ts +19 -3
  29. package/lib/ergo/interfaces.ts +25 -7
  30. package/package.json +6 -2
  31. package/tests/{AbstractExtractor.mock.ts → AbstractErgoExtractor.mock.ts} +12 -7
  32. package/tests/AbstractErgoExtractor.spec.ts +281 -0
  33. package/tests/AbstractErgoExtractorAction.mock.ts +45 -0
  34. package/tests/AbstractErgoExtractorAction.spec.ts +269 -0
  35. package/tests/initializable/AbstractInitializable.mock.ts +15 -8
  36. package/tests/initializable/AbstractInitializable.spec.ts +37 -5
  37. package/tests/initializable/AbstractInitializableAction.mock.ts +45 -0
  38. package/tests/initializable/AbstractInitializableAction.spec.ts +65 -0
  39. package/tests/testData.ts +38 -2
  40. package/tests/testUtils.ts +22 -0
  41. package/tsconfig.build.tsbuildinfo +1 -1
  42. package/dist/ergo/initializable/InitializableByAddress.d.ts +0 -19
  43. package/dist/ergo/initializable/InitializableByAddress.d.ts.map +0 -1
  44. package/dist/ergo/initializable/InitializableByAddress.js +0 -30
  45. package/dist/ergo/initializable/InitializableByToken.d.ts +0 -19
  46. package/dist/ergo/initializable/InitializableByToken.d.ts.map +0 -1
  47. package/dist/ergo/initializable/InitializableByToken.js +0 -30
  48. package/dist/tsconfig.tsbuildinfo +0 -1
  49. package/tests/AbstractExtractor.spec.ts +0 -106
@@ -3,8 +3,9 @@ import { describe, expect, it, vi, vitest } from 'vitest';
3
3
  import {
4
4
  ErgoNetworkType,
5
5
  NodeNetwork,
6
- ErgoExtractedData,
6
+ AbstractBoxData,
7
7
  ExplorerNetwork,
8
+ AbstractErgoExtractorEntity,
8
9
  } from '../../lib';
9
10
  import { MockedInitializableErgoExtractor } from './AbstractInitializable.mock';
10
11
  import { transactionBatch } from './testData';
@@ -59,7 +60,7 @@ describe('AbstractInitializableErgoExtractor', () => {
59
60
  'node_url',
60
61
  'address'
61
62
  );
62
- const processSpy = vitest.fn();
63
+ const processSpy = vitest.fn().mockResolvedValue(true);
63
64
  extractor.processTransactions = processSpy;
64
65
  await extractor['processTransactionBatch'](transactionBatch);
65
66
  expect(processSpy).toBeCalledTimes(2);
@@ -75,6 +76,28 @@ describe('AbstractInitializableErgoExtractor', () => {
75
76
  }
76
77
  );
77
78
  });
79
+
80
+ /**
81
+ * @target processTransactionBatch should throw error when processing transactions fails for a block
82
+ * @dependencies
83
+ * @scenario
84
+ * - mock extractor
85
+ * - spy `processTransactions` to return false (always fails)
86
+ * - run test (call `processTransactionBatch`)
87
+ * @expected
88
+ * - to throw error
89
+ */
90
+ it('should throw error when processing transactions fails for a block', async () => {
91
+ const extractor = new MockedInitializableErgoExtractor(
92
+ ErgoNetworkType.Node,
93
+ 'node_url',
94
+ 'address'
95
+ );
96
+ extractor.processTransactions = vitest.fn().mockResolvedValue(false);
97
+ await expect(() =>
98
+ extractor['processTransactionBatch'](transactionBatch)
99
+ ).rejects.toThrowError();
100
+ });
78
101
  });
79
102
 
80
103
  describe('initWithRetrial', () => {
@@ -102,7 +125,10 @@ describe('AbstractInitializableErgoExtractor', () => {
102
125
  const removeSpy = vitest.fn();
103
126
  extractor['actions'] = {
104
127
  removeAllData: removeSpy,
105
- } as unknown as AbstractInitializableErgoExtractorAction<ErgoExtractedData>;
128
+ } as unknown as AbstractInitializableErgoExtractorAction<
129
+ AbstractBoxData,
130
+ AbstractErgoExtractorEntity
131
+ >;
106
132
  const initSpy = vitest.fn();
107
133
  await extractor['initWithRetrial'](initSpy);
108
134
  expect(removeSpy).not.toHaveBeenCalled();
@@ -131,7 +157,10 @@ describe('AbstractInitializableErgoExtractor', () => {
131
157
  const removeSpy = vitest.fn();
132
158
  extractor['actions'] = {
133
159
  removeAllData: removeSpy,
134
- } as unknown as AbstractInitializableErgoExtractorAction<ErgoExtractedData>;
160
+ } as unknown as AbstractInitializableErgoExtractorAction<
161
+ AbstractBoxData,
162
+ AbstractErgoExtractorEntity
163
+ >;
135
164
  const initSpy = vitest.fn();
136
165
  await extractor['initWithRetrial'](initSpy);
137
166
  expect(removeSpy).toHaveBeenCalledOnce();
@@ -161,7 +190,10 @@ describe('AbstractInitializableErgoExtractor', () => {
161
190
  const removeSpy = vitest.fn();
162
191
  extractor['actions'] = {
163
192
  removeAllData: removeSpy,
164
- } as unknown as AbstractInitializableErgoExtractorAction<ErgoExtractedData>;
193
+ } as unknown as AbstractInitializableErgoExtractorAction<
194
+ AbstractBoxData,
195
+ AbstractErgoExtractorEntity
196
+ >;
165
197
  const initSpy = vitest.fn().mockRejectedValue(0);
166
198
  await expect(
167
199
  async () => await extractor['initWithRetrial'](initSpy)
@@ -0,0 +1,45 @@
1
+ import { DataSource } from 'typeorm';
2
+ import { pick } from 'lodash-es';
3
+
4
+ import {
5
+ AbstractErgoExtractorEntity,
6
+ BlockInfo,
7
+ AbstractBoxData,
8
+ AbstractInitializableErgoExtractorAction,
9
+ } from '../../lib';
10
+ import { TestEntity } from '../testUtils';
11
+
12
+ export class TestInitializableErgoExtractorAction extends AbstractInitializableErgoExtractorAction<
13
+ AbstractBoxData,
14
+ AbstractErgoExtractorEntity
15
+ > {
16
+ constructor(dataSource: DataSource) {
17
+ super(dataSource, TestEntity);
18
+ }
19
+
20
+ /**
21
+ * create the test database entity from data and block information
22
+ */
23
+ createEntity = (
24
+ boxes: AbstractBoxData[],
25
+ block: BlockInfo,
26
+ extractor: string
27
+ ): Omit<AbstractErgoExtractorEntity, 'id'>[] => {
28
+ return boxes.map((box) => ({
29
+ boxId: box.boxId,
30
+ block: block.hash,
31
+ height: block.height,
32
+ serialized: box.serialized,
33
+ extractor: extractor,
34
+ }));
35
+ };
36
+
37
+ /**
38
+ * convert the database entity back to raw data
39
+ */
40
+ convertEntityToData = (
41
+ entities: AbstractErgoExtractorEntity[]
42
+ ): AbstractBoxData[] => {
43
+ return entities.map((data) => pick(data, ['boxId', 'serialized']));
44
+ };
45
+ }
@@ -0,0 +1,65 @@
1
+ import { DataSource, Repository } from 'typeorm';
2
+ import { describe, it, expect, beforeEach } from 'vitest';
3
+
4
+ import { TestInitializableErgoExtractorAction } from './AbstractInitializableAction.mock';
5
+ import { createDatabase, TestEntity } from '../testUtils';
6
+ import { sampleEntities } from '../testData';
7
+
8
+ describe('AbstractErgoExtractorAction', () => {
9
+ let dataSource: DataSource;
10
+ let action: TestInitializableErgoExtractorAction;
11
+ let repository: Repository<TestEntity>;
12
+ beforeEach(async () => {
13
+ dataSource = await createDatabase();
14
+ action = new TestInitializableErgoExtractorAction(dataSource);
15
+ repository = dataSource.getRepository(TestEntity);
16
+ });
17
+
18
+ describe('removeAllData', () => {
19
+ /**
20
+ * @target removeAllData should remove all available data related to this extractor
21
+ * @dependencies
22
+ * @scenario
23
+ * - insert 4 entities related to this extractor
24
+ * - run test (call `removeAllData`)
25
+ * @expected
26
+ * - to have 4 entities before removing
27
+ * - to have no remaining entities after remove
28
+ */
29
+ it(`should remove all available data related to this extractor`, async () => {
30
+ await dataSource.getRepository(TestEntity).insert(sampleEntities);
31
+ const countBefore = await repository.count();
32
+
33
+ await action.removeAllData('extractor');
34
+ const countAfter = await repository.count();
35
+
36
+ expect(countBefore).toEqual(4);
37
+ expect(countAfter).toEqual(0);
38
+ });
39
+
40
+ /**
41
+ * @target removeAllData should not remove any data related to another extractor
42
+ * @dependencies
43
+ * @scenario
44
+ * - insert 4 entities related to another extractor
45
+ * - run test (call `removeAllData`)
46
+ * @expected
47
+ * - to have 4 entities after removing
48
+ */
49
+ it(`should not remove any data related to another extractor`, async () => {
50
+ await dataSource.getRepository(TestEntity).insert(
51
+ sampleEntities.map((entity) => ({
52
+ ...entity,
53
+ extractor: 'extractor-new',
54
+ }))
55
+ );
56
+ const countBefore = await repository.count();
57
+
58
+ await action.removeAllData('extractor');
59
+ const countAfter = await repository.count();
60
+
61
+ expect(countBefore).toEqual(4);
62
+ expect(countAfter).toEqual(4);
63
+ });
64
+ });
65
+ });
package/tests/testData.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Block } from '../lib';
2
+ import { TestEntity } from './testUtils';
2
3
 
3
4
  export const tx = {
4
5
  id: '3b91fbd2b6f4f3f971098655ffa320841001b071908de057cdf8c425cd3b3e61',
@@ -100,8 +101,6 @@ export const extractedData = {
100
101
  boxId: 'boxId1',
101
102
  address: 'address1',
102
103
  serialized: 'serialized1',
103
- blockId: 'blockId1',
104
- height: 98,
105
104
  };
106
105
 
107
106
  export const block: Block = {
@@ -109,3 +108,40 @@ export const block: Block = {
109
108
  height: 100,
110
109
  parentHash: 'parentHash',
111
110
  } as Block;
111
+
112
+ export const block2: Block = {
113
+ hash: 'hash2',
114
+ height: 101,
115
+ parentHash: 'parentHash2',
116
+ } as Block;
117
+
118
+ export const sampleEntities: Omit<TestEntity, 'id'>[] = [
119
+ {
120
+ extractor: 'extractor',
121
+ boxId: '1',
122
+ serialized: 'serialized1',
123
+ block: 'blockId1',
124
+ height: 100,
125
+ },
126
+ {
127
+ extractor: 'extractor',
128
+ boxId: '2',
129
+ serialized: 'serialized2',
130
+ block: 'blockId2',
131
+ height: 200,
132
+ },
133
+ {
134
+ extractor: 'extractor',
135
+ boxId: '3',
136
+ serialized: 'serialized3',
137
+ block: 'blockId3',
138
+ height: 300,
139
+ },
140
+ {
141
+ extractor: 'extractor',
142
+ boxId: '4',
143
+ serialized: 'serialized4',
144
+ block: 'blockId4',
145
+ height: 400,
146
+ },
147
+ ];
@@ -0,0 +1,22 @@
1
+ import { DataSource, Entity } from 'typeorm';
2
+ import { AbstractErgoExtractorEntity } from '../lib';
3
+
4
+ @Entity('test_entity')
5
+ export class TestEntity extends AbstractErgoExtractorEntity {}
6
+
7
+ /**
8
+ * generates a dataSource with in memory database for testing
9
+ */
10
+ export const createDatabase = async (): Promise<DataSource> => {
11
+ const dataSource = new DataSource({
12
+ type: 'sqlite',
13
+ database: `:memory:`,
14
+ entities: [TestEntity],
15
+ migrations: [],
16
+ synchronize: true,
17
+ logging: false,
18
+ });
19
+ await dataSource.initialize();
20
+ await dataSource.runMigrations();
21
+ return dataSource;
22
+ };