Add tests and fix validators
This commit is contained in:
1
src/lexer.go
Normal file
1
src/lexer.go
Normal file
@@ -0,0 +1 @@
|
||||
package main
|
||||
1
src/lexer_test.go
Normal file
1
src/lexer_test.go
Normal file
@@ -0,0 +1 @@
|
||||
package main
|
||||
@@ -1,8 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
// "fmt"
|
||||
)
|
||||
type Filter struct {
|
||||
|
||||
}
|
||||
|
||||
func validateBrackets(src string) int {
|
||||
count := 0
|
||||
@@ -55,12 +55,14 @@ func validatePointerBalance(src string) int {
|
||||
for _, c := range src {
|
||||
if c == '[' || c == ']' {
|
||||
break
|
||||
} else if c == '+' {
|
||||
} else if c == '>' {
|
||||
pointer_index++
|
||||
max_index = max(max_index, pointer_index)
|
||||
} else if c == '-' {
|
||||
} else if c == '<' {
|
||||
pointer_index--
|
||||
return -1
|
||||
if pointer_index < 0 {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
}
|
||||
return max_index
|
||||
88
src/linter_test.go
Normal file
88
src/linter_test.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestValidateBrackets(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected int
|
||||
}{
|
||||
{"[][][]", 1},
|
||||
{"[[[]]]", 1},
|
||||
{"[[[][]]]", 1},
|
||||
{"[", 0},
|
||||
{"]", 0},
|
||||
{"][", 0},
|
||||
{"[]", 1},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result := validateBrackets(test.input)
|
||||
if result != test.expected {
|
||||
t.Errorf("validateBrackets(%q) = %v; expected %v", test.input, result, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateOperators(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected int
|
||||
}{
|
||||
{"+-<>-+.,[]", -1},
|
||||
{"+-<>-+.,()", 8},
|
||||
{"hello", 0},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result := validateOperators(test.input)
|
||||
if result != test.expected {
|
||||
t.Errorf("validateOperators(%q) = %v; expected %v", test.input, result, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateLoopDepth(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected int
|
||||
}{
|
||||
{"+++---", 0},
|
||||
{"+++[->+<]", 1},
|
||||
{"[[[", -1},
|
||||
{"[]", 1},
|
||||
{"[[][]]", 2},
|
||||
{"[[[]][]]", 3},
|
||||
{"[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]", 22},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result := validateLoopDepth(test.input)
|
||||
if result != test.expected {
|
||||
t.Errorf("validateLoopDepth(%q) = %v; expected %v", test.input, result, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidatePointerBalance(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected int
|
||||
}{
|
||||
{">>><<<", 3},
|
||||
{"<<<>>>", -1},
|
||||
{">>>>>>", 6},
|
||||
{">>>>[]", 4},
|
||||
{"<<<<[]", -1},
|
||||
{"><><[]", 1},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result := validatePointerBalance(test.input)
|
||||
if result != test.expected {
|
||||
t.Errorf("validatePointerBalance(%q) = %v; expected %v", test.input, result, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
35
src/main.go
35
src/main.go
@@ -31,39 +31,4 @@ func main() {
|
||||
|
||||
save(file, firstArray, secondArray)
|
||||
load(file)
|
||||
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println(validateBrackets("[][][]"))
|
||||
fmt.Println(validateBrackets("[[[]]]"))
|
||||
fmt.Println(validateBrackets("[[[][]]]"))
|
||||
fmt.Println(validateBrackets("["))
|
||||
fmt.Println(validateBrackets("]"))
|
||||
fmt.Println(validateBrackets("]["))
|
||||
fmt.Println(validateBrackets("[]"))
|
||||
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println(validateOperators("+-<>-+.,[]"))
|
||||
fmt.Println(validateOperators("+-<>-+.,()"))
|
||||
fmt.Println(validateOperators("hello"))
|
||||
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println(validateLoopDepth("+++---"))
|
||||
fmt.Println(validateLoopDepth("+++[->+<]"))
|
||||
fmt.Println(validateLoopDepth("[[["))
|
||||
fmt.Println(validateLoopDepth("[]"))
|
||||
fmt.Println(validateLoopDepth("[[][]]"))
|
||||
fmt.Println(validateLoopDepth("[[[]][]]"))
|
||||
fmt.Println(validateLoopDepth("[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]"))
|
||||
|
||||
fmt.Println()
|
||||
|
||||
fmt.Println(validatePointerBalance("+++---"))
|
||||
fmt.Println(validatePointerBalance("---+++"))
|
||||
fmt.Println(validatePointerBalance("++++++"))
|
||||
fmt.Println(validatePointerBalance("++++[]"))
|
||||
fmt.Println(validatePointerBalance("----[]"))
|
||||
fmt.Println(validatePointerBalance("+-+-[]"))
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"encoding/binary"
|
||||
"os"
|
||||
)
|
||||
@@ -56,8 +55,5 @@ func load(filepath string) ([]byte, []byte, error) {
|
||||
}
|
||||
|
||||
data2Array = data2Array[4+data1ArraySize:]
|
||||
fmt.Printf("Размер первого массива: %d\n", data1ArraySize)
|
||||
fmt.Printf("Первый массив: %v\n", data1Array)
|
||||
fmt.Printf("Второй массив: %v\n", data2Array)
|
||||
return data1Array, data2Array, nil
|
||||
}
|
||||
47
src/persistence_test.go
Normal file
47
src/persistence_test.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSaveAndLoad(t *testing.T) {
|
||||
file := "test.bfc"
|
||||
firstArray := []byte{0x01, 0x02, 0x03, 0x04, 0x05}
|
||||
secondArray := []byte{0xAA, 0xBB, 0xCC}
|
||||
|
||||
save(file, firstArray, secondArray)
|
||||
|
||||
if _, err := os.Stat(file); os.IsNotExist(err) {
|
||||
t.Errorf("Файл %s не был создан", file)
|
||||
}
|
||||
|
||||
load(file)
|
||||
|
||||
os.Remove(file)
|
||||
}
|
||||
|
||||
func TestSaveContent(t *testing.T) {
|
||||
file := "test_content.bfc"
|
||||
firstArray := []byte{1, 2, 3}
|
||||
secondArray := []byte{10, 20}
|
||||
|
||||
save(file, firstArray, secondArray)
|
||||
|
||||
data, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
t.Fatalf("Не удалось прочитать файл: %v", err)
|
||||
}
|
||||
|
||||
sizeBytes := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(sizeBytes, uint32(len(firstArray)))
|
||||
expected := append(sizeBytes, firstArray...)
|
||||
expected = append(expected, secondArray...)
|
||||
if !bytes.Equal(data, expected) {
|
||||
t.Errorf("Содержимое файла: %v; ожидалось: %v", data, expected)
|
||||
}
|
||||
|
||||
os.Remove(file)
|
||||
}
|
||||
73
src/settings.go
Normal file
73
src/settings.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Unicode bool `json:"unicode"`
|
||||
MemoryCells int `json:"memory_cells"`
|
||||
LoadDump string `json:"load_dump"`
|
||||
SaveDump string `json:"save_dump"`
|
||||
Sources []string `json:"soгrces"`
|
||||
Compiled string `json:"compiled"`
|
||||
Lint []LintRule `json:"lint"`
|
||||
}
|
||||
|
||||
type LintRule struct {
|
||||
Name string `json:"name"`
|
||||
Level string `json:"level"`
|
||||
Expected string `json:"expected"`
|
||||
}
|
||||
|
||||
func createDefaultConfig() *Config {
|
||||
return &Config{
|
||||
Unicode: false,
|
||||
MemoryCells: 30000,
|
||||
LoadDump: "data_in.bin",
|
||||
SaveDump: "data_out.bin",
|
||||
Sources: []string{"example/default.bf"},
|
||||
Compiled: "bin/default.bfc",
|
||||
Lint: []LintRule{
|
||||
{Name: "brackets", Level: "error", Expected: "=1"},
|
||||
{Name: "operators", Level: "warning", Expected: "=1"},
|
||||
{Name: "loop_depth", Level: "warning", Expected: "<=100"},
|
||||
{Name: "loop_depth", Level: "error", Expected: "<=255"},
|
||||
{Name: "pointer_balance", Level: "error", Expected: "<0"},
|
||||
{Name: "pointer_balance", Level: "warning", Expected: ">30000"},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func saveConfig(filename string, config *Config) error {
|
||||
data, err := json.MarshalIndent(config, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(filename, data, 0644)
|
||||
}
|
||||
|
||||
func loadConfig(filename string) (*Config, error) {
|
||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||
config := createDefaultConfig()
|
||||
err := saveConfig(filename, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return config, errors.New("\"brainfuck.json\" not found. Used default config")
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var config Config
|
||||
err = json.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &config, nil
|
||||
}
|
||||
Reference in New Issue
Block a user