roda-plugins 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gems +7 -0
- data/.gitignore +3 -0
- data/.ruby-version +1 -0
- data/Makefile +45 -0
- data/lib/roda/plugins/assets.rb +178 -0
- data/lib/roda/plugins/components.rb +195 -0
- data/lib/roda/plugins/version.rb +1 -1
- data/test/assets_test.rb +53 -0
- data/test/components_test.rb +99 -0
- data/test/dummy/assets/css/app.scss +1 -0
- data/test/dummy/assets/js/head/app.coffee +1 -0
- data/test/dummy/assets/raw.css +1 -0
- data/test/helper.rb +57 -0
- metadata +24 -10
- data/Gemfile +0 -4
- data/Rakefile +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f390fa66a5124b6f929fc4569dae579a31320676
|
4
|
+
data.tar.gz: e14588885bc08bfaa9da27f7403dc0e112ac8452
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6df848c99bb4b8eb030e2f7548330895bdc227b25233619ff8820702c0061790b4deb28cfcdd282747e614e350923489d9a5da9d482a133112112dd2c5ad7a1
|
7
|
+
data.tar.gz: 69f3b7eacab67dd5aa2e8a2319db5e75e56b91607ff9c59fb669bdfab562d929778973cee1a31fc9528f91bfac050196e85c2b76829c691d2af2746aff508561
|
data/.gems
ADDED
data/.gitignore
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.2
|
data/Makefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
GEMSPEC=$(shell ls *.gemspec | head -1)
|
2
|
+
VERSION=$(shell ruby -rubygems -e 'puts Gem::Specification.load("$(GEMSPEC)").version')
|
3
|
+
PROJECT=$(shell ruby -rubygems -e 'puts Gem::Specification.load("$(GEMSPEC)").name')
|
4
|
+
GEM=$(PROJECT)-$(VERSION).gem
|
5
|
+
|
6
|
+
.PHONY: install package publish test server $(GEM)
|
7
|
+
|
8
|
+
define install_bs
|
9
|
+
which bs || (wget https://raw.githubusercontent.com/educabilia/bs/master/bin/bs && chmod +x bs && sudo mv bs /usr/local/bin)
|
10
|
+
|
11
|
+
@if [ -s .gs ]; then \
|
12
|
+
true; \
|
13
|
+
else \
|
14
|
+
mkdir .gs; \
|
15
|
+
touch .env; \
|
16
|
+
echo 'GEM_HOME=$(PWD)/.gs' >> .env; \
|
17
|
+
echo 'GEM_PATH=$(PWD)/.gs' >> .env; \
|
18
|
+
echo 'PATH=$(PWD)/.gs/bin:$$PATH' >> .env; \
|
19
|
+
echo 'RACK_ENV=test' >> .env.test; \
|
20
|
+
fi;
|
21
|
+
|
22
|
+
bs gem list dep-cj -i || bs gem install dep-cj
|
23
|
+
gem list cutest-cj -i || gem install cutest-cj
|
24
|
+
bs gem list pry -i || bs gem install pry
|
25
|
+
bs gem list awesome_print -i || bs gem install awesome_print
|
26
|
+
endef
|
27
|
+
|
28
|
+
install:
|
29
|
+
$(call install_bs)
|
30
|
+
bs dep install
|
31
|
+
bs gem cleanup
|
32
|
+
|
33
|
+
test:
|
34
|
+
bs env $$(cat .env.test) cutest test/**/*_test.rb
|
35
|
+
|
36
|
+
package: $(GEM)
|
37
|
+
|
38
|
+
# Always build the gem
|
39
|
+
$(GEM):
|
40
|
+
gem build $(PROJECT).gemspec
|
41
|
+
|
42
|
+
publish: $(GEM)
|
43
|
+
gem push $(GEM)
|
44
|
+
rm $(GEM)
|
45
|
+
git tag -a $(VERSION)
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require "tilt"
|
2
|
+
|
3
|
+
class Roda
|
4
|
+
module RodaPlugins
|
5
|
+
module Assets
|
6
|
+
def self.load_dependencies(app, opts={})
|
7
|
+
app.plugin :render
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.configure(app, opts={}, &block)
|
11
|
+
if app.opts[:assets]
|
12
|
+
app.opts[:assets].merge!(opts)
|
13
|
+
else
|
14
|
+
app.opts[:assets] = opts.dup
|
15
|
+
end
|
16
|
+
|
17
|
+
opts = app.opts[:assets]
|
18
|
+
opts[:css] ||= []
|
19
|
+
opts[:js] ||= []
|
20
|
+
opts[:js_folder] ||= 'js'
|
21
|
+
opts[:css_folder] ||= 'css'
|
22
|
+
opts[:path] ||= File.expand_path("assets", Dir.pwd)
|
23
|
+
opts[:route] ||= 'assets'
|
24
|
+
opts[:css_engine] ||= 'scss'
|
25
|
+
opts[:js_engine] ||= 'coffee'
|
26
|
+
opts[:headers] ||= {}
|
27
|
+
opts[:cache] = app.thread_safe_cache if opts.fetch(:cache, true)
|
28
|
+
|
29
|
+
yield opts if block
|
30
|
+
end
|
31
|
+
|
32
|
+
module ClassMethods
|
33
|
+
# Copy the assets options into the subclass, duping
|
34
|
+
# them as necessary to prevent changes in the subclass
|
35
|
+
# affecting the parent class.
|
36
|
+
def inherited(subclass)
|
37
|
+
super
|
38
|
+
opts = subclass.opts[:assets] = assets_opts.dup
|
39
|
+
opts[:cache] = thread_safe_cache if opts[:cache]
|
40
|
+
end
|
41
|
+
|
42
|
+
# Return the assets options for this class.
|
43
|
+
def assets_opts
|
44
|
+
opts[:assets]
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def asset_path file, type
|
49
|
+
file.gsub!(/\.#{type}$/, '')
|
50
|
+
assets = assets_opts[:"#{type}"]
|
51
|
+
|
52
|
+
if assets.is_a? Array
|
53
|
+
file_path = assets.select {|a| a["#{file}"]}.first
|
54
|
+
else
|
55
|
+
file = file.split('/')
|
56
|
+
sub = file.shift.to_sym
|
57
|
+
file = file.join '/'
|
58
|
+
file_path = assets[sub].select {|a| a["#{file}"]}.first
|
59
|
+
|
60
|
+
if file_path && !file_path[/^\.\//]
|
61
|
+
file_path = "#{sub}/#{file_path}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
folder = assets_opts[:"#{type}_folder"]
|
66
|
+
|
67
|
+
if file_path
|
68
|
+
if !file_path[/^\.\//]
|
69
|
+
"#{assets_opts[:path]}/#{folder}/#{file_path}"
|
70
|
+
else
|
71
|
+
file_path
|
72
|
+
end
|
73
|
+
else
|
74
|
+
file
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
module InstanceMethods
|
80
|
+
def assets_opts
|
81
|
+
self.class.assets_opts
|
82
|
+
end
|
83
|
+
|
84
|
+
def assets type, options = {}
|
85
|
+
attrs = options.map{|k,v| "#{k}=\"#{v}\""}
|
86
|
+
tags = []
|
87
|
+
type = [type] unless type.is_a? Array
|
88
|
+
files = type.length == 1 \
|
89
|
+
? assets_opts[:"#{type[0]}"] \
|
90
|
+
: assets_opts[:"#{type[0]}"][:"#{type[1]}"]
|
91
|
+
|
92
|
+
files.each do |file|
|
93
|
+
file.gsub!(/\./, '$2E')
|
94
|
+
file = file.split('/')
|
95
|
+
file[file.length - 1] = file.last.gsub(/\$2E/, '.')
|
96
|
+
file = file.join '/'
|
97
|
+
path = assets_opts[:route] + '/' + assets_opts[:"#{type[0]}_folder"]
|
98
|
+
attr = type[0].to_s == 'js' ? 'src' : 'href'
|
99
|
+
attrs.unshift "#{attr}=\"/#{path}/#{file}\""
|
100
|
+
tags << send("#{type[0]}_assets_tag", attrs.join(' '))
|
101
|
+
end
|
102
|
+
|
103
|
+
tags.join "\n"
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
# <link rel="stylesheet" href="theme.css">
|
109
|
+
def css_assets_tag attrs
|
110
|
+
"<link rel=\"stylesheet\" #{attrs} />"
|
111
|
+
end
|
112
|
+
|
113
|
+
# <script src="scriptfile.js"></script>
|
114
|
+
def js_assets_tag attrs
|
115
|
+
"<script type=\"text/javascript\" #{attrs}></script>"
|
116
|
+
end
|
117
|
+
|
118
|
+
def render_asset *args
|
119
|
+
self.class.render_asset(*args)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
module RequestClassMethods
|
124
|
+
def assets_opts
|
125
|
+
roda_class.assets_opts
|
126
|
+
end
|
127
|
+
|
128
|
+
%w(css js).each do |type|
|
129
|
+
define_method "#{type}_assets_path" do
|
130
|
+
Regexp.new(
|
131
|
+
assets_opts[:route] + '/' + assets_opts[:"#{type}_folder"] + '/(.*)'
|
132
|
+
)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
module RequestMethods
|
138
|
+
def assets
|
139
|
+
%w(css js).each do |type|
|
140
|
+
on self.class.public_send "#{type}_assets_path" do |file|
|
141
|
+
file.gsub!(/\$2E/, '.')
|
142
|
+
|
143
|
+
content_type = Rack::Mime.mime_type File.extname(file)
|
144
|
+
|
145
|
+
response.headers.merge!({
|
146
|
+
"Content-Type" => content_type + '; charset=UTF-8',
|
147
|
+
}.merge(scope.assets_opts[:headers]))
|
148
|
+
|
149
|
+
engine = scope.assets_opts[:"#{type}_engine"]
|
150
|
+
|
151
|
+
if !file[/^\.\//]
|
152
|
+
path = scope.assets_opts[:route] + '/' + scope.assets_opts[:"#{type}_folder"] + "/#{file}"
|
153
|
+
else
|
154
|
+
path = file
|
155
|
+
end
|
156
|
+
|
157
|
+
if File.exists? "#{path}.#{engine}"
|
158
|
+
scope.render path: "#{path}.#{engine}"
|
159
|
+
elsif File.exists? "#{path}.#{type}"
|
160
|
+
File.read "#{path}.#{type}"
|
161
|
+
elsif File.exists?(path) && path[/\.#{type}$/]
|
162
|
+
File.read path
|
163
|
+
elsif File.exists? path
|
164
|
+
begin
|
165
|
+
scope.render path: path
|
166
|
+
rescue
|
167
|
+
File.read path
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
register_plugin(:assets, Assets)
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
class Roda
|
2
|
+
module RodaPlugins
|
3
|
+
module Components
|
4
|
+
def self.configure(app, opts={})
|
5
|
+
if app.opts[:components]
|
6
|
+
app.opts[:components].merge!(opts)
|
7
|
+
else
|
8
|
+
app.opts[:components] = opts.dup
|
9
|
+
end
|
10
|
+
|
11
|
+
opts = app.opts[:components]
|
12
|
+
opts[:cache] = app.thread_safe_cache if opts.fetch(:cache, true)
|
13
|
+
opts[:settings] ||= {}
|
14
|
+
opts[:cache][:components] ||= {}
|
15
|
+
opts[:cache][:events] ||= {}
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def inherited(subclass)
|
20
|
+
super
|
21
|
+
opts.merge! subclass.opts[:components]
|
22
|
+
end
|
23
|
+
|
24
|
+
def components_opts
|
25
|
+
opts[:components]
|
26
|
+
end
|
27
|
+
|
28
|
+
def components
|
29
|
+
cache[:components].keys
|
30
|
+
end
|
31
|
+
|
32
|
+
def load_component name
|
33
|
+
cache[:components][name]
|
34
|
+
end
|
35
|
+
|
36
|
+
def component(name, events = [], &block)
|
37
|
+
name = name.to_s
|
38
|
+
cache[:components][name] = block
|
39
|
+
cache[:events][name] ||= {}
|
40
|
+
|
41
|
+
events.each do |event|
|
42
|
+
if event.is_a? String
|
43
|
+
event_array = cache[:events][name][event] ||= []
|
44
|
+
event_array << { component: name, call: event }
|
45
|
+
elsif event.is_a? Hash
|
46
|
+
for_component = event[:for].to_s
|
47
|
+
response_to = event[:respond_to].to_s
|
48
|
+
call_with = event[:with]
|
49
|
+
|
50
|
+
event_array = cache[:events][for_component || name][response_to] ||= []
|
51
|
+
event_array << { component: name, call: call_with || response_to }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def load_setup_component name
|
57
|
+
cache[:components]["_setup_#{name}"]
|
58
|
+
end
|
59
|
+
|
60
|
+
def setup_component(name, &block)
|
61
|
+
cache[:components]["_setup_#{name}"] = block
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def cache
|
67
|
+
components_opts[:cache]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
module InstanceMethods
|
72
|
+
def component(name, opts = {})
|
73
|
+
name = name.to_s
|
74
|
+
|
75
|
+
component_request = ComponentRequest.new(self, self.class, name, opts)
|
76
|
+
|
77
|
+
content = catch :halt do
|
78
|
+
if setup_component = self.class.load_setup_component(name)
|
79
|
+
instance_exec(component_request, &setup_component)
|
80
|
+
end
|
81
|
+
|
82
|
+
opts[:call] ||= 'display'
|
83
|
+
|
84
|
+
instance_exec(component_request, &self.class.load_component(name))
|
85
|
+
|
86
|
+
raise "Couldn't find on method `#{opts[:call]}`, for the `#{name}` component."
|
87
|
+
end
|
88
|
+
|
89
|
+
response.write content if content.is_a? String
|
90
|
+
|
91
|
+
component_request.trigger_events
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class ComponentRequest
|
96
|
+
attr_reader :app, :component_class, :component_name, :component_opts, :cache
|
97
|
+
|
98
|
+
def initialize app, component_class, component_name, opts = {}
|
99
|
+
@app = app
|
100
|
+
@component_class = component_class
|
101
|
+
@component_name = component_name
|
102
|
+
@component_opts = opts
|
103
|
+
@cache = Roda::RodaCache.new
|
104
|
+
end
|
105
|
+
|
106
|
+
def on name, &block
|
107
|
+
name = name.to_s
|
108
|
+
|
109
|
+
if name == component_opts[:call].to_s
|
110
|
+
throw :halt, yield(component_opts[:locals] || {})
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def display &block
|
115
|
+
on 'display', &block
|
116
|
+
end
|
117
|
+
|
118
|
+
def html &block
|
119
|
+
class_cache[:html_loaded] ||= begin
|
120
|
+
comp_cache[:html] ||= yield
|
121
|
+
true
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def setup &block
|
126
|
+
class_cache[:ran_setup] ||= begin
|
127
|
+
block.call comp_dom, comp_tmpl
|
128
|
+
true
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def dom
|
133
|
+
cache[:dom] ||= comp_cache[:dom].dup
|
134
|
+
end
|
135
|
+
|
136
|
+
def dom_html
|
137
|
+
dom.to_html
|
138
|
+
end
|
139
|
+
|
140
|
+
def tmpl name
|
141
|
+
(cache[:tmpl] ||= {}).fetch(name){ comp_tmpl.fetch(name).dup }
|
142
|
+
end
|
143
|
+
|
144
|
+
def set_tmpl name, value, keep = false
|
145
|
+
comp_tmpl[name] = value
|
146
|
+
value.remove unless keep
|
147
|
+
end
|
148
|
+
|
149
|
+
def trigger_events
|
150
|
+
trigger component_opts.dup.delete(:call), component_opts
|
151
|
+
end
|
152
|
+
|
153
|
+
def trigger event, opts = {}
|
154
|
+
event = event.to_s
|
155
|
+
|
156
|
+
if opts.key?(:for)
|
157
|
+
name = opts.delete(:for).to_s
|
158
|
+
else
|
159
|
+
name = component_name
|
160
|
+
end
|
161
|
+
|
162
|
+
if events = class_cache[:events][name]
|
163
|
+
(events[event] || []).each do |e|
|
164
|
+
if component_opts[:call] != e[:call]
|
165
|
+
e_opts = opts.dup.merge({call: e[:call]})
|
166
|
+
app.component e[:component], e_opts
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
private
|
173
|
+
|
174
|
+
def comp_dom
|
175
|
+
comp_cache[:dom] ||= Nokogiri::HTML(comp_cache[:html])
|
176
|
+
end
|
177
|
+
|
178
|
+
def comp_tmpl
|
179
|
+
comp_cache[:tmpl] ||= {}
|
180
|
+
end
|
181
|
+
|
182
|
+
def class_cache
|
183
|
+
component_class.send(:cache)
|
184
|
+
end
|
185
|
+
|
186
|
+
def component_cache
|
187
|
+
class_cache["#{component_name}_cache"] ||= {}
|
188
|
+
end
|
189
|
+
alias :comp_cache :component_cache
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
register_plugin(:components, Components)
|
194
|
+
end
|
195
|
+
end
|
data/lib/roda/plugins/version.rb
CHANGED
data/test/assets_test.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
require 'tilt'
|
4
|
+
require 'tilt/sass'
|
5
|
+
require 'tilt/coffee'
|
6
|
+
|
7
|
+
setup do
|
8
|
+
app :bare do
|
9
|
+
plugin(:assets, {
|
10
|
+
path: './test/dummy/assets',
|
11
|
+
css_engine: 'scss',
|
12
|
+
js_engine: 'coffee',
|
13
|
+
headers: {
|
14
|
+
"Cache-Control" => 'public, max-age=2592000, no-transform',
|
15
|
+
'Connection' => 'keep-alive',
|
16
|
+
'Age' => '25637',
|
17
|
+
'Strict-Transport-Security' => 'max-age=31536000',
|
18
|
+
'Content-Disposition' => 'inline'
|
19
|
+
}
|
20
|
+
})
|
21
|
+
|
22
|
+
assets_opts[:css] = ['app', '../raw.css']
|
23
|
+
assets_opts[:js] = { head: ['app'] }
|
24
|
+
|
25
|
+
route do |r|
|
26
|
+
r.assets
|
27
|
+
|
28
|
+
r.is 'test' do
|
29
|
+
response.write assets :css
|
30
|
+
response.write assets [:js, :head]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
scope 'assets' do
|
37
|
+
test 'config' do |app|
|
38
|
+
assert app.assets_opts[:path] == './test/dummy/assets'
|
39
|
+
assert app.assets_opts[:css].include? 'app'
|
40
|
+
end
|
41
|
+
|
42
|
+
test 'middleware/render' do |app|
|
43
|
+
assert body('/assets/css/app.css')['color: red']
|
44
|
+
assert body('/assets/css/raw.css')['color: blue']
|
45
|
+
assert body('/assets/js/head/app.js')['console.log']
|
46
|
+
end
|
47
|
+
|
48
|
+
test 'instance_methods' do |app|
|
49
|
+
html = body '/test'
|
50
|
+
assert html['link']
|
51
|
+
assert html['script']
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
setup do
|
5
|
+
app :bare do
|
6
|
+
plugin :components
|
7
|
+
|
8
|
+
component(:foo, ['world']) do |c|
|
9
|
+
c.display do
|
10
|
+
'bar'
|
11
|
+
end
|
12
|
+
|
13
|
+
c.on 'bar' do
|
14
|
+
'foo'
|
15
|
+
end
|
16
|
+
|
17
|
+
c.on 'test' do
|
18
|
+
c.trigger 'world'
|
19
|
+
'foo'
|
20
|
+
end
|
21
|
+
|
22
|
+
c.on 'world' do
|
23
|
+
'hello'
|
24
|
+
end
|
25
|
+
|
26
|
+
c.on 'dom' do
|
27
|
+
c.dom_html
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
events = [
|
32
|
+
{respond_to: 'test', for: :foo, with: 'foo_test'},
|
33
|
+
{respond_to: 'world', for: :foo},
|
34
|
+
]
|
35
|
+
|
36
|
+
component(:bar, events) do |c|
|
37
|
+
c.on 'foo_test' do
|
38
|
+
'bar'
|
39
|
+
end
|
40
|
+
|
41
|
+
c.on 'world' do
|
42
|
+
'world'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
route do |r|
|
47
|
+
r.root do
|
48
|
+
component(:foo)
|
49
|
+
end
|
50
|
+
|
51
|
+
r.on 'bar' do
|
52
|
+
component(:foo, call: :bar)
|
53
|
+
end
|
54
|
+
|
55
|
+
r.on 'test' do
|
56
|
+
component(:foo, call: 'test')
|
57
|
+
end
|
58
|
+
|
59
|
+
r.on 'dom' do
|
60
|
+
component(:foo, call: :dom)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
scope 'components' do
|
67
|
+
test '#routing' do
|
68
|
+
assert body['bar']
|
69
|
+
assert !body['foo']
|
70
|
+
assert body('/bar')['foo']
|
71
|
+
assert !body('/bar')['bar']
|
72
|
+
end
|
73
|
+
|
74
|
+
test '#before' do |app|
|
75
|
+
app.setup_component(:foo) do |c|
|
76
|
+
c.html do
|
77
|
+
<<-EOF
|
78
|
+
<html>
|
79
|
+
<body>
|
80
|
+
<div class='before'>before</div>
|
81
|
+
</body>
|
82
|
+
<html>
|
83
|
+
EOF
|
84
|
+
end
|
85
|
+
|
86
|
+
c.setup do |dom|
|
87
|
+
dom.at('body').add_child '<div>after</div>'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
body = body('/dom')
|
92
|
+
assert body['before']
|
93
|
+
assert body['after']
|
94
|
+
end
|
95
|
+
|
96
|
+
test 'events' do |app|
|
97
|
+
assert body('/test')['helloworldfoobar']
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
body { color: red; }
|
@@ -0,0 +1 @@
|
|
1
|
+
console.log 'test'
|
@@ -0,0 +1 @@
|
|
1
|
+
body { color: blue; }
|
data/test/helper.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
lib = File.expand_path('../../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
require 'roda'
|
5
|
+
|
6
|
+
after do
|
7
|
+
@app = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
module Kernel
|
11
|
+
private
|
12
|
+
|
13
|
+
def app(type=nil, &block)
|
14
|
+
case type
|
15
|
+
when :new
|
16
|
+
@app = _app{route(&block)}
|
17
|
+
when :bare
|
18
|
+
@app = _app(&block)
|
19
|
+
when Symbol
|
20
|
+
@app = _app do
|
21
|
+
plugin type
|
22
|
+
route(&block)
|
23
|
+
end
|
24
|
+
else
|
25
|
+
@app ||= _app{route(&block)}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def req(path='/', env={})
|
30
|
+
if path.is_a?(Hash)
|
31
|
+
env = path
|
32
|
+
else
|
33
|
+
env['PATH_INFO'] = path
|
34
|
+
end
|
35
|
+
|
36
|
+
env = {"REQUEST_METHOD" => "GET", "PATH_INFO" => "/", "SCRIPT_NAME" => ""}.merge(env)
|
37
|
+
@app.call(env)
|
38
|
+
end
|
39
|
+
|
40
|
+
def status(path='/', env={})
|
41
|
+
req(path, env)[0]
|
42
|
+
end
|
43
|
+
|
44
|
+
def header(name, path='/', env={})
|
45
|
+
req(path, env)[1][name]
|
46
|
+
end
|
47
|
+
|
48
|
+
def body(path='/', env={})
|
49
|
+
req(path, env)[2].join
|
50
|
+
end
|
51
|
+
|
52
|
+
def _app(&block)
|
53
|
+
c = Class.new(Roda)
|
54
|
+
c.class_eval(&block)
|
55
|
+
c
|
56
|
+
end
|
57
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roda-plugins
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- cj
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-03 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Plugins for Roda
|
14
14
|
email:
|
@@ -17,15 +17,24 @@ executables: []
|
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
-
- .
|
21
|
-
-
|
20
|
+
- ".gems"
|
21
|
+
- ".gitignore"
|
22
|
+
- ".ruby-version"
|
22
23
|
- LICENSE.txt
|
24
|
+
- Makefile
|
23
25
|
- README.md
|
24
|
-
- Rakefile
|
25
26
|
- lib/roda/plugins.rb
|
27
|
+
- lib/roda/plugins/assets.rb
|
28
|
+
- lib/roda/plugins/components.rb
|
26
29
|
- lib/roda/plugins/root.rb
|
27
30
|
- lib/roda/plugins/version.rb
|
28
31
|
- roda-plugins.gemspec
|
32
|
+
- test/assets_test.rb
|
33
|
+
- test/components_test.rb
|
34
|
+
- test/dummy/assets/css/app.scss
|
35
|
+
- test/dummy/assets/js/head/app.coffee
|
36
|
+
- test/dummy/assets/raw.css
|
37
|
+
- test/helper.rb
|
29
38
|
homepage: ''
|
30
39
|
licenses:
|
31
40
|
- MIT
|
@@ -36,19 +45,24 @@ require_paths:
|
|
36
45
|
- lib
|
37
46
|
required_ruby_version: !ruby/object:Gem::Requirement
|
38
47
|
requirements:
|
39
|
-
- -
|
48
|
+
- - ">="
|
40
49
|
- !ruby/object:Gem::Version
|
41
50
|
version: '0'
|
42
51
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
52
|
requirements:
|
44
|
-
- -
|
53
|
+
- - ">="
|
45
54
|
- !ruby/object:Gem::Version
|
46
55
|
version: '0'
|
47
56
|
requirements: []
|
48
57
|
rubyforge_project:
|
49
|
-
rubygems_version: 2.
|
58
|
+
rubygems_version: 2.2.2
|
50
59
|
signing_key:
|
51
60
|
specification_version: 4
|
52
61
|
summary: Plugins for Roda.
|
53
|
-
test_files:
|
54
|
-
|
62
|
+
test_files:
|
63
|
+
- test/assets_test.rb
|
64
|
+
- test/components_test.rb
|
65
|
+
- test/dummy/assets/css/app.scss
|
66
|
+
- test/dummy/assets/js/head/app.coffee
|
67
|
+
- test/dummy/assets/raw.css
|
68
|
+
- test/helper.rb
|
data/Gemfile
DELETED
data/Rakefile
DELETED