File size: 4,952 Bytes
505d5db | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | import unittest
import cv2
import numpy as np
from PIL import Image
import os
from typing import Dict, Any, Optional, TypedDict, List, Tuple, cast
from src.utils.barcode import Barcode
class BarcodeResult(TypedDict):
type: str
data: str
valid: bool
class TestBarcode(unittest.TestCase):
def setUp(self):
self.barcode = Barcode()
# Create test directory if it doesn't exist
self.test_dir = os.path.dirname(os.path.abspath(__file__))
self.test_images_dir = os.path.join(self.test_dir, 'test_images')
os.makedirs(self.test_images_dir, exist_ok=True)
def test_validate_barcode(self):
"""Test barcode validation for different formats"""
# Test valid EAN-13
self.assertTrue(self.barcode.validate_barcode('5901234123457', 'EAN13'))
# Test invalid EAN-13
self.assertFalse(self.barcode.validate_barcode('5901234123458', 'EAN13'))
# Test valid EAN-8
self.assertTrue(self.barcode.validate_barcode('40170725', 'EAN8'))
# Test invalid EAN-8
self.assertFalse(self.barcode.validate_barcode('40170726', 'EAN8'))
# Test valid UPC-A
self.assertTrue(self.barcode.validate_barcode('042100005264', 'UPCA'))
# Test invalid UPC-A
self.assertFalse(self.barcode.validate_barcode('042100005265', 'UPCA'))
def test_scan_and_validate_from_pil(self):
"""Test barcode scanning from PIL Image"""
# Create a simple test image with a barcode
# This is a placeholder - you should replace with actual barcode images
test_image_path = os.path.join(self.test_images_dir, 'test_barcode.png')
if not os.path.exists(test_image_path):
# Create a blank image if test image doesn't exist
img = Image.new('RGB', (400, 200), color='white')
img.save(test_image_path)
# Load test image
image = Image.open(test_image_path)
# Test scanning
results = self.barcode.scan_and_validate(image)
# Basic structure test
self.assertIsInstance(results, list)
# If a barcode is found, verify the result structure
for result in results:
typed_result = cast(BarcodeResult, result)
self.assertIsInstance(result, dict)
self.assertTrue(all(key in result for key in ['type', 'data', 'valid']))
self.assertIsInstance(typed_result['type'], str)
self.assertIsInstance(typed_result['data'], str)
self.assertIsInstance(typed_result['valid'], bool)
def test_scan_and_validate_from_cv2(self):
"""Test barcode scanning from OpenCV image"""
# Create a test image using OpenCV
test_image_path = os.path.join(self.test_images_dir, 'test_barcode_cv2.png')
if not os.path.exists(test_image_path):
# Create a blank image if test image doesn't exist
img = np.full((200, 400, 3), 255, dtype=np.uint8) # White background
cv2.imwrite(test_image_path, img)
# Load test image
image = cv2.imread(test_image_path)
# Test scanning with show_image=True
scan_result = self.barcode.scan_and_validate(image, show_image=True)
self.assertIsInstance(scan_result, tuple)
results, annotated_image = scan_result
# Verify results
self.assertIsInstance(results, list)
self.assertIsInstance(annotated_image, np.ndarray)
# Check if the annotated image has the same dimensions as input
self.assertEqual(annotated_image.shape, image.shape)
def test_error_handling(self):
"""Test error handling for invalid inputs"""
# Test with None - should raise an exception
with self.assertRaises(Exception):
self.barcode.scan_and_validate(None) # type: ignore
# Test with invalid image type - should raise an exception
with self.assertRaises(Exception):
self.barcode.scan_and_validate("not an image") # type: ignore
# Test empty strings are always invalid
self.assertFalse(self.barcode.validate_barcode("", "EAN13"))
self.assertFalse(self.barcode.validate_barcode("", "UNKNOWN"))
# Test validation with unknown format
# For unknown formats, we validate against known formats first
self.assertFalse(self.barcode.validate_barcode("invalid", "UNKNOWN")) # Invalid data structure
self.assertFalse(self.barcode.validate_barcode("12345678", "UNKNOWN")) # Valid structure but not a valid barcode
self.assertTrue(self.barcode.validate_barcode("5901234123457", "UNKNOWN")) # Valid EAN13 structure
if __name__ == '__main__':
unittest.main() |