image_optim 0.20.2 → 0.21.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.
@@ -63,7 +63,9 @@ describe ImageOptim::Worker do
63
63
  it 'creates all workers for which options_proc returns true' do
64
64
  workers = Array.new(3){ worker_double }
65
65
  klasses = workers.map{ |worker| double(:init => worker) }
66
- options_proc = proc{ |klass| klass != klasses[1] ? {} : false }
66
+ options_proc = proc do |klass|
67
+ klass == klasses[1] ? {:disable => true} : {}
68
+ end
67
69
 
68
70
  allow(Worker).to receive(:klasses).and_return(klasses)
69
71
 
@@ -52,43 +52,6 @@ describe ImageOptim do
52
52
  end
53
53
 
54
54
  describe :optimize_image do
55
- def flatten_animation(image)
56
- if image.format == :gif
57
- flattened = image.temp_path
58
- flatten_command = %W[
59
- convert
60
- #{image.to_s.shellescape}
61
- -coalesce
62
- -append
63
- #{flattened.to_s.shellescape}
64
- ].join(' ')
65
- expect(Cmd.run(flatten_command)).to be_truthy
66
- flattened
67
- else
68
- image
69
- end
70
- end
71
-
72
- def nrmse(image_a, image_b)
73
- coalesce_a = flatten_animation(image_a)
74
- coalesce_b = flatten_animation(image_b)
75
- nrmse_command = %W[
76
- compare
77
- -metric RMSE
78
- -alpha Background
79
- #{coalesce_a.to_s.shellescape}
80
- #{coalesce_b.to_s.shellescape}
81
- /dev/null
82
- 2>&1
83
- ].join(' ')
84
- output = Cmd.capture(nrmse_command)
85
- if [0, 1].include?($CHILD_STATUS.exitstatus)
86
- output[/\((\d+(\.\d+)?)\)/, 1].to_f
87
- else
88
- fail "compare #{image_a} with #{image_b} failed with `#{output}`"
89
- end
90
- end
91
-
92
55
  define :have_same_data_as do |expected|
93
56
  match{ |actual| actual.binread == expected.binread }
94
57
  end
@@ -97,21 +60,6 @@ describe ImageOptim do
97
60
  match(&:size?)
98
61
  end
99
62
 
100
- define :be_smaller_than do |expected|
101
- match{ |actual| actual.size < expected.size }
102
- end
103
-
104
- define :be_similar_to do |expected, max_difference|
105
- match do |actual|
106
- @diff = nrmse(actual, expected)
107
- @diff <= max_difference
108
- end
109
- failure_message do |actual|
110
- "expected #{actual} to have at most #{max_difference} difference from "\
111
- "#{expected}, got normalized root-mean-square error of #{@diff}"
112
- end
113
- end
114
-
115
63
  describe 'optimizing images' do
116
64
  rotated = images_dir / 'orient/original.jpg'
117
65
  rotate_images = images_dir.glob('orient/?.jpg')
Binary file
data/spec/spec_helper.rb CHANGED
@@ -10,3 +10,55 @@ end
10
10
  RSpec.configure do |c|
11
11
  c.alias_example_to :they
12
12
  end
13
+
14
+ def flatten_animation(image)
15
+ if image.format == :gif
16
+ flattened = image.temp_path
17
+ flatten_command = %W[
18
+ convert
19
+ #{image.to_s.shellescape}
20
+ -coalesce
21
+ -append
22
+ #{flattened.to_s.shellescape}
23
+ ].join(' ')
24
+ expect(ImageOptim::Cmd.run(flatten_command)).to be_truthy
25
+ flattened
26
+ else
27
+ image
28
+ end
29
+ end
30
+
31
+ def nrmse(image_a, image_b)
32
+ coalesce_a = flatten_animation(image_a)
33
+ coalesce_b = flatten_animation(image_b)
34
+ nrmse_command = %W[
35
+ compare
36
+ -metric RMSE
37
+ -alpha Background
38
+ #{coalesce_a.to_s.shellescape}
39
+ #{coalesce_b.to_s.shellescape}
40
+ /dev/null
41
+ 2>&1
42
+ ].join(' ')
43
+ output = ImageOptim::Cmd.capture(nrmse_command)
44
+ if [0, 1].include?($CHILD_STATUS.exitstatus)
45
+ output[/\((\d+(\.\d+)?)\)/, 1].to_f
46
+ else
47
+ fail "compare #{image_a} with #{image_b} failed with `#{output}`"
48
+ end
49
+ end
50
+
51
+ RSpec::Matchers.define :be_smaller_than do |expected|
52
+ match{ |actual| actual.size < expected.size }
53
+ end
54
+
55
+ RSpec::Matchers.define :be_similar_to do |expected, max_difference|
56
+ match do |actual|
57
+ @diff = nrmse(actual, expected)
58
+ @diff <= max_difference
59
+ end
60
+ failure_message do |actual|
61
+ "expected #{actual} to have at most #{max_difference} difference from "\
62
+ "#{expected}, got normalized root-mean-square error of #{@diff}"
63
+ end
64
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: image_optim
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.2
4
+ version: 0.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Kuchin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-26 00:00:00.000000000 Z
11
+ date: 2015-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fspath
@@ -44,20 +44,20 @@ dependencies:
44
44
  requirements:
45
45
  - - ~>
46
46
  - !ruby/object:Gem::Version
47
- version: '1.1'
47
+ version: '1.2'
48
48
  - - ! '>='
49
49
  - !ruby/object:Gem::Version
50
- version: 1.1.3
50
+ version: 1.2.2
51
51
  type: :runtime
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
55
  - - ~>
56
56
  - !ruby/object:Gem::Version
57
- version: '1.1'
57
+ version: '1.2'
58
58
  - - ! '>='
59
59
  - !ruby/object:Gem::Version
60
- version: 1.1.3
60
+ version: 1.2.2
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: progress
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -127,6 +127,9 @@ dependencies:
127
127
  - - ~>
128
128
  - !ruby/object:Gem::Version
129
129
  version: '0.27'
130
+ - - ! '!='
131
+ - !ruby/object:Gem::Version
132
+ version: 0.30.1
130
133
  type: :development
131
134
  prerelease: false
132
135
  version_requirements: !ruby/object:Gem::Requirement
@@ -134,20 +137,9 @@ dependencies:
134
137
  - - ~>
135
138
  - !ruby/object:Gem::Version
136
139
  version: '0.27'
137
- - !ruby/object:Gem::Dependency
138
- name: haml
139
- requirement: !ruby/object:Gem::Requirement
140
- requirements:
141
- - - ~>
142
- - !ruby/object:Gem::Version
143
- version: '4.0'
144
- type: :development
145
- prerelease: false
146
- version_requirements: !ruby/object:Gem::Requirement
147
- requirements:
148
- - - ~>
140
+ - - ! '!='
149
141
  - !ruby/object:Gem::Version
150
- version: '4.0'
142
+ version: 0.30.1
151
143
  description:
152
144
  email:
153
145
  executables:
@@ -163,6 +155,7 @@ files:
163
155
  - Gemfile
164
156
  - LICENSE.txt
165
157
  - README.markdown
158
+ - Vagrantfile
166
159
  - bin/image_optim
167
160
  - image_optim.gemspec
168
161
  - lib/image_optim.rb
@@ -200,9 +193,11 @@ files:
200
193
  - lib/image_optim/worker/pngout.rb
201
194
  - lib/image_optim/worker/pngquant.rb
202
195
  - lib/image_optim/worker/svgo.rb
196
+ - script/template/jquery-2.1.3.min.js
197
+ - script/template/sortable-0.6.0.min.js
198
+ - script/template/worker_analysis.erb
203
199
  - script/update_worker_options_in_readme
204
200
  - script/worker_analysis
205
- - script/worker_analysis.haml
206
201
  - spec/image_optim/bin_resolver/comparable_condition_spec.rb
207
202
  - spec/image_optim/bin_resolver/simple_version_spec.rb
208
203
  - spec/image_optim/bin_resolver_spec.rb
@@ -211,6 +206,7 @@ files:
211
206
  - spec/image_optim/handler_spec.rb
212
207
  - spec/image_optim/hash_helpers_spec.rb
213
208
  - spec/image_optim/image_path_spec.rb
209
+ - spec/image_optim/railtie_spec.rb
214
210
  - spec/image_optim/runner/glob_helpers_spec.rb
215
211
  - spec/image_optim/runner/option_parser_spec.rb
216
212
  - spec/image_optim/space_spec.rb
@@ -236,6 +232,7 @@ files:
236
232
  - spec/images/orient/original.jpg
237
233
  - spec/images/quant/64.png
238
234
  - spec/images/quant/generate
235
+ - spec/images/rails.png
239
236
  - spec/images/test.svg
240
237
  - spec/images/transparency1.png
241
238
  - spec/images/transparency2.png
@@ -262,7 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
262
259
  version: '0'
263
260
  requirements: []
264
261
  rubyforge_project: image_optim
265
- rubygems_version: 2.4.5
262
+ rubygems_version: 2.4.7
266
263
  signing_key:
267
264
  specification_version: 4
268
265
  summary: Optimize (lossless compress, optionally lossy) images (jpeg, png, gif, svg)
@@ -277,6 +274,7 @@ test_files:
277
274
  - spec/image_optim/handler_spec.rb
278
275
  - spec/image_optim/hash_helpers_spec.rb
279
276
  - spec/image_optim/image_path_spec.rb
277
+ - spec/image_optim/railtie_spec.rb
280
278
  - spec/image_optim/runner/glob_helpers_spec.rb
281
279
  - spec/image_optim/runner/option_parser_spec.rb
282
280
  - spec/image_optim/space_spec.rb
@@ -302,6 +300,7 @@ test_files:
302
300
  - spec/images/orient/original.jpg
303
301
  - spec/images/quant/64.png
304
302
  - spec/images/quant/generate
303
+ - spec/images/rails.png
305
304
  - spec/images/test.svg
306
305
  - spec/images/transparency1.png
307
306
  - spec/images/transparency2.png
@@ -1,174 +0,0 @@
1
- !!! 5
2
- %html
3
- %head
4
- %meta(http-equiv="Content-Type" content="text/html; charset=utf-8")
5
- %title Worker Analysis
6
- :css
7
- body {
8
- font: 14px "Myriad Pro", "Helvetica", Arial, sans-serif;
9
- margin: 20px;
10
- padding: 0;
11
- }
12
-
13
- .formats {
14
- display: block;
15
- font-size: 1.5em;
16
- margin: 1em 0;
17
- font-weight: bold;
18
- }
19
-
20
- table {
21
- border-collapse: collapse;
22
- border-spacing: 0;
23
- }
24
- th, td {
25
- border: 1px solid #ccc;
26
- padding: 6px 8px 2px;
27
- }
28
- th {
29
- text-align: left;
30
- border-color: #999;
31
- }
32
- th:not([data-sortable="false"]) {
33
- cursor: pointer;
34
- padding-right: 18px;
35
- }
36
- th:after {
37
- position: absolute;
38
- width: 18px;
39
- height: 14px;
40
- line-height: 14px;
41
- font-size: 0.8em;
42
- color: #999;
43
- visibility: hidden;
44
- text-align: center;
45
- }
46
- th[data-sorted="true"]:after {
47
- visibility: visible;
48
- }
49
- th[data-sorted-direction="descending"]:after {
50
- content: "▼";
51
- }
52
- th[data-sorted-direction="ascending"]:after {
53
- content: "▲";
54
- }
55
- table[data-sortable] tbody tr:hover {
56
- background: #ddf;
57
- }
58
- body:not(.show-unused) tr.unused, tr.filtered-out {
59
- display: none;
60
- }
61
-
62
- input { display: block; width: 30%; }
63
- input[type=checkbox] { display: inline; width: auto; }
64
-
65
- .number {
66
- text-align: right;
67
- }
68
-
69
- .warn-low {
70
- background: rgba(255, 0, 0, 0.1);
71
- }
72
- .warn-medium {
73
- background: rgba(255, 0, 0, 0.4);
74
- }
75
- .warn-high {
76
- background: rgba(255, 0, 0, 0.8);
77
- }
78
-
79
- .worker-name,
80
- .worker-success-count {
81
- display: inline-block;
82
- border-radius: 8px;
83
- }
84
- .worker-name {
85
- background: #ddd;
86
- padding: 2px 5px 0;
87
- border: 1px solid #999;
88
- margin: -3px 0 1px 0;
89
- }
90
- .worker-success-count {
91
- font-size: 0.9em;
92
- line-height: 1em;
93
- background: #dfd;
94
- padding: 1px 2px 0;
95
- border: 1px solid #9b9;
96
- }
97
- .worker-name.unused {
98
- text-decoration: line-through;
99
- }
100
- :javascript
101
- /*! sortable.js 0.6.0 */
102
- (function(){var a,b,c,d,e,f,g;a="table[data-sortable]",d=/^-?[£$¤]?[\d,.]+%?$/,g=/^\s+|\s+$/g,f="ontouchstart"in document.documentElement,c=f?"touchstart":"click",b=function(a,b,c){return null!=a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent("on"+b,c)},e={init:function(b){var c,d,f,g,h;for(null==b&&(b={}),null==b.selector&&(b.selector=a),d=document.querySelectorAll(b.selector),h=[],f=0,g=d.length;g>f;f++)c=d[f],h.push(e.initTable(c));return h},initTable:function(a){var b,c,d,f,g,h;if(1===(null!=(h=a.tHead)?h.rows.length:void 0)&&"true"!==a.getAttribute("data-sortable-initialized")){for(a.setAttribute("data-sortable-initialized","true"),d=a.querySelectorAll("th"),b=f=0,g=d.length;g>f;b=++f)c=d[b],"false"!==c.getAttribute("data-sortable")&&e.setupClickableTH(a,c,b);return a}},setupClickableTH:function(a,d,f){var g;return g=e.getColumnType(a,f),"click"===c&&b(d,"mousedown",function(){return event.preventDefault?event.preventDefault():event.returnValue=!1}),b(d,c,function(){var b,c,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;for("true"===this.getAttribute("data-sorted")?(l=this.getAttribute("data-sorted-direction"),b="ascending"===l?"descending":"ascending"):b=this.getAttribute("data-default-direction")||g.defaultSortDirection,n=this.parentNode.querySelectorAll("th"),o=0,r=n.length;r>o;o++)d=n[o],d.setAttribute("data-sorted","false"),d.removeAttribute("data-sorted-direction");for(this.setAttribute("data-sorted","true"),this.setAttribute("data-sorted-direction",b),m=a.tBodies[0],i=[],u=m.rows,c=p=0,s=u.length;s>p;c=++p)h=u[c],i.push([e.getNodeValue(h.cells[f]),h,c]);for(k="descending"===b?-1:1,i.sort(function(a,b){var c;return c=g.compare(a,b),0!==c?c*k:a[2]-b[2]}),v=[],q=0,t=i.length;t>q;q++)j=i[q],v.push(m.appendChild(j[1]));return v})},getColumnType:function(a,b){var c,f,g,h,i;for(i=a.tBodies[0].rows,g=0,h=i.length;h>g;g++)if(c=i[g],f=e.getNodeValue(c.cells[b]),""!==f){if(f.match(d))return e.types.numeric;if(!isNaN(Date.parse(f)))return e.types.date}return e.types.alpha},getNodeValue:function(a){return a?null!==a.getAttribute("data-value")?a.getAttribute("data-value"):"undefined"!=typeof a.innerText?a.innerText.replace(g,""):a.textContent.replace(g,""):""},types:{numeric:{defaultSortDirection:"descending",compare:function(a,b){var c,d;return c=parseFloat(a[0].replace(/[^0-9.-]/g,""),10),d=parseFloat(b[0].replace(/[^0-9.-]/g,""),10),isNaN(c)&&(c=0),isNaN(d)&&(d=0),c-d}},alpha:{defaultSortDirection:"ascending",compare:function(a,b){return a[0].localeCompare(b[0])}},date:{defaultSortDirection:"ascending",compare:function(a,b){var c,d;return c=Date.parse(a[0]),d=Date.parse(b[0]),isNaN(c)&&(c=0),isNaN(d)&&(d=0),c-d}}}},setTimeout(e.init,0),window.Sortable=e}).call(this);
103
- :javascript
104
- function toggleShowUnused(){
105
- var checked = document.getElementById('toggle-show-unused').checked
106
- document.body.classList[checked ? 'add' : 'remove']('show-unused')
107
- }
108
- function filterTable(){
109
- var filter = new RegExp(document.getElementById('filter').value)
110
- var rows = document.querySelectorAll('tbody.filterable tr')
111
- for (var i = 0, _i = rows.length; i < _i; i++) {
112
- var row = rows[i]
113
- if (!row.hasAttribute('data-filter-text')) {
114
- var text = row.textContent.replace(/\s+/g, ' ')
115
- row.setAttribute('data-filter-text', text)
116
- }
117
- var show = filter.test(row.getAttribute('data-filter-text'))
118
- row.classList[show ? 'remove' : 'add']('filtered-out')
119
- }
120
- }
121
- %body
122
- .formats
123
- - format_links.each do |format, link|
124
- - if stats_format == format
125
- %span= format
126
- - else
127
- %a(href="#{link}")= format
128
- %table
129
- %tr
130
- %td.warn-low Max difference >= 0.001
131
- %td.warn-medium Max difference >= 0.01
132
- %td.warn-high Max difference >= 0.1
133
- %p
134
- %label
135
- %input#toggle-show-unused(type="checkbox" onchange="toggleShowUnused()")
136
- Show chains with workers failed for every image
137
- %p
138
- %label(for="filter")
139
- Filter chains by regexp
140
- %input#filter(type="text" onkeyup="filterTable()")
141
- %p
142
- Images: #{stats.each_chain.first.entry_count},
143
- size: #{stats.each_chain.first.original_size}
144
- %table(data-sortable)
145
- %thead
146
- %tr
147
- %th Chain
148
- %th(data-default-direction="ascending"
149
- data-sorted="true"
150
- data-sorted-direction="ascending") Optimized size
151
- %th(data-default-direction="ascending") Ratio
152
- %th(data-default-direction="ascending") Avg ratio
153
- %th(data-default-direction="ascending") Time (s)
154
- %th(data-default-direction="ascending") Avg difference
155
- %th(data-default-direction="ascending") Max difference
156
- %th Speed (B/s)
157
- %tbody.filterable
158
- - stats.each_chain do |chain|
159
- %tr{class: chain.unused_workers && 'unused'}
160
- %td
161
- - chain.worker_stats.each do |worker_stat|
162
- .worker-name{:class => worker_stat.unused? && 'unused'}
163
- = worker_stat.name
164
- - unless worker_stat.unused?
165
- .worker-success-count(title="successfull count")
166
- = worker_stat.success_count
167
- %td.number= chain.optimized_size
168
- %td.number= format '%.5f', chain.ratio
169
- %td.number= format '%.5f', chain.avg_ratio
170
- %td.number= format '%.2f', chain.time
171
- %td.number= format '%.5f', chain.avg_difference
172
- %td.number{class: chain.warn_level && "warn-#{chain.warn_level}"}
173
- = format '%.5f', chain.max_difference
174
- %td.number= format '%.2f', chain.speed