hungryform 0.0.4 → 0.0.6

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -1
  3. data/.rspec +0 -1
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +5 -0
  6. data/README.md +72 -43
  7. data/Rakefile +3 -4
  8. data/hungryform.gemspec +4 -4
  9. data/lib/hungryform/configuration.rb +31 -0
  10. data/lib/hungryform/elements/base/active_element.rb +44 -36
  11. data/lib/hungryform/elements/base/element.rb +40 -49
  12. data/lib/hungryform/elements/base/group.rb +74 -71
  13. data/lib/hungryform/elements/base/hashable.rb +32 -30
  14. data/lib/hungryform/elements/base/options_element.rb +28 -24
  15. data/lib/hungryform/elements/html.rb +1 -1
  16. data/lib/hungryform/elements/page.rb +4 -0
  17. data/lib/hungryform/elements/radio_group.rb +1 -1
  18. data/lib/hungryform/elements/select_field.rb +14 -18
  19. data/lib/hungryform/elements/{text_area_field.rb → text_area.rb} +1 -1
  20. data/lib/hungryform/elements.rb +9 -1
  21. data/lib/hungryform/exceptions.rb +3 -0
  22. data/lib/hungryform/form.rb +32 -2
  23. data/lib/hungryform/resolver.rb +14 -16
  24. data/lib/hungryform/version.rb +1 -1
  25. data/lib/hungryform.rb +22 -5
  26. data/spec/elements/group_spec.rb +10 -1
  27. data/spec/elements/html_spec.rb +11 -9
  28. data/spec/elements/page_spec.rb +10 -7
  29. data/spec/elements/radio_group_spec.rb +9 -15
  30. data/spec/elements/select_field_spec.rb +19 -33
  31. data/spec/elements/shared_examples/active_element.rb +52 -0
  32. data/spec/elements/shared_examples/element.rb +42 -0
  33. data/spec/elements/shared_examples/group.rb +31 -0
  34. data/spec/elements/shared_examples/options_element.rb +24 -0
  35. data/spec/elements/text_area_spec.rb +14 -0
  36. data/spec/elements/text_field_spec.rb +10 -3
  37. data/spec/form_spec.rb +68 -1
  38. data/spec/resolver_spec.rb +7 -7
  39. data/spec/spec_helper.rb +4 -2
  40. metadata +29 -40
  41. data/Gemfile.lock +0 -52
  42. data/spec/elements/text_area_field_spec.rb +0 -7
  43. data/spec/support/shared_active_element.rb +0 -65
  44. data/spec/support/shared_element.rb +0 -62
  45. data/spec/support/shared_group.rb +0 -42
  46. data/spec/support/shared_options_element.rb +0 -36
@@ -1,37 +1,39 @@
1
1
  module HungryForm
2
- module Elements::Base
3
- # This module adds hashing capabilities to form elements.
4
- # Do not include this module in your classes. It is already
5
- # included in the base_element class.
6
- #
7
- # Sample usage:
8
- #
9
- # class MyField
10
- # attr_accessor :param1, :param2
11
- # hashable :param1, :param2
12
- # ...
13
- # end
14
- #
15
- # Any instance of MyField class will have the "to_hash" method
16
- # that will contain only the accessor/reader params defined in
17
- # the hashable macro.
18
- module Hashable
19
- def self.included(base)
20
- base.extend ClassMethods
21
- base.class_attribute :hashable_attributes
22
- base.hashable_attributes = []
23
- end
2
+ module Elements
3
+ module Base
4
+ # This module adds hashing capabilities to form elements.
5
+ # Do not include this module in your classes. It is already
6
+ # included in the base_element class.
7
+ #
8
+ # Sample usage:
9
+ #
10
+ # class MyField
11
+ # attr_accessor :param1, :param2
12
+ # hashable :param1, :param2
13
+ # ...
14
+ # end
15
+ #
16
+ # Any instance of MyField class will have the "to_hash" method
17
+ # that will contain only the accessor/reader params defined in
18
+ # the hashable macro.
19
+ module Hashable
20
+ def self.included(base)
21
+ base.extend ClassMethods
22
+ base.class_attribute :hashable_attributes
23
+ base.hashable_attributes = []
24
+ end
24
25
 
25
- def to_hash
26
- hash = self.class.hashable_attributes.each_with_object({}) do |param, h|
27
- h[param] = send(param) unless send(param).nil?
26
+ def to_hash
27
+ hash = self.class.hashable_attributes.each_with_object({}) do |param, h|
28
+ h[param] = send(param) unless send(param).nil?
29
+ end
30
+ hash.merge(_type: self.class.name.demodulize)
28
31
  end
29
- hash.merge(_type: self.class.name.demodulize)
30
- end
31
32
 
32
- module ClassMethods
33
- def hashable(*params)
34
- self.hashable_attributes = hashable_attributes.dup.concat params
33
+ module ClassMethods
34
+ def hashable(*params)
35
+ self.hashable_attributes = hashable_attributes.dup.concat params
36
+ end
35
37
  end
36
38
  end
37
39
  end
@@ -1,33 +1,37 @@
1
1
  module HungryForm
2
- module Elements::Base
3
- # The BaseOptionsElement class can be used as a base class for
4
- # fields with options, such as select or radio
5
- class OptionsElement < ActiveElement
6
- attr_accessor :options
2
+ module Elements
3
+ module Base
4
+ # The BaseOptionsElement class can be used as a base class for
5
+ # fields with options, such as select or radio
6
+ class OptionsElement < ActiveElement
7
+ attr_accessor :options
7
8
 
8
- hashable :options
9
+ hashable :options
9
10
 
10
- def initialize(name, parent, resolver, attributes = {}, &block)
11
- if attributes.key?(:options)
12
- self.options = attributes[:options].dup
13
- else
14
- fail HungryFormException, "No options provided for #{name}"
15
- end
11
+ def initialize(name, parent, resolver, attributes = {}, &block)
12
+ if attributes.key?(:options)
13
+ self.options = attributes.delete(:options)
14
+ else
15
+ fail HungryFormException, "No options provided for #{name}"
16
+ end
16
17
 
17
- unless options.is_a?(Hash)
18
- self.options = resolver.get_value(options, self)
19
- end
18
+ unless options.is_a?(Hash)
19
+ self.options = resolver.get_value(options, self)
20
+ end
20
21
 
21
- super
22
- end
22
+ self.options = ActiveSupport::HashWithIndifferentAccess.new(options)
23
+
24
+ super
25
+ end
23
26
 
24
- # Sets a value of the element
25
- # Checks the value from the resolver params against the available options
26
- def set_value
27
- if resolver.params.key?(name) && options.key?(resolver.params[name])
28
- self.value = resolver.params[name]
29
- else
30
- self.value = @attributes[:value]
27
+ # Sets a value of the element
28
+ # Checks the value from the resolver params against the available options
29
+ def set_value
30
+ if resolver.params.key?(name) && options.key?(resolver.params[name])
31
+ self.value = resolver.params[name]
32
+ else
33
+ self.value = attributes.delete(:value)
34
+ end
31
35
  end
32
36
  end
33
37
  end
@@ -6,7 +6,7 @@ module HungryForm
6
6
 
7
7
  def initialize(name, parent, resolver, attributes = {}, &block)
8
8
  super
9
- self.value = @attributes[:value] || ''
9
+ self.value = @attributes.delete(:value) || ''
10
10
  end
11
11
  end
12
12
  end
@@ -26,6 +26,10 @@ module HungryForm
26
26
  super
27
27
  self.title ||= label
28
28
  end
29
+
30
+ def to_s
31
+ self.name
32
+ end
29
33
  end
30
34
  end
31
35
  end
@@ -9,7 +9,7 @@ module HungryForm
9
9
  self.value = resolver.params[name]
10
10
  end
11
11
  else
12
- self.value = @attributes[:value]
12
+ self.value = attributes.delete(:value)
13
13
  end
14
14
  end
15
15
  end
@@ -1,31 +1,27 @@
1
1
  module HungryForm
2
2
  module Elements
3
3
  class SelectField < Base::OptionsElement
4
- attr_accessor :multiple
5
- alias_method :multiple?, :multiple
6
-
7
- hashable :multiple
8
-
9
- def initialize(name, parent, resolver, attributes = {}, &block)
10
- self.multiple = attributes[:multiple] || false
11
- super
12
- end
13
-
14
4
  # Sets a value of the element
15
5
  # Checks the value from the resolver params against the available options
16
6
  def set_value
17
7
  if resolver.params.key?(name)
8
+ self.value = resolver.params[name] if acceptable_values?
9
+ else
10
+ self.value = attributes.delete(:value)
11
+ end
12
+ end
13
+
14
+ private
18
15
 
19
- # Check if all values present in the options
20
- if multiple?
21
- acceptable_values = (resolver.params[name] - options.keys).empty?
22
- else
23
- acceptable_values = options.keys.include?(resolver.params[name])
24
- end
16
+ # Check if all of the values from the resolver params are present
17
+ # in the options.
18
+ def acceptable_values?
19
+ options_sym_keys = options.keys.map(&:to_sym)
25
20
 
26
- self.value = resolver.params[name] if acceptable_values
21
+ if @attributes[:multiple] && resolver.params[name].respond_to?(:map)
22
+ (resolver.params[name].map(&:to_sym) - options_sym_keys).empty?
27
23
  else
28
- self.value = @attributes[:value]
24
+ options_sym_keys.include?(resolver.params[name].to_sym)
29
25
  end
30
26
  end
31
27
  end
@@ -1,6 +1,6 @@
1
1
  module HungryForm
2
2
  module Elements
3
- class TextAreaField < Base::ActiveElement
3
+ class TextArea < Base::ActiveElement
4
4
  end
5
5
  end
6
6
  end
@@ -1,5 +1,13 @@
1
1
  module HungryForm
2
2
  module Elements
3
+ # Find a class of the Elements module by name
4
+ def self.find_class(name)
5
+ constants.find { |c| Class === const_get(c) && c.to_s.underscore.to_sym == name }
6
+ end
7
+
8
+ def self.all_classes
9
+ constants.select { |c| Class === const_get(c) }
10
+ end
3
11
  end
4
12
  end
5
13
 
@@ -13,5 +21,5 @@ require_relative 'elements/group'
13
21
  require_relative 'elements/html'
14
22
  require_relative 'elements/text_field'
15
23
  require_relative 'elements/select_field'
16
- require_relative 'elements/text_area_field'
24
+ require_relative 'elements/text_area'
17
25
  require_relative 'elements/radio_group'
@@ -0,0 +1,3 @@
1
+ module HungryForm
2
+ HungryFormException = Class.new(StandardError)
3
+ end
@@ -1,6 +1,7 @@
1
1
  require 'json'
2
2
  require 'active_support/core_ext/string/inflections'
3
3
  require 'active_support/core_ext/class/attribute'
4
+ require 'active_support/core_ext/hash/indifferent_access'
4
5
  require 'hungryform/version'
5
6
  require 'hungryform/resolver'
6
7
  require 'hungryform/validator'
@@ -32,7 +33,7 @@ module HungryForm
32
33
  # in the form.pages array. Pages without dependencies will be allways
33
34
  # resolved. The rest of the pages will be ignored.
34
35
  class Form
35
- attr_reader :pages
36
+ attr_reader :pages, :current_page
36
37
 
37
38
  def initialize(attributes = {}, &block)
38
39
  unless block_given?
@@ -43,6 +44,12 @@ module HungryForm
43
44
  @pages = []
44
45
 
45
46
  instance_eval(&block)
47
+
48
+ if @resolver.params[:page]
49
+ @current_page = pages.find { |p| p.name.to_s == @resolver.params[:page] }
50
+ end
51
+
52
+ @current_page ||= pages.first
46
53
  end
47
54
 
48
55
  # Create a form page
@@ -68,7 +75,7 @@ module HungryForm
68
75
  !valid?
69
76
  end
70
77
 
71
- # Get all the elements that the form consists of
78
+ # Get all the elements the form consists of
72
79
  def elements
73
80
  @resolver.elements
74
81
  end
@@ -82,5 +89,28 @@ module HungryForm
82
89
  def to_json
83
90
  JSON.generate(to_hash)
84
91
  end
92
+
93
+ # Create a hash of form elements values
94
+ def values
95
+ active_elements = elements.select do |name, el|
96
+ el.is_a? Elements::Base::ActiveElement
97
+ end
98
+
99
+ active_elements.each_with_object({}) do |(name, el), o|
100
+ o[name.to_sym] = el.value
101
+ end
102
+ end
103
+
104
+ def next_page
105
+ pages.each_cons(2) do |page, next_page|
106
+ return next_page if page == current_page
107
+ end
108
+ end
109
+
110
+ def prev_page
111
+ pages.each_cons(2) do |prev_page, page|
112
+ return prev_page if page == current_page
113
+ end
114
+ end
85
115
  end
86
116
  end
@@ -5,8 +5,9 @@ module HungryForm
5
5
  attr_accessor :elements, :params
6
6
 
7
7
  def initialize(options = {})
8
- @params = options[:params] || {}
9
- @elements = {}
8
+ self.params = ActiveSupport::HashWithIndifferentAccess.new(options[:params] || {})
9
+
10
+ self.elements = {}
10
11
  end
11
12
 
12
13
  # Gets element value by element's name.
@@ -26,22 +27,19 @@ module HungryForm
26
27
  # we get its placeholders and replace substrings in the name argument
27
28
  element.placeholders.each { |k, v| name[k] &&= v } if element
28
29
 
29
- return @elements[name].value if @elements.key?(name)
30
- return @params[name] if @params.key?(name)
31
-
32
- name
30
+ elements[name].try(:value) || params[name] || name
33
31
  end
34
32
 
35
33
  # Gets dependency rules hash and returns true or false depending on
36
34
  # the result of a recursive processing of the rules
37
35
  def resolve_dependency(dependency)
38
36
  dependency.each do |operator, arguments|
37
+ operator = operator.to_sym
38
+
39
39
  case operator
40
- when 'AND'
41
- return resolve_multi_dependency(:and, arguments)
42
- when 'OR'
43
- return resolve_multi_dependency(:or, arguments)
44
- when 'NOT'
40
+ when :and, :or
41
+ return resolve_multi_dependency(operator, arguments)
42
+ when :not
45
43
  return !resolve_dependency(arguments)
46
44
  end
47
45
 
@@ -51,13 +49,13 @@ module HungryForm
51
49
  return false if arguments.any?(&:nil?)
52
50
 
53
51
  case operator
54
- when 'EQ'
52
+ when :eq
55
53
  return arguments[0].to_s == arguments[1].to_s
56
- when 'LT'
54
+ when :lt
57
55
  return arguments[0].to_f < arguments[1].to_f
58
- when 'GT'
56
+ when :gt
59
57
  return arguments[0].to_f > arguments[1].to_f
60
- when 'SET'
58
+ when :set
61
59
  return !arguments[0].empty?
62
60
  end
63
61
  end
@@ -65,7 +63,7 @@ module HungryForm
65
63
 
66
64
  private
67
65
 
68
- # Helper method to resolve AND or OR conditions.
66
+ # Method resolves AND or OR conditions.
69
67
  # Walks through the arguments and resolves their dependencies.
70
68
  def resolve_multi_dependency(type, arguments)
71
69
  if arguments.size == 0
@@ -1,3 +1,3 @@
1
1
  module HungryForm
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.6"
3
3
  end
data/lib/hungryform.rb CHANGED
@@ -1,12 +1,29 @@
1
+ module HungryForm
2
+ class << self
3
+ attr_writer :configuration
4
+
5
+ def configuration
6
+ @configuration ||= Configuration.new
7
+ end
8
+
9
+ def configure
10
+ yield(configuration)
11
+ end
12
+
13
+ def reset_config
14
+ @configuration = Configuration.new
15
+ end
16
+ end
17
+ end
18
+
1
19
  require 'json'
2
20
  require 'active_support/core_ext/string/inflections'
3
21
  require 'active_support/core_ext/class/attribute'
22
+ require 'active_support/core_ext/object'
4
23
  require 'hungryform/version'
5
24
  require 'hungryform/form'
25
+ require 'hungryform/exceptions'
6
26
  require 'hungryform/resolver'
27
+ require 'hungryform/configuration'
7
28
  require 'hungryform/validator'
8
- require 'hungryform/elements'
9
-
10
- module HungryForm
11
- HungryFormException = Class.new(StandardError)
12
- end
29
+ require 'hungryform/elements'
@@ -1,5 +1,14 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe HungryForm::Elements::Group do
4
- it_behaves_like "a group"
4
+ let(:resolver_options) { {} }
5
+ let(:resolver) { HungryForm::Resolver.new(resolver_options) }
6
+ let(:group_options) { {} }
7
+ let(:group) { HungryForm::Elements::Group.new(:parent_name, nil, resolver, group_options) {} }
8
+ let(:options) { {} }
9
+
10
+ subject { HungryForm::Elements::Group.new(:element_name, group, resolver, options) {} }
11
+
12
+ it_behaves_like 'an element'
13
+ it_behaves_like 'a group'
5
14
  end
@@ -1,17 +1,19 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe HungryForm::Elements::Html do
4
- it_behaves_like "an element" do
5
- let(:element_options) { {} }
6
- end
4
+ let(:resolver_options) { {} }
5
+ let(:resolver) { HungryForm::Resolver.new(resolver_options) }
6
+ let(:group_options) { {} }
7
+ let(:group) { HungryForm::Elements::Group.new(:group, nil, resolver, group_options) {} }
8
+ let(:options) { { value: 'body text' } }
9
+
10
+ subject { HungryForm::Elements::Html.new(:element_name, nil, resolver, options) {} }
7
11
 
8
- let(:resolver) { HungryForm::Resolver.new() }
9
- let(:options) { {value: "body text"} }
10
- subject { HungryForm::Elements::Html.new(:html, nil, resolver, options) {} }
12
+ it_behaves_like 'an element'
11
13
 
12
- describe ".new" do
13
- it "should have a value" do
14
- expect(subject.value).to eq "body text"
14
+ describe '.new' do
15
+ it 'should have a value' do
16
+ expect(subject.value).to eq 'body text'
15
17
  end
16
18
  end
17
19
  end
@@ -1,25 +1,28 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe HungryForm::Elements::Page do
4
- let(:resolver) { HungryForm::Resolver.new() }
4
+ let(:resolver_options) { {} }
5
+ let(:resolver) { HungryForm::Resolver.new(resolver_options) }
6
+
5
7
  let(:options) { {} }
6
- let(:page) { HungryForm::Elements::Page.new(:pagename, nil, resolver, options) {} }
8
+ subject { HungryForm::Elements::Page.new(:element_name, nil, resolver, options) {} }
7
9
 
8
- it_behaves_like "a group"
10
+ it_behaves_like 'an element'
11
+ it_behaves_like 'a group'
9
12
 
10
13
  describe ".new" do
11
14
  it "should have one element" do
12
- page = HungryForm::Elements::Page.new(:pagename, nil, resolver, options) do
15
+ subject = HungryForm::Elements::Page.new(:element_name, nil, resolver, options) do
13
16
  html :html_name, value: "<p>Test html block</p>"
14
17
  end
15
- expect(page.elements.size).to eq 1
18
+ expect(subject.elements.size).to eq 1
16
19
  end
17
20
  end
18
21
 
19
22
  describe "#group" do
20
23
  it "should contain a group" do
21
- page.group(:group_name, {}) {}
22
- expect(page.elements.first.class).to eq HungryForm::Elements::Group
24
+ subject.group(:group_name, {}) {}
25
+ expect(subject.elements.first.class).to eq HungryForm::Elements::Group
23
26
  end
24
27
  end
25
28
  end
@@ -3,27 +3,21 @@ require "spec_helper"
3
3
  describe HungryForm::Elements::RadioGroup do
4
4
  let(:resolver_options) { {} }
5
5
  let(:resolver) { HungryForm::Resolver.new(resolver_options) }
6
- let(:group) { HungryForm::Elements::Group.new(:group, nil, resolver, {}) {} }
6
+ let(:group_options) { {} }
7
+ let(:group) { HungryForm::Elements::Group.new(:group, nil, resolver, group_options) {} }
7
8
 
8
- let(:element_options) do
9
+ let(:options) do
9
10
  {
10
11
  :options => {
11
12
  "1" => "First",
12
- "2" => "Second",
13
- "3" => "Third"
13
+ "element_value" => "Second" # element_value is checked in shared_active_element
14
14
  }
15
15
  }
16
16
  end
17
- subject { HungryForm::Elements::RadioGroup.new(:element_name, group, resolver, element_options) {} }
18
17
 
19
- it_behaves_like "an element with options" do
20
- let(:options_element_options) do
21
- {
22
- :options => {
23
- "1" => "First",
24
- "element_value" => "Second" # element_value is checked in shared_active_element
25
- }
26
- }
27
- end
28
- end
18
+ subject { HungryForm::Elements::RadioGroup.new(:element_name, group, resolver, options) {} }
19
+
20
+ it_behaves_like 'an element'
21
+ it_behaves_like 'an active element'
22
+ it_behaves_like 'an element with options'
29
23
  end
@@ -3,45 +3,31 @@ require "spec_helper"
3
3
  describe HungryForm::Elements::SelectField do
4
4
  let(:resolver_options) { {} }
5
5
  let(:resolver) { HungryForm::Resolver.new(resolver_options) }
6
-
7
6
  let(:group_options) { {} }
8
7
  let(:group) { HungryForm::Elements::Group.new(:group, nil, resolver, group_options) {} }
9
8
 
10
- let(:element_options) do
11
- {
12
- :options => {
13
- "1" => "First",
14
- "2" => "Second",
15
- "3" => "Third"
16
- }
17
- }
18
- end
19
- subject { HungryForm::Elements::SelectField.new(:element_name, group, resolver, element_options) {} }
9
+ let(:options) do
10
+ {
11
+ :options => {
12
+ '1' => 'First',
13
+ 'element_value' => 'Second' # element_value is checked in shared_active_element
14
+ }
15
+ }
16
+ end
20
17
 
21
- it_behaves_like "an element with options" do
22
- let(:options_element_options) do
23
- {
24
- :options => {
25
- "1" => "First",
26
- "element_value" => "Second" # element_value is checked in shared_active_element
27
- }
28
- }
29
- end
30
- end
18
+ subject { HungryForm::Elements::SelectField.new(:element_name, group, resolver, options) {} }
31
19
 
32
- describe "#set_value" do
33
- context "when multiple enabled" do
34
- it "assigns multiple values" do
35
- resolver_options[:params] = {"group_element_name" => ["1", "2", "3"]}
36
- element_options[:multiple] = true
37
- expect(subject.value).to eq(["1", "2", "3"])
20
+ it_behaves_like 'an element'
21
+ it_behaves_like 'an active element'
22
+ it_behaves_like 'an element with options'
23
+
24
+ describe '#set_value' do
25
+ context 'when multiple enabled' do
26
+ it 'assigns multiple values' do
27
+ resolver_options[:params] = {"group_element_name" => ["1", "element_value"]}
28
+ options[:multiple] = true
29
+ expect(subject.value).to eq(["1", "element_value"])
38
30
  end
39
31
  end
40
32
  end
41
-
42
- describe "#to_hash" do
43
- it "should include multiple" do
44
- expect(subject.to_hash).to include(:multiple)
45
- end
46
- end
47
33
  end
@@ -0,0 +1,52 @@
1
+ RSpec.shared_examples "an active element" do
2
+ describe ".new" do
3
+ it "should have empty error" do
4
+ expect(subject.error).to eq ""
5
+ end
6
+
7
+ it "should not be required if its parent is not visible" do
8
+ group_options[:visible] = false
9
+ options[:required] = true
10
+ expect(subject.required?).to eq false
11
+ end
12
+
13
+ it "should have a nil value" do
14
+ expect(subject.value).to be nil
15
+ end
16
+
17
+ it "should have a value from form params" do
18
+ resolver_options[:params]= {"group_element_name" => "element_value" }
19
+ expect(subject.value).to eq "element_value"
20
+ end
21
+
22
+ it "should have a value from element structure" do
23
+ options[:value] = "element_value"
24
+ expect(subject.value).to eq "element_value"
25
+ end
26
+ end
27
+
28
+ describe "#valid?" do
29
+ context "when required" do
30
+ before(:each) { options[:required] = true }
31
+
32
+ it "is valid" do
33
+ subject.value = "value"
34
+ expect(subject.valid?).to eq true
35
+ expect(subject.error).to eq ''
36
+ end
37
+
38
+ it "is invalid" do
39
+ subject.value = ''
40
+ expect(subject.valid?).to eq false
41
+ expect(subject.error).to eq 'This field is required'
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "#to_hash" do
47
+ it 'should include required, value and error' do
48
+ options.merge!(value: '', required: true)
49
+ expect(subject.to_hash).to include(:required, :value, :error)
50
+ end
51
+ end
52
+ end