Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

incorporated functionality from Brian Takita:

  - be_empty, match, and object equality matchers
  - afters

broke tests into a few files in anticipation of incorporating Brian's suite functionality.
  • Loading branch information...
commit ded64e929f77ce4f4776ffb83b81c9d2db0b27ad 1 parent dbecda9
Nick Kallen authored
View
4 TODO
@@ -0,0 +1,4 @@
+added several matchers, afters, and presumably fixed some extra calling of befores in certain contexts
+need a way to do global before and afters
+calling screw.unit multiple times i don''t like the current solution
+need to investigate race condition with data store
View
21 lib/screw.behaviors.js
@@ -13,7 +13,11 @@ $(Screw).bind('load', function() {
},
run_befores: function() {
$(this).fn('parent').fn('run_befores');
- $(this).children('.befores').find('.before').fn('run');
+ $(this).children('.befores').children('.before').fn('run');
+ },
+ run_afters: function() {
+ $(this).fn('parent').fn('run_afters');
+ $(this).children('.afters').children('.after').fn('run');
},
enqueue: function() {
$(this).children('.its').children('.it').fn('enqueue');
@@ -32,10 +36,13 @@ $(Screw).bind('load', function() {
},
run: function() {
try {
- // TESTME
- $(this)
- .fn('parent').fn('run_befores');
- $(this).data('screwunit.run')();
+ try {
+ $(this)
+ .fn('parent').fn('run_befores');
+ $(this).data('screwunit.run')();
+ } finally {
+ $(this).fn('parent').fn('run_afters');
+ }
$(this).trigger('passed');
} catch(e) {
$(this).trigger('failed', [e]);
@@ -57,6 +64,10 @@ $(Screw).bind('load', function() {
$('.before').fn({
run: function() { $(this).data('screwunit.run')() }
+ });
+
+ $('.after').fn({
+ run: function() { $(this).data('screwunit.run')() }
});
$(Screw).trigger('before');
View
59 lib/screw.builder.js
@@ -24,6 +24,7 @@ var Screw = {
.append('<ol class="befores">')
.append('<ul class="its">')
.append('<ul class="describes">')
+ .append('<ol class="afters">')
this.context.push(describe);
fn.call();
@@ -47,8 +48,16 @@ var Screw = {
.data('screwunit.run', fn);
this.context[this.context.length-1]
- .find('.befores')
+ .children('.befores')
.append(before);
+ },
+ after: function(fn) {
+ var after = $('<li class="after">')
+ .data('screwunit.run', fn);
+
+ this.context[this.context.length-1]
+ .children('.afters')
+ .append(after);
}
},
Matchers: {
@@ -56,8 +65,9 @@ var Screw = {
return {
to: function(matcher, expected, not) {
var matched = matcher.match(expected, actual);
- if (not ? matched : !matched)
+ if (not ? matched : !matched) {
throw(matcher.failure_message(expected, actual, not));
+ }
},
to_not: function(matcher, expected) {
this.to(matcher, expected, true);
@@ -66,21 +76,50 @@ var Screw = {
},
equal: {
match: function(expected, actual) {
- if (expected instanceof Array)
- return Screw.Matchers.array_equal.match(actual, expected);
+ if (Screw.Matchers.equal.by_type[expected.constructor.name])
+ return Screw.Matchers.equal.by_type[expected.constructor.name](expected, actual);
else
- return actual == expected;
+ return expected == actual;
},
failure_message: function(expected, actual, not) {
- // TESTME
return 'expected ' + $([actual]).print() + (not ? ' to not equal ' : ' to equal ') + $([expected]).print();
+ },
+ by_type: {
+ Array: function(expected, actual) {
+ for (var i = 0; i < actual.length; i++)
+ if (!Screw.Matchers.equal.match(expected[i], actual[i])) return false;
+ return actual.length == expected.length;
+ },
+ Object: function(expected, actual) {
+ for (var key in expected)
+ if (!Screw.Matchers.equal.match(expected[key], actual[key])) return false;
+ for (var key in actual)
+ if (!Screw.Matchers.equal.match(actual[key], expected[key])) return false;
+ return true;
+ }
+ }
+ },
+ match: {
+ match: function(expected, actual) {
+ if (expected.constructor == String) {
+ return actual.indexOf(expected) > -1;
+ } else {
+ return expected.exec(actual);
+ }
+ },
+ failure_message: function(expected, actual, not) {
+ return 'expected ' + $([actual]).print() + (not ? ' to not match ' : ' to match ') + $([expected]).print();
}
},
- array_equal: {
+ be_empty: {
match: function(expected, actual) {
- for(var i = 0; i < actual.length; i++)
- if (actual[i] != expected[i]) { return false }
- return actual.length == expected.length;
+ if (actual.length == undefined) {
+ throw(actual.toString() + " does not respond to length");
+ }
+ return actual.length == 0;
+ },
+ failure_message: function(expected, actual, not) {
+ return 'expected ' + $([actual]).print() + (not ? ' to not be empty' : ' to be empty');
}
}
}
View
174 spec/behaviors_spec.html
@@ -0,0 +1,174 @@
+<html>
+ <head>
+ <script src="../lib/jquery-1.2.3.js"></script>
+ <script src="../lib/jquery.fn.js"></script>
+ <script src="../lib/jquery.print.js"></script>
+ <script src="../lib/screw.builder.js"></script>
+ <script src="../lib/screw.events.js"></script>
+ <script src="../lib/screw.behaviors.js"></script>
+ <link rel="stylesheet" href="../lib/screw.css">
+ <script type="text/javascript">
+ Screw.Unit(function() {
+ describe('Screw.Unit', function() {
+ describe('behaviors', function() {
+ describe('#run', function() {
+ describe("A describe with a before and after block", function() {
+ var before_invoked = false, after_invoked = false;
+ before(function() { before_invoked = true });
+ after(function() { after_invoked = true });
+
+ describe('[after] blocks', function() {
+ it("does not invoke the [after] until after the first [it]", function() {
+ expect(after_invoked).to(equal, false);
+ });
+
+ it("invokes the [after] after the first [it]", function() {
+ expect(after_invoked).to(equal, true);
+ after_invoked = false;
+ });
+
+ it("invokes the [after] after each [it]", function() {
+ expect(after_invoked).to(equal, true);
+ });
+ });
+
+ describe('[before] blocks', function() {
+ it("invokes the [before] before an it", function() {
+ expect(before_invoked).to(equal, true);
+ before_invoked = false;
+ });
+
+ it("invokes the [before] before each it", function() {
+ expect(before_invoked).to(equal, true);
+ });
+ });
+ });
+
+ describe("A [describe] with two [before] and two [after] blocks", function() {
+ var before_invocations = [], after_invocations = [];
+ before(function() { before_invocations.push('before 1') });
+ before(function() { before_invocations.push('before 2') });
+
+ after(function() { after_invocations.push('after 1') });
+ after(function() { after_invocations.push('after 2') });
+
+ it("invokes the [before]s in lexical order before each [it]", function() {
+ expect(before_invocations).to(equal, ['before 1', 'before 2']);
+ });
+
+ it("invokes the [afters]s in lexical order after each [it]", function() {
+ expect(after_invocations).to(equal, ['after 1', 'after 2']);
+ });
+ });
+
+ describe("A describe with a nested describe", function() {
+ var before_invocations = [], after_invocations = [];
+ before(function() {
+ before_invocations = [];
+ before_invocations.push("outermost before");
+ });
+
+ after(function() {
+ after_invocations = [];
+ after_invocations.push("outermost after");
+ });
+
+ it("outside a nested [describe], does not invoke any of the nested's [before]s", function() {
+ expect(before_invocations).to(equal, ["outermost before"]);
+ });
+
+ it("outside a nested [describe], does not invoke any of the nested's [after]s", function() {
+ expect(after_invocations).to(equal, ["outermost after"]);
+ });
+
+ describe("a nested [describe]", function() {
+ before(function() {
+ before_invocations.push("inner before");
+ });
+
+ after(function() {
+ after_invocations.push("inner after");
+ });
+
+ it("runs [before]s in the parent [describe] before each [it]", function() {
+ expect(before_invocations).to(equal, ["outermost before", "inner before"]);
+ });
+
+ it("runs [after]s in the parent [describe] after each [it]", function() {
+ expect(after_invocations).to(equal, ["outermost after", "inner after"]);
+ });
+
+ describe("a doubly nested [describe]", function() {
+ before(function() {
+ before_invocations.push('innermost before');
+ });
+
+ after(function() {
+ after_invocations.push('innermost after');
+ });
+
+ describe('[before] blocks', function() {
+ it("runs [before]s in all ancestors before an [it]", function() {
+ expect(before_invocations).to(equal, ["outermost before", "inner before", "innermost before"]);
+ });
+
+ it("runs [before]s in all ancestors before each [it]", function() {
+ expect(before_invocations).to(equal, ["outermost before", "inner before", "innermost before"]);
+ });
+ });
+
+ describe('[after] blocks', function() {
+ it("runs [after]s in all ancestors after an [it]", function() {
+ expect(after_invocations).to(equal, ["outermost after", "inner after", "innermost after"]);
+ });
+
+ it("runs [after]s in all ancestors after each [it]", function() {
+ expect(after_invocations).to(equal, ["outermost after", "inner after", "innermost after"]);
+ });
+ });
+ });
+ });
+ });
+
+ describe("A describe block with exceptions", function() {
+ var after_invoked = false;
+ after(function() {
+ after_invoked = true;
+ });
+
+ describe("an exception in a test", function() {
+ it("fails because it throws an exception", function() {
+ throw('an exception');
+ });
+
+ it("invokes [after]s even if the previous [it] raised an exception", function() {
+ expect(after_invoked).to(equal, true);
+ });
+ });
+ });
+ });
+
+ describe("#selector", function() {
+ describe('a [describe]', function() {
+ it('manufactures a CSS selector that uniquely locates the [describe]', function() {
+ $('.describe').each(function() {
+ expect($($(this).fn('selector')).get(0)).to(equal, $(this).get(0))
+ });
+ });
+ });
+
+ describe('an [it]', function() {
+ it('manufactures a CSS selector that uniquely locates the [it]', function() {
+ $('.it').each(function() {
+ expect($($(this).fn('selector')).get(0)).to(equal, $(this).get(0))
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ </script>
+ </head>
+ <body></body>
+</html>
View
106 spec/matchers_spec.html
@@ -0,0 +1,106 @@
+<html>
+ <head>
+ <script src="../lib/jquery-1.2.3.js"></script>
+ <script src="../lib/jquery.fn.js"></script>
+ <script src="../lib/jquery.print.js"></script>
+ <script src="../lib/screw.builder.js"></script>
+ <script src="../lib/screw.events.js"></script>
+ <script src="../lib/screw.behaviors.js"></script>
+ <link rel="stylesheet" href="../lib/screw.css">
+ <script type="text/javascript">
+ Screw.Unit(function() {
+ describe('Screw.Unit', function() {
+ describe("Matchers", function() {
+ describe('#equal', function() {
+ it("invokes the provided matcher on a call to expect", function() {
+ expect(true).to(equal, true);
+ expect(true).to_not(equal, false);
+ });
+
+ describe('when given an object', function() {
+ it("matches Objects with the same keys and values", function() {
+ expect({a: 'b', c: 'd'}).to(equal, {a: 'b', c: 'd'});
+ expect({a: 'b', c: 'd', e: 'f'}).to_not(equal, {a: 'b', c: 'd', e: 'G'});
+ });
+
+ it("recursively applies equality to complex elements", function() {
+ expect({a: {b: 'c'}}).to(equal, {a: {b: 'c'}});
+ expect({a: {b: 'c'}}).to_not(equal, {a: {b: 'D'}});
+ });
+ });
+
+ describe('when given an array', function() {
+ it("matches Arrays with the same elements", function() {
+ expect([1, 2, 4]).to(equal, [1, 2, 4]);
+ expect([1, 2, 3]).to_not(equal, [3, 2, 1]);
+ });
+
+ it("recursively applies equality to complex elements", function() {
+ expect([{a: 'b'}, {c: 'd'}]).to(equal, [{a: 'b'}, {c: 'd'}]);
+ expect([{a: 'b'}, {c: 'd'}]).to_not(equal, [{a: 'b'}, {c: 'E'}]);
+ });
+ });
+
+ describe(".failure_message", function() {
+ it("prints 'expected [expected] to (not) be equal [actual]'", function() {
+ var message = null;
+ try { expect(1).to(equal, 2) } catch(e) { message = e }
+ expect(message).to(equal, "expected [1] to equal [2]");
+
+ try { expect(1).to_not(equal, 1) } catch(e) { message = e }
+ expect(message).to(equal, "expected [1] to not equal [1]");
+ });
+ });
+ });
+
+ describe('#match', function() {
+ describe('when given a regular expression', function() {
+ it("matches Strings produced by the grammar", function() {
+ expect("The wheels of the bus").to(match, /bus/);
+ expect("The wheels of the bus").to_not(match, /boat/);
+ });
+ });
+
+ describe('when given a string', function() {
+ it("matches [expected]s containing [actual]s", function() {
+ expect("The wheels of the bus").to(match, "wheels");
+ expect("The wheels of the bus").to_not(match, "oars");
+ });
+ });
+
+ describe(".failure_message", function() {
+ it("prints 'expected [actual] to (not) match [expected]", function() {
+ var message = null;
+ try { expect("hello").to(match, "schmello") } catch(e) { message = e }
+ expect(message).to(equal, "expected [hello] to match [schmello]");
+
+ try { expect("hello").to_not(match, "ello") } catch(e) { message = e }
+ expect(message).to(equal, "expected [hello] to not match [ello]");
+ });
+ });
+ });
+
+ describe('#be_empty', function() {
+ it("matches Arrays with no elements", function() {
+ expect([]).to(be_empty);
+ expect([1]).to_not(be_empty);
+ });
+
+ describe(".failure_message", function() {
+ it("prints 'expected [actual] to (not) be empty", function() {
+ var message = null;
+ try { expect([1]).to(be_empty) } catch(e) { message = e }
+ expect(message).to(equal, "expected [1] to be empty");
+
+ try { expect([]).to_not(be_empty) } catch(e) { message = e }
+ expect(message).to(equal, "expected [] to not be empty");
+ });
+ });
+ });
+ });
+ });
+ });
+ </script>
+ </head>
+ <body></body>
+</html>
View
116 spec/screwunit_spec.html
@@ -1,116 +0,0 @@
-<html>
- <head>
- <script src="../lib/jquery-1.2.3.js"></script>
- <script src="../lib/jquery.fn.js"></script>
- <script src="../lib/jquery.print.js"></script>
- <script src="../lib/screw.builder.js"></script>
- <script src="../lib/screw.events.js"></script>
- <script src="../lib/screw.behaviors.js"></script>
- <link rel="stylesheet" href="../lib/screw.css">
- <script type="text/javascript">
- Screw.Unit(function() {
- describe('Screw.Unit', function() {
- describe("Matchers", function() {
- it("invokes the provided matcher on a call to expect", function() {
- expect(true).to(equal, true);
- expect(true).to_not(equal, false);
- });
-
- it("equal matches Arrays with the same elements", function() {
- expect([1, 2, 4]).to(equal, [1, 2, 3]);
- expect([1, 2, 3]).to_not(equal, [3, 2, 1]);
- });
- });
-
- describe('#run', function() {
- describe("A describe with a before block", function() {
- var before_invoked = false;
- before(function() {
- before_invoked = true;
- });
-
- it("invokes the before prior to an it", function() {
- expect(before_invoked).to(equal, true);
- before_invoked = false;
- });
-
- it("invokes the before prior to each it", function() {
- expect(before_invoked).to(equal, true);
- });
- });
-
- describe("A describe with two before blocks", function() {
- var invocations = [];
- before(function() {
- invocations.push('before 1');
- });
-
- before(function() {
- invocations.push('before 2');
- });
-
- it("invokes the befores in lexical order prior to each it", function() {
- expect(invocations).to(equal, ['before 1', 'before 2']);
- });
- });
-
- describe("A describe with a nested describe", function() {
- var invocations = [];
- before(function() {
- invocations = [];
- invocations.push("outermost before");
- });
-
- it("after a nested describe, does not invoke any of its befores", function() {
- expect(invocations).to(equal, ["outermost before"]);
- });
-
- describe("a nested describe", function() {
- before(function() {
- invocations.push("inner before");
- });
-
- describe("a doubly nested describe", function() {
- before(function() {
- invocations.push('innermost before');
- })
-
- it("runs befores in all ancestors prior to an it", function() {
- expect(invocations).to(equal, ["outermost before", "inner before", "innermost before"]);
- });
-
- it("runs befores in all ancestors prior to each it", function() {
- expect(invocations).to(equal, ["outermost before", "inner before", "innermost before"]);
- });
- });
-
- it("runs a before in the parent describe before each it", function() {
- expect(invocations).to(equal, ["outermost before", "inner before"]);
- });
- });
- });
- });
-
- describe("#selector", function() {
- describe('a describe', function() {
- it('returns a css selector that uniquely locates the describe', function() {
- $('.describe').each(function() {
- expect($($(this).fn('selector')).get(0)).to(equal, $(this).get(0))
- });
- });
- });
-
- describe('an it', function() {
- it('returns a css selector that uniquely locates the it', function() {
- $('.it').each(function() {
- expect($($(this).fn('selector')).get(0)).to(equal, $(this).get(0))
- });
- });
- });
- });
- });
- });
- </script>
- </head>
- <body></body>
-</html>
View
15 spec/suite.html
@@ -0,0 +1,15 @@
+<html>
+ <head>
+ <script src="../lib/jquery-1.2.3.js"></script>
+ <script src="../lib/jquery.fn.js"></script>
+ <script src="../lib/jquery.print.js"></script>
+ <script src="../lib/screw.builder.js"></script>
+ <script src="../lib/screw.events.js"></script>
+ <script src="../lib/screw.behaviors.js"></script>
+ <link rel="stylesheet" href="../lib/screw.css">
+
+ <script src="behaviors_spec.js"></script>
+ <script src="matchers_spec.js"></script>
+ </head>
+ <body></body>
+</html>
Please sign in to comment.
Something went wrong with that request. Please try again.