assert.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. var BaseAssert = require("sdk/test/assert").Assert;
  6. /**
  7. * Whether or not given property descriptors are equivalent. They are
  8. * equivalent either if both are marked as "conflict" or "required" property
  9. * or if all the properties of descriptors are equal.
  10. * @param {Object} actual
  11. * @param {Object} expected
  12. */
  13. function equivalentDescriptors(actual, expected) {
  14. return (actual.conflict && expected.conflict) ||
  15. (actual.required && expected.required) ||
  16. equalDescriptors(actual, expected);
  17. }
  18. function equalDescriptors(actual, expected) {
  19. return actual.get === expected.get &&
  20. actual.set === expected.set &&
  21. actual.value === expected.value &&
  22. !!actual.enumerable === !!expected.enumerable &&
  23. !!actual.configurable === !!expected.configurable &&
  24. !!actual.writable === !!expected.writable;
  25. }
  26. /**
  27. * Whether or not given `target` array contains all the element
  28. * from a given `source` array.
  29. */
  30. function containsSet(source, target) {
  31. return source.some(function(element) {
  32. return 0 > target.indexOf(element);
  33. });
  34. }
  35. /**
  36. * Whether or not given two arrays contain all elements from another.
  37. */
  38. function equivalentSets(source, target) {
  39. return containsSet(source, target) && containsSet(target, source);
  40. }
  41. /**
  42. * Finds name of the property from `source` property descriptor map, that
  43. * is not equivalent of the name named property in the `target` property
  44. * descriptor map. If not found `null` is returned instead.
  45. */
  46. function findNonEquivalentPropertyName(source, target) {
  47. var value = null;
  48. Object.getOwnPropertyNames(source).some(function(key) {
  49. var areEquivalent = false;
  50. if (!equivalentDescriptors(source[key], target[key])) {
  51. value = key;
  52. areEquivalent = true;
  53. }
  54. return areEquivalent;
  55. });
  56. return value;
  57. }
  58. var AssertDescriptor = {
  59. equalTraits: {
  60. value: function equivalentTraits(actual, expected, message) {
  61. var difference;
  62. var actualKeys = Object.getOwnPropertyNames(actual);
  63. var expectedKeys = Object.getOwnPropertyNames(expected);
  64. if (equivalentSets(actualKeys, expectedKeys)) {
  65. this.fail({
  66. operator: "equalTraits",
  67. message: "Traits define different properties",
  68. actual: actualKeys.sort().join(","),
  69. expected: expectedKeys.sort().join(","),
  70. });
  71. }
  72. else if ((difference = findNonEquivalentPropertyName(actual, expected))) {
  73. this.fail({
  74. operator: "equalTraits",
  75. message: "Traits define non-equivalent property `" + difference + "`",
  76. actual: actual[difference],
  77. expected: expected[difference]
  78. });
  79. }
  80. else {
  81. this.pass(message || "Traits are equivalent.");
  82. }
  83. }
  84. }
  85. };
  86. exports.Assert = function Assert() {
  87. return Object.create(BaseAssert.apply(null, arguments), AssertDescriptor);
  88. };