Files
ComfyAssets-ComfyUI_PromptM…/tests/test_hashing.py
T

149 lines
5.1 KiB
Python

"""
Tests for hashing utilities.
Tests generate_content_hash and is_duplicate_prompt which are
currently untested. generate_prompt_hash is covered in test_basic.py
but we add edge cases here.
"""
import os
import sys
import unittest
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from utils.hashing import (
generate_prompt_hash,
generate_content_hash,
is_duplicate_prompt,
)
class TestGenerateContentHash(unittest.TestCase):
"""Test generate_content_hash function."""
def test_basic_content(self):
content = {
"text": "A prompt",
"category": "nature",
"tags": ["sky"],
"workflow_name": "wf1",
}
h = generate_content_hash(content)
self.assertEqual(len(h), 64) # SHA256 hex digest
def test_normalization_case_insensitive(self):
c1 = {"text": "Hello World", "category": "Test"}
c2 = {"text": "hello world", "category": "test"}
self.assertEqual(generate_content_hash(c1), generate_content_hash(c2))
def test_normalization_strips_whitespace(self):
c1 = {"text": " hello ", "category": " test "}
c2 = {"text": "hello", "category": "test"}
self.assertEqual(generate_content_hash(c1), generate_content_hash(c2))
def test_tag_order_independent(self):
c1 = {"text": "prompt", "tags": ["beta", "alpha"]}
c2 = {"text": "prompt", "tags": ["alpha", "beta"]}
self.assertEqual(generate_content_hash(c1), generate_content_hash(c2))
def test_different_text_different_hash(self):
c1 = {"text": "prompt A"}
c2 = {"text": "prompt B"}
self.assertNotEqual(generate_content_hash(c1), generate_content_hash(c2))
def test_different_category_different_hash(self):
c1 = {"text": "same", "category": "cat1"}
c2 = {"text": "same", "category": "cat2"}
self.assertNotEqual(generate_content_hash(c1), generate_content_hash(c2))
def test_different_tags_different_hash(self):
c1 = {"text": "same", "tags": ["tag1"]}
c2 = {"text": "same", "tags": ["tag2"]}
self.assertNotEqual(generate_content_hash(c1), generate_content_hash(c2))
def test_empty_dict(self):
h = generate_content_hash({})
self.assertEqual(len(h), 64)
def test_missing_fields_use_defaults(self):
c1 = {"text": "hello"}
c2 = {"text": "hello", "category": None, "tags": [], "workflow_name": None}
self.assertEqual(generate_content_hash(c1), generate_content_hash(c2))
def test_none_category_same_as_empty(self):
c1 = {"text": "test", "category": None}
c2 = {"text": "test", "category": ""}
self.assertEqual(generate_content_hash(c1), generate_content_hash(c2))
def test_none_workflow_same_as_empty(self):
c1 = {"text": "test", "workflow_name": None}
c2 = {"text": "test", "workflow_name": ""}
self.assertEqual(generate_content_hash(c1), generate_content_hash(c2))
def test_empty_tags_filtered(self):
c1 = {"text": "test", "tags": ["valid", "", " "]}
c2 = {"text": "test", "tags": ["valid"]}
self.assertEqual(generate_content_hash(c1), generate_content_hash(c2))
def test_deterministic(self):
content = {"text": "stable", "tags": ["a", "b"]}
h1 = generate_content_hash(content)
h2 = generate_content_hash(content)
self.assertEqual(h1, h2)
class TestIsDuplicatePrompt(unittest.TestCase):
"""Test is_duplicate_prompt function."""
def test_identical_texts_are_duplicates(self):
self.assertTrue(is_duplicate_prompt("hello", "hello"))
def test_case_insensitive(self):
self.assertTrue(is_duplicate_prompt("Hello World", "hello world"))
def test_whitespace_insensitive(self):
self.assertTrue(is_duplicate_prompt(" hello ", "hello"))
def test_different_texts_not_duplicates(self):
self.assertFalse(is_duplicate_prompt("text A", "text B"))
def test_threshold_parameter_accepted(self):
# threshold is unused but should not cause errors
self.assertTrue(is_duplicate_prompt("same", "same", threshold=0.5))
def test_empty_strings_are_duplicates(self):
self.assertTrue(is_duplicate_prompt("", ""))
def test_unicode_comparison(self):
self.assertTrue(is_duplicate_prompt("日本語", "日本語"))
self.assertFalse(is_duplicate_prompt("日本語", "中文"))
class TestGeneratePromptHashEdgeCases(unittest.TestCase):
"""Additional edge cases for generate_prompt_hash."""
def test_non_string_raises_type_error(self):
with self.assertRaises(TypeError):
generate_prompt_hash(123)
def test_none_raises_type_error(self):
with self.assertRaises(TypeError):
generate_prompt_hash(None)
def test_empty_string(self):
h = generate_prompt_hash("")
self.assertEqual(len(h), 64)
def test_unicode_hash(self):
h = generate_prompt_hash("émojis 🎨 日本語")
self.assertEqual(len(h), 64)
def test_very_long_text(self):
h = generate_prompt_hash("x" * 100000)
self.assertEqual(len(h), 64)
if __name__ == "__main__":
unittest.main()