lackie 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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