image_optim_pack 0.13.0-aarch64-linux-gnu

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.
Files changed (77) 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 +67 -0
  5. data/.github/workflows/check.yml +34 -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 +100 -0
  11. data/CHANGELOG.markdown +623 -0
  12. data/Dockerfile +184 -0
  13. data/Dockerfile.debian +184 -0
  14. data/Gemfile +14 -0
  15. data/LICENSE.txt +27 -0
  16. data/Makefile +573 -0
  17. data/README.markdown +120 -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-aarch64-gnu.gemspec +3 -0
  48. data/image_optim_pack-linux-aarch64-musl.gemspec +3 -0
  49. data/image_optim_pack-linux-x86_64-gnu.gemspec +3 -0
  50. data/image_optim_pack-linux-x86_64-musl.gemspec +3 -0
  51. data/image_optim_pack.gemspec +62 -0
  52. data/lib/image_optim/pack.rb +136 -0
  53. data/lib/image_optim_pack.rb +3 -0
  54. data/patches/pngcrush.patch +15 -0
  55. data/script/extract +19 -0
  56. data/script/livecheck +263 -0
  57. data/script/platform_downloads +59 -0
  58. data/script/run +167 -0
  59. data/spec/image_optim/pack_spec.rb +122 -0
  60. data/spec/image_optim_spec.rb +42 -0
  61. data/spec/spec_helper.rb +10 -0
  62. data/vendor/linux-aarch64-gnu/advpng +0 -0
  63. data/vendor/linux-aarch64-gnu/gifsicle +0 -0
  64. data/vendor/linux-aarch64-gnu/jhead +0 -0
  65. data/vendor/linux-aarch64-gnu/jpeg-recompress +0 -0
  66. data/vendor/linux-aarch64-gnu/jpegoptim +0 -0
  67. data/vendor/linux-aarch64-gnu/jpegtran +0 -0
  68. data/vendor/linux-aarch64-gnu/libjpeg.so +0 -0
  69. data/vendor/linux-aarch64-gnu/liblcms2.so +0 -0
  70. data/vendor/linux-aarch64-gnu/libpng.so +0 -0
  71. data/vendor/linux-aarch64-gnu/libz.so +0 -0
  72. data/vendor/linux-aarch64-gnu/optipng +0 -0
  73. data/vendor/linux-aarch64-gnu/oxipng +0 -0
  74. data/vendor/linux-aarch64-gnu/pngcrush +0 -0
  75. data/vendor/linux-aarch64-gnu/pngout +0 -0
  76. data/vendor/linux-aarch64-gnu/pngquant +0 -0
  77. metadata +202 -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://github.com/Matthias-Wandel/jhead/tags.atom',
23
+ regexp: %r{<id>tag:github.com,2008:Repository/\d+/(\d+(?:\.\d+)*)</id>},
24
+ info_url: 'https://github.com/Matthias-Wandel/jhead',
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
+ liblcms2: {
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/pnggroup/libpng/blob/libpng16/CHANGES#:~:text=Send%20comments/corrections/commendations%20to%20png%2Dmng%2Dimplement%20at%20lists.sf.net.',
55
+ },
56
+ libz: {
57
+ url: 'https://github.com/madler/zlib/releases.atom',
58
+ regexp: %r{<id>tag:github.com,2008:Repository/\d+/v(\d+(?:\.\d+)*)</id>},
59
+ info_url: 'https://www.zlib.net/ChangeLog.txt',
60
+ },
61
+ optipng: {
62
+ url: 'https://optipng.sourceforge.net',
63
+ regexp: %r{/optipng/optipng-(\d+(?:\.\d+)*)\.tar\.gz\?download},
64
+ info_url: 'https://optipng.sourceforge.net/history.txt',
65
+ },
66
+ oxipng: {
67
+ url: 'https://github.com/oxipng/oxipng/releases.atom',
68
+ regexp: %r{<id>tag:github.com,2008:Repository/\d+/v(\d+(?:\.\d+)*)</id>},
69
+ info_url: 'https://github.com/oxipng/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,167 @@
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
+ platform=$3
66
+
67
+ passes-filter "$vm" || return 0
68
+ header "$vm"
69
+
70
+ container_name="image_optim_pack-build-$vm"
71
+ workdir=/pack
72
+
73
+ if [[ -z "$NO_UP" ]]; then
74
+ used_image=$("$container_tool" inspect --format='{{.Config.Image}}' "$container_name" 2>/dev/null || true)
75
+
76
+ if [[ -n "$used_image" && "$used_image" != "$image" ]]; then
77
+ echo "Container is using $used_image instead of $image, recreating"
78
+ "$container_tool" rm --force "$container_name"
79
+ fi
80
+
81
+ used_image_id=$("$container_tool" inspect --format '{{.Image}}' "$container_name" 2>/dev/null || true)
82
+ used_platform=$("$container_tool" inspect --format '{{.Os}}/{{.Architecture}}' "$used_image_id" 2>/dev/null || true)
83
+
84
+ if [[ -n "$used_platform" && "$used_platform" != "$platform" ]]; then
85
+ echo "Container is using image platform $used_platform instead of $platform, recreating"
86
+ "$container_tool" rm --force "$container_name"
87
+ fi
88
+
89
+ status=$("$container_tool" inspect --format '{{.State.Status}}' "$container_name" 2>/dev/null || true)
90
+
91
+ if [[ "$status" == "" ]]; then
92
+ mount="./_path_:$workdir/_path_"
93
+
94
+ "$container_tool" \
95
+ container create \
96
+ --platform "$platform" \
97
+ --name "$container_name" \
98
+ --stop-signal SIGHUP \
99
+ -it \
100
+ -v "${mount//_path_/}:ro" \
101
+ -v "${mount//_path_/build/$vm}" \
102
+ -v "${mount//_path_/vendor/$vm}" \
103
+ --workdir "$workdir" \
104
+ "$image"
105
+
106
+ "$container_tool" container start "$container_name"
107
+
108
+ "$container_tool" exec -it "$container_name" sh -exc "
109
+ if command -v apt-get; then
110
+ apt-get update
111
+ apt-get -y install make gcc g++ chrpath perl pkg-config autoconf automake libtool nasm cmake patch
112
+ elif command -v apk; then
113
+ apk add --no-cache bash make gcc g++ chrpath perl pkgconf autoconf automake libtool nasm cmake patch file
114
+ else
115
+ echo 'unsupported package manager' >&2
116
+ exit 1
117
+ fi
118
+ "
119
+ fi
120
+
121
+ if [[ "$status" = @(created|exited) ]]; then
122
+ "$container_tool" container start "$container_name"
123
+ fi
124
+
125
+ if [[ "$status" = @(created|exited|running) ]]; then
126
+ "$container_tool" exec -it "$container_name" bash -exc "
127
+ UPDATED_FILE=/.updated
128
+ if [ -f \"\$UPDATED_FILE\" ] && [ \"\$(date -r \"\$UPDATED_FILE\" +%F)\" == \"\$(date +%F)\" ]; then
129
+ echo \"Skipping updates\"
130
+ exit 0
131
+ fi
132
+
133
+ if command -v apt-get; then
134
+ apt-get update
135
+ apt-get -y dist-upgrade
136
+ elif command -v apk; then
137
+ apk upgrade --no-cache
138
+ else
139
+ echo 'unsupported package manager' >&2
140
+ exit 1
141
+ fi
142
+
143
+ rustup update
144
+
145
+ touch \"\$UPDATED_FILE\"
146
+ "
147
+ fi
148
+
149
+ if ! [[ "$status" = @(|created|exited|running) ]]; then
150
+ echo "unexpected status $status"
151
+ exit 1
152
+ fi
153
+ fi
154
+
155
+ "$container_tool" exec -it "$container_name" bash -exc "
156
+ make $MAKE_TASK
157
+ "
158
+
159
+ chmod 755 vendor/$vm/*
160
+
161
+ [[ -n "$NO_HALT" ]] || "$container_tool" container stop "$container_name"
162
+ }
163
+
164
+ container_build linux-x86_64-gnu rust:slim-bullseye linux/amd64
165
+ container_build linux-x86_64-musl rust:alpine linux/amd64
166
+ container_build linux-aarch64-gnu rust:slim-bookworm linux/arm64
167
+ container_build linux-aarch64-musl rust:alpine linux/arm64
@@ -0,0 +1,122 @@
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-foo-bar')).to have_attributes(os: '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-foo-bar')).to have_attributes(arch: 'K_qbit')
49
+ end
50
+ end
51
+
52
+ describe :version do
53
+ it 'returns last but one part of path' do
54
+ expect(Path.new('path/futureos-K_qbit-foo-bar')).to have_attributes(version: 'foo-bar')
55
+ end
56
+ end
57
+
58
+ describe :bins do
59
+ subject{ Pack.path.bins }
60
+
61
+ define :be_non_libraries do
62
+ match do |bin|
63
+ bin.name !~ /^lib/
64
+ end
65
+ end
66
+
67
+ it{ should be_an(Array) }
68
+
69
+ it{ should_not be_empty }
70
+
71
+ it{ should all(be_an(ImageOptim::BinResolver::Bin)) }
72
+
73
+ it{ should all(have_attributes(version: be)) }
74
+
75
+ it{ should all(be_non_libraries) }
76
+ end
77
+
78
+ describe 'bin helpers' do
79
+ def bins_with_versions(*versions)
80
+ versions.map do |version|
81
+ double(version: version, inspect: version ? 'good' : 'bad')
82
+ end
83
+ end
84
+
85
+ def path_with_bins(*bins)
86
+ path = Path.new('path')
87
+ allow(path).to receive(:bins).and_return(bins)
88
+ path
89
+ end
90
+
91
+ describe 'all good bins' do
92
+ let(:bins){ bins_with_versions('1.3', '6.1.6') }
93
+ subject{ path_with_bins(*bins) }
94
+
95
+ it{ should be_all_bins_working }
96
+ it{ should_not be_all_bins_failing }
97
+ it{ should have_attributes(working_bins: eq(bins)) }
98
+ it{ should have_attributes(failing_bins: be_empty) }
99
+ end
100
+
101
+ describe 'mixed good/bad bins' do
102
+ let(:bins){ bins_with_versions('1.3', nil, '6.1.6', nil) }
103
+ subject{ path_with_bins(*bins) }
104
+
105
+ it{ should_not be_all_bins_working }
106
+ it{ should_not be_all_bins_failing }
107
+ it{ should have_attributes(working_bins: bins.select(&:version)) }
108
+ it{ should have_attributes(failing_bins: bins.reject(&:version)) }
109
+ end
110
+
111
+ describe 'all bad bins' do
112
+ let(:bins){ bins_with_versions(nil, nil) }
113
+ subject{ path_with_bins(*bins) }
114
+
115
+ it{ should_not be_all_bins_working }
116
+ it{ should be_all_bins_failing }
117
+ it{ should have_attributes(working_bins: be_empty) }
118
+ it{ should have_attributes(failing_bins: eq(bins)) }
119
+ end
120
+ end
121
+ end
122
+ 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