imgix 3.2.1 → 3.3.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.
@@ -3,6 +3,7 @@
3
3
  module Imgix
4
4
  module ParamHelpers
5
5
  def rect(position)
6
+ warn "Warning: `ParamHelpers.rect` has been deprecated and will be removed in the next major version.\n"
6
7
  @options[:rect] = position and return self if position.is_a?(String)
7
8
 
8
9
  @options[:rect] = [
@@ -10,26 +10,26 @@ module Imgix
10
10
  include ParamHelpers
11
11
 
12
12
  ALIASES = {
13
- width: :w,
14
- height: :h,
15
- rotation: :rot,
13
+ width: :w,
14
+ height: :h,
15
+ rotation: :rot,
16
16
  noise_reduction: :nr,
17
- sharpness: :sharp,
18
- exposure: :exp,
19
- vibrance: :vib,
20
- saturation: :sat,
21
- brightness: :bri,
22
- contrast: :con,
23
- highlight: :high,
24
- shadow: :shad,
25
- gamma: :gam,
26
- pixelate: :px,
27
- halftone: :htn,
28
- watermark: :mark,
29
- text: :txt,
30
- format: :fm,
31
- quality: :q
32
- }
17
+ sharpness: :sharp,
18
+ exposure: :exp,
19
+ vibrance: :vib,
20
+ saturation: :sat,
21
+ brightness: :bri,
22
+ contrast: :con,
23
+ highlight: :high,
24
+ shadow: :shad,
25
+ gamma: :gam,
26
+ pixelate: :px,
27
+ halftone: :htn,
28
+ watermark: :mark,
29
+ text: :txt,
30
+ format: :fm,
31
+ quality: :q
32
+ }.freeze
33
33
 
34
34
  def initialize(prefix, secure_url_token, path = '/')
35
35
  @prefix = prefix
@@ -75,10 +75,16 @@ module Imgix
75
75
 
76
76
  ALIASES.each do |from, to|
77
77
  define_method from do |*args|
78
+ warn "Warning: `Path.#{from}' has been deprecated and " \
79
+ "will be removed in the next major version (along " \
80
+ "with all parameter `ALIASES`).\n"
78
81
  self.send(to, *args)
79
82
  end
80
83
 
81
84
  define_method "#{from}=" do |*args|
85
+ warn "Warning: `Path.#{from}=' has been deprecated and " \
86
+ "will be removed in the next major version (along " \
87
+ "with all parameter `ALIASES`).\n"
82
88
  self.send("#{to}=", *args)
83
89
  return self
84
90
  end
@@ -88,20 +94,20 @@ module Imgix
88
94
  prev_options = @options.dup
89
95
  @options.merge!(params)
90
96
 
91
- width = @options['w'.to_sym]
92
- height = @options['h'.to_sym]
93
- aspect_ratio = @options['ar'.to_sym]
97
+ width = @options[:w]
98
+ height = @options[:h]
99
+ aspect_ratio = @options[:ar]
94
100
 
95
- if ((width) || (height && aspect_ratio))
96
- srcset = build_dpr_srcset(options: options, params:@options)
97
- else
98
- srcset = build_srcset_pairs(options: options, params: @options)
99
- end
101
+ srcset = if width || (height && aspect_ratio)
102
+ build_dpr_srcset(options: options, params: @options)
103
+ else
104
+ build_srcset_pairs(options: options, params: @options)
105
+ end
100
106
 
101
107
  @options = prev_options
102
108
  srcset
103
109
  end
104
-
110
+
105
111
  private
106
112
 
107
113
  def signature
@@ -131,23 +137,24 @@ module Imgix
131
137
  def build_srcset_pairs(options:, params:)
132
138
  srcset = ''
133
139
 
134
- widths = options['widths'.to_sym] || []
135
- width_tolerance = options['width_tolerance'.to_sym] || DEFAULT_WIDTH_TOLERANCE
136
- min_srcset = options['min_width'.to_sym] || MIN_WIDTH
137
- max_srcset = options['max_width'.to_sym] || MAX_WIDTH
140
+ widths = options[:widths] || []
141
+ width_tolerance = options[:width_tolerance] || DEFAULT_WIDTH_TOLERANCE
142
+ min_width = options[:min_width] || MIN_WIDTH
143
+ max_width = options[:max_width] || MAX_WIDTH
138
144
 
139
145
  if !widths.empty?
140
146
  validate_widths!(widths)
141
147
  srcset_widths = widths
142
- elsif width_tolerance != DEFAULT_WIDTH_TOLERANCE or min_srcset != MIN_WIDTH or max_srcset != MAX_WIDTH
143
- validate_range!(min_srcset, max_srcset)
144
- srcset_widths = TARGET_WIDTHS.call(width_tolerance, min_srcset, max_srcset)
148
+ elsif width_tolerance != DEFAULT_WIDTH_TOLERANCE || min_width != MIN_WIDTH || max_width != MAX_WIDTH
149
+ validate_range!(min_width, max_width)
150
+ validate_width_tolerance!(width_tolerance)
151
+ srcset_widths = TARGET_WIDTHS.call(width_tolerance, min_width, max_width)
145
152
  else
146
153
  srcset_widths = @target_widths
147
154
  end
148
155
 
149
156
  for width in srcset_widths do
150
- params['w'.to_sym] = width
157
+ params[:w] = width
151
158
  srcset += "#{to_url(params)} #{width}w,\n"
152
159
  end
153
160
 
@@ -157,17 +164,17 @@ module Imgix
157
164
  def build_dpr_srcset(options:, params:)
158
165
  srcset = ''
159
166
 
160
- disable_variable_quality = options['disable_variable_quality'.to_sym] || false
167
+ disable_variable_quality = options[:disable_variable_quality] || false
161
168
  validate_variable_qualities!(disable_variable_quality)
162
169
 
163
- target_ratios = [1,2,3,4,5]
164
- quality = params['q'.to_sym]
170
+ target_ratios = [1, 2, 3, 4, 5]
171
+ quality = params[:q]
165
172
 
166
173
  for ratio in target_ratios do
167
- params['dpr'.to_sym] = ratio
174
+ params[:dpr] = ratio
168
175
 
169
176
  unless disable_variable_quality
170
- params['q'.to_sym] = quality || DPR_QUALITY[ratio]
177
+ params[:q] = quality || DPR_QUALITY[ratio]
171
178
  end
172
179
 
173
180
  srcset += "#{to_url(params)} #{ratio}x,\n"
@@ -176,30 +183,37 @@ module Imgix
176
183
  srcset[0..-3]
177
184
  end
178
185
 
179
- def validate_widths!(widths)
180
- unless widths.is_a? Array
181
- raise ArgumentError, "The widths argument must be passed a valid array of integers"
182
- else
183
- positive_integers = widths.all? {|i| i.is_a?(Integer) and i > 0}
184
- unless positive_integers
185
- raise ArgumentError, "A custom widths array must only contain positive integer values"
186
- end
186
+ def validate_width_tolerance!(width_tolerance)
187
+ width_increment_error = 'error: `width_tolerance` must be a positive `Numeric` value'
188
+
189
+ if !width_tolerance.is_a?(Numeric) || width_tolerance <= 0
190
+ raise ArgumentError, width_increment_error
187
191
  end
188
192
  end
189
193
 
194
+ def validate_widths!(widths)
195
+ widths_error = 'error: `widths` must be an array of positive `Numeric` values'
196
+ raise ArgumentError, widths_error unless widths.is_a?(Array)
197
+
198
+ all_positive_integers = widths.all? { |i| i.is_a?(Integer) && i > 0 }
199
+ raise ArgumentError, widths_error unless all_positive_integers
200
+ end
201
+
190
202
  def validate_range!(min_srcset, max_srcset)
191
- if min_srcset.is_a? Numeric and max_srcset.is_a? Numeric
192
- unless min_srcset > 0 and max_srcset > 0
193
- raise ArgumentError, "The min and max arguments must be passed positive Numeric values"
194
- end
195
- else
196
- raise ArgumentError, "The min and max arguments must be passed positive Numeric values"
203
+ range_numeric_error = 'error: `min_width` and `max_width` must be positive `Numeric` values'
204
+ unless min_srcset.is_a?(Numeric) && max_srcset.is_a?(Numeric)
205
+ raise ArgumentError, range_numeric_error
206
+ end
207
+
208
+ unless min_srcset > 0 && max_srcset > 0
209
+ raise ArgumentError, range_numeric_error
197
210
  end
198
211
  end
199
212
 
200
- def validate_variable_qualities!(disable_variable_quality)
201
- unless disable_variable_quality.is_a?(TrueClass) || disable_variable_quality.is_a?(FalseClass)
202
- raise ArgumentError, "The disable_variable_quality argument must be passed a Boolean value"
213
+ def validate_variable_qualities!(disable_quality)
214
+ disable_quality_error = 'error: `disable_quality` must be a Boolean value'
215
+ unless disable_quality.is_a?(TrueClass) || disable_quality.is_a?(FalseClass)
216
+ raise ArgumentError, disable_quality_error
203
217
  end
204
218
  end
205
219
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Imgix
4
- VERSION = '3.2.1'
4
+ VERSION = '3.3.0'
5
5
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class ParamHelpers < Imgix::Test
6
+ def test_param_helpers_emits_dep_warning
7
+ host_warn = "Warning: The identifier `host' has been deprecated and " \
8
+ "will\nappear as `domain' in the next major version, e.g. " \
9
+ "`@host'\nbecomes `@domain', `options[:host]' becomes " \
10
+ "`options[:domain]'.\n"
11
+
12
+ assert_output(nil, host_warn) {
13
+ client = Imgix::Client.new(host: 'test.imgix.net')
14
+
15
+ rect_warn = "Warning: `ParamHelpers.rect` has been deprecated and " \
16
+ "will be removed in the next major version.\n"
17
+
18
+ assert_output(nil, rect_warn){
19
+ client.path('/images/demo.png').rect(x: 0, y: 50, width: 200, height: 300)
20
+ }
21
+ }
22
+ end
23
+ end
@@ -3,6 +3,27 @@
3
3
  require 'test_helper'
4
4
 
5
5
  class PathTest < Imgix::Test
6
+ def test_prefix_with_arg_warns
7
+ prefix_warn = "Warning: `Client::prefix' will take zero arguments " \
8
+ "in the next major version.\n"
9
+
10
+ assert_output(nil, prefix_warn) {
11
+ Imgix::Client.new(
12
+ domain: 'test.imgix.net',
13
+ include_library_param: false
14
+ ).prefix("")
15
+ }
16
+
17
+ # `new_prefix' is a placeholder until the bump, when it will become
18
+ # `prefix`.
19
+ assert_output(nil, nil) {
20
+ Imgix::Client.new(
21
+ domain: 'test.imgix.net',
22
+ include_library_param: false
23
+ ).new_prefix
24
+ }
25
+ end
26
+
6
27
  def test_creating_a_path
7
28
  path = client.path('/images/demo.png')
8
29
  assert_equal 'https://demo.imgix.net/images/demo.png?s=2c7c157eaf23b06a0deb2f60b81938c4', path.to_url
@@ -14,7 +35,12 @@ class PathTest < Imgix::Test
14
35
  def test_signing_path_with_param
15
36
  url = 'https://demo.imgix.net/images/demo.png?w=200&s=da421114ca238d1f4a927b889f67c34e'
16
37
  path = client.path('/images/demo.png')
17
- path.width = 200
38
+
39
+ assert_output(nil, "Warning: `Path.width=' has been deprecated and " \
40
+ "will be removed in the next major version (along " \
41
+ "with all parameter `ALIASES`).\n") {
42
+ path.width = 200
43
+ }
18
44
 
19
45
  assert_equal url, path.to_url
20
46
 
@@ -22,13 +48,23 @@ class PathTest < Imgix::Test
22
48
  assert_equal url, path.to_url(w: 200)
23
49
 
24
50
  path = client.path('/images/demo.png')
25
- assert_equal url, path.width(200).to_url
51
+
52
+ assert_output(nil, "Warning: `Path.width' has been deprecated and " \
53
+ "will be removed in the next major version (along " \
54
+ "with all parameter `ALIASES`).\n") {
55
+ assert_equal url, path.width(200).to_url
56
+ }
26
57
  end
27
58
 
28
59
  def test_resetting_defaults
29
60
  url = 'https://demo.imgix.net/images/demo.png?w=200&s=da421114ca238d1f4a927b889f67c34e'
30
61
  path = client.path('/images/demo.png')
31
- path.height = 300
62
+
63
+ assert_output(nil, "Warning: `Path.height=' has been deprecated and " \
64
+ "will be removed in the next major version (along " \
65
+ "with all parameter `ALIASES`).\n") {
66
+ path.height = 300
67
+ }
32
68
 
33
69
  assert_equal url, path.defaults.to_url(w: 200)
34
70
  end
@@ -40,7 +76,21 @@ class PathTest < Imgix::Test
40
76
  assert_equal url, path.to_url(h: 200, w: 200)
41
77
 
42
78
  path = client.path('/images/demo.png')
43
- assert_equal url, path.height(200).width(200).to_url
79
+
80
+ assert_output(nil, "Warning: `Path.height' has been deprecated and " \
81
+ "will be removed in the next major version (along " \
82
+ "with all parameter `ALIASES`).\n") {
83
+ path.height(200)
84
+ }
85
+
86
+
87
+ assert_output(nil, "Warning: `Path.width' has been deprecated and " \
88
+ "will be removed in the next major version (along " \
89
+ "with all parameter `ALIASES`).\n") {
90
+ path.width(200)
91
+ }
92
+
93
+ assert_equal url, path.to_url
44
94
  end
45
95
 
46
96
  def test_path_with_multi_value_param_safely_encoded
@@ -1,716 +1,755 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module SrcsetTest
6
+ RESOLUTIONS = [
7
+ 100, 116, 135, 156, 181, 210, 244, 283,
8
+ 328, 380, 441, 512, 594, 689, 799, 927,
9
+ 1075, 1247, 1446, 1678, 1946, 2257, 2619,
10
+ 3038, 3524, 4087, 4741, 5500, 6380, 7401, 8192
11
+ ].freeze
12
+
13
+ DPR_QUALITY = [75, 50, 35, 23, 20].freeze
14
+
15
+ DOMAIN = 'testing.imgix.net'
16
+ TOKEN = 'MYT0KEN'
17
+ JPG_PATH = 'image.jpg'
18
+
19
+ def mock_client
20
+ Imgix::Client.new(
21
+ host: DOMAIN,
22
+ include_library_param: false
23
+ ).path(JPG_PATH)
24
+ end
25
+
26
+ def mock_signed_client
27
+ Imgix::Client.new(
28
+ host: DOMAIN,
29
+ secure_url_token: TOKEN,
30
+ include_library_param: false
31
+ ).path(JPG_PATH)
32
+ end
33
+
34
+ def signature_base(params)
35
+ TOKEN + '/' + JPG_PATH + params
36
+ end
37
+
38
+ def get_sig_from(src)
39
+ src.slice(src.index('s=') + 2, src.length)
40
+ end
41
+
42
+ def get_params_from(src)
43
+ src[src.index('?')..src.index('s=') - 2]
44
+ end
45
+
46
+ def get_expected_signature(src)
47
+ # Ensure signature param exists.
48
+ assert_includes src, 's='
49
+
50
+ params = get_params_from(src)
51
+ signature_base = signature_base(params)
52
+
53
+ Digest::MD5.hexdigest(signature_base)
54
+ end
55
+
56
+ class SrcsetDefault < Imgix::Test
57
+ include SrcsetTest
58
+
59
+ def test_no_parameters
60
+ srcset = path.to_srcset
61
+
62
+ expected_number_of_pairs = 31
63
+ assert_equal expected_number_of_pairs, srcset.split(',').length
64
+ end
65
+
66
+ def test_srcset_pair_values
67
+ resolutions = RESOLUTIONS
68
+ srcset = path.to_srcset
69
+ srclist = srcset.split(',').map do |srcset_split|
70
+ srcset_split.split(' ')[1].to_i
71
+ end
72
+
73
+ for i in 0..srclist.length - 1
74
+ assert_equal(srclist[i], resolutions[i])
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def path
81
+ @client ||= mock_signed_client
82
+ end
83
+ end
84
+
85
+ class SrcsetGivenWidth < Imgix::Test
86
+ include SrcsetTest
87
+
88
+ def test_srcset_in_dpr_form
89
+ device_pixel_ratio = 1
90
+
91
+ srcset.split(',').map do |src|
92
+ ratio = src.split(' ')[1]
93
+ assert_equal "#{device_pixel_ratio}x", ratio
94
+ device_pixel_ratio += 1
95
+ end
96
+ end
97
+
98
+ def test_srcset_has_dpr_params
99
+ i = 1
100
+ srcset.split(',').map do |srcset_split|
101
+ src = srcset_split.split(' ')[0]
102
+ assert_includes src, "dpr=#{i}"
103
+ i += 1
104
+ end
105
+ end
106
+
107
+ def test_srcset_signs_urls
108
+ srcset.split(',').map do |srcset_split|
109
+ src = srcset_split.split(' ')[0]
110
+ expected_signature = get_expected_signature(src)
111
+
112
+ assert_includes src, expected_signature
113
+ end
114
+ end
115
+
116
+ def test_srcset_has_variable_qualities
117
+ i = 0
118
+ srcset.split(',').map do |src|
119
+ assert_includes src, "q=#{DPR_QUALITY[i]}"
120
+ i += 1
121
+ end
122
+ end
123
+
124
+ def test_srcset_respects_overriding_quality
125
+ quality_override = 100
126
+ srcset = mock_signed_client.to_srcset(w: 100, q: quality_override)
127
+
128
+ srcset.split(',').map do |src|
129
+ assert_includes src, "q=#{quality_override}"
130
+ end
131
+ end
132
+
133
+ def test_disable_variable_quality
134
+ srcset = mock_signed_client.to_srcset(
135
+ w: 100,
136
+ options: { disable_variable_quality: true }
137
+ )
138
+
139
+ srcset.split(',').map do |src|
140
+ assert(not(src.include?('q=')))
141
+ end
142
+ end
143
+
144
+ def test_respects_quality_param_when_disabled
145
+ quality_override = 100
146
+ srcset = mock_signed_client.to_srcset(
147
+ w: 100, q: 100,
148
+ options: { disable_variable_quality: true }
149
+ )
150
+
151
+ srcset.split(',').map do |src|
152
+ assert_includes src, "q=#{quality_override}"
153
+ end
154
+ end
155
+
156
+ private
157
+
158
+ def srcset
159
+ @client ||= mock_signed_client.to_srcset(w: 100)
160
+ end
161
+ end
162
+
163
+ class SrcsetGivenHeight < Imgix::Test
164
+ include SrcsetTest
165
+
166
+ def test_srcset_generates_width_pairs
167
+ expected_number_of_pairs = 31
168
+ assert_equal expected_number_of_pairs, srcset.split(',').length
169
+ end
170
+
171
+ def test_srcset_pair_values
172
+ resolutions = RESOLUTIONS
173
+ srclist = srcset.split(',').map do |srcset_split|
174
+ srcset_split.split(' ')[1].to_i
175
+ end
176
+
177
+ for i in 0..srclist.length - 1
178
+ assert_equal(srclist[i], resolutions[i])
179
+ end
180
+ end
181
+
182
+ def test_srcset_respects_height_parameter
183
+ srcset.split(',').map do |src|
184
+ assert_includes src, 'h='
185
+ end
186
+ end
187
+
188
+ def test_srcset_within_bounds
189
+ min, *max = srcset.split(',')
190
+
191
+ # parse out the width descriptor as an integer
192
+ min = min.split(' ')[1].to_i
193
+ max = max[max.length - 1].split(' ')[1].to_i
194
+
195
+ assert_operator min, :>=, 100
196
+ assert_operator max, :<=, 8192
197
+ end
198
+
199
+ # a 17% testing threshold is used to account for rounding
200
+ def test_srcset_iterates_17_percent
201
+ increment_allowed = 0.17
202
+
203
+ # create an array of widths
204
+ widths = srcset.split(',').map do |src|
205
+ src.split(' ')[1].to_i
206
+ end
207
+
208
+ prev = widths[0]
209
+
210
+ for i in 1..widths.length - 1
211
+ element = widths[i]
212
+ assert_operator (element.to_f / prev.to_f), :<, (1 + increment_allowed)
213
+ prev = element
214
+ end
215
+ end
216
+
217
+ def test_srcset_signs_urls
218
+ srcset.split(',').map do |srcset_split|
219
+ src = srcset_split.split(' ')[0]
220
+ expected_signature = get_expected_signature(src)
221
+
222
+ assert_includes src, expected_signature
223
+ end
224
+ end
225
+
226
+ private
227
+
228
+ def srcset
229
+ @client ||= mock_signed_client.to_srcset(h: 100)
230
+ end
231
+ end
232
+
233
+ class SrcsetGivenWidthAndHeight < Imgix::Test
234
+ include SrcsetTest
235
+
236
+ def test_srcset_in_dpr_form
237
+ device_pixel_ratio = 1
238
+ srcset.split(',').map do |src|
239
+ ratio = src.split(' ')[1]
240
+ assert_equal "#{device_pixel_ratio}x", ratio
241
+ device_pixel_ratio += 1
242
+ end
243
+ end
244
+
245
+ def test_srcset_has_dpr_params
246
+ i = 1
247
+ srcset.split(',').map do |srcset_split|
248
+ src = srcset_split.split(' ')[0]
249
+ assert_includes src, "dpr=#{i}"
250
+ i += 1
251
+ end
252
+ end
253
+
254
+ def test_srcset_signs_urls
255
+ srcset.split(',').map do |srcset_split|
256
+ src = srcset_split.split(' ')[0]
257
+ expected_signature = get_expected_signature(src)
258
+
259
+ assert_includes src, expected_signature
260
+ end
261
+ end
262
+
263
+ def test_srcset_has_variable_qualities
264
+ i = 0
265
+ srcset.split(',').map do |src|
266
+ assert_includes src, "q=#{DPR_QUALITY[i]}"
267
+ i += 1
268
+ end
269
+ end
270
+
271
+ def test_srcset_respects_overriding_quality
272
+ quality_override = 100
273
+ srcset = mock_signed_client.to_srcset(w: 100, h: 100, q: quality_override)
274
+
275
+ srcset.split(',').map do |src|
276
+ assert_includes src, "q=#{quality_override}"
277
+ end
278
+ end
279
+
280
+ def test_disable_variable_quality
281
+ srcset = mock_signed_client.to_srcset(
282
+ w: 100, h: 100,
283
+ options: { disable_variable_quality: true }
284
+ )
285
+
286
+ srcset.split(',').map do |src|
287
+ assert(not(src.include?('q=')))
288
+ end
289
+ end
290
+
291
+ def test_respects_quality_param_when_disabled
292
+ quality_override = 100
293
+ srcset = mock_signed_client.to_srcset(
294
+ w: 100, h: 100, q: 100,
295
+ options: { disable_variable_quality: true }
296
+ )
297
+
298
+ srcset.split(',').map do |src|
299
+ assert_includes src, "q=#{quality_override}"
300
+ end
301
+ end
302
+
303
+ private
304
+
305
+ def srcset
306
+ @client ||= mock_signed_client.to_srcset(w: 100, h: 100)
307
+ end
308
+ end
309
+
310
+ class SrcsetGivenAspectRatio < Imgix::Test
311
+ include SrcsetTest
312
+
313
+ def test_srcset_generates_width_pairs
314
+ expected_number_of_pairs = 31
315
+ assert_equal expected_number_of_pairs, srcset.split(',').length
316
+ end
317
+
318
+ def test_srcset_pair_values
319
+ srclist = srcset.split(',').map do |srcset_split|
320
+ srcset_split.split(' ')[1].to_i
321
+ end
322
+
323
+ for i in 0..srclist.length - 1
324
+ assert_equal(srclist[i], RESOLUTIONS[i])
325
+ end
326
+ end
327
+
328
+ def test_srcset_within_bounds
329
+ min, *max = srcset.split(',')
330
+
331
+ # parse out the width descriptor as an integer
332
+ min = min.split(' ')[1].to_i
333
+ max = max[max.length - 1].split(' ')[1].to_i
334
+
335
+ assert_operator min, :>=, 100
336
+ assert_operator max, :<=, 8192
337
+ end
338
+
339
+ # a 17% testing threshold is used to account for rounding
340
+ def test_srcset_iterates_17_percent
341
+ increment_allowed = 0.17
342
+
343
+ # create an array of widths
344
+ widths = srcset.split(',').map do |src|
345
+ src.split(' ')[1].to_i
346
+ end
347
+
348
+ prev = widths[0]
349
+
350
+ for i in 1..widths.length - 1
351
+ element = widths[i]
352
+ assert_operator (element.to_f / prev.to_f), :<, (1 + increment_allowed)
353
+ prev = element
354
+ end
355
+ end
356
+
357
+ def test_srcset_signs_urls
358
+ srcset.split(',').map do |srcset_split|
359
+ src = srcset_split.split(' ')[0]
360
+ expected_signature = get_expected_signature(src)
361
+
362
+ assert_includes src, expected_signature
363
+ end
364
+ end
365
+
366
+ private
367
+
368
+ def srcset
369
+ @client ||= mock_signed_client.to_srcset(ar: '3:2')
370
+ end
371
+ end
372
+
373
+ class SrcsetGivenAspectRatioAndHeight < Imgix::Test
374
+ include SrcsetTest
375
+
376
+ def test_srcset_in_dpr_form
377
+ device_pixel_ratio = 1
378
+
379
+ srcset.split(',').map do |src|
380
+ ratio = src.split(' ')[1]
381
+ assert_equal "#{device_pixel_ratio}x", ratio
382
+ device_pixel_ratio += 1
383
+ end
384
+ end
385
+
386
+ def test_srcset_has_dpr_params
387
+ i = 1
388
+ srcset.split(',').map do |srcset_split|
389
+ src = srcset_split.split(' ')[0]
390
+ assert_includes src, "dpr=#{i}"
391
+ i += 1
392
+ end
393
+ end
394
+
395
+ def test_srcset_signs_urls
396
+ srcset.split(',').map do |srcset_split|
397
+ src = srcset_split.split(' ')[0]
398
+ expected_signature = get_expected_signature(src)
399
+
400
+ assert_includes src, expected_signature
401
+ end
402
+ end
403
+
404
+ def test_srcset_has_variable_qualities
405
+ i = 0
406
+ srcset.split(',').map do |src|
407
+ assert_includes src, "q=#{DPR_QUALITY[i]}"
408
+ i += 1
409
+ end
410
+ end
411
+
412
+ def test_srcset_respects_overriding_quality
413
+ quality_override = 100
414
+ srcset = mock_signed_client.to_srcset(
415
+ w: 100, ar: '3:2', q: quality_override
416
+ )
417
+
418
+ srcset.split(',').map do |src|
419
+ assert_includes src, "q=#{quality_override}"
420
+ end
421
+ end
422
+
423
+ def test_disable_variable_quality
424
+ srcset = mock_signed_client.to_srcset(
425
+ w: 100, ar: '3:2',
426
+ options: { disable_variable_quality: true }
427
+ )
428
+
429
+ srcset.split(',').map do |src|
430
+ assert(not(src.include?('q=')))
431
+ end
432
+ end
433
+
434
+ def test_respects_quality_param_when_disabled
435
+ quality_override = 100
436
+ srcset = mock_signed_client.to_srcset(
437
+ w: 100, h: 100, q: 100,
438
+ options: { disable_variable_quality: true }
439
+ )
440
+
441
+ srcset.split(',').map do |src|
442
+ assert_includes src, "q=#{quality_override}"
443
+ end
444
+ end
445
+
446
+ private
447
+
448
+ def srcset
449
+ @client ||= mock_signed_client.to_srcset({ h: 100, ar: '3:2' })
450
+ end
451
+ end
452
+
453
+ class SrcsetWidthTolerance < Imgix::Test
454
+ include SrcsetTest
455
+
456
+ def test_srcset_generates_width_pairs
457
+ expected_number_of_pairs = 15
458
+ assert_equal expected_number_of_pairs, srcset.split(',').length
459
+ end
460
+
461
+ def test_srcset_pair_values
462
+ resolutions = [100, 140, 196, 274, 384,
463
+ 538, 753, 1054, 1476, 2066,
464
+ 2893, 4050, 5669, 7937, 8192]
465
+
466
+ srclist = srcset.split(',').map do |srcset_split|
467
+ srcset_split.split(' ')[1].to_i
468
+ end
469
+
470
+ for i in 0..srclist.length - 1
471
+ assert_equal(srclist[i], resolutions[i])
472
+ end
473
+ end
474
+
475
+ def test_srcset_within_bounds
476
+ min, *max = srcset.split(',')
477
+
478
+ # parse out the width descriptor as an integer
479
+ min = min.split(' ')[1].to_i
480
+ max = max[max.length - 1].split(' ')[1].to_i
481
+ assert_operator min, :>=, 100
482
+ assert_operator max, :<=, 8192
483
+ end
484
+
485
+ # a 41% testing threshold is used to account for rounding
486
+ def test_srcset_iterates_41_percent
487
+ increment_allowed = 0.41
488
+
489
+ # create an array of widths
490
+ widths = srcset.split(',').map do |src|
491
+ src.split(' ')[1].to_i
492
+ end
493
+
494
+ prev = widths[0]
495
+
496
+ for i in 1..widths.length - 1
497
+ element = widths[i]
498
+ assert_operator (element.to_f / prev.to_f), :<, (1 + increment_allowed)
499
+ prev = element
500
+ end
501
+ end
502
+
503
+ def test_invalid_tolerance_emits_error
504
+ assert_raises(ArgumentError) do
505
+ mock_client.to_srcset(options: { width_tolerance: 'abc' })
506
+ end
507
+ end
508
+
509
+ def test_negative_tolerance_emits_error
510
+ assert_raises(ArgumentError) do
511
+ mock_client.to_srcset(options: { width_tolerance: -0.10 })
512
+ end
513
+ end
514
+
515
+ def test_with_param_after
516
+ srcset = mock_signed_client.to_srcset(
517
+ options: { width_tolerance: 0.20 },
518
+ h: 1000, fit: 'clip'
519
+ )
520
+
521
+ assert_includes(srcset, 'h=')
522
+ assert(not(srcset.include?('width_tolerance=')))
523
+ end
524
+
525
+ def test_with_param_before
526
+ srcset = mock_signed_client.to_srcset(
527
+ h: 1000, fit: 'clip',
528
+ options: { width_tolerance: 0.20 }
529
+ )
530
+
531
+ assert_includes(srcset, 'h=')
532
+ assert(not(srcset.include?('width_tolerance=')))
533
+ end
534
+
535
+ private
536
+
537
+ def srcset
538
+ @client ||= mock_signed_client.to_srcset(
539
+ options: { width_tolerance: 0.20 }
540
+ )
541
+ end
542
+ end
543
+
544
+ class SrcsetCustomWidths < Imgix::Test
545
+ include SrcsetTest
546
+
547
+ def test_srcset_generates_width_pairs
548
+ expected_number_of_pairs = 4
549
+ assert_equal expected_number_of_pairs, srcset.split(',').length
550
+ end
551
+
552
+ def test_srcset_pair_values
553
+ resolutions = [100, 500, 1000, 1800]
554
+ srclist = srcset.split(',').map do |srcset_split|
555
+ srcset_split.split(' ')[1].to_i
556
+ end
557
+
558
+ for i in 0..srclist.length - 1
559
+ assert_equal(srclist[i], resolutions[i])
560
+ end
561
+ end
562
+
563
+ def test_srcset_within_bounds
564
+ min, *max = srcset.split(',')
565
+
566
+ # parse out the width descriptor as an integer
567
+ min = min.split(' ')[1].to_i
568
+ max = max[max.length - 1].split(' ')[1].to_i
569
+
570
+ assert_operator min, :>=, @widths[0]
571
+ assert_operator max, :<=, @widths[-1]
572
+ end
573
+
574
+ def test_invalid_widths_input_emits_error
575
+ assert_raises(ArgumentError) do
576
+ mock_client.to_srcset(options: { widths: 'abc' })
577
+ end
578
+ end
579
+
580
+ def test_non_integer_array_emits_error
581
+ assert_raises(ArgumentError) do
582
+ mock_client.to_srcset(options: { widths: [100, 200, false] })
583
+ end
584
+ end
585
+
586
+ def test_negative_integer_array_emits_error
587
+ assert_raises(ArgumentError) do
588
+ mock_client.to_srcset(options: { widths: [100, 200, -100] })
589
+ end
590
+ end
591
+
592
+ def test_with_param_after
593
+ srcset = mock_signed_client.to_srcset(
594
+ options: { widths: [100, 200, 300] },
595
+ h: 1000, fit: 'clip'
596
+ )
597
+
598
+ assert_includes(srcset, 'h=')
599
+ assert(not(srcset.include?('widths=')))
600
+ end
601
+
602
+ def test_with_param_before
603
+ srcset = mock_client.to_srcset(
604
+ h: 1000, fit: 'clip',
605
+ options: { widths: [100, 200, 300] }
606
+ )
607
+ assert_includes(srcset, 'h=')
608
+ assert(not(srcset.include?('widths=')))
609
+ end
610
+
611
+ private
612
+
613
+ def srcset
614
+ @widths = [100, 500, 1000, 1800]
615
+ @client ||= mock_signed_client.to_srcset(options: { widths: @widths })
616
+ end
617
+ end
618
+
619
+ class SrcsetMinMaxWidths < Imgix::Test
620
+ include SrcsetTest
621
+
622
+ def test_srcset_generates_width_pairs
623
+ expected_number_of_pairs = 11
624
+ assert_equal expected_number_of_pairs, srcset.split(',').length
625
+ end
626
+
627
+ def test_srcset_pair_values
628
+ resolutions = [500, 580, 673, 780, 905, 1050,
629
+ 1218, 1413, 1639, 1901, 2000]
630
+ srclist = srcset.split(',').map do |srcset_split|
631
+ srcset_split.split(' ')[1].to_i
632
+ end
633
+
634
+ for i in 0..srclist.length - 1
635
+ assert_equal(srclist[i], resolutions[i])
636
+ end
637
+ end
638
+
639
+ def test_srcset_within_bounds
640
+ min, *max = srcset.split(',')
641
+
642
+ # parse out the width descriptor as an integer
643
+ min = min.split(' ')[1].to_i
644
+ max = max[max.length - 1].split(' ')[1].to_i
645
+
646
+ assert_operator min, :>=, @MIN
647
+ assert_operator max, :<=, @MAX
648
+ end
649
+
650
+ # a 41% testing threshold is used to account for rounding
651
+ def test_with_custom_width_tolerance
652
+ srcset = mock_client.to_srcset(
653
+ options: { min_width: 500, max_width: 2000, width_tolerance: 0.20 }
654
+ )
655
+
656
+ increment_allowed = 0.41
657
+
658
+ # create an array of widths
659
+ widths = srcset.split(',').map do |src|
660
+ src.split(' ')[1].to_i
661
+ end
662
+
663
+ prev = widths[0]
664
+
665
+ for i in 1..widths.length - 1
666
+ element = widths[i]
667
+ assert_operator (element.to_f / prev.to_f), :<, (1 + increment_allowed)
668
+ prev = element
669
+ end
670
+ end
671
+
672
+ def test_invalid_min_emits_error
673
+ assert_raises(ArgumentError) do
674
+ mock_client.to_srcset(options: { min_width: 'abc' })
675
+ end
676
+ end
677
+
678
+ def test_negative_max_emits_error
679
+ assert_raises(ArgumentError) do
680
+ mock_client.to_srcset(options: { max_width: -100 })
681
+ end
682
+ end
683
+
684
+ def test_with_param_after
685
+ srcset = mock_client.to_srcset(
686
+ options: { min_width: 500, max_width: 2000 },
687
+ h: 1000, fit: 'clip'
688
+ )
689
+
690
+ assert_includes(srcset, 'h=')
691
+ assert(not(srcset.include?('min_width=')))
692
+ assert(not(srcset.include?('max_width=')))
693
+ end
694
+
695
+ def test_with_param_before
696
+ srcset = mock_client.to_srcset(
697
+ h: 1000, fit: 'clip',
698
+ options: { min_width: 500, max_width: 2000 }
699
+ )
700
+
701
+ assert_includes(srcset, 'h=')
702
+ assert(not(srcset.include?('min_width=')))
703
+ assert(not(srcset.include?('max_width=')))
704
+ end
705
+
706
+ def test_only_min
707
+ min_width = 1000
708
+ max_width = 8192
709
+ srcset = mock_client.to_srcset(options: { min_width: min_width })
710
+
711
+ min, *max = srcset.split(',')
712
+
713
+ # parse out the width descriptor as an integer
714
+ min = min.split(' ')[1].to_i
715
+ max = max[max.length - 1].split(' ')[1].to_i
716
+
717
+ assert_operator min, :>=, min_width
718
+ assert_operator max, :<=, max_width
719
+ end
720
+
721
+ def test_only_max
722
+ min_width = 100
723
+ max_width = 1000
724
+ srcset = mock_client.to_srcset(options: { max_width: max_width })
725
+ min, *max = srcset.split(',')
726
+
727
+ # parse out the width descriptor as an integer
728
+ min = min.split(' ')[1].to_i
729
+ max = max[max.length - 1].split(' ')[1].to_i
730
+
731
+ assert_operator min, :>=, min_width
732
+ assert_operator max, :<=, max_width
733
+ end
734
+
735
+ def test_max_as_100
736
+ srcset = mock_client.to_srcset(options: { max_width: 100 })
737
+ assert_equal(srcset, 'https://testing.imgix.net/image.jpg?w=100 100w')
738
+ end
739
+
740
+ def test_min_as_8192
741
+ srcset = mock_client.to_srcset(options: { min_width: 8192 })
742
+ assert_equal(srcset, 'https://testing.imgix.net/image.jpg?w=8192 8192w')
743
+ end
744
+
745
+ private
4
746
 
5
- class SrcsetDefault < Imgix::Test
6
- def test_no_parameters
7
- srcset = path.to_srcset()
8
- expected_number_of_pairs = 31
9
- assert_equal expected_number_of_pairs, srcset.split(',').length
10
- end
11
-
12
- def test_srcset_pair_values
13
- resolutions = [100, 116, 134, 156, 182, 210, 244, 282,
14
- 328, 380, 442, 512, 594, 688, 798, 926,
15
- 1074, 1246, 1446, 1678, 1946, 2258, 2618,
16
- 3038, 3524, 4088, 4742, 5500, 6380, 7400, 8192]
17
- srcset = path.to_srcset()
18
- srclist = srcset.split(',').map { |srcset_split|
19
- srcset_split.split(' ')[1].to_i
20
- }
21
-
22
- for i in 0..srclist.length - 1 do
23
- assert_equal(srclist[i], resolutions[i])
24
- end
25
- end
26
-
27
- private
28
- def path
29
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg')
30
- end
31
- end
32
-
33
- class SrcsetGivenWidth < Imgix::Test
34
- def test_srcset_in_dpr_form
35
- device_pixel_ratio = 1
36
-
37
- srcset.split(',').map { |src|
38
- ratio = src.split(' ')[1]
39
- assert_equal ("#{device_pixel_ratio}x"), ratio
40
- device_pixel_ratio += 1
41
- }
42
- end
43
-
44
- def test_srcset_has_dpr_params
45
- i = 1
46
- srcset.split(',').map { |srcset_split|
47
- src = srcset_split.split(' ')[0]
48
- assert_includes src, "dpr=#{i}"
49
- i += 1
50
- }
51
- end
52
-
53
- def test_srcset_signs_urls
54
- srcset.split(',').map { |srcset_split|
55
- src = srcset_split.split(' ')[0]
56
- assert_includes src, 's='
57
-
58
- # parses out all parameters except for 's=...'
59
- params = src[src.index('?')..src.index('s=') - 2]
60
-
61
- # parses out the 's=...' parameter
62
- generated_signature = src.slice(src.index('s=') + 2, src.length)
63
-
64
- signature_base = 'MYT0KEN' + '/image.jpg' + params;
65
- expected_signature = Digest::MD5.hexdigest(signature_base)
66
-
67
- assert_equal expected_signature, generated_signature
68
- }
69
- end
70
-
71
- def test_srcset_has_variable_qualities
72
- i = 0
73
- srcset.split(',').map { |src|
74
- assert_includes src, "q=#{DPR_QUALITY[i]}"
75
- i += 1
76
- }
77
- end
78
-
79
- def test_srcset_respects_overriding_quality
80
- quality_override = 100
81
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(w:100, q:quality_override)
82
-
83
- srcset.split(',').map { |src|
84
- assert_includes src, "q=#{quality_override}"
85
- }
86
- end
87
-
88
- def test_disable_variable_quality
89
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(w:100, options: { disable_variable_quality: true })
90
-
91
- srcset.split(',').map { |src|
92
- assert(not(src.include? "q="))
93
- }
94
- end
95
-
96
- def test_respects_quality_param_when_disabled
97
- quality_override = 100
98
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(w:100, q:100, options: { disable_variable_quality: true })
99
-
100
- srcset.split(',').map { |src|
101
- assert_includes src, "q=#{quality_override}"
102
- }
103
- end
104
-
105
- private
106
- DPR_QUALITY = [75, 50, 35, 23, 20]
107
-
108
- def srcset
109
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(w:100)
110
- end
111
- end
112
-
113
- class SrcsetGivenHeight < Imgix::Test
114
- def test_srcset_generates_width_pairs
115
- expected_number_of_pairs = 31
116
- assert_equal expected_number_of_pairs, srcset.split(',').length
117
- end
118
-
119
- def test_srcset_pair_values
120
- resolutions = [100, 116, 134, 156, 182, 210, 244, 282,
121
- 328, 380, 442, 512, 594, 688, 798, 926,
122
- 1074, 1246, 1446, 1678, 1946, 2258, 2618,
123
- 3038, 3524, 4088, 4742, 5500, 6380, 7400, 8192]
124
- srclist = srcset.split(',').map { |srcset_split|
125
- srcset_split.split(' ')[1].to_i
126
- }
127
-
128
- for i in 0..srclist.length - 1 do
129
- assert_equal(srclist[i], resolutions[i])
130
- end
131
- end
132
-
133
- def test_srcset_respects_height_parameter
134
- srcset.split(',').map { |src|
135
- assert_includes src, 'h='
136
- }
137
- end
138
-
139
- def test_srcset_within_bounds
140
- min, *max = srcset.split(',')
141
-
142
- # parse out the width descriptor as an integer
143
- min = min.split(' ')[1].to_i
144
- max = max[max.length - 1].split(' ')[1].to_i
145
-
146
- assert_operator min, :>=, 100
147
- assert_operator max, :<=, 8192
148
- end
149
-
150
- # a 17% testing threshold is used to account for rounding
151
- def test_srcset_iterates_17_percent
152
- increment_allowed = 0.17
153
-
154
- # create an array of widths
155
- widths = srcset.split(',').map { |src|
156
- src.split(' ')[1].to_i
157
- }
158
-
159
- prev = widths[0]
160
-
161
- for i in 1..widths.length - 1 do
162
- element = widths[i]
163
- assert_operator (element.to_f / prev.to_f), :<, (1 + increment_allowed)
164
- prev = element
165
- end
166
- end
167
-
168
- def test_srcset_signs_urls
169
- srcset.split(',').map { |srcset_split|
170
- src = srcset_split.split(' ')[0]
171
- assert_includes src, 's='
172
-
173
- # parses out all parameters except for 's=...'
174
- params = src[src.index('?')..src.index('s=') - 2]
175
-
176
- # parses out the 's=...' parameter
177
- generated_signature = src.slice(src.index('s=') + 2, src.length)
178
-
179
- signature_base = 'MYT0KEN' + '/image.jpg' + params;
180
- expected_signature = Digest::MD5.hexdigest(signature_base)
181
-
182
- assert_equal expected_signature, generated_signature
183
- }
184
- end
185
-
186
- private
187
- def srcset
188
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(h:100)
189
- end
190
- end
191
-
192
- class SrcsetGivenWidthAndHeight < Imgix::Test
193
- def test_srcset_in_dpr_form
194
- device_pixel_ratio = 1
195
- srcset.split(',').map { |src|
196
- ratio = src.split(' ')[1]
197
- assert_equal ("#{device_pixel_ratio}x"), ratio
198
- device_pixel_ratio += 1
199
- }
200
- end
201
-
202
- def test_srcset_has_dpr_params
203
- i = 1
204
- srcset.split(',').map { |srcset_split|
205
- src = srcset_split.split(' ')[0]
206
- assert_includes src, "dpr=#{i}"
207
- i += 1
208
- }
209
- end
210
-
211
- def test_srcset_signs_urls
212
- srcset.split(',').map { |srcset_split|
213
- src = srcset_split.split(' ')[0]
214
- assert_includes src, 's='
215
-
216
- # parses out all parameters except for 's=...'
217
- params = src[src.index('?')..src.index('s=') - 2]
218
-
219
- # parses out the 's=...' parameter
220
- generated_signature = src.slice(src.index('s=') + 2, src.length)
221
-
222
- signature_base = 'MYT0KEN' + '/image.jpg' + params;
223
- expected_signature = Digest::MD5.hexdigest(signature_base)
224
-
225
- assert_equal expected_signature, generated_signature
226
- }
227
- end
228
-
229
- def test_srcset_has_variable_qualities
230
- i = 0
231
- srcset.split(',').map { |src|
232
- assert_includes src, "q=#{DPR_QUALITY[i]}"
233
- i += 1
234
- }
235
- end
236
-
237
- def test_srcset_respects_overriding_quality
238
- quality_override = 100
239
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(w:100, h:100, q:quality_override)
240
-
241
- srcset.split(',').map { |src|
242
- assert_includes src, "q=#{quality_override}"
243
- }
244
- end
245
-
246
- def test_disable_variable_quality
247
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(w:100, h:100, options: { disable_variable_quality: true })
248
-
249
- srcset.split(',').map { |src|
250
- assert(not(src.include? "q="))
251
- }
252
- end
253
-
254
- def test_respects_quality_param_when_disabled
255
- quality_override = 100
256
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(w:100, h:100, q:100, options: { disable_variable_quality: true })
257
-
258
- srcset.split(',').map { |src|
259
- assert_includes src, "q=#{quality_override}"
260
- }
261
- end
262
-
263
- private
264
- DPR_QUALITY = [75, 50, 35, 23, 20]
265
-
266
- def srcset
267
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(w:100,h:100)
268
- end
269
- end
270
-
271
- class SrcsetGivenAspectRatio < Imgix::Test
272
- def test_srcset_generates_width_pairs
273
- expected_number_of_pairs = 31
274
- assert_equal expected_number_of_pairs, srcset.split(',').length
275
- end
276
-
277
- def test_srcset_pair_values
278
- resolutions = [100, 116, 134, 156, 182, 210, 244, 282,
279
- 328, 380, 442, 512, 594, 688, 798, 926,
280
- 1074, 1246, 1446, 1678, 1946, 2258, 2618,
281
- 3038, 3524, 4088, 4742, 5500, 6380, 7400, 8192]
282
- srclist = srcset.split(',').map { |srcset_split|
283
- srcset_split.split(' ')[1].to_i
284
- }
285
-
286
- for i in 0..srclist.length - 1 do
287
- assert_equal(srclist[i], resolutions[i])
288
- end
289
- end
290
-
291
- def test_srcset_within_bounds
292
- min, *max = srcset.split(',')
293
-
294
- # parse out the width descriptor as an integer
295
- min = min.split(' ')[1].to_i
296
- max = max[max.length - 1].split(' ')[1].to_i
297
-
298
- assert_operator min, :>=, 100
299
- assert_operator max, :<=, 8192
300
- end
301
-
302
- # a 17% testing threshold is used to account for rounding
303
- def test_srcset_iterates_17_percent
304
- increment_allowed = 0.17
305
-
306
- # create an array of widths
307
- widths = srcset.split(',').map { |src|
308
- src.split(' ')[1].to_i
309
- }
310
-
311
- prev = widths[0]
312
-
313
- for i in 1..widths.length - 1 do
314
- element = widths[i]
315
- assert_operator (element.to_f / prev.to_f), :<, (1 + increment_allowed)
316
- prev = element
317
- end
318
- end
319
-
320
- def test_srcset_signs_urls
321
- srcset.split(',').map { |srcset_split|
322
- src = srcset_split.split(' ')[0]
323
- assert_includes src, 's='
324
-
325
- # parses out all parameters except for 's=...'
326
- params = src[src.index('?')..src.index('s=') - 2]
327
-
328
- # parses out the 's=...' parameter
329
- generated_signature = src.slice(src.index('s=') + 2, src.length)
330
-
331
- signature_base = 'MYT0KEN' + '/image.jpg' + params;
332
- expected_signature = Digest::MD5.hexdigest(signature_base)
333
-
334
- assert_equal expected_signature, generated_signature
335
- }
336
- end
337
-
338
- private
339
- def srcset
340
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(ar:'3:2')
341
- end
342
- end
343
-
344
- class SrcsetGivenAspectRatioAndHeight < Imgix::Test
345
- def test_srcset_in_dpr_form
346
- device_pixel_ratio = 1
347
-
348
- srcset.split(',').map { |src|
349
- ratio = src.split(' ')[1]
350
- assert_equal ("#{device_pixel_ratio}x"), ratio
351
- device_pixel_ratio += 1
352
- }
353
- end
354
-
355
- def test_srcset_has_dpr_params
356
- i = 1
357
- srcset.split(',').map { |srcset_split|
358
- src = srcset_split.split(' ')[0]
359
- assert_includes src, "dpr=#{i}"
360
- i += 1
361
- }
362
- end
363
-
364
- def test_srcset_signs_urls
365
- srcset.split(',').map { |srcset_split|
366
- src = srcset_split.split(' ')[0]
367
- assert_includes src, 's='
368
-
369
- # parses out all parameters except for 's=...'
370
- params = src[src.index('?')..src.index('s=') - 2]
371
-
372
- # parses out the 's=...' parameter
373
- generated_signature = src.slice(src.index('s=') + 2, src.length)
374
-
375
- signature_base = 'MYT0KEN' + '/image.jpg' + params;
376
- expected_signature = Digest::MD5.hexdigest(signature_base)
377
-
378
- assert_equal expected_signature, generated_signature
379
- }
380
- end
381
-
382
- def test_srcset_has_variable_qualities
383
- i = 0
384
- srcset.split(',').map { |src|
385
- assert_includes src, "q=#{DPR_QUALITY[i]}"
386
- i += 1
387
- }
388
- end
389
-
390
- def test_srcset_respects_overriding_quality
391
- quality_override = 100
392
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(w:100, ar:'3:2', q:quality_override)
393
-
394
- srcset.split(',').map { |src|
395
- assert_includes src, "q=#{quality_override}"
396
- }
397
- end
398
-
399
- def test_disable_variable_quality
400
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(w:100, ar:'3:2', options: { disable_variable_quality: true })
401
-
402
- srcset.split(',').map { |src|
403
- assert(not(src.include? "q="))
404
- }
405
- end
406
-
407
- def test_respects_quality_param_when_disabled
408
- quality_override = 100
409
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(w:100, h:100, q:100, options: { disable_variable_quality: true })
410
-
411
- srcset.split(',').map { |src|
412
- assert_includes src, "q=#{quality_override}"
413
- }
414
- end
415
-
416
- private
417
- DPR_QUALITY = [75, 50, 35, 23, 20]
418
-
419
- def srcset
420
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset({h:100,ar:'3:2'})
421
- end
422
- end
423
-
424
- class SrcsetWidthTolerance < Imgix::Test
425
- def test_srcset_generates_width_pairs
426
- expected_number_of_pairs = 15
427
- assert_equal expected_number_of_pairs, srcset.split(',').length
428
- end
429
-
430
- def test_srcset_pair_values
431
- resolutions = [100,140,196,274,384,538,752,1054,1476,2066,2892,4050,5670,7938,8192]
432
- srclist = srcset.split(',').map { |srcset_split|
433
- srcset_split.split(' ')[1].to_i
434
- }
435
-
436
- for i in 0..srclist.length - 1 do
437
- assert_equal(srclist[i], resolutions[i])
438
- end
439
- end
440
-
441
- def test_srcset_within_bounds
442
- min, *max = srcset.split(',')
443
-
444
- # parse out the width descriptor as an integer
445
- min = min.split(' ')[1].to_i
446
- max = max[max.length - 1].split(' ')[1].to_i
447
- assert_operator min, :>=, 100
448
- assert_operator max, :<=, 8192
449
- end
450
-
451
- # a 41% testing threshold is used to account for rounding
452
- def test_srcset_iterates_41_percent
453
- increment_allowed = 0.41
454
-
455
- # create an array of widths
456
- widths = srcset.split(',').map { |src|
457
- src.split(' ')[1].to_i
458
- }
459
-
460
- prev = widths[0]
461
-
462
- for i in 1..widths.length - 1 do
463
- element = widths[i]
464
- assert_operator (element.to_f / prev.to_f), :<, (1 + increment_allowed)
465
- prev = element
466
- end
467
- end
468
-
469
- def test_invalid_tolerance_emits_error
470
- assert_raises(ArgumentError) {
471
- Imgix::Client.new(host: 'testing.imgix.net')
472
- .path('image.jpg')
473
- .to_srcset(options: {width_tolerance: 'abc'})
474
- }
475
- end
476
-
477
- def test_negative_tolerance_emits_error
478
- assert_raises(ArgumentError) {
479
- Imgix::Client.new(host: 'testing.imgix.net')
480
- .path('image.jpg')
481
- .to_srcset(options: {width_tolerance: -0.10})
482
- }
483
- end
484
-
485
- def test_with_param_after
486
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false)
487
- .path('image.jpg')
488
- .to_srcset(options: {width_tolerance: 0.20}, h:1000, fit:"clip")
489
- assert_includes(srcset, "h=")
490
- assert(not(srcset.include? "width_tolerance="))
491
- end
492
-
493
- def test_with_param_before
494
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false)
495
- .path('image.jpg')
496
- .to_srcset(h:1000, fit:"clip", options: {width_tolerance: 0.20})
497
- assert_includes(srcset, "h=")
498
- assert(not(srcset.include? "width_tolerance="))
499
- end
500
-
501
- private
502
- def srcset
503
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(options: {width_tolerance: 0.20})
504
- end
505
- end
506
-
507
- class SrcsetCustomWidths < Imgix::Test
508
- def test_srcset_generates_width_pairs
509
- expected_number_of_pairs = 4
510
- assert_equal expected_number_of_pairs, srcset.split(',').length
511
- end
512
-
513
- def test_srcset_pair_values
514
- resolutions = [100, 500, 1000, 1800]
515
- srclist = srcset.split(',').map { |srcset_split|
516
- srcset_split.split(' ')[1].to_i
517
- }
518
-
519
- for i in 0..srclist.length - 1 do
520
- assert_equal(srclist[i], resolutions[i])
521
- end
522
- end
523
-
524
- def test_srcset_within_bounds
525
- min, *max = srcset.split(',')
526
-
527
- # parse out the width descriptor as an integer
528
- min = min.split(' ')[1].to_i
529
- max = max[max.length - 1].split(' ')[1].to_i
530
-
531
- assert_operator min, :>=, @widths[0]
532
- assert_operator max, :<=, @widths[-1]
533
- end
534
-
535
- def test_invalid_widths_input_emits_error
536
- assert_raises(ArgumentError) {
537
- Imgix::Client.new(host: 'testing.imgix.net')
538
- .path('image.jpg')
539
- .to_srcset(options: {widths: 'abc'})
540
- }
541
- end
542
-
543
- def test_non_integer_array_emits_error
544
- assert_raises(ArgumentError) {
545
- Imgix::Client.new(host: 'testing.imgix.net')
546
- .path('image.jpg')
547
- .to_srcset(options: {widths: [100, 200, false]})
548
- }
549
- end
550
-
551
- def test_negative_integer_array_emits_error
552
- assert_raises(ArgumentError) {
553
- Imgix::Client.new(host: 'testing.imgix.net')
554
- .path('image.jpg')
555
- .to_srcset(options: {widths: [100, 200, -100]})
556
- }
557
- end
558
-
559
- def test_with_param_after
560
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false)
561
- .path('image.jpg')
562
- .to_srcset(options: {widths: [100, 200, 300]}, h:1000, fit:"clip")
563
- assert_includes(srcset, "h=")
564
- assert(not(srcset.include? "widths="))
565
- end
566
-
567
- def test_with_param_before
568
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false)
569
- .path('image.jpg')
570
- .to_srcset(h:1000, fit:"clip", options: {widths: [100, 200, 300]})
571
- assert_includes(srcset, "h=")
572
- assert(not(srcset.include? "widths="))
573
- end
574
-
575
- private
576
- def srcset
577
- @widths = [100, 500, 1000, 1800]
578
- @client ||= Imgix::Client.new(
579
- host: 'testing.imgix.net',
580
- include_library_param: false)
581
- .path('image.jpg')
582
- .to_srcset(options: {widths: @widths})
583
- end
584
- end
585
-
586
- class SrcsetMinMaxWidths < Imgix::Test
587
- def test_srcset_generates_width_pairs
588
- expected_number_of_pairs = 11
589
- assert_equal expected_number_of_pairs, srcset.split(',').length
590
- end
591
-
592
- def test_srcset_pair_values
593
- resolutions = [500,580,672,780,906,1050,1218,1414,1640,1902,2000]
594
- srclist = srcset.split(',').map { |srcset_split|
595
- srcset_split.split(' ')[1].to_i
596
- }
597
-
598
- for i in 0..srclist.length - 1 do
599
- assert_equal(srclist[i], resolutions[i])
600
- end
601
- end
602
-
603
- def test_srcset_within_bounds
604
- min, *max = srcset.split(',')
605
-
606
- # parse out the width descriptor as an integer
607
- min = min.split(' ')[1].to_i
608
- max = max[max.length - 1].split(' ')[1].to_i
609
-
610
- assert_operator min, :>=, @MIN
611
- assert_operator max, :<=, @MAX
612
- end
613
-
614
- # a 41% testing threshold is used to account for rounding
615
- def test_with_custom_width_tolerance
616
- srcset = Imgix::Client.new(host: 'testing.imgix.net', secure_url_token: 'MYT0KEN', include_library_param: false).path('image.jpg').to_srcset(options: {min_width: 500, max_width: 2000, width_tolerance: 0.20})
617
-
618
- increment_allowed = 0.41
619
-
620
- # create an array of widths
621
- widths = srcset.split(',').map { |src|
622
- src.split(' ')[1].to_i
623
- }
624
-
625
- prev = widths[0]
626
-
627
- for i in 1..widths.length - 1 do
628
- element = widths[i]
629
- assert_operator (element.to_f / prev.to_f), :<, (1 + increment_allowed)
630
- prev = element
631
- end
632
- end
633
-
634
- def test_invalid_min_emits_error
635
- assert_raises(ArgumentError) {
636
- Imgix::Client.new(host: 'testing.imgix.net')
637
- .path('image.jpg')
638
- .to_srcset(options: {min_width: 'abc'})
639
- }
640
- end
641
-
642
- def test_negative_max_emits_error
643
- assert_raises(ArgumentError) {
644
- Imgix::Client.new(host: 'testing.imgix.net')
645
- .path('image.jpg')
646
- .to_srcset(options: {max_width: -100})
647
- }
648
- end
649
-
650
- def test_with_param_after
651
- srcset = Imgix::Client.new(host: 'testing.imgix.net', include_library_param: false)
652
- .path('image.jpg')
653
- .to_srcset(options: {min_width: 500, max_width:2000}, h:1000, fit:"clip")
654
-
655
- assert_includes(srcset, "h=")
656
- assert(not(srcset.include? "min_width="))
657
- assert(not(srcset.include? "max_width="))
658
- end
659
-
660
- def test_with_param_before
661
- srcset = Imgix::Client.new(host: 'testing.imgix.net', include_library_param: false)
662
- .path('image.jpg')
663
- .to_srcset(h:1000, fit:"clip", options: {min_width: 500, max_width:2000})
664
-
665
- assert_includes(srcset, "h=")
666
- assert(not(srcset.include? "min_width="))
667
- assert(not(srcset.include? "max_width="))
668
- end
669
-
670
- def test_only_min
671
- min_width = 1000
672
- max_width = 8192
673
- srcset = Imgix::Client.new(host: 'testing.imgix.net', include_library_param: false).path('image.jpg').to_srcset(options: {min_width: min_width})
674
-
675
- min, *max = srcset.split(',')
676
-
677
- # parse out the width descriptor as an integer
678
- min = min.split(' ')[1].to_i
679
- max = max[max.length - 1].split(' ')[1].to_i
680
-
681
- assert_operator min, :>=, min_width
682
- assert_operator max, :<=, max_width
683
- end
684
-
685
- def test_only_max
686
- min_width = 100
687
- max_width = 1000
688
- srcset = Imgix::Client.new(host: 'testing.imgix.net', include_library_param: false).path('image.jpg').to_srcset(options: {max_width: max_width})
689
- min, *max = srcset.split(',')
690
-
691
- # parse out the width descriptor as an integer
692
- min = min.split(' ')[1].to_i
693
- max = max[max.length - 1].split(' ')[1].to_i
694
-
695
- assert_operator min, :>=, min_width
696
- assert_operator max, :<=, max_width
697
- end
698
-
699
- def test_max_as_100
700
- srcset = Imgix::Client.new(host: 'testing.imgix.net', include_library_param: false).path('image.jpg').to_srcset(options: {max_width: 100})
701
- assert_equal(srcset, "https://testing.imgix.net/image.jpg?w=100 100w")
702
- end
703
-
704
- def test_min_as_8192
705
- srcset = Imgix::Client.new(host: 'testing.imgix.net', include_library_param: false).path('image.jpg').to_srcset(options: {min_width: 8192})
706
- assert_equal(srcset, "https://testing.imgix.net/image.jpg?w=8192 8192w")
707
- end
708
-
709
- private
710
- def srcset
711
- @MIN = 500
712
- @MAX = 2000
713
- @client ||= Imgix::Client.new(host: 'testing.imgix.net', include_library_param: false).path('image.jpg').to_srcset(options: {min_width: @MIN, max_width: @MAX})
714
- end
747
+ def srcset
748
+ @MIN = 500
749
+ @MAX = 2000
750
+ @client ||= mock_client.to_srcset(
751
+ options: { min_width: @MIN, max_width: @MAX }
752
+ )
715
753
  end
754
+ end
716
755
  end