s-function.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. describe('Function', function() {
  2. "use strict";
  3. describe('bind', function() {
  4. var actual, expected,
  5. testSubject;
  6. testSubject = {
  7. push: function(o) {
  8. this.a.push(o);
  9. }
  10. };
  11. function func() {
  12. Array.prototype.forEach.call(arguments, function(a) {
  13. this.push(a);
  14. }, this);
  15. return this;
  16. };
  17. beforeEach(function() {
  18. actual = [];
  19. testSubject.a = [];
  20. });
  21. it('binds properly without a context', function() {
  22. var context;
  23. testSubject.func = function() {
  24. context = this;
  25. }.bind();
  26. testSubject.func();
  27. expect(context).toBe(function() {return this}.call());
  28. });
  29. it('binds properly without a context, and still supplies bound arguments', function() {
  30. var a, context;
  31. testSubject.func = function() {
  32. a = Array.prototype.slice.call(arguments);
  33. context = this;
  34. }.bind(undefined, 1,2,3);
  35. testSubject.func(1,2,3);
  36. expect(a).toEqual([1,2,3,1,2,3]);
  37. expect(context).toBe(function() {return this}.call());
  38. });
  39. it('binds a context properly', function() {
  40. testSubject.func = func.bind(actual);
  41. testSubject.func(1,2,3);
  42. expect(actual).toEqual([1,2,3]);
  43. expect(testSubject.a).toEqual([]);
  44. });
  45. it('binds a context and supplies bound arguments', function() {
  46. testSubject.func = func.bind(actual, 1,2,3);
  47. testSubject.func(4,5,6);
  48. expect(actual).toEqual([1,2,3,4,5,6]);
  49. expect(testSubject.a).toEqual([]);
  50. });
  51. it('returns properly without binding a context', function() {
  52. testSubject.func = function() {
  53. return this;
  54. }.bind();
  55. var context = testSubject.func();
  56. expect(context).toBe(function() {return this}.call());
  57. });
  58. it('returns properly without binding a context, and still supplies bound arguments', function() {
  59. var context;
  60. testSubject.func = function() {
  61. context = this;
  62. return Array.prototype.slice.call(arguments);
  63. }.bind(undefined, 1,2,3);
  64. actual = testSubject.func(1,2,3);
  65. expect(context).toBe(function() {return this}.call());
  66. expect(actual).toEqual([1,2,3,1,2,3]);
  67. });
  68. it('returns properly while binding a context properly', function() {
  69. var ret;
  70. testSubject.func = func.bind(actual);
  71. ret = testSubject.func(1,2,3);
  72. expect(ret).toBe(actual);
  73. expect(ret).not.toBe(testSubject);
  74. });
  75. it('returns properly while binding a context and supplies bound arguments', function() {
  76. var ret;
  77. testSubject.func = func.bind(actual, 1,2,3);
  78. ret = testSubject.func(4,5,6);
  79. expect(ret).toBe(actual);
  80. expect(ret).not.toBe(testSubject);
  81. });
  82. it('passes the correct arguments as a constructor', function() {
  83. var ret, expected = { name: "Correct" };
  84. testSubject.func = function(arg) {
  85. return arg;
  86. }.bind({ name: "Incorrect" });
  87. ret = new testSubject.func(expected);
  88. expect(ret).toBe(expected);
  89. });
  90. it('returns the return value of the bound function when called as a constructor', function () {
  91. var oracle = [1, 2, 3];
  92. var subject = function () {
  93. return oracle;
  94. }.bind(null);
  95. var result = new subject;
  96. expect(result).toBe(oracle);
  97. });
  98. it('returns the correct value if constructor returns primitive', function() {
  99. var oracle = [1, 2, 3];
  100. var subject = function () {
  101. return oracle;
  102. }.bind(null);
  103. var result = new subject;
  104. expect(result).toBe(oracle);
  105. oracle = {};
  106. result = new subject;
  107. expect(result).toBe(oracle);
  108. oracle = function(){};
  109. result = new subject;
  110. expect(result).toBe(oracle);
  111. oracle = "asdf";
  112. result = new subject;
  113. expect(result).not.toBe(oracle);
  114. oracle = null;
  115. result = new subject;
  116. expect(result).not.toBe(oracle);
  117. oracle = true;
  118. result = new subject;
  119. expect(result).not.toBe(oracle);
  120. oracle = 1;
  121. result = new subject;
  122. expect(result).not.toBe(oracle);
  123. });
  124. it('returns the value that instance of original "class" when called as a constructor', function() {
  125. var classA = function(x) {
  126. this.name = x || "A";
  127. }
  128. var classB = classA.bind(null, "B");
  129. var result = new classB;
  130. expect(result instanceof classA).toBe(true);
  131. expect(result instanceof classB).toBe(true);
  132. });
  133. });
  134. });