action_widget 0.5.1 → 0.6.0.pre
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/.gitignore +1 -0
- data/.travis.yml +5 -0
- data/README.md +286 -2
- data/Rakefile +4 -0
- data/action_widget.gemspec +6 -2
- data/lib/action_widget/base.rb +10 -20
- data/lib/action_widget/view_helper.rb +6 -5
- data/lib/action_widget.rb +43 -1
- data/spec/action_widget_spec.rb +45 -0
- data/spec/spec_helper.rb +82 -0
- metadata +59 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65f04e0efe22c4a80632c8bb2788b48f60c0d1d9
|
4
|
+
data.tar.gz: 2319ca299e05f2611cef8a1f420f886dcaebadfa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90bda59277298cee6d43f1e98580fd812def0f5a6de6a1066ac762a470cf04d0ef2b4dac78798e264f5cd197dc51ea13f448ba7b1371fb44e9cde66024c19efb
|
7
|
+
data.tar.gz: d715ab381e066c58275390dda86e5f1156bfba030519c8292db06fcd0ecf017a61ca3624ea00f199e97b1e6996d1f908e0891be776d0e9a3988a2ca804dc985f
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,6 +1,23 @@
|
|
1
1
|
# ActionWidget
|
2
2
|
|
3
|
-
|
3
|
+
`ActionWidget` is a light-weight widget system for [Ruby on
|
4
|
+
Rails](http://rubyonrails.com) and [Middleman](http://middlemanapp.com). It is
|
5
|
+
essentially a minimal tool set for building desktop-like UI components. The
|
6
|
+
main idea behind `ActionWidget` is the separation of the concept of an UI
|
7
|
+
component and its representation. While the representation of component might
|
8
|
+
easily change over time, the concept of a component is unlikely to change
|
9
|
+
significantly. Think of a button for instance: Most developers will agree that
|
10
|
+
a button is conceptually something that has a caption and when clicked triggers
|
11
|
+
an action. When we think about the visual representation of a button, however,
|
12
|
+
things get more complicated. While most people will agree to a certain degree
|
13
|
+
on what can visually be considered a button and what is something else, people
|
14
|
+
tend to have different ideas about a button's exact representation. There are
|
15
|
+
buttons with icons, without icons, round ones, rectangular ones, and so on.
|
16
|
+
Despite their different appearances, the functionality and in this sense the
|
17
|
+
component's concept stays the same: when clicked an action is triggered.
|
18
|
+
ActionWidget provides developers with a tool set that helps them to strictly
|
19
|
+
decouple a component's concept from its representation to support future
|
20
|
+
change.
|
4
21
|
|
5
22
|
## Installation
|
6
23
|
|
@@ -18,7 +35,274 @@ Or install it yourself as:
|
|
18
35
|
|
19
36
|
## Usage
|
20
37
|
|
21
|
-
|
38
|
+
`ActionWidget` can be used to build arbitrarily complex view components. To
|
39
|
+
illustrate the basic usage of `ActionWidget`, however, we start with a simple
|
40
|
+
example, a widget for representing a button. We then continue with widgets that
|
41
|
+
except blocks. We will use a widget representing panels as an example. Finally,
|
42
|
+
we see discuss how to build widgets that utilize widgets themselves for
|
43
|
+
constructing navigation components.
|
44
|
+
|
45
|
+
### Simple Widgets
|
46
|
+
|
47
|
+
The goal of this section is to build a widget that represents a button. The
|
48
|
+
button we are designing must have a `caption` and a `type`. The type can either
|
49
|
+
be `regular`, `accept`, or `cancel`. The button further must have a specified
|
50
|
+
`size`, which can be `small`, `medium`, or `large`. Finally, the button
|
51
|
+
requires a `target` that defines the resource it links to. `ActionWidget`
|
52
|
+
compentens utilize [SmartProperties](http://github.com/t6d/smart_properties) to
|
53
|
+
define attributes that can be configured to automatically enforce these
|
54
|
+
constraints and provide sensible defaults.
|
55
|
+
|
56
|
+
In the example below, we simple use an `<a>` tag to represent a button. The
|
57
|
+
attributes `size` and `type` are simply translated into CSS classes. The
|
58
|
+
`caption` will be used as the text encolsed by the `<a>` tag and the `target`
|
59
|
+
will be used as the value the the `<a>` tag's `href` attribute.
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
class ButtonWidget < ActionWidget::Base
|
63
|
+
property :caption,
|
64
|
+
converts: :to_s,
|
65
|
+
required: true
|
66
|
+
|
67
|
+
property :target,
|
68
|
+
converts: :to_s,
|
69
|
+
accepts: lambda { |uri| URI.parse(uri) rescue false },
|
70
|
+
required: true
|
71
|
+
|
72
|
+
property :type,
|
73
|
+
converts: :to_sym,
|
74
|
+
accepts: [:regular, :accept, :cancel],
|
75
|
+
default: :regular
|
76
|
+
|
77
|
+
property :size,
|
78
|
+
converts: :to_sym,
|
79
|
+
accepts: [:small, :medium, :large],
|
80
|
+
default: :medium
|
81
|
+
|
82
|
+
def render
|
83
|
+
content_tag(:a, caption, href: target, class: css_classes)
|
84
|
+
end
|
85
|
+
|
86
|
+
protected
|
87
|
+
|
88
|
+
def css_classes
|
89
|
+
css_classes = ['btn']
|
90
|
+
css_classes << "btn-#{size}" unless size == :regular
|
91
|
+
css_classes << "btn-#{type}" unless type == :medium
|
92
|
+
css_classes
|
93
|
+
end
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
97
|
+
By convention, a widget's class name should end in "Widget". This way,
|
98
|
+
`ActionWidget` automatically generates `ActionView` helper methods for more
|
99
|
+
convenient instantiation and rendering of a widget.
|
100
|
+
|
101
|
+
In our example, the widget can be instantiated by simply calling the helper
|
102
|
+
method `button_widget` and providing it with all necessary attributes:
|
103
|
+
|
104
|
+
```erb
|
105
|
+
<%= button_widget caption: 'Go to Admin Area', size: :small, target: '/admin' %>
|
106
|
+
```
|
107
|
+
|
108
|
+
Instead of using the provided helper method, a widget can always be instantiated
|
109
|
+
manually:
|
110
|
+
|
111
|
+
```erb
|
112
|
+
<%= ButtonWidget.new(self, caption: 'Go to Admin Area', size: :small, target: '/admin').render %>
|
113
|
+
```
|
114
|
+
|
115
|
+
In both cases, the resulting HTML looks as follows:
|
116
|
+
|
117
|
+
```html
|
118
|
+
<a class="btn btn-small" href="/admin">Go to Admin Area</a>
|
119
|
+
```
|
120
|
+
|
121
|
+
### Widgets that Accept Blocks
|
122
|
+
|
123
|
+
The panel widget we are building requires a `title` and a block that defines the
|
124
|
+
widgets content.
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
require 'action_widget'
|
128
|
+
|
129
|
+
class PanelWidget < ActionWidget::Base
|
130
|
+
property :title, required: true, converts: :to_s
|
131
|
+
|
132
|
+
def render(&block)
|
133
|
+
content_tag(:div, class: 'panel') do
|
134
|
+
content_tag(:h2, title, class: 'title') +
|
135
|
+
content_tag(:div, class: 'content', &block)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
```
|
140
|
+
|
141
|
+
Again, the automatically generated helper method, `#panel_widget` in this case,
|
142
|
+
can be used to instantiate and render the widget:
|
143
|
+
|
144
|
+
```erb
|
145
|
+
<%= panel_widget title: "Important Notice" do %>
|
146
|
+
The system will be down for maintanence today.
|
147
|
+
<% end %>
|
148
|
+
```
|
149
|
+
|
150
|
+
Executing the code above results in the follwing HTML:
|
151
|
+
|
152
|
+
```html
|
153
|
+
<div class="panel">
|
154
|
+
<h2 class="title">Important Notice</h2>
|
155
|
+
<div class="content">
|
156
|
+
The system will be down for maintanence today.
|
157
|
+
</div>
|
158
|
+
</div>
|
159
|
+
```
|
160
|
+
|
161
|
+
Since widgets are simple Ruby classes, they naturally support inheritance.
|
162
|
+
Let's assume we require a special panel widget for sidebars that renders a
|
163
|
+
different header. There are two options:
|
164
|
+
|
165
|
+
1. we can provide the tag that is chosen for the header as a property, or
|
166
|
+
2. we restructure the `PanelWidget` class and then subclass it.
|
167
|
+
|
168
|
+
Let's take the second approach and extract the header rendering and the content
|
169
|
+
rendering into their own methods so we can overwrite either one of them in a
|
170
|
+
potential subclass.
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
class PanelWidget < ActionWidget::Base
|
174
|
+
property :title, required: true, converts: :to_s
|
175
|
+
|
176
|
+
def render(&block)
|
177
|
+
header + content(&block)
|
178
|
+
end
|
179
|
+
|
180
|
+
protected
|
181
|
+
|
182
|
+
def header
|
183
|
+
content_tag(:h2, title)
|
184
|
+
end
|
185
|
+
|
186
|
+
def content(&block)
|
187
|
+
content_tag(:div, &block)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
```
|
191
|
+
|
192
|
+
After this refactoring, we are able to subclass `PanelWidget` and customize the
|
193
|
+
`header` method:
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
class SidebarPanelWidget < PanelWidget
|
197
|
+
protected
|
198
|
+
|
199
|
+
def header
|
200
|
+
content_tag(:h3, title)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
```
|
204
|
+
|
205
|
+
### Nested Widgets
|
206
|
+
|
207
|
+
Let's assume we want to implement a widget that simplifies the rendering of
|
208
|
+
navigational menus. The widget only exposes one property, `orientation`, which
|
209
|
+
can either be `horizontal` or `vertical`.
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
class MenuWidget < ActionWidget::Base
|
213
|
+
property :orientation,
|
214
|
+
accepts: [:horizontal, :vertical],
|
215
|
+
converts: :to_sym,
|
216
|
+
default: :horizontal,
|
217
|
+
required: true
|
218
|
+
|
219
|
+
def render(&block)
|
220
|
+
content_tag(:nav, class: orientation) do
|
221
|
+
content_tag(:ul) do
|
222
|
+
capture(self, &block)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
def item(caption, target)
|
228
|
+
content_tag(:li) do
|
229
|
+
content_tag(:a, caption, href: target)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def submenu(caption, &block)
|
234
|
+
content_tag(:li) do
|
235
|
+
content_tag(:span, caption) +
|
236
|
+
self.class.new(view, orientation: orientation).render(&block)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
```
|
241
|
+
|
242
|
+
The following example demonstrates how to use this widget:
|
243
|
+
|
244
|
+
```erb
|
245
|
+
<%= menu_widget do |m| %>
|
246
|
+
<%= m.item "Dashboard", "/" %>
|
247
|
+
<%= m.submenu "Admin" do |m| %>
|
248
|
+
<%= m.item "Manage Users", "/admin/users" %>
|
249
|
+
<%= m.item "Manage Groups", "/admin/groups" %>
|
250
|
+
<% end %>
|
251
|
+
<% end %>
|
252
|
+
```
|
253
|
+
|
254
|
+
Executing the code above, will result in the following HTML being generated:
|
255
|
+
|
256
|
+
```html
|
257
|
+
<nav class="horizontal">
|
258
|
+
<ul>
|
259
|
+
<li> <a href="/">Dashboard</a> </li>
|
260
|
+
<li>
|
261
|
+
<span>Admin</span>
|
262
|
+
<nav class="horizontal">
|
263
|
+
<ul>
|
264
|
+
<li><a href="/admin/users">Manage Users</a></li>
|
265
|
+
<li><a href="/admin/groups">Manage Groups</a></li>
|
266
|
+
</ul>
|
267
|
+
</nav>
|
268
|
+
</li>
|
269
|
+
</ul>
|
270
|
+
</nav>
|
271
|
+
```
|
272
|
+
|
273
|
+
### Option Capturing and Positional Argument Forwarding
|
274
|
+
|
275
|
+
`ActionWidget` instances capture all initializer keyword
|
276
|
+
arguments that do not correspond to a property in a general `options` hash.
|
277
|
+
All positional arguments supplied to an autogenerated helper are
|
278
|
+
forwarded to the `render` method.
|
279
|
+
|
280
|
+
```ruby
|
281
|
+
class ParagraphWidget < ActionWidget::Base
|
282
|
+
def render(content, &block)
|
283
|
+
content = capture(&block) if block
|
284
|
+
content_tag(:p, content, class: options[:class])
|
285
|
+
end
|
286
|
+
end
|
287
|
+
```
|
288
|
+
|
289
|
+
This widget can be used in the following two ways:
|
290
|
+
|
291
|
+
```erb
|
292
|
+
<%= paragraph_widget("Some content", class: 'important') %>
|
293
|
+
|
294
|
+
<%= paragraph_widget(class: 'important') do %>
|
295
|
+
Some content
|
296
|
+
<% end %>
|
297
|
+
```
|
298
|
+
|
299
|
+
In both cases, the resulting HTML reads as follows:
|
300
|
+
|
301
|
+
```html
|
302
|
+
<p class="important">
|
303
|
+
Some content
|
304
|
+
</p>
|
305
|
+
```
|
22
306
|
|
23
307
|
## Contributing
|
24
308
|
|
data/Rakefile
CHANGED
data/action_widget.gemspec
CHANGED
@@ -10,7 +10,11 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
11
11
|
gem.name = "action_widget"
|
12
12
|
gem.require_paths = ["lib"]
|
13
|
-
gem.version = "0.
|
13
|
+
gem.version = "0.6.0.pre"
|
14
14
|
|
15
|
-
gem.add_dependency 'smart_properties', '~> 1.
|
15
|
+
gem.add_dependency 'smart_properties', '~> 1.10'
|
16
|
+
|
17
|
+
gem.add_development_dependency 'rake', '~> 10.0'
|
18
|
+
gem.add_development_dependency 'rspec', '~> 3.3'
|
19
|
+
gem.add_development_dependency 'actionview', '~> 4.0'
|
16
20
|
end
|
data/lib/action_widget/base.rb
CHANGED
@@ -1,31 +1,21 @@
|
|
1
|
-
require 'smart_properties'
|
2
|
-
|
3
1
|
module ActionWidget
|
4
|
-
class Base
|
2
|
+
class Base < SimpleDelegator
|
3
|
+
alias view __getobj__
|
5
4
|
include SmartProperties
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
attr_reader :options
|
7
|
+
|
8
|
+
def initialize(view, attributes = {})
|
9
|
+
properties = self.class.properties
|
10
|
+
attributes, options = attributes.partition { |name, value| properties.key?(name) }
|
11
|
+
|
12
|
+
@options = Hash[options]
|
13
|
+
super(view, Hash[attributes])
|
10
14
|
end
|
11
15
|
|
12
16
|
def render
|
13
17
|
raise NotImplementedError, "#{self.class} must implement #render"
|
14
18
|
end
|
15
|
-
|
16
|
-
protected
|
17
|
-
|
18
|
-
attr_reader :view
|
19
|
-
|
20
|
-
undef :capture if method_defined?(:capture)
|
21
|
-
|
22
|
-
def method_missing(method, *args, &block)
|
23
|
-
view.send(method, *args, &block)
|
24
|
-
rescue NoMethodError
|
25
|
-
# Double check - the NoMethodError might have occurred somewhere else.
|
26
|
-
view.respond_to?(method) ? raise : super
|
27
|
-
end
|
28
|
-
|
29
19
|
end
|
30
20
|
end
|
31
21
|
|
@@ -2,18 +2,19 @@ module ActionWidget
|
|
2
2
|
module ViewHelper
|
3
3
|
|
4
4
|
def method_missing(name, *args, &block)
|
5
|
-
return super unless name
|
5
|
+
return super unless ActionWidget.helper?(name)
|
6
6
|
|
7
7
|
klass = begin
|
8
|
-
|
8
|
+
ActionWidget.class_for(name)
|
9
9
|
rescue NameError, LoadError
|
10
10
|
return super
|
11
11
|
end
|
12
12
|
|
13
13
|
ActionWidget::ViewHelper.module_eval <<-RUBY
|
14
|
-
def #{name}(*args, &block)
|
15
|
-
|
16
|
-
|
14
|
+
def #{name}(*args, &block) # def example_widget(*args, &block)
|
15
|
+
attrs = args.last.kind_of?(Hash) ? args.pop : {}
|
16
|
+
#{klass}.new(self, attrs).render(*args, &block) # ExampleWidget.new(self, attrs).render(*args, &block)
|
17
|
+
end # end
|
17
18
|
RUBY
|
18
19
|
|
19
20
|
send(name, *args, &block)
|
data/lib/action_widget.rb
CHANGED
@@ -1,3 +1,45 @@
|
|
1
|
+
require 'smart_properties'
|
2
|
+
|
3
|
+
module ActionWidget
|
4
|
+
class Configuration
|
5
|
+
include SmartProperties
|
6
|
+
property :prefix
|
7
|
+
property :suffix
|
8
|
+
|
9
|
+
attr_reader :pattern
|
10
|
+
|
11
|
+
def initialize(*)
|
12
|
+
super
|
13
|
+
|
14
|
+
@pattern = Regexp.new([
|
15
|
+
(prefix.underscore if prefix.presence),
|
16
|
+
"(.*)",
|
17
|
+
(suffix.underscore if suffix.presence)
|
18
|
+
].compact.join("_"))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def configuration
|
24
|
+
@configuration ||= Configuration.new(suffix: "Widget")
|
25
|
+
end
|
26
|
+
|
27
|
+
def configure(&block)
|
28
|
+
@configuration = Configuration.new(&block)
|
29
|
+
end
|
30
|
+
|
31
|
+
def helper?(name)
|
32
|
+
!!configuration.pattern.match(name)
|
33
|
+
end
|
34
|
+
|
35
|
+
def class_for(helper_name)
|
36
|
+
basename = configuration.pattern.match(helper_name)[1]
|
37
|
+
classname = [configuration.prefix, basename.camelcase, configuration.suffix].join("")
|
38
|
+
classname.constantize
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
1
43
|
require 'action_widget/base'
|
2
44
|
require 'action_widget/view_helper'
|
3
|
-
require 'action_widget/extensions'
|
45
|
+
require 'action_widget/extensions'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class DummyWidget < ActionWidget::Base
|
4
|
+
property :type
|
5
|
+
|
6
|
+
def render(content = nil)
|
7
|
+
classes = [options[:class], type].compact
|
8
|
+
if classes.empty?
|
9
|
+
content_tag(:p, content)
|
10
|
+
else
|
11
|
+
content_tag(:p, content, class: classes)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class ViewContext < ActionView::Base
|
17
|
+
include ActionWidget::ViewHelper
|
18
|
+
end
|
19
|
+
|
20
|
+
RSpec.describe DummyWidget do
|
21
|
+
let(:view) { ViewContext.new }
|
22
|
+
|
23
|
+
it "should delegate unknown method calls to the view context" do
|
24
|
+
expect(described_class.new(view).render).to eq("<p></p>")
|
25
|
+
end
|
26
|
+
|
27
|
+
context "option capturing and positional argument forwarding" do
|
28
|
+
let(:expected_html) { '<p class="wide teaser">Hello World</p>' }
|
29
|
+
|
30
|
+
it "should be possible to reference a property using a symbol" do
|
31
|
+
attributes = {type: 'teaser', class: 'wide'}
|
32
|
+
expect(view.dummy_widget("Hello World", attributes)).to eq(expected_html)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should be possible to reference a property using a string" do
|
36
|
+
attributes = {"type" => 'teaser', class: 'wide'}
|
37
|
+
expect(view.dummy_widget("Hello World", attributes)).to eq(expected_html)
|
38
|
+
end
|
39
|
+
|
40
|
+
specify "keyword arguments that do not correspond to a property should be captured as options" do
|
41
|
+
instance = described_class.new(view, class: 'wide')
|
42
|
+
expect(instance.options).to eq({class: 'wide'})
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'rspec'
|
3
|
+
require 'action_view'
|
4
|
+
|
5
|
+
require 'action_widget'
|
6
|
+
|
7
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
8
|
+
RSpec.configure do |config|
|
9
|
+
# rspec-expectations config goes here. You can use an alternate
|
10
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
11
|
+
# assertions if you prefer.
|
12
|
+
config.expect_with :rspec do |expectations|
|
13
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
14
|
+
# and `failure_message` of custom matchers include text for helper methods
|
15
|
+
# defined using `chain`, e.g.:
|
16
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
17
|
+
# # => "be bigger than 2 and smaller than 4"
|
18
|
+
# ...rather than:
|
19
|
+
# # => "be bigger than 2"
|
20
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
21
|
+
end
|
22
|
+
|
23
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
24
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
25
|
+
config.mock_with :rspec do |mocks|
|
26
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
27
|
+
# a real object. This is generally recommended, and will default to
|
28
|
+
# `true` in RSpec 4.
|
29
|
+
mocks.verify_partial_doubles = true
|
30
|
+
end
|
31
|
+
|
32
|
+
# These two settings work together to allow you to limit a spec run
|
33
|
+
# to individual examples or groups you care about by tagging them with
|
34
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
35
|
+
# get run.
|
36
|
+
config.filter_run :focus
|
37
|
+
config.run_all_when_everything_filtered = true
|
38
|
+
|
39
|
+
# Allows RSpec to persist some state between runs in order to support
|
40
|
+
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
41
|
+
# you configure your source control system to ignore this file.
|
42
|
+
#
|
43
|
+
# config.example_status_persistence_file_path = "spec/examples.txt"
|
44
|
+
|
45
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
46
|
+
# recommended. For more details, see:
|
47
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
48
|
+
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
49
|
+
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
50
|
+
config.disable_monkey_patching!
|
51
|
+
|
52
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
53
|
+
# be too noisy due to issues in dependencies.
|
54
|
+
config.warnings = true
|
55
|
+
|
56
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
57
|
+
# file, and it's useful to allow more verbose output when running an
|
58
|
+
# individual spec file.
|
59
|
+
if config.files_to_run.one?
|
60
|
+
# Use the documentation formatter for detailed output,
|
61
|
+
# unless a formatter has already been configured
|
62
|
+
# (e.g. via a command-line flag).
|
63
|
+
config.default_formatter = 'doc'
|
64
|
+
end
|
65
|
+
|
66
|
+
# Print the 10 slowest examples and example groups at the
|
67
|
+
# end of the spec run, to help surface which specs are running
|
68
|
+
# particularly slow.
|
69
|
+
config.profile_examples = 10
|
70
|
+
|
71
|
+
# Run specs in random order to surface order dependencies. If you find an
|
72
|
+
# order dependency and want to debug it, you can fix the order by providing
|
73
|
+
# the seed, which is printed after each run.
|
74
|
+
# --seed 1234
|
75
|
+
config.order = :random
|
76
|
+
|
77
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
78
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
79
|
+
# test failures related to randomization by passing the same `--seed` value
|
80
|
+
# as the one that triggered the failure.
|
81
|
+
Kernel.srand config.seed
|
82
|
+
end
|
metadata
CHANGED
@@ -1,29 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: action_widget
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Tennhard
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-10-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: smart_properties
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.10'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: actionview
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.0'
|
27
69
|
description:
|
28
70
|
email:
|
29
71
|
- me@t6d.de
|
@@ -31,7 +73,8 @@ executables: []
|
|
31
73
|
extensions: []
|
32
74
|
extra_rdoc_files: []
|
33
75
|
files:
|
34
|
-
- .gitignore
|
76
|
+
- ".gitignore"
|
77
|
+
- ".travis.yml"
|
35
78
|
- Gemfile
|
36
79
|
- LICENSE
|
37
80
|
- README.md
|
@@ -45,6 +88,8 @@ files:
|
|
45
88
|
- lib/action_widget/extensions/rails/generators.rb
|
46
89
|
- lib/action_widget/extensions/rails/railtie.rb
|
47
90
|
- lib/action_widget/view_helper.rb
|
91
|
+
- spec/action_widget_spec.rb
|
92
|
+
- spec/spec_helper.rb
|
48
93
|
- support/templates/widget.rb.erb
|
49
94
|
- support/templates/widget_spec.rb.erb
|
50
95
|
homepage: http://github.com/t6d/action_widget
|
@@ -56,19 +101,21 @@ require_paths:
|
|
56
101
|
- lib
|
57
102
|
required_ruby_version: !ruby/object:Gem::Requirement
|
58
103
|
requirements:
|
59
|
-
- -
|
104
|
+
- - ">="
|
60
105
|
- !ruby/object:Gem::Version
|
61
106
|
version: '0'
|
62
107
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
108
|
requirements:
|
64
|
-
- -
|
109
|
+
- - ">"
|
65
110
|
- !ruby/object:Gem::Version
|
66
|
-
version:
|
111
|
+
version: 1.3.1
|
67
112
|
requirements: []
|
68
113
|
rubyforge_project:
|
69
|
-
rubygems_version: 2.
|
114
|
+
rubygems_version: 2.4.5
|
70
115
|
signing_key:
|
71
116
|
specification_version: 4
|
72
117
|
summary: Reusable view components for your Ruby web application
|
73
|
-
test_files:
|
118
|
+
test_files:
|
119
|
+
- spec/action_widget_spec.rb
|
120
|
+
- spec/spec_helper.rb
|
74
121
|
has_rdoc:
|