mitm/dict_test.go

497 lines
12 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"fmt"
"os"
"testing"
)
// createTestDictFile creates a temporary dict file for testing
func createTestDictFile(t *testing.T, content string) string {
tmpFile, err := os.CreateTemp("", "test_dict_*.txt")
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
_, err = tmpFile.WriteString(content)
if err != nil {
t.Fatalf("Failed to write to temp file: %v", err)
}
tmpFile.Close()
return tmpFile.Name()
}
func TestDictE2E(t *testing.T) {
dict, err := NewChineseDict("dict.txt")
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
for range 1000 {
char := dict.GetRandomCharacter()
fmt.Printf("%c", char)
if char == 0 {
t.Error("GetRandomCharacter returned null rune")
}
}
fmt.Println()
count := dict.GetCharacterCount()
if count == 0 {
t.Error("GetCharacterCount returned 0")
}
count = dict.GetLineCount()
if count == 0 {
t.Error("GetLineCount returned 0")
}
}
func TestDictE2ESingleLineVer(t *testing.T) {
dict, err := NewChineseDict("random_char.txt")
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
for range 1000 {
char := dict.GetRandomCharacter()
fmt.Printf("%c", char)
if char == 0 {
t.Error("GetRandomCharacter returned null rune")
}
}
fmt.Println()
count := dict.GetCharacterCount()
if count == 0 {
t.Error("GetCharacterCount returned 0")
}
count = dict.GetLineCount()
if count == 0 {
t.Error("GetLineCount returned 0")
}
}
func TestNewChineseDict(t *testing.T) {
testContent := `大家好大家好,家人们晚上好
先点点关注不迷路,点个小红心
Hello world test 测试`
tmpFile := createTestDictFile(t, testContent)
defer os.Remove(tmpFile)
dict, err := NewChineseDict(tmpFile)
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
if dict == nil {
t.Fatal("NewChineseDict returned nil dictionary")
}
expectedLines := 3
if len(dict.lines) != expectedLines {
t.Errorf("Expected %d lines, got %d", expectedLines, len(dict.lines))
}
// Check initial state
if dict.currentLineIndex != -1 {
t.Errorf("Expected currentLineIndex to be -1, got %d", dict.currentLineIndex)
}
if dict.currentCharIndex != 0 {
t.Errorf("Expected currentCharIndex to be 0, got %d", dict.currentCharIndex)
}
}
func TestNewChineseDictWithEmptyLines(t *testing.T) {
testContent := `大家好大家好
先点点关注不迷路
Hello world test`
tmpFile := createTestDictFile(t, testContent)
defer os.Remove(tmpFile)
dict, err := NewChineseDict(tmpFile)
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
expectedLines := 3 // Empty lines should be filtered out
if len(dict.lines) != expectedLines {
t.Errorf("Expected %d lines (empty lines filtered), got %d", expectedLines, len(dict.lines))
}
}
func TestNewChineseDictFileNotFound(t *testing.T) {
_, err := NewChineseDict("nonexistent_file.txt")
if err == nil {
t.Error("Expected error for nonexistent file, got nil")
}
}
func TestIsValidCharacter(t *testing.T) {
dict := &ChineseDict{}
testCases := []struct {
char rune
expected bool
desc string
}{
{'大', true, "Chinese character"},
{'家', true, "Chinese character"},
{'好', true, "Chinese character"},
{'a', true, "English lowercase"},
{'Z', true, "English uppercase"},
{'H', true, "English uppercase"},
{',', false, "Comma punctuation"},
{'', false, "Chinese comma"},
{' ', false, "Space"},
{'!', false, "Exclamation mark"},
{'。', false, "Chinese period"},
{'1', false, "Number"},
{'@', false, "Symbol"},
{'\n', false, "Newline"},
}
for _, tc := range testCases {
result := dict.isValidCharacter(tc.char)
if result != tc.expected {
t.Errorf("isValidCharacter('%c') for %s: expected %v, got %v",
tc.char, tc.desc, tc.expected, result)
}
}
}
func TestGetRandomCharacter(t *testing.T) {
testContent := `大家好abc
Hello世界
测试Test`
tmpFile := createTestDictFile(t, testContent)
defer os.Remove(tmpFile)
dict, err := NewChineseDict(tmpFile)
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
// Test getting characters
validChars := make(map[rune]bool)
for i := 0; i < 50; i++ { // Get multiple characters to test randomness
char := dict.GetRandomCharacter()
if char == 0 {
t.Error("GetRandomCharacter returned null rune")
}
if !dict.isValidCharacter(char) {
t.Errorf("GetRandomCharacter returned invalid character: '%c'", char)
}
validChars[char] = true
}
// Should have gotten some variety of characters
if len(validChars) < 5 {
t.Errorf("Expected more variety in characters, got only %d unique chars", len(validChars))
}
}
func TestGetRandomCharacterEmptyDict(t *testing.T) {
dict := &ChineseDict{lines: []string{}}
char := dict.GetRandomCharacter()
if char != 0 {
t.Errorf("Expected null rune for empty dict, got '%c'", char)
}
}
func TestGetRandomCharacterOnlyPunctuation(t *testing.T) {
testContent := `,。!?
@#$%
,,,。。。`
tmpFile := createTestDictFile(t, testContent)
defer os.Remove(tmpFile)
dict, err := NewChineseDict(tmpFile)
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
// This should handle lines with only punctuation gracefully
// The function should try all lines and return null when no valid characters found
char := dict.GetRandomCharacter()
if char != 0 {
t.Errorf("Expected null rune for punctuation-only dict, got '%c'", char)
}
}
func TestGetRandomString(t *testing.T) {
testContent := `大家好abc
Hello世界
测试Test`
tmpFile := createTestDictFile(t, testContent)
defer os.Remove(tmpFile)
dict, err := NewChineseDict(tmpFile)
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
// Test different lengths
testLengths := []int{1, 5, 10, 20}
for _, length := range testLengths {
result := dict.GetRandomString(length)
runes := []rune(result)
if len(runes) != length {
t.Errorf("GetRandomString(%d): expected length %d, got %d",
length, length, len(runes))
}
// Verify all characters are valid
for _, r := range runes {
if !dict.isValidCharacter(r) {
t.Errorf("GetRandomString returned invalid character: '%c'", r)
}
}
}
}
func TestGetRandomStringZeroLength(t *testing.T) {
testContent := `大家好`
tmpFile := createTestDictFile(t, testContent)
defer os.Remove(tmpFile)
dict, err := NewChineseDict(tmpFile)
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
result := dict.GetRandomString(0)
if result != "" {
t.Errorf("Expected empty string for length 0, got '%s'", result)
}
result = dict.GetRandomString(-1)
if result != "" {
t.Errorf("Expected empty string for negative length, got '%s'", result)
}
}
func TestGetRandomStringEmptyDict(t *testing.T) {
dict := &ChineseDict{lines: []string{}}
result := dict.GetRandomString(5)
if result != "" {
t.Errorf("Expected empty string for empty dict, got '%s'", result)
}
}
func TestGetLineCount(t *testing.T) {
testContent := `Line 1
Line 2
Line 3
Line 5`
tmpFile := createTestDictFile(t, testContent)
defer os.Remove(tmpFile)
dict, err := NewChineseDict(tmpFile)
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
expectedCount := 4 // Empty line should be filtered out
count := dict.GetLineCount()
if count != expectedCount {
t.Errorf("Expected line count %d, got %d", expectedCount, count)
}
}
func TestGetCharacterCount(t *testing.T) {
testContent := `大家好abc
Hello世界
测试Test。`
tmpFile := createTestDictFile(t, testContent)
defer os.Remove(tmpFile)
dict, err := NewChineseDict(tmpFile)
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
count := dict.GetCharacterCount()
// Count manually: 大家好abc + Hello世界 + 测试Test = 3+3 + 5+2 + 2+4 = 19 valid chars
expectedCount := 19
if count != expectedCount {
t.Errorf("Expected character count %d, got %d", expectedCount, count)
}
}
func TestSelectNewRandomLine(t *testing.T) {
testContent := `Line 1
Line 2
Line 3`
tmpFile := createTestDictFile(t, testContent)
defer os.Remove(tmpFile)
dict, err := NewChineseDict(tmpFile)
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
// Test multiple selections to ensure randomness
selectedLines := make(map[int]bool)
for i := 0; i < 20; i++ {
dict.selectNewRandomLine()
if dict.currentLineIndex < 0 || dict.currentLineIndex >= len(dict.lines) {
t.Errorf("selectNewRandomLine set invalid index: %d", dict.currentLineIndex)
}
if dict.currentCharIndex != 0 {
t.Errorf("selectNewRandomLine should reset currentCharIndex to 0, got %d", dict.currentCharIndex)
}
selectedLines[dict.currentLineIndex] = true
}
// Should have selected different lines (with high probability)
if len(selectedLines) < 2 {
t.Error("selectNewRandomLine appears to not be random enough")
}
}
func TestCharacterSequencing(t *testing.T) {
// Test that characters are returned in sequence from lines
testContent := `abc
def`
tmpFile := createTestDictFile(t, testContent)
defer os.Remove(tmpFile)
dict, err := NewChineseDict(tmpFile)
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
// Get enough characters to likely exhaust at least one line
chars := make([]rune, 10)
for i := 0; i < 10; i++ {
chars[i] = dict.GetRandomCharacter()
}
// Verify we got valid characters
for i, char := range chars {
if !dict.isValidCharacter(char) {
t.Errorf("Character at position %d is invalid: '%c'", i, char)
}
}
// Should contain characters from our test content
validTestChars := map[rune]bool{'a': true, 'b': true, 'c': true, 'd': true, 'e': true, 'f': true}
for _, char := range chars {
if !validTestChars[char] {
t.Errorf("Got unexpected character: '%c'", char)
}
}
}
func TestMixedLanguageContent(t *testing.T) {
testContent := `Hello世界This is 测试。
English中文Mixed内容with punctuation
Another行with more混合content。`
tmpFile := createTestDictFile(t, testContent)
defer os.Remove(tmpFile)
dict, err := NewChineseDict(tmpFile)
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
// Get many characters and verify they're all valid
chineseCount := 0
englishCount := 0
for i := 0; i < 100; i++ {
char := dict.GetRandomCharacter()
if char == 0 {
t.Error("Got null character")
continue
}
if !dict.isValidCharacter(char) {
t.Errorf("Got invalid character: '%c' (U+%04X)", char, char)
continue
}
if char >= 0x4E00 && char <= 0x9FFF {
chineseCount++
} else if (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') {
englishCount++
}
}
// Should have gotten both Chinese and English characters
if chineseCount == 0 {
t.Error("Expected some Chinese characters, got none")
}
if englishCount == 0 {
t.Error("Expected some English characters, got none")
}
t.Logf("Got %d Chinese and %d English characters", chineseCount, englishCount)
}
func TestSingleLineContent(t *testing.T) {
testContent := `华枝睾吸虫豆卷叶野螟小叶榕木`
//黄眉企鹅五房` for multiline false test
tmpFile := createTestDictFile(t, testContent)
defer os.Remove(tmpFile)
dict, err := NewChineseDict(tmpFile)
if err != nil {
t.Fatalf("NewChineseDict failed: %v", err)
}
runeInPosition := 0
currentPosition := -1
for range 100 {
char := dict.GetRandomCharacter()
if char == 0 {
t.Error("Got null character")
continue
}
if !dict.isValidCharacter(char) {
t.Errorf("Got invalid character: '%c' (U+%04X)", char, char)
continue
}
if char == '华' || char == '黄' {
currentPosition = 0
}
if currentPosition+1 == dict.currentCharIndex {
runeInPosition++
currentPosition++
}
}
if runeInPosition == 100 {
t.Error("GetRandomCharacter is not random enough, always returning characters in sequence")
}
t.Logf("Rune in position: %d", runeInPosition)
}