mandrake 0.0.1
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 +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +82 -0
- data/Rakefile +9 -0
- data/lib/mandrake.rb +7 -0
- data/lib/mandrake/builder.rb +51 -0
- data/lib/mandrake/dsl.rb +11 -0
- data/lib/mandrake/dsl/conditional_expression.rb +62 -0
- data/lib/mandrake/dsl/stringify.rb +58 -0
- data/lib/mandrake/middleware.rb +17 -0
- data/lib/mandrake/translator.rb +114 -0
- data/lib/mandrake/version.rb +3 -0
- data/mandrake.gemspec +25 -0
- data/spec/builder/anything.rb +5 -0
- data/spec/builder/comment.ru +4 -0
- data/spec/builder/end.ru +5 -0
- data/spec/builder/line.ru +1 -0
- data/spec/builder/options.ru +2 -0
- data/spec/builder_spec.rb +257 -0
- data/spec/dsl/conditional_expression_spec.rb +35 -0
- data/spec/dsl/stringify_spec.rb +62 -0
- data/spec/dsl_spec.rb +8 -0
- data/spec/middleware_spec.rb +14 -0
- data/spec/spec_helper.rb +63 -0
- metadata +139 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bbdd8197b3ad464e48233e2d45f606524ddb7173
|
4
|
+
data.tar.gz: 13d1da46f40a86180e7fe7e06d12184dfef4fd4b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d5be45a91f9ba3ce2834bb4613ea0674c2eac952be45aacb6e5471545dabcabb762497627c453f8423c683992276f46eea073061d13d2c5345a871f66f4fa6c9
|
7
|
+
data.tar.gz: b83f14dba4208000e3b0bc8904163eb5c1e217c2df88867d3eebea0f9987c7420ff4a521955546a3d0f77f0020dfda10635d67d543f5f750604db9680b4d8ea3
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 namusyaka
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# Mandrake
|
2
|
+
|
3
|
+
Mandrake loads middlewares conditionally, and it provides two options and DSL for setting conditions.
|
4
|
+
If you use Mandrake, you can avoid executing unnecessary middlewares by setting conditions.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'mandrake'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install mandrake
|
19
|
+
|
20
|
+
## Builder
|
21
|
+
|
22
|
+
Mandrake provides `:if` and `:unless` options which are available on `#use` method.
|
23
|
+
These options can be used to set the condition to enable the middleware at runtime.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
Mandrake::Builder.new do
|
27
|
+
use Rack::Deflate, if: request.path_info.start_with?("/deflater")
|
28
|
+
use Rack::ETag, unless: request.path_info.end_with?("etag")
|
29
|
+
run ->(env){ [200, {'Content-Type' => 'text/plain'}, ["Hello World"]] }
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
Mandrake provides `env` and `request` methods for building the conditional expression.
|
34
|
+
They can be used in the block.
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
Mandrake::Builder.new do
|
38
|
+
request.path_info.start_with?("/public") #=> 'request.path_info.start_with?("/public")'
|
39
|
+
env["PATH_INFO"] == "/public" #=> 'env["PATH_INFO"] == "/public"'
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
If you want to use these without the block executed on initialization,
|
44
|
+
you must pass the **proc** to the conditional options.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
builder = Mandrake::Builder.new
|
48
|
+
builder.use Rack::Deflater, if: proc{ request.path_info.start_with?("/public") }
|
49
|
+
```
|
50
|
+
|
51
|
+
The arguments of these options allow to pass the **lambda**, but its behavior is different from **proc**.
|
52
|
+
**lambda** is defined as the validation method by `define_method`. Therefore the validation method will be slow.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
Mandrake::Builder.new do
|
56
|
+
use Rack::Deflate, if: proc{ request.path_info.start_with?("/deflater") }
|
57
|
+
run ->(env){ [200, {'Content-Type' => 'text/plain'}, ["Hello World"]] }
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
In the end, `Mandrake::Builder` inherits `Rack::Builder`, so you can use this like `Rack::Builder` basically.
|
62
|
+
Of course, it does not break the compatibility.
|
63
|
+
|
64
|
+
## Middleware
|
65
|
+
|
66
|
+
This class is for incorporating mandrake into your application easily.
|
67
|
+
You can use as well as the Rack Middleware.
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
use Mandrake::Middleware do
|
71
|
+
use Rack::Deflate, if: request.path_info.start_with?("/deflater")
|
72
|
+
use Rack::ETag, unless: request.path_info.end_with?("etag")
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
## Contributing
|
77
|
+
|
78
|
+
1. Fork it ( https://github.com/namusyaka/mandrake/fork )
|
79
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
80
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
81
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
82
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/mandrake.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'mandrake/translator'
|
2
|
+
require 'rack'
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Mandrake
|
6
|
+
# Mandrake::Builder based on Rack::Builder
|
7
|
+
# It adds :if and :unless options to the `use` method,
|
8
|
+
# and enables conditional expression builders such as `env` and `request`
|
9
|
+
# @example
|
10
|
+
# Mandrake::Builder.new do
|
11
|
+
# use Rack::Deflater, if: request.path_info.start_with?("/deflater")
|
12
|
+
# use Rack::ETag, unless: request.path_info.end_with?("etag")
|
13
|
+
# run ->(env){ [200, {'Content-Type' => 'text/plain'}, ["Hello World"]] }
|
14
|
+
# end
|
15
|
+
class Builder < Rack::Builder
|
16
|
+
extend Forwardable
|
17
|
+
def_delegators :translator, :use, :request, :env
|
18
|
+
|
19
|
+
# Converts to application by using Mandrake::Translator
|
20
|
+
def to_app
|
21
|
+
app = @map ? generate_map(@run, @map) : @run
|
22
|
+
fail "missing run or map statement" unless app
|
23
|
+
app = translator.translate.reverse.inject(app) do |application, middleware|
|
24
|
+
middleware.call(application)
|
25
|
+
end
|
26
|
+
@warmup.call(app) if @warmup
|
27
|
+
app
|
28
|
+
end
|
29
|
+
|
30
|
+
# This method is for delegating methods
|
31
|
+
# Returns an instance of Mandrake::Translator for use in delegation and to_app
|
32
|
+
# @return [Mandrake::Translator]
|
33
|
+
def translator
|
34
|
+
@translator ||= Translator.new
|
35
|
+
end
|
36
|
+
|
37
|
+
private :translator
|
38
|
+
|
39
|
+
if Rack.release <= "1.5"
|
40
|
+
def warmup(prc=nil, &block)
|
41
|
+
@warmup = prc || block
|
42
|
+
end
|
43
|
+
|
44
|
+
def generate_map(default_app, mapping)
|
45
|
+
mapped = default_app ? {'/' => default_app} : {}
|
46
|
+
mapping.each { |r,b| mapped[r] = self.class.new(default_app, &b).to_app }
|
47
|
+
Rack::URLMap.new(mapped)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/mandrake/dsl.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'mandrake/dsl/stringify'
|
2
|
+
require 'mandrake/dsl/conditional_expression'
|
3
|
+
|
4
|
+
module Mandrake
|
5
|
+
# A module as namespace for defining DSL classes
|
6
|
+
# @!visibility private
|
7
|
+
module DSL
|
8
|
+
Env = Class.new(Stringify)
|
9
|
+
Request = Class.new(Stringify)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Mandrake
|
2
|
+
module DSL
|
3
|
+
# A class for building conditional expressions
|
4
|
+
# @example
|
5
|
+
# cond1 = Mandrake::DSL::If.new('env["PATH_INFO"] == "/"')
|
6
|
+
# cond2 = Mandrake::DSL::Unless.new('env["REQUEST_METHOD"] == "GET"')
|
7
|
+
# cond1 + cond2 #=> '(env["PATH_INFO"] == "/") && !(env["REQUEST_METHOD"] == "GET")'
|
8
|
+
# cond1.concat(cond2) #=> '(env["PATH_INFO"] == "/") && !(env["REQUEST_METHOD"] == "GET")'
|
9
|
+
# cond1 #=> '(env["PATH_INFO"] == "/") && !(env["REQUEST_METHOD"] == "GET")'
|
10
|
+
# @!visibility private
|
11
|
+
class ConditionalExpression
|
12
|
+
attr_accessor :code
|
13
|
+
|
14
|
+
# @!visibility private
|
15
|
+
def self.expression
|
16
|
+
@expression
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param [String] text
|
20
|
+
# @!visibility private
|
21
|
+
def self.template(text)
|
22
|
+
@expression ||= text
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [Mandrake::DSL::Stringify::Relation, Proc] code
|
26
|
+
# @!visibility private
|
27
|
+
def initialize(code)
|
28
|
+
@code = code
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param [Mandrake::DSL::ConditonalExpression] other_expression
|
32
|
+
# @!visibility private
|
33
|
+
def +(other_expression)
|
34
|
+
expression + " && " + other_expression.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
# Concatenates an other expression with self
|
38
|
+
# @param [Mandrake::DSL::ConditonalExpression] other_expression
|
39
|
+
# @!visibility private
|
40
|
+
def concat(other_expression)
|
41
|
+
@expression = send(:+, other_expression)
|
42
|
+
end
|
43
|
+
|
44
|
+
# @!visibility private
|
45
|
+
def expression
|
46
|
+
@expression ||= self.class.expression.gsub(/{:condition:}/, @code.to_s)
|
47
|
+
end
|
48
|
+
|
49
|
+
alias to_s expression
|
50
|
+
end
|
51
|
+
|
52
|
+
# @!visibility private
|
53
|
+
class If < ConditionalExpression
|
54
|
+
template "({:condition:})"
|
55
|
+
end
|
56
|
+
|
57
|
+
# @!visibility private
|
58
|
+
class Unless < ConditionalExpression
|
59
|
+
template "!({:condition:})"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Mandrake
|
2
|
+
module DSL
|
3
|
+
# A class for building an expression by using the method_missing method
|
4
|
+
# @example
|
5
|
+
# Oh = Class.new(Mandrake::DSL::Stringify)
|
6
|
+
# Oh.stringify.Mikey.hello('boy').to_s #=> "oh.Mikey.hello(\"boy\")"
|
7
|
+
# Oh.stringify.James.goodbye('man').to_s #=> "oh.James.goodbye(\"man\")"
|
8
|
+
# Oh.stringify.Mikey.hello('boy').and(Oh.stringify.James.goodbye('man')).to_s
|
9
|
+
# #=> "oh.Mikey.hello(\"boy\") && oh.James.goodbye(\"man\")"
|
10
|
+
# @!visibility private
|
11
|
+
class Stringify
|
12
|
+
# @!visibility private
|
13
|
+
def stringify
|
14
|
+
self.class.stringify
|
15
|
+
end
|
16
|
+
|
17
|
+
# @!visibility private
|
18
|
+
def self.stringify
|
19
|
+
Stringify::Relation.new(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @!visibility private
|
23
|
+
class Relation
|
24
|
+
# Defines a method for the relation
|
25
|
+
# @param [String, Symbol] name
|
26
|
+
# @yield block on which to base the method
|
27
|
+
# @!visibility private
|
28
|
+
def self.chain(name, &block)
|
29
|
+
define_method(name){|*args| instance_exec(*args, &block); self; }
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param [Class] klass
|
33
|
+
# @!visibility private
|
34
|
+
def initialize(klass)
|
35
|
+
@class = klass
|
36
|
+
reset_string
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns a string built by this class
|
40
|
+
# @!visibility private
|
41
|
+
def to_s
|
42
|
+
@string
|
43
|
+
end
|
44
|
+
|
45
|
+
chain(:[]) {|*args| @string << "[#{args.map(&:inspect) * ", "}]" }
|
46
|
+
chain(:==) {|value| @string << " == #{value.inspect}" }
|
47
|
+
chain(:and) {|relation| @string << " && " << relation.to_s }
|
48
|
+
chain(:or) {|relation| @string << " || " << relation.to_s }
|
49
|
+
chain(:method_missing) {|method_name, *args|
|
50
|
+
@string << ".#{method_name}"
|
51
|
+
@string << "(#{args.map(&:inspect) * ", "})" unless args.length.zero? }
|
52
|
+
chain(:reset_string) { @string = "#{@class.name.downcase.split(/::/).last}" }
|
53
|
+
alias equal ==
|
54
|
+
alias eq equal
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'mandrake/builder'
|
2
|
+
|
3
|
+
module Mandrake
|
4
|
+
# Mandrake::Middleware can quickly be used on your application
|
5
|
+
# @example
|
6
|
+
# use Mandrake::Middleware do
|
7
|
+
# use Rack::ETag, if: request.path_info.start_with?("/public")
|
8
|
+
# end
|
9
|
+
module Middleware
|
10
|
+
def self.new(app, &block)
|
11
|
+
builder = Mandrake::Builder.new
|
12
|
+
builder.instance_eval(&block)
|
13
|
+
builder.run(app)
|
14
|
+
builder.to_app
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'mandrake/dsl'
|
2
|
+
|
3
|
+
module Mandrake
|
4
|
+
# A class for being delegated from the Mandrake::Builder class
|
5
|
+
# @!visibility private
|
6
|
+
class Translator
|
7
|
+
# Construcsts an instance of Mandrake::Translator
|
8
|
+
def initialize
|
9
|
+
@middlewares = []
|
10
|
+
end
|
11
|
+
|
12
|
+
# @overload Rack::Builder#use(middleware, *args, options = {})
|
13
|
+
# @param [Hash] options The options can be included :if and :unless keys
|
14
|
+
# @return [Array] All registered middlewares
|
15
|
+
def use(middleware, *args, **options, &block)
|
16
|
+
parameters = extract_parameters_from(options)
|
17
|
+
@middlewares << Any.new(middleware, (options.empty? ? args : (args << options)), parameters, block)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Translates middlewares to compatible data with Rack::Builder's processing
|
21
|
+
# @return [Array]
|
22
|
+
def translate
|
23
|
+
@middlewares.map do |middleware|
|
24
|
+
if middleware.conditional?
|
25
|
+
then proc{|app| Wrapper.new(app, middleware.construct(app), middleware.condition) }
|
26
|
+
else proc{|app| middleware.construct(app) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# The string builder for building an expression
|
32
|
+
# @see Mandrake::DSL::Env
|
33
|
+
def env
|
34
|
+
DSL::Env.stringify
|
35
|
+
end
|
36
|
+
|
37
|
+
# The string builder for building an expression
|
38
|
+
# @see Mandrake::DSL::Request
|
39
|
+
def request
|
40
|
+
DSL::Request.stringify
|
41
|
+
end
|
42
|
+
|
43
|
+
# Extracts :if and :unless pairs from options
|
44
|
+
# @!visibility private
|
45
|
+
def extract_parameters_from(options)
|
46
|
+
[:if, :unless].inject({}) do |parameters, key|
|
47
|
+
expression = parameters[key] = options.delete(key) if options[key]
|
48
|
+
if expression.instance_of?(Proc) && !expression.lambda?
|
49
|
+
parameters[key] = instance_eval(&expression)
|
50
|
+
end
|
51
|
+
parameters
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private :extract_parameters_from
|
56
|
+
|
57
|
+
# A class for use in Mandrake::Translator#translate
|
58
|
+
# @!visibility private
|
59
|
+
class Any < Struct.new(:klass, :arguments, :parameters, :block)
|
60
|
+
# @!visibility private
|
61
|
+
def condition
|
62
|
+
@condition ||=
|
63
|
+
begin
|
64
|
+
expressions = []
|
65
|
+
expressions << DSL::If.new(parameters[:if]) if parameters[:if]
|
66
|
+
expressions << DSL::Unless.new(parameters[:unless]) if parameters[:unless]
|
67
|
+
expressions.inject(:+)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# @!visibility private
|
72
|
+
def construct(app)
|
73
|
+
klass.new(app, *arguments, &block)
|
74
|
+
end
|
75
|
+
|
76
|
+
# @!visibility private
|
77
|
+
def conditional?
|
78
|
+
!!condition
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# A wrapper class for conditional middleware which is containing the validator
|
83
|
+
# @!visibility private
|
84
|
+
class Wrapper
|
85
|
+
attr_accessor :env, :request
|
86
|
+
|
87
|
+
# @!visibility private
|
88
|
+
def initialize(app, middleware, condition)
|
89
|
+
@app = app
|
90
|
+
@middleware = middleware
|
91
|
+
add_validator(condition)
|
92
|
+
end
|
93
|
+
|
94
|
+
# @param [Hash] env
|
95
|
+
# @!visibility private
|
96
|
+
def call(env)
|
97
|
+
@env = env
|
98
|
+
@request = Rack::Request.new(@env)
|
99
|
+
valid? ? @middleware.call(env) : @app.call(env)
|
100
|
+
end
|
101
|
+
|
102
|
+
# @param [String, Proc] condition
|
103
|
+
# @!visibility private
|
104
|
+
def add_validator(condition)
|
105
|
+
code = condition.code
|
106
|
+
if code.instance_of?(Proc) && code.lambda?
|
107
|
+
singleton_class.send(:define_method, :valid?, &code)
|
108
|
+
else
|
109
|
+
instance_eval("def valid?; #{condition} end")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/mandrake.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'mandrake/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "mandrake"
|
8
|
+
spec.version = Mandrake::VERSION
|
9
|
+
spec.authors = ["namusyaka"]
|
10
|
+
spec.email = ["namusyaka@gmail.com"]
|
11
|
+
spec.summary = %q{Mandrake loads middlewares conditionally, and it provides two options and DSL for setting conditions}
|
12
|
+
spec.description = spec.summary
|
13
|
+
spec.homepage = "https://github.com/namusyaka/mandrake"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "rack"
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "rspec"
|
25
|
+
end
|
data/spec/builder/end.ru
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
run lambda{ |env| [200, {'Content-Type' => 'text/plain'}, [__LINE__.to_s]] }
|
@@ -0,0 +1,257 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rack/builder'
|
3
|
+
require 'rack/lint'
|
4
|
+
require 'rack/mock'
|
5
|
+
require 'rack/showexceptions'
|
6
|
+
require 'rack/urlmap'
|
7
|
+
|
8
|
+
describe Mandrake::Builder do
|
9
|
+
it "supports mapping" do
|
10
|
+
app = builder_to_app do
|
11
|
+
map '/' do |outer_env|
|
12
|
+
run lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, ['root']] }
|
13
|
+
end
|
14
|
+
map '/sub' do
|
15
|
+
run lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, ['sub']] }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq 'root'
|
19
|
+
expect(Rack::MockRequest.new(app).get("/sub").body.to_s).to eq 'sub'
|
20
|
+
end
|
21
|
+
|
22
|
+
it "doesn't dupe env even when mapping" do
|
23
|
+
app = builder_to_app do
|
24
|
+
use NothingMiddleware
|
25
|
+
map '/' do |outer_env|
|
26
|
+
run lambda { |inner_env|
|
27
|
+
inner_env['new_key'] = 'new_value'
|
28
|
+
[200, {"Content-Type" => "text/plain"}, ['root']]
|
29
|
+
}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq 'root'
|
33
|
+
expect(NothingMiddleware.env['new_key']).to eq 'new_value'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "chains apps by default" do
|
37
|
+
app = builder_to_app do
|
38
|
+
use Rack::ShowExceptions
|
39
|
+
run lambda { |env| raise "bzzzt" }
|
40
|
+
end
|
41
|
+
|
42
|
+
expect(Rack::MockRequest.new(app).get("/")).to be_server_error
|
43
|
+
expect(Rack::MockRequest.new(app).get("/")).to be_server_error
|
44
|
+
expect(Rack::MockRequest.new(app).get("/")).to be_server_error
|
45
|
+
end
|
46
|
+
|
47
|
+
it "has implicit #to_app" do
|
48
|
+
app = builder do
|
49
|
+
use Rack::ShowExceptions
|
50
|
+
run lambda { |env| raise "bzzzt" }
|
51
|
+
end
|
52
|
+
|
53
|
+
expect(Rack::MockRequest.new(app).get("/")).to be_server_error
|
54
|
+
expect(Rack::MockRequest.new(app).get("/")).to be_server_error
|
55
|
+
expect(Rack::MockRequest.new(app).get("/")).to be_server_error
|
56
|
+
end
|
57
|
+
|
58
|
+
it "supports blocks on use" do
|
59
|
+
app = builder do
|
60
|
+
use Rack::ShowExceptions
|
61
|
+
use Rack::Auth::Basic do |username, password|
|
62
|
+
'secret' == password
|
63
|
+
end
|
64
|
+
|
65
|
+
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ['Hi Boss']] }
|
66
|
+
end
|
67
|
+
|
68
|
+
response = Rack::MockRequest.new(app).get("/")
|
69
|
+
expect(response).to be_client_error
|
70
|
+
expect(response.status).to eq 401
|
71
|
+
|
72
|
+
# with auth...
|
73
|
+
response = Rack::MockRequest.new(app).get("/",
|
74
|
+
'HTTP_AUTHORIZATION' => 'Basic ' + ["joe:secret"].pack("m*"))
|
75
|
+
expect(response.status).to eq 200
|
76
|
+
expect(response.body.to_s).to eq 'Hi Boss'
|
77
|
+
end
|
78
|
+
|
79
|
+
it "has explicit #to_app" do
|
80
|
+
app = builder do
|
81
|
+
use Rack::ShowExceptions
|
82
|
+
run lambda { |env| raise "bzzzt" }
|
83
|
+
end
|
84
|
+
|
85
|
+
expect(Rack::MockRequest.new(app).get("/")).to be_server_error
|
86
|
+
expect(Rack::MockRequest.new(app).get("/")).to be_server_error
|
87
|
+
expect(Rack::MockRequest.new(app).get("/")).to be_server_error
|
88
|
+
end
|
89
|
+
|
90
|
+
it "can mix map and run for endpoints" do
|
91
|
+
app = builder do
|
92
|
+
map '/sub' do
|
93
|
+
run lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, ['sub']] }
|
94
|
+
end
|
95
|
+
run lambda { |inner_env| [200, {"Content-Type" => "text/plain"}, ['root']] }
|
96
|
+
end
|
97
|
+
|
98
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq 'root'
|
99
|
+
expect(Rack::MockRequest.new(app).get("/sub").body.to_s).to eq 'sub'
|
100
|
+
end
|
101
|
+
|
102
|
+
it "accepts middleware-only map blocks" do
|
103
|
+
app = builder do
|
104
|
+
map('/foo') { use Rack::ShowExceptions }
|
105
|
+
run lambda { |env| raise "bzzzt" }
|
106
|
+
end
|
107
|
+
|
108
|
+
expect { Rack::MockRequest.new(app).get("/") }.to raise_error(RuntimeError)
|
109
|
+
expect(Rack::MockRequest.new(app).get("/foo")).to be_server_error
|
110
|
+
end
|
111
|
+
|
112
|
+
it "yields the generated app to a block for warmup" do
|
113
|
+
warmed_up_app = nil
|
114
|
+
|
115
|
+
app = Mandrake::Builder.new do
|
116
|
+
warmup { |a| warmed_up_app = a }
|
117
|
+
run lambda { |env| [200, {}, []] }
|
118
|
+
end.to_app
|
119
|
+
|
120
|
+
expect(warmed_up_app).to equal app
|
121
|
+
end
|
122
|
+
|
123
|
+
it "initialize apps once" do
|
124
|
+
app = builder do
|
125
|
+
class AppClass
|
126
|
+
def initialize
|
127
|
+
@called = 0
|
128
|
+
end
|
129
|
+
def call(env)
|
130
|
+
raise "bzzzt" if @called > 0
|
131
|
+
@called += 1
|
132
|
+
[200, {'Content-Type' => 'text/plain'}, ['OK']]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
use Rack::ShowExceptions
|
137
|
+
run AppClass.new
|
138
|
+
end
|
139
|
+
|
140
|
+
expect(Rack::MockRequest.new(app).get("/").status).to eq 200
|
141
|
+
expect(Rack::MockRequest.new(app).get("/")).to be_server_error
|
142
|
+
end
|
143
|
+
|
144
|
+
it "allows use after run" do
|
145
|
+
app = builder do
|
146
|
+
run lambda { |env| raise "bzzzt" }
|
147
|
+
use Rack::ShowExceptions
|
148
|
+
end
|
149
|
+
|
150
|
+
expect(Rack::MockRequest.new(app).get("/")).to be_server_error
|
151
|
+
expect(Rack::MockRequest.new(app).get("/")).to be_server_error
|
152
|
+
expect(Rack::MockRequest.new(app).get("/")).to be_server_error
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'complains about a missing run' do
|
156
|
+
expect { Rack::Lint.new Mandrake::Builder.app { use Rack::ShowExceptions }}.to raise_error(RuntimeError)
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "parse_file" do
|
160
|
+
def config_file(name)
|
161
|
+
File.join(File.dirname(__FILE__), 'builder', name)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "parses commented options" do
|
165
|
+
app, options = Mandrake::Builder.parse_file config_file('options.ru')
|
166
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq 'OK'
|
167
|
+
end
|
168
|
+
|
169
|
+
it "removes __END__ before evaluating app" do
|
170
|
+
app, _ = Mandrake::Builder.parse_file config_file('end.ru')
|
171
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq 'OK'
|
172
|
+
end
|
173
|
+
|
174
|
+
it "supports multi-line comments" do
|
175
|
+
expect { Mandrake::Builder.parse_file config_file('comment.ru') }.not_to raise_error
|
176
|
+
end
|
177
|
+
|
178
|
+
it "requires anything not ending in .ru" do
|
179
|
+
$: << File.dirname(__FILE__)
|
180
|
+
app, * = Mandrake::Builder.parse_file 'builder/anything'
|
181
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq 'OK'
|
182
|
+
$:.pop
|
183
|
+
end
|
184
|
+
|
185
|
+
it "sets __LINE__ correctly" do
|
186
|
+
app, _ = Mandrake::Builder.parse_file config_file('line.ru')
|
187
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq '1'
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
describe 'new_from_string' do
|
192
|
+
it "builds a rack app from string" do
|
193
|
+
app, = Mandrake::Builder.new_from_string "run lambda{|env| [200, {'Content-Type' => 'text/plane'}, ['OK']] }"
|
194
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq 'OK'
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe 'conditional builder' do
|
199
|
+
it 'support request and env DSL on block' do
|
200
|
+
app = builder do
|
201
|
+
_env = env
|
202
|
+
run lambda { |env| [200, {"Content-Type" => "text/plain"}, [request.to_s << _env.to_s]] }
|
203
|
+
end
|
204
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq 'requestenv'
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'support :if option on use' do
|
208
|
+
app = builder do
|
209
|
+
use Dummy, if: request.path_info.start_with?("/public")
|
210
|
+
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ['Hi Boss']] }
|
211
|
+
end
|
212
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq 'Hi Boss'
|
213
|
+
expect(Rack::MockRequest.new(app).get("/public").body.to_s).to eq 'YAY!'
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'support :unless option on use' do
|
217
|
+
app = builder do
|
218
|
+
use Dummy, unless: request.path_info.start_with?("/public")
|
219
|
+
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ['Hi Boss']] }
|
220
|
+
end
|
221
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq 'YAY!'
|
222
|
+
expect(Rack::MockRequest.new(app).get("/public").body.to_s).to eq 'Hi Boss'
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'allow to pass proc to :if and :unless options' do
|
226
|
+
app = builder do
|
227
|
+
use Dummy, if: proc{ request.path_info.start_with?("/public") }
|
228
|
+
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ['Hi Boss']] }
|
229
|
+
end
|
230
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq 'Hi Boss'
|
231
|
+
expect(Rack::MockRequest.new(app).get("/public").body.to_s).to eq 'YAY!'
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'allow to pass lambda to :if and :unless options' do
|
235
|
+
app = builder do
|
236
|
+
use Dummy, if: ->{ request.path_info.start_with?("/public") }
|
237
|
+
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ['Hi Boss']] }
|
238
|
+
end
|
239
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq 'Hi Boss'
|
240
|
+
expect(Rack::MockRequest.new(app).get("/public").body.to_s).to eq 'YAY!'
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'can be set the arguments to #use' do
|
244
|
+
app = builder do
|
245
|
+
use OptionalMiddleware, hey: true do
|
246
|
+
"hey"
|
247
|
+
end
|
248
|
+
use Dummy, if: env["REQUEST_METHOD"] == "POST"
|
249
|
+
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ['Hi Boss']] }
|
250
|
+
end
|
251
|
+
response = Rack::MockRequest.new(app).get("/public")
|
252
|
+
expect(response.headers["Options"]).to be_an_instance_of(String)
|
253
|
+
expect(response.headers["Block"]).to be_an_instance_of(String)
|
254
|
+
expect(response.body.to_s).to eq 'Hi Boss'
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mandrake::DSL::ConditionalExpression do
|
4
|
+
SampleCondition = Class.new(described_class)
|
5
|
+
SampleCondition.template '({:condition:})'
|
6
|
+
|
7
|
+
describe "+" do
|
8
|
+
let(:a){ Mandrake::DSL::If.new("a and b") }
|
9
|
+
let(:b){ Mandrake::DSL::Unless.new("a and b") }
|
10
|
+
subject { (a + b).to_s }
|
11
|
+
it { should eq('(a and b) && !(a and b)') }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "concat" do
|
15
|
+
let(:a){ Mandrake::DSL::If.new("a and b") }
|
16
|
+
let(:b){ Mandrake::DSL::Unless.new("a and b") }
|
17
|
+
before { a.concat(b) }
|
18
|
+
subject { a.to_s }
|
19
|
+
it { should eq('(a and b) && !(a and b)') }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "built-in classes" do
|
23
|
+
describe "If" do
|
24
|
+
let(:condition){ Mandrake::DSL::If.new("a and b") }
|
25
|
+
subject { condition.to_s }
|
26
|
+
it { should eq('(a and b)') }
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "Unless" do
|
30
|
+
let(:condition){ Mandrake::DSL::Unless.new("a and b") }
|
31
|
+
subject { condition.to_s }
|
32
|
+
it { should eq('!(a and b)') }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mandrake::DSL::Stringify do
|
4
|
+
Sample = Class.new(described_class)
|
5
|
+
context "basic" do
|
6
|
+
subject { Sample.stringify.unknown_method.eq('hello').to_s }
|
7
|
+
it { should eq('sample.unknown_method == "hello"') }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "arguments" do
|
11
|
+
context "with Fixnum" do
|
12
|
+
subject { Sample.stringify.hello_world(1234).eq('1234').to_s }
|
13
|
+
it { should eq('sample.hello_world(1234) == "1234"') }
|
14
|
+
end
|
15
|
+
|
16
|
+
context "with String" do
|
17
|
+
subject { Sample.stringify.hello_world('1234').eq('1234').to_s }
|
18
|
+
it { should eq('sample.hello_world("1234") == "1234"') }
|
19
|
+
end
|
20
|
+
|
21
|
+
context "with Array" do
|
22
|
+
subject { Sample.stringify.hello_world([1, 2, 3, 4]).eq([1, 2, 3, 4]).to_s }
|
23
|
+
it { should eq('sample.hello_world([1, 2, 3, 4]) == [1, 2, 3, 4]') }
|
24
|
+
end
|
25
|
+
|
26
|
+
context "with Hash" do
|
27
|
+
subject { Sample.stringify.hello_world({a: :hey}).eq({a: :hey}).to_s }
|
28
|
+
it { should eq('sample.hello_world({:a=>:hey}) == {:a=>:hey}') }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
describe "[]" do
|
34
|
+
subject { Sample.stringify.method_that_does_not_exist['Hello'].eq('Hello World').to_s }
|
35
|
+
it { should eq('sample.method_that_does_not_exist["Hello"] == "Hello World"') }
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "and" do
|
39
|
+
subject { Sample.stringify.a.eq('Hello World').and(Sample.stringify.b.start_with?("/public")).to_s }
|
40
|
+
it { should eq('sample.a == "Hello World" && sample.b.start_with?("/public")') }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "or" do
|
44
|
+
subject { Sample.stringify.a.eq('Hello World').or(Sample.stringify.b.start_with?("/public")).to_s }
|
45
|
+
it { should eq('sample.a == "Hello World" || sample.b.start_with?("/public")') }
|
46
|
+
end
|
47
|
+
|
48
|
+
context "use == instead of eq" do
|
49
|
+
subject { Sample.stringify.a == 'hello'}
|
50
|
+
it { should eq('sample.a == "hello"') }
|
51
|
+
end
|
52
|
+
|
53
|
+
context "without eq" do
|
54
|
+
subject { Sample.stringify.method_that_does_not_exist['Hello'].include?('howl').to_s }
|
55
|
+
it { should eq('sample.method_that_does_not_exist["Hello"].include?("howl")') }
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#reset_string" do
|
59
|
+
subject { Sample.stringify.method_that_does_not_exist.reset_string.hey['hello'].include?('howl').to_s }
|
60
|
+
it { should eq('sample.hey["hello"].include?("howl")') }
|
61
|
+
end
|
62
|
+
end
|
data/spec/dsl_spec.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mandrake::DSL do
|
4
|
+
shared_examples_for('a constant for dsl'){|constant|
|
5
|
+
it { expect(constant).to respond_to(:stringify) }}
|
6
|
+
it_behaves_like 'a constant for dsl', described_class::Env
|
7
|
+
it_behaves_like 'a constant for dsl', described_class::Request
|
8
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mandrake::Middleware do
|
4
|
+
it "can be executed in Rack::Builder" do
|
5
|
+
app = rack_builder do
|
6
|
+
use Mandrake::Middleware do
|
7
|
+
use Dummy, if: request.path_info.start_with?("/public")
|
8
|
+
end
|
9
|
+
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ['Hi Boss']] }
|
10
|
+
end
|
11
|
+
expect(Rack::MockRequest.new(app).get("/").body.to_s).to eq 'Hi Boss'
|
12
|
+
expect(Rack::MockRequest.new(app).get("/public").body.to_s).to eq 'YAY!'
|
13
|
+
end
|
14
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require File.expand_path("../../lib/mandrake", __FILE__)
|
2
|
+
require 'bundler' unless defined?(Bundler)
|
3
|
+
Bundler.require(:test)
|
4
|
+
|
5
|
+
class OptionalMiddleware
|
6
|
+
def initialize(app, options = {}, &block)
|
7
|
+
@app = app
|
8
|
+
@options = options
|
9
|
+
@block = true if block_given?
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
response = @app.call(env)
|
14
|
+
response[1].merge!("Options" => @options.inspect, "Block" => @block.inspect)
|
15
|
+
response
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class NothingMiddleware
|
20
|
+
def initialize(app)
|
21
|
+
@app = app
|
22
|
+
end
|
23
|
+
def call(env)
|
24
|
+
@@env = env
|
25
|
+
response = @app.call(env)
|
26
|
+
response
|
27
|
+
end
|
28
|
+
def self.env
|
29
|
+
@@env
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Dummy
|
34
|
+
def initialize(app)
|
35
|
+
@app = app
|
36
|
+
end
|
37
|
+
|
38
|
+
def call(env)
|
39
|
+
[200, {}, ["YAY!"]]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def app
|
44
|
+
@app
|
45
|
+
end
|
46
|
+
|
47
|
+
def rack_builder(&block)
|
48
|
+
Rack::Lint.new Rack::Builder.new(&block)
|
49
|
+
end
|
50
|
+
|
51
|
+
def builder(&block)
|
52
|
+
Rack::Lint.new Mandrake::Builder.new(&block)
|
53
|
+
end
|
54
|
+
|
55
|
+
def builder_to_app(&block)
|
56
|
+
Rack::Lint.new Mandrake::Builder.new(&block).to_app
|
57
|
+
end
|
58
|
+
|
59
|
+
class TestApp
|
60
|
+
def call(env)
|
61
|
+
[200, {"Content-Type" => "text/plain"}, ["test app"]]
|
62
|
+
end
|
63
|
+
end
|
metadata
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mandrake
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- namusyaka
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-08-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.6'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Mandrake loads middlewares conditionally, and it provides two options
|
70
|
+
and DSL for setting conditions
|
71
|
+
email:
|
72
|
+
- namusyaka@gmail.com
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- .gitignore
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- lib/mandrake.rb
|
83
|
+
- lib/mandrake/builder.rb
|
84
|
+
- lib/mandrake/dsl.rb
|
85
|
+
- lib/mandrake/dsl/conditional_expression.rb
|
86
|
+
- lib/mandrake/dsl/stringify.rb
|
87
|
+
- lib/mandrake/middleware.rb
|
88
|
+
- lib/mandrake/translator.rb
|
89
|
+
- lib/mandrake/version.rb
|
90
|
+
- mandrake.gemspec
|
91
|
+
- spec/builder/anything.rb
|
92
|
+
- spec/builder/comment.ru
|
93
|
+
- spec/builder/end.ru
|
94
|
+
- spec/builder/line.ru
|
95
|
+
- spec/builder/options.ru
|
96
|
+
- spec/builder_spec.rb
|
97
|
+
- spec/dsl/conditional_expression_spec.rb
|
98
|
+
- spec/dsl/stringify_spec.rb
|
99
|
+
- spec/dsl_spec.rb
|
100
|
+
- spec/middleware_spec.rb
|
101
|
+
- spec/spec_helper.rb
|
102
|
+
homepage: https://github.com/namusyaka/mandrake
|
103
|
+
licenses:
|
104
|
+
- MIT
|
105
|
+
metadata: {}
|
106
|
+
post_install_message:
|
107
|
+
rdoc_options: []
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - '>='
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
requirements: []
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 2.0.14
|
123
|
+
signing_key:
|
124
|
+
specification_version: 4
|
125
|
+
summary: Mandrake loads middlewares conditionally, and it provides two options and
|
126
|
+
DSL for setting conditions
|
127
|
+
test_files:
|
128
|
+
- spec/builder/anything.rb
|
129
|
+
- spec/builder/comment.ru
|
130
|
+
- spec/builder/end.ru
|
131
|
+
- spec/builder/line.ru
|
132
|
+
- spec/builder/options.ru
|
133
|
+
- spec/builder_spec.rb
|
134
|
+
- spec/dsl/conditional_expression_spec.rb
|
135
|
+
- spec/dsl/stringify_spec.rb
|
136
|
+
- spec/dsl_spec.rb
|
137
|
+
- spec/middleware_spec.rb
|
138
|
+
- spec/spec_helper.rb
|
139
|
+
has_rdoc:
|