Initial commit: Create comprehensive Git playground

- Multi-language source code (Python, JavaScript, Java, C++, Go)
- Configuration files (JSON, YAML, INI)
- Sample data files (CSV, JSON, logs)
- Binary and media assets (PNG, SVG, PDF)
- Test files and deployment scripts
- Nested directory structure for testing Git features

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Alexander Domene
2025-08-25 20:37:14 +02:00
commit 1f786a83ce
23 changed files with 1004 additions and 0 deletions

81
.gitignore vendored Normal file
View File

@@ -0,0 +1,81 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
.venv/
pip-log.txt
pip-delete-this-directory.txt
.tox/
.coverage
.pytest_cache/
# Node.js
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.npm
.eslintcache
# Java
*.class
*.jar
*.war
*.ear
*.logs
target/
# C/C++
*.o
*.a
*.so
*.exe
# Go
*.exe~
*.dlv
*.test
*.out
go.work
# IDEs
.vscode/
.idea/
*.swp
*.swo
*~
# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Logs
logs/
*.log
# Environment variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# Build directories
build/
dist/
out/
# Temporary files
tmp/
temp/
*.tmp
*.temp

0
CLAUDE.MD Normal file
View File

BIN
README.md Normal file

Binary file not shown.

BIN
assets/binary_data.bin Normal file

Binary file not shown.

36
assets/document.pdf Normal file
View File

@@ -0,0 +1,36 @@
%PDF-1.4
1 0 obj
<< /Type /Catalog /Pages 2 0 R >>
endobj
2 0 obj
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
endobj
3 0 obj
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Resources << /Font << /F1 4 0 R >> >> /Contents 5 0 R >>
endobj
4 0 obj
<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>
endobj
5 0 obj
<< /Length 44 >>
stream
BT
/F1 12 Tf
72 720 Td
(Sample PDF Document) Tj
ET
endstream
endobj
xref
0 6
0000000000 65535 f
0000000009 00000 n
0000000058 00000 n
0000000115 00000 n
0000000251 00000 n
0000000314 00000 n
trailer
<< /Size 6 /Root 1 0 R >>
startxref
408
%%EOF

17
assets/logo.svg Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#FF6B6B;stop-opacity:1" />
<stop offset="100%" style="stop-color:#4ECDC4;stop-opacity:1" />
</linearGradient>
</defs>
<circle cx="50" cy="50" r="45" fill="url(#grad1)" stroke="#333" stroke-width="2"/>
<text x="50" y="55" font-family="Arial, sans-serif" font-size="16" font-weight="bold"
text-anchor="middle" fill="white">LOGO</text>
<path d="M 20 30 L 80 30 L 70 20 L 30 20 Z" fill="rgba(255,255,255,0.3)"/>
<path d="M 20 70 L 80 70 L 70 80 L 30 80 Z" fill="rgba(255,255,255,0.3)"/>
</svg>

After

Width:  |  Height:  |  Size: 773 B

BIN
assets/sample.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 B

19
config.json Normal file
View File

@@ -0,0 +1,19 @@
{
"name": "sandbox-project",
"version": "1.0.0",
"debug": true,
"database": {
"host": "localhost",
"port": 5432,
"name": "sandbox_db"
},
"features": {
"logging": true,
"caching": false,
"analytics": true
},
"api_keys": {
"development": "dev_key_123",
"staging": "staging_key_456"
}
}

40
config/database.yml Normal file
View File

@@ -0,0 +1,40 @@
development:
adapter: postgresql
encoding: unicode
database: sandbox_dev
pool: 5
username: postgres
password: password
host: localhost
port: 5432
test:
adapter: postgresql
encoding: unicode
database: sandbox_test
pool: 5
username: postgres
password: password
host: localhost
port: 5432
staging:
adapter: postgresql
encoding: unicode
database: sandbox_staging
pool: 10
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
host: <%= ENV['DB_HOST'] %>
port: 5432
production:
adapter: postgresql
encoding: unicode
database: sandbox_production
pool: 20
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
host: <%= ENV['DB_HOST'] %>
port: 5432
ssl: true

32
config/settings.ini Normal file
View File

@@ -0,0 +1,32 @@
[DEFAULT]
debug = true
log_level = INFO
max_workers = 4
[database]
host = localhost
port = 5432
name = sandbox_db
timeout = 30
[api]
base_url = https://api.example.com
timeout = 10
retry_count = 3
rate_limit = 100
[cache]
enabled = true
ttl = 3600
max_size = 1000
[logging]
format = %(asctime)s - %(name)s - %(levelname)s - %(message)s
file = logs/application.log
max_file_size = 10MB
backup_count = 5
[features]
feature_a = enabled
feature_b = disabled
feature_c = beta

20
data/logs.txt Normal file
View File

@@ -0,0 +1,20 @@
2023-01-25 10:30:15 INFO Application started successfully
2023-01-25 10:30:16 INFO Database connection established
2023-01-25 10:30:17 INFO Loading configuration from config.json
2023-01-25 10:31:22 DEBUG User authentication request for user_id: 12345
2023-01-25 10:31:23 INFO User 12345 authenticated successfully
2023-01-25 10:32:45 WARN Rate limit approaching for API endpoint /api/users
2023-01-25 10:33:01 ERROR Failed to connect to external service: timeout after 30s
2023-01-25 10:33:02 INFO Retrying connection to external service (attempt 1/3)
2023-01-25 10:33:15 INFO Connection to external service restored
2023-01-25 10:34:28 DEBUG Processing data batch: 500 records
2023-01-25 10:34:35 INFO Data batch processed successfully
2023-01-25 10:35:12 WARN High memory usage detected: 85%
2023-01-25 10:36:45 INFO Garbage collection completed, memory usage: 62%
2023-01-25 10:37:22 DEBUG Cache hit ratio: 92%
2023-01-25 10:38:01 ERROR Database query timeout: SELECT * FROM large_table
2023-01-25 10:38:02 INFO Query optimization applied
2023-01-25 10:38:15 INFO Optimized query completed in 2.3s
2023-01-25 10:39:33 INFO Scheduled task 'data_cleanup' started
2023-01-25 10:40:45 INFO Scheduled task 'data_cleanup' completed
2023-01-25 10:41:00 INFO System health check: All services running normally

61
data/sample_data.json Normal file
View File

@@ -0,0 +1,61 @@
{
"users": [
{
"id": 1,
"name": "John Doe",
"profile": {
"age": 28,
"email": "john@example.com",
"preferences": {
"theme": "dark",
"notifications": true,
"language": "en"
}
},
"posts": [
{
"id": 101,
"title": "Hello World",
"content": "This is my first post!",
"tags": ["intro", "hello"],
"created_at": "2023-01-15T10:30:00Z"
},
{
"id": 102,
"title": "Learning Git",
"content": "Git is a powerful version control system.",
"tags": ["git", "learning", "development"],
"created_at": "2023-01-20T14:45:00Z"
}
]
},
{
"id": 2,
"name": "Jane Smith",
"profile": {
"age": 32,
"email": "jane@example.com",
"preferences": {
"theme": "light",
"notifications": false,
"language": "es"
}
},
"posts": [
{
"id": 103,
"title": "Data Analysis Tips",
"content": "Here are some useful tips for data analysis...",
"tags": ["data", "analysis", "tips"],
"created_at": "2023-01-18T09:15:00Z"
}
]
}
],
"metadata": {
"version": "1.0",
"generated_at": "2023-01-25T12:00:00Z",
"total_users": 2,
"total_posts": 3
}
}

11
data/users.csv Normal file
View File

@@ -0,0 +1,11 @@
id,name,email,age,department,salary,join_date
1,John Doe,john.doe@example.com,28,Engineering,75000,2022-01-15
2,Jane Smith,jane.smith@example.com,32,Marketing,68000,2021-03-20
3,Bob Johnson,bob.johnson@example.com,45,Sales,82000,2020-07-10
4,Alice Brown,alice.brown@example.com,29,Engineering,78000,2022-05-08
5,Charlie Davis,charlie.davis@example.com,35,HR,65000,2021-11-12
6,Eva Wilson,eva.wilson@example.com,27,Design,72000,2022-09-03
7,Frank Miller,frank.miller@example.com,38,Engineering,85000,2020-12-01
8,Grace Lee,grace.lee@example.com,31,Marketing,70000,2021-08-18
9,Henry Taylor,henry.taylor@example.com,26,Sales,62000,2023-02-14
10,Ivy Chen,ivy.chen@example.com,33,Engineering,80000,2021-06-25
1 id name email age department salary join_date
2 1 John Doe john.doe@example.com 28 Engineering 75000 2022-01-15
3 2 Jane Smith jane.smith@example.com 32 Marketing 68000 2021-03-20
4 3 Bob Johnson bob.johnson@example.com 45 Sales 82000 2020-07-10
5 4 Alice Brown alice.brown@example.com 29 Engineering 78000 2022-05-08
6 5 Charlie Davis charlie.davis@example.com 35 HR 65000 2021-11-12
7 6 Eva Wilson eva.wilson@example.com 27 Design 72000 2022-09-03
8 7 Frank Miller frank.miller@example.com 38 Engineering 85000 2020-12-01
9 8 Grace Lee grace.lee@example.com 31 Marketing 70000 2021-08-18
10 9 Henry Taylor henry.taylor@example.com 26 Sales 62000 2023-02-14
11 10 Ivy Chen ivy.chen@example.com 33 Engineering 80000 2021-06-25

29
main.py Normal file
View File

@@ -0,0 +1,29 @@
#!/usr/bin/env python3
"""
Main application entry point for the sandbox project.
"""
import json
import os
from datetime import datetime
def load_config():
"""Load configuration from config.json"""
try:
with open('config.json', 'r') as f:
return json.load(f)
except FileNotFoundError:
return {"debug": True, "version": "1.0.0"}
def main():
"""Main function"""
config = load_config()
print(f"Sandbox Project v{config.get('version', '1.0.0')}")
print(f"Debug mode: {config.get('debug', False)}")
print(f"Current time: {datetime.now()}")
if config.get("debug"):
print("Running in debug mode")
if __name__ == "__main__":
main()

38
package.json Normal file
View File

@@ -0,0 +1,38 @@
{
"name": "sandbox-project",
"version": "1.0.0",
"description": "A Git playground for testing various Git features and workflows",
"main": "main.py",
"scripts": {
"start": "python main.py",
"test": "pytest tests/",
"lint": "eslint src/*.js",
"build": "echo 'Building project...'",
"clean": "rm -rf __pycache__ *.pyc"
},
"keywords": [
"git",
"playground",
"testing",
"sandbox"
],
"author": "Sandbox Team",
"license": "MIT",
"dependencies": {
"lodash": "^4.17.21",
"moment": "^2.29.4"
},
"devDependencies": {
"eslint": "^8.0.0",
"jest": "^29.0.0",
"prettier": "^2.8.0"
},
"repository": {
"type": "git",
"url": "https://github.com/example/sandbox-project.git"
},
"bugs": {
"url": "https://github.com/example/sandbox-project/issues"
},
"homepage": "https://github.com/example/sandbox-project#readme"
}

71
scripts/deploy.sh Executable file
View File

@@ -0,0 +1,71 @@
#!/bin/bash
# Deployment script for sandbox project
set -e # Exit on any error
echo "Starting deployment process..."
# Configuration
ENVIRONMENT=${1:-development}
BUILD_DIR="./build"
BACKUP_DIR="./backups"
echo "Environment: $ENVIRONMENT"
# Create necessary directories
mkdir -p $BUILD_DIR
mkdir -p $BACKUP_DIR
# Backup current deployment
if [ -d "$BUILD_DIR/current" ]; then
echo "Creating backup of current deployment..."
timestamp=$(date +%Y%m%d_%H%M%S)
cp -r $BUILD_DIR/current $BACKUP_DIR/backup_$timestamp
fi
# Build the project
echo "Building project..."
if [ -f "package.json" ]; then
npm install
npm run build
fi
# Run tests
echo "Running tests..."
if [ -f "package.json" ]; then
npm test
fi
if [ -f "requirements.txt" ]; then
pip install -r requirements.txt
pytest tests/ || echo "Python tests not found, skipping..."
fi
# Deploy
echo "Deploying to $ENVIRONMENT..."
case $ENVIRONMENT in
"production")
echo "Production deployment - implementing safety checks..."
# Add production-specific deployment steps
;;
"staging")
echo "Staging deployment..."
# Add staging-specific deployment steps
;;
"development")
echo "Development deployment..."
# Add development-specific deployment steps
;;
*)
echo "Unknown environment: $ENVIRONMENT"
exit 1
;;
esac
# Health check
echo "Performing health check..."
# Add health check logic here
echo "Deployment completed successfully!"
echo "Deployed at: $(date)"

74
src/StringHelper.java Normal file
View File

@@ -0,0 +1,74 @@
package src;
import java.util.*;
import java.util.stream.Collectors;
/**
* String utility class for various string operations
*/
public class StringHelper {
/**
* Reverses a string
*/
public static String reverse(String str) {
if (str == null || str.isEmpty()) {
return str;
}
return new StringBuilder(str).reverse().toString();
}
/**
* Counts word occurrences in a string
*/
public static Map<String, Integer> wordCount(String text) {
if (text == null || text.trim().isEmpty()) {
return new HashMap<>();
}
return Arrays.stream(text.toLowerCase().split("\\s+"))
.filter(word -> !word.isEmpty())
.collect(Collectors.toMap(
word -> word,
word -> 1,
Integer::sum
));
}
/**
* Checks if a string is a palindrome
*/
public static boolean isPalindrome(String str) {
if (str == null) {
return false;
}
String cleaned = str.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
return cleaned.equals(reverse(cleaned));
}
/**
* Capitalizes the first letter of each word
*/
public static String titleCase(String str) {
if (str == null || str.isEmpty()) {
return str;
}
return Arrays.stream(str.split("\\s+"))
.map(word -> word.isEmpty() ? word :
Character.toUpperCase(word.charAt(0)) +
word.substring(1).toLowerCase())
.collect(Collectors.joining(" "));
}
/**
* Main method for testing
*/
public static void main(String[] args) {
System.out.println("Testing StringHelper:");
System.out.println("Reverse 'hello': " + reverse("hello"));
System.out.println("Is 'racecar' palindrome: " + isPalindrome("racecar"));
System.out.println("Title case 'hello world': " + titleCase("hello world"));
}
}

46
src/calculator.js Normal file
View File

@@ -0,0 +1,46 @@
/**
* Simple calculator module for testing JavaScript functionality
*/
class Calculator {
constructor() {
this.history = [];
}
add(a, b) {
const result = a + b;
this.history.push(`${a} + ${b} = ${result}`);
return result;
}
subtract(a, b) {
const result = a - b;
this.history.push(`${a} - ${b} = ${result}`);
return result;
}
multiply(a, b) {
const result = a * b;
this.history.push(`${a} * ${b} = ${result}`);
return result;
}
divide(a, b) {
if (b === 0) {
throw new Error("Division by zero is not allowed");
}
const result = a / b;
this.history.push(`${a} / ${b} = ${result}`);
return result;
}
getHistory() {
return this.history.slice();
}
clearHistory() {
this.history = [];
}
}
module.exports = Calculator;

140
src/data_structures.go Normal file
View File

@@ -0,0 +1,140 @@
package main
import (
"fmt"
"sort"
)
// Stack implementation
type Stack struct {
items []int
}
func (s *Stack) Push(item int) {
s.items = append(s.items, item)
}
func (s *Stack) Pop() (int, bool) {
if len(s.items) == 0 {
return 0, false
}
item := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return item, true
}
func (s *Stack) IsEmpty() bool {
return len(s.items) == 0
}
// Queue implementation
type Queue struct {
items []int
}
func (q *Queue) Enqueue(item int) {
q.items = append(q.items, item)
}
func (q *Queue) Dequeue() (int, bool) {
if len(q.items) == 0 {
return 0, false
}
item := q.items[0]
q.items = q.items[1:]
return item, true
}
func (q *Queue) IsEmpty() bool {
return len(q.items) == 0
}
// Binary search
func binarySearch(arr []int, target int) int {
sort.Ints(arr)
left, right := 0, len(arr)-1
for left <= right {
mid := left + (right-left)/2
if arr[mid] == target {
return mid
} else if arr[mid] < target {
left = mid + 1
} else {
right = mid - 1
}
}
return -1
}
// Merge sort
func mergeSort(arr []int) []int {
if len(arr) <= 1 {
return arr
}
mid := len(arr) / 2
left := mergeSort(arr[:mid])
right := mergeSort(arr[mid:])
return merge(left, right)
}
func merge(left, right []int) []int {
result := make([]int, 0, len(left)+len(right))
i, j := 0, 0
for i < len(left) && j < len(right) {
if left[i] <= right[j] {
result = append(result, left[i])
i++
} else {
result = append(result, right[j])
j++
}
}
result = append(result, left[i:]...)
result = append(result, right[j:]...)
return result
}
func main() {
// Test Stack
stack := &Stack{}
stack.Push(1)
stack.Push(2)
stack.Push(3)
fmt.Println("Stack operations:")
for !stack.IsEmpty() {
if item, ok := stack.Pop(); ok {
fmt.Printf("Popped: %d\n", item)
}
}
// Test Queue
queue := &Queue{}
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
fmt.Println("\nQueue operations:")
for !queue.IsEmpty() {
if item, ok := queue.Dequeue(); ok {
fmt.Printf("Dequeued: %d\n", item)
}
}
// Test binary search and merge sort
arr := []int{64, 34, 25, 12, 22, 11, 90}
fmt.Printf("\nOriginal array: %v\n", arr)
sorted := mergeSort(arr)
fmt.Printf("Sorted array: %v\n", sorted)
target := 25
index := binarySearch(sorted, target)
fmt.Printf("Binary search for %d: index %d\n", target, index)
}

81
src/math_ops.cpp Normal file
View File

@@ -0,0 +1,81 @@
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
/**
* Mathematical operations library
*/
namespace MathOps {
// Calculate factorial
long long factorial(int n) {
if (n <= 1) return 1;
long long result = 1;
for (int i = 2; i <= n; ++i) {
result *= i;
}
return result;
}
// Check if number is prime
bool isPrime(int n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) {
return false;
}
}
return true;
}
// Find GCD using Euclidean algorithm
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
// Calculate mean of vector
double mean(const std::vector<double>& numbers) {
if (numbers.empty()) return 0.0;
double sum = 0.0;
for (double num : numbers) {
sum += num;
}
return sum / numbers.size();
}
// Calculate standard deviation
double standardDeviation(const std::vector<double>& numbers) {
if (numbers.size() <= 1) return 0.0;
double avg = mean(numbers);
double sum_squared_diff = 0.0;
for (double num : numbers) {
sum_squared_diff += (num - avg) * (num - avg);
}
return std::sqrt(sum_squared_diff / (numbers.size() - 1));
}
}
int main() {
std::cout << "Math Operations Demo:" << std::endl;
std::cout << "Factorial of 5: " << MathOps::factorial(5) << std::endl;
std::cout << "Is 17 prime? " << (MathOps::isPrime(17) ? "Yes" : "No") << std::endl;
std::cout << "GCD of 48 and 18: " << MathOps::gcd(48, 18) << std::endl;
std::vector<double> numbers = {1.0, 2.0, 3.0, 4.0, 5.0};
std::cout << "Mean of [1,2,3,4,5]: " << MathOps::mean(numbers) << std::endl;
std::cout << "Std dev of [1,2,3,4,5]: " << MathOps::standardDeviation(numbers) << std::endl;
return 0;
}

54
src/utils.py Normal file
View File

@@ -0,0 +1,54 @@
"""
Utility functions for the sandbox project
"""
import hashlib
import random
import string
from typing import List, Dict, Any
def generate_random_string(length: int = 10) -> str:
"""Generate a random string of specified length"""
letters = string.ascii_lowercase + string.digits
return ''.join(random.choice(letters) for _ in range(length))
def hash_string(text: str, algorithm: str = 'sha256') -> str:
"""Hash a string using the specified algorithm"""
hash_obj = hashlib.new(algorithm)
hash_obj.update(text.encode('utf-8'))
return hash_obj.hexdigest()
def flatten_dict(d: Dict[str, Any], parent_key: str = '', sep: str = '.') -> Dict[str, Any]:
"""Flatten a nested dictionary"""
items = []
for k, v in d.items():
new_key = f"{parent_key}{sep}{k}" if parent_key else k
if isinstance(v, dict):
items.extend(flatten_dict(v, new_key, sep=sep).items())
else:
items.append((new_key, v))
return dict(items)
def chunk_list(lst: List[Any], chunk_size: int) -> List[List[Any]]:
"""Split a list into chunks of specified size"""
return [lst[i:i + chunk_size] for i in range(0, len(lst), chunk_size)]
class DataProcessor:
"""A class for processing various data types"""
def __init__(self):
self.processed_count = 0
def process_numbers(self, numbers: List[float]) -> Dict[str, float]:
"""Process a list of numbers and return statistics"""
if not numbers:
return {}
self.processed_count += 1
return {
'count': len(numbers),
'sum': sum(numbers),
'average': sum(numbers) / len(numbers),
'min': min(numbers),
'max': max(numbers)
}

View File

@@ -0,0 +1,53 @@
const Calculator = require('../../src/calculator');
describe('Calculator', () => {
let calculator;
beforeEach(() => {
calculator = new Calculator();
});
test('should add two numbers correctly', () => {
expect(calculator.add(2, 3)).toBe(5);
expect(calculator.add(-1, 1)).toBe(0);
expect(calculator.add(0, 0)).toBe(0);
});
test('should subtract two numbers correctly', () => {
expect(calculator.subtract(5, 3)).toBe(2);
expect(calculator.subtract(1, 1)).toBe(0);
expect(calculator.subtract(0, 5)).toBe(-5);
});
test('should multiply two numbers correctly', () => {
expect(calculator.multiply(3, 4)).toBe(12);
expect(calculator.multiply(-2, 3)).toBe(-6);
expect(calculator.multiply(0, 5)).toBe(0);
});
test('should divide two numbers correctly', () => {
expect(calculator.divide(10, 2)).toBe(5);
expect(calculator.divide(7, 2)).toBe(3.5);
expect(calculator.divide(-6, 3)).toBe(-2);
});
test('should throw error when dividing by zero', () => {
expect(() => calculator.divide(5, 0)).toThrow('Division by zero is not allowed');
});
test('should maintain calculation history', () => {
calculator.add(2, 3);
calculator.multiply(4, 5);
const history = calculator.getHistory();
expect(history).toHaveLength(2);
expect(history[0]).toBe('2 + 3 = 5');
expect(history[1]).toBe('4 * 5 = 20');
});
test('should clear history', () => {
calculator.add(1, 1);
calculator.clearHistory();
expect(calculator.getHistory()).toHaveLength(0);
});
});

101
tests/unit/test_utils.py Normal file
View File

@@ -0,0 +1,101 @@
import pytest
import sys
import os
# Add src directory to path for imports
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'src'))
from utils import generate_random_string, hash_string, flatten_dict, chunk_list, DataProcessor
class TestUtils:
def test_generate_random_string(self):
# Test default length
result = generate_random_string()
assert len(result) == 10
assert result.isalnum()
# Test custom length
result = generate_random_string(5)
assert len(result) == 5
# Test uniqueness
result1 = generate_random_string(20)
result2 = generate_random_string(20)
assert result1 != result2
def test_hash_string(self):
# Test SHA256 (default)
result = hash_string("hello")
assert len(result) == 64 # SHA256 produces 64 character hex string
# Test MD5
result = hash_string("hello", "md5")
assert len(result) == 32 # MD5 produces 32 character hex string
# Test consistency
result1 = hash_string("test")
result2 = hash_string("test")
assert result1 == result2
def test_flatten_dict(self):
nested = {
"a": 1,
"b": {
"c": 2,
"d": {
"e": 3
}
}
}
expected = {
"a": 1,
"b.c": 2,
"b.d.e": 3
}
result = flatten_dict(nested)
assert result == expected
# Test custom separator
result = flatten_dict(nested, sep="_")
assert "b_c" in result
assert "b_d_e" in result
def test_chunk_list(self):
data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
result = chunk_list(data, 3)
expected = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
assert result == expected
# Test uneven chunks
result = chunk_list(data, 4)
expected = [[1, 2, 3, 4], [5, 6, 7, 8], [9]]
assert result == expected
# Test empty list
result = chunk_list([], 3)
assert result == []
class TestDataProcessor:
def test_process_numbers(self):
processor = DataProcessor()
numbers = [1.0, 2.0, 3.0, 4.0, 5.0]
result = processor.process_numbers(numbers)
assert result['count'] == 5
assert result['sum'] == 15.0
assert result['average'] == 3.0
assert result['min'] == 1.0
assert result['max'] == 5.0
assert processor.processed_count == 1
def test_process_numbers_empty_list(self):
processor = DataProcessor()
result = processor.process_numbers([])
assert result == {}
assert processor.processed_count == 0