roda-component 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gems +5 -0
- data/.gitignore +3 -0
- data/.ruby-version +1 -0
- data/Makefile +44 -0
- data/lib/roda/component/dom.rb +84 -0
- data/lib/roda/component/events.rb +76 -0
- data/lib/roda/component/version.rb +1 -1
- data/lib/roda/component.rb +179 -2
- data/lib/roda/plugins/component.rb +162 -0
- data/roda-component.gemspec +4 -0
- data/test/component_test.rb +11 -0
- data/test/dummy/app.rb +21 -0
- data/test/dummy/components/form.rb +3 -0
- data/test/dummy/components/layout.rb +11 -0
- data/test/dummy/public/index.html +8 -0
- data/test/helper.rb +63 -0
- metadata +77 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 95f5fccbca82cb752d424a9b2e0987ec07bfca2e
|
4
|
+
data.tar.gz: bdc28e2ada9efc593d92dd6688138f3b083711e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bb6088580e10be47d06aeeb12bff00f50069724bcb4f77e708e7e5b69c29aa17c5e2219d9d4aadd6b14e90fa69f7e00cf1a0c81b98668451dff2fc69544274b
|
7
|
+
data.tar.gz: 8ad3c54ca9685f83f918f92d0b114530a788193e6c7a7365df410f5f1268c648f6ec7c4f6e55ab0cb499702b6bfd64e393f4fe706583dbbbcc416f35be8795c8
|
data/.gems
ADDED
data/.gitignore
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.3
|
data/Makefile
ADDED
@@ -0,0 +1,44 @@
|
|
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
|
+
endef
|
25
|
+
|
26
|
+
install:
|
27
|
+
$(call install_bs)
|
28
|
+
bs dep install
|
29
|
+
bs gem cleanup
|
30
|
+
|
31
|
+
test:
|
32
|
+
bs env $$(cat .env.test) cutest test/**/*_test.rb
|
33
|
+
|
34
|
+
package: $(GEM)
|
35
|
+
|
36
|
+
# Always build the gem
|
37
|
+
$(GEM):
|
38
|
+
gem build $(PROJECT).gemspec
|
39
|
+
|
40
|
+
publish: $(GEM)
|
41
|
+
gem push $(GEM)
|
42
|
+
rm $(GEM)
|
43
|
+
git tag -a $(VERSION)
|
44
|
+
git push
|
@@ -0,0 +1,84 @@
|
|
1
|
+
unless RUBY_ENGINE == 'opal'
|
2
|
+
require 'nokogiri'
|
3
|
+
end
|
4
|
+
|
5
|
+
class Roda
|
6
|
+
class Component
|
7
|
+
class DOM
|
8
|
+
attr_accessor :dom
|
9
|
+
|
10
|
+
def initialize dom
|
11
|
+
@dom = dom
|
12
|
+
end
|
13
|
+
|
14
|
+
def find string, &block
|
15
|
+
if server?
|
16
|
+
@node = dom.css string
|
17
|
+
else
|
18
|
+
@node = dom.find string
|
19
|
+
end
|
20
|
+
|
21
|
+
if block
|
22
|
+
if server?
|
23
|
+
@node.each do |node|
|
24
|
+
block.call node
|
25
|
+
end
|
26
|
+
else
|
27
|
+
block.call @node
|
28
|
+
end
|
29
|
+
else
|
30
|
+
if server?
|
31
|
+
@node = @node.first
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def html= content
|
39
|
+
if server?
|
40
|
+
@node.inner_html = content
|
41
|
+
else
|
42
|
+
@node.html content
|
43
|
+
end
|
44
|
+
|
45
|
+
@node
|
46
|
+
end
|
47
|
+
|
48
|
+
def html content = false
|
49
|
+
if !content
|
50
|
+
if server?
|
51
|
+
@node ? @node.to_html : dom.to_html
|
52
|
+
else
|
53
|
+
@node ? @node.html : dom.html
|
54
|
+
end
|
55
|
+
else
|
56
|
+
self.html = content
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# This allows you to use all the nokogiri or opal jquery methods if a
|
61
|
+
# global one isn't set
|
62
|
+
def method_missing method, *args, &block
|
63
|
+
# respond_to?(symbol, include_all=false)
|
64
|
+
if dom.respond_to? method, true
|
65
|
+
dom.send method, *args, &block
|
66
|
+
else
|
67
|
+
super
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def server? &block
|
74
|
+
RUBY_ENGINE == 'ruby'
|
75
|
+
end
|
76
|
+
alias :server :server?
|
77
|
+
|
78
|
+
def client?
|
79
|
+
RUBY_ENGINE == 'opal'
|
80
|
+
end
|
81
|
+
alias :client :client?
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class Roda
|
2
|
+
class Component
|
3
|
+
class Events < Struct.new(:klass, :component_opts, :scope)
|
4
|
+
def on name, options = {}, &block
|
5
|
+
class_name = options.delete(:for) || klass._name
|
6
|
+
class_events = (events[class_name] ||= {})
|
7
|
+
event = (class_events[name] ||= [])
|
8
|
+
event << [block, klass._name, options]
|
9
|
+
end
|
10
|
+
|
11
|
+
def trigger name, options = {}
|
12
|
+
content = ''
|
13
|
+
|
14
|
+
events[klass._name][name].each do |event|
|
15
|
+
block, comp, _ = event
|
16
|
+
|
17
|
+
response = Instance.new(component(comp), scope).instance_exec options, &block
|
18
|
+
|
19
|
+
if response.is_a? Roda::Component::DOM
|
20
|
+
content = response.to_html
|
21
|
+
elsif response.is_a? String
|
22
|
+
content = response.to_s
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
content
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def component comp
|
32
|
+
if server?
|
33
|
+
Object.const_get(component_opts[:class_name][comp]).new scope
|
34
|
+
else
|
35
|
+
component_opts[:comp][comp]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def events
|
40
|
+
component_opts[:events]
|
41
|
+
end
|
42
|
+
|
43
|
+
def server?
|
44
|
+
RUBY_ENGINE == 'ruby'
|
45
|
+
end
|
46
|
+
alias :server :server?
|
47
|
+
|
48
|
+
def client?
|
49
|
+
RUBY_ENGINE == 'opal'
|
50
|
+
end
|
51
|
+
alias :client :client?
|
52
|
+
|
53
|
+
class Instance < Struct.new(:instance, :scope)
|
54
|
+
def method_missing method, *args, &block
|
55
|
+
if instance.respond_to? method, true
|
56
|
+
instance.send method, *args, &block
|
57
|
+
elsif server && scope.respond_to?(method, true)
|
58
|
+
scope.send method, *args, &block
|
59
|
+
else
|
60
|
+
super
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def server?
|
65
|
+
RUBY_ENGINE == 'ruby'
|
66
|
+
end
|
67
|
+
alias :server :server?
|
68
|
+
|
69
|
+
def client?
|
70
|
+
RUBY_ENGINE == 'opal'
|
71
|
+
end
|
72
|
+
alias :client :client?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/roda/component.rb
CHANGED
@@ -1,7 +1,184 @@
|
|
1
|
-
require
|
1
|
+
require 'opal'
|
2
|
+
require 'opal-jquery'
|
3
|
+
require "base64"
|
4
|
+
require 'roda/component/dom'
|
5
|
+
require 'roda/component/events'
|
6
|
+
|
7
|
+
if RUBY_ENGINE == 'opal'
|
8
|
+
$component_opts ||= {
|
9
|
+
events: {},
|
10
|
+
comp: {},
|
11
|
+
cache: {}
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
2
15
|
|
3
16
|
class Roda
|
4
17
|
class Component
|
5
|
-
|
18
|
+
VERSION = "0.0.1"
|
19
|
+
|
20
|
+
attr_accessor :scope
|
21
|
+
|
22
|
+
def initialize(scope = false)
|
23
|
+
@scope = scope
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
attr_accessor :_name
|
28
|
+
|
29
|
+
if RUBY_ENGINE == 'ruby'
|
30
|
+
def inherited(subclass)
|
31
|
+
super
|
32
|
+
# We want to set the app for all sub classes
|
33
|
+
subclass.set_app app
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# The name of the component
|
38
|
+
def name _name
|
39
|
+
if server?
|
40
|
+
component_opts[:class_name][_name] = self.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
@_name = _name
|
44
|
+
end
|
45
|
+
|
46
|
+
# The html source
|
47
|
+
def html _html, &block
|
48
|
+
if server?
|
49
|
+
if _html.is_a? String
|
50
|
+
cache[:html] = File.read _html
|
51
|
+
else
|
52
|
+
cache[:html] = yield
|
53
|
+
end
|
54
|
+
|
55
|
+
cache[:dom] = Nokogiri::HTML cache[:html]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# setup your dom
|
60
|
+
def setup &block
|
61
|
+
block.call cache[:dom] if server?
|
62
|
+
end
|
63
|
+
alias :clean :setup
|
64
|
+
|
65
|
+
def events
|
66
|
+
@_events ||= Events.new self, component_opts, false
|
67
|
+
end
|
68
|
+
|
69
|
+
def on *args, &block
|
70
|
+
events.on(*args, &block)
|
71
|
+
end
|
72
|
+
|
73
|
+
# cache for class
|
74
|
+
def cache
|
75
|
+
unless @_cache
|
76
|
+
@_cache ||= Roda::RodaCache.new
|
77
|
+
@_cache[:tmpl] = {}
|
78
|
+
end
|
79
|
+
|
80
|
+
@_cache
|
81
|
+
end
|
82
|
+
|
83
|
+
# set the current roda app
|
84
|
+
def set_app app
|
85
|
+
@_app = app.respond_to?(:new) ? app.new : app
|
86
|
+
end
|
87
|
+
|
88
|
+
# roda app method
|
89
|
+
def app
|
90
|
+
@_app ||= {}
|
91
|
+
end
|
92
|
+
|
93
|
+
# We need to save the nokogiri dom and the raw html.
|
94
|
+
# the reason we ave the raw html is so that we can use it client side.
|
95
|
+
def tmpl name, dom, remove = true
|
96
|
+
cache[:tmpl][name] = {
|
97
|
+
dom: remove ? dom.remove : dom
|
98
|
+
}
|
99
|
+
cache[:tmpl][name][:html] = cache[:tmpl][name][:dom].to_html
|
100
|
+
cache[:tmpl][name]
|
101
|
+
end
|
102
|
+
alias :add_tmpl :tmpl
|
103
|
+
alias :set_tmpl :tmpl
|
104
|
+
|
105
|
+
# shortcut to comp opts
|
106
|
+
def component_opts
|
107
|
+
if server?
|
108
|
+
app.component_opts
|
109
|
+
else
|
110
|
+
$component_opts
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def server?
|
117
|
+
RUBY_ENGINE == 'ruby'
|
118
|
+
end
|
119
|
+
|
120
|
+
def client?
|
121
|
+
RUBY_ENGINE == 'opal'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def cache
|
126
|
+
@_cache ||= self.class.cache.dup
|
127
|
+
end
|
128
|
+
|
129
|
+
def cache= new_cache
|
130
|
+
@_cache = new_cache
|
131
|
+
end
|
132
|
+
|
133
|
+
def events
|
134
|
+
@_events ||= Events.new self.class, component_opts, scope
|
135
|
+
end
|
136
|
+
|
137
|
+
def dom
|
138
|
+
d = cache[:dom] || begin
|
139
|
+
if server?
|
140
|
+
Nokogiri::HTML cache[:html]
|
141
|
+
else
|
142
|
+
Element
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
DOM.new d
|
147
|
+
end
|
148
|
+
|
149
|
+
# Grab the template from the cache, use the nokogiri dom or create a
|
150
|
+
# jquery element for server side
|
151
|
+
def tmpl name
|
152
|
+
if server?
|
153
|
+
DOM.new cache[:tmpl][name][:dom].dup
|
154
|
+
else
|
155
|
+
DOM.new Element[cache[:tmpl][name][:html].dup]
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def component_opts
|
160
|
+
self.class.component_opts
|
161
|
+
end
|
162
|
+
|
163
|
+
def trigger *args
|
164
|
+
events.trigger(*args)
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
|
169
|
+
def server?
|
170
|
+
RUBY_ENGINE == 'ruby'
|
171
|
+
end
|
172
|
+
alias :server :server?
|
173
|
+
|
174
|
+
def client?
|
175
|
+
RUBY_ENGINE == 'opal'
|
176
|
+
end
|
177
|
+
alias :client :client?
|
178
|
+
end
|
179
|
+
|
180
|
+
# This is just here to make things more cross compatible
|
181
|
+
if RUBY_ENGINE == 'opal'
|
182
|
+
RodaCache = Hash
|
6
183
|
end
|
7
184
|
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'roda/component'
|
2
|
+
require 'json'
|
3
|
+
require "base64"
|
4
|
+
|
5
|
+
class Roda
|
6
|
+
module RodaPlugins
|
7
|
+
module Component
|
8
|
+
def self.configure(app, opts={})
|
9
|
+
if app.opts[:component]
|
10
|
+
app.opts[:component].merge!(opts)
|
11
|
+
else
|
12
|
+
app.opts[:component] = opts.dup
|
13
|
+
end
|
14
|
+
|
15
|
+
opts = app.opts[:component]
|
16
|
+
opts[:cache] = app.thread_safe_cache if opts.fetch(:cache, true)
|
17
|
+
opts[:path] ||= 'components'
|
18
|
+
opts[:route] ||= 'components'
|
19
|
+
opts[:assets_route] ||= 'assets/components'
|
20
|
+
opts[:class] ||= Roda::Component
|
21
|
+
opts[:settings] ||= {}
|
22
|
+
opts[:class_name] ||= {}
|
23
|
+
opts[:events] ||= {}
|
24
|
+
opts[:cache][:tmpl] ||= {}
|
25
|
+
|
26
|
+
# Set the current app
|
27
|
+
opts[:class].set_app app
|
28
|
+
end
|
29
|
+
|
30
|
+
module InstanceMethods
|
31
|
+
def component_opts
|
32
|
+
self.class.component_opts
|
33
|
+
end
|
34
|
+
|
35
|
+
def load_component name
|
36
|
+
Object.const_get(
|
37
|
+
component_opts[:class_name][name.to_sym]
|
38
|
+
).new self
|
39
|
+
end
|
40
|
+
|
41
|
+
def load_component_js comp, action = :display
|
42
|
+
# grab a copy of the cache
|
43
|
+
cache = comp.class.cache.dup
|
44
|
+
# remove html and dom cache as we don't need that for the client
|
45
|
+
cache.delete :html
|
46
|
+
cache.delete :dom
|
47
|
+
cache.delete :cache
|
48
|
+
|
49
|
+
cache = Base64.encode64 cache.to_json
|
50
|
+
options = Base64.encode64 options.to_json
|
51
|
+
comp_name = comp.class._name
|
52
|
+
|
53
|
+
js = <<-EOF
|
54
|
+
Document.ready? do
|
55
|
+
unless $component_opts[:comp][:"#{comp_name}"]
|
56
|
+
c = $component_opts[:comp][:"#{comp_name}"] = #{comp.class}.new
|
57
|
+
c.cache = JSON.parse Base64.decode64('#{cache}')
|
58
|
+
c.#{action}(JSON.parse(Base64.decode64('#{options}')))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
EOF
|
62
|
+
|
63
|
+
("<script>" + Opal.compile(js) + "</script>")
|
64
|
+
end
|
65
|
+
|
66
|
+
def component name, options = {}, &block
|
67
|
+
comp = load_component name
|
68
|
+
|
69
|
+
action = options[:call] || 'display'
|
70
|
+
|
71
|
+
# call action
|
72
|
+
# TODO: make sure the single method parameter isn't a block
|
73
|
+
if comp.method(action).parameters.length > 0
|
74
|
+
comp_response = comp.send(action, options, &block)
|
75
|
+
else
|
76
|
+
comp_response = comp.send(action, &block)
|
77
|
+
end
|
78
|
+
|
79
|
+
if comp_response.is_a? Roda::Component::DOM
|
80
|
+
content = comp_response.to_html
|
81
|
+
else
|
82
|
+
content = comp_response.to_s
|
83
|
+
end
|
84
|
+
|
85
|
+
content += load_component_js comp, action
|
86
|
+
end
|
87
|
+
alias :comp :component
|
88
|
+
alias :roda_component :component
|
89
|
+
end
|
90
|
+
|
91
|
+
module ClassMethods
|
92
|
+
# Copy the assets options into the subclass, duping
|
93
|
+
# them as necessary to prevent changes in the subclass
|
94
|
+
# affecting the parent class.
|
95
|
+
def inherited(subclass)
|
96
|
+
super
|
97
|
+
opts = component_opts.dup
|
98
|
+
opts[:cache] = thread_safe_cache if opts[:cache]
|
99
|
+
end
|
100
|
+
|
101
|
+
def component_opts
|
102
|
+
opts[:component]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
module RequestClassMethods
|
107
|
+
def component_opts
|
108
|
+
roda_class.component_opts
|
109
|
+
end
|
110
|
+
|
111
|
+
def component_assets_route_regex
|
112
|
+
component_opts[:assets_route]
|
113
|
+
end
|
114
|
+
|
115
|
+
def component_route_regex
|
116
|
+
Regexp.new(
|
117
|
+
component_opts[:route] + "/([a-zA-Z0-9_-]*)/([a-zA-Z0-9_-]*)/([a-zA-Z0-9_-]*)"
|
118
|
+
)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
module RequestMethods
|
123
|
+
def components
|
124
|
+
on self.class.component_assets_route_regex do |component, action|
|
125
|
+
# Process the ruby code into javascript
|
126
|
+
Opal::Processor.source_map_enabled = false
|
127
|
+
env = Opal::Environment.new
|
128
|
+
# Append the gems path
|
129
|
+
env.append_path Gem::Specification.find_by_name("roda-component").gem_dir + '/lib'
|
130
|
+
js = env['roda/component'].to_s
|
131
|
+
# Append the path to the components folder
|
132
|
+
env.append_path scope.component_opts[:path]
|
133
|
+
# Loop through and and convert all the files to javascript
|
134
|
+
Dir[scope.component_opts[:path] + '/**/*.rb'].each do |file|
|
135
|
+
file = file.gsub(scope.component_opts[:path] + '/', '')
|
136
|
+
js << env[file].to_s
|
137
|
+
end
|
138
|
+
# Set the header to javascript
|
139
|
+
response.headers["Content-Type"] = 'application/javascript; charset=UTF-8'
|
140
|
+
|
141
|
+
js
|
142
|
+
end
|
143
|
+
|
144
|
+
on self.class.component_route_regex do |comp, type, action|
|
145
|
+
comp = scope.load_component(comp.to_sym)
|
146
|
+
|
147
|
+
case type
|
148
|
+
when 'call'
|
149
|
+
response.write comp.public_send action
|
150
|
+
when 'trigger'
|
151
|
+
response.write scope.load_component(comp.to_sym).events.trigger action.to_sym
|
152
|
+
end
|
153
|
+
|
154
|
+
response.write scope.load_component_js comp, action
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
register_plugin(:component, Component)
|
161
|
+
end
|
162
|
+
end
|
data/roda-component.gemspec
CHANGED
@@ -18,6 +18,10 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_runtime_dependency "opal"
|
22
|
+
spec.add_runtime_dependency "opal-jquery"
|
23
|
+
spec.add_runtime_dependency "faye"
|
24
|
+
spec.add_runtime_dependency "tilt"
|
21
25
|
spec.add_development_dependency "bundler", "~> 1.7"
|
22
26
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
27
|
end
|
data/test/dummy/app.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
class TestApp < Roda
|
2
|
+
plugin :component, {
|
3
|
+
path: './test/dummy/components'
|
4
|
+
}
|
5
|
+
|
6
|
+
route do |r|
|
7
|
+
r.components
|
8
|
+
|
9
|
+
r.on 'app' do
|
10
|
+
'working'
|
11
|
+
end
|
12
|
+
|
13
|
+
r.root do
|
14
|
+
component(:layout) do
|
15
|
+
'Hello, World!'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Dir["./test/dummy/components/*.rb"].each { |file| require file }
|
21
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
lib = File.expand_path('../../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
require 'roda'
|
5
|
+
require 'roda/component'
|
6
|
+
require_relative 'dummy/app'
|
7
|
+
|
8
|
+
before do
|
9
|
+
@app = TestApp
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
@app = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
module Kernel
|
17
|
+
private
|
18
|
+
|
19
|
+
def app(type=nil, &block)
|
20
|
+
case type
|
21
|
+
when :new
|
22
|
+
@app = _app{route(&block)}
|
23
|
+
when :bare
|
24
|
+
@app = _app(&block)
|
25
|
+
when Symbol
|
26
|
+
@app = _app do
|
27
|
+
plugin type
|
28
|
+
route(&block)
|
29
|
+
end
|
30
|
+
else
|
31
|
+
@app ||= _app{route(&block)}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def req(path='/', env={})
|
36
|
+
if path.is_a?(Hash)
|
37
|
+
env = path
|
38
|
+
else
|
39
|
+
env['PATH_INFO'] = path
|
40
|
+
end
|
41
|
+
|
42
|
+
env = {"REQUEST_METHOD" => "GET", "PATH_INFO" => "/", "SCRIPT_NAME" => ""}.merge(env)
|
43
|
+
@app.call(env)
|
44
|
+
end
|
45
|
+
|
46
|
+
def status(path='/', env={})
|
47
|
+
req(path, env)[0]
|
48
|
+
end
|
49
|
+
|
50
|
+
def header(name, path='/', env={})
|
51
|
+
req(path, env)[1][name]
|
52
|
+
end
|
53
|
+
|
54
|
+
def body(path='/', env={})
|
55
|
+
req(path, env)[2].join
|
56
|
+
end
|
57
|
+
|
58
|
+
def _app(&block)
|
59
|
+
c = Class.new(Roda)
|
60
|
+
c.class_eval(&block)
|
61
|
+
c
|
62
|
+
end
|
63
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roda-component
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
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-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: opal
|
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: opal-jquery
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: faye
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
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: tilt
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
13
69
|
- !ruby/object:Gem::Dependency
|
14
70
|
name: bundler
|
15
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -45,14 +101,26 @@ executables: []
|
|
45
101
|
extensions: []
|
46
102
|
extra_rdoc_files: []
|
47
103
|
files:
|
104
|
+
- ".gems"
|
48
105
|
- ".gitignore"
|
106
|
+
- ".ruby-version"
|
49
107
|
- Gemfile
|
50
108
|
- LICENSE.txt
|
109
|
+
- Makefile
|
51
110
|
- README.md
|
52
111
|
- Rakefile
|
53
112
|
- lib/roda/component.rb
|
113
|
+
- lib/roda/component/dom.rb
|
114
|
+
- lib/roda/component/events.rb
|
54
115
|
- lib/roda/component/version.rb
|
116
|
+
- lib/roda/plugins/component.rb
|
55
117
|
- roda-component.gemspec
|
118
|
+
- test/component_test.rb
|
119
|
+
- test/dummy/app.rb
|
120
|
+
- test/dummy/components/form.rb
|
121
|
+
- test/dummy/components/layout.rb
|
122
|
+
- test/dummy/public/index.html
|
123
|
+
- test/helper.rb
|
56
124
|
homepage: ''
|
57
125
|
licenses:
|
58
126
|
- MIT
|
@@ -77,5 +145,11 @@ rubygems_version: 2.2.2
|
|
77
145
|
signing_key:
|
78
146
|
specification_version: 4
|
79
147
|
summary: ''
|
80
|
-
test_files:
|
148
|
+
test_files:
|
149
|
+
- test/component_test.rb
|
150
|
+
- test/dummy/app.rb
|
151
|
+
- test/dummy/components/form.rb
|
152
|
+
- test/dummy/components/layout.rb
|
153
|
+
- test/dummy/public/index.html
|
154
|
+
- test/helper.rb
|
81
155
|
has_rdoc:
|