form_object_model 0.1.0
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/.gitignore +17 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +87 -0
- data/Rakefile +16 -0
- data/form_object_model.gemspec +23 -0
- data/lib/form_object_model.rb +6 -0
- data/lib/form_object_model/form.rb +118 -0
- data/lib/form_object_model/helper.rb +8 -0
- data/lib/form_object_model/matcher.rb +15 -0
- data/lib/form_object_model/version.rb +3 -0
- data/spec/integration/form_object_model_spec.rb +156 -0
- data/spec/spec_helper.rb +9 -0
- metadata +115 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Sean Geoghegan
|
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,87 @@
|
|
1
|
+
# FormObjectModel
|
2
|
+
|
3
|
+
[](http://travis-ci.org/reinteractive-open/form-object-model)
|
4
|
+
|
5
|
+
This gem lets you construct an object model
|
6
|
+
of a form you're using in your request specs.
|
7
|
+
With a form object model, locators and field types
|
8
|
+
are defined in a single place so if the form structure
|
9
|
+
changes your test don't need to change, only the
|
10
|
+
definition of the form fields.
|
11
|
+
|
12
|
+
So given the following form in a page:
|
13
|
+
|
14
|
+
```html
|
15
|
+
<form action="/foo">
|
16
|
+
<label for="name">Name</label>
|
17
|
+
<input type="text" name="name" id="name" />
|
18
|
+
|
19
|
+
<label for="title">Title</label>
|
20
|
+
<select id="title" name="title">
|
21
|
+
<option>Mr</option>
|
22
|
+
<option>Miss</option>
|
23
|
+
<option>Mrs</option>
|
24
|
+
</select>
|
25
|
+
|
26
|
+
<h3>Gender</h3>
|
27
|
+
<label for="gender_male">Male</label>
|
28
|
+
<input type="radio" name="gender" value="male" id="gender_male" />
|
29
|
+
|
30
|
+
<label for="gender_female">Female</label>
|
31
|
+
<input type="radio" name="gender" value="female" id="gender_female" />
|
32
|
+
</form>
|
33
|
+
```
|
34
|
+
|
35
|
+
Forms are defined like so:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
form = FormObjectModel.new do |fom|
|
39
|
+
form.text_field :name, "Name"
|
40
|
+
form.select :title, "Title"
|
41
|
+
form.radio :gender, "input[name = gender]"
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
You can then set the value of the fields, in a consistent way, regardless of the field type. This is done like so:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
form.name = "Joe Bloggs"
|
49
|
+
form.title = "Mr"
|
50
|
+
form.gender = "Male"
|
51
|
+
```
|
52
|
+
|
53
|
+
And assert the field value using:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
form.name.should have_value("Joe Bloggs")
|
57
|
+
form.title.should have_value("Mr")
|
58
|
+
form.gender.should have_value("Male")
|
59
|
+
```
|
60
|
+
|
61
|
+
## TODOs
|
62
|
+
|
63
|
+
* Support more field types, currently just handle, text, select and radio buttons.
|
64
|
+
* Make it easier to define custom field types for custom widgets.
|
65
|
+
|
66
|
+
## Installation
|
67
|
+
|
68
|
+
Add this line to your application's Gemfile:
|
69
|
+
|
70
|
+
gem 'form_object_model'
|
71
|
+
|
72
|
+
And then execute:
|
73
|
+
|
74
|
+
$ bundle
|
75
|
+
|
76
|
+
Or install it yourself as:
|
77
|
+
|
78
|
+
$ gem install form_object_model
|
79
|
+
|
80
|
+
## Contributing
|
81
|
+
|
82
|
+
1. Fork it
|
83
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
84
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
85
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
86
|
+
5. Create new Pull Request
|
87
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
|
4
|
+
begin
|
5
|
+
# Set up load paths for all bundled gems
|
6
|
+
ENV["BUNDLE_GEMFILE"] = File.expand_path("../Gemfile", __FILE__)
|
7
|
+
Bundler.setup
|
8
|
+
rescue Bundler::GemNotFound
|
9
|
+
raise RuntimeError, "Bundler couldn't find some gems." +
|
10
|
+
"Did you run `bundle install`?"
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'rspec/core/rake_task'
|
14
|
+
RSpec::Core::RakeTask.new(:spec)
|
15
|
+
task :default => :spec
|
16
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/form_object_model/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Sean Geoghegan"]
|
6
|
+
gem.email = ["sean@seangeo.me"]
|
7
|
+
gem.description = %q{An OO form testing helper that makes Capayaba-based form testing easy.}
|
8
|
+
gem.summary = %q{An OO form testing helper that makes Capayaba-based form testing easy.}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "form_object_model"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = FormObjectModel::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency('capybara', '~> 1.1')
|
19
|
+
|
20
|
+
gem.add_development_dependency('rspec')
|
21
|
+
gem.add_development_dependency('rake')
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module FormObjectModel
|
2
|
+
class Form
|
3
|
+
Field = Struct.new(:page, :name, :locator)
|
4
|
+
class TextField < Field
|
5
|
+
def fill(value)
|
6
|
+
page.fill_in(locator, :with => value.to_s)
|
7
|
+
end
|
8
|
+
|
9
|
+
def has_value?(value)
|
10
|
+
page.has_field?(locator, :with => value.to_s)
|
11
|
+
end
|
12
|
+
|
13
|
+
def value
|
14
|
+
page.find_field(locator).value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class SelectField < Field
|
19
|
+
def fill(value)
|
20
|
+
page.select(value.to_s, :from => locator)
|
21
|
+
end
|
22
|
+
|
23
|
+
def has_value?(value)
|
24
|
+
page.has_select?(locator, :selected => value.to_s)
|
25
|
+
end
|
26
|
+
|
27
|
+
def value
|
28
|
+
value = nil
|
29
|
+
page.within(page.find_field(locator)) do
|
30
|
+
value = page.find("option[selected]").text
|
31
|
+
end
|
32
|
+
value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class RadioField < Field
|
37
|
+
# This lets you select the radio button by it's label instead of id
|
38
|
+
def fill(value)
|
39
|
+
if button = button_for(value)
|
40
|
+
button.set(true)
|
41
|
+
else
|
42
|
+
raise "Could not find button with locator '#{locator}' and label '#{value}'"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def has_value?(value)
|
47
|
+
button = button_for(value)
|
48
|
+
button && %w(checked true).include?(button['checked'])
|
49
|
+
end
|
50
|
+
|
51
|
+
def value
|
52
|
+
element = checked_element
|
53
|
+
element && element.value
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
def checked_element
|
58
|
+
page.all(locator).find {|b| b['checked'] == 'checked' }
|
59
|
+
end
|
60
|
+
|
61
|
+
def button_for(value)
|
62
|
+
label_ids = label_ids_for(value)
|
63
|
+
page.all(locator).find {|b| label_ids.include?(b['id']) }
|
64
|
+
end
|
65
|
+
|
66
|
+
def label_ids_for(value)
|
67
|
+
page.all("label:contains('#{value}')").map {|label| label['for'] }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
attr_reader :page
|
72
|
+
|
73
|
+
def initialize(page)
|
74
|
+
@page = page
|
75
|
+
yield(self) if block_given?
|
76
|
+
end
|
77
|
+
|
78
|
+
def text_field(name, locator)
|
79
|
+
define_field(name, TextField.new(page, name, locator))
|
80
|
+
end
|
81
|
+
|
82
|
+
def select(name, locator)
|
83
|
+
define_field(name, SelectField.new(page, name, locator))
|
84
|
+
end
|
85
|
+
|
86
|
+
# Radio button locators should match all buttons in the group
|
87
|
+
def radio(name, locator)
|
88
|
+
define_field(name, RadioField.new(page, name, locator))
|
89
|
+
end
|
90
|
+
|
91
|
+
def submit_button(locator, &after_submit_block)
|
92
|
+
@submit_button = locator
|
93
|
+
@after_submit_block = after_submit_block
|
94
|
+
end
|
95
|
+
|
96
|
+
def submit
|
97
|
+
raise "FormObjectModel#submit_button called before submit_button locator was set" unless @submit_button
|
98
|
+
page.click_button @submit_button
|
99
|
+
if @after_submit_block
|
100
|
+
@after_submit_block.call(page)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def within
|
105
|
+
yield(self)
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def define_field(name, field)
|
111
|
+
(class << self; self; end).class_eval do
|
112
|
+
define_method(name) {|*args| field }
|
113
|
+
define_method("#{name.to_s}=".to_sym) {|val| field.fill(val) }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module FormObjectModel
|
2
|
+
class FormObjectHaveValueMatcher < Struct.new(:value)
|
3
|
+
attr_reader :actual
|
4
|
+
|
5
|
+
def matches?(actual)
|
6
|
+
@actual = actual
|
7
|
+
actual.has_value?(value)
|
8
|
+
end
|
9
|
+
|
10
|
+
def failure_message_for_should
|
11
|
+
"Expected field '#{actual.locator}' to have value '#{value}' but had '#{actual.value}'"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe FormObjectModel do
|
4
|
+
let(:page) { Capybara::Session.new(:rack_test, @app) }
|
5
|
+
after { page.reset! }
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
@app = lambda do |env|
|
9
|
+
if env['REQUEST_METHOD'] == 'POST'
|
10
|
+
body = <<-HTML
|
11
|
+
<html>
|
12
|
+
<head>
|
13
|
+
</head>
|
14
|
+
<body>
|
15
|
+
<p>Submitted</p>
|
16
|
+
</body>
|
17
|
+
</html>
|
18
|
+
HTML
|
19
|
+
else
|
20
|
+
body = <<-HTML
|
21
|
+
<html>
|
22
|
+
<head>
|
23
|
+
</head>
|
24
|
+
<body>
|
25
|
+
<form action="/" method="post">
|
26
|
+
<label for="textfield1">Text Field 1</label>
|
27
|
+
<input type="text" id="textfield1" name="textfield1" />
|
28
|
+
|
29
|
+
<label for="selectfield1">Select Field</label>
|
30
|
+
<select id="selectfield1">
|
31
|
+
<option>Option 1</option>
|
32
|
+
<option>Option 2</option>
|
33
|
+
<option>Option 3</option>
|
34
|
+
</select>
|
35
|
+
|
36
|
+
<label for="radio1">Radio 1"</label>
|
37
|
+
<input type="radio" name="radio" id="radio1" value="Radio1"/>
|
38
|
+
<label for="radio2">Radio 2"</label>
|
39
|
+
<input type="radio" name="radio" id="radio2" value="Radio2"/>
|
40
|
+
<label for="radio3">Radio 3"</label>
|
41
|
+
<input type="radio" name="radio" id="radio3" value="Radio3"/>
|
42
|
+
|
43
|
+
<input type="submit" name="submit" value="Submit" />
|
44
|
+
</form>
|
45
|
+
</body>
|
46
|
+
</html>
|
47
|
+
HTML
|
48
|
+
end
|
49
|
+
[200,
|
50
|
+
{ 'Content-Type' => 'text/html',
|
51
|
+
'Content-Length' => body.length.to_s },
|
52
|
+
[body]]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
let(:form) do
|
57
|
+
FormObjectModel::Form.new(page) do |f|
|
58
|
+
f.text_field :textfield1, "Text Field 1"
|
59
|
+
f.select :selectfield1, "Select Field"
|
60
|
+
f.radio :radiobuttons1, "input[name = radio]"
|
61
|
+
f.submit_button "Submit"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
before { page.visit("/") }
|
66
|
+
|
67
|
+
context "text fields" do
|
68
|
+
it "should set the value of the field" do
|
69
|
+
form.textfield1 = "My Value"
|
70
|
+
page.should have_field("Text Field 1", :with => "My Value")
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should fail when the value of the field is different" do
|
74
|
+
page.fill_in("Text Field 1", :with => "A value")
|
75
|
+
lambda { form.textfield1.should have_value("Other value") }.should raise_error(RSpec::Expectations::ExpectationNotMetError)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should pass when the value of the field is the same" do
|
79
|
+
page.fill_in("Text Field 1", :with => "A value")
|
80
|
+
form.textfield1.should have_value("A value")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "single select" do
|
85
|
+
it "should set the value of the field" do
|
86
|
+
form.selectfield1 = "Option 2"
|
87
|
+
page.should have_select("Select Field", :selected => "Option 2")
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should fail when set to another value" do
|
91
|
+
page.select("Option 3", :from => "Select Field")
|
92
|
+
lambda { form.selectfield1.should have_value("Option 2") }.should raise_error(RSpec::Expectations::ExpectationNotMetError)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should pass with the value is the same" do
|
96
|
+
page.select("Option 2", :from => "Select Field")
|
97
|
+
form.selectfield1.should have_value("Option 2")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "radio buttons" do
|
102
|
+
it "should set the radio button via its label" do
|
103
|
+
form.radiobuttons1 = "Radio 2"
|
104
|
+
page.should have_checked_field("radio2")
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should set the radio button via the other label" do
|
108
|
+
form.radiobuttons1 = "Radio 3"
|
109
|
+
page.should have_checked_field("radio3")
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should fail when the radio button is set to another value" do
|
113
|
+
page.choose("radio2")
|
114
|
+
lambda { form.radiobuttons1.should have_value("Radio 1") }.should raise_error(RSpec::Expectations::ExpectationNotMetError)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should pass when the radio button is set to the same value" do
|
118
|
+
page.choose("radio3")
|
119
|
+
form.radiobuttons1.should have_value("Radio 3")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context "submit" do
|
124
|
+
it "should submit the form" do
|
125
|
+
form.submit
|
126
|
+
page.should have_content("Submitted")
|
127
|
+
end
|
128
|
+
|
129
|
+
context "with a submit callback" do
|
130
|
+
let(:form) do
|
131
|
+
FormObjectModel::Form.new(page) do |f|
|
132
|
+
f.submit_button "Submit" do
|
133
|
+
page.should have_content("Submitted")
|
134
|
+
@callback_fired = true
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should call the callback after submission" do
|
140
|
+
form.submit
|
141
|
+
@callback_fired.should be_true
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context "without submit defined" do
|
146
|
+
let(:form) do
|
147
|
+
FormObjectModel::Form.new(page)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should raise an error on submission" do
|
151
|
+
lambda { form.submit }.should raise_error
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: form_object_model
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Sean Geoghegan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: capybara
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.1'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.1'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: An OO form testing helper that makes Capayaba-based form testing easy.
|
63
|
+
email:
|
64
|
+
- sean@seangeo.me
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- .gitignore
|
70
|
+
- .travis.yml
|
71
|
+
- Gemfile
|
72
|
+
- LICENSE
|
73
|
+
- README.md
|
74
|
+
- Rakefile
|
75
|
+
- form_object_model.gemspec
|
76
|
+
- lib/form_object_model.rb
|
77
|
+
- lib/form_object_model/form.rb
|
78
|
+
- lib/form_object_model/helper.rb
|
79
|
+
- lib/form_object_model/matcher.rb
|
80
|
+
- lib/form_object_model/version.rb
|
81
|
+
- spec/integration/form_object_model_spec.rb
|
82
|
+
- spec/spec_helper.rb
|
83
|
+
homepage: ''
|
84
|
+
licenses: []
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
segments:
|
96
|
+
- 0
|
97
|
+
hash: -173730069923801373
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
segments:
|
105
|
+
- 0
|
106
|
+
hash: -173730069923801373
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 1.8.19
|
110
|
+
signing_key:
|
111
|
+
specification_version: 3
|
112
|
+
summary: An OO form testing helper that makes Capayaba-based form testing easy.
|
113
|
+
test_files:
|
114
|
+
- spec/integration/form_object_model_spec.rb
|
115
|
+
- spec/spec_helper.rb
|