EnumerableSet.behavior.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
  2. const { expect } = require('chai');
  3. function shouldBehaveLikeSet(values, methods, events) {
  4. const [valueA, valueB, valueC] = values;
  5. async function expectMembersMatch(set, values) {
  6. const contains = await Promise.all(values.map(value => methods.contains(set, value)));
  7. expect(contains.every(Boolean)).to.be.equal(true);
  8. const length = await methods.length(set);
  9. expect(length).to.bignumber.equal(values.length.toString());
  10. // To compare values we convert to strings to workaround Chai
  11. // limitations when dealing with nested arrays (required for BNs)
  12. const indexedValues = await Promise.all(
  13. Array(values.length)
  14. .fill()
  15. .map((_, index) => methods.at(set, index)),
  16. );
  17. expect(indexedValues.map(v => v.toString())).to.have.same.members(values.map(v => v.toString()));
  18. const returnedValues = await methods.values(set);
  19. expect(returnedValues.map(v => v.toString())).to.have.same.members(values.map(v => v.toString()));
  20. }
  21. it('starts empty', async function () {
  22. expect(await methods.contains(this.set, valueA)).to.equal(false);
  23. await expectMembersMatch(this.set, []);
  24. });
  25. describe('add', function () {
  26. it('adds a value', async function () {
  27. const receipt = await methods.add(this.set, valueA);
  28. expectEvent(receipt, events.addReturn, { ret0: true });
  29. await expectMembersMatch(this.set, [valueA]);
  30. });
  31. it('adds several values', async function () {
  32. await methods.add(this.set, valueA);
  33. await methods.add(this.set, valueB);
  34. await expectMembersMatch(this.set, [valueA, valueB]);
  35. expect(await methods.contains(this.set, valueC)).to.equal(false);
  36. });
  37. it('returns false when adding values already in the set', async function () {
  38. await methods.add(this.set, valueA);
  39. const receipt = await methods.add(this.set, valueA);
  40. expectEvent(receipt, events.addReturn, { ret0: false });
  41. await expectMembersMatch(this.set, [valueA]);
  42. });
  43. });
  44. describe('at', function () {
  45. it('reverts when retrieving non-existent elements', async function () {
  46. await expectRevert.unspecified(methods.at(this.set, 0));
  47. });
  48. });
  49. describe('remove', function () {
  50. it('removes added values', async function () {
  51. await methods.add(this.set, valueA);
  52. const receipt = await methods.remove(this.set, valueA);
  53. expectEvent(receipt, events.removeReturn, { ret0: true });
  54. expect(await methods.contains(this.set, valueA)).to.equal(false);
  55. await expectMembersMatch(this.set, []);
  56. });
  57. it('returns false when removing values not in the set', async function () {
  58. const receipt = await methods.remove(this.set, valueA);
  59. expectEvent(receipt, events.removeReturn, { ret0: false });
  60. expect(await methods.contains(this.set, valueA)).to.equal(false);
  61. });
  62. it('adds and removes multiple values', async function () {
  63. // []
  64. await methods.add(this.set, valueA);
  65. await methods.add(this.set, valueC);
  66. // [A, C]
  67. await methods.remove(this.set, valueA);
  68. await methods.remove(this.set, valueB);
  69. // [C]
  70. await methods.add(this.set, valueB);
  71. // [C, B]
  72. await methods.add(this.set, valueA);
  73. await methods.remove(this.set, valueC);
  74. // [A, B]
  75. await methods.add(this.set, valueA);
  76. await methods.add(this.set, valueB);
  77. // [A, B]
  78. await methods.add(this.set, valueC);
  79. await methods.remove(this.set, valueA);
  80. // [B, C]
  81. await methods.add(this.set, valueA);
  82. await methods.remove(this.set, valueB);
  83. // [A, C]
  84. await expectMembersMatch(this.set, [valueA, valueC]);
  85. expect(await methods.contains(this.set, valueB)).to.equal(false);
  86. });
  87. });
  88. }
  89. module.exports = {
  90. shouldBehaveLikeSet,
  91. };