EnumerableMap.test.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. const { accounts, contract } = require('@openzeppelin/test-environment');
  2. const { BN, expectEvent } = require('@openzeppelin/test-helpers');
  3. const { expect } = require('chai');
  4. const zip = require('lodash.zip');
  5. const EnumerableMapMock = contract.fromArtifact('EnumerableMapMock');
  6. describe('EnumerableMap', function () {
  7. const [ accountA, accountB, accountC ] = accounts;
  8. const keyA = new BN('7891');
  9. const keyB = new BN('451');
  10. const keyC = new BN('9592328');
  11. beforeEach(async function () {
  12. this.map = await EnumerableMapMock.new();
  13. });
  14. async function expectMembersMatch (map, keys, values) {
  15. expect(keys.length).to.equal(values.length);
  16. await Promise.all(keys.map(async key =>
  17. expect(await map.contains(key)).to.equal(true)
  18. ));
  19. expect(await map.length()).to.bignumber.equal(keys.length.toString());
  20. expect(await Promise.all(keys.map(key =>
  21. map.get(key)
  22. ))).to.have.same.members(values);
  23. // To compare key-value pairs, we zip keys and values, and convert BNs to
  24. // strings to workaround Chai limitations when dealing with nested arrays
  25. expect(await Promise.all([...Array(keys.length).keys()].map(async (index) => {
  26. const entry = await map.at(index);
  27. return [entry.key.toString(), entry.value];
  28. }))).to.have.same.deep.members(
  29. zip(keys.map(k => k.toString()), values)
  30. );
  31. }
  32. it('starts empty', async function () {
  33. expect(await this.map.contains(keyA)).to.equal(false);
  34. await expectMembersMatch(this.map, [], []);
  35. });
  36. it('adds a key', async function () {
  37. const receipt = await this.map.set(keyA, accountA);
  38. expectEvent(receipt, 'OperationResult', { result: true });
  39. await expectMembersMatch(this.map, [keyA], [accountA]);
  40. });
  41. it('adds several keys', async function () {
  42. await this.map.set(keyA, accountA);
  43. await this.map.set(keyB, accountB);
  44. await expectMembersMatch(this.map, [keyA, keyB], [accountA, accountB]);
  45. expect(await this.map.contains(keyC)).to.equal(false);
  46. });
  47. it('returns false when adding keys already in the set', async function () {
  48. await this.map.set(keyA, accountA);
  49. const receipt = (await this.map.set(keyA, accountA));
  50. expectEvent(receipt, 'OperationResult', { result: false });
  51. await expectMembersMatch(this.map, [keyA], [accountA]);
  52. });
  53. it('updates values for keys already in the set', async function () {
  54. await this.map.set(keyA, accountA);
  55. await this.map.set(keyA, accountB);
  56. await expectMembersMatch(this.map, [keyA], [accountB]);
  57. });
  58. it('removes added keys', async function () {
  59. await this.map.set(keyA, accountA);
  60. const receipt = await this.map.remove(keyA);
  61. expectEvent(receipt, 'OperationResult', { result: true });
  62. expect(await this.map.contains(keyA)).to.equal(false);
  63. await expectMembersMatch(this.map, [], []);
  64. });
  65. it('returns false when removing keys not in the set', async function () {
  66. const receipt = await this.map.remove(keyA);
  67. expectEvent(receipt, 'OperationResult', { result: false });
  68. expect(await this.map.contains(keyA)).to.equal(false);
  69. });
  70. it('adds and removes multiple keys', async function () {
  71. // []
  72. await this.map.set(keyA, accountA);
  73. await this.map.set(keyC, accountC);
  74. // [A, C]
  75. await this.map.remove(keyA);
  76. await this.map.remove(keyB);
  77. // [C]
  78. await this.map.set(keyB, accountB);
  79. // [C, B]
  80. await this.map.set(keyA, accountA);
  81. await this.map.remove(keyC);
  82. // [A, B]
  83. await this.map.set(keyA, accountA);
  84. await this.map.set(keyB, accountB);
  85. // [A, B]
  86. await this.map.set(keyC, accountC);
  87. await this.map.remove(keyA);
  88. // [B, C]
  89. await this.map.set(keyA, accountA);
  90. await this.map.remove(keyB);
  91. // [A, C]
  92. await expectMembersMatch(this.map, [keyA, keyC], [accountA, accountC]);
  93. expect(await this.map.contains(keyB)).to.equal(false);
  94. });
  95. });