strelka 0.0.1pre4
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/.gemtest +0 -0
- data/History.rdoc +4 -0
- data/IDEAS.textile +174 -0
- data/Manifest.txt +38 -0
- data/README.rdoc +66 -0
- data/Rakefile +64 -0
- data/bin/leash +403 -0
- data/data/strelka/apps/strelka-admin +65 -0
- data/data/strelka/apps/strelka-setup +26 -0
- data/data/strelka/bootstrap-config.rb +34 -0
- data/data/strelka/templates/admin/console.tmpl +21 -0
- data/data/strelka/templates/layout.tmpl +30 -0
- data/lib/strelka/app/defaultrouter.rb +85 -0
- data/lib/strelka/app/filters.rb +70 -0
- data/lib/strelka/app/parameters.rb +64 -0
- data/lib/strelka/app/plugins.rb +205 -0
- data/lib/strelka/app/routing.rb +140 -0
- data/lib/strelka/app/templating.rb +157 -0
- data/lib/strelka/app.rb +175 -0
- data/lib/strelka/behavior/plugin.rb +36 -0
- data/lib/strelka/constants.rb +53 -0
- data/lib/strelka/httprequest.rb +52 -0
- data/lib/strelka/logging.rb +241 -0
- data/lib/strelka/mixins.rb +143 -0
- data/lib/strelka/process.rb +19 -0
- data/lib/strelka.rb +40 -0
- data/spec/data/layout.tmpl +3 -0
- data/spec/data/main.tmpl +1 -0
- data/spec/lib/constants.rb +32 -0
- data/spec/lib/helpers.rb +134 -0
- data/spec/strelka/app/defaultrouter_spec.rb +215 -0
- data/spec/strelka/app/parameters_spec.rb +74 -0
- data/spec/strelka/app/plugins_spec.rb +167 -0
- data/spec/strelka/app/routing_spec.rb +139 -0
- data/spec/strelka/app/templating_spec.rb +169 -0
- data/spec/strelka/app_spec.rb +160 -0
- data/spec/strelka/httprequest_spec.rb +54 -0
- data/spec/strelka/logging_spec.rb +72 -0
- data/spec/strelka_spec.rb +27 -0
- metadata +226 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'mongrel2/handler'
|
4
|
+
require 'strelka' unless defined?( Strelka )
|
5
|
+
|
6
|
+
|
7
|
+
# The process-style handler base class.
|
8
|
+
class Strelka::Process < Mongrel2::Handler
|
9
|
+
include Strelka::Loggable,
|
10
|
+
Strelka::Constants
|
11
|
+
|
12
|
+
### Create a new Process.
|
13
|
+
def initialize( * )
|
14
|
+
@
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
end # class Strelka::Process
|
19
|
+
|
data/lib/strelka.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'mongrel2'
|
4
|
+
require 'configurability'
|
5
|
+
|
6
|
+
# An application framework for Ruby-mongrel2
|
7
|
+
#
|
8
|
+
# == Author/s
|
9
|
+
#
|
10
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
11
|
+
#
|
12
|
+
module Strelka
|
13
|
+
|
14
|
+
# Library version constant
|
15
|
+
VERSION = '0.0.1'
|
16
|
+
|
17
|
+
# Version-control revision constant
|
18
|
+
REVISION = %q$Revision: 1e34f33f76af $
|
19
|
+
|
20
|
+
|
21
|
+
require 'strelka/logging'
|
22
|
+
extend Strelka::Logging
|
23
|
+
|
24
|
+
require 'strelka/constants'
|
25
|
+
include Strelka::Constants
|
26
|
+
|
27
|
+
|
28
|
+
### Get the library version. If +include_buildnum+ is true, the version string will
|
29
|
+
### include the VCS rev ID.
|
30
|
+
def self::version_string( include_buildnum=false )
|
31
|
+
vstring = "%s %s" % [ self.name, VERSION ]
|
32
|
+
vstring << " (build %s)" % [ REVISION[/: ([[:xdigit:]]+)/, 1] || '0' ] if include_buildnum
|
33
|
+
return vstring
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'strelka/app'
|
37
|
+
require 'strelka/httprequest'
|
38
|
+
|
39
|
+
end # module Strelka
|
40
|
+
|
data/spec/data/main.tmpl
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
A template for testing the Templating plugin.
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'strelka' unless defined?( Strelka )
|
4
|
+
|
5
|
+
|
6
|
+
### A collection of constants used in testing
|
7
|
+
module Strelka::TestConstants # :nodoc:all
|
8
|
+
|
9
|
+
include Strelka::Constants
|
10
|
+
|
11
|
+
unless defined?( TEST_HOST )
|
12
|
+
|
13
|
+
TEST_HOST = 'localhost'
|
14
|
+
|
15
|
+
# App id for testing
|
16
|
+
TEST_APPID = 'BD17D85C-4730-4BF2-999D-9D2B2E0FCCF9'
|
17
|
+
|
18
|
+
# 0mq socket specifications for Handlers
|
19
|
+
TEST_SEND_SPEC = 'tcp://127.0.0.1:9998'
|
20
|
+
TEST_RECV_SPEC = 'tcp://127.0.0.1:9997'
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
# Freeze all testing constants
|
25
|
+
constants.each do |cname|
|
26
|
+
const_get(cname).freeze
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
|
data/spec/lib/helpers.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
BEGIN {
|
5
|
+
require 'pathname'
|
6
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent.parent
|
7
|
+
|
8
|
+
srcdir = basedir.parent
|
9
|
+
mongrel2dir = srcdir + 'Mongrel2/lib'
|
10
|
+
|
11
|
+
libdir = basedir + "lib"
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift( mongrel2dir.to_s ) unless $LOAD_PATH.include?( mongrel2dir.to_s )
|
14
|
+
$LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
|
15
|
+
$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
|
16
|
+
}
|
17
|
+
|
18
|
+
# SimpleCov test coverage reporting; enable this using the :coverage rake task
|
19
|
+
if ENV['COVERAGE']
|
20
|
+
$stderr.puts "\n\n>>> Enabling coverage report.\n\n"
|
21
|
+
require 'simplecov'
|
22
|
+
SimpleCov.start do
|
23
|
+
add_filter 'spec'
|
24
|
+
add_group "Needing tests" do |file|
|
25
|
+
file.covered_percent < 90
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'configurability'
|
31
|
+
require 'pathname'
|
32
|
+
require 'tmpdir'
|
33
|
+
|
34
|
+
require 'rspec'
|
35
|
+
require 'mongrel2'
|
36
|
+
require 'mongrel2/testing'
|
37
|
+
|
38
|
+
require 'strelka'
|
39
|
+
|
40
|
+
require 'spec/lib/constants'
|
41
|
+
# require 'spec/lib/matchers'
|
42
|
+
|
43
|
+
### RSpec helper functions.
|
44
|
+
module Strelka::SpecHelpers
|
45
|
+
include Strelka::TestConstants
|
46
|
+
|
47
|
+
class ArrayLogger
|
48
|
+
### Create a new ArrayLogger that will append content to +array+.
|
49
|
+
def initialize( array )
|
50
|
+
@array = array
|
51
|
+
end
|
52
|
+
|
53
|
+
### Write the specified +message+ to the array.
|
54
|
+
def write( message )
|
55
|
+
@array << message
|
56
|
+
end
|
57
|
+
|
58
|
+
### No-op -- this is here just so Logger doesn't complain
|
59
|
+
def close; end
|
60
|
+
|
61
|
+
end # class ArrayLogger
|
62
|
+
|
63
|
+
|
64
|
+
unless defined?( LEVEL )
|
65
|
+
LEVEL = {
|
66
|
+
:debug => Logger::DEBUG,
|
67
|
+
:info => Logger::INFO,
|
68
|
+
:warn => Logger::WARN,
|
69
|
+
:error => Logger::ERROR,
|
70
|
+
:fatal => Logger::FATAL,
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
###############
|
75
|
+
module_function
|
76
|
+
###############
|
77
|
+
|
78
|
+
### Make an easily-comparable version vector out of +ver+ and return it.
|
79
|
+
def vvec( ver )
|
80
|
+
return ver.split('.').collect {|char| char.to_i }.pack('N*')
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
### Reset the logging subsystem to its default state.
|
85
|
+
def reset_logging
|
86
|
+
Strelka.reset_logger
|
87
|
+
Mongrel2.reset_logger
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
### Alter the output of the default log formatter to be pretty in SpecMate output
|
92
|
+
def setup_logging( level=Logger::FATAL )
|
93
|
+
|
94
|
+
# Turn symbol-style level config into Logger's expected Fixnum level
|
95
|
+
if Strelka::Logging::LOG_LEVELS.key?( level.to_s )
|
96
|
+
level = Strelka::Logging::LOG_LEVELS[ level.to_s ]
|
97
|
+
end
|
98
|
+
|
99
|
+
logger = Logger.new( $stderr )
|
100
|
+
Strelka.logger = logger
|
101
|
+
Strelka.logger.level = level
|
102
|
+
Mongrel2.logger.level = level
|
103
|
+
|
104
|
+
# Only do this when executing from a spec in TextMate
|
105
|
+
if ENV['HTML_LOGGING'] || (ENV['TM_FILENAME'] && ENV['TM_FILENAME'] =~ /_spec\.rb/)
|
106
|
+
Thread.current['logger-output'] = []
|
107
|
+
logdevice = ArrayLogger.new( Thread.current['logger-output'] )
|
108
|
+
Strelka.logger = Logger.new( logdevice )
|
109
|
+
# Strelka.logger.level = level
|
110
|
+
Strelka.logger.formatter = Strelka::Logging::HtmlFormatter.new( logger )
|
111
|
+
Mongrel2.logger = Strelka.logger
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
abort "You need a version of RSpec >= 2.6.0" unless defined?( RSpec )
|
119
|
+
|
120
|
+
### Mock with RSpec
|
121
|
+
RSpec.configure do |c|
|
122
|
+
include Strelka::TestConstants
|
123
|
+
|
124
|
+
c.mock_with( :rspec )
|
125
|
+
|
126
|
+
c.extend( Strelka::TestConstants )
|
127
|
+
c.include( Strelka::TestConstants )
|
128
|
+
c.include( Mongrel2::SpecHelpers )
|
129
|
+
c.include( Strelka::SpecHelpers )
|
130
|
+
# c.include( Strelka::Matchers )
|
131
|
+
end
|
132
|
+
|
133
|
+
# vim: set nosta noet ts=4 sw=4:
|
134
|
+
|
@@ -0,0 +1,215 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
BEGIN {
|
4
|
+
require 'pathname'
|
5
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
|
6
|
+
$LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
|
7
|
+
}
|
8
|
+
|
9
|
+
require 'rspec'
|
10
|
+
|
11
|
+
require 'spec/lib/helpers'
|
12
|
+
|
13
|
+
require 'strelka'
|
14
|
+
require 'strelka/app/defaultrouter'
|
15
|
+
|
16
|
+
|
17
|
+
#####################################################################
|
18
|
+
### C O N T E X T S
|
19
|
+
#####################################################################
|
20
|
+
|
21
|
+
describe Strelka::App::DefaultRouter do
|
22
|
+
|
23
|
+
before( :all ) do
|
24
|
+
setup_logging( :fatal )
|
25
|
+
@request_factory = Mongrel2::RequestFactory.new( route: '/user' )
|
26
|
+
end
|
27
|
+
|
28
|
+
before( :each ) do
|
29
|
+
@router = Strelka::App::DefaultRouter.new
|
30
|
+
end
|
31
|
+
|
32
|
+
after( :all ) do
|
33
|
+
reset_logging()
|
34
|
+
end
|
35
|
+
|
36
|
+
context "a router with routes for 'foo', 'foo/bar'" do
|
37
|
+
|
38
|
+
before( :each ) do
|
39
|
+
@router.add_route( :GET, ['foo'], :the_foo_action )
|
40
|
+
@router.add_route( :GET, ['foo','bar'], :the_foo_bar_action )
|
41
|
+
end
|
42
|
+
|
43
|
+
it "routes /user/foo/bar/baz to the foo/bar action" do
|
44
|
+
req = @request_factory.get( '/user/foo/bar/baz' )
|
45
|
+
@router.route_request( req ).should == :the_foo_bar_action
|
46
|
+
end
|
47
|
+
|
48
|
+
it "routes /user/foo/bar to the foo/bar action" do
|
49
|
+
req = @request_factory.get( '/user/foo/bar' )
|
50
|
+
@router.route_request( req ).should == :the_foo_bar_action
|
51
|
+
end
|
52
|
+
|
53
|
+
it "routes /user/foo to the foo action" do
|
54
|
+
req = @request_factory.get( '/user/foo' )
|
55
|
+
@router.route_request( req ).should == :the_foo_action
|
56
|
+
end
|
57
|
+
|
58
|
+
it "doesn't route /user" do
|
59
|
+
req = @request_factory.get( '/user' )
|
60
|
+
@router.route_request( req ).should be_nil()
|
61
|
+
end
|
62
|
+
|
63
|
+
it "doesn't route /user/other" do
|
64
|
+
req = @request_factory.get( '/user/other' )
|
65
|
+
@router.route_request( req ).should be_nil()
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
context "a router with routes for 'foo', 'foo/bar', and a fallback action" do
|
71
|
+
|
72
|
+
before( :each ) do
|
73
|
+
@router.add_route( :GET, [], :the_fallback_action )
|
74
|
+
@router.add_route( :GET, ['foo'], :the_foo_action )
|
75
|
+
@router.add_route( :GET, ['foo','bar'], :the_foo_bar_action )
|
76
|
+
end
|
77
|
+
|
78
|
+
it "routes /user/foo/bar/baz to the foo/bar action" do
|
79
|
+
req = @request_factory.get( '/user/foo/bar/baz' )
|
80
|
+
@router.route_request( req ).should == :the_foo_bar_action
|
81
|
+
end
|
82
|
+
|
83
|
+
it "routes /user/foo/bar to the foo/bar action" do
|
84
|
+
req = @request_factory.get( '/user/foo/bar' )
|
85
|
+
@router.route_request( req ).should == :the_foo_bar_action
|
86
|
+
end
|
87
|
+
|
88
|
+
it "routes /user/foo to the foo action" do
|
89
|
+
req = @request_factory.get( '/user/foo' )
|
90
|
+
@router.route_request( req ).should == :the_foo_action
|
91
|
+
end
|
92
|
+
|
93
|
+
it "routes /user to the fallback action" do
|
94
|
+
req = @request_factory.get( '/user' )
|
95
|
+
@router.route_request( req ).should == :the_fallback_action
|
96
|
+
end
|
97
|
+
|
98
|
+
it "routes /user/other to the fallback action" do
|
99
|
+
req = @request_factory.get( '/user/other' )
|
100
|
+
@router.route_request( req ).should == :the_fallback_action
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
context "a router with routes for 'foo', 'foo/\w{3}', and 'foo/\w{6}'" do
|
106
|
+
|
107
|
+
before( :each ) do
|
108
|
+
@router.add_route( :GET, ['foo'], :the_foo_action )
|
109
|
+
@router.add_route( :GET, ['foo',/\w{3}/], :the_foo_threeaction )
|
110
|
+
@router.add_route( :GET, ['foo',/\w{6}/], :the_foo_sixaction )
|
111
|
+
end
|
112
|
+
|
113
|
+
it "routes /user/foo/barbim/baz to the foo/\w{6} action" do
|
114
|
+
req = @request_factory.get( '/user/foo/barbim/baz' )
|
115
|
+
@router.route_request( req ).should == :the_foo_sixaction
|
116
|
+
end
|
117
|
+
|
118
|
+
it "routes /user/foo/barbat to the foo/\w{6} action" do
|
119
|
+
req = @request_factory.get( '/user/foo/barbat' )
|
120
|
+
@router.route_request( req ).should == :the_foo_sixaction
|
121
|
+
end
|
122
|
+
|
123
|
+
it "routes /user/foo/bar/baz to the foo/\w{3} action" do
|
124
|
+
req = @request_factory.get( '/user/foo/bar/baz' )
|
125
|
+
@router.route_request( req ).should == :the_foo_threeaction
|
126
|
+
end
|
127
|
+
|
128
|
+
it "routes /user/foo/bar to the foo/\w{3} action" do
|
129
|
+
req = @request_factory.get( '/user/foo/bar' )
|
130
|
+
@router.route_request( req ).should == :the_foo_threeaction
|
131
|
+
end
|
132
|
+
|
133
|
+
it "routes /user/foo to the foo action" do
|
134
|
+
req = @request_factory.get( '/user/foo' )
|
135
|
+
@router.route_request( req ).should == :the_foo_action
|
136
|
+
end
|
137
|
+
|
138
|
+
it "doesn't route /user" do
|
139
|
+
req = @request_factory.get( '/user' )
|
140
|
+
@router.route_request( req ).should be_nil()
|
141
|
+
end
|
142
|
+
|
143
|
+
it "doesn't route /user/other" do
|
144
|
+
req = @request_factory.get( '/user/other' )
|
145
|
+
@router.route_request( req ).should be_nil()
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
# get '/foo/\w{3}'
|
151
|
+
# get '/foo/\d+'
|
152
|
+
|
153
|
+
context "a router with routes for: 'foo/\w{3}', then 'foo/\d+'" do
|
154
|
+
|
155
|
+
before( :each ) do
|
156
|
+
@router.add_route( :GET, ['foo',/\w{3}/], :the_foo_threeaction )
|
157
|
+
@router.add_route( :GET, ['foo',/\d+/], :the_foo_digitaction )
|
158
|
+
end
|
159
|
+
|
160
|
+
it "routes /user/foo/1 to the foo/\d+ action" do
|
161
|
+
req = @request_factory.get( '/user/foo/1' )
|
162
|
+
@router.route_request( req ).should == :the_foo_digitaction
|
163
|
+
end
|
164
|
+
|
165
|
+
it "routes /user/foo/12 to the foo/\d+ action" do
|
166
|
+
req = @request_factory.get( '/user/foo/12' )
|
167
|
+
@router.route_request( req ).should == :the_foo_digitaction
|
168
|
+
end
|
169
|
+
|
170
|
+
it "routes /user/foo/123 to the foo/\w{3} action" do
|
171
|
+
req = @request_factory.get( '/user/foo/123' )
|
172
|
+
@router.route_request( req ).should == :the_foo_threeaction
|
173
|
+
end
|
174
|
+
|
175
|
+
it "routes /user/foo/1234 to the foo/\d+ action" do
|
176
|
+
req = @request_factory.get( '/user/foo/1234' )
|
177
|
+
@router.route_request( req ).should == :the_foo_digitaction
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
# get '/foo/\d+'
|
183
|
+
# get '/foo/\w{3}'
|
184
|
+
|
185
|
+
context "a router with routes for: 'foo/\d+', then 'foo/\w{3}'" do
|
186
|
+
|
187
|
+
before( :each ) do
|
188
|
+
@router.add_route( :GET, ['foo',/\d+/], :the_foo_digitaction )
|
189
|
+
@router.add_route( :GET, ['foo',/\w{3}/], :the_foo_threeaction )
|
190
|
+
end
|
191
|
+
|
192
|
+
it "routes /user/foo/1 to the foo/\d+ action" do
|
193
|
+
req = @request_factory.get( '/user/foo/1' )
|
194
|
+
@router.route_request( req ).should == :the_foo_digitaction
|
195
|
+
end
|
196
|
+
|
197
|
+
it "routes /user/foo/12 to the foo/\d+ action" do
|
198
|
+
req = @request_factory.get( '/user/foo/12' )
|
199
|
+
@router.route_request( req ).should == :the_foo_digitaction
|
200
|
+
end
|
201
|
+
|
202
|
+
it "routes /user/foo/123 to the foo/\d+ action" do
|
203
|
+
req = @request_factory.get( '/user/foo/123' )
|
204
|
+
@router.route_request( req ).should == :the_foo_digitaction
|
205
|
+
end
|
206
|
+
|
207
|
+
it "routes /user/foo/1234 to the foo/\d+ action" do
|
208
|
+
req = @request_factory.get( '/user/foo/1234' )
|
209
|
+
@router.route_request( req ).should == :the_foo_digitaction
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
BEGIN {
|
4
|
+
require 'pathname'
|
5
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
|
6
|
+
$LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
|
7
|
+
}
|
8
|
+
|
9
|
+
require 'rspec'
|
10
|
+
|
11
|
+
require 'spec/lib/helpers'
|
12
|
+
|
13
|
+
require 'strelka'
|
14
|
+
require 'strelka/app/plugins'
|
15
|
+
require 'strelka/app/parameters'
|
16
|
+
require 'strelka/behavior/plugin'
|
17
|
+
|
18
|
+
|
19
|
+
#####################################################################
|
20
|
+
### C O N T E X T S
|
21
|
+
#####################################################################
|
22
|
+
|
23
|
+
describe Strelka::App::Parameters do
|
24
|
+
|
25
|
+
before( :all ) do
|
26
|
+
setup_logging( :fatal )
|
27
|
+
end
|
28
|
+
|
29
|
+
after( :all ) do
|
30
|
+
reset_logging()
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
it_should_behave_like( "A Strelka::App Plugin" )
|
35
|
+
|
36
|
+
|
37
|
+
describe "an including App" do
|
38
|
+
|
39
|
+
before( :each ) do
|
40
|
+
@app = Class.new( Strelka::App ) do
|
41
|
+
plugin :parameters
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "has a parameters Hash" do
|
46
|
+
@app.parameters.should be_a( Hash )
|
47
|
+
end
|
48
|
+
|
49
|
+
it "can declare a parameter with a validation pattern" do
|
50
|
+
@app.class_eval do
|
51
|
+
param :username, /\w+/i
|
52
|
+
end
|
53
|
+
|
54
|
+
@app.parameters.should have( 1 ).member
|
55
|
+
@app.parameters[ :username ].
|
56
|
+
should include( :constraint => /(?<username>(?i-mx:\w+))/ )
|
57
|
+
end
|
58
|
+
|
59
|
+
it "inherits parameters from its superclass" do
|
60
|
+
@app.class_eval do
|
61
|
+
param :username, /\w+/i
|
62
|
+
end
|
63
|
+
subapp = Class.new( @app )
|
64
|
+
|
65
|
+
subapp.parameters.should have( 1 ).member
|
66
|
+
subapp.parameters[ :username ].
|
67
|
+
should include( :constraint => /(?<username>(?i-mx:\w+))/ )
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
end
|
74
|
+
|
@@ -0,0 +1,167 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
BEGIN {
|
4
|
+
require 'pathname'
|
5
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
|
6
|
+
$LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
|
7
|
+
}
|
8
|
+
|
9
|
+
require 'rspec'
|
10
|
+
|
11
|
+
require 'spec/lib/helpers'
|
12
|
+
|
13
|
+
require 'strelka'
|
14
|
+
require 'strelka/app/plugins'
|
15
|
+
|
16
|
+
|
17
|
+
#####################################################################
|
18
|
+
### C O N T E X T S
|
19
|
+
#####################################################################
|
20
|
+
|
21
|
+
describe Strelka::App::Plugins do
|
22
|
+
|
23
|
+
before( :all ) do
|
24
|
+
setup_logging( :fatal )
|
25
|
+
@original_plugin_registry = Strelka::App.loaded_plugins.dup
|
26
|
+
end
|
27
|
+
|
28
|
+
after( :all ) do
|
29
|
+
Strelka::App.loaded_plugins.clear
|
30
|
+
Strelka::App.loaded_plugins.replace( @original_plugin_registry )
|
31
|
+
reset_logging()
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
describe "Plugin module" do
|
36
|
+
|
37
|
+
it "registers itself with a plugin registry" do
|
38
|
+
plugin = Module.new do
|
39
|
+
extend Strelka::App::Plugin
|
40
|
+
end
|
41
|
+
|
42
|
+
Strelka::App.loaded_plugins.should include( plugin.plugin_name => plugin )
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
it "extends the object even if included" do
|
47
|
+
plugin = Module.new do
|
48
|
+
include Strelka::App::Plugin
|
49
|
+
end
|
50
|
+
|
51
|
+
Strelka::App.loaded_plugins.should include( plugin.plugin_name => plugin )
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
context "that declares that it should run before another" do
|
56
|
+
|
57
|
+
before( :each ) do
|
58
|
+
@other_mod = Module.new { include Strelka::App::Plugin }
|
59
|
+
modname = @other_mod.plugin_name
|
60
|
+
@before_mod = Module.new do
|
61
|
+
include Strelka::App::Plugin
|
62
|
+
run_before( modname )
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
it "knows that it isn't after the other plugin" do
|
67
|
+
@before_mod.should_not be_after( @other_mod )
|
68
|
+
end
|
69
|
+
|
70
|
+
it "knows that it is before the other plugin" do
|
71
|
+
@before_mod.should be_before( @other_mod )
|
72
|
+
end
|
73
|
+
|
74
|
+
it "sorts before the other plugin" do
|
75
|
+
[ @other_mod, @before_mod].sort.should == [ @before_mod, @other_mod ]
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
context "that declares that it should run after another" do
|
81
|
+
|
82
|
+
before( :each ) do
|
83
|
+
@other_mod = Module.new { include Strelka::App::Plugin }
|
84
|
+
modname = @other_mod.plugin_name
|
85
|
+
@after_mod = Module.new do
|
86
|
+
include Strelka::App::Plugin
|
87
|
+
run_after( modname )
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it "knows that it is after the other plugin" do
|
92
|
+
@after_mod.should be_after( @other_mod )
|
93
|
+
end
|
94
|
+
|
95
|
+
it "knows that is isn't before the other plugin" do
|
96
|
+
@after_mod.should_not be_before( @other_mod )
|
97
|
+
end
|
98
|
+
|
99
|
+
it "sorts after the other plugin" do
|
100
|
+
[ @after_mod, @other_mod ].sort.should == [ @other_mod, @after_mod ]
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
context "loading" do
|
109
|
+
it "appends class methods if the plugin has them" do
|
110
|
+
plugin = Module.new do
|
111
|
+
include Strelka::App::Plugin
|
112
|
+
module ClassMethods
|
113
|
+
def a_class_method; return "yep."; end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
app = Class.new( Strelka::App )
|
118
|
+
app.install_plugin( plugin )
|
119
|
+
|
120
|
+
app.a_class_method.should == "yep."
|
121
|
+
end
|
122
|
+
|
123
|
+
it "adds class-instance variables to the class if the plugin has them" do
|
124
|
+
plugin = Module.new do
|
125
|
+
include Strelka::App::Plugin
|
126
|
+
module ClassMethods
|
127
|
+
@testing_value = :default
|
128
|
+
attr_accessor :testing_value
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
app = Class.new( Strelka::App )
|
133
|
+
app.install_plugin( plugin )
|
134
|
+
|
135
|
+
app.testing_value.should == :default
|
136
|
+
app.testing_value = :not_the_default
|
137
|
+
app.testing_value.should == :not_the_default
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
context "plugin/plugins declarative" do
|
143
|
+
|
144
|
+
before( :each ) do
|
145
|
+
@including_class = Class.new { include Strelka::App::Plugins }
|
146
|
+
end
|
147
|
+
|
148
|
+
it "can declare a single plugin to load" do
|
149
|
+
klass = Class.new( @including_class ) do
|
150
|
+
plugin :routing
|
151
|
+
end
|
152
|
+
|
153
|
+
klass.ancestors.should include( Strelka::App::Routing )
|
154
|
+
end
|
155
|
+
|
156
|
+
it "can declare a list of plugins to load" do
|
157
|
+
klass = Class.new( @including_class ) do
|
158
|
+
plugins :templating, :routing
|
159
|
+
end
|
160
|
+
|
161
|
+
klass.ancestors.should include( Strelka::App::Routing, Strelka::App::Templating )
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|