|
@@ -119,61 +119,63 @@ describe('Arrays', function () {
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- for (const type of TYPES) {
|
|
|
- const elements = Array.from({ length: 10 }, generators[type]);
|
|
|
+ for (const { name, isValueType } of TYPES) {
|
|
|
+ const elements = Array.from({ length: 10 }, generators[name]);
|
|
|
|
|
|
- describe(type, function () {
|
|
|
+ describe(name, function () {
|
|
|
const fixture = async () => {
|
|
|
- return { instance: await ethers.deployContract(`${capitalize(type)}ArraysMock`, [elements]) };
|
|
|
+ return { instance: await ethers.deployContract(`${capitalize(name)}ArraysMock`, [elements]) };
|
|
|
};
|
|
|
|
|
|
beforeEach(async function () {
|
|
|
Object.assign(this, await loadFixture(fixture));
|
|
|
});
|
|
|
|
|
|
- describe('sort', function () {
|
|
|
- for (const length of [0, 1, 2, 8, 32, 128]) {
|
|
|
- describe(`${type}[] of length ${length}`, function () {
|
|
|
- beforeEach(async function () {
|
|
|
- this.array = Array.from({ length }, generators[type]);
|
|
|
- });
|
|
|
-
|
|
|
- afterEach(async function () {
|
|
|
- const expected = Array.from(this.array).sort(comparator);
|
|
|
- const reversed = Array.from(expected).reverse();
|
|
|
- expect(await this.instance.sort(this.array)).to.deep.equal(expected);
|
|
|
- expect(await this.instance.sortReverse(this.array)).to.deep.equal(reversed);
|
|
|
- });
|
|
|
-
|
|
|
- it('sort array', async function () {
|
|
|
- // nothing to do here, beforeEach and afterEach already take care of everything.
|
|
|
- });
|
|
|
-
|
|
|
- if (length > 1) {
|
|
|
- it('sort array for identical elements', async function () {
|
|
|
- // duplicate the first value to all elements
|
|
|
- this.array.fill(this.array.at(0));
|
|
|
+ if (isValueType) {
|
|
|
+ describe('sort', function () {
|
|
|
+ for (const length of [0, 1, 2, 8, 32, 128]) {
|
|
|
+ describe(`${name}[] of length ${length}`, function () {
|
|
|
+ beforeEach(async function () {
|
|
|
+ this.array = Array.from({ length }, generators[name]);
|
|
|
});
|
|
|
|
|
|
- it('sort already sorted array', async function () {
|
|
|
- // pre-sort the elements
|
|
|
- this.array.sort(comparator);
|
|
|
+ afterEach(async function () {
|
|
|
+ const expected = Array.from(this.array).sort(comparator);
|
|
|
+ const reversed = Array.from(expected).reverse();
|
|
|
+ expect(await this.instance.sort(this.array)).to.deep.equal(expected);
|
|
|
+ expect(await this.instance.sortReverse(this.array)).to.deep.equal(reversed);
|
|
|
});
|
|
|
|
|
|
- it('sort reversed array', async function () {
|
|
|
- // pre-sort in reverse order
|
|
|
- this.array.sort(comparator).reverse();
|
|
|
+ it('sort array', async function () {
|
|
|
+ // nothing to do here, beforeEach and afterEach already take care of everything.
|
|
|
});
|
|
|
|
|
|
- it('sort almost sorted array', async function () {
|
|
|
- // pre-sort + rotate (move the last element to the front) for an almost sorted effect
|
|
|
- this.array.sort(comparator);
|
|
|
- this.array.unshift(this.array.pop());
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
+ if (length > 1) {
|
|
|
+ it('sort array for identical elements', async function () {
|
|
|
+ // duplicate the first value to all elements
|
|
|
+ this.array.fill(this.array.at(0));
|
|
|
+ });
|
|
|
+
|
|
|
+ it('sort already sorted array', async function () {
|
|
|
+ // pre-sort the elements
|
|
|
+ this.array.sort(comparator);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('sort reversed array', async function () {
|
|
|
+ // pre-sort in reverse order
|
|
|
+ this.array.sort(comparator).reverse();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('sort almost sorted array', async function () {
|
|
|
+ // pre-sort + rotate (move the last element to the front) for an almost sorted effect
|
|
|
+ this.array.sort(comparator);
|
|
|
+ this.array.unshift(this.array.pop());
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
describe('unsafeAccess', function () {
|
|
|
describe('storage', function () {
|
|
@@ -197,7 +199,7 @@ describe('Arrays', function () {
|
|
|
});
|
|
|
|
|
|
describe('memory', function () {
|
|
|
- const fragment = `$unsafeMemoryAccess(${type}[] arr, uint256 pos)`;
|
|
|
+ const fragment = `$unsafeMemoryAccess(${name}[] arr, uint256 pos)`;
|
|
|
|
|
|
for (const i in elements) {
|
|
|
it(`unsafeMemoryAccess within bounds #${i}`, async function () {
|
|
@@ -211,7 +213,9 @@ describe('Arrays', function () {
|
|
|
|
|
|
it('unsafeMemoryAccess loop around', async function () {
|
|
|
for (let i = 251n; i < 256n; ++i) {
|
|
|
- expect(await this.mock[fragment](elements, 2n ** i - 1n)).to.equal(BigInt(elements.length));
|
|
|
+ expect(await this.mock[fragment](elements, 2n ** i - 1n)).to.equal(
|
|
|
+ isValueType ? BigInt(elements.length) : generators[name].zero,
|
|
|
+ );
|
|
|
expect(await this.mock[fragment](elements, 2n ** i + 0n)).to.equal(elements[0]);
|
|
|
expect(await this.mock[fragment](elements, 2n ** i + 1n)).to.equal(elements[1]);
|
|
|
}
|