Remove nose dependence
Also move test images into the base repo because they're not very big anyways
13
.github/workflows/python-package.yml
vendored
@ -81,17 +81,12 @@ jobs:
|
|||||||
run: git clone https://git.pileof.rocks/drewcassidy/quicktex-test-images.git tests/images
|
run: git clone https://git.pileof.rocks/drewcassidy/quicktex-test-images.git tests/images
|
||||||
|
|
||||||
- name: Build wheels
|
- name: Build wheels
|
||||||
uses: joerick/cibuildwheel@v2.3.1
|
uses: pypa/cibuildwheel@v2.3.1
|
||||||
env:
|
env:
|
||||||
MACOSX_DEPLOYMENT_TARGET: "10.15"
|
MACOSX_DEPLOYMENT_TARGET: "10.15"
|
||||||
CIBW_BUILD: "cp{37,38,39,310}-*"
|
# CIBW_ARCHS_MACOS: ${{ matrix.arch }}
|
||||||
CIBW_ARCHS_MACOS: ${{ matrix.arch }}
|
# CIBW_ARCHS_LINUX: ${{ matrix.arch }}
|
||||||
CIBW_ARCHS_LINUX: ${{ matrix.arch }}
|
# CIBW_ARCHS_WINDOWS: "auto64"
|
||||||
CIBW_ARCHS_WINDOWS: "auto64"
|
|
||||||
CIBW_MANYLINUX_X86_64_IMAGE: "manylinux2014"
|
|
||||||
CIBW_MANYLINUX_AARCH64_IMAGE: "manylinux2014"
|
|
||||||
CIBW_TEST_EXTRAS: "tests"
|
|
||||||
CIBW_TEST_COMMAND: nosetests {project}/tests -d
|
|
||||||
CIBW_TEST_SKIP: "*-macosx_arm64"
|
CIBW_TEST_SKIP: "*-macosx_arm64"
|
||||||
|
|
||||||
- name: Upload Wheels
|
- name: Upload Wheels
|
||||||
|
3
.gitignore
vendored
@ -12,9 +12,6 @@ docs/_build/
|
|||||||
#mypy
|
#mypy
|
||||||
out
|
out
|
||||||
|
|
||||||
# Test images
|
|
||||||
tests/images/
|
|
||||||
|
|
||||||
# IDEs
|
# IDEs
|
||||||
**/.idea
|
**/.idea
|
||||||
|
|
||||||
|
4
.gitmodules
vendored
@ -1,4 +0,0 @@
|
|||||||
[submodule "extern/pybind11"]
|
|
||||||
path = extern/pybind11
|
|
||||||
url = https://github.com/pybind/pybind11.git
|
|
||||||
branch = stable
|
|
@ -37,13 +37,13 @@ dependencies = ["Pillow", "click"]
|
|||||||
dynamic = ["version"]
|
dynamic = ["version"]
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
tests = ["nose", "parameterized"]
|
tests = ["parameterized"]
|
||||||
docs = ["sphinx", "myst-parser", "sphinx-rtd-theme"]
|
docs = ["sphinx", "myst-parser", "sphinx-rtd-theme"]
|
||||||
stubs = ["pybind11-stubgen"]
|
stubs = ["pybind11-stubgen"]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
repository = "https://github.com/drewcassidy/quicktex"
|
Source = "https://github.com/drewcassidy/quicktex"
|
||||||
changelog = "https://github.com/drewcassidy/quicktex/blob/main/CHANGELOG.md"
|
Changelog = "https://github.com/drewcassidy/quicktex/blob/main/CHANGELOG.md"
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
quicktex = "quicktex.__main__:main"
|
quicktex = "quicktex.__main__:main"
|
||||||
@ -54,4 +54,11 @@ packages = { find = { include = ["quicktex*"] } } # only include quicktex and no
|
|||||||
package-data = { '*' = ['py.typed', '*.pyi'] } # include stubs
|
package-data = { '*' = ['py.typed', '*.pyi'] } # include stubs
|
||||||
package-dir = { '' = '.' } # without this line, C++ source files get included in the bdist
|
package-dir = { '' = '.' } # without this line, C++ source files get included in the bdist
|
||||||
|
|
||||||
|
[tool.cibuildwheel]
|
||||||
|
build = "cp{37,38,39,310}-*"
|
||||||
|
test-command = "python -m unittest --verbose
|
||||||
|
test-extras = ["tests"]
|
||||||
|
manylinux-x86_64-image = "manylinux2014"
|
||||||
|
manylinux-aarch64-image = "manylinux2014"
|
||||||
|
|
||||||
[tool.setuptools_scm]
|
[tool.setuptools_scm]
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
import os.path
|
import os.path
|
||||||
|
import unittest
|
||||||
|
|
||||||
# Some checks to run before tests can begin
|
|
||||||
images_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'images')
|
images_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'images')
|
||||||
|
|
||||||
assert os.path.isdir(images_path), 'test images repo not present'
|
|
||||||
assert os.path.isfile(os.path.join(images_path, '__init__.py')), 'images __init__.py not present, is the test image repo present?'
|
|
||||||
bp_size = os.path.getsize(os.path.join(images_path, 'Boilerplate.png'))
|
|
||||||
assert bp_size == 955989, 'Boilerplate.png is the wrong size, is the test image repo checked out with LFS enabled?'
|
|
||||||
|
BIN
tests/images/Boilerplate.png
Normal file
After Width: | Height: | Size: 934 KiB |
BIN
tests/images/Bun.afdesign
Normal file
BIN
tests/images/Bun.png
Normal file
After Width: | Height: | Size: 375 KiB |
32
tests/images/__init__.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
from PIL import Image
|
||||||
|
from quicktex.s3tc.bc1 import BC1Block
|
||||||
|
from quicktex.s3tc.bc4 import BC4Block
|
||||||
|
from quicktex import RawTexture
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
image_path = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
class BC1Blocks:
|
||||||
|
class Entry:
|
||||||
|
def __init__(self, filename, block):
|
||||||
|
path = os.path.join(image_path, 'bc1', filename)
|
||||||
|
self.image = Image.open(path).convert('RGBA')
|
||||||
|
self.texture = RawTexture.frombytes(self.image.tobytes('raw', 'RGBA'), *self.image.size)
|
||||||
|
self.block = block
|
||||||
|
|
||||||
|
greyscale = Entry('greyscale_unpacked.png', BC1Block.frombytes(b'\xFF\xFF\x49\x4A\x78\x78\x78\x78'))
|
||||||
|
three_color = Entry('3color_unpacked.png', BC1Block.frombytes(b'\xE0\x07\x00\xF8\x29\x29\x29\x29'))
|
||||||
|
three_color_black = Entry('3color_black_unpacked.png', BC1Block.frombytes(b'\xE0\x07\x00\xF8\x27\x27\x27\x27'))
|
||||||
|
|
||||||
|
|
||||||
|
class BC4Blocks:
|
||||||
|
class Entry:
|
||||||
|
def __init__(self, filename, block):
|
||||||
|
path = os.path.join(image_path, 'bc4', filename)
|
||||||
|
self.image = Image.open(path).convert('RGBA')
|
||||||
|
self.texture = RawTexture.frombytes(self.image.tobytes('raw', 'RGBA'), *self.image.size)
|
||||||
|
self.block = block
|
||||||
|
|
||||||
|
six_value = Entry('6value.png', BC4Block(8, 248, [[0, 1, 2, 3]] * 2 + [[4, 5, 6, 7]] * 2))
|
||||||
|
eight_value = Entry('8value.png', BC4Block(240, 16, [[0, 1, 2, 3]] * 2 + [[4, 5, 6, 7]] * 2))
|
BIN
tests/images/bc1/3color.dds
Normal file
BIN
tests/images/bc1/3color.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
tests/images/bc1/3color_black.dds
Normal file
BIN
tests/images/bc1/3color_black.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
tests/images/bc1/3color_black_unpacked.png
Normal file
After Width: | Height: | Size: 103 B |
BIN
tests/images/bc1/3color_unpacked.png
Normal file
After Width: | Height: | Size: 100 B |
BIN
tests/images/bc1/greyscale.dds
Normal file
BIN
tests/images/bc1/greyscale.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
tests/images/bc1/greyscale_unpacked.png
Normal file
After Width: | Height: | Size: 103 B |
BIN
tests/images/bc4/6value.dds
Normal file
BIN
tests/images/bc4/6value.png
Normal file
After Width: | Height: | Size: 513 B |
BIN
tests/images/bc4/8value.dds
Normal file
BIN
tests/images/bc4/8value.png
Normal file
After Width: | Height: | Size: 509 B |
BIN
tests/images/blocks.afdesign
Normal file
@ -1,5 +1,4 @@
|
|||||||
import unittest
|
import unittest
|
||||||
import nose
|
|
||||||
import os.path
|
import os.path
|
||||||
from parameterized import parameterized, parameterized_class
|
from parameterized import parameterized, parameterized_class
|
||||||
import quicktex
|
import quicktex
|
||||||
@ -108,9 +107,9 @@ class TestBC1Texture(unittest.TestCase):
|
|||||||
self.assertEqual(self.tex[-1, -1], self.tex[self.wb - 1, self.hb - 1], 'incorrect negative subscripting')
|
self.assertEqual(self.tex[-1, -1], self.tex[self.wb - 1, self.hb - 1], 'incorrect negative subscripting')
|
||||||
|
|
||||||
with self.assertRaises(IndexError):
|
with self.assertRaises(IndexError):
|
||||||
thing = self.tex[self.wb, self.hb]
|
_ = self.tex[self.wb, self.hb]
|
||||||
with self.assertRaises(IndexError):
|
with self.assertRaises(IndexError):
|
||||||
thing = self.tex[-1 - self.wb, -1 - self.hb]
|
_ = self.tex[-1 - self.wb, -1 - self.hb]
|
||||||
|
|
||||||
def test_buffer(self):
|
def test_buffer(self):
|
||||||
"""Test the buffer protocol of BC1Texture"""
|
"""Test the buffer protocol of BC1Texture"""
|
||||||
@ -158,7 +157,8 @@ class TestBC1Encoder(unittest.TestCase):
|
|||||||
|
|
||||||
out_block = out_tex[0, 0]
|
out_block = out_tex[0, 0]
|
||||||
|
|
||||||
if self.color_mode != BC1Encoder.ColorMode.FourColor: # we only care about the selectors if we are in 3 color mode
|
if self.color_mode != BC1Encoder.ColorMode.FourColor:
|
||||||
|
# we only care about the selectors if we are in 3 color mode
|
||||||
self.assertTrue(out_block.is_3color, 'returned 4-color block for 3 color test block')
|
self.assertTrue(out_block.is_3color, 'returned 4-color block for 3 color test block')
|
||||||
self.assertEqual(out_block, BC1Blocks.three_color.block, 'encoded block is incorrect')
|
self.assertEqual(out_block, BC1Blocks.three_color.block, 'encoded block is incorrect')
|
||||||
else:
|
else:
|
||||||
@ -173,7 +173,8 @@ class TestBC1Encoder(unittest.TestCase):
|
|||||||
out_block = out_tex[0, 0]
|
out_block = out_tex[0, 0]
|
||||||
has_black = 3 in [j for row in out_block.selectors for j in row]
|
has_black = 3 in [j for row in out_block.selectors for j in row]
|
||||||
|
|
||||||
if self.color_mode == BC1Encoder.ColorMode.ThreeColorBlack: # we only care about the selectors if we are in 3 color black mode
|
if self.color_mode == BC1Encoder.ColorMode.ThreeColorBlack:
|
||||||
|
# we only care about the selectors if we are in 3 color black mode
|
||||||
self.assertTrue(out_block.is_3color, 'returned 4-color block for 3 color test block with black')
|
self.assertTrue(out_block.is_3color, 'returned 4-color block for 3 color test block with black')
|
||||||
self.assertTrue(has_black, 'block does not have black pixels as expected')
|
self.assertTrue(has_black, 'block does not have black pixels as expected')
|
||||||
self.assertEqual(out_block, BC1Blocks.three_color_black.block, "encoded block is incorrect")
|
self.assertEqual(out_block, BC1Blocks.three_color_black.block, "encoded block is incorrect")
|
||||||
@ -207,7 +208,3 @@ class TestBC1Decoder(unittest.TestCase):
|
|||||||
img_diff = ImageChops.difference(out_img, image).convert('L')
|
img_diff = ImageChops.difference(out_img, image).convert('L')
|
||||||
img_hist = img_diff.histogram()
|
img_hist = img_diff.histogram()
|
||||||
self.assertEqual(16, img_hist[0], 'decoded block is incorrect')
|
self.assertEqual(16, img_hist[0], 'decoded block is incorrect')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
nose.main()
|
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
import unittest
|
import unittest
|
||||||
import nose
|
|
||||||
from parameterized import parameterized, parameterized_class
|
from parameterized import parameterized, parameterized_class
|
||||||
from quicktex.s3tc.bc4 import BC4Block, BC4Texture, BC4Encoder, BC4Decoder
|
from quicktex.s3tc.bc4 import BC4Block, BC4Texture, BC4Encoder, BC4Decoder
|
||||||
from tests.images import BC4Blocks
|
from tests.images import BC4Blocks
|
||||||
from PIL import Image, ImageChops
|
from PIL import Image, ImageChops
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
nose.main()
|
|
||||||
|
|
||||||
|
|
||||||
class TestBC4Block(unittest.TestCase):
|
class TestBC4Block(unittest.TestCase):
|
||||||
"""Tests for the BC1Block class"""
|
"""Tests for the BC1Block class"""
|
||||||
@ -119,9 +115,9 @@ class TestBC4Texture(unittest.TestCase):
|
|||||||
self.assertEqual(self.tex[-1, -1], self.tex[self.wb - 1, self.hb - 1], 'incorrect negative subscripting')
|
self.assertEqual(self.tex[-1, -1], self.tex[self.wb - 1, self.hb - 1], 'incorrect negative subscripting')
|
||||||
|
|
||||||
with self.assertRaises(IndexError):
|
with self.assertRaises(IndexError):
|
||||||
thing = self.tex[self.wb, self.hb]
|
_ = self.tex[self.wb, self.hb]
|
||||||
with self.assertRaises(IndexError):
|
with self.assertRaises(IndexError):
|
||||||
thing = self.tex[-1 - self.wb, -1 - self.hb]
|
_ = self.tex[-1 - self.wb, -1 - self.hb]
|
||||||
|
|
||||||
def test_buffer(self):
|
def test_buffer(self):
|
||||||
"""Test the buffer protocol of BC4Texture"""
|
"""Test the buffer protocol of BC4Texture"""
|
||||||
|
@ -3,32 +3,21 @@
|
|||||||
import unittest
|
import unittest
|
||||||
import os.path
|
import os.path
|
||||||
import quicktex
|
import quicktex
|
||||||
import nose
|
|
||||||
|
|
||||||
tests_path = os.path.dirname(os.path.realpath(__file__))
|
tests_path = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
|
||||||
def test_images():
|
class TestInstall(unittest.TestCase):
|
||||||
"""Test for the images submodule"""
|
def test_version(self):
|
||||||
|
"""Test if the extension module version matches what setuptools returns"""
|
||||||
|
try:
|
||||||
|
from importlib import metadata
|
||||||
|
except ImportError:
|
||||||
|
# Python < 3.8, so we cant get the metadata, so just check if it exists
|
||||||
|
assert quicktex.__version__
|
||||||
|
print(f'Cannot check version in python < 3.8. __version__ is {quicktex.__version__}')
|
||||||
|
return
|
||||||
|
|
||||||
images_path = os.path.join(tests_path, 'images')
|
version = metadata.version('quicktex')
|
||||||
|
|
||||||
assert os.path.isdir(images_path), 'test images repo not present. run "git clone https://git.pileof.rocks/drewcassidy/quicktex-test-images.git tests/images" to download them'
|
assert version == quicktex.__version__, 'incorrect version string from extension module'
|
||||||
assert os.path.isfile(os.path.join(images_path, '__init__.py')), 'images __init__.py not present, is the test image repo present?'
|
|
||||||
bp_size = os.path.getsize(os.path.join(images_path, 'Boilerplate.png'))
|
|
||||||
assert bp_size == 955989, 'Boilerplate.png is the wrong size, is the test image repo checked out with LFS enabled?'
|
|
||||||
|
|
||||||
|
|
||||||
def test_version():
|
|
||||||
"""Test if the extension module version matches what setuptools returns"""
|
|
||||||
try:
|
|
||||||
from importlib import metadata
|
|
||||||
except ImportError:
|
|
||||||
# Python < 3.8, so we cant get the metadata, so just check if it exists
|
|
||||||
assert quicktex.__version__
|
|
||||||
print(f'Cannot check version in python < 3.8. __version__ is {quicktex.__version__}')
|
|
||||||
return
|
|
||||||
|
|
||||||
version = metadata.version('quicktex')
|
|
||||||
|
|
||||||
assert version == quicktex.__version__, 'incorrect version string from extension module'
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import unittest
|
import unittest
|
||||||
import nose
|
|
||||||
import os.path
|
import os.path
|
||||||
from tests.images import image_path
|
from tests.images import image_path
|
||||||
from quicktex import RawTexture
|
from quicktex import RawTexture
|
||||||
@ -57,7 +56,3 @@ class TestRawTexture(unittest.TestCase):
|
|||||||
"""Test the frombytes factory function"""
|
"""Test the frombytes factory function"""
|
||||||
bytetex = RawTexture.frombytes(self.boilerplate_bytes, *self.boilerplate.size)
|
bytetex = RawTexture.frombytes(self.boilerplate_bytes, *self.boilerplate.size)
|
||||||
self.assertEqual(self.boilerplate_bytes, bytetex.tobytes(), 'Incorrect bytes after writing to buffer')
|
self.assertEqual(self.boilerplate_bytes, bytetex.tobytes(), 'Incorrect bytes after writing to buffer')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
nose.main()
|
|
||||||
|