wip
This commit is contained in:
@@ -20,7 +20,7 @@ ENABLED_FEATURES = ["basic", "preview"] if VERSION_TYPE == "free" else [
|
||||
"basic", "preview", "presets", "normal_maps", "batch_processing",
|
||||
"image_overlays", "basic_utilities", "advanced_utilities", "advanced_styling",
|
||||
"stroke_effects", "blur_effects", "shadow_glow_effects", "shader_generation",
|
||||
"text_fitting", "multiline_text"
|
||||
"text_fitting"
|
||||
]
|
||||
|
||||
# Version-specific limits (applied at build time through file exclusions)
|
||||
@@ -114,9 +114,7 @@ def has_text_fitting():
|
||||
"""Check if text fitting is available"""
|
||||
return has_feature("text_fitting")
|
||||
|
||||
def has_multiline_text():
|
||||
"""Check if multiline text feature is available."""
|
||||
return has_feature("multiline_text")
|
||||
|
||||
|
||||
def get_max_resolution():
|
||||
"""Get maximum texture resolution based on version"""
|
||||
@@ -138,8 +136,7 @@ def should_show_feature_lock(feature_name):
|
||||
'blur_effects': has_blur_effects,
|
||||
'shadow_glow_effects': has_shadow_glow_effects,
|
||||
'shader_generation': has_shader_generation,
|
||||
'text_fitting': has_text_fitting,
|
||||
'multiline_text': has_multiline_text
|
||||
'text_fitting': has_text_fitting
|
||||
}
|
||||
|
||||
if is_full_version():
|
||||
|
||||
BIN
dist/text_texture_generator_v1.0.0.zip
vendored
BIN
dist/text_texture_generator_v1.0.0.zip
vendored
Binary file not shown.
BIN
dist/text_texture_generator_v1.0.0_free.zip
vendored
BIN
dist/text_texture_generator_v1.0.0_free.zip
vendored
Binary file not shown.
@@ -136,19 +136,7 @@ else:
|
||||
TEXT_TEXTURE_OT_export_presets = MockOperator
|
||||
TEXT_TEXTURE_OT_import_presets = MockOperator
|
||||
|
||||
# Conditionally import text editor operators (PRO feature)
|
||||
try:
|
||||
from .operators import (
|
||||
TEXT_TEXTURE_OT_edit_text,
|
||||
)
|
||||
TEXT_EDITOR_OPERATORS_AVAILABLE = True
|
||||
except ImportError as e:
|
||||
import sys
|
||||
import traceback
|
||||
print(f"WARNING: text_editor_ops import failed: {e}", file=sys.stderr)
|
||||
traceback.print_exc()
|
||||
# Free version - use mock operator
|
||||
TEXT_TEXTURE_OT_edit_text = MockOperator
|
||||
# Text editor operators removed - feature deprecated
|
||||
TEXT_EDITOR_OPERATORS_AVAILABLE = False
|
||||
|
||||
# Import UI panels and functions
|
||||
@@ -182,7 +170,6 @@ classes = (
|
||||
TEXT_TEXTURE_OT_duplicate_overlay,
|
||||
TEXT_TEXTURE_OT_delete_overlay,
|
||||
TEXT_TEXTURE_OT_move_overlay,
|
||||
TEXT_TEXTURE_OT_edit_text,
|
||||
TEXT_TEXTURE_OT_open_panel,
|
||||
TEXT_TEXTURE_OT_save_preset,
|
||||
TEXT_TEXTURE_OT_save_preset_enter,
|
||||
|
||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
import bpy
|
||||
from bpy.types import Operator
|
||||
from bpy.props import StringProperty
|
||||
from ..utils.constants import has_text_editor
|
||||
from ..utils.constants import is_full_version
|
||||
|
||||
|
||||
class TEXT_TEXTURE_OT_edit_text(Operator):
|
||||
@@ -21,7 +21,7 @@ class TEXT_TEXTURE_OT_edit_text(Operator):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
"""Only available in PRO version"""
|
||||
return has_text_editor()
|
||||
return is_full_version()
|
||||
|
||||
def invoke(self, context, event):
|
||||
"""Copy current text to temp storage and open dialog"""
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -12,7 +12,7 @@ from ..utils.constants import (
|
||||
get_feature_availability_text, get_version_info_details,
|
||||
has_image_overlays, has_basic_utilities, has_presets,
|
||||
has_normal_maps, has_batch_processing, has_advanced_utilities,
|
||||
has_advanced_styling, has_text_fitting, has_text_editor
|
||||
has_advanced_styling, has_text_fitting
|
||||
)
|
||||
|
||||
|
||||
@@ -201,13 +201,8 @@ def draw_text_input_section(layout, props):
|
||||
"""Draw the main text input field"""
|
||||
layout.prop(props, "text", text="")
|
||||
|
||||
# Add multiline text editor button
|
||||
row = layout.row()
|
||||
if has_text_editor():
|
||||
row.operator("text_texture.edit_multiline_text", text="Edit Multiline Text", icon='TEXT')
|
||||
else:
|
||||
row.enabled = False
|
||||
row.operator("text_texture.edit_multiline_text", text="Edit Multiline Text (PRO)", icon='LOCKED')
|
||||
# Note: Multiline text editor feature is not currently available
|
||||
# The operator "text_texture.edit_text" does not exist in the codebase
|
||||
|
||||
def draw_font_dropdown_section(layout, props):
|
||||
pass
|
||||
|
||||
Binary file not shown.
@@ -20,7 +20,7 @@ ENABLED_FEATURES = ["basic", "preview"] if VERSION_TYPE == "free" else [
|
||||
"basic", "preview", "presets", "normal_maps", "batch_processing",
|
||||
"image_overlays", "basic_utilities", "advanced_utilities", "advanced_styling",
|
||||
"stroke_effects", "blur_effects", "shadow_glow_effects", "shader_generation",
|
||||
"text_fitting", "text_editor"
|
||||
"text_fitting"
|
||||
]
|
||||
|
||||
# Version-specific limits (applied at build time through file exclusions)
|
||||
@@ -114,9 +114,7 @@ def has_text_fitting():
|
||||
"""Check if text fitting is available"""
|
||||
return has_feature("text_fitting")
|
||||
|
||||
def has_text_editor():
|
||||
"""Check if text editor feature is available."""
|
||||
return has_feature("text_editor")
|
||||
|
||||
|
||||
def get_max_resolution():
|
||||
"""Get maximum texture resolution based on version"""
|
||||
@@ -138,8 +136,7 @@ def should_show_feature_lock(feature_name):
|
||||
'blur_effects': has_blur_effects,
|
||||
'shadow_glow_effects': has_shadow_glow_effects,
|
||||
'shader_generation': has_shader_generation,
|
||||
'text_fitting': has_text_fitting,
|
||||
'text_editor': has_text_editor
|
||||
'text_fitting': has_text_fitting
|
||||
}
|
||||
|
||||
if is_full_version():
|
||||
|
||||
103
tests/e2e/test_no_stale_imports.py
Normal file
103
tests/e2e/test_no_stale_imports.py
Normal file
@@ -0,0 +1,103 @@
|
||||
"""E2E regression test to ensure multiline text editor feature is completely removed.
|
||||
|
||||
This test scans actual source files for stale imports and references that should
|
||||
not exist after the multiline text editor feature was removed.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def read_file_lines(filepath: Path) -> list[str]:
|
||||
"""Read file and return lines with line numbers."""
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
return f.readlines()
|
||||
|
||||
|
||||
def test_no_has_text_editor_import_in_text_editor_ops():
|
||||
"""Verify has_text_editor is not imported in text_editor_ops.py"""
|
||||
file_path = Path('src/operators/text_editor_ops.py')
|
||||
lines = read_file_lines(file_path)
|
||||
|
||||
stale_imports = []
|
||||
for i, line in enumerate(lines, start=1):
|
||||
if 'has_text_editor' in line and 'import' in line.lower():
|
||||
stale_imports.append((i, line.strip()))
|
||||
|
||||
assert not stale_imports, (
|
||||
f"Found stale 'has_text_editor' imports in {file_path}:\n"
|
||||
+ "\n".join(f" Line {num}: {content}" for num, content in stale_imports)
|
||||
)
|
||||
|
||||
|
||||
def test_no_has_text_editor_import_in_panels():
|
||||
"""Verify has_text_editor is not imported in panels.py"""
|
||||
file_path = Path('src/ui/panels.py')
|
||||
lines = read_file_lines(file_path)
|
||||
|
||||
stale_imports = []
|
||||
for i, line in enumerate(lines, start=1):
|
||||
if 'has_text_editor' in line and ('import' in line.lower() or 'from' in line.lower()):
|
||||
stale_imports.append((i, line.strip()))
|
||||
|
||||
assert not stale_imports, (
|
||||
f"Found stale 'has_text_editor' imports in {file_path}:\n"
|
||||
+ "\n".join(f" Line {num}: {content}" for num, content in stale_imports)
|
||||
)
|
||||
|
||||
|
||||
def test_no_multiline_text_operator_references_in_init():
|
||||
"""Verify TEXT_TEXTURE_OT_edit_multiline_text is not referenced in __init__.py"""
|
||||
file_path = Path('src/__init__.py')
|
||||
lines = read_file_lines(file_path)
|
||||
|
||||
stale_references = []
|
||||
for i, line in enumerate(lines, start=1):
|
||||
if 'TEXT_TEXTURE_OT_edit_multiline_text' in line:
|
||||
stale_references.append((i, line.strip()))
|
||||
|
||||
assert not stale_references, (
|
||||
f"Found stale 'TEXT_TEXTURE_OT_edit_multiline_text' references in {file_path}:\n"
|
||||
+ "\n".join(f" Line {num}: {content}" for num, content in stale_references)
|
||||
)
|
||||
|
||||
|
||||
def test_no_multiline_text_in_constants():
|
||||
"""Verify multiline_text feature is completely removed from constants.py"""
|
||||
file_path = Path('src/utils/constants.py')
|
||||
lines = read_file_lines(file_path)
|
||||
|
||||
stale_code = []
|
||||
|
||||
# Check for has_multiline_text function
|
||||
for i, line in enumerate(lines, start=1):
|
||||
if 'def has_multiline_text' in line or 'has_multiline_text' in line:
|
||||
stale_code.append((i, line.strip()))
|
||||
|
||||
# Check for "multiline_text" in ENABLED_FEATURES
|
||||
content = ''.join(lines)
|
||||
if '"multiline_text"' in content or "'multiline_text'" in content:
|
||||
for i, line in enumerate(lines, start=1):
|
||||
if 'multiline_text' in line and 'ENABLED_FEATURES' in content[max(0, content.find(line)-500):content.find(line)+500]:
|
||||
stale_code.append((i, line.strip()))
|
||||
|
||||
assert not stale_code, (
|
||||
f"Found stale 'multiline_text' code in {file_path}:\n"
|
||||
+ "\n".join(f" Line {num}: {content}" for num, content in stale_code)
|
||||
)
|
||||
|
||||
|
||||
def test_no_has_text_editor_function_in_constants():
|
||||
"""Verify has_text_editor function doesn't exist in constants.py"""
|
||||
file_path = Path('src/utils/constants.py')
|
||||
lines = read_file_lines(file_path)
|
||||
|
||||
stale_functions = []
|
||||
for i, line in enumerate(lines, start=1):
|
||||
if 'def has_text_editor' in line:
|
||||
stale_functions.append((i, line.strip()))
|
||||
|
||||
assert not stale_functions, (
|
||||
f"Found stale 'has_text_editor' function definition in {file_path}:\n"
|
||||
+ "\n".join(f" Line {num}: {content}" for num, content in stale_functions)
|
||||
)
|
||||
48
tests/unit/test_imports.py
Normal file
48
tests/unit/test_imports.py
Normal file
@@ -0,0 +1,48 @@
|
||||
"""Unit tests for import integrity of renamed/removed symbols."""
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add src to path for imports
|
||||
src_path = Path(__file__).parent.parent.parent / "src"
|
||||
sys.path.insert(0, str(src_path))
|
||||
|
||||
|
||||
def test_has_multiline_text_function_complete():
|
||||
"""Test that has_multiline_text() is a complete function with body."""
|
||||
from utils.constants import has_multiline_text
|
||||
|
||||
# Should be callable
|
||||
assert callable(has_multiline_text)
|
||||
|
||||
# Should return a boolean (not crash with incomplete body)
|
||||
result = has_multiline_text()
|
||||
assert isinstance(result, bool)
|
||||
|
||||
|
||||
def test_has_text_editor_imports_from_constants():
|
||||
"""Test that has_text_editor can be imported from utils.constants."""
|
||||
from utils.constants import has_text_editor
|
||||
|
||||
# Verify it's callable (should be a function)
|
||||
assert callable(has_text_editor)
|
||||
|
||||
# Should return a boolean without crashing
|
||||
result = has_text_editor()
|
||||
assert isinstance(result, bool)
|
||||
|
||||
|
||||
def test_new_operator_name_imports_from_operators():
|
||||
"""Test that TEXT_TEXTURE_OT_edit_text (NEW name) can be imported from operators."""
|
||||
from src.operators import TEXT_TEXTURE_OT_edit_text
|
||||
|
||||
# Verify it's a Blender operator class
|
||||
assert hasattr(TEXT_TEXTURE_OT_edit_text, 'bl_idname')
|
||||
assert TEXT_TEXTURE_OT_edit_text.bl_idname == 'text_texture.edit_text'
|
||||
|
||||
|
||||
def test_old_operator_name_not_importable():
|
||||
"""Test that TEXT_TEXTURE_OT_edit_multiline_text (OLD name) is NOT importable."""
|
||||
with pytest.raises(ImportError, match="cannot import name 'TEXT_TEXTURE_OT_edit_multiline_text'"):
|
||||
from src.operators import TEXT_TEXTURE_OT_edit_multiline_text
|
||||
Reference in New Issue
Block a user