MongodbTests.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. const { ObjectId } = require('mongodb-legacy')
  2. const { expect } = require('chai')
  3. const sinon = require('sinon')
  4. describe('Mongo ObjectId comparison', function () {
  5. const ObjectId1 = new ObjectId('111111111111111111111111')
  6. const ObjectId2 = new ObjectId('65d8607441ef95170e89bd2a')
  7. const ObjectId1a = new ObjectId('111111111111111111111111')
  8. const ObjectId1b = new ObjectId('111111111111111111111111')
  9. const string1 = ObjectId1.toString()
  10. const string2 = ObjectId2.toString()
  11. const number1 = Number(ObjectId1)
  12. const repr1 = 'new ObjectId("111111111111111111111111")'
  13. describe('using chai', function () {
  14. describe('equal (===)', function () {
  15. it('object ids should equal themselves', function () {
  16. expect(ObjectId1).to.equal(ObjectId1)
  17. expect(ObjectId2).to.equal(ObjectId2)
  18. })
  19. it('different objects with the same id should not be equal', function () {
  20. expect(ObjectId1a).to.not.equal(ObjectId1b)
  21. })
  22. it('different object ids should not be equal', function () {
  23. expect(ObjectId1).to.not.equal(ObjectId2)
  24. })
  25. it('object id should not equal a string with the same id (left operand)', function () {
  26. expect(ObjectId1).to.not.equal(string1)
  27. })
  28. it('object id should not equal a string with the same id (right operand)', function () {
  29. expect(string1).to.not.equal(ObjectId1)
  30. })
  31. it('object id should not equal a string with a different id', function () {
  32. expect(ObjectId1).to.not.equal(string2)
  33. })
  34. it('object id should not equal a number with the same id (left operand)', function () {
  35. expect(ObjectId1).to.not.equal(number1)
  36. })
  37. it('object id should not equal a number with the same id (right operand)', function () {
  38. expect(number1).to.not.equal(ObjectId1)
  39. })
  40. it('object id should not equal the string representation with the same id (left operand)', function () {
  41. expect(ObjectId1).to.not.equal(repr1)
  42. })
  43. it('object id should not equal the string representation with the same id (right operand)', function () {
  44. expect(repr1).to.not.equal(ObjectId1)
  45. })
  46. })
  47. describe('deep equal', function () {
  48. it('object ids should deep equal themselves', function () {
  49. expect(ObjectId1).to.deep.equal(ObjectId1)
  50. expect(ObjectId2).to.deep.equal(ObjectId2)
  51. })
  52. it('different objects with the same id should be deep equal', function () {
  53. expect(ObjectId1a).to.deep.equal(ObjectId1b)
  54. })
  55. it('different object ids should not be deep equal', function () {
  56. expect(ObjectId1).to.not.deep.equal(ObjectId2)
  57. })
  58. it('object id should not deep equal a string with the same id (left operand)', function () {
  59. expect(ObjectId1).to.not.deep.equal(string1)
  60. })
  61. it('object id should not deep equal a string with the same id (right operand)', function () {
  62. expect(string1).to.not.deep.equal(ObjectId1)
  63. })
  64. it('object id should not deep equal a string with a different id', function () {
  65. expect(ObjectId1).to.not.deep.equal(string2)
  66. })
  67. it('object id should not deep equal a number with the same id (left operand)', function () {
  68. expect(ObjectId1).to.not.deep.equal(number1)
  69. })
  70. it('object id should not deep equal a number with the same id (right operand)', function () {
  71. expect(number1).to.not.deep.equal(ObjectId1)
  72. })
  73. it('object id should not deep equal the string representation with the same id (left operand)', function () {
  74. expect(ObjectId1).to.not.deep.equal(repr1)
  75. })
  76. it('object id should not deep equal the string representation with the same id (right operand)', function () {
  77. expect(repr1).to.not.deep.equal(ObjectId1)
  78. })
  79. })
  80. })
  81. describe('using sinon', function () {
  82. describe('match', function () {
  83. it('object ids should match themselves', function () {
  84. sinon.assert.match(ObjectId1, ObjectId1)
  85. sinon.assert.match(ObjectId2, ObjectId2)
  86. })
  87. it('different objects with the same id should match', function () {
  88. sinon.assert.match(ObjectId1a, ObjectId1b)
  89. })
  90. it('different object ids should not match', function () {
  91. expect(() => {
  92. sinon.assert.match(ObjectId1, ObjectId2)
  93. }).to.throw()
  94. })
  95. it('object id should not match a string with the same id (left operand)', function () {
  96. expect(() => {
  97. sinon.assert.match(ObjectId1, string1)
  98. }).to.throw()
  99. })
  100. it('object id should not match a string with the same id (right operand)', function () {
  101. expect(() => {
  102. sinon.assert.match(string1, ObjectId1)
  103. }).to.throw()
  104. })
  105. it('object id should not match a string with a different id', function () {
  106. expect(() => {
  107. sinon.assert.match(ObjectId1, string2)
  108. }).to.throw()
  109. })
  110. it('object id should not match a number with the same id (left operand)', function () {
  111. // This assertion fails because ObjectId2 becomes NaN when coerced to a number.
  112. expect(() => {
  113. sinon.assert.match(ObjectId2, 123)
  114. }).to.throw()
  115. })
  116. it('object id should not match a number with the same id (left operand) but does match when the ObjectId has decimal digits only', function () {
  117. // We would want this assertion to fail, but ObjectId1 becomes 1.1111...e+23
  118. // when coerced to a number, and this can match a number with the same value.
  119. //
  120. // For an(object, number) comparison sinon coerces the object to a number using ==
  121. // which takes the string representation of the object id and converts it to a number
  122. // via .valueOf. Most of the time this gives NaN because the object ids
  123. // are hexadecimal but if the ObjectId is a valid **decimal** number then it will
  124. // be coerced to that number. This behaviour is by design in sinon but I think we
  125. // can live with it because it is unlikely that we will compare an ObjectId to a
  126. // number and get a false positive.
  127. expect(() => {
  128. sinon.assert.match(ObjectId1, number1)
  129. }).to.not.throw()
  130. })
  131. it('object id should not match a number with the same id (right operand)', function () {
  132. expect(() => {
  133. sinon.assert.match(number1, ObjectId1)
  134. }).to.throw()
  135. })
  136. it('object id should not match the string representation with the same id (left operand)', function () {
  137. expect(() => {
  138. sinon.assert.match(ObjectId1, repr1)
  139. }).to.throw()
  140. })
  141. it('object id should not match the string representation with the same id (right operand)', function () {
  142. expect(() => {
  143. sinon.assert.match(repr1, ObjectId1)
  144. }).to.throw()
  145. })
  146. })
  147. })
  148. })