EnumerableSet.behavior.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. const { expect } = require('chai');
  2. function shouldBehaveLikeSet(events) {
  3. async function expectMembersMatch(methods, values) {
  4. expect(await methods.length()).to.equal(values.length);
  5. for (const value of values) expect(await methods.contains(value)).to.be.true;
  6. expect(await Promise.all(values.map((_, index) => methods.at(index)))).to.have.deep.members(values);
  7. expect([...(await methods.values())]).to.have.deep.members(values);
  8. }
  9. it('starts empty', async function () {
  10. expect(await this.methods.contains(this.valueA)).to.be.false;
  11. await expectMembersMatch(this.methods, []);
  12. });
  13. describe('add', function () {
  14. it('adds a value', async function () {
  15. await expect(this.methods.add(this.valueA)).to.emit(this.mock, events.addReturn).withArgs(true);
  16. await expectMembersMatch(this.methods, [this.valueA]);
  17. });
  18. it('adds several values', async function () {
  19. await this.methods.add(this.valueA);
  20. await this.methods.add(this.valueB);
  21. await expectMembersMatch(this.methods, [this.valueA, this.valueB]);
  22. expect(await this.methods.contains(this.valueC)).to.be.false;
  23. });
  24. it('returns false when adding values already in the set', async function () {
  25. await this.methods.add(this.valueA);
  26. await expect(this.methods.add(this.valueA)).to.emit(this.mock, events.addReturn).withArgs(false);
  27. await expectMembersMatch(this.methods, [this.valueA]);
  28. });
  29. });
  30. describe('at', function () {
  31. it('reverts when retrieving non-existent elements', async function () {
  32. await expect(this.methods.at(0)).to.be.reverted;
  33. });
  34. });
  35. describe('remove', function () {
  36. it('removes added values', async function () {
  37. await this.methods.add(this.valueA);
  38. await expect(this.methods.remove(this.valueA)).to.emit(this.mock, events.removeReturn).withArgs(true);
  39. expect(await this.methods.contains(this.valueA)).to.be.false;
  40. await expectMembersMatch(this.methods, []);
  41. });
  42. it('returns false when removing values not in the set', async function () {
  43. await expect(this.methods.remove(this.valueA)).to.emit(this.mock, events.removeReturn).withArgs(false);
  44. expect(await this.methods.contains(this.valueA)).to.be.false;
  45. });
  46. it('adds and removes multiple values', async function () {
  47. // []
  48. await this.methods.add(this.valueA);
  49. await this.methods.add(this.valueC);
  50. // [A, C]
  51. await this.methods.remove(this.valueA);
  52. await this.methods.remove(this.valueB);
  53. // [C]
  54. await this.methods.add(this.valueB);
  55. // [C, B]
  56. await this.methods.add(this.valueA);
  57. await this.methods.remove(this.valueC);
  58. // [A, B]
  59. await this.methods.add(this.valueA);
  60. await this.methods.add(this.valueB);
  61. // [A, B]
  62. await this.methods.add(this.valueC);
  63. await this.methods.remove(this.valueA);
  64. // [B, C]
  65. await this.methods.add(this.valueA);
  66. await this.methods.remove(this.valueB);
  67. // [A, C]
  68. await expectMembersMatch(this.methods, [this.valueA, this.valueC]);
  69. expect(await this.methods.contains(this.valueB)).to.be.false;
  70. });
  71. });
  72. }
  73. module.exports = {
  74. shouldBehaveLikeSet,
  75. };