lackie 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
data/lib/lackie.rb CHANGED
@@ -2,7 +2,7 @@ lib = File.dirname(__FILE__)
2
2
  $:.unshift(lib) unless $:.include?(lib) || $:.include?(File.expand_path(lib))
3
3
 
4
4
  module Lackie
5
- VERSION = '0.1.6'
5
+ VERSION = '0.1.7'
6
6
  end
7
7
 
8
8
  require 'lackie/remote_control'
@@ -8,12 +8,9 @@ Lackie = {
8
8
  return;
9
9
  }
10
10
  Lackie.get("/yield", function(body) {
11
- if (body.indexOf('Lackie.reload()') == 0) {
12
- Lackie.reload();
13
- return;
14
- }
11
+ var json = JSON.parse(body);
15
12
  Lackie.wip = true;
16
- Lackie.execute(body);
13
+ Lackie.execute(json.command, json.id);
17
14
  });
18
15
  },
19
16
 
@@ -24,20 +21,25 @@ Lackie = {
24
21
  });
25
22
  },
26
23
 
27
- execute: function(command) {
24
+ execute: function(command, id) {
25
+ if (command.indexOf('Lackie.reload()') == 0) {
26
+ Lackie.reload(id);
27
+ return;
28
+ }
29
+
28
30
  var result;
29
31
  try {
30
- result = { 'value': eval(command) };
32
+ result = { id: id, value: eval(command) };
31
33
  }
32
34
  catch(e) {
33
- result = { 'error': e.toString() };
35
+ result = { id: id, error: e.toString() };
34
36
  }
35
37
  Lackie.result(result);
36
38
  },
37
39
 
38
- reload: function() {
40
+ reload: function(id) {
39
41
  Lackie.enabled = false;
40
- Lackie.post("/result", '{ "value": "reloading" }', function() {
42
+ Lackie.post("/result", '{ "id": ' + id + ', "value": "reloading" }', function() {
41
43
  window.location.reload(true);
42
44
  });
43
45
  },
@@ -51,32 +53,50 @@ Lackie = {
51
53
  },
52
54
 
53
55
  get: function(path, bodyCallback) {
54
- Lackie.usingAjax(function(xhReq) {
55
- xhReq.open("GET", Lackie.url(path), true);
56
- xhReq.onreadystatechange = function () {
57
- if (xhReq.readyState != 4 || xhReq.status != 200) {
58
- return;
56
+ var xhReq = Lackie.createXMLHttpRequest();
57
+ function readyStateChange() {
58
+ if (xhReq.readyState != 4) {
59
+ return;
59
60
  }
60
- bodyCallback(xhReq.responseText);
61
- };
62
- xhReq.send(null);
63
- });
61
+ var body = xhReq.responseText;
62
+ var status = xhReq.status;
63
+ Lackie.disposeXMLHttpRequest(xhReq);
64
+ if (status == 200) {
65
+ bodyCallback(body);
66
+ }
67
+ }
68
+ xhReq.open("GET", Lackie.url(path), true);
69
+ xhReq.onreadystatechange = readyStateChange;
70
+ xhReq.send(null);
64
71
  },
65
-
66
- post: function(path, params, callback) {
67
- Lackie.usingAjax(function(xhReq) {
68
- xhReq.open("POST", Lackie.url(path), true);
69
- xhReq.onreadystatechange = function () {
70
- if (xhReq.readyState != 2 || xhReq.status != 200) {
71
- return;
72
+
73
+ post: function(path, json, callback) {
74
+ var xhReq = Lackie.createXMLHttpRequest();
75
+ function readyStateChange() {
76
+ if (xhReq.readyState != 4) {
77
+ return;
72
78
  }
73
- callback();
74
- };
75
- xhReq.setRequestHeader("Content-type", "application/json");
76
- xhReq.setRequestHeader("Content-length", params.length);
77
- xhReq.setRequestHeader("Connection", "close");
78
- xhReq.send(params);
79
- });
79
+ var status = xhReq.status;
80
+ Lackie.disposeXMLHttpRequest(xhReq);
81
+ if (status == 200) {
82
+ callback();
83
+ }
84
+ }
85
+ xhReq.open("POST", Lackie.url(path), true);
86
+ xhReq.setRequestHeader("Content-type", "application/json");
87
+ xhReq.setRequestHeader("Content-length", json.length);
88
+ xhReq.setRequestHeader("Connection", "close");
89
+ xhReq.onreadystatechange = readyStateChange;
90
+ xhReq.send(json);
91
+ },
92
+
93
+
94
+ disposeXMLHttpRequest: function(xhReq) {
95
+ try {
96
+ if (typeof xhReq.destroy == 'function') {
97
+ xhReq.destroy();
98
+ }
99
+ } catch(e) {}
80
100
  },
81
101
 
82
102
  createXMLHttpRequest: function() {
@@ -89,20 +109,6 @@ Lackie = {
89
109
  throw new Error("XMLHttpRequest not supported");
90
110
  },
91
111
 
92
- usingAjax: function(callback) {
93
- var xhReq = Lackie.createXMLHttpRequest();
94
- try {
95
- callback(xhReq);
96
- }
97
- finally {
98
- try {
99
- if (typeof xhReq.destroy == 'function')
100
- xhReq.destroy();
101
- delete xhReq;
102
- } catch(e) {}
103
- }
104
- },
105
-
106
112
  url: function(path) {
107
113
  var now = new Date();
108
114
  return Lackie.baseUrl + path + '?' + now.getTime().toString();
@@ -1,13 +1,15 @@
1
1
  require 'lackie/javascript'
2
+ require 'lackie/rack/logger'
2
3
 
3
4
  module Lackie
4
5
  module Rack
5
6
  class Middleware
6
- def initialize(app)
7
- @app = app
7
+ def initialize(app, logger=NilLogger.new)
8
+ @app, @logger = app, logger
8
9
  @command = nil
9
10
  @result = nil
10
11
  @surrender = Lackie::JavaScript::Surrender.new
12
+ @command_id = 0
11
13
  end
12
14
 
13
15
  def call(env)
@@ -20,13 +22,15 @@ module Lackie
20
22
  end
21
23
 
22
24
  def surrender(request)
23
- #@result = nil
25
+ @logger.log("surrendered to #{request.user_agent}")
24
26
  js(@surrender.script)
25
27
  end
26
28
 
27
29
  def eval(request)
28
30
  @result = nil
29
31
  @command = request.body.read.to_s
32
+ @command_id += 1
33
+ @logger.log("eval " + command_json(@command))
30
34
  plain("OK")
31
35
  end
32
36
 
@@ -36,7 +40,7 @@ module Lackie
36
40
  else
37
41
  cmd = @command
38
42
  @command = nil
39
- js(cmd)
43
+ js(command_json(cmd))
40
44
  end
41
45
  end
42
46
 
@@ -50,6 +54,10 @@ module Lackie
50
54
 
51
55
  private
52
56
 
57
+ def command_json(cmd)
58
+ { :command => cmd, :id => @command_id }.to_json
59
+ end
60
+
53
61
  def get_result(request)
54
62
  if @result.nil?
55
63
  not_found
@@ -61,7 +69,15 @@ module Lackie
61
69
  end
62
70
 
63
71
  def set_result(request)
64
- @result = request.body.read.to_s
72
+ begin
73
+ r = JSON.parse(request.body.read.to_s)
74
+ rescue
75
+ return bad_request
76
+ end
77
+ if r['id'].to_i == @command_id
78
+ @result = r.to_json
79
+ @logger.log("result #{@result}")
80
+ end
65
81
  plain("OK")
66
82
  end
67
83
 
@@ -84,6 +100,10 @@ module Lackie
84
100
  def not_found
85
101
  [404, {'Content-Type' => 'text/plain'}, ['Not Found']]
86
102
  end
103
+
104
+ def bad_request
105
+ [400, {'Content-Type' => 'text/plain'}, ['Bad Request']]
106
+ end
87
107
  end
88
108
  end
89
109
  end
@@ -5,14 +5,14 @@ module Lackie
5
5
  module Rack
6
6
  describe Middleware do
7
7
  before do
8
- Lackie::JavaScript::Surrender.should_receive(:new).and_return(mock("surrender", :script => "yowzer"))
8
+ Lackie::JavaScript::Surrender.stub!(:new).and_return(mock("surrender", :script => "yowzer"))
9
9
  @app = mock("app")
10
10
  @env = mock("env")
11
11
  @middleware = Middleware.new(@app)
12
12
  end
13
13
 
14
14
  def request(options)
15
- @request = mock("Request: #{options.inspect}", options)
15
+ @request = mock("Request: #{options.inspect}", options.merge(:user_agent => "some-user-agent"))
16
16
  ::Rack::Request.stub!(:new).with(@env).and_return(@request)
17
17
  @middleware.call(@env)
18
18
  end
@@ -42,19 +42,45 @@ module Lackie
42
42
  end
43
43
 
44
44
  describe "POST /lackie/eval with the body 'foo()'" do
45
- describe "followed by GET /lackie/yield" do
45
+ describe "then GET /lackie/yield" do
46
46
  it "returns 'foo()' as the response body" do
47
47
  post("/lackie/eval", "foo()")
48
- get("/lackie/yield").should == [200, {"Content-Type"=>"text/javascript"}, ["foo()"]]
48
+ get("/lackie/yield").should == [200, {"Content-Type"=>"text/javascript"},
49
+ ['{"command":"foo()","id":1}'] ]
49
50
  end
50
51
 
51
- describe "followed by GET /lackie/yield" do
52
- it "returns '' as the response body" do
52
+ describe "then GET /lackie/yield" do
53
+ it "returns not found" do
53
54
  post("/lackie/eval", "foo()")
54
55
  get("/lackie/yield")
55
56
  get("/lackie/yield").should == [404, {"Content-Type"=>"text/plain"}, ["Not Found"]]
56
57
  end
57
58
  end
59
+
60
+ describe "then POST /lackie/eval with the body 'bar()'" do
61
+ describe "then POST /lackie/result with the body 'foo-result'" do
62
+ describe "then GET /lackie/result" do
63
+ it "returns 404 not found" do
64
+ post("/lackie/eval", "foo()")
65
+ post("/lackie/eval", "bar()")
66
+ post("/lackie/result", { :id => 1, :value => "foo-result" }.to_json)
67
+ get("/lackie/result").should == [404, {'Content-Type' => 'text/plain'}, ["Not Found"]]
68
+ end
69
+ describe "then POST /lackie/result with the body 'bar-result'" do
70
+ describe "then GET /lackie/result" do
71
+ it "returns the value 'bar-result'" do
72
+ post("/lackie/eval", "foo()")
73
+ post("/lackie/eval", "bar()")
74
+ post("/lackie/result", { :id => 1, :value => "foo-result" }.to_json)
75
+ post("/lackie/result", { :id => 2, :value => "bar-result" }.to_json)
76
+ result_body = JSON.parse(get("/lackie/result").last.first)
77
+ result_body["value"].should == "bar-result"
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
58
84
  end
59
85
  end
60
86
 
@@ -64,11 +90,23 @@ module Lackie
64
90
  end
65
91
  end
66
92
 
67
- describe "POST /lackie/result with 'yippee'" do
68
- describe "followed by GET /lackie/result" do
93
+ describe "POST /lackie/result with valid json in the body" do
94
+ describe "then GET /lackie/result" do
69
95
  it "gets 'bar' as the response body" do
70
- post("/lackie/result", "'bar'")
71
- get("/lackie/result").should == [200, {"Content-Type"=>"application/json"}, ["'bar'"]]
96
+ post("/lackie/eval", "happy")
97
+ json_string = { :value => "go lucky", :id => 1 }.to_json
98
+ post("/lackie/result", json_string)
99
+ result_body = JSON.parse(get("/lackie/result").last.first)
100
+ result_body["id"].should == 1
101
+ result_body["value"].should == "go lucky"
102
+ end
103
+ end
104
+ end
105
+
106
+ describe "POST /lackie/result with invalid json in the body" do
107
+ describe "then GET /lackie/result" do
108
+ it "returns 400 Bad Request" do
109
+ post("/lackie/result", "crunch").should == [400, {"Content-Type"=>'text/plain'}, ["Bad Request"]]
72
110
  end
73
111
  end
74
112
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lackie
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease: false
4
+ hash: 21
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 6
10
- version: 0.1.6
9
+ - 7
10
+ version: 0.1.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Josh Chisholm
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-26 00:00:00 +00:00
18
+ date: 2011-01-28 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -194,10 +194,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
194
  requirements: []
195
195
 
196
196
  rubyforge_project:
197
- rubygems_version: 1.3.7
197
+ rubygems_version: 1.4.1
198
198
  signing_key:
199
199
  specification_version: 3
200
- summary: lackie-0.1.6
200
+ summary: lackie-0.1.7
201
201
  test_files:
202
202
  - features/remote_control.feature
203
203
  - features/step_definitions/lackie_steps.rb