form 0.0.0 → 0.0.1.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +15 -1
- data/README.rdoc +1 -1
- data/examples/hash.rb +27 -0
- data/examples/object.rb +19 -0
- data/form.gemspec +4 -1
- data/lib/form/builder.rb +130 -0
- data/lib/form/component/base.rb +69 -0
- data/lib/form/component/button.rb +26 -0
- data/lib/form/component/input.rb +17 -0
- data/lib/form/component/label.rb +25 -0
- data/lib/form/component/text_area.rb +23 -0
- data/lib/form/component.rb +9 -0
- data/lib/form/extensions/hash.rb +10 -0
- data/lib/form/locales/en.yml +3 -0
- data/lib/form/tag.rb +106 -0
- data/lib/form/version.rb +2 -2
- data/lib/form.rb +22 -0
- data/spec/form/builder_spec.rb +95 -0
- data/spec/form/component/base_spec.rb +80 -0
- data/spec/form/component/input_spec.rb +4 -0
- data/spec/form/component/label_spec.rb +56 -0
- data/spec/form/component/text_area_spec.rb +62 -0
- data/spec/form/extensions/hash_spec.rb +9 -0
- data/spec/form/tag_spec.rb +119 -0
- data/spec/form_spec.rb +27 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/have_tag_matcher.rb +121 -0
- data/spec/support/helpers.rb +9 -0
- data/spec/support/input_instantiation_shared.rb +28 -0
- data/spec/support/input_shared.rb +13 -0
- metadata +89 -14
data/spec/form_spec.rb
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Form do
|
4
|
+
describe ".new" do
|
5
|
+
let(:data) { mock }
|
6
|
+
let(:base_name) { mock }
|
4
7
|
|
8
|
+
it "instantiates a new Form::Builder object" do
|
9
|
+
Form::Builder.should_receive(:new).with(data, base_name)
|
10
|
+
Form.new(data, base_name)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe ".add_locale" do
|
15
|
+
let(:en) {
|
16
|
+
File.expand_path("../../lib/form/locales/en.yml", __FILE__)
|
17
|
+
}
|
18
|
+
|
19
|
+
let(:ptBR) {
|
20
|
+
File.expand_path("../../lib/form/locales/pt-BR.yml", __FILE__)
|
21
|
+
}
|
22
|
+
|
23
|
+
it "includes English by default" do
|
24
|
+
I18n.load_path.should include(en)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "appends other locales" do
|
28
|
+
I18n.load_path.should_receive(:<<).with(ptBR)
|
29
|
+
Form.add_locale "pt-BR"
|
30
|
+
end
|
31
|
+
end
|
5
32
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -3,4 +3,14 @@ Bundler.setup(:default, :development)
|
|
3
3
|
Bundler.require
|
4
4
|
|
5
5
|
require "form"
|
6
|
+
require "nokogiri"
|
6
7
|
|
8
|
+
Dir["spec/support/**/*.rb"].each {|file| require file}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.include Form::RSpec::Matchers
|
12
|
+
config.include Form::RSpec::Helpers
|
13
|
+
config.after do
|
14
|
+
I18n.reload!
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# Extracted from http://rubygems.org/gems/swiss_knife
|
2
|
+
#
|
3
|
+
module Form
|
4
|
+
module RSpec
|
5
|
+
module Matchers
|
6
|
+
def have_tag(selector, options = {}, &block)
|
7
|
+
HaveTag.new(:html, selector, options, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
def have_node(selector, options = {}, &block)
|
11
|
+
HaveTag.new(:xml, selector, options, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
class HaveTag
|
15
|
+
attr_reader :options, :selector, :actual, :actual_count, :doc, :type
|
16
|
+
|
17
|
+
def initialize(type, selector, options = {}, &block)
|
18
|
+
@selector = selector.to_s
|
19
|
+
@type = type
|
20
|
+
|
21
|
+
case options
|
22
|
+
when Hash
|
23
|
+
@options = options
|
24
|
+
when Numeric
|
25
|
+
@options = {:count => options}
|
26
|
+
else
|
27
|
+
@options = {:text => options}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def doc_for(input)
|
32
|
+
engine = type == :xml ? Nokogiri::XML : Nokogiri::HTML
|
33
|
+
|
34
|
+
if input.respond_to?(:body)
|
35
|
+
engine.parse(input.body.to_s)
|
36
|
+
elsif Nokogiri::XML::Element === input
|
37
|
+
input
|
38
|
+
else
|
39
|
+
engine.parse(input.to_s)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def matches?(actual, &block)
|
44
|
+
@actual = actual
|
45
|
+
@doc = doc_for(actual)
|
46
|
+
|
47
|
+
matches = doc.css(selector)
|
48
|
+
|
49
|
+
return options[:count] == 0 if matches.empty?
|
50
|
+
matches = filter_on_inner_text(matches) if options[:text]
|
51
|
+
matches = filter_on_nested_expectations(matches, block) if block
|
52
|
+
|
53
|
+
@actual_count = matches.size
|
54
|
+
|
55
|
+
return false if not acceptable_count?(actual_count)
|
56
|
+
|
57
|
+
!matches.empty?
|
58
|
+
end
|
59
|
+
|
60
|
+
def description
|
61
|
+
"have tag #{selector.inspect} with #{options.inspect}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def failure_message
|
65
|
+
explanation = actual_count ? "but found #{actual_count}" : "but did not"
|
66
|
+
"expected\n#{doc.to_s}\nto have #{failure_count_phrase} #{failure_selector_phrase}, #{explanation}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def negative_failure_message
|
70
|
+
explanation = actual_count ? "but found #{actual_count}" : "but did"
|
71
|
+
"expected\n#{doc.to_s}\nnot to have #{failure_count_phrase} #{failure_selector_phrase}, #{explanation}"
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
def filter_on_inner_text(elements)
|
76
|
+
elements.select do |el|
|
77
|
+
next(el.inner_text =~ options[:text]) if options[:text].is_a?(Regexp)
|
78
|
+
el.inner_text == options[:text]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def filter_on_nested_expectations(elements, block)
|
83
|
+
elements.select do |el|
|
84
|
+
begin
|
85
|
+
block.call(el)
|
86
|
+
rescue ::RSpec::Expectations::ExpectationNotMetError
|
87
|
+
false
|
88
|
+
else
|
89
|
+
true
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def acceptable_count?(count)
|
95
|
+
return false unless options[:count] === count if options[:count]
|
96
|
+
return false unless count >= options[:minimum] if options[:minimum]
|
97
|
+
return false unless count <= options[:maximum] if options[:maximum]
|
98
|
+
true
|
99
|
+
end
|
100
|
+
|
101
|
+
def failure_count_phrase
|
102
|
+
if options[:count]
|
103
|
+
"#{options[:count]} elements matching"
|
104
|
+
elsif options[:minimum] || options[:maximum]
|
105
|
+
count_explanations = []
|
106
|
+
count_explanations << "at least #{options[:minimum]}" if options[:minimum]
|
107
|
+
count_explanations << "at most #{options[:maximum]}" if options[:maximum]
|
108
|
+
"#{count_explanations.join(' and ')} elements matching"
|
109
|
+
else
|
110
|
+
"an element matching"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def failure_selector_phrase
|
115
|
+
phrase = selector.inspect
|
116
|
+
phrase << (options[:text] ? " with inner text #{options[:text].inspect}" : "")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
shared_examples_for "input instantiation" do
|
2
|
+
let(:name) { "myfield" }
|
3
|
+
let(:html) { mock.as_null_object }
|
4
|
+
|
5
|
+
context "with default attributes" do
|
6
|
+
subject { described_class.new }
|
7
|
+
|
8
|
+
let(:options) { {} }
|
9
|
+
let(:expected_options) { {type: type} }
|
10
|
+
|
11
|
+
it "instantiates component" do
|
12
|
+
component.should_receive(:new).with(subject, name, expected_options).and_return(html)
|
13
|
+
subject.public_send(helper, name, options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "with custom attributes" do
|
18
|
+
subject { described_class.new }
|
19
|
+
|
20
|
+
let(:options) { {autofocus: true} }
|
21
|
+
let(:expected_options) { options.merge(type: type) }
|
22
|
+
|
23
|
+
it "instantiates component" do
|
24
|
+
component.should_receive(:new).with(subject, name, expected_options).and_return(html)
|
25
|
+
subject.public_send(helper, name, options)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
shared_examples_for "input" do
|
2
|
+
let(:form) { mock(data: {myfield: "some value"}) }
|
3
|
+
let(:name) { "myfield" }
|
4
|
+
|
5
|
+
context "with custom attributes" do
|
6
|
+
let(:options) { {autofocus: true, class: "some-class"} }
|
7
|
+
let(:html) { Form::Component::Input.new(form, name, options).to_html }
|
8
|
+
subject { Nokogiri(html).css("input").first }
|
9
|
+
|
10
|
+
its(["type"]) { should eql(type) }
|
11
|
+
its(["value"]) { should eql("some value") }
|
12
|
+
end
|
13
|
+
end
|
metadata
CHANGED
@@ -1,19 +1,30 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: form
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.1.alpha1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Nando Vieira
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-02-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: i18n
|
16
|
+
requirement: &70226081174820 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70226081174820
|
14
25
|
- !ruby/object:Gem::Dependency
|
15
26
|
name: rake
|
16
|
-
requirement: &
|
27
|
+
requirement: &70226081174280 !ruby/object:Gem::Requirement
|
17
28
|
none: false
|
18
29
|
requirements:
|
19
30
|
- - ~>
|
@@ -21,10 +32,10 @@ dependencies:
|
|
21
32
|
version: '0.9'
|
22
33
|
type: :development
|
23
34
|
prerelease: false
|
24
|
-
version_requirements: *
|
35
|
+
version_requirements: *70226081174280
|
25
36
|
- !ruby/object:Gem::Dependency
|
26
37
|
name: rspec
|
27
|
-
requirement: &
|
38
|
+
requirement: &70226081173720 !ruby/object:Gem::Requirement
|
28
39
|
none: false
|
29
40
|
requirements:
|
30
41
|
- - ~>
|
@@ -32,7 +43,40 @@ dependencies:
|
|
32
43
|
version: '2.8'
|
33
44
|
type: :development
|
34
45
|
prerelease: false
|
35
|
-
version_requirements: *
|
46
|
+
version_requirements: *70226081173720
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: nokogiri
|
49
|
+
requirement: &70226081172860 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.5'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70226081172860
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: awesome_print
|
60
|
+
requirement: &70226081171560 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70226081171560
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: &70226081169700 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70226081169700
|
36
80
|
description: A simple form builder for Ruby objects.
|
37
81
|
email:
|
38
82
|
- fnando.vieira@gmail.com
|
@@ -46,11 +90,34 @@ files:
|
|
46
90
|
- Gemfile.lock
|
47
91
|
- README.rdoc
|
48
92
|
- Rakefile
|
93
|
+
- examples/hash.rb
|
94
|
+
- examples/object.rb
|
49
95
|
- form.gemspec
|
50
96
|
- lib/form.rb
|
97
|
+
- lib/form/builder.rb
|
98
|
+
- lib/form/component.rb
|
99
|
+
- lib/form/component/base.rb
|
100
|
+
- lib/form/component/button.rb
|
101
|
+
- lib/form/component/input.rb
|
102
|
+
- lib/form/component/label.rb
|
103
|
+
- lib/form/component/text_area.rb
|
104
|
+
- lib/form/extensions/hash.rb
|
105
|
+
- lib/form/locales/en.yml
|
106
|
+
- lib/form/tag.rb
|
51
107
|
- lib/form/version.rb
|
108
|
+
- spec/form/builder_spec.rb
|
109
|
+
- spec/form/component/base_spec.rb
|
110
|
+
- spec/form/component/input_spec.rb
|
111
|
+
- spec/form/component/label_spec.rb
|
112
|
+
- spec/form/component/text_area_spec.rb
|
113
|
+
- spec/form/extensions/hash_spec.rb
|
114
|
+
- spec/form/tag_spec.rb
|
52
115
|
- spec/form_spec.rb
|
53
116
|
- spec/spec_helper.rb
|
117
|
+
- spec/support/have_tag_matcher.rb
|
118
|
+
- spec/support/helpers.rb
|
119
|
+
- spec/support/input_instantiation_shared.rb
|
120
|
+
- spec/support/input_shared.rb
|
54
121
|
homepage: http://rubygems.org/gems/form
|
55
122
|
licenses: []
|
56
123
|
post_install_message:
|
@@ -65,22 +132,30 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
65
132
|
version: '0'
|
66
133
|
segments:
|
67
134
|
- 0
|
68
|
-
hash: -
|
135
|
+
hash: -4539759013921381376
|
69
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
137
|
none: false
|
71
138
|
requirements:
|
72
|
-
- - ! '
|
139
|
+
- - ! '>'
|
73
140
|
- !ruby/object:Gem::Version
|
74
|
-
version:
|
75
|
-
segments:
|
76
|
-
- 0
|
77
|
-
hash: -168652467651521831
|
141
|
+
version: 1.3.1
|
78
142
|
requirements: []
|
79
143
|
rubyforge_project:
|
80
|
-
rubygems_version: 1.8.
|
144
|
+
rubygems_version: 1.8.11
|
81
145
|
signing_key:
|
82
146
|
specification_version: 3
|
83
147
|
summary: A simple form builder for Ruby objects.
|
84
148
|
test_files:
|
149
|
+
- spec/form/builder_spec.rb
|
150
|
+
- spec/form/component/base_spec.rb
|
151
|
+
- spec/form/component/input_spec.rb
|
152
|
+
- spec/form/component/label_spec.rb
|
153
|
+
- spec/form/component/text_area_spec.rb
|
154
|
+
- spec/form/extensions/hash_spec.rb
|
155
|
+
- spec/form/tag_spec.rb
|
85
156
|
- spec/form_spec.rb
|
86
157
|
- spec/spec_helper.rb
|
158
|
+
- spec/support/have_tag_matcher.rb
|
159
|
+
- spec/support/helpers.rb
|
160
|
+
- spec/support/input_instantiation_shared.rb
|
161
|
+
- spec/support/input_shared.rb
|