formal_wear 0.0.1
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/.coveralls.yml +1 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +33 -0
- data/Rakefile +2 -0
- data/formal_wear.gemspec +23 -0
- data/lib/formal_wear/class_methods.rb +24 -0
- data/lib/formal_wear/instance_methods.rb +107 -0
- data/lib/formal_wear/version.rb +3 -0
- data/lib/formal_wear.rb +22 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/test_formal_wear.rb +69 -0
- data/spec/test_formal_wear_spec.rb +151 -0
- metadata +145 -0
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-pro
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Jacob Stetser
|
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,33 @@
|
|
1
|
+
# FormalWear
|
2
|
+
|
3
|
+
[](https://travis-ci.org/wideopenspaces/formal_wear.png) [](https://codeclimate.com/github/wideopenspaces/formal_wear) [](https://coveralls.io/r/wideopenspaces/formal_wear)
|
4
|
+
|
5
|
+
"You're going to like the way you look. I guarantee it."
|
6
|
+
|
7
|
+
FormalWear helps you create Form Objects with required and optional attributes and gets all fancy widdit.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'formal_wear'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install formal_wear
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Contributing
|
28
|
+
|
29
|
+
1. Fork it
|
30
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
31
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
32
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
33
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/formal_wear.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/formal_wear/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Jake Stetser"]
|
6
|
+
gem.email = ["jake@wideopenspac.es"]
|
7
|
+
gem.description = %q{FormalWear helps you create Form Objects with required and optional attributes and gets all fancy widdit.}
|
8
|
+
gem.summary = %q{You're going to like the way you look. I guarantee it.}
|
9
|
+
gem.homepage = "https://github.com/wideopenspaces/formal_wear"
|
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 = "formal_wear"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = FormalWear::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency 'activesupport', '>= 3.0.20'
|
19
|
+
gem.add_dependency 'hash_assertions', '~> 0.1.0'
|
20
|
+
gem.add_development_dependency 'rspec'
|
21
|
+
gem.add_development_dependency 'mocha', '~> 0.13.1'
|
22
|
+
gem.add_development_dependency 'coveralls'
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module FormalWear
|
2
|
+
module ClassMethods
|
3
|
+
def required_attrs(attrs)
|
4
|
+
validate_attrs!(attrs)
|
5
|
+
|
6
|
+
required = class_variable_get(:@@required_fields) || {}
|
7
|
+
class_variable_set(:@@required_fields, required.merge(attrs))
|
8
|
+
|
9
|
+
create_accessors(attrs.keys)
|
10
|
+
end
|
11
|
+
def required_attr(a); required_attrs(a); end
|
12
|
+
|
13
|
+
def create_accessors(keys)
|
14
|
+
keys.each { |k| self.send(:attr_accessor, k) unless method_defined?(k) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate_attrs!(attrs)
|
18
|
+
attrs.each do |a, opts|
|
19
|
+
opts.assert_valid_keys(*ALLOWED_KEYS)
|
20
|
+
opts.assert_required_keys(*REQUIRED_KEYS)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module FormalWear
|
2
|
+
module InstanceMethods
|
3
|
+
### THE NITTY GRITTY STARTS HERE
|
4
|
+
|
5
|
+
# Start the configuration process
|
6
|
+
def initialize(primary)
|
7
|
+
@primary = primary
|
8
|
+
update_sources
|
9
|
+
end
|
10
|
+
|
11
|
+
def required_attributes
|
12
|
+
required_fields.dup.each do |field, options|
|
13
|
+
options.slice!(:name, :type)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Return the list of required fields for this configurator
|
18
|
+
def required_fields
|
19
|
+
@@required_fields
|
20
|
+
end
|
21
|
+
|
22
|
+
def required_fields_without_custom_stores
|
23
|
+
required_fields.reject { |f,o| custom_store?(o) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def required_fields_with_custom_stores
|
27
|
+
required_fields.select { |f,o| custom_store?(o) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_h
|
31
|
+
{}.merge(required_attributes: required_attributes).tap do |h|
|
32
|
+
required_fields.keys.each { |k| h[k] = self.send(k) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def update(attrs)
|
37
|
+
raise ArgumentError, "update requires a Hash"
|
38
|
+
attrs.each do |field, value|
|
39
|
+
self.send(:"#{field}=", value) if instance_method_defined?(field)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def valid?
|
44
|
+
required_fields.keys.all? { |k| self.send(k).present? }
|
45
|
+
end
|
46
|
+
|
47
|
+
def save
|
48
|
+
return false unless valid?
|
49
|
+
saving do
|
50
|
+
required_fields.each { |field, options| set_field(field, options) }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# Redefine this in a configurator if you need to do anything before you save the data
|
57
|
+
def before_save
|
58
|
+
end
|
59
|
+
|
60
|
+
# Redefine this in a configurator in order to run tasks after completing setup
|
61
|
+
def after_save
|
62
|
+
end
|
63
|
+
|
64
|
+
def saving(&block)
|
65
|
+
before_save
|
66
|
+
yield if block_given?
|
67
|
+
after_save
|
68
|
+
end
|
69
|
+
|
70
|
+
def set_field(field, options)
|
71
|
+
custom_store?(options) ? set_via_custom_store(field, options) : self.send(:"set_#{field}")
|
72
|
+
end
|
73
|
+
|
74
|
+
def set_via_custom_store(field, options)
|
75
|
+
return set_via_symbol(options) if symbol_store?(options)
|
76
|
+
return set_via_lambda(field, options) if lambda_store?(options)
|
77
|
+
end
|
78
|
+
|
79
|
+
def set_via_symbol(options)
|
80
|
+
self.send(options[:store])
|
81
|
+
end
|
82
|
+
|
83
|
+
def set_via_lambda(field, options)
|
84
|
+
callable = options[:store]
|
85
|
+
self.instance_eval(&callable)
|
86
|
+
end
|
87
|
+
|
88
|
+
def custom_store?(options)
|
89
|
+
options[:store].present?
|
90
|
+
end
|
91
|
+
|
92
|
+
def symbol_store?(options)
|
93
|
+
custom_store?(options) && options[:store].is_a?(Symbol)
|
94
|
+
end
|
95
|
+
|
96
|
+
def lambda_store?(options)
|
97
|
+
custom_store?(options) && options[:store].try(:lambda?)
|
98
|
+
end
|
99
|
+
|
100
|
+
# When donning formal_wear, pre-populate from source if available
|
101
|
+
def update_sources
|
102
|
+
required_fields.each do |field, options|
|
103
|
+
send(:"#{field}=", options[:source].call(self)) if options[:source] rescue nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/formal_wear.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'formal_wear/version'
|
2
|
+
require 'formal_wear/class_methods'
|
3
|
+
require 'formal_wear/instance_methods'
|
4
|
+
require 'hash_assertions'
|
5
|
+
require 'active_support/core_ext'
|
6
|
+
require 'active_support/concern'
|
7
|
+
|
8
|
+
module FormalWear
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
### CLASS LEVEL BEHAVIOR
|
12
|
+
REQUIRED_KEYS = [:name, :type, :source]
|
13
|
+
ALLOWED_KEYS = REQUIRED_KEYS | [:store, :select_options]
|
14
|
+
|
15
|
+
included do
|
16
|
+
extend FormalWear::ClassMethods
|
17
|
+
include FormalWear::InstanceMethods
|
18
|
+
|
19
|
+
attr_reader :primary
|
20
|
+
cattr_reader :required_fields
|
21
|
+
end
|
22
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
require 'coveralls'
|
8
|
+
Coveralls.wear!
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
12
|
+
config.run_all_when_everything_filtered = true
|
13
|
+
config.filter_run :focus
|
14
|
+
config.mock_with :mocha
|
15
|
+
|
16
|
+
# Run specs in random order to surface order dependencies. If you find an
|
17
|
+
# order dependency and want to debug it, you can fix the order by providing
|
18
|
+
# the seed, which is printed after each run.
|
19
|
+
# --seed 1234
|
20
|
+
config.order = 'random'
|
21
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'formal_wear'
|
2
|
+
|
3
|
+
class TestFormalWear
|
4
|
+
include FormalWear
|
5
|
+
|
6
|
+
required_attr moms_id: {
|
7
|
+
name: "Your mom's id",
|
8
|
+
type: :text,
|
9
|
+
source: ->(s) { s.primary.thing_to_be_configured },
|
10
|
+
}
|
11
|
+
|
12
|
+
required_attr docs_id: {
|
13
|
+
name: "Your doc's id",
|
14
|
+
type: :text,
|
15
|
+
source: ->(s) { s.primary.dependent_object.another_thing_to_be_configured },
|
16
|
+
store: :set_my_docs_id
|
17
|
+
}
|
18
|
+
|
19
|
+
required_attr lambda_lambda_lambda: {
|
20
|
+
name: 'Revenge Of The Nerds!',
|
21
|
+
type: :text,
|
22
|
+
source: ->(s) { s.get_pledged },
|
23
|
+
store: ->(s) { s.got_lambda? }
|
24
|
+
}
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def after_save
|
29
|
+
# no-op
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_moms_id
|
33
|
+
# no-op
|
34
|
+
end
|
35
|
+
|
36
|
+
def set_my_docs_id
|
37
|
+
# no-op
|
38
|
+
end
|
39
|
+
|
40
|
+
def got_lambda?
|
41
|
+
# no-op
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_pledged
|
45
|
+
primary.dependent_object.another_thing_to_be_configured
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class ExternalObjectOne
|
50
|
+
attr_accessor :thing_to_be_configured, :dependent_object
|
51
|
+
|
52
|
+
def initialize(initial_value, initial_subvalue)
|
53
|
+
@thing_to_be_configured = initial_value
|
54
|
+
@dependent_object = ExternalObjectTwo.new(initial_subvalue)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
class ExternalObjectTwo
|
60
|
+
attr_accessor :another_thing_to_be_configured
|
61
|
+
|
62
|
+
def initialize(initial_value)
|
63
|
+
@another_thing_to_be_configured = initial_value
|
64
|
+
end
|
65
|
+
|
66
|
+
def yet_another_thing_to_be_configured
|
67
|
+
"Stuff"
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'test_formal_wear'
|
3
|
+
|
4
|
+
describe TestFormalWear do
|
5
|
+
let(:primary) { ExternalObjectOne.new(nil, nil)}
|
6
|
+
let(:config) { TestFormalWear.new(primary) }
|
7
|
+
|
8
|
+
describe 'a configurator with completed setup' do
|
9
|
+
let(:ready_primary) { ExternalObjectOne.new('Formal', 'Wear') }
|
10
|
+
let(:ready_config) { TestFormalWear.new(ready_primary) }
|
11
|
+
|
12
|
+
subject { ready_config }
|
13
|
+
|
14
|
+
context 'when initialized' do
|
15
|
+
describe '#moms_id' do
|
16
|
+
it 'is equal to ExternalObjectOne.thing_to_be_configured' do
|
17
|
+
subject.moms_id.should == subject.primary.thing_to_be_configured
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#docs_id' do
|
22
|
+
it 'is equal to ExternalObjectTwo.another_thing_to_be_configured' do
|
23
|
+
subject.docs_id.should == subject.primary.dependent_object.another_thing_to_be_configured
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'a new configurator object' do
|
30
|
+
subject { config }
|
31
|
+
|
32
|
+
it 'has a required_fields method' do
|
33
|
+
subject.should respond_to(:required_fields)
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#required_fields' do
|
37
|
+
subject { config.required_fields }
|
38
|
+
it { should be_a(Hash) }
|
39
|
+
|
40
|
+
it 'contains the appropriate required fields' do
|
41
|
+
subject.keys.should =~ [:moms_id, :docs_id, :lambda_lambda_lambda]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'has a valid? method' do
|
46
|
+
subject.should respond_to(:valid?)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'has a getter method for each of the required fields' do
|
50
|
+
subject.required_fields.keys.each do |k|
|
51
|
+
subject.should respond_to(k)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'has a setter method for each of the required fields' do
|
56
|
+
subject.required_fields.keys.each do |k|
|
57
|
+
subject.should respond_to(:"#{k}=")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when a required field has a "store" key' do
|
62
|
+
context 'that is a symbol' do
|
63
|
+
it 'responds to a method corresponding to that symbol' do
|
64
|
+
subject.should respond_to(subject.required_fields[:docs_id][:store])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'when a required field does not have a "store" key' do
|
70
|
+
it 'responds to a set_xxx method for each required field' do
|
71
|
+
config.required_fields_without_custom_stores.each do |field, options|
|
72
|
+
subject.should respond_to(:"set_#{field}")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#valid?' do
|
79
|
+
subject { config }
|
80
|
+
|
81
|
+
context 'when none of the required fields are set' do
|
82
|
+
before do
|
83
|
+
config.moms_id = nil
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'returns false' do
|
87
|
+
config.valid?.should be_false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'when not all of the required fields are set' do
|
92
|
+
before do
|
93
|
+
config.moms_id = 'zztop'
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'returns false' do
|
97
|
+
config.valid?.should be_false
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'when all of the required fields are set' do
|
102
|
+
before do
|
103
|
+
config.moms_id = config.docs_id = config.lambda_lambda_lambda = '1'
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'returns true' do
|
107
|
+
config.valid?.should be_true
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe '#save' do
|
113
|
+
subject { config }
|
114
|
+
|
115
|
+
context 'when not valid?' do
|
116
|
+
it 'returns false' do
|
117
|
+
subject.save.should be_false
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'when valid?' do
|
122
|
+
before do
|
123
|
+
subject.moms_id = subject.docs_id = subject.lambda_lambda_lambda = '1'
|
124
|
+
subject.required_fields_without_custom_stores.keys.each do |k|
|
125
|
+
subject.expects("set_#{k}").returns(true)
|
126
|
+
end
|
127
|
+
|
128
|
+
subject.required_fields_with_custom_stores.each do |field, opt|
|
129
|
+
if opt[:store].is_a?(Symbol)
|
130
|
+
subject.expects(opt[:store]).returns(true)
|
131
|
+
subject.expects(:"set_#{field}").never
|
132
|
+
elsif opt[:store].try(:lambda?)
|
133
|
+
subject.expects(:got_lambda?).returns(true)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
subject.expects(:after_save).returns(true)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'calls the set_xxx methods for each required field' do
|
141
|
+
subject.save
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'calls #after_save' do
|
145
|
+
# condition met by expectation above
|
146
|
+
subject.save
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
metadata
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: formal_wear
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jake Stetser
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-07-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.20
|
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: 3.0.20
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: hash_assertions
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.1.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.1.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
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
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: mocha
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.13.1
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.13.1
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: coveralls
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: FormalWear helps you create Form Objects with required and optional attributes
|
95
|
+
and gets all fancy widdit.
|
96
|
+
email:
|
97
|
+
- jake@wideopenspac.es
|
98
|
+
executables: []
|
99
|
+
extensions: []
|
100
|
+
extra_rdoc_files: []
|
101
|
+
files:
|
102
|
+
- .coveralls.yml
|
103
|
+
- .gitignore
|
104
|
+
- .rspec
|
105
|
+
- .travis.yml
|
106
|
+
- Gemfile
|
107
|
+
- LICENSE
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- formal_wear.gemspec
|
111
|
+
- lib/formal_wear.rb
|
112
|
+
- lib/formal_wear/class_methods.rb
|
113
|
+
- lib/formal_wear/instance_methods.rb
|
114
|
+
- lib/formal_wear/version.rb
|
115
|
+
- spec/spec_helper.rb
|
116
|
+
- spec/test_formal_wear.rb
|
117
|
+
- spec/test_formal_wear_spec.rb
|
118
|
+
homepage: https://github.com/wideopenspaces/formal_wear
|
119
|
+
licenses: []
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ! '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ! '>='
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubyforge_project:
|
138
|
+
rubygems_version: 1.8.24
|
139
|
+
signing_key:
|
140
|
+
specification_version: 3
|
141
|
+
summary: You're going to like the way you look. I guarantee it.
|
142
|
+
test_files:
|
143
|
+
- spec/spec_helper.rb
|
144
|
+
- spec/test_formal_wear.rb
|
145
|
+
- spec/test_formal_wear_spec.rb
|