Skip to content

Commit

Permalink
Add initial unit tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
tjko committed Oct 29, 2023
1 parent fdac587 commit 24b32a6
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 1 deletion.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@ jpegoptim.prn
jpegoptim.ps
jpegoptim.txt
*.o
*.jpg
build/
autom4te.cache/
6 changes: 6 additions & 0 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
STRIP = strip

PYTHON ?= python3

INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
Expand All @@ -58,6 +59,8 @@ DISTNAME = $(PKGNAME)-$(Version)

OBJS = $(PKGNAME).o jpegdest.o jpegsrc.o jpegmarker.o misc.o @GNUGETOPT@

.PHONY: test

all: $(PKGNAME)

dssim.o: dssim.c
Expand Down Expand Up @@ -107,4 +110,7 @@ love:
spell:
codespell -S .git -S tools

test: all
(cd test && $(PYTHON) test.py -v)

# eof
13 changes: 13 additions & 0 deletions test/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Test images for jpegoptim.

Copyright 2023 by Timo Kokkonen.
These images are licensed under CC BY-NC-SA 4.0.

To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/


jpegoptim_test1.jpg: Test image created with Photoshop using generative AI.
jpegoptim_test2.jpg: Test image scaled down and already optimized.



Binary file added test/jpegoptim_test1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/jpegoptim_test2-broken.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/jpegoptim_test2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
105 changes: 105 additions & 0 deletions test/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#!/usr/bin/env python3
#
# test.py -- Unit tests for jpegoptim
#
# Copyright (C) 2023 Timo Kokkonen <tjko@iki.fi>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

"""jpegoptim unit tester"""

import os
import subprocess
import unittest


class JpegoptimTests(unittest.TestCase):
"""jpegoptim test cases"""

program = '../jpegoptim'
debug = False

def run_test(self, args, check=True, directory=None):
"""execute jpegoptim for a test"""
command = [self.program] + args
if directory:
if not os.path.isdir(directory):
os.makedirs(directory)
command.extend(['-o', '-d', directory])
if self.debug:
print(f'\nRun command: {" ".join(command)}')
res = subprocess.run(command, encoding="utf-8", check=check,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = res.stdout
if self.debug:
print(f'Result: {res.returncode}')
print(f'---\n{output}\n---\n')
return output, res.returncode


def test_version(self):
"""test version information output"""
output, _ = self.run_test(['--version'])
self.assertIn('GNU General Public License', output)
self.assertRegex(output, r'jpegoptim v\d+\.\d+\.\d+')

def test_noarguments(self):
"""test running withouth arguments"""
output, res = self.run_test([], check=False)
self.assertEqual(1, res)
self.assertRegex(output, r'file argument\(?s\)? missing')

def test_default(self):
"""test default optimization"""
output, _ = self.run_test(['jpegoptim_test1.jpg'], directory='tmp/default')
self.assertRegex(output, r'\s\[OK\]\s.*\soptimized\.\s*$')
# check that output file is indeed smaller than the input file
self.assertGreater(os.path.getsize('jpegoptim_test1.jpg'),
os.path.getsize('tmp/default/jpegoptim_test1.jpg'))

# check that output file is valid and "optimized"
output, _ = self.run_test(['-n', 'tmp/default/jpegoptim_test1.jpg'])
self.assertRegex(output, r'\s\[OK\]\s.*\sskipped\.\s*$')

def test_lossy(self):
"""test lossy optimization"""
output, _ = self.run_test(['-m', '10', 'jpegoptim_test1.jpg'],
directory='tmp/lossy')
self.assertRegex(output, r'\s\[OK\]\s.*\soptimized\.\s*$')
# check that output file is indeed smaller than the input file
self.assertGreater(os.path.getsize('jpegoptim_test1.jpg'),
os.path.getsize('tmp/lossy/jpegoptim_test1.jpg'))

# check that output file is valid and "optimized"
output, _ = self.run_test(['-n', 'tmp/lossy/jpegoptim_test1.jpg'])
self.assertRegex(output, r'\s\[OK\]\s.*\sskipped\.\s*$')

def test_optimized(self):
"""test already optimized image"""
output, _ = self.run_test(['jpegoptim_test2.jpg'],
directory='tmp/optimized')
self.assertRegex(output, r'\s\[OK\]\s.*\sskipped\.\s*$')

def test_broken(self):
"""test broken image"""
output, _ = self.run_test(['jpegoptim_test2-broken.jpg'],
directory='tmp/broken', check=False)
self.assertRegex(output, r'\s\[WARNING\]\s.*\sskipped\.\s*$')


if __name__ == '__main__':
unittest.main()

# eof :-)

0 comments on commit 24b32a6

Please sign in to comment.