Permalink
Browse files

bugfixes!!!

  • Loading branch information...
1 parent ce48882 commit 23f51af1282c4e13c9d90af8e858ba69d868510d @sinisterchipmunk committed Mar 16, 2012
@@ -76,3 +76,7 @@
Then /^show me the program flow$/ do
puts simulator.state[:flow]
end
+
+Then /^the receipt should be blank$/ do
+ simulator.state[:receipt].should be_blank
+end
@@ -193,12 +193,20 @@
})
],
When: [
- o('LEADING_WHEN Expression Block', function() {
+ o('LEADING_WHEN WhenArgs Block', function() {
return [[$2, $3]];
- }), o('LEADING_WHEN Expression Block TERMINATOR', function() {
+ }), o('LEADING_WHEN WhenArgs Block TERMINATOR', function() {
return [[$2, $3]];
})
],
+ WhenArgs: [
+ o('Expression', function() {
+ return [$1];
+ }), o('WhenArgs , Expression', function() {
+ $1.push($3);
+ return $1;
+ })
+ ],
Return: [
o('RETURN Expression', function() {
return new Return($2);
@@ -1,5 +1,5 @@
(function() {
- var Block, Extension, Identifier, Switch,
+ var Block, Closure, Extension, Identifier, MethodCall, Switch,
__hasProp = Object.prototype.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
@@ -9,6 +9,10 @@
Identifier = require('nodes/identifier').Identifier;
+ Closure = require('nodes/closure').Closure;
+
+ MethodCall = require('nodes/method_call').MethodCall;
+
exports.Switch = Switch = (function(_super) {
__extends(Switch, _super);
@@ -18,15 +22,24 @@
}
Switch.prototype.to_code = function() {
- var header, whens, _else, _when;
+ var header, w, whens, _else, _when;
header = "switch " + (this.expression.to_code()) + "\n";
whens = (function() {
var _i, _len, _ref, _results;
_ref = this.whens;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
_when = _ref[_i];
- _results.push(" when " + (_when[0].to_code()) + "\n" + (this.indent(_when[1])));
+ _results.push(" when " + (((function() {
+ var _j, _len2, _ref2, _results2;
+ _ref2 = _when[0];
+ _results2 = [];
+ for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
+ w = _ref2[_j];
+ _results2.push(w.to_code());
+ }
+ return _results2;
+ })()).join(', ')) + "\n" + (this.indent(_when[1])));
}
return _results;
}).call(this);
@@ -43,28 +56,43 @@
};
Switch.prototype.prepare = function() {
- var If, Operation, new_if, _i, _if, _len, _ref, _when;
+ var If, Operation, closure, condition, invocation, new_if, _i, _if, _j, _len, _len2, _ref, _ref2, _when;
If = require('nodes/if').If;
Operation = require('nodes/operation').Operation;
this.actual_value = this.create(Identifier, 'switch.actual_value');
this._if = _if = null;
+ this.closures = [];
_ref = this.whens;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
_when = _ref[_i];
- new_if = this.create(If, this.create(Operation, this.actual_value, '==', _when[0]), _when[1], 'if');
- if (this._if) {
- _if.addElse(this.create(Block, [new_if]));
- _if = new_if;
- } else {
- this._if = _if = new_if;
+ this.closures.push(closure = this.create(Closure, [], _when[1]));
+ _ref2 = _when[0];
+ for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
+ condition = _ref2[_j];
+ invocation = this.create(Block, [this.create(MethodCall, this.create(Identifier, closure.getID()), [])]);
+ new_if = this.create(If, this.create(Operation, this.actual_value, '==', condition), invocation, 'if');
+ if (this._if) {
+ _if.addElse(this.create(Block, [new_if]));
+ _if = new_if;
+ } else {
+ this._if = _if = new_if;
+ }
}
}
if (this.else_block) return _if.addElse(this.else_block);
};
Switch.prototype.compile = function(b) {
+ var closure, current_screen, _i, _len, _ref;
this.assign(b, this.actual_value, this.expression);
- return this._if.compile(b.root.current_screen());
+ current_screen = b.root.current_screen();
+ _ref = this.closures;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ closure = _ref[_i];
+ closure.compile(b);
+ }
+ b.root.goto(current_screen);
+ return this._if.compile(current_screen);
};
return Switch;
@@ -36,6 +36,7 @@
this.recursion_depth = 0;
this.max_recursion_depth = 10000;
this.state = {
+ key: "",
flow: [],
screen: {
id: null
@@ -116,16 +117,17 @@
};
Simulator.prototype.is_waiting_for_input = function() {
- var card, next, scr, tform, variant, _i, _len, _ref2;
+ var card, next, scr, tform, variant, waiting_for_keypad, _i, _len, _ref2;
if (!(this.state.screen && this.state.screen.element)) return false;
scr = this.state.screen.element;
if (scr.first('display') && !this.state.key) return true;
next = this.state.screen.element.first('next');
+ waiting_for_keypad = false;
if (next) {
_ref2 = next.all("variant");
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
variant = _ref2[_i];
- if (variant.attrs['key']) return !this.state.key;
+ if (!this.state.key && variant.attrs['key']) waiting_for_keypad = true;
}
}
if (tform = this.state.screen.element.first('tform')) {
@@ -136,7 +138,7 @@
}
}
if (scr.first('submit')) return true;
- return false;
+ return waiting_for_keypad;
};
Simulator.prototype.evaluate = function(variable, type, attrs) {
@@ -211,7 +213,7 @@
if (this.state.key === variant.attrs['key']) {
return [variant.attrs['uri']];
}
- } else {
+ } else if (!this.state.card) {
throw new Error("waiting for input");
}
} else {
@@ -257,7 +259,7 @@
char = text.charAt(0);
if (field) {
variable = this.find_variable(field.attrs.name);
- type = field.attrs.type === 'text' ? 'string' : field.attrs.type;
+ type = 'string';
this.evaluate(variable, type, {
lo: "tmlvar:" + field.attrs.name,
op: "plus",
@@ -262,7 +262,11 @@
};
TMLBuilder.prototype.goto = function(screen_id) {
- return this._current_screen = screen_id;
+ if (screen_id.attrs) {
+ return this._current_screen = screen_id.attrs.id;
+ } else {
+ return this._current_screen = screen_id;
+ }
};
TMLBuilder.prototype.add_return_screen = function() {
@@ -3,6 +3,19 @@ require 'spec_helper'
describe "conditions", ->
doc = sim = null
+ it "should not evaluate 0 == ''", ->
+ doc = dom """
+ one = ""
+ two = 0
+ switch one
+ when "0" then two = 1
+ when 0 then two = 2
+ when "" then two = 3
+ """
+ sim = simulate doc
+ sim.start()
+ expect(sim.state.variables.two.value).toEqual 3
+
describe "program flow", ->
beforeEach ->
doc = dom """
@@ -2,40 +2,76 @@ require 'spec_helper'
describe "switch", ->
doc = sim = null
- beforeEach ->
- # the closure is not necessary for the code to work, but it is necessary to allow
- # the simulator to inject values into `i` after the first screen has already been
- # processed.
- doc = dom """
- i = j = 0
- closure = ->
- switch i
- when 0 then j = 1
- when 1
- j = 2
- else j = 3
- closure()
- """
- # console.log doc.toString()
- sim = simulate doc
- describe "with i == 0", ->
- it "should set j to 1", ->
- sim.start()
- expect(sim.state.variables.j.value).toEqual 1
+ describe "with multi argument cases", ->
+ beforeEach ->
+ doc = dom """
+ i = j = 0
+ closure = ->
+ switch i
+ when 0, 1 then j = 1
+ else j = 3
+ closure()
+ """
+ # console.log doc.toString()
+ sim = simulate doc
- describe "with i == 1", ->
- it "should set j to 2", ->
- sim.step()
- sim.state.variables.i.value = 1
- sim.start()
+ describe "with i == 0", ->
+ it "should set j to 1", ->
+ sim.start()
+ expect(sim.state.variables.j.value).toEqual 1
+
+ describe "with i == 1", ->
+ it "should set j to 1", ->
+ sim.step()
+ sim.state.variables.i.value = 1
+ sim.start()
+
+ expect(sim.state.variables.j.value).toEqual 1
+
+ describe "with i == 2", ->
+ it "should set j to 3", ->
+ sim.step()
+ sim.state.variables.i.value = 2
+ sim.start()
+
+ expect(sim.state.variables.j.value).toEqual 3
+
+ describe "with single argument cases", ->
+ beforeEach ->
+ # the closure is not necessary for the code to work, but it is necessary to allow
+ # the simulator to inject values into `i` after the first screen has already been
+ # processed.
+ doc = dom """
+ i = j = 0
+ closure = ->
+ switch i
+ when 0 then j = 1
+ when 1
+ j = 2
+ else j = 3
+ closure()
+ """
+ # console.log doc.toString()
+ sim = simulate doc
+
+ describe "with i == 0", ->
+ it "should set j to 1", ->
+ sim.start()
+ expect(sim.state.variables.j.value).toEqual 1
+
+ describe "with i == 1", ->
+ it "should set j to 2", ->
+ sim.step()
+ sim.state.variables.i.value = 1
+ sim.start()
- expect(sim.state.variables.j.value).toEqual 2
+ expect(sim.state.variables.j.value).toEqual 2
- describe "with i == 2", ->
- it "should set j to 3", ->
- sim.step()
- sim.state.variables.i.value = 2
- sim.start()
+ describe "with i == 2", ->
+ it "should set j to 3", ->
+ sim.step()
+ sim.state.variables.i.value = 2
+ sim.start()
- expect(sim.state.variables.j.value).toEqual 3
+ expect(sim.state.variables.j.value).toEqual 3
@@ -3,11 +3,31 @@ require 'spec_helper'
describe "keypad input", ->
doc = sim = null
+ it "should not evaluate to no keypress == '0'", ->
+ doc = dom """
+ result = 0
+ closure = ->
+ read_card 'magnetic'
+ switch ch = getch '1 2 3 4 5 6 7 8 9 0 cancel'
+ when 'cancel' then return
+ when '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
+ result = 1
+ display "0", "1", "2"
+ display '3'
+ closure()
+ """
+ # console.log doc.toString()
+ sim = simulate doc
+ sim.start()
+ sim.swipe_card "visa"
+ expect(sim.state.variables.result.value).toEqual 0
+ expect(sim.state.display.trim()).toEqual "3"
+
describe "with a display", ->
beforeEach ->
doc = dom """
a = 1
- display 'views/basic-embedded-variable'
+ show_view 'views/basic-embedded-variable'
b = getch('1')
"""
# console.log doc.toString()
@@ -5,11 +5,18 @@ describe "Simulator", ->
beforeEach -> doc = build('tml', xmlns: 'http://www.ingenico.co.uk/tml')
it "should handle text entry", ->
- doc = dom "text = ''\nswitch getch '1'\n when '1' then text += 'A'\ndisplay '\\n<input type=\"text\" name=\"text\" />'"
+ doc = dom "result = ''\nswitch getch '1'\n when '1' then result += 'A'\ndisplay '\\n<input type=\"text\" name=\"result\" />'"
sim = simulate doc
sim.start()
sim.enter "1234", false
- expect(sim.state.variables.text.value).toEqual("A234")
+ expect(sim.state.variables.result.value).toEqual("A234")
+
+ it "should handle number entry", ->
+ doc = dom "result = 5\nswitch getch '1'\n when '1' then result += 4\ndisplay '\\n<input type=\"number\" name=\"result\" />'"
+ sim = simulate doc
+ sim.start()
+ sim.enter "1234", false
+ expect(sim.state.variables.result.value).toEqual(9234)
describe "display output", ->
@@ -169,8 +169,13 @@ grammar =
# An individual **When** clause, with action.
When: [
- o 'LEADING_WHEN Expression Block', -> [[$2, $3]]
- o 'LEADING_WHEN Expression Block TERMINATOR', -> [[$2, $3]]
+ o 'LEADING_WHEN WhenArgs Block', -> [[$2, $3]]
+ o 'LEADING_WHEN WhenArgs Block TERMINATOR', -> [[$2, $3]]
+ ]
+
+ WhenArgs: [
+ o 'Expression', -> [ $1 ]
+ o 'WhenArgs , Expression', -> $1.push $3; $1
]
Return: [
Oops, something went wrong. Retry.

0 comments on commit 23f51af

Please sign in to comment.