drunkmonkey 0.0.1 → 0.0.2

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.
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