oscillator 0.0.2 → 0.0.3

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.
@@ -1,6 +1,6 @@
1
1
  require 'oscillator/version'
2
- require 'oscillator/file_size_validator'
3
- require 'oscillator/canonical_uploader_path'
2
+ require 'oscillator/validations'
3
+ require 'oscillator/file_location_resolver'
4
4
 
5
5
  module Oscillator
6
6
  end
@@ -0,0 +1,11 @@
1
+ module Oscillator
2
+ module FileLocationResolver
3
+ def filename
4
+ "#{mounted_as}.#{file.extension.downcase}" if @filename
5
+ end
6
+
7
+ def store_dir
8
+ "#{model.class.name.underscore}/#{model.id}"
9
+ end
10
+ end
11
+ end
@@ -1,68 +1,70 @@
1
- # lib/file_size_validator.rb
2
1
  # Based on: https://gist.github.com/795665
2
+ require 'singleton'
3
3
 
4
- class FileSizeValidator < ActiveModel::EachValidator
5
- MESSAGES = { :is => :wrong_size, :minimum => :size_too_small, :maximum => :size_too_big }.freeze
6
- CHECKS = { :is => :==, :minimum => :>=, :maximum => :<= }.freeze
4
+ module Oscillator
5
+ class FileSizeValidator < ActiveModel::EachValidator
6
+ MESSAGES = { :is => :wrong_size, :minimum => :size_too_small, :maximum => :size_too_big }.freeze
7
+ CHECKS = { :is => :==, :minimum => :>=, :maximum => :<= }.freeze
7
8
 
8
- DEFAULT_TOKENIZER = lambda { |value| value.split(//) }
9
- RESERVED_OPTIONS = [:minimum, :maximum, :within, :is, :tokenizer, :too_short, :too_long]
9
+ DEFAULT_TOKENIZER = lambda { |value| value.split(//) }
10
+ RESERVED_OPTIONS = [:minimum, :maximum, :within, :is, :tokenizer, :too_short, :too_long]
10
11
 
11
- def initialize(options)
12
- if range = (options.delete(:in) || options.delete(:within))
13
- raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range)
14
- options[:minimum], options[:maximum] = range.begin, range.end
15
- options[:maximum] -= 1 if range.exclude_end?
16
- end
12
+ def initialize(options)
13
+ if range = (options.delete(:in) || options.delete(:within))
14
+ raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range)
15
+ options[:minimum], options[:maximum] = range.begin, range.end
16
+ options[:maximum] -= 1 if range.exclude_end?
17
+ end
17
18
 
18
- super
19
- end
19
+ super
20
+ end
20
21
 
21
- def check_validity!
22
- keys = CHECKS.keys & options.keys
22
+ def check_validity!
23
+ keys = CHECKS.keys & options.keys
23
24
 
24
- if keys.empty?
25
- raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'
26
- end
25
+ if keys.empty?
26
+ raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'
27
+ end
27
28
 
28
- keys.each do |key|
29
- value = options[key]
29
+ keys.each do |key|
30
+ value = options[key]
30
31
 
31
- unless value.is_a?(Integer) && value >= 0
32
- raise ArgumentError, ":#{key} must be a nonnegative Integer"
32
+ unless value.is_a?(Integer) && value >= 0
33
+ raise ArgumentError, ":#{key} must be a nonnegative Integer"
34
+ end
33
35
  end
34
36
  end
35
- end
36
37
 
37
- def validate_each(record, attribute, value)
38
- raise(ArgumentError, "A CarrierWave::Uploader::Base object was expected") unless value.kind_of? CarrierWave::Uploader::Base
38
+ def validate_each(record, attribute, value)
39
+ raise(ArgumentError, "A CarrierWave::Uploader::Base object was expected") unless value.kind_of? CarrierWave::Uploader::Base
39
40
 
40
- value = (options[:tokenizer] || DEFAULT_TOKENIZER).call(value) if value.kind_of?(String)
41
+ value = (options[:tokenizer] || DEFAULT_TOKENIZER).call(value) if value.kind_of?(String)
41
42
 
42
- CHECKS.each do |key, validity_check|
43
- next unless check_value = options[key]
43
+ CHECKS.each do |key, validity_check|
44
+ next unless check_value = options[key]
44
45
 
45
- value ||= [] if key == :maximum
46
+ value ||= [] if key == :maximum
46
47
 
47
- value_size = value.size
48
- next if value_size.send(validity_check, check_value)
48
+ value_size = value.size
49
+ next if value_size.send(validity_check, check_value)
49
50
 
50
- errors_options = options.except(*RESERVED_OPTIONS)
51
- errors_options[:file_size] = help.number_to_human_size check_value
51
+ errors_options = options.except(*RESERVED_OPTIONS)
52
+ errors_options[:file_size] = help.number_to_human_size check_value
52
53
 
53
- default_message = options[MESSAGES[key]]
54
- errors_options[:message] ||= default_message if default_message
54
+ default_message = options[MESSAGES[key]]
55
+ errors_options[:message] ||= default_message if default_message
55
56
 
56
- record.errors.add(attribute, MESSAGES[key], errors_options)
57
+ record.errors.add(attribute, MESSAGES[key], errors_options)
58
+ end
57
59
  end
58
- end
59
60
 
60
- def help
61
- Helper.instance
62
- end
61
+ def help
62
+ Helper.instance
63
+ end
63
64
 
64
- class Helper
65
- include Singleton
66
- include ActionView::Helpers::NumberHelper
65
+ class Helper
66
+ include ::Singleton
67
+ include ::ActionView::Helpers::NumberHelper
68
+ end
67
69
  end
68
70
  end
@@ -0,0 +1 @@
1
+ require 'oscillator/file_size_validator'
@@ -1,3 +1,3 @@
1
1
  module Oscillator
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ class ResolvableUploader < CarrierWave::Uploader::Base
4
+ include Oscillator::FileLocationResolver
5
+ end
6
+
7
+ class MyModel
8
+ def id
9
+ 123
10
+ end
11
+ end
12
+
13
+ describe Oscillator::FileLocationResolver, :carrier_wave do
14
+ let(:model) { MyModel.new }
15
+ let(:uploader) { ResolvableUploader.new model, :resolver }
16
+
17
+ describe '#filename' do
18
+ context 'when a file has been stored' do
19
+ before { uploader.store! File.open(@test_image_directory + 'SMALL-LOGO-SHORT-AND-WIDE.PNG') }
20
+
21
+ it 'is the mounted as name along with the lowercase file extension' do
22
+ uploader.filename.should eql 'resolver.png'
23
+ end
24
+ end
25
+
26
+ context 'when a file has not been stored' do
27
+ it 'is nil' do
28
+ uploader.filename.should be_nil
29
+ end
30
+ end
31
+ end
32
+
33
+ describe '#store_dir' do
34
+ it 'is the underscored class name followed by a subfolder for the ID of the model' do
35
+ uploader.store_dir.should eql 'my_model/123'
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,164 @@
1
+ require 'spec_helper'
2
+
3
+ class ImageUploader < CarrierWave::Uploader::Base
4
+ end
5
+
6
+ class ValidatableClassWithMinimum
7
+ include ActiveModel::Validations
8
+ extend CarrierWave::Mount
9
+
10
+ attr_accessor :image
11
+
12
+ mount_uploader :image
13
+
14
+ validates :image,
15
+ :'oscillator/file_size' => {
16
+ minimum: 2 }
17
+ end
18
+
19
+ class ValidatableClassWithMaximum
20
+ include ActiveModel::Validations
21
+ extend CarrierWave::Mount
22
+
23
+ attr_accessor :image
24
+
25
+ mount_uploader :image
26
+
27
+ validates :image,
28
+ :'oscillator/file_size' => {
29
+ maximum: 2 }
30
+ end
31
+
32
+ class ValidatableClassWithWithin
33
+ include ActiveModel::Validations
34
+ extend CarrierWave::Mount
35
+
36
+ attr_accessor :image
37
+
38
+ mount_uploader :image
39
+
40
+ validates :image,
41
+ :'oscillator/file_size' => {
42
+ within: 2..4 }
43
+ end
44
+
45
+ class ValidatableClassWithIs
46
+ include ActiveModel::Validations
47
+ extend CarrierWave::Mount
48
+
49
+ attr_accessor :image
50
+
51
+ mount_uploader :image
52
+
53
+ validates :image,
54
+ :'oscillator/file_size' => {
55
+ is: 2 }
56
+ end
57
+
58
+ describe Oscillator::FileSizeValidator, :carrier_wave do
59
+ describe '#valid?' do
60
+ context 'when a `minimum` is set' do
61
+ let(:validatable) { ValidatableClassWithMinimum.new }
62
+
63
+ context 'and a file lower than the minimum is stored' do
64
+ before { validatable.image.store! File.open(@test_image_directory + '0-byte-file.txt') }
65
+
66
+ it 'is false' do
67
+ validatable.should_not be_valid
68
+ end
69
+ end
70
+
71
+ context 'and a file the same as the minimum is stored' do
72
+ before { validatable.image.store! File.open(@test_image_directory + '2-byte-file.txt') }
73
+
74
+ it 'is true' do
75
+ validatable.should be_valid
76
+ end
77
+ end
78
+ end
79
+
80
+ context 'when a `maximum` is set' do
81
+ let(:validatable) { ValidatableClassWithMaximum.new }
82
+
83
+ context 'and a file higher than the maximum is stored' do
84
+ before { validatable.image.store! File.open(@test_image_directory + '3-byte-file.txt') }
85
+
86
+ it 'is false' do
87
+ validatable.should_not be_valid
88
+ end
89
+ end
90
+
91
+ context 'and a file the same as the maximum is stored' do
92
+ before { validatable.image.store! File.open(@test_image_directory + '2-byte-file.txt') }
93
+
94
+ it 'is true' do
95
+ validatable.should be_valid
96
+ end
97
+ end
98
+ end
99
+
100
+ context 'when a `within` range is set' do
101
+ let(:validatable) { ValidatableClassWithWithin.new }
102
+
103
+ context 'and a file below the bottom of the range is stored' do
104
+ before { validatable.image.store! File.open(@test_image_directory + '0-byte-file.txt') }
105
+
106
+ it 'is false' do
107
+ validatable.should_not be_valid
108
+ end
109
+ end
110
+
111
+ context 'and a file at the bottom of the range is stored' do
112
+ before { validatable.image.store! File.open(@test_image_directory + '2-byte-file.txt') }
113
+
114
+ it 'is true' do
115
+ validatable.should be_valid
116
+ end
117
+ end
118
+
119
+ context 'and a file at the top of the range is stored' do
120
+ before { validatable.image.store! File.open(@test_image_directory + '4-byte-file.txt') }
121
+
122
+ it 'is true' do
123
+ validatable.should be_valid
124
+ end
125
+ end
126
+
127
+ context 'and a file above the top of the range is stored' do
128
+ before { validatable.image.store! File.open(@test_image_directory + '5-byte-file.txt') }
129
+
130
+ it 'is false' do
131
+ validatable.should_not be_valid
132
+ end
133
+ end
134
+ end
135
+
136
+ context 'when `is` is set' do
137
+ let(:validatable) { ValidatableClassWithIs.new }
138
+
139
+ context 'and a file below the bottom of the range is stored' do
140
+ before { validatable.image.store! File.open(@test_image_directory + '0-byte-file.txt') }
141
+
142
+ it 'is false' do
143
+ validatable.should_not be_valid
144
+ end
145
+ end
146
+
147
+ context 'and a file that is the exact size is stored' do
148
+ before { validatable.image.store! File.open(@test_image_directory + '2-byte-file.txt') }
149
+
150
+ it 'is true' do
151
+ validatable.should be_valid
152
+ end
153
+ end
154
+
155
+ context 'and a file above the top of the range is stored' do
156
+ before { validatable.image.store! File.open(@test_image_directory + '3-byte-file.txt') }
157
+
158
+ it 'is false' do
159
+ validatable.should_not be_valid
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
File without changes
@@ -0,0 +1 @@
1
+ a
@@ -0,0 +1 @@
1
+ aa
@@ -0,0 +1 @@
1
+ aaa
@@ -0,0 +1 @@
1
+ aaaa
@@ -0,0 +1,12 @@
1
+ require 'active_model'
2
+ require 'action_view'
3
+ require 'carrierwave'
4
+ require 'oscillator'
5
+
6
+ Dir[File.expand_path('../support/**/*.rb', __FILE__)].each { |f| require f }
7
+
8
+ RSpec.configure do |config|
9
+ config.after(:suite) do
10
+ `rm -rf ./my_model`
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ ###
2
+ # Makes CarrierWave tests faster and more reliable
3
+ #
4
+
5
+ CarrierWave.configure do |config|
6
+ config.storage = :file
7
+ config.enable_processing = false
8
+ end
9
+
10
+ RSpec.configure do |config|
11
+ config.before(:each, :carrier_wave => true) do
12
+ @test_image_directory = File.dirname(__FILE__) + '/../fixtures/'
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ RSpec.configure do |config|
2
+ # Configure RSpec to run focused specs, and also respect the alias 'fit' for focused specs
3
+ config.treat_symbols_as_metadata_keys_with_true_values = true
4
+ config.filter_run :focused => true
5
+ config.alias_example_to :fit, :focused => true
6
+ config.run_all_when_everything_filtered = true
7
+ end
@@ -0,0 +1,4 @@
1
+ RSpec.configure do |config|
2
+ # Configure RSpec to respect the alias 'pit' for pending specs
3
+ config.alias_example_to :pit, :pending => true
4
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oscillator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,24 +10,152 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-10-02 00:00:00.000000000 Z
13
+ date: 2012-10-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: activerecord
16
+ name: carrierwave
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
21
21
  - !ruby/object:Gem::Version
22
- version: '3.1'
22
+ version: '0.5'
23
23
  type: :runtime
24
24
  prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: '0.5'
31
+ - !ruby/object:Gem::Dependency
32
+ name: activemodel
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ~>
37
+ - !ruby/object:Gem::Version
38
+ version: '3.1'
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: '3.1'
47
+ - !ruby/object:Gem::Dependency
48
+ name: actionpack
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '3.1'
55
+ type: :development
56
+ prerelease: false
25
57
  version_requirements: !ruby/object:Gem::Requirement
26
58
  none: false
27
59
  requirements:
28
60
  - - ~>
29
61
  - !ruby/object:Gem::Version
30
62
  version: '3.1'
63
+ - !ruby/object:Gem::Dependency
64
+ name: rspec
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ version: '2.11'
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ version: '2.11'
79
+ - !ruby/object:Gem::Dependency
80
+ name: fuubar
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ~>
85
+ - !ruby/object:Gem::Version
86
+ version: '1.0'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ version: '1.0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: guard
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ~>
101
+ - !ruby/object:Gem::Version
102
+ version: 1.4.0
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 1.4.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: guard-rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ~>
117
+ - !ruby/object:Gem::Version
118
+ version: 2.0.0
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ~>
125
+ - !ruby/object:Gem::Version
126
+ version: 2.0.0
127
+ - !ruby/object:Gem::Dependency
128
+ name: rb-fsevent
129
+ requirement: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ~>
133
+ - !ruby/object:Gem::Version
134
+ version: 0.9.1
135
+ type: :development
136
+ prerelease: false
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ~>
141
+ - !ruby/object:Gem::Version
142
+ version: 0.9.1
143
+ - !ruby/object:Gem::Dependency
144
+ name: awesome_print
145
+ requirement: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ~>
149
+ - !ruby/object:Gem::Version
150
+ version: 1.1.0
151
+ type: :development
152
+ prerelease: false
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ none: false
155
+ requirements:
156
+ - - ~>
157
+ - !ruby/object:Gem::Version
158
+ version: 1.1.0
31
159
  description: ''
32
160
  email: support@chirrpy.com
33
161
  executables: []
@@ -36,13 +164,26 @@ extra_rdoc_files:
36
164
  - README.md
37
165
  - LICENSE
38
166
  files:
39
- - lib/oscillator/canonical_uploader_path.rb
167
+ - lib/oscillator/file_location_resolver.rb
40
168
  - lib/oscillator/file_size_validator.rb
169
+ - lib/oscillator/validations.rb
41
170
  - lib/oscillator/version.rb
42
171
  - lib/oscillator.rb
43
172
  - Rakefile
44
173
  - README.md
45
174
  - LICENSE
175
+ - spec/file_location_resolver_spec.rb
176
+ - spec/file_size_validator_spec.rb
177
+ - spec/fixtures/0-byte-file.txt
178
+ - spec/fixtures/2-byte-file.txt
179
+ - spec/fixtures/3-byte-file.txt
180
+ - spec/fixtures/4-byte-file.txt
181
+ - spec/fixtures/5-byte-file.txt
182
+ - spec/fixtures/SMALL-LOGO-SHORT-AND-WIDE.PNG
183
+ - spec/spec_helper.rb
184
+ - spec/support/carrier_wave.rb
185
+ - spec/support/focused.rb
186
+ - spec/support/pending.rb
46
187
  homepage: https://github.com/chirrpy/oscillator
47
188
  licenses: []
48
189
  post_install_message:
@@ -68,4 +209,16 @@ rubygems_version: 1.8.24
68
209
  signing_key:
69
210
  specification_version: 3
70
211
  summary: Shared CarrierWave and Validations and Configurations
71
- test_files: []
212
+ test_files:
213
+ - spec/file_location_resolver_spec.rb
214
+ - spec/file_size_validator_spec.rb
215
+ - spec/fixtures/0-byte-file.txt
216
+ - spec/fixtures/2-byte-file.txt
217
+ - spec/fixtures/3-byte-file.txt
218
+ - spec/fixtures/4-byte-file.txt
219
+ - spec/fixtures/5-byte-file.txt
220
+ - spec/fixtures/SMALL-LOGO-SHORT-AND-WIDE.PNG
221
+ - spec/spec_helper.rb
222
+ - spec/support/carrier_wave.rb
223
+ - spec/support/focused.rb
224
+ - spec/support/pending.rb
@@ -1,9 +0,0 @@
1
- module CanonicalUploaderPath
2
- def filename
3
- "#{mounted_as}.#{file.extension.downcase}" if @filename
4
- end
5
-
6
- def store_dir
7
- "#{model.class.name.underscore}/#{model.id}"
8
- end
9
- end