cuttlebone 0.1.3 → 0.1.4
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/.gitignore +1 -0
- data/Rakefile +31 -0
- data/cuttlebone.gemspec +2 -0
- data/examples/todo.rb +1 -1
- data/features/rack.feature +19 -0
- data/features/step_definitions/rack_steps.rb +13 -0
- data/features/step_definitions/steps.rb +3 -2
- data/features/support/env.rb +8 -1
- data/features/support/test_driver.rb +24 -11
- data/lib/cuttlebone/drivers/base.rb +13 -0
- data/lib/cuttlebone/drivers/rack.rb +154 -0
- data/lib/cuttlebone/{session → drivers}/shell.rb +5 -4
- data/lib/cuttlebone/session.rb +90 -3
- data/lib/cuttlebone/version.rb +1 -1
- data/lib/cuttlebone.rb +8 -2
- data/public/error.html +21 -0
- data/public/favicon.png +0 -0
- data/public/index.html +20 -0
- data/public/javascripts/cuttlebone.js +41 -0
- data/public/javascripts/jquery-1.5.1.min.js +16 -0
- data/public/javascripts/jquery.min.js +16 -0
- data/public/sources/cuttlebone.sass +2 -0
- data/public/sources/error.html.haml +14 -0
- data/public/sources/index.html.haml +16 -0
- data/public/stylesheets/cuttlebone.css +2 -0
- data/spec/drivers_base_spec.rb +7 -0
- data/spec/rack_application_spec.rb +42 -0
- data/spec/rack_driver_spec.rb +19 -0
- data/spec/rack_middleware_spec.rb +68 -0
- data/spec/{session_base_spec.rb → session_spec.rb} +12 -9
- data/vendor/active_support.rb +18 -0
- metadata +46 -8
- data/lib/cuttlebone/session/base.rb +0 -61
- data/lib/cuttlebone/session/rack.rb +0 -4
@@ -0,0 +1,68 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'rack/test'
|
5
|
+
|
6
|
+
describe Cuttlebone::Drivers::Rack::Middleware do
|
7
|
+
|
8
|
+
include Rack::Test::Methods
|
9
|
+
|
10
|
+
let(:id1) { Digest::SHA1.hexdigest((Time.now.usec*rand).to_s) }
|
11
|
+
let(:driver) { Cuttlebone::Drivers::Rack.new }
|
12
|
+
|
13
|
+
let(:null_app) { proc { |env| Rack::Response.new('null').finish } }
|
14
|
+
|
15
|
+
let(:app) { described_class.new(null_app, driver) }
|
16
|
+
|
17
|
+
it "takes a backend and returns a middleware component" do
|
18
|
+
subject = described_class.new(null_app)
|
19
|
+
subject.should respond_to(:call)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "takes an optional Cuttlebone driver as second argument" do
|
23
|
+
subject = described_class.new(null_app, driver)
|
24
|
+
subject.should respond_to(:call)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "raises error when no application was given" do
|
28
|
+
expect{ described_class.new() }.should raise_error
|
29
|
+
end
|
30
|
+
|
31
|
+
it "handles POST '/init' and returns a unique session identifier" do
|
32
|
+
post '/init'
|
33
|
+
last_response.should be_ok
|
34
|
+
last_response.body.should match(/"id":"[0-9a-f]{40}"/)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "handles POST '/prompt' and returns active context's prompt" do
|
38
|
+
driver.sessions.should_receive(:[]).with(id1).and_return(mock("Cuttlebone::Session", :id => id1, :prompt => 'prompt'))
|
39
|
+
post "/prompt/#{id1}"
|
40
|
+
last_response.should be_ok
|
41
|
+
last_response.body.should match(/"prompt":"prompt"/)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "handles POST '/command' and returns active context's current result" do
|
45
|
+
driver.sessions.should_receive(:[]).with(id1).and_return(mock("Cuttlebone::Session", :id => id1, :prompt => 'prompt', :call => [nil,nil,['ok'],nil]))
|
46
|
+
post "/call/#{id1}", 'command' => 'x'
|
47
|
+
last_response.should be_ok
|
48
|
+
last_response.body.should match(/"output":\["ok"\]/)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "handles POST '/command' and returns error when no real command was given" do
|
52
|
+
driver.sessions.should_receive(:[]).with(id1).and_return(mock("Cuttlebone::Session", :id => id1, :prompt => 'prompt'))
|
53
|
+
post "/call/#{id1}"
|
54
|
+
last_response.status.should == 409
|
55
|
+
end
|
56
|
+
|
57
|
+
xit "handles utf-8 strings properly" do
|
58
|
+
s = mock("Cuttlebone::Session", :id => id1, :prompt => 'prompt')
|
59
|
+
s.stub!(:call).and_return { |c| [nil, nil, c.reverse, nil] }
|
60
|
+
driver.sessions.should_receive(:[]).with(id1).and_return(s)
|
61
|
+
|
62
|
+
post "/call/#{id1}", 'command' => 'árvíztűrő tükörfúrógép'
|
63
|
+
|
64
|
+
last_response.should be_ok
|
65
|
+
last_response.body.should match(/"output":"pégórúfröküt őrűtzívrá"/u)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Cuttlebone::Session
|
3
|
+
describe Cuttlebone::Session do
|
4
4
|
let(:valid_context) { 'x' }
|
5
5
|
let(:valid_command) { 'y' }
|
6
6
|
|
@@ -15,13 +15,15 @@ describe Cuttlebone::Session::Base do
|
|
15
15
|
Cuttlebone.stub!(:definitions).and_return([ valid_context_definition ])
|
16
16
|
end
|
17
17
|
|
18
|
+
it { should respond_to(:id) }
|
19
|
+
|
18
20
|
context "having an active 'x' context" do
|
19
|
-
subject { Cuttlebone::Session
|
21
|
+
subject { Cuttlebone::Session.new(valid_context) }
|
20
22
|
|
21
23
|
it { should_not be_terminated }
|
22
24
|
|
23
25
|
it "should have no internal error" do
|
24
|
-
subject.internal_error.should
|
26
|
+
subject.internal_error.should be_nil
|
25
27
|
end
|
26
28
|
|
27
29
|
it "should evaluate a string command" do
|
@@ -43,20 +45,20 @@ describe Cuttlebone::Session::Base do
|
|
43
45
|
end
|
44
46
|
|
45
47
|
context "having no active contexts" do
|
46
|
-
subject { Cuttlebone::Session
|
48
|
+
subject { Cuttlebone::Session.new() }
|
47
49
|
|
48
50
|
it "should have no internal error" do
|
49
|
-
subject.internal_error.should
|
51
|
+
subject.internal_error.should be_nil
|
50
52
|
end
|
51
53
|
|
52
54
|
it { should be_terminated }
|
53
55
|
end
|
54
56
|
|
55
57
|
context "having 1 context" do
|
56
|
-
subject { Cuttlebone::Session
|
58
|
+
subject { Cuttlebone::Session.new(valid_context) }
|
57
59
|
|
58
60
|
it "should have no internal error" do
|
59
|
-
subject.internal_error.should
|
61
|
+
subject.internal_error.should be_nil
|
60
62
|
end
|
61
63
|
|
62
64
|
it { should_not be_terminated }
|
@@ -69,10 +71,11 @@ describe Cuttlebone::Session::Base do
|
|
69
71
|
end
|
70
72
|
|
71
73
|
context "given a wrong context" do
|
72
|
-
subject { Cuttlebone::Session
|
74
|
+
subject { Cuttlebone::Session.new('invalid_context') }
|
73
75
|
|
74
76
|
it "should indicate internal error" do
|
75
|
-
subject.internal_error.should_not
|
77
|
+
subject.internal_error.should_not be_nil
|
78
|
+
subject.internal_error.should_not be_empty
|
76
79
|
end
|
77
80
|
|
78
81
|
it "should be terminated" do
|
data/vendor/active_support.rb
CHANGED
@@ -54,3 +54,21 @@ class Module
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
57
|
+
|
58
|
+
# (active_support)/lib/active_support/core_ext/array/extract_options.rb (stripped)
|
59
|
+
class Hash
|
60
|
+
def extractable_options?
|
61
|
+
instance_of?(Hash)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Array
|
66
|
+
def extract_options!
|
67
|
+
if last.is_a?(Hash) && last.extractable_options?
|
68
|
+
pop
|
69
|
+
else
|
70
|
+
{}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: cuttlebone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.1.
|
5
|
+
version: 0.1.4
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Bence Golda
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-26 23:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -68,6 +68,28 @@ dependencies:
|
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
70
|
version_requirements: *id005
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: capybara
|
73
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 0.4.0
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: *id006
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: haml
|
84
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 3.0.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: *id007
|
71
93
|
description: Cuttlebone helps you creating shell-alike applications.
|
72
94
|
email:
|
73
95
|
- bence@golda.me
|
@@ -86,6 +108,8 @@ files:
|
|
86
108
|
- cuttlebone.gemspec
|
87
109
|
- examples/todo.rb
|
88
110
|
- features/example.feature
|
111
|
+
- features/rack.feature
|
112
|
+
- features/step_definitions/rack_steps.rb
|
89
113
|
- features/step_definitions/steps.rb
|
90
114
|
- features/support/env.rb
|
91
115
|
- features/support/test_driver.rb
|
@@ -93,17 +117,31 @@ files:
|
|
93
117
|
- lib/cuttlebone.rb
|
94
118
|
- lib/cuttlebone/controller.rb
|
95
119
|
- lib/cuttlebone/definition.rb
|
120
|
+
- lib/cuttlebone/drivers/base.rb
|
121
|
+
- lib/cuttlebone/drivers/rack.rb
|
122
|
+
- lib/cuttlebone/drivers/shell.rb
|
96
123
|
- lib/cuttlebone/exceptions.rb
|
97
124
|
- lib/cuttlebone/session.rb
|
98
|
-
- lib/cuttlebone/session/base.rb
|
99
|
-
- lib/cuttlebone/session/rack.rb
|
100
|
-
- lib/cuttlebone/session/shell.rb
|
101
125
|
- lib/cuttlebone/version.rb
|
126
|
+
- public/error.html
|
127
|
+
- public/favicon.png
|
128
|
+
- public/index.html
|
129
|
+
- public/javascripts/cuttlebone.js
|
130
|
+
- public/javascripts/jquery-1.5.1.min.js
|
131
|
+
- public/javascripts/jquery.min.js
|
132
|
+
- public/sources/cuttlebone.sass
|
133
|
+
- public/sources/error.html.haml
|
134
|
+
- public/sources/index.html.haml
|
135
|
+
- public/stylesheets/cuttlebone.css
|
102
136
|
- spec/controller_spec.rb
|
103
137
|
- spec/cuttlebone_spec.rb
|
104
138
|
- spec/definition_spec.rb
|
139
|
+
- spec/drivers_base_spec.rb
|
140
|
+
- spec/rack_application_spec.rb
|
141
|
+
- spec/rack_driver_spec.rb
|
142
|
+
- spec/rack_middleware_spec.rb
|
105
143
|
- spec/rcov.opts
|
106
|
-
- spec/
|
144
|
+
- spec/session_spec.rb
|
107
145
|
- spec/spec.opts
|
108
146
|
- spec/spec_helper.rb
|
109
147
|
- vendor/active_support.rb
|
@@ -121,7 +159,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
121
159
|
requirements:
|
122
160
|
- - ">="
|
123
161
|
- !ruby/object:Gem::Version
|
124
|
-
hash:
|
162
|
+
hash: 836932418591510968
|
125
163
|
segments:
|
126
164
|
- 0
|
127
165
|
version: "0"
|
@@ -137,6 +175,6 @@ rubyforge_project: cuttlebone
|
|
137
175
|
rubygems_version: 1.5.3
|
138
176
|
signing_key:
|
139
177
|
specification_version: 3
|
140
|
-
summary: cuttlebone-0.1.
|
178
|
+
summary: cuttlebone-0.1.4
|
141
179
|
test_files: []
|
142
180
|
|
@@ -1,61 +0,0 @@
|
|
1
|
-
class Cuttlebone::Session::Base
|
2
|
-
|
3
|
-
attr_reader :stack, :internal_error
|
4
|
-
|
5
|
-
def initialize *stack_objects
|
6
|
-
setup_contexts 'cuttlebone.stack_objects' => stack_objects
|
7
|
-
end
|
8
|
-
|
9
|
-
def active_context
|
10
|
-
stack.last
|
11
|
-
end
|
12
|
-
|
13
|
-
delegate :name, :prompt, :to => :active_context
|
14
|
-
|
15
|
-
def setup_contexts env={}
|
16
|
-
@stack ||= (env['cuttlebone.stack_objects'] || []).map{ |o| Cuttlebone::Controller.new(self, o) }
|
17
|
-
rescue Cuttlebone::InvalidContextError => e
|
18
|
-
@internal_error = %{Context initialization failed for #{e.context.inspect}!}
|
19
|
-
@stack = []
|
20
|
-
rescue => e
|
21
|
-
@internal_error = %{Internal error occured: #{e.message} (#{e.class})}
|
22
|
-
@stack = []
|
23
|
-
end
|
24
|
-
private :setup_contexts
|
25
|
-
|
26
|
-
def process command
|
27
|
-
active_context = @stack.pop
|
28
|
-
|
29
|
-
action, next_context, output, error = begin
|
30
|
-
a, n, o, e = active_context.process(command)
|
31
|
-
raise ArgumentError, "Unknown action: #{a}" unless [ :self, :replace, :add, :drop ].include?(a.to_s.to_sym)
|
32
|
-
raise TypeError, "Output must be an instance of String or nil!" unless o.is_a?(Array) or o.nil?
|
33
|
-
raise TypeError, "Error must be an instance of String or nil!" unless e.is_a?(String) or e.nil?
|
34
|
-
[ a.to_s.to_sym, n, o, e ]
|
35
|
-
rescue => e
|
36
|
-
[ :self, active_context, nil, %{Cuttlebone::Session: #{e.message} (#{e.class})} ]
|
37
|
-
end
|
38
|
-
case action
|
39
|
-
when :self
|
40
|
-
@stack << active_context
|
41
|
-
when :replace
|
42
|
-
@stack << Cuttlebone::Controller.new(self, next_context)
|
43
|
-
when :add
|
44
|
-
@stack << active_context << Cuttlebone::Controller.new(self, next_context)
|
45
|
-
when :drop
|
46
|
-
# noop
|
47
|
-
end
|
48
|
-
[ action, next_context, output, error ]
|
49
|
-
end
|
50
|
-
private :process
|
51
|
-
|
52
|
-
def call command, env={}
|
53
|
-
setup_contexts env
|
54
|
-
process command
|
55
|
-
end
|
56
|
-
|
57
|
-
def terminated?
|
58
|
-
stack.empty?
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|