Packing.test.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. const { ethers } = require('hardhat');
  2. const { expect } = require('chai');
  3. const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
  4. const { forceDeployCode } = require('../helpers/deploy');
  5. const { product } = require('../helpers/iterate');
  6. const { SIZES } = require('../../scripts/generate/templates/Packing.opts');
  7. async function fixture() {
  8. return { mock: await forceDeployCode('$Packing') };
  9. }
  10. describe('Packing', function () {
  11. beforeEach(async function () {
  12. Object.assign(this, await loadFixture(fixture));
  13. });
  14. describe('pack', function () {
  15. for (const [size1, size2] of product(SIZES, SIZES).filter(([size1, size2]) => SIZES.includes(size1 + size2))) {
  16. const value1 = ethers.hexlify(ethers.randomBytes(size1));
  17. const value2 = ethers.hexlify(ethers.randomBytes(size2));
  18. const packed = ethers.concat([value1, value2]);
  19. it(`pack bytes${size1} + bytes${size2} => bytes${size1 + size2}`, async function () {
  20. expect(await this.mock[`$pack_${size1}_${size2}`](value1, value2)).to.equal(packed);
  21. expect(await this.mock[`$extract_${size1 + size2}_${size1}`](packed, 0)).to.equal(value1);
  22. expect(await this.mock[`$extract_${size1 + size2}_${size2}`](packed, size1)).to.equal(value2);
  23. });
  24. }
  25. });
  26. describe('extract / replace', function () {
  27. for (const [size1, size2] of product(SIZES, SIZES).filter(([size1, size2]) => size1 > size2)) {
  28. const MAX_OFFSET = size1 - size2;
  29. const offset = ethers.toNumber(ethers.randomBytes(1)) % (MAX_OFFSET + 1);
  30. const outer = ethers.randomBytes(size1);
  31. const value = ethers.randomBytes(size2);
  32. it(`extract bytes${size2} from bytes${size1}`, async function () {
  33. expect(await this.mock[`$extract_${size1}_${size2}`](outer, offset)).to.equal(
  34. ethers.hexlify(outer.slice(offset, offset + size2)),
  35. );
  36. await expect(this.mock[`$extract_${size1}_${size2}`](outer, MAX_OFFSET)).to.not.be.revertedWithCustomError(
  37. this.mock,
  38. 'OutOfRangeAccess',
  39. );
  40. await expect(this.mock[`$extract_${size1}_${size2}`](outer, MAX_OFFSET + 1)).to.be.revertedWithCustomError(
  41. this.mock,
  42. 'OutOfRangeAccess',
  43. );
  44. });
  45. it(`replace bytes${size2} from bytes${size1}`, async function () {
  46. expect(await this.mock[`$replace_${size1}_${size2}`](outer, value, offset)).to.equal(
  47. ethers.concat([outer.slice(0, offset), value, outer.slice(offset + size2)]),
  48. );
  49. await expect(
  50. this.mock[`$replace_${size1}_${size2}`](outer, value, MAX_OFFSET),
  51. ).to.not.be.revertedWithCustomError(this.mock, 'OutOfRangeAccess');
  52. await expect(
  53. this.mock[`$replace_${size1}_${size2}`](outer, value, MAX_OFFSET + 1),
  54. ).to.be.revertedWithCustomError(this.mock, 'OutOfRangeAccess');
  55. });
  56. }
  57. });
  58. });