This repository has been archived by the owner on Jul 9, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 467
/
Copy pathrevert_error_test.ts
201 lines (190 loc) · 8.87 KB
/
revert_error_test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
import * as chai from 'chai';
import * as _ from 'lodash';
import {
AnyRevertError,
getThrownErrorRevertErrorBytes,
RawRevertError,
RevertError,
StringRevertError,
} from '../src/revert_error';
import { chaiSetup } from './utils/chai_setup';
chaiSetup.configure();
const expect = chai.expect;
// tslint:disable: max-classes-per-file
class DescendantRevertError extends StringRevertError {
public constructor(message: string) {
super(message);
}
}
class CustomRevertError extends RevertError {
public constructor(message?: string) {
super('CustomRevertError', 'CustomRevertError(string message)', { message });
}
}
class ArrayRevertError extends RevertError {
public constructor(strings?: string[]) {
super('ArrayRevertError', 'ArrayRevertError(string[] strings)', { strings });
}
}
class FixedSizeArrayRevertError extends RevertError {
public constructor(strings?: string[]) {
super('FixedArrayRevertError', 'FixedArrayRevertError(string[2] strings)', { strings });
}
}
class ParentRevertError extends RevertError {
public constructor(nestedError?: string) {
super('ParentRevertError', 'ParentRevertError(bytes nestedError)', { nestedError });
}
}
RevertError.registerType(CustomRevertError);
RevertError.registerType(ParentRevertError);
describe('RevertError', () => {
describe('equality', () => {
const message = 'foo';
it('should equate two identical RevertErrors', () => {
const revert1 = new StringRevertError(message);
const revert2 = new StringRevertError(message);
expect(revert1.equals(revert2)).to.be.true();
});
it('should equate two RevertErrors with missing fields', () => {
const revert1 = new StringRevertError(message);
const revert2 = new StringRevertError();
expect(revert1.equals(revert2)).to.be.true();
});
it('should equate AnyRevertError with a real RevertError', () => {
const revert1 = new StringRevertError(message);
const revert2 = new AnyRevertError();
expect(revert1.equals(revert2)).to.be.true();
});
it('should equate two revert errors with identical array fields', () => {
const strings = ['foo', 'bar'];
const revert1 = new ArrayRevertError(strings);
const revert2 = new ArrayRevertError(strings);
expect(revert1.equals(revert2)).to.be.true();
});
it('should not equate two revert errors with different sized array fields', () => {
const strings = ['foo', 'bar'];
const revert1 = new ArrayRevertError(strings);
const revert2 = new ArrayRevertError(strings.slice(0, 1));
expect(revert1.equals(revert2)).to.be.false();
});
it('should not equate two revert errors with different array field values', () => {
const strings1 = ['foo', 'bar'];
const strings2 = ['foo', 'baz'];
const revert1 = new ArrayRevertError(strings1);
const revert2 = new ArrayRevertError(strings2);
expect(revert1.equals(revert2)).to.be.false();
});
it('should equate two revert errors with identical fixed-size array fields', () => {
const strings = ['foo', 'bar'];
const revert1 = new FixedSizeArrayRevertError(strings);
const revert2 = new FixedSizeArrayRevertError(strings);
expect(revert1.equals(revert2)).to.be.true();
});
it('should not equate two revert errors with different sized fixed-size array fields', () => {
const strings = ['foo', 'bar'];
const revert1 = new FixedSizeArrayRevertError(strings);
const revert2 = new FixedSizeArrayRevertError(strings.slice(0, 1));
expect(revert1.equals(revert2)).to.be.false();
});
it('should not equate two revert errors with the wrong sized fixed-size array fields', () => {
const strings = ['foo', 'bar', 'baz'];
const revert1 = new FixedSizeArrayRevertError(strings);
const revert2 = new FixedSizeArrayRevertError(strings);
expect(revert1.equals(revert2)).to.be.false();
});
it('should not equate two revert errors with different fixed-size array field values', () => {
const strings1 = ['foo', 'bar'];
const strings2 = ['foo', 'baz'];
const revert1 = new FixedSizeArrayRevertError(strings1);
const revert2 = new FixedSizeArrayRevertError(strings2);
expect(revert1.equals(revert2)).to.be.false();
});
it('should not equate a the same RevertError type with different values', () => {
const revert1 = new StringRevertError(message);
const revert2 = new StringRevertError(`${message}1`);
expect(revert1.equals(revert2)).to.be.false();
});
it('should not equate different RevertError types', () => {
const revert1 = new StringRevertError(message);
const revert2 = new DescendantRevertError(message);
expect(revert1.equals(revert2)).to.be.false();
});
it('should equate two `RawRevertError` types with the same raw data', () => {
const revert1 = new RawRevertError('0x0123456789');
const revert2 = new RawRevertError(revert1.encode());
expect(revert1.equals(revert2)).to.be.true();
});
it('should not equate two `RawRevertError` types with the different raw data', () => {
const revert1 = new RawRevertError('0x0123456789');
const revert2 = new RawRevertError(`${revert1.encode()}00`);
expect(revert1.equals(revert2)).to.be.false();
});
});
describe('registering', () => {
it('should throw when registering an already registered signature', () => {
class CustomRevertError2 extends RevertError {
public constructor() {
super('CustomRevertError2', new CustomRevertError().signature, {});
}
}
expect(() => RevertError.registerType(CustomRevertError2)).to.throw();
});
});
describe('decoding', () => {
// tslint:disable: prefer-template custom-no-magic-numbers
const message = 'foobar';
const encoded =
'0x08c379a0' +
'0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000006' +
Buffer.from(message).toString('hex') +
_.repeat('00', 32 - 6);
it('should decode an ABI encoded revert error', () => {
const expected = new StringRevertError(message);
const decoded = RevertError.decode(encoded);
expect(decoded.equals(expected)).to.be.true();
});
it('should decode an unknown selector as a `RawRevertError`', () => {
const _encoded = encoded.substr(0, 2) + '00' + encoded.substr(4);
const decoded = RevertError.decode(_encoded, true);
expect(decoded).is.instanceof(RawRevertError);
});
it('should fail to decode a malformed ABI encoded revert error', () => {
const _encoded = encoded.substr(0, encoded.length - 1);
const decode = () => RevertError.decode(_encoded);
expect(decode).to.throw();
});
it('should decode a nested revert error', () => {
const nested = new StringRevertError(message);
const parent = new ParentRevertError(nested.encode());
const decoded = RevertError.decode(parent.encode());
expect(decoded.encode()).to.equal(new ParentRevertError(nested.encode()).encode());
});
});
describe('getThrownErrorRevertErrorBytes', () => {
it('should decode Parity revert errors', () => {
const revertAbi = '0x1234';
const parityError = { code: 1234, message: 'VM execution error.', data: `Reverted ${revertAbi}`, name: '' };
const revertError = getThrownErrorRevertErrorBytes(parityError);
expect(revertError).to.be.eq(revertAbi);
});
});
describe('encoding', () => {
const message = 'foobar';
it('should be able to encode', () => {
const expected =
'0x08c379a0' +
'0000000000000000000000000000000000000000000000000000000000000020' +
'0000000000000000000000000000000000000000000000000000000000000006' +
Buffer.from(message).toString('hex') +
_.repeat('00', 32 - 6);
const revert = new StringRevertError(message);
expect(revert.encode()).to.equal(expected);
});
it('should throw if missing parameter values', () => {
const revert = new StringRevertError();
expect(() => revert.encode()).to.throw();
});
});
});