image_optim_pack 0.12.0-arm64-darwin

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.dockerignore +10 -0
  3. data/.github/dependabot.yml +6 -0
  4. data/.github/workflows/build.yml +47 -0
  5. data/.github/workflows/check.yml +33 -0
  6. data/.github/workflows/docker-build.yml +29 -0
  7. data/.github/workflows/livecheck.yml +35 -0
  8. data/.github/workflows/rubocop.yml +16 -0
  9. data/.gitignore +7 -0
  10. data/.rubocop.yml +97 -0
  11. data/CHANGELOG.markdown +546 -0
  12. data/Dockerfile +184 -0
  13. data/Dockerfile.debian +184 -0
  14. data/Gemfile +10 -0
  15. data/LICENSE.txt +27 -0
  16. data/Makefile +543 -0
  17. data/README.markdown +121 -0
  18. data/acknowledgements/7z.txt +56 -0
  19. data/acknowledgements/advancecomp.txt +674 -0
  20. data/acknowledgements/bmp2png.txt +8 -0
  21. data/acknowledgements/cexcept.txt +8 -0
  22. data/acknowledgements/gifread.txt +14 -0
  23. data/acknowledgements/gifsicle.txt +343 -0
  24. data/acknowledgements/iqa.txt +30 -0
  25. data/acknowledgements/jhead.txt +12 -0
  26. data/acknowledgements/jpeg-archive.txt +20 -0
  27. data/acknowledgements/jpegoptim.txt +339 -0
  28. data/acknowledgements/libjpeg-turbo.txt +27 -0
  29. data/acknowledgements/libjpeg-x86-simd.txt +17 -0
  30. data/acknowledgements/libjpeg.txt +64 -0
  31. data/acknowledgements/liblcms2.txt +21 -0
  32. data/acknowledgements/libpng.txt +90 -0
  33. data/acknowledgements/mozjpeg.txt +7 -0
  34. data/acknowledgements/optipng-authors.txt +26 -0
  35. data/acknowledgements/optipng.txt +21 -0
  36. data/acknowledgements/oxipng.txt +20 -0
  37. data/acknowledgements/pngcrush.txt +35 -0
  38. data/acknowledgements/pngout.txt +9 -0
  39. data/acknowledgements/pngquant.txt +56 -0
  40. data/acknowledgements/smallfry.txt +13 -0
  41. data/acknowledgements/zlib.txt +34 -0
  42. data/acknowledgements/zopfli-contributors.txt +6 -0
  43. data/acknowledgements/zopfli.txt +201 -0
  44. data/checksums.mk +17 -0
  45. data/image_optim_pack-darwin-arm64.gemspec +3 -0
  46. data/image_optim_pack-darwin-x86_64.gemspec +3 -0
  47. data/image_optim_pack-linux-x86_64.gemspec +3 -0
  48. data/image_optim_pack.gemspec +62 -0
  49. data/lib/image_optim/pack.rb +119 -0
  50. data/lib/image_optim_pack.rb +3 -0
  51. data/patches/pngcrush.patch +15 -0
  52. data/script/extract +19 -0
  53. data/script/livecheck +263 -0
  54. data/script/platform_downloads +59 -0
  55. data/script/run +131 -0
  56. data/spec/image_optim/pack_spec.rb +116 -0
  57. data/spec/image_optim_spec.rb +42 -0
  58. data/spec/spec_helper.rb +10 -0
  59. data/vendor/darwin-arm64/advpng +0 -0
  60. data/vendor/darwin-arm64/gifsicle +0 -0
  61. data/vendor/darwin-arm64/jhead +0 -0
  62. data/vendor/darwin-arm64/jpeg-recompress +0 -0
  63. data/vendor/darwin-arm64/jpegoptim +0 -0
  64. data/vendor/darwin-arm64/jpegtran +0 -0
  65. data/vendor/darwin-arm64/libjpeg.dylib +0 -0
  66. data/vendor/darwin-arm64/liblcms2.dylib +0 -0
  67. data/vendor/darwin-arm64/libpng.dylib +0 -0
  68. data/vendor/darwin-arm64/libz.dylib +0 -0
  69. data/vendor/darwin-arm64/optipng +0 -0
  70. data/vendor/darwin-arm64/oxipng +0 -0
  71. data/vendor/darwin-arm64/pngcrush +0 -0
  72. data/vendor/darwin-arm64/pngout +0 -0
  73. data/vendor/darwin-arm64/pngquant +0 -0
  74. metadata +199 -0
data/script/livecheck ADDED
@@ -0,0 +1,263 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'uri'
5
+ require 'net/http'
6
+ require 'openssl'
7
+ require 'rubygems/version'
8
+ require 'fspath'
9
+
10
+ CONFIG = {
11
+ advancecomp: {
12
+ url: 'https://github.com/amadvance/advancecomp/releases.atom',
13
+ regexp: %r{<id>tag:github.com,2008:Repository/\d+/\D+?(\d+(?:\.\d+)*)</id>},
14
+ info_url: 'https://www.advancemame.it/comp-history',
15
+ },
16
+ gifsicle: {
17
+ url: 'https://www.lcdf.org/gifsicle/',
18
+ regexp: /gifsicle-(\d+(?:\.\d+)*)\.tar\.gz/,
19
+ info_url: 'https://www.lcdf.org/gifsicle/changes.html',
20
+ },
21
+ jhead: {
22
+ url: 'https://www.sentex.ca/~mwandel/jhead/',
23
+ regexp: /jhead-(\d+(?:\.\d+)*)/,
24
+ info_url: 'https://www.sentex.ca/~mwandel/jhead/changes.txt',
25
+ },
26
+ jpegoptim: {
27
+ url: 'https://github.com/tjko/jpegoptim/tags.atom',
28
+ regexp: %r{<id>tag:github.com,2008:Repository/\d+/\D+?(\d+(?:\.\d+)*)</id>},
29
+ info_url: 'https://github.com/tjko/jpegoptim/#readme',
30
+ },
31
+ jpegarchive: {
32
+ url: 'https://github.com/danielgtaylor/jpeg-archive/releases.atom',
33
+ regexp: %r{<id>tag:github.com,2008:Repository/\d+/\D+?(\d+(?:\.\d+)*)</id>},
34
+ info_url: 'https://github.com/danielgtaylor/jpeg-archive/releases',
35
+ },
36
+ libjpeg: {
37
+ url: 'https://www.ijg.org/files/',
38
+ regexp: /jpegsrc.v(.*?).tar.gz/,
39
+ info_url: 'https://jpegclub.org/reference/reference-sources/#:~:text=CHANGE%20LOG',
40
+ },
41
+ liblcms: {
42
+ url: 'https://sourceforge.net/projects/lcms/rss?path=/lcms',
43
+ regexp: %r{/lcms/(\d+(?:\.\d+)*)/},
44
+ info_url: 'https://www.littlecms.com/blog/',
45
+ },
46
+ libmozjpeg: {
47
+ url: 'https://github.com/mozilla/mozjpeg/releases.atom',
48
+ regexp: %r{<id>tag:github.com,2008:Repository/\d+/\D+?(\d+(?:\.\d+)*)</id>},
49
+ info_url: 'https://github.com/mozilla/mozjpeg/releases',
50
+ },
51
+ libpng: {
52
+ url: 'https://sourceforge.net/projects/libpng/rss?path=/libpng16',
53
+ regexp: %r{/libpng\d*/(\d+(?:\.\d+)*)/},
54
+ info_url: 'https://github.com/glennrp/libpng/blob/libpng16/CHANGES#:~:text=Send%20comments/corrections/commendations%20to%20png%2Dmng%2Dimplement%20at%20lists.sf.net.',
55
+ },
56
+ libz: {
57
+ url: 'https://sourceforge.net/projects/libpng/rss?path=/zlib',
58
+ regexp: %r{/zlib/(\d+(?:\.\d+)*)/},
59
+ info_url: 'https://github.com/glennrp/zlib/blob/master/ChangeLog',
60
+ },
61
+ optipng: {
62
+ url: 'https://sourceforge.net/projects/optipng/rss',
63
+ regexp: %r{/OptiPNG/optipng-(\d+(?:\.\d+)*)/},
64
+ info_url: 'https://optipng.sourceforge.net/history.txt',
65
+ },
66
+ oxipng: {
67
+ url: 'https://github.com/shssoichiro/oxipng/releases.atom',
68
+ regexp: %r{<id>tag:github.com,2008:Repository/\d+/v(\d+(?:\.\d+)*)</id>},
69
+ info_url: 'https://github.com/shssoichiro/oxipng/releases',
70
+ },
71
+ pngcrush: {
72
+ url: 'https://sourceforge.net/projects/pmt/rss?path=/pngcrush',
73
+ regexp: %r{/pngcrush/(\d+(?:\.\d+)*)/},
74
+ info_url: 'https://pmt.sourceforge.io/pngcrush/ChangeLog.html',
75
+ },
76
+ pngout_linux: {
77
+ url: 'https://www.jonof.id.au/kenutils.html',
78
+ regexp: %r{/files/kenutils/pngout-(\d{8})-linux.tar.gz},
79
+ info_url: 'https://www.jonof.id.au/kenutils.html#:~:text=Revision%20history',
80
+ },
81
+ pngout_darwin: {
82
+ url: 'https://www.jonof.id.au/kenutils.html',
83
+ regexp: %r{/files/kenutils/pngout-(\d{8})-mac(?:os)?.zip},
84
+ info_url: 'https://www.jonof.id.au/kenutils.html#:~:text=Revision%20history',
85
+ },
86
+ pngquant: {
87
+ url: 'https://index.crates.io/pn/gq/pngquant',
88
+ regexp: /"vers":"([^"]+)"/,
89
+ },
90
+ }.freeze
91
+
92
+ Thread.report_on_exception = false
93
+
94
+ # Fetch and compare latest tool/library versions
95
+ class Livecheck
96
+ # Commands
97
+ class Cli
98
+ VERSION_REGEXP = /^([A-Z_]+)_VER *:= *([^$\n]*)$/.freeze
99
+
100
+ def initialize(args)
101
+ @update = args.delete('--update')
102
+ abort '--update is the only supported option' unless args.empty?
103
+ end
104
+
105
+ def run
106
+ dump_changes
107
+
108
+ return unless livechecks.any?(&:changed?)
109
+
110
+ exit 1 unless @update
111
+
112
+ update_changelog
113
+ update_makefile
114
+ rescue StandardError => e
115
+ warn e
116
+ exit 2
117
+ end
118
+
119
+ private
120
+
121
+ def dump_changes
122
+ livechecks.each do |lc|
123
+ next unless lc.changed?
124
+
125
+ puts "#{lc.name_n_latest_version} (current: #{lc.current_version}) #{lc.info_url}"
126
+ end
127
+ end
128
+
129
+ def update_changelog
130
+ changelog = FSPath('CHANGELOG.markdown')
131
+ lines = changelog.readlines
132
+ i = 4
133
+ if lines[i] =~ /^## /
134
+ lines.insert(i, "\n")
135
+ else
136
+ i += 1 while lines[i] =~ /^\* /
137
+ end
138
+ lines.insert(i, changelog_entry)
139
+ write(changelog, lines.join(''))
140
+ end
141
+
142
+ def update_makefile
143
+ content = makefile.read.gsub(VERSION_REGEXP) do
144
+ livecheck = livechecks_by_name[Regexp.last_match[1].downcase]
145
+ "#{livecheck.name.upcase}_VER := #{livecheck.latest_version}"
146
+ end
147
+ write(makefile, content)
148
+ end
149
+
150
+ def makefile
151
+ FSPath('Makefile')
152
+ end
153
+
154
+ def livechecks
155
+ @livechecks ||= makefile.read.scan(VERSION_REGEXP).map do |name, version|
156
+ Livecheck.new(name.downcase, version)
157
+ end
158
+ end
159
+
160
+ def livechecks_by_name
161
+ @livechecks_by_name ||= Hash[livechecks.map{ |lc| [lc.name, lc] }]
162
+ end
163
+
164
+ def changelog_entry
165
+ github_user = `git config github.user`.strip
166
+ changed = livechecks.select(&:changed?)
167
+ "* #{to_sentence(changed.map(&:name_n_latest_version))} [@#{github_user}](https://github.com/#{github_user})\n"
168
+ end
169
+
170
+ def to_sentence(array)
171
+ case array.length
172
+ when 0 then ''
173
+ when 1 then array[0].to_s
174
+ else "#{array[0...-1].join(', ')} and #{array[-1]}"
175
+ end
176
+ end
177
+
178
+ def write(path, data)
179
+ path.temp_file(path.dirname) do |io|
180
+ io.write data
181
+ mode = path.exist? ? path.stat.mode : (~File.umask & 0o777)
182
+ io.path.rename(path)
183
+ path.chmod(mode)
184
+ end
185
+ warn "Wrote #{path}"
186
+ end
187
+ end
188
+
189
+ # Compare versions including libjpeg ones (9b <=> 9)
190
+ class Version
191
+ include Comparable
192
+
193
+ attr_reader :string, :parsed
194
+ alias_method :to_s, :string
195
+
196
+ def initialize(string)
197
+ @string = string
198
+ @parsed = begin
199
+ Gem::Version.new(string)
200
+ rescue ArgumentError
201
+ nil
202
+ end
203
+ end
204
+
205
+ def <=>(other)
206
+ if parsed && other.parsed
207
+ parsed <=> other.parsed
208
+ else
209
+ string <=> other.string
210
+ end
211
+ end
212
+ end
213
+
214
+ attr_reader :name, :current_version
215
+
216
+ def initialize(name, current_version)
217
+ @name = name
218
+ @current_version = Version.new(current_version)
219
+ @fetcher = Thread.new{ fetch_versions.last }
220
+ end
221
+
222
+ def latest_version
223
+ @fetcher.value
224
+ end
225
+
226
+ def changed?
227
+ latest_version != current_version
228
+ end
229
+
230
+ def name_n_latest_version
231
+ "#{name} #{latest_version}"
232
+ end
233
+
234
+ def info_url
235
+ config[:info_url]
236
+ end
237
+
238
+ private
239
+
240
+ def config
241
+ CONFIG[name.to_sym] || fail(ArgumentError, "Livecheck for #{name} not defined")
242
+ end
243
+
244
+ def get(url)
245
+ uri = URI(url)
246
+ http = Net::HTTP.new(uri.host, uri.port)
247
+ http.use_ssl = (uri.scheme == 'https')
248
+ http.request_get(uri.request_uri).body
249
+ end
250
+
251
+ def fetch_versions
252
+ body = get(config[:url])
253
+
254
+ version_regex = config[:regexp]
255
+
256
+ versions = body.scan(version_regex).map{ |match| Version.new(*match) }.sort
257
+ fail "No versions found for #{name} in body:\n#{body}" if versions.empty?
258
+
259
+ versions
260
+ end
261
+ end
262
+
263
+ Livecheck::Cli.new(ARGV).run
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'gems'
5
+ require 'ostruct'
6
+ require 'terminal-table'
7
+
8
+ versions = Gems.versions('image_optim_pack').map do |attributes|
9
+ attributes['number'] = Gem::Version.new(attributes['number'])
10
+ OpenStruct.new(attributes) # rubocop:disable Style/OpenStructUse
11
+ end
12
+
13
+ platforms = versions.map(&:platform).uniq.sort_by do |platform|
14
+ platform.sub('amd64', 'x86_64').split('-').reverse
15
+ end
16
+
17
+ version_time = begin
18
+ time_pairs = versions.group_by(&:number).map do |version_n, platform_versions|
19
+ [version_n, platform_versions.map{ |v| Time.parse(v.created_at) }.min]
20
+ end.sort
21
+ time_pairs << [nil, Time.now]
22
+
23
+ time_pairs.each_cons(2).to_h do |(version_n, created_at), (_, next_created_at)|
24
+ [version_n, next_created_at - created_at]
25
+ end
26
+ end
27
+
28
+ table = Terminal::Table.new
29
+
30
+ table.headings = ['version', 'days', 'base dls'] + platforms.map do |platform|
31
+ platform.split('-').reverse.join("\n")
32
+ end + ['total']
33
+
34
+ versions.group_by(&:number).each do |version_n, platform_versions|
35
+ next if platform_versions.length == 1
36
+
37
+ downloads_by_platform = Hash[platform_versions.map do |version|
38
+ [version.platform, version.downloads_count]
39
+ end]
40
+
41
+ base_downloads = platform_versions.map(&:downloads_count).min
42
+
43
+ platform_values = downloads_by_platform.values_at(*platforms).map do |count|
44
+ next '' unless count
45
+
46
+ count == base_downloads ? '=' : format('%+d', count - base_downloads)
47
+ end
48
+ table.add_row [
49
+ version_n,
50
+ (version_time[version_n] / (24 * 60 * 60)).round,
51
+ base_downloads,
52
+ ] + platform_values + [downloads_by_platform.values.sum]
53
+ end
54
+
55
+ (1...table.number_of_columns).each do |column|
56
+ table.align_column(column, :right)
57
+ end
58
+
59
+ puts table
data/script/run ADDED
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env bash -e
2
+
3
+ # Build tools on Mac OS X host and in all vms
4
+
5
+ MAKE_TASK='all -j'
6
+
7
+ filters=()
8
+ for arg in "$@"; do
9
+ if [[ "$arg" =~ ^([A-Z_]+)=(.*)$ ]]; then
10
+ eval "$(printf %q=%q "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}")"
11
+ else
12
+ filters+=($arg)
13
+ fi
14
+ done
15
+ filters=$(IFS='|'; echo "${filters[*]}")
16
+
17
+ passes-filter() {
18
+ [[ '' = "$filters" ]] || [[ "$1" =~ $filters ]]
19
+ }
20
+
21
+ header() {
22
+ printf '\033[1;7m######## %s ########\033[0m\n' "$1"
23
+ }
24
+
25
+ if [[ $(uname -s) != 'Darwin' ]]; then
26
+ echo 'expected to run on Mac OS X'
27
+ exit 1
28
+ fi
29
+
30
+ make download-dependencies
31
+
32
+ for arch in x86_64 arm64; do
33
+ platform="darwin-$arch"
34
+ passes-filter "$platform" || continue
35
+ header "$platform"
36
+
37
+ build_dir=~_image_optim/pack
38
+
39
+ mkdir -p "vendor/$platform"
40
+
41
+ rsync -aR --del Makefile checksums.mk download patches "$build_dir"
42
+
43
+ sudo -u _image_optim --set-home zsh -exc "
44
+ mkdir -p '$build_dir'
45
+ cd '$build_dir'
46
+
47
+ make $MAKE_TASK ARCH=$arch
48
+ "
49
+
50
+ rsync -aR --del "$build_dir/./vendor/$platform" .
51
+ done
52
+
53
+ if command -v docker &> /dev/null; then
54
+ container_tool="docker"
55
+ elif command -v podman &> /dev/null; then
56
+ container_tool="podman"
57
+ else
58
+ echo "neither docker nor podman found"
59
+ exit 1
60
+ fi
61
+
62
+ container_build() {
63
+ vm=$1
64
+ image=$2
65
+
66
+ passes-filter "$vm" || return 0
67
+ header "$vm"
68
+
69
+ container_name="image_optim_pack-build-$vm"
70
+ workdir=/pack
71
+
72
+ if [[ -z "$NO_UP" ]]; then
73
+ status=$("$container_tool" inspect --format '{{.State.Status}}' "$container_name" 2>/dev/null || true)
74
+
75
+ if [[ "$status" == "" ]]; then
76
+ mount="./_path_:$workdir/_path_"
77
+
78
+ "$container_tool" \
79
+ container create \
80
+ --name="$container_name" \
81
+ --stop-signal SIGHUP \
82
+ -it \
83
+ -v "${mount//_path_/}:ro" \
84
+ -v "${mount//_path_/build/$vm}" \
85
+ -v "${mount//_path_/vendor/$vm}" \
86
+ --workdir "$workdir" \
87
+ "$image"
88
+
89
+ "$container_tool" container start "$container_name"
90
+
91
+ "$container_tool" exec -it "$container_name" bash -exc "
92
+ apt-get update
93
+ apt-get -y install make gcc g++ chrpath perl pkg-config autoconf automake libtool nasm cmake patch
94
+ "
95
+ fi
96
+
97
+ if [[ "$status" = @(created|exited) ]]; then
98
+ "$container_tool" container start "$container_name"
99
+ fi
100
+
101
+ if [[ "$status" = @(created|exited|running) ]]; then
102
+ "$container_tool" exec -it "$container_name" bash -exc "
103
+ UPDATED_FILE=/.updated
104
+ if [ -f \"\$UPDATED_FILE\" ] && [ \"\$(date -r \"\$UPDATED_FILE\" +%F)\" == \"\$(date +%F)\" ]; then
105
+ echo \"Skipping updates\"
106
+ exit 0
107
+ fi
108
+ touch \"\$UPDATED_FILE\"
109
+
110
+ apt-get update
111
+ apt-get -y dist-upgrade
112
+ rustup update
113
+ "
114
+ fi
115
+
116
+ if ! [[ "$status" = @(|created|exited|running) ]]; then
117
+ echo "unexpected status $status"
118
+ exit 1
119
+ fi
120
+ fi
121
+
122
+ "$container_tool" exec -it "$container_name" bash -exc "
123
+ make $MAKE_TASK
124
+ "
125
+
126
+ chmod 755 vendor/$vm/*
127
+
128
+ [[ -n "$NO_HALT" ]] || "$container_tool" container stop "$container_name"
129
+ }
130
+
131
+ container_build linux-x86_64 rust:slim-buster
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'image_optim/pack'
5
+
6
+ describe ImageOptim::Pack do
7
+ before do
8
+ stub_const('Pack', ImageOptim::Pack)
9
+ stub_const('Path', Pack::Path)
10
+ end
11
+
12
+ describe :path do
13
+ it 'returns path' do
14
+ expect(Pack.path).to be
15
+ end
16
+
17
+ it 'returns instance of Path' do
18
+ expect(Pack.path).to be_an(Path)
19
+ end
20
+
21
+ it 'yields debug messages' do
22
+ expect{ |block| Pack.path(&block) }.
23
+ to yield_with_args(/^image_optim_pack: all bins .* worked$/)
24
+ end
25
+ end
26
+
27
+ describe ImageOptim::Pack::Path do
28
+ describe :path do
29
+ it 'returns FSPath with path' do
30
+ expect(Path.new('path').path).to eq(FSPath('path'))
31
+ end
32
+ end
33
+
34
+ describe :to_s do
35
+ it 'returns stringified path' do
36
+ expect(Path.new(Pathname('path')).to_s).to eq('path')
37
+ end
38
+ end
39
+
40
+ describe :os do
41
+ it 'returns last but one part of path' do
42
+ expect(Path.new('path/futureos-K-qbit').os).to eq('futureos')
43
+ end
44
+ end
45
+
46
+ describe :arch do
47
+ it 'returns last but one part of path' do
48
+ expect(Path.new('path/futureos-K-qbit').arch).to eq('K-qbit')
49
+ end
50
+ end
51
+
52
+ describe :bins do
53
+ subject{ Pack.path.bins }
54
+
55
+ define :be_non_libraries do
56
+ match do |bin|
57
+ bin.name !~ /^lib/
58
+ end
59
+ end
60
+
61
+ it{ should be_an(Array) }
62
+
63
+ it{ should_not be_empty }
64
+
65
+ it{ should all(be_an(ImageOptim::BinResolver::Bin)) }
66
+
67
+ it{ should all(have_attributes(version: be)) }
68
+
69
+ it{ should all(be_non_libraries) }
70
+ end
71
+
72
+ describe 'bin helpers' do
73
+ def bins_with_versions(*versions)
74
+ versions.map do |version|
75
+ double(version: version, inspect: version ? 'good' : 'bad')
76
+ end
77
+ end
78
+
79
+ def path_with_bins(*bins)
80
+ path = Path.new('path')
81
+ allow(path).to receive(:bins).and_return(bins)
82
+ path
83
+ end
84
+
85
+ describe 'all good bins' do
86
+ let(:bins){ bins_with_versions('1.3', '6.1.6') }
87
+ subject{ path_with_bins(*bins) }
88
+
89
+ it{ should be_all_bins_working }
90
+ it{ should_not be_all_bins_failing }
91
+ it{ should have_attributes(working_bins: eq(bins)) }
92
+ it{ should have_attributes(failing_bins: be_empty) }
93
+ end
94
+
95
+ describe 'mixed good/bad bins' do
96
+ let(:bins){ bins_with_versions('1.3', nil, '6.1.6', nil) }
97
+ subject{ path_with_bins(*bins) }
98
+
99
+ it{ should_not be_all_bins_working }
100
+ it{ should_not be_all_bins_failing }
101
+ it{ should have_attributes(working_bins: bins.select(&:version)) }
102
+ it{ should have_attributes(failing_bins: bins.reject(&:version)) }
103
+ end
104
+
105
+ describe 'all bad bins' do
106
+ let(:bins){ bins_with_versions(nil, nil) }
107
+ subject{ path_with_bins(*bins) }
108
+
109
+ it{ should_not be_all_bins_working }
110
+ it{ should be_all_bins_failing }
111
+ it{ should have_attributes(working_bins: be_empty) }
112
+ it{ should have_attributes(failing_bins: eq(bins)) }
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'image_optim'
5
+ require 'image_optim/cmd'
6
+ require 'tempfile'
7
+
8
+ describe ImageOptim do
9
+ before do
10
+ stub_const('Cmd', ImageOptim::Cmd)
11
+ end
12
+
13
+ # grab images from image_optim gem
14
+ image_optim_root = Gem.loaded_specs['image_optim'].gem_dir
15
+ images_dir = FSPath.new(image_optim_root) / 'spec/images'
16
+ test_images = images_dir.glob('**/*.*')
17
+
18
+ isolated_options_base = Hash[
19
+ ImageOptim::Worker.klasses.map do |klass|
20
+ [klass.bin_sym, false]
21
+ end
22
+ ].merge(skip_missing_workers: false)
23
+
24
+ ImageOptim::Worker.klasses.each do |worker_klass|
25
+ next if [:pngout, :svgo].include?(worker_klass.bin_sym)
26
+
27
+ describe "#{worker_klass.bin_sym} worker" do
28
+ it 'optimizes at least one test image' do
29
+ options = isolated_options_base.merge(worker_klass.bin_sym => true)
30
+
31
+ image_optim = ImageOptim.new(options)
32
+ if Array(worker_klass.init(image_optim)).empty?
33
+ image_optim = ImageOptim.new(options.merge(allow_lossy: true))
34
+ end
35
+
36
+ expect(test_images.any? do |original|
37
+ image_optim.optimize_image(original)
38
+ end).to be true
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.configure do |c|
4
+ c.before do
5
+ stub_const('ImageOptim::Config::GLOBAL_PATH', File::NULL)
6
+ stub_const('ImageOptim::Config::LOCAL_PATH', File::NULL)
7
+ end
8
+
9
+ c.order = :random
10
+ end
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file