Permalink
Browse files

git-svn-id: http://jsspec.googlecode.com/svn/trunk@102 92187c49-0d35-…

…0410-b305-2f54cc65526e
  • Loading branch information...
1 parent 19d0f23 commit 846c06642726934111e268cbd4db015df9c0ece3 @akngs akngs committed Jan 17, 2008
Showing with 160 additions and 7 deletions.
  1. +1 −1 exp/build.xml
  2. +84 −3 exp/src/JSSpec2.js
  3. +75 −3 exp/src/JSSpec2_spec.js
View
@@ -3,7 +3,7 @@
<target name="test">
<java jar="lib/js.jar" fork="true">
- <arg line="-f src/JSSpec2_spec.js" />
+ <arg line="-f src/JSSpec2.js src/JSSpec2_spec.js" />
</java>
</target>
</project>
View
@@ -81,8 +81,40 @@ JSSpec2.RhinoRunner = function() {
}
};
-JSSpec2.Story = function(name) {
- this.name = name;
+JSSpec2.PlainTextLoader = function() {
+ this.currnet_story = null;
+
+ this.interprete = function(message) {
+ var lines = message.split("\n");
+ for(var i = 0; i < lines.length; i++) {
+ this.interprete_line(JSSpec2.UTILS.strip(lines[i]));
+ }
+ }
+
+ this.get_story = function() {
+ return this.current_story;
+ }
+
+ this.interprete_line = function(line) {
+ if(line.indexOf("Story:") == 0) {
+ this.current_story = new JSSpec2.Story(line.match(/^Story\:\s*(.*)/i)[1]);
+ } else if(line.indexOf("As a") == 0) {
+ this.current_story.set_role(line.match(/^As a\s*(.*)/i)[1]);
+ } else if(line.indexOf("I want") == 0) {
+ this.current_story.set_feature(line.match(/^I want\s*(.*)/i)[1]);
+ } else if(line.indexOf("So that") == 0) {
+ this.current_story.set_benefit(line.match(/^So that\s*(.*)/i)[1]);
+ } else if(line.indexOf("Scenario:") == 0) {
+ this.current_scenario = new JSSpec2.Scenario();
+ this.current_story.add_scenario(this.current_scenario);
+ } else {
+ // just ignore
+ }
+ }
+};
+
+JSSpec2.Story = function(title) {
+ this.title = title;
this.role = null;
this.feature = null;
this.benefit = null;
@@ -105,6 +137,13 @@ JSSpec2.Story = function(name) {
this.scenarios.push(scenario);
}
+ this.get_title = function() {return this.title;}
+ this.get_role = function() {return this.role;}
+ this.get_feature = function() {return this.feature;}
+ this.get_benefit = function() {return this.benefit;}
+ this.get_scenarios = function() {return this.scenarios;}
+
+
this.run = function() {
for(var i = 0; i < this.scenarios.length; i++) {
this.scenarios[i].run();
@@ -223,6 +262,17 @@ JSSpec2.Scenario = function(name) {
}
}
+JSSpec2.Step = function(message, args, context, handler) {
+ this.message = message;
+ this.args = args;
+ this.context = context;
+ this.handler = handler;
+
+ this.run = function() {
+ this.handler.apply(this.context, [this.args]);
+ }
+}
+
JSSpec2.Expectation = function(actual_value) {
this.mode = "first_pass";
this.passed = true;
@@ -255,8 +305,15 @@ JSSpec2.Expectation = function(actual_value) {
*/
this.should_be_function = function() {this.should_be_type("function");}
this.should_be_string = function() {this.should_be_type("string");}
+ this.should_be_boolean = function() {this.should_be_type("boolean");}
+ this.should_be_number = function() {this.should_be_type("number");}
+ this.should_be_array = function() {this.should_be_type("array");}
+ this.should_be_date = function() {this.should_be_type("date");}
+ this.should_be_regexp = function() {this.should_be_type("regexp");}
+ this.should_be_object = function() {this.should_be_type("object");}
+
this.should_be_type = function(expected_type) {
- var actual_type = typeof actual_value;
+ var actual_type = this._typeof(actual_value);
if(expected_type != actual_type) {
this.passed = false;
@@ -267,9 +324,33 @@ JSSpec2.Expectation = function(actual_value) {
}
}
}
+ this._typeof = function(o) {
+ var ctor = o.constructor;
+
+ if(ctor == Array) {
+ return "array";
+ } else if(ctor == Date) {
+ return "date";
+ } else if(ctor == RegExp) {
+ return "regexp";
+ } else {
+ return typeof o;
+ }
+ }
}
+
+
JSSpec2.EMPTY_FUNCTION = function() {}
+
+
+JSSpec2.UTILS = {};
+JSSpec2.UTILS.strip = function(str) {
+ return str.replace(/^\s+/, '').replace(/\s+$/, '');
+}
+
+
+
// Main
var runner = new JSSpec2.RhinoRunner();
View
@@ -1,5 +1,3 @@
-load("/prj/jsspec/exp/src/JSSpec2.js")
-
with(JSSpec2) {
story("Fullstack DSL for BDD")
as_a("spec writer")
@@ -21,6 +19,24 @@ with(JSSpec2) {
value_of(this.v.and).should_be_function()
})
+ scenario("executing STEP")
+ given("defined 'given' has two arguments - number1 and number2", function() {
+ this.context = {}
+ this.given = new JSSpec2.Step(
+ "two numbers are {number1} and {number2}",
+ {number1: "12", number2: "34"},
+ this.context,
+ function(args) {this.args = args;}
+ )
+ })
+ when("'given' runs", function() {
+ this.given.run();
+ })
+ then("the arguments should be bound", function() {
+ value_of(this.context.args.number1).should_be("12");
+ value_of(this.context.args.number2).should_be("34");
+ })
+
story("Expectation APIs")
scenario("Boolean expectation")
given("boolean expectations are in test mode", function() {
@@ -46,22 +62,78 @@ with(JSSpec2) {
given("type expectations are in test mode", function() {
this.function_type = new JSSpec2.Expectation(function() {}); this.function_type.set_mode("test")
this.string_type = new JSSpec2.Expectation("Hello"); this.string_type.set_mode("test")
- // TODO: Add more types such as boolean, number, array, date, regex, object, ...
+ this.boolean_type = new JSSpec2.Expectation(true); this.boolean_type.set_mode("test")
+ this.number_type = new JSSpec2.Expectation(1); this.number_type.set_mode("test")
+ this.array_type = new JSSpec2.Expectation([1,2,3]); this.array_type.set_mode("test")
+ this.date_type = new JSSpec2.Expectation(new Date()); this.date_type.set_mode("test")
+ this.regex_type = new JSSpec2.Expectation(/Hello/); this.regex_type.set_mode("test")
+ this.object_type = new JSSpec2.Expectation({a:1}); this.object_type.set_mode("test")
})
when("runner performs various tests", function() {
this.function_type.should_be_function()
this.string_type.should_be_string()
+ this.boolean_type.should_be_boolean()
+ this.number_type.should_be_number()
+ this.array_type.should_be_array()
+ this.date_type.should_be_date()
+ this.regex_type.should_be_regexp()
+ this.object_type.should_be_object()
})
then("the tests should be performed correctly", function() {
value_of(this.function_type.is_passed()).should_be_true()
value_of(this.string_type.is_passed()).should_be_true()
+ value_of(this.boolean_type.is_passed()).should_be_true()
+ value_of(this.number_type.is_passed()).should_be_true()
+ value_of(this.array_type.is_passed()).should_be_true()
+ value_of(this.date_type.is_passed()).should_be_true()
+ value_of(this.regex_type.is_passed()).should_be_true()
+ value_of(this.object_type.is_passed()).should_be_true()
})
+ scenario("")
// -----------------------------------------------------------------------
story("Temporary specs for bootstrap")
+ scenario("plain text loader")
+ given("plain text loader", {loader: new JSSpec2.PlainTextLoader()})
+ when("loader interpretes story title", function() {
+ this.loader.interprete(
+ "Story: transfer to cash account\n" +
+ " As a savings account holder\n" +
+ " I want to transfer money from my savings account\n" +
+ " So that I can get cash easily from an ATM\n" +
+ " \n" +
+ " Scenario: savings account is in credit\n" +
+ " Given my savings account balance is 100\n" /* +
+ " And my cash account balance is 10\n" +
+ " When I transfer 20\n" +
+ " Then my savings account balance should be 80\n" +
+ " And my cash account balance should be 30\n" +
+ " \n" +
+ " Scenario: savings account is overdrawn\n" +
+ " Given my savings account balance is -20\n" +
+ " And my cash account balance is 10\n" +
+ " When I transfer 20\n" +
+ " Then my savings account balance should be -20\n" +
+ " And my cash account balance should be 10\n"/**/
+ );
+
+ this.story = this.loader.get_story();
+ })
+ then("story instance should be created", function() {
+ var story = this.story;
+ value_of(story.get_title()).should_be("transfer to cash account");
+ value_of(story.get_role()).should_be("savings account holder");
+ value_of(story.get_feature()).should_be("to transfer money from my savings account");
+ value_of(story.get_benefit()).should_be("I can get cash easily from an ATM");
+ value_of(story.get_scenarios().length).should_be(1);
+
+ var scenario = story.get_scenarios()[0];
+ })
+
+
scenario("polymorphic 'Scenario.add_given' - object")
given("empty scenario", {scenario: new JSSpec2.Scenario("scenario 1")})
when("'addGiven' is called with an object", function() {

0 comments on commit 846c066

Please sign in to comment.