1.0.0 Release
This commit is contained in:
42
tests/README.md
Normal file
42
tests/README.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# HereIAm Tests
|
||||
|
||||
This directory contains all test scripts for the HereIAm application.
|
||||
|
||||
## Test Scripts
|
||||
|
||||
### Python Unit Tests
|
||||
- `test_config.py` - Tests configuration management
|
||||
- `test_dialog.py` - Tests options dialog functionality
|
||||
- `test_logging.py` - Tests logging configuration
|
||||
- `test_restart.py` - Tests application restart functionality
|
||||
|
||||
### Shell Scripts
|
||||
- `test_app.sh` - Tests the built macOS application bundle
|
||||
|
||||
## Running Tests
|
||||
|
||||
### Python Tests
|
||||
Run individual test files:
|
||||
```bash
|
||||
cd tests
|
||||
python3 test_config.py
|
||||
python3 test_dialog.py
|
||||
python3 test_logging.py
|
||||
python3 test_restart.py
|
||||
```
|
||||
|
||||
### App Bundle Test
|
||||
Test the built application:
|
||||
```bash
|
||||
cd tests
|
||||
./test_app.sh
|
||||
```
|
||||
|
||||
**Note:** Make sure to build the application first by running `../build_app.sh` from the tests directory.
|
||||
|
||||
## Test Requirements
|
||||
|
||||
- Python 3.x
|
||||
- PyQt5
|
||||
- Built HereIAm.app (for app bundle tests)
|
||||
- macOS (for app bundle tests)
|
||||
138
tests/test_app.sh
Executable file
138
tests/test_app.sh
Executable file
@@ -0,0 +1,138 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Test script for HereIAm.app
|
||||
# Verifies the built application works correctly
|
||||
|
||||
set -e
|
||||
|
||||
echo "🧪 Testing HereIAm.app..."
|
||||
echo "========================="
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
APP_PATH="../dist/HereIAm.app"
|
||||
|
||||
# Check if app exists
|
||||
if [ ! -d "$APP_PATH" ]; then
|
||||
echo -e "${RED}❌ Error: $APP_PATH not found!${NC}"
|
||||
echo "Please run '../build_app.sh' first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}📱 Testing app structure...${NC}"
|
||||
|
||||
# Test executable exists
|
||||
if [ -f "$APP_PATH/Contents/MacOS/HereIAm" ]; then
|
||||
echo -e "${GREEN}✅ Executable found${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Executable missing${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test Info.plist exists
|
||||
if [ -f "$APP_PATH/Contents/Info.plist" ]; then
|
||||
echo -e "${GREEN}✅ Info.plist found${NC}"
|
||||
|
||||
# Check bundle identifier
|
||||
bundle_id=$(plutil -extract CFBundleIdentifier raw "$APP_PATH/Contents/Info.plist" 2>/dev/null || echo "")
|
||||
if [ "$bundle_id" = "net.tekop.hereiam" ]; then
|
||||
echo -e "${GREEN}✅ Bundle identifier correct${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ Bundle identifier: $bundle_id${NC}"
|
||||
fi
|
||||
|
||||
# Check version
|
||||
version=$(plutil -extract CFBundleVersion raw "$APP_PATH/Contents/Info.plist" 2>/dev/null || echo "")
|
||||
echo -e "${BLUE}📋 Version: $version${NC}"
|
||||
|
||||
else
|
||||
echo -e "${RED}❌ Info.plist missing${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test assets are bundled
|
||||
if [ -d "$APP_PATH/Contents/Resources/assets" ]; then
|
||||
echo -e "${GREEN}✅ Assets directory found${NC}"
|
||||
|
||||
# Check for required icons
|
||||
for icon in "Enabled.icns" "Disabled-Light.icns" "Disabled-Dark.icns"; do
|
||||
if [ -f "$APP_PATH/Contents/Resources/assets/$icon" ]; then
|
||||
echo -e "${GREEN}✅ $icon found${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ $icon missing${NC}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo -e "${RED}❌ Assets directory missing${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test code signing (if signed)
|
||||
echo -e "${BLUE}🔍 Checking code signature...${NC}"
|
||||
if codesign -dv "$APP_PATH" 2>/dev/null; then
|
||||
echo -e "${GREEN}✅ App is code signed${NC}"
|
||||
|
||||
# Verify signature
|
||||
if codesign --verify --verbose "$APP_PATH" 2>/dev/null; then
|
||||
echo -e "${GREEN}✅ Signature is valid${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ Signature verification failed${NC}"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ App is not code signed${NC}"
|
||||
echo -e "${YELLOW} (Users may see security warnings)${NC}"
|
||||
fi
|
||||
|
||||
# Test Gatekeeper assessment (if signed)
|
||||
echo -e "${BLUE}🛡️ Checking Gatekeeper assessment...${NC}"
|
||||
if spctl --assess --verbose "$APP_PATH" 2>/dev/null; then
|
||||
echo -e "${GREEN}✅ Gatekeeper will allow this app${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ Gatekeeper may block this app${NC}"
|
||||
echo -e "${YELLOW} (Code signing and notarization recommended for distribution)${NC}"
|
||||
fi
|
||||
|
||||
# Get app size
|
||||
app_size=$(du -sh "$APP_PATH" | cut -f1)
|
||||
echo -e "${BLUE}📦 App bundle size: $app_size${NC}"
|
||||
|
||||
# Basic launch test (background)
|
||||
echo -e "${BLUE}🚀 Testing app launch...${NC}"
|
||||
"$APP_PATH/Contents/MacOS/HereIAm" &
|
||||
APP_PID=$!
|
||||
|
||||
# Wait a moment for launch
|
||||
sleep 3
|
||||
|
||||
# Check if process is running
|
||||
if kill -0 $APP_PID 2>/dev/null; then
|
||||
echo -e "${GREEN}✅ App launched successfully${NC}"
|
||||
|
||||
# Clean shutdown
|
||||
kill $APP_PID 2>/dev/null || true
|
||||
sleep 1
|
||||
|
||||
# Force kill if still running
|
||||
kill -9 $APP_PID 2>/dev/null || true
|
||||
|
||||
echo -e "${GREEN}✅ App shutdown cleanly${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ App failed to launch or crashed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}🎉 All tests passed!${NC}"
|
||||
echo -e "${GREEN}📱 HereIAm.app is ready for distribution${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}📝 Next steps:${NC}"
|
||||
echo "1. Test manually: open $APP_PATH"
|
||||
echo "2. Create DMG: ../create_dmg.sh"
|
||||
echo "3. For distribution: code sign and notarize"
|
||||
echo ""
|
||||
47
tests/test_config.py
Normal file
47
tests/test_config.py
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script to verify the configuration system works correctly
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, '/Users/JeThomas/scripts/HereIAm/src')
|
||||
|
||||
from config_manager import ConfigManager
|
||||
|
||||
def test_config_manager():
|
||||
print("Testing ConfigManager...")
|
||||
|
||||
# Create config manager
|
||||
cm = ConfigManager()
|
||||
|
||||
# Test loading default config
|
||||
config = cm.load_config()
|
||||
print(f"Default config: {config}")
|
||||
|
||||
# Test updating config with new move_px
|
||||
test_config = {
|
||||
'wait_time': 300,
|
||||
'start_enabled': False,
|
||||
'log_level': 'DEBUG',
|
||||
'move_px': 15
|
||||
}
|
||||
|
||||
success = cm.save_config(test_config)
|
||||
print(f"Save config success: {success}")
|
||||
|
||||
# Test loading updated config
|
||||
loaded_config = cm.load_config()
|
||||
print(f"Loaded config: {loaded_config}")
|
||||
|
||||
# Test individual value operations
|
||||
cm.set_config_value('wait_time', 180)
|
||||
cm.set_config_value('move_px', 20)
|
||||
wait_time = cm.get_config_value('wait_time')
|
||||
move_px = cm.get_config_value('move_px')
|
||||
print(f"Individual wait_time: {wait_time}")
|
||||
print(f"Individual move_px: {move_px}")
|
||||
|
||||
print("ConfigManager tests completed!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_config_manager()
|
||||
47
tests/test_dialog.py
Normal file
47
tests/test_dialog.py
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script to verify options dialog works correctly
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, '/Users/JeThomas/scripts/HereIAm/src')
|
||||
|
||||
from PyQt5 import QtWidgets
|
||||
from options_dialog import OptionsDialog
|
||||
|
||||
def test_dialog_multiple_opens():
|
||||
print("Testing multiple dialog opens...")
|
||||
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
|
||||
# Test opening dialog multiple times
|
||||
for i in range(3):
|
||||
print(f"Opening dialog #{i+1}")
|
||||
|
||||
dialog = OptionsDialog(
|
||||
current_wait_time=240 + i*10,
|
||||
current_start_enabled=True,
|
||||
current_log_level="INFO",
|
||||
current_move_px=10 + i
|
||||
)
|
||||
|
||||
# Show dialog briefly (simulate quick open/close)
|
||||
dialog.show()
|
||||
app.processEvents() # Process pending events
|
||||
|
||||
# Get values to ensure dialog is functional
|
||||
values = dialog.get_values()
|
||||
print(f"Dialog #{i+1} values: {values}")
|
||||
|
||||
# Close dialog
|
||||
dialog.close()
|
||||
dialog.deleteLater()
|
||||
app.processEvents() # Process cleanup events
|
||||
|
||||
print(f"Dialog #{i+1} closed successfully")
|
||||
|
||||
print("Multiple dialog test completed successfully!")
|
||||
app.quit()
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_dialog_multiple_opens()
|
||||
42
tests/test_logging.py
Normal file
42
tests/test_logging.py
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script to verify logging is working correctly
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
sys.path.insert(0, '/Users/JeThomas/scripts/HereIAm/src')
|
||||
|
||||
from logging_config import setup_logging, get_logger
|
||||
from config_manager import ConfigManager
|
||||
|
||||
def test_logging():
|
||||
print("Testing logging system...")
|
||||
|
||||
# Test 1: Default logging setup
|
||||
setup_logging()
|
||||
logger = get_logger("test_logger")
|
||||
logger.info("Test message 1 - Default setup")
|
||||
logger.debug("This debug message should NOT appear in default setup")
|
||||
|
||||
# Test 2: Debug mode
|
||||
print("\nSwitching to DEBUG mode...")
|
||||
setup_logging(debug=True, force_reconfigure=True)
|
||||
logger.info("Test message 2 - Debug mode")
|
||||
logger.debug("This debug message SHOULD appear in debug mode")
|
||||
|
||||
# Test 3: Load config and apply logging
|
||||
print("\nTesting with config manager...")
|
||||
cm = ConfigManager()
|
||||
config = cm.load_config()
|
||||
debug_mode = config.get('log_level', 'INFO').upper() == 'DEBUG'
|
||||
setup_logging(debug=debug_mode, force_reconfigure=True)
|
||||
|
||||
logger.info(f"Test message 3 - Config mode (debug={debug_mode})")
|
||||
logger.debug(f"Debug message based on config: log_level={config.get('log_level', 'INFO')}")
|
||||
|
||||
print(f"\nCheck the log file at: ~/logs/hereiam.log")
|
||||
print("Also check console output above for debug messages")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_logging()
|
||||
30
tests/test_restart.py
Normal file
30
tests/test_restart.py
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script to verify restart logic
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
def test_restart_logic():
|
||||
print("Testing restart logic...")
|
||||
|
||||
# Simulate the restart logic
|
||||
script_path = os.path.abspath(__file__)
|
||||
print(f"Current script path: {script_path}")
|
||||
print(f"sys.argv: {sys.argv}")
|
||||
print(f"__name__: {__name__}")
|
||||
print(f"sys.executable: {sys.executable}")
|
||||
print(f"Current working directory: {os.getcwd()}")
|
||||
|
||||
# Show what command would be used for restart
|
||||
if __name__ != "__main__":
|
||||
args = [sys.executable] + sys.argv
|
||||
else:
|
||||
args = [sys.executable, script_path]
|
||||
|
||||
print(f"Restart command would be: {' '.join(args)}")
|
||||
print("Test completed - no actual restart performed")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_restart_logic()
|
||||
Reference in New Issue
Block a user