volt 0.8.27.beta3 → 0.8.27.beta4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/CHANGELOG.md +11 -0
  4. data/CONTRIBUTING.md +3 -2
  5. data/{Readme.md → README.md} +9 -12
  6. data/Rakefile +2 -9
  7. data/VERSION +1 -1
  8. data/app/volt/models/user.rb +8 -0
  9. data/app/volt/tasks/live_query/data_store.rb +13 -5
  10. data/app/volt/tasks/live_query/live_query.rb +45 -3
  11. data/app/volt/tasks/live_query/live_query_pool.rb +9 -1
  12. data/app/volt/tasks/query_tasks.rb +20 -2
  13. data/app/volt/tasks/store_tasks.rb +37 -20
  14. data/app/volt/tasks/user_tasks.rb +15 -13
  15. data/lib/volt/boot.rb +5 -3
  16. data/lib/volt/cli/console.rb +1 -0
  17. data/lib/volt/cli/generate.rb +15 -0
  18. data/lib/volt/cli.rb +19 -12
  19. data/lib/volt/config.rb +1 -1
  20. data/lib/volt/controllers/model_controller.rb +13 -3
  21. data/lib/volt/extra_core/extra_core.rb +1 -0
  22. data/lib/volt/extra_core/hash.rb +26 -0
  23. data/lib/volt/extra_core/object.rb +5 -1
  24. data/lib/volt/models/array_model.rb +86 -35
  25. data/lib/volt/models/associations.rb +53 -0
  26. data/lib/volt/models/buffer.rb +22 -10
  27. data/lib/volt/models/dirty.rb +88 -0
  28. data/lib/volt/models/errors.rb +21 -0
  29. data/lib/volt/models/field_helpers.rb +2 -2
  30. data/lib/volt/models/listener_tracker.rb +17 -0
  31. data/lib/volt/models/model.rb +213 -69
  32. data/lib/volt/models/model_helpers.rb +27 -17
  33. data/lib/volt/models/permissions.rb +246 -0
  34. data/lib/volt/models/persistors/array_store.rb +149 -81
  35. data/lib/volt/models/persistors/base.rb +16 -0
  36. data/lib/volt/models/persistors/cookies.rb +14 -9
  37. data/lib/volt/models/persistors/flash.rb +3 -0
  38. data/lib/volt/models/persistors/local_store.rb +0 -16
  39. data/lib/volt/models/persistors/model_store.rb +1 -2
  40. data/lib/volt/models/persistors/query/normalizer.rb +51 -0
  41. data/lib/volt/models/persistors/query/query_listener.rb +21 -5
  42. data/lib/volt/models/persistors/query/query_listener_pool.rb +0 -9
  43. data/lib/volt/models/persistors/store.rb +8 -0
  44. data/lib/volt/models/persistors/store_state.rb +4 -27
  45. data/lib/volt/models/state_helpers.rb +11 -0
  46. data/lib/volt/models/state_manager.rb +43 -0
  47. data/lib/volt/models/url.rb +5 -5
  48. data/lib/volt/models/validations.rb +38 -41
  49. data/lib/volt/models/validators/email_validator.rb +4 -9
  50. data/lib/volt/models/validators/format_validator.rb +23 -8
  51. data/lib/volt/models/validators/length_validator.rb +2 -2
  52. data/lib/volt/models/validators/numericality_validator.rb +7 -3
  53. data/lib/volt/models/validators/phone_number_validator.rb +4 -9
  54. data/lib/volt/models/validators/presence_validator.rb +2 -2
  55. data/lib/volt/models/validators/unique_validator.rb +2 -2
  56. data/lib/volt/models/validators/user_validation.rb +6 -0
  57. data/lib/volt/models.rb +8 -3
  58. data/lib/volt/page/bindings/attribute_binding.rb +10 -4
  59. data/lib/volt/page/bindings/content_binding.rb +9 -5
  60. data/lib/volt/page/bindings/if_binding.rb +25 -2
  61. data/lib/volt/page/bindings/template_binding.rb +19 -1
  62. data/lib/volt/page/bindings/yield_binding.rb +31 -0
  63. data/lib/volt/page/page.rb +11 -16
  64. data/lib/volt/reactive/class_eventable.rb +71 -0
  65. data/lib/volt/reactive/computation.rb +79 -10
  66. data/lib/volt/reactive/dependency.rb +27 -8
  67. data/lib/volt/reactive/eventable.rb +36 -22
  68. data/lib/volt/reactive/reactive_array.rb +2 -3
  69. data/lib/volt/reactive/reactive_hash.rb +8 -3
  70. data/lib/volt/router/routes.rb +2 -1
  71. data/lib/volt/server/component_templates.rb +0 -2
  72. data/lib/volt/server/html_parser/component_view_scope.rb +59 -0
  73. data/lib/volt/server/html_parser/view_handler.rb +3 -0
  74. data/lib/volt/server/html_parser/view_parser.rb +1 -0
  75. data/lib/volt/server/html_parser/view_scope.rb +17 -41
  76. data/lib/volt/server/rack/component_paths.rb +1 -10
  77. data/lib/volt/server/rack/index_files.rb +9 -4
  78. data/lib/volt/server/rack/opal_files.rb +22 -14
  79. data/lib/volt/server/rack/quiet_common_logger.rb +1 -1
  80. data/lib/volt/server/socket_connection_handler.rb +4 -0
  81. data/lib/volt/spec/setup.rb +26 -0
  82. data/lib/volt/tasks/dispatcher.rb +11 -0
  83. data/lib/volt/utils/event_counter.rb +29 -0
  84. data/lib/volt/utils/generic_pool.rb +12 -0
  85. data/lib/volt/utils/modes.rb +40 -0
  86. data/lib/volt/utils/promise_patch.rb +66 -0
  87. data/lib/volt/utils/timers.rb +33 -0
  88. data/lib/volt/volt/users.rb +48 -5
  89. data/lib/volt.rb +4 -0
  90. data/spec/apps/kitchen_sink/Gemfile +3 -1
  91. data/spec/apps/kitchen_sink/app/main/config/routes.rb +9 -8
  92. data/spec/apps/kitchen_sink/app/main/controllers/main_controller.rb +9 -0
  93. data/spec/apps/kitchen_sink/app/main/controllers/yield_component_controller.rb +5 -0
  94. data/spec/apps/kitchen_sink/app/main/views/main/cookie_test.html +1 -1
  95. data/spec/apps/kitchen_sink/app/main/views/main/index.html +1 -1
  96. data/spec/apps/kitchen_sink/app/main/views/main/main.html +2 -1
  97. data/spec/apps/kitchen_sink/app/main/views/main/yield.html +18 -0
  98. data/spec/apps/kitchen_sink/app/main/views/yield-component/index.html +4 -0
  99. data/spec/extra_core/logger_spec.rb +4 -2
  100. data/spec/integration/user_spec.rb +42 -42
  101. data/spec/integration/yield_spec.rb +18 -0
  102. data/spec/models/associations_spec.rb +37 -0
  103. data/spec/models/dirty_spec.rb +102 -0
  104. data/spec/models/model_spec.rb +64 -8
  105. data/spec/models/model_state_spec.rb +24 -0
  106. data/spec/models/permissions_spec.rb +96 -0
  107. data/spec/models/user_spec.rb +8 -5
  108. data/spec/models/user_validation_spec.rb +24 -0
  109. data/spec/models/validations_spec.rb +44 -5
  110. data/spec/models/validators/email_validator_spec.rb +109 -82
  111. data/spec/models/validators/format_validator_spec.rb +4 -107
  112. data/spec/models/validators/length_validator_spec.rb +9 -9
  113. data/spec/models/validators/phone_number_validator_spec.rb +60 -103
  114. data/spec/models/validators/shared_examples_for_validators.rb +123 -0
  115. data/spec/reactive/class_eventable_spec.rb +37 -0
  116. data/spec/reactive/computation_spec.rb +68 -3
  117. data/spec/reactive/dependency_spec.rb +71 -0
  118. data/spec/reactive/eventable_spec.rb +21 -0
  119. data/spec/reactive/reactive_hash_spec.rb +12 -0
  120. data/spec/router/routes_spec.rb +50 -50
  121. data/spec/server/html_parser/view_parser_spec.rb +0 -3
  122. data/spec/server/rack/component_paths_spec.rb +11 -0
  123. data/spec/server/rack/quite_common_logger_spec.rb +3 -4
  124. data/spec/spec_helper.rb +7 -3
  125. data/templates/component/config/dependencies.rb +1 -7
  126. data/templates/component/config/routes.rb +1 -1
  127. data/templates/component/controllers/main_controller.rb.tt +20 -0
  128. data/templates/component/views/{index → main}/index.html.tt +0 -0
  129. data/templates/newgem/lib/newgem.rb.tt +1 -3
  130. data/templates/project/app/main/config/routes.rb +3 -3
  131. data/templates/project/app/main/views/main/main.html.tt +4 -4
  132. data/templates/project/config/app.rb.tt +6 -0
  133. data/volt.gemspec +11 -7
  134. metadata +96 -42
  135. data/lib/volt/models/model_state.rb +0 -21
  136. data/templates/component/controllers/main_controller.rb +0 -18
@@ -11,7 +11,7 @@ describe Volt::User do
11
11
  describe '.login_field' do
12
12
  subject { Volt::User.login_field }
13
13
 
14
- context 'when use_username is set to true' do
14
+ describe 'when use_username is set to true' do
15
15
  before do
16
16
  allow(Volt).to receive(:config).and_return FakeConfig.new
17
17
  end
@@ -21,7 +21,7 @@ describe Volt::User do
21
21
  end
22
22
  end
23
23
 
24
- context 'when use_username is not set' do
24
+ describe 'when use_username is not set' do
25
25
  it "returns :email" do
26
26
  expect(subject).to eq :email
27
27
  end
@@ -34,7 +34,7 @@ describe Volt::User do
34
34
  subject { user.password = 'test' }
35
35
 
36
36
  if RUBY_PLATFORM != 'opal'
37
- context 'when it is a Volt server' do
37
+ describe 'when it is a Volt server' do
38
38
  before do
39
39
  allow(BCrypt::Password).to receive(:create).with('test').
40
40
  and_return 'hashed-password'
@@ -54,15 +54,18 @@ describe Volt::User do
54
54
  end
55
55
  end
56
56
 
57
- context 'when it is not a Volt server' do
57
+ describe 'when it is not a Volt server' do
58
58
  before do
59
59
  allow(Volt).to receive(:server?).and_return false
60
60
  end
61
61
 
62
+ subject { user.password = 'a valid test password' }
63
+
64
+
62
65
  it 'sets _password to passed value' do
63
66
  subject
64
67
 
65
- expect(user._password).to eq 'test'
68
+ expect(user._password).to eq('a valid test password')
66
69
  end
67
70
  end
68
71
  end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe Volt::UserValidatorHelpers do
5
+ context "with user" do
6
+ before do
7
+ allow(Volt).to receive(:user_id) { 294 }
8
+ end
9
+
10
+ it 'should assign user_id when owning by a user' do
11
+ todo = TestUserTodo.new
12
+ expect(todo._user_id).to eq(294)
13
+ end
14
+
15
+ it 'should not allow the user_id to be changed' do
16
+ todo = TestUserTodo.new
17
+ expect(todo._user_id).to eq(294)
18
+
19
+ todo._user_id = 500
20
+
21
+ expect(todo._user_id).to eq(294)
22
+ end
23
+ end
24
+ end
@@ -16,6 +16,7 @@ describe Volt::Model do
16
16
  end
17
17
 
18
18
  it 'should return errors for all failed validations' do
19
+ model.validate!
19
20
  expect(model.errors).to eq(
20
21
  count: ['must be a number'],
21
22
  description: ['needs to be longer'],
@@ -27,9 +28,10 @@ describe Volt::Model do
27
28
  end
28
29
 
29
30
  it 'should show all fields in marked errors once saved' do
30
- model.save!
31
+ buffer = model.buffer
32
+ buffer.save!
31
33
 
32
- expect(model.marked_errors.keys).to eq(
34
+ expect(buffer.marked_errors.keys).to eq(
33
35
  [:count, :description, :email, :name, :phone_number, :username]
34
36
  )
35
37
  end
@@ -72,6 +74,11 @@ describe Volt::Model do
72
74
  message = 'must be specified'
73
75
  it_should_behave_like 'a built in validation', :username, message
74
76
  end
77
+
78
+ it 'should fail on non-numbers' do
79
+ model._count = 'not a number'
80
+ expect(model.errors[:count]).to eq(['must be a number'])
81
+ end
75
82
  end
76
83
 
77
84
  describe 'validators with multiple criteria' do
@@ -98,11 +105,43 @@ describe Volt::Model do
98
105
  end
99
106
 
100
107
  context 'when one fails' do
101
- before { model._special_field = 'regex' }
108
+ before do
109
+ # Prevent rollback for testing
110
+ allow(model).to receive(:revert_changes!)
111
+ model._special_field = 'regex'
112
+ end
102
113
 
103
114
  it 'returns an array with a single error' do
104
- expect(model.errors).to eq({ special_field: [ proc_message ] })
115
+ expect(model.errors.to_h).to eq({ special_field: [ proc_message ] })
105
116
  end
106
117
  end
107
118
  end
108
- end
119
+
120
+ it 'should report if errors have happened in changed attributes' do
121
+ # Prevent revert_changes! so it doesn't revert on failed values
122
+ allow(model).to receive(:revert_changes!)
123
+
124
+ expect(model.error_in_changed_attributes?).to eq(false)
125
+
126
+ model._not_validated_attr = 'yes'
127
+ expect(model.error_in_changed_attributes?).to eq(false)
128
+
129
+ model._name = '5' # fail, too short
130
+ expect(model.changed?(:name)).to eq(true)
131
+ expect(model.error_in_changed_attributes?).to eq(true)
132
+
133
+ model._name = 'Jimmy'
134
+ expect(model.error_in_changed_attributes?).to eq(false)
135
+ end
136
+
137
+ it 'should revert changes which fail a validation' do
138
+ model._name = 'bob' # fails too short validation
139
+ expect(model._name).to eq(nil)
140
+
141
+ model._name = 'Jimmy' # long enough, passes
142
+ expect(model._name).to eq('Jimmy')
143
+
144
+ model._name = 'ok' # fails again
145
+ expect(model._name).to eq('Jimmy')
146
+ end
147
+ end
@@ -1,120 +1,147 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Volt::EmailValidator do
4
- subject { Volt::EmailValidator.new(*params) }
5
- let(:params) { [model, field_name, options] }
6
-
7
- let(:model) { Volt::Model.new email: email }
8
- let(:field_name) { :email }
9
- let(:options) { true }
3
+ describe Volt::Model do
4
+ let(:model) { test_model_class.new }
5
+
6
+ let(:test_model_class) do
7
+ Class.new(Volt::Model) do
8
+ validate :count, numericality: { min: 5, max: 10 }
9
+ validate :description, length: { message: 'needs to be longer',
10
+ length: 50 }
11
+ validate :email, email: true
12
+ validate :name, length: 4
13
+ validate :phone_number, phone_number: true
14
+ validate :username, presence: true
15
+ end
16
+ end
10
17
 
11
- let(:valid_email) { 'test@example.com' }
12
- let(:invalid_email) { 'test@example-com' }
13
- let(:email) { valid_email }
18
+ it 'should return errors for all failed validations' do
19
+ model.validate!
20
+ expect(model.errors).to eq(
21
+ count: ['must be a number'],
22
+ description: ['needs to be longer'],
23
+ email: ['must be an email address'],
24
+ name: ['must be at least 4 characters'],
25
+ phone_number: ['must be a phone number with area or country code'],
26
+ username: ['must be specified']
27
+ )
28
+ end
14
29
 
15
- describe '.validate' do
16
- let(:result) { described_class.validate(*params.dup.insert(1, nil)) }
30
+ it 'should show all fields in marked errors once saved' do
31
+ buffer = model.buffer
32
+ buffer.save!
17
33
 
18
- before do
19
- allow(described_class).to receive(:new).and_return subject
20
- allow(subject).to receive(:errors).and_call_original
34
+ expect(buffer.marked_errors.keys).to eq(
35
+ [:count, :description, :email, :name, :phone_number, :username]
36
+ )
37
+ end
21
38
 
22
- result
39
+ describe 'builtin validations' do
40
+ shared_examples_for 'a built in validation' do |field, message|
41
+ specify do
42
+ expect { model.mark_field! field }
43
+ .to change { model.marked_errors }
44
+ .from({}).to({ field => [message ] })
45
+ end
23
46
  end
24
47
 
25
- it 'initializes an email validator with the provided arguments' do
26
- expect(described_class).to have_received(:new).with(*params)
48
+ describe 'numericality' do
49
+ message = 'must be a number'
50
+ it_should_behave_like 'a built in validation', :count, message
27
51
  end
28
52
 
29
- it 'calls errors on the email validator' do
30
- expect(subject).to have_received :errors
53
+ describe 'length' do
54
+ message = 'needs to be longer'
55
+ it_should_behave_like 'a built in validation', :description, message
31
56
  end
32
57
 
33
- it 'returns the result of calling errors on the validator' do
34
- expect(subject.errors).to eq result
58
+ describe 'email' do
59
+ message = 'must be an email address'
60
+ it_should_behave_like 'a built in validation', :email, message
35
61
  end
36
- end
37
-
38
- describe '#valid?' do
39
- context 'when using the default regex' do
40
- let(:options) { true }
41
62
 
42
- context 'when the email is valid' do
43
- let(:email) { valid_email }
44
-
45
- specify { expect(subject.valid?).to eq true }
46
- end
47
-
48
- context 'when the email is missing a TLD' do
49
- let(:email) { 'test@example' }
63
+ describe 'name' do
64
+ message = 'must be at least 4 characters'
65
+ it_should_behave_like 'a built in validation', :name, message
66
+ end
50
67
 
51
- specify { expect(subject.valid?).to eq false }
52
- end
68
+ describe 'phone_number' do
69
+ message = 'must be a phone number with area or country code'
70
+ it_should_behave_like 'a built in validation', :phone_number, message
71
+ end
53
72
 
54
- context 'when the email TLD is only one character' do
55
- let(:email) { 'test@example.c' }
73
+ describe 'presence' do
74
+ message = 'must be specified'
75
+ it_should_behave_like 'a built in validation', :username, message
76
+ end
56
77
 
57
- specify { expect(subject.valid?).to eq false }
58
- end
78
+ it 'should fail on non-numbers' do
79
+ model._count = 'not a number'
80
+ expect(model.errors[:count]).to eq(['must be a number'])
81
+ end
82
+ end
59
83
 
60
- context 'when the email is missing an username' do
61
- let(:email) { '@example.com' }
84
+ describe 'validators with multiple criteria' do
85
+ let(:regex_message) { 'regex failed' }
86
+ let(:proc_message) { 'proc failed' }
62
87
 
63
- specify { expect(subject.valid?).to eq false }
88
+ let(:test_model_class) do
89
+ Class.new(Volt::Model) do
90
+ validate :special_field, format: [
91
+ { with: /regex/, message: 'regex failed' },
92
+ { with: ->(x) {x == false}, message: 'proc failed' }
93
+ ]
64
94
  end
95
+ end
65
96
 
66
- context 'when the email is missing the @ symbol' do
67
- let(:email) { 'test.example.com' }
97
+ context 'when multiple fail' do
98
+ before { model._special_field = 'nope' }
68
99
 
69
- specify { expect(subject.valid?).to eq false }
100
+ it 'returns an array of errors' do
101
+ expect(model.errors).to eq({
102
+ special_field: [ regex_message, proc_message ]
103
+ })
70
104
  end
71
105
  end
72
106
 
73
- context 'when using a custom regex' do
74
- let(:options) { { with: /.+\@.+/ } }
75
-
76
- context 'and the email qualifies' do
77
- let(:email) { 'test@example' }
78
-
79
- specify { expect(subject.valid?).to eq true }
107
+ context 'when one fails' do
108
+ before do
109
+ # Prevent rollback for testing
110
+ allow(model).to receive(:revert_changes!)
111
+ model._special_field = 'regex'
80
112
  end
81
113
 
82
- context 'and the email does not qualify' do
83
- let(:email) { 'test$example' }
84
-
85
- specify { expect(subject.valid?).to eq false }
114
+ it 'returns an array with a single error' do
115
+ expect(model.errors.to_h).to eq({ special_field: [ proc_message ] })
86
116
  end
87
117
  end
88
118
  end
89
119
 
90
- describe '#errors' do
91
- context 'when the model has a valid email' do
92
- let(:email) { valid_email }
120
+ it 'should report if errors have happened in changed attributes' do
121
+ # Prevent revert_changes! so it doesn't revert on failed values
122
+ allow(model).to receive(:revert_changes!)
93
123
 
94
- it 'returns an empty error hash' do
95
- expect(subject.errors).to eq({})
96
- end
97
- end
124
+ expect(model.error_in_changed_attributes?).to eq(false)
98
125
 
99
- context 'when the model has an invalid email' do
100
- let(:email) { invalid_email }
126
+ model._not_validated_attr = 'yes'
127
+ expect(model.error_in_changed_attributes?).to eq(false)
101
128
 
102
- it 'returns an array of errors for email' do
103
- expect(subject.errors).to eq(email: ['must be an email address'])
104
- end
105
- end
129
+ model._name = '5' # fail, too short
130
+ expect(model.changed?(:name)).to eq(true)
131
+ expect(model.error_in_changed_attributes?).to eq(true)
106
132
 
107
- context 'when provided a custom error message' do
108
- let(:options) { { message: custom_message } }
109
- let(:custom_message) { 'this is a custom message' }
133
+ model._name = 'Jimmy'
134
+ expect(model.error_in_changed_attributes?).to eq(false)
135
+ end
110
136
 
111
- context 'and the email is invalid' do
112
- let(:email) { invalid_email }
137
+ it 'should revert changes which fail a validation' do
138
+ model._name = 'bob' # fails too short validation
139
+ expect(model._name).to eq(nil)
113
140
 
114
- it 'returns errors with the custom message' do
115
- expect(subject.errors).to eq(email: [custom_message])
116
- end
117
- end
118
- end
141
+ model._name = 'Jimmy' # long enough, passes
142
+ expect(model._name).to eq('Jimmy')
143
+
144
+ model._name = 'ok' # fails again
145
+ expect(model._name).to eq('Jimmy')
119
146
  end
120
- end
147
+ end
@@ -1,10 +1,11 @@
1
1
  require 'spec_helper'
2
+ require 'models/validators/shared_examples_for_validators'
2
3
 
3
4
  describe Volt::FormatValidator do
4
5
  subject { described_class.new(*init_params) }
5
6
 
6
7
  let(:init_params) { [ model, field_name ] }
7
- let(:validate_params) { [ model, nil, field_name, options ] }
8
+ let(:validate_params) { [ model, field_name, options ] }
8
9
 
9
10
  let(:model) { Volt::Model.new field: field_content }
10
11
  let(:field_name) { :field }
@@ -26,9 +27,7 @@ describe Volt::FormatValidator do
26
27
 
27
28
  let(:validate) { described_class.validate(*validate_params) }
28
29
 
29
- before do
30
- allow(described_class).to receive(:new).and_return subject
31
- end
30
+ it_behaves_like 'a format validator'
32
31
 
33
32
  context 'when no criteria is provided' do
34
33
  before { validate }
@@ -39,106 +38,4 @@ describe Volt::FormatValidator do
39
38
 
40
39
  specify { expect(subject).to be_valid }
41
40
  end
42
-
43
- context 'when the only criterion is a regex' do
44
- let(:options) { regex_opts }
45
-
46
- before { validate }
47
-
48
- context 'and the field matches' do
49
- let(:field_content) { valid_content }
50
-
51
- it 'should have no errors' do
52
- expect(subject.errors).to eq({})
53
- end
54
-
55
- specify { expect(subject).to be_valid }
56
- end
57
-
58
- context 'and the field does not match' do
59
- let(:field_content) { invalid_content }
60
-
61
- it 'should report the related error message' do
62
- expect(subject.errors).to eq field_name => [regex_message]
63
- end
64
-
65
- specify { expect(subject).to_not be_valid }
66
- end
67
- end
68
-
69
- context 'when the only criterion is a block' do
70
- let(:options) { proc_opts }
71
-
72
- before { validate }
73
-
74
- context 'and the field passes the block' do
75
- let(:field_content) { valid_content }
76
-
77
- it 'should have no errors' do
78
- expect(subject.errors).to eq({})
79
- end
80
-
81
- specify { expect(subject).to be_valid }
82
- end
83
-
84
- context 'and the field fails the block' do
85
- let(:field_content) { invalid_content }
86
-
87
- it 'should report the related error message' do
88
- expect(subject.errors).to eq field_name => [proc_message]
89
- end
90
-
91
- specify { expect(subject).to_not be_valid }
92
- end
93
- end
94
-
95
- context 'when there is both regex and block criteria' do
96
- let(:options) { [ regex_opts, proc_opts ] }
97
-
98
- before { validate }
99
-
100
- context 'and the field passes all criteria' do
101
- let(:field_content) { valid_content }
102
-
103
- it 'should have no errors' do
104
- expect(subject.errors).to eq({})
105
- end
106
-
107
- specify { expect(subject).to be_valid }
108
- end
109
-
110
- context 'and the field fails the regex' do
111
- let(:regex) { /^invalid/ }
112
-
113
- it 'should report the related error message' do
114
- expect(subject.errors).to eq field_name => [regex_message]
115
- end
116
-
117
- specify { expect(subject).to_not be_valid }
118
- end
119
-
120
- context 'and the field fails the block' do
121
- let(:proc_regex) { /^invalid/ }
122
-
123
- it 'should report the related error message' do
124
- expect(subject.errors).to eq field_name => [proc_message]
125
- end
126
-
127
- specify { expect(subject).to_not be_valid }
128
- end
129
-
130
- context 'and the field fails both the regex and the block' do
131
- let(:field_content) { invalid_content }
132
-
133
- it 'should report the regex error message' do
134
- expect(subject.errors[field_name]).to include regex_message
135
- end
136
-
137
- it 'should report the proc error message' do
138
- expect(subject.errors[field_name]).to include proc_message
139
- end
140
-
141
- specify { expect(subject).to_not be_valid }
142
- end
143
- end
144
- end
41
+ end
@@ -2,22 +2,22 @@ require 'spec_helper'
2
2
 
3
3
  describe Volt::LengthValidator do
4
4
  subject { Volt::LengthValidator.validate(*params) }
5
- let(:params) { [model, nil, field_name, options] }
5
+ let(:params) { [model, field_name, options] }
6
6
 
7
7
  let(:model) { Volt::Model.new name: name }
8
8
  let(:field_name) { :name }
9
9
  let(:name) { "John Doe" }
10
10
 
11
11
  describe '.validate' do
12
- context 'when options is a Fixnum' do
12
+ describe 'when options is a Fixnum' do
13
13
  let(:options) { 5 }
14
14
 
15
- context 'when name is "John Doe"' do
15
+ describe 'when name is "John Doe"' do
16
16
  let(:name) { "John Doe" }
17
17
  it { expect(subject).to eq({}) }
18
18
  end
19
19
 
20
- context 'when name is "John"' do
20
+ describe 'when name is "John"' do
21
21
  let(:name) { "John" }
22
22
  it do
23
23
  expect(subject).to eq({
@@ -27,17 +27,17 @@ describe Volt::LengthValidator do
27
27
  end
28
28
  end
29
29
 
30
- context 'when options is a Hash' do
30
+ describe 'when options is a Hash' do
31
31
  let(:options) do
32
32
  { length: 5, maximum: 10 }
33
33
  end
34
34
 
35
- context 'when name is "John Doe"' do
35
+ describe 'when name is "John Doe"' do
36
36
  let(:name) { "John Doe" }
37
37
  it { expect(subject).to eq({}) }
38
38
  end
39
39
 
40
- context 'when name is "John"' do
40
+ describe 'when name is "John"' do
41
41
  let(:name) { "John" }
42
42
  it do
43
43
  if RUBY_PLATFORM == 'opal'
@@ -52,7 +52,7 @@ describe Volt::LengthValidator do
52
52
  end
53
53
  end
54
54
 
55
- context 'when name is "Zach Galifianakis"' do
55
+ describe 'when name is "Zach Galifianakis"' do
56
56
  let(:name) { "Zach Galifianakis" }
57
57
  it do
58
58
  if RUBY_PLATFORM == 'opal'
@@ -68,7 +68,7 @@ describe Volt::LengthValidator do
68
68
  end
69
69
  end
70
70
 
71
- context 'when options not a Fixnum or a Hash' do
71
+ describe 'when options not a Fixnum or a Hash' do
72
72
  let(:options) { 'string' }
73
73
 
74
74
  it "raises an exception" do