duck.test.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. var duck = require("../");
  2. var testMatcher = function(options) {
  3. return function(test) {
  4. var matcher = options.matcher;
  5. var description = options.description;
  6. var positives = options.positives;
  7. var negatives = options.negatives;
  8. test.equal(matcher.describeSelf(), description);
  9. positives.forEach(function(positive) {
  10. test.same(true, matcher.matches(positive));
  11. var result = matcher.matchesWithDescription(positive);
  12. test.same(true, result.matches);
  13. test.same("", result.description);
  14. });
  15. negatives.forEach(function(negative) {
  16. test.same(false, matcher.matches(negative.value));
  17. test.same(negative.description, matcher.describeMismatch(negative.value));
  18. var result = matcher.matchesWithDescription(negative.value);
  19. test.same(false, result.matches);
  20. test.same(negative.description, result.description);
  21. });
  22. test.done();
  23. };
  24. };
  25. exports.isMatchesPrimitiveValues = testMatcher({
  26. matcher: duck.is(1),
  27. description: "1",
  28. positives: [1],
  29. negatives: [
  30. {value: 2, description: "was 2"},
  31. {value: "1", description: "was '1'"},
  32. {value: null, description: "was null"}
  33. ]
  34. });
  35. exports.isMatchesObjectUsingIsEqual = testMatcher({
  36. matcher: duck.is({}),
  37. description: "{}",
  38. positives: [{}],
  39. negatives: [
  40. {value: {hair: "none"}, description: "was { hair: 'none' }"}
  41. ]
  42. });
  43. exports.isDoesNothingToMatchers = testMatcher({
  44. matcher: duck.is(duck.is(1)),
  45. description: "1",
  46. positives: [1],
  47. negatives: [
  48. {value: 2, description: "was 2"},
  49. {value: "1", description: "was '1'"},
  50. {value: null, description: "was null"}
  51. ]
  52. });
  53. exports.isObjectMatchesValuesExactly = testMatcher({
  54. matcher: duck.isObject({
  55. name: "Bob",
  56. age: 24
  57. }),
  58. description: "{\n age: 24,\n name: 'Bob'\n}",
  59. positives: [{name: "Bob", age: 24}],
  60. negatives: [
  61. {value: {name: "Bob"}, description: "missing property: \"age\""},
  62. {value: {}, description: "missing property: \"age\"\nmissing property: \"name\""},
  63. {value: {name: "bob", age: 24}, description: "value of property \"name\" didn't match:\n was 'bob'\n expected 'Bob'"},
  64. {value: {name: "Bob", age: 24, hair: "none"}, description: "unexpected property: \"hair\""}
  65. ]
  66. });
  67. exports.isObjectSubDescriptionsAreIndented = testMatcher({
  68. matcher: duck.isObject({artist: duck.isObject({name: "Bob"})}),
  69. description: "{\n artist: {\n name: 'Bob'\n }\n}",
  70. positives: [],
  71. negatives: [
  72. {
  73. value: {artist: {name: "Jim"}},
  74. description:
  75. "value of property \"artist\" didn't match:\n" +
  76. " value of property \"name\" didn't match:\n" +
  77. " was 'Jim'\n" +
  78. " expected 'Bob'\n" +
  79. " expected {\n" +
  80. " name: 'Bob'\n" +
  81. " }"
  82. }
  83. ]
  84. });
  85. exports.hasPropertiesBehavesAsIsObjectExceptIgnoresUnexpectedValues = testMatcher({
  86. matcher: duck.hasProperties({
  87. name: "Bob",
  88. age: 24
  89. }),
  90. description: "object with properties {\n age: 24,\n name: 'Bob'\n}",
  91. positives: [{name: "Bob", age: 24}, {name: "Bob", age: 24, hair: "none"}],
  92. negatives: [
  93. {value: {name: "Bob"}, description: "missing property: \"age\""},
  94. {value: {}, description: "missing property: \"age\"\nmissing property: \"name\""},
  95. {value: {name: "bob", age: 24}, description: "value of property \"name\" didn't match:\n was 'bob'\n expected 'Bob'"}
  96. ]
  97. });
  98. exports.isArrayMatchesLengthAndIndividualElements = testMatcher({
  99. matcher: duck.isArray(["apple", "banana"]),
  100. description: "['apple', 'banana']",
  101. positives: [["apple", "banana"]],
  102. negatives: [
  103. {value: [], description: "was of length 0"},
  104. {value: ["apple", "banana", "coconut"], description: "was of length 3"},
  105. {value: ["apple", "coconut",], description: "element at index 1 didn't match:\n was 'coconut'\n expected 'banana'"}
  106. ]
  107. });
  108. exports.isArraySubDescriptionsAreIndented = testMatcher({
  109. matcher: duck.isArray([duck.isObject({name: "Bob"})]),
  110. description: "[{\n name: 'Bob'\n}]",
  111. positives: [[{name: "Bob"}]],
  112. negatives: [
  113. {
  114. value: [{name: "Jim"}],
  115. description:
  116. "element at index 0 didn't match:\n" +
  117. " value of property \"name\" didn't match:\n" +
  118. " was 'Jim'\n" +
  119. " expected 'Bob'\n" +
  120. " expected {\n" +
  121. " name: 'Bob'\n" +
  122. " }"
  123. }
  124. ]
  125. });
  126. exports.isArraySubDescriptionsAreIndented = testMatcher({
  127. matcher: duck.any,
  128. description: "<any>",
  129. positives: [{name: "Bob"}, null, undefined, 0, 1, "Bob", []],
  130. negatives: []
  131. });
  132. exports.assertReturnsNormallyOnSuccess = function(test) {
  133. duck.assertThat(42, duck.is(42));
  134. test.done();
  135. };
  136. exports.assertRaisesErrorIfAssertionFails = function(test) {
  137. try {
  138. duck.assertThat(42, duck.is(43));
  139. test.fail("Should throw error");
  140. } catch (error) {
  141. test.equal(error.name, "AssertionError");
  142. test.equal(error.message, "Expected 43\nbut was 42");
  143. }
  144. test.done();
  145. };