drunkmonkey 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 19d6e3cc109628d8686e1994aa9e97f67c74e157
4
- data.tar.gz: 105874a81de22fde196db492685c77f1a6938690
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZDFkMWFjNjRmMzIwZjdjYTUzZGU3MDI4MzA4ZTlhYzYwNzM2NzI3NA==
5
+ data.tar.gz: !binary |-
6
+ ZGY5NWRiMmRhYzFhMjY4NTMzYTUxZjZmNWQyMjhmYjQwOGVjOGZmMA==
5
7
  SHA512:
6
- metadata.gz: 9be7bdf707ae8baabdf59e94d85f6b324efe4c76001c42ca0548159fb1a32129dd82c8fbc55cd4b86b4be96f16ddd1cb46c39111ff5dccba4e0acac1aecd2ce9
7
- data.tar.gz: 68d289778433af7a80f56ad610df5104a4bd949d4ec6be1e78b5b882dc1196e1609b30ec91b3bb8ea2cdab4c38c2457e6f8abed0dbf443eada7903bca11f7f80
8
+ metadata.gz: !binary |-
9
+ OTc0NDc2NWFmODIxYzczZDNiNDA4Njc4ZmQyZDAzYzJjOTRkYWM1ZDdjMDM2
10
+ ZWIyNTUyZGI0ZTE4YzlhYWRiNjdhNTYyMjdmODcxZWQ2MmZhNmFhYzEyMzEz
11
+ N2ViYzZmYTJlMDNjNTBmODkyODUyZTA2YjlhODE0ZDNmMzllOGM=
12
+ data.tar.gz: !binary |-
13
+ ZWEzNWE2ZWFlMTgxODZlMDRlOGQyMzI2YmUxNWRhZGRkNGU5MjNmZmJlZGRk
14
+ OGU3MDBkMTQwMDI4NjliZGVlZDQ0ZmViNGI1MGFjODc3OGRhOWEwMWY1NWZi
15
+ NmU2NjJmYjQ3YjA2MGFlYjFhZDc4M2VmODkwZTlkNjQzZWM5MWY=
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # DrunkMonkey
2
2
 
3
+ [![Build Status](https://travis-ci.org/minoritea/drunkmonkey.png?branch=master)](https://travis-ci.org/minoritea/drunkmonkey)
4
+
3
5
  DrunkMonkey is a rack middleware providing realtime two-way http communication with API for [Portal](https://github.com/flowersinthesand/portal/ "Portal").
4
6
 
5
7
  ## Supported servers
data/Rakefile CHANGED
@@ -1 +1,4 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ RSpec::Core::RakeTask.new(:spec)
4
+ task default: :spec
data/drunkmonkey.gemspec CHANGED
@@ -22,10 +22,13 @@ Gem::Specification.new do |spec|
22
22
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
23
  spec.require_paths = ["lib"]
24
24
 
25
- spec.add_dependency "celluloid", ">= 0.15"
26
- spec.add_dependency "rack", ">= 1.5"
27
- spec.add_dependency "websocket", ">= 1.1"
25
+ spec.add_runtime_dependency "celluloid", ">= 0.15"
26
+ spec.add_runtime_dependency "rack", ">= 1.5"
27
+ spec.add_runtime_dependency "websocket", ">= 1.1"
28
28
 
29
29
  spec.add_development_dependency "bundler", "~> 1.3"
30
30
  spec.add_development_dependency "rake"
31
- end
31
+ spec.add_development_dependency "rspec", ">= 2.14"
32
+
33
+ spec.required_ruby_version = ">= 1.9.3"
34
+ end
@@ -3,27 +3,27 @@ require "websocket"
3
3
  module DrunkMonkey
4
4
  module Transport
5
5
  # Taken from https://github.com/simulacre/sinatra-websocket/
6
- # Originally taken from skinny https://github.com/sj26/skinny and updated to support Firefox
6
+ # Originally taken from skinny https://github.com/sj26/skinny
7
7
  def self.websocket? env
8
8
  env['HTTP_CONNECTION'] && env['HTTP_UPGRADE'] &&
9
9
  env['HTTP_CONNECTION'].split(',').map(&:strip).map(&:downcase).include?('upgrade') &&
10
10
  env['HTTP_UPGRADE'].downcase == 'websocket'
11
11
  end
12
12
 
13
- def self.connection_from env, options
13
+ def self.call env, options = {}
14
14
  request = Rack::Request.new(env)
15
15
  if websocket? env
16
- WebSocket.resume request, **options
16
+ WebSocket.resume request, options
17
17
  [500,{},[]]
18
18
  else
19
- body = Comet.resume request, **options
19
+ body = Comet.resume request, options
20
20
  [200,{},[body]]
21
21
  end
22
22
  end
23
23
 
24
24
  class Base
25
25
  class << self
26
- def resume request, **options
26
+ def resume request, options = {}
27
27
  @sessions ||= {}
28
28
 
29
29
  params = parse_params request
@@ -32,7 +32,7 @@ module DrunkMonkey
32
32
  session = @sessions[id]
33
33
 
34
34
  return session if session
35
- @sessions[id] = new **options
35
+ @sessions[id] = new options
36
36
  end
37
37
 
38
38
  def parse_params request
@@ -48,7 +48,7 @@ module DrunkMonkey
48
48
  end
49
49
  end
50
50
 
51
- def initialize **options
51
+ def initialize options = {}
52
52
  @controller = Celluloid::Actor[options[:controller_name]]
53
53
  @messages = []
54
54
  end
@@ -64,7 +64,7 @@ module DrunkMonkey
64
64
  class WebSocket < Base
65
65
  include Celluloid
66
66
 
67
- def self.resume request, **options
67
+ def self.resume request, options = {}
68
68
  websocket = super
69
69
  websocket.handle_connection request
70
70
  end
@@ -120,7 +120,7 @@ module DrunkMonkey
120
120
  class Comet < Base
121
121
  include Celluloid
122
122
 
123
- def self.resume request, **options
123
+ def self.resume request, options = {}
124
124
  comet = super
125
125
  comet.handle_connection(request)
126
126
  end
@@ -1,3 +1,3 @@
1
1
  module DrunkMonkey
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/drunkmonkey.rb CHANGED
@@ -26,7 +26,7 @@ module DrunkMonkey
26
26
  end
27
27
  end
28
28
 
29
- class Builder < ::Rack::Builder
29
+ class Base
30
30
  extend Forwardable
31
31
 
32
32
  DEFAULT_OPTIONS = {
@@ -34,53 +34,52 @@ module DrunkMonkey
34
34
  controller_name: :default_controller
35
35
  }.freeze
36
36
 
37
- def_delegator :controller, :on
37
+ def_delegator :@controller, :on
38
+ def_delegator :@map, :call
38
39
 
39
- def controller
40
- self.class.controller
41
- end
42
-
43
- def controller= instance
44
- self.class.controller=instance
40
+ def initialize app = nil, options = {}, &block
41
+ options = DEFAULT_OPTIONS.merge(options)
42
+ @controller = Celluloid::Actor[options[:controller_name]] ||
43
+ Controller.new(options[:controller_name])
44
+
45
+ mapping = Hash.new
46
+ mapping[options[:path]] = -> env do
47
+ Transport.call env, options
48
+ end
49
+
50
+ @base_mapping = mapping.dup
51
+
52
+ mapping["/"] = app if app
53
+
54
+ @map = Rack::URLMap.new mapping
45
55
  end
46
56
 
47
- class << self
48
- attr_accessor :controller
57
+ def remap app = nil
58
+ mapping = @base_mapping.dup
59
+ mapping["/"] = app if app
60
+ @map = Rack::URLMap.new mapping
49
61
  end
50
62
 
51
- def initialize default_app = nil, **options , &block
52
- options = DEFAULT_OPTIONS.merge(options)
53
- self.controller ||= Controller.new(options[:controller_name])
54
-
55
- super(default_app, &block)
56
-
57
- map options[:path] do
58
- run -> env do
59
- Transport.connection_from env, options
63
+ def self.middleware
64
+ Class.new do
65
+ class << self
66
+ attr_accessor :base
60
67
  end
61
- end
62
- end
63
- end
64
-
65
- def self.middleware
66
- Class.new do
67
- class << self
68
- attr_accessor :builder
69
- end
70
-
71
- def initialize app, **options, &block
72
- if self.class.builder
73
- self.class.builder.run app
74
- else
75
- self.class.builder = Builder.new app, **options, &block
68
+
69
+ def initialize app = nil, options = {}, &block
70
+ if self.class.base
71
+ self.class.base.remap app
72
+ else
73
+ self.class.base = Base.new(app,options,&block)
74
+ end
76
75
  end
77
- end
78
76
 
79
- def call env
80
- self.class.builder.call env
77
+ def call env
78
+ self.class.base.call env
79
+ end
81
80
  end
82
81
  end
83
82
  end
84
83
 
85
- Middleware = self.middleware
84
+ Middleware = Base.middleware
86
85
  end
data/sample/app.rb CHANGED
@@ -2,7 +2,9 @@ require "puma"
2
2
  require "rack/handler/puma"
3
3
  require "drunkmonkey"
4
4
 
5
+ #stock sessions on the global space
5
6
  sockets = {}
7
+
6
8
  Rack::Handler::Puma.run(Rack::Builder.new{
7
9
  root = File.dirname(__FILE__)
8
10
  use DrunkMonkey::Middleware do
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+ require "drunkmonkey"
3
+
4
+ module DrunkMonkey
5
+ describe Controller do
6
+ describe "#initialize" do
7
+ specify do
8
+ expect(Celluloid::Actor[:test_controller]).to be_nil
9
+ controller = Controller.new :test_controller
10
+ expect(controller).to eq(Celluloid::Actor[:test_controller])
11
+ expect(controller.instance_variable_get(:@handlers)).to eq(Hash.new)
12
+ end
13
+ end
14
+
15
+ describe "#on" do
16
+ specify do
17
+ controller = Controller.new :test_controller
18
+ handler = proc do |socket, message|
19
+ end
20
+ controller.on :message, &handler
21
+ expect(controller.instance_variable_get(:@handlers)).to eq({message: handler})
22
+ end
23
+ end
24
+
25
+ describe "#fire" do
26
+ specify do
27
+ controller = Controller.new :test_controller
28
+ controller.on :message do |socket, message|
29
+ raise StandardError, [socket, message].to_s
30
+ end
31
+ expect{controller.fire :message, 1, 2}.to raise_error([1,2].to_s)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,62 @@
1
+ require "spec_helper"
2
+ require "drunkmonkey"
3
+
4
+ module DrunkMonkey
5
+ describe Base do
6
+ describe "DEFAULT_OPTIONS" do
7
+ specify do
8
+ option = {
9
+ path: "/drunkmonkey",
10
+ controller_name: :default_controller
11
+ }
12
+ expect(Base::DEFAULT_OPTIONS).to eq(option)
13
+ end
14
+ end
15
+
16
+ describe "@controller" do
17
+ specify do
18
+ base = Base.new
19
+ expect(base.instance_variable_get(:@controller)).to eq(Celluloid::Actor[:default_controller])
20
+ end
21
+ end
22
+
23
+ describe "#on" do
24
+ specify do
25
+ base = Base.new controller_name: :default_controller
26
+ handler = proc{|socket,message| }
27
+ base.on :message, &handler
28
+ controller = Celluloid::Actor[:default_controller]
29
+ expect(controller.instance_variable_get(:@handlers)[:message]).to eq(handler)
30
+ end
31
+ end
32
+ end
33
+
34
+ describe Middleware do
35
+ describe "#initialize" do
36
+ specify do
37
+ app = -> env {[200,{},[]]}
38
+ middleware = Middleware.new(app,{}){}
39
+ expect(Middleware.new(app,{}){}.class.base).to eq(middleware.class.base)
40
+ end
41
+ end
42
+
43
+ describe "#call" do
44
+ specify do
45
+ app = -> env {[200,{},[env]]}
46
+ middleware = Middleware.new(app,{}){}
47
+ env = {
48
+ "REQUEST_METHOD" => "GET",
49
+ "SCRIPT_NAME" => "",
50
+ "PATH_INFO" => "/",
51
+ "QUERY_STRING" => "",
52
+ "SERVER_NAME" => "localhost",
53
+ "SERVER_PORT" => "80",
54
+ "rack.input" => StringIO.new("")
55
+
56
+ }
57
+
58
+ expect(middleware.call(env)).to eq(Middleware.base.call(env))
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,5 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require "rspec"
4
+ require "celluloid"
5
+ Celluloid.logger = nil
@@ -0,0 +1,108 @@
1
+ require "spec_helper"
2
+ require "drunkmonkey"
3
+
4
+ module Helpers
5
+ def websocket_env
6
+ env = Hash.new
7
+ env['HTTP_CONNECTION'] = "UPGRADE"
8
+ env['HTTP_UPGRADE'] = "WEBSOCKET"
9
+ env
10
+ end
11
+ end
12
+
13
+ RSpec.configure do |c|
14
+ c.include Helpers
15
+ end
16
+
17
+ module DrunkMonkey
18
+ describe Transport do
19
+ describe ".websocket?" do
20
+ specify do
21
+ env = websocket_env
22
+ expect(Transport.websocket?(env)).to eq(true)
23
+ end
24
+ specify do
25
+ env = Hash.new
26
+ env['HTTP_CONNECTION'] = ""
27
+ env['HTTP_UPGRADE'] = ""
28
+ expect(Transport.websocket?(env)).to eq(false)
29
+ end
30
+ end
31
+ end
32
+
33
+ module Transport
34
+ describe Base do
35
+ describe "#initialize" do
36
+ specify do
37
+ base = Base.new controller_name: :controller
38
+ expect(base.instance_variable_get(:@messages)).to eq([])
39
+ end
40
+ end
41
+
42
+ describe "#portal" do
43
+ specify do
44
+ base = Base.new controller_name: :controller
45
+ expect(base.portal("hello")).to eq({type:"message", data:"hello", id:1,reply:false}.to_json)
46
+ end
47
+ end
48
+
49
+ describe ".parse_params" do
50
+ specify do
51
+ env = websocket_env
52
+ env["REQUEST_METHOD"] = "POST"
53
+ env["rack.input"] = StringIO.new(%(data={"data":"aaa"}))
54
+ expect(Base.parse_params(Rack::Request.new(env))).to eq({"data" => "aaa"})
55
+ end
56
+
57
+ specify do
58
+ env = websocket_env
59
+ env["REQUEST_METHOD"] = "GET"
60
+ env["rack.input"] = StringIO.new("")
61
+ env["QUERY_STRING"] = "data=aaa"
62
+ expect(Base.parse_params(Rack::Request.new(env))).to eq({"data" => "aaa"})
63
+ end
64
+ end
65
+
66
+ describe ".resume" do
67
+ specify do
68
+ env = websocket_env
69
+ env["REQUEST_METHOD"] = "GET"
70
+ env["rack.input"] = StringIO.new("")
71
+ env["QUERY_STRING"] = "id=111"
72
+ session = Base.resume(Rack::Request.new(env), controller_name: :default_controller)
73
+ expect(Base.resume(Rack::Request.new(env),
74
+ controller_name: :default_controller)).to eq(session)
75
+ end
76
+
77
+ specify do
78
+ env = websocket_env
79
+ env["REQUEST_METHOD"] = "POST"
80
+ env["rack.input"] = StringIO.new(%(data={"id":"1234"}))
81
+ session = Base.resume(Rack::Request.new(env), controller_name: :default_controller)
82
+ expect(Base.resume(Rack::Request.new(env),
83
+ controller_name: :default_controller)).to eq(session)
84
+ end
85
+ end
86
+ end
87
+
88
+ describe WebSocket do
89
+ describe "#push" do
90
+ specify do
91
+ websocket = WebSocket.new(controller_name: :default_controller)
92
+ websocket.push "aaa"
93
+ expect(websocket.instance_variable_get(:@messages)).to eq(["aaa"])
94
+ end
95
+ end
96
+ end
97
+
98
+ describe Comet do
99
+ describe "#push" do
100
+ specify do
101
+ comet = Comet.new(controller_name: :default_controller)
102
+ comet.push "aaa"
103
+ expect(comet.instance_variable_get(:@messages)).to eq(["aaa"])
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
metadata CHANGED
@@ -1,55 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drunkmonkey
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Minori Tokuda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-24 00:00:00.000000000 Z
11
+ date: 2013-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ! '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.15'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ! '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.15'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rack
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ! '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.5'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ! '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.5'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: websocket
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ! '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '1.1'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ! '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.1'
55
55
  - !ruby/object:Gem::Dependency
@@ -70,20 +70,34 @@ dependencies:
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ! '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ! '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
- description: |2
84
- DrunkMonkey is a rack middleware providing realtime two-way http communication with API for Portal, a javascript messaging library.
85
- It provides just two protocols currently; websocket and longpoll comet.
86
- You can write code once for each protocols.
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '2.14'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '2.14'
97
+ description: ! " DrunkMonkey is a rack middleware providing realtime two-way http
98
+ communication with API for Portal, a javascript messaging library.\n It provides
99
+ just two protocols currently; websocket and longpoll comet.\n You can write code
100
+ once for each protocols.\n"
87
101
  email:
88
102
  - minorityland@gmail.jp
89
103
  executables: []
@@ -91,6 +105,7 @@ extensions: []
91
105
  extra_rdoc_files: []
92
106
  files:
93
107
  - .gitignore
108
+ - .travis.yml
94
109
  - Gemfile
95
110
  - LICENSE.txt
96
111
  - README.md
@@ -102,6 +117,10 @@ files:
102
117
  - sample/app.rb
103
118
  - sample/public/index.html
104
119
  - sample/public/portal.js
120
+ - spec/controller_spec.rb
121
+ - spec/middleware_spec.rb
122
+ - spec/spec_helper.rb
123
+ - spec/transport_spec.rb
105
124
  homepage: https://github.com/minoritea/drunkmonkey
106
125
  licenses:
107
126
  - MIT
@@ -112,19 +131,23 @@ require_paths:
112
131
  - lib
113
132
  required_ruby_version: !ruby/object:Gem::Requirement
114
133
  requirements:
115
- - - '>='
134
+ - - ! '>='
116
135
  - !ruby/object:Gem::Version
117
- version: '0'
136
+ version: 1.9.3
118
137
  required_rubygems_version: !ruby/object:Gem::Requirement
119
138
  requirements:
120
- - - '>='
139
+ - - ! '>='
121
140
  - !ruby/object:Gem::Version
122
141
  version: '0'
123
142
  requirements: []
124
143
  rubyforge_project:
125
- rubygems_version: 2.0.6
144
+ rubygems_version: 2.1.10
126
145
  signing_key:
127
146
  specification_version: 4
128
147
  summary: DrunkMonkey is a rack middleware providing realtime two-way http communication
129
148
  with API for Portal.
130
- test_files: []
149
+ test_files:
150
+ - spec/controller_spec.rb
151
+ - spec/middleware_spec.rb
152
+ - spec/spec_helper.rb
153
+ - spec/transport_spec.rb