test: update + add tests

This commit is contained in:
2024-09-03 00:09:46 +03:00
parent 0a6c5fdc5e
commit d3f88bbfdc
39 changed files with 546 additions and 184 deletions

96
parser_test.go Normal file
View File

@@ -0,0 +1,96 @@
package main
import "testing"
func TestParseDepth(t *testing.T) {
tests := []struct {
line string
indentSize int
expected int
}{
{" node", 4, 1},
{" node", 4, 2},
{"node", 4, 0},
{"\tnode", 0, 1},
}
for _, test := range tests {
result := parseDepth(test.line, test.indentSize)
if result != test.expected {
t.Errorf("parseDepth(%q, %d)\n actual = %d\nwant = %d", test.line, test.indentSize, result, test.expected)
}
}
}
func TestParseInput(t *testing.T) {
input := "root\n child1\n child2\n grandchild1\n"
root := parseInput(input)
if root.name != "." {
t.Errorf("Expected root name to be '.', got %s", root.name)
}
if len(root.children) != 1 {
t.Fatalf("Expected root to have 1 child, got %d", len(root.children))
}
child1 := root.children[0]
if child1.name != "root" {
t.Errorf("Expected child1 name to be 'root', got %s", child1.name)
}
if len(child1.children) != 2 {
t.Fatalf("Expected child1 to have 2 children, got %d", len(child1.children))
}
grandchild1 := child1.children[1].children[0]
if grandchild1.name != "grandchild1" {
t.Errorf("Expected grandchild1 name to be 'grandchild1', got %s", grandchild1.name)
}
}
func TestGetAsciiLine(t *testing.T) {
root := &Node{name: ".", depth: 0, children: []*Node{}, parent: nil}
child := &Node{name: "child", depth: 1, children: []*Node{}, parent: root}
root.children = append(root.children, child)
opts := Options{rootDot: true}
result := getTreeLine(child, &opts)
expected := "└── child"
if result != expected {
t.Errorf("getTreeLine()\n actual = %q\nwant = %q", result, expected)
}
}
func TestGetName(t *testing.T) {
node := &Node{name: "node", depth: 0, children: []*Node{}, parent: nil}
opts := Options{trailingSlash: true}
result := getName(node, &opts)
expected := "node"
if result != expected {
t.Errorf("getName()\n actual = %q\nwant = %q", result, expected)
}
node.children = append(node.children, &Node{name: "child", depth: 1, children: []*Node{}, parent: node})
result = getName(node, &opts)
expected = "node/"
if result != expected {
t.Errorf("getName()\n actual = %q\nwant = %q", result, expected)
}
}
func TestIsLastChild(t *testing.T) {
root := &Node{name: ".", depth: 0, children: []*Node{}, parent: nil}
child1 := &Node{name: "child1", depth: 1, children: []*Node{}, parent: root}
child2 := &Node{name: "child2", depth: 1, children: []*Node{}, parent: root}
root.children = append(root.children, child1, child2)
if isLastChild(child1) {
t.Errorf("Expected child1 to not be the last child")
}
if !isLastChild(child2) {
t.Errorf("Expected child2 to be the last child")
}
}

View File

@@ -0,0 +1,7 @@
.
└── a
├── b
│ └── c
└── d
├── e
└── f

View File

@@ -0,0 +1,7 @@
.
`-- a
|-- b
| `-- c
`-- d
|-- e
`-- f

View File

@@ -0,0 +1,7 @@
.
└── ./a
├── ./a/b
│ └── ./a/b/c
└── ./a/d
├── ./a/d/e
└── ./a/d/f

View File

@@ -0,0 +1,6 @@
a
├── b
│ └── c
└── d
├── e
└── f

View File

@@ -0,0 +1,7 @@
.
└── a/
├── b/
│ └── c
└── d/
├── e
└── f

View File

@@ -0,0 +1,7 @@
.
└── SceneBase (Node2D)
├── GroundLayer (TileMapLayer)
│ ├── Player (CharacterBody2D)
│ └── Enemy (CharacterBody2D)
├── Trees (TileMapLayer)
└── Rocks (TileMapLayer)

View File

@@ -0,0 +1,7 @@
.
`-- SceneBase (Node2D)
|-- GroundLayer (TileMapLayer)
| |-- Player (CharacterBody2D)
| `-- Enemy (CharacterBody2D)
|-- Trees (TileMapLayer)
`-- Rocks (TileMapLayer)

View File

@@ -0,0 +1,7 @@
.
└── ./SceneBase (Node2D)
├── ./SceneBase (Node2D)/GroundLayer (TileMapLayer)
│ ├── ./SceneBase (Node2D)/GroundLayer (TileMapLayer)/Player (CharacterBody2D)
│ └── ./SceneBase (Node2D)/GroundLayer (TileMapLayer)/Enemy (CharacterBody2D)
├── ./SceneBase (Node2D)/Trees (TileMapLayer)
└── ./SceneBase (Node2D)/Rocks (TileMapLayer)

View File

@@ -0,0 +1,6 @@
SceneBase (Node2D)
├── GroundLayer (TileMapLayer)
│ ├── Player (CharacterBody2D)
│ └── Enemy (CharacterBody2D)
├── Trees (TileMapLayer)
└── Rocks (TileMapLayer)

View File

@@ -0,0 +1,7 @@
.
└── SceneBase (Node2D)/
├── GroundLayer (TileMapLayer)/
│ ├── Player (CharacterBody2D)
│ └── Enemy (CharacterBody2D)
├── Trees (TileMapLayer)
└── Rocks (TileMapLayer)

View File

@@ -0,0 +1,8 @@
.
└── .
└── SceneBase (Node2D)
├── GroundLayer (TileMapLayer)
│ ├── Player (CharacterBody2D)
│ └── Enemy (CharacterBody2D)
├── Trees (TileMapLayer)
└── Rocks (TileMapLayer)

View File

@@ -0,0 +1,8 @@
.
`-- .
`-- SceneBase (Node2D)
|-- GroundLayer (TileMapLayer)
| |-- Player (CharacterBody2D)
| `-- Enemy (CharacterBody2D)
|-- Trees (TileMapLayer)
`-- Rocks (TileMapLayer)

View File

@@ -0,0 +1,8 @@
.
└── ./.
└── ././SceneBase (Node2D)
├── ././SceneBase (Node2D)/GroundLayer (TileMapLayer)
│ ├── ././SceneBase (Node2D)/GroundLayer (TileMapLayer)/Player (CharacterBody2D)
│ └── ././SceneBase (Node2D)/GroundLayer (TileMapLayer)/Enemy (CharacterBody2D)
├── ././SceneBase (Node2D)/Trees (TileMapLayer)
└── ././SceneBase (Node2D)/Rocks (TileMapLayer)

View File

@@ -0,0 +1,7 @@
.
└── SceneBase (Node2D)
├── GroundLayer (TileMapLayer)
│ ├── Player (CharacterBody2D)
│ └── Enemy (CharacterBody2D)
├── Trees (TileMapLayer)
└── Rocks (TileMapLayer)

View File

@@ -0,0 +1,8 @@
.
└── ./
└── SceneBase (Node2D)/
├── GroundLayer (TileMapLayer)/
│ ├── Player (CharacterBody2D)
│ └── Enemy (CharacterBody2D)
├── Trees (TileMapLayer)
└── Rocks (TileMapLayer)

View File

@@ -0,0 +1,11 @@
.
└── usr
├── local
├── bin
│ ├── sh
│ ├── bash
│ ├── zsh
│ └── fish
└── sbin
├── sysctl
└── tcpdump

View File

@@ -0,0 +1,11 @@
.
`-- usr
|-- local
|-- bin
| |-- sh
| |-- bash
| |-- zsh
| `-- fish
`-- sbin
|-- sysctl
`-- tcpdump

View File

@@ -0,0 +1,11 @@
.
└── ./usr
├── ./usr/local
├── ./usr/bin
│ ├── ./usr/bin/sh
│ ├── ./usr/bin/bash
│ ├── ./usr/bin/zsh
│ └── ./usr/bin/fish
└── ./usr/sbin
├── ./usr/sbin/sysctl
└── ./usr/sbin/tcpdump

View File

@@ -0,0 +1,10 @@
usr
├── local
├── bin
│ ├── sh
│ ├── bash
│ ├── zsh
│ └── fish
└── sbin
├── sysctl
└── tcpdump

View File

@@ -0,0 +1,11 @@
.
└── usr/
├── local
├── bin/
│ ├── sh
│ ├── bash
│ ├── zsh
│ └── fish
└── sbin/
├── sysctl
└── tcpdump

View File

@@ -0,0 +1,9 @@
.
├── I
│ └── am
│ └── a
│ └── superhero!
├── a
│ └── what?
└── a
└── superhero!

View File

@@ -0,0 +1,9 @@
.
|-- I
| `-- am
| `-- a
| `-- superhero!
|-- a
| `-- what?
`-- a
`-- superhero!

View File

@@ -0,0 +1,9 @@
.
├── ./I
│ └── ./I/am
│ └── ./I/am/a
│ └── ./I/am/a/superhero!
├── ./a
│ └── ./a/what?
└── ./a
└── ./a/superhero!

View File

@@ -0,0 +1,8 @@
I
└── am
└── a
└── superhero!
a
└── what?
a
└── superhero!

View File

@@ -0,0 +1,9 @@
.
├── I/
│ └── am/
│ └── a/
│ └── superhero!
├── a/
│ └── what?
└── a/
└── superhero!

View File

@@ -0,0 +1,9 @@
.
├── I
│ └── am
│ └── a
│ └── superhero!
├── a
│ └── what?
└── a
└── superhero!

View File

@@ -0,0 +1,9 @@
.
|-- I
| `-- am
| `-- a
| `-- superhero!
|-- a
| `-- what?
`-- a
`-- superhero!

View File

@@ -0,0 +1,9 @@
.
├── ./I
│ └── ./I/am
│ └── ./I/am/a
│ └── ./I/am/a/superhero!
├── ./a
│ └── ./a/what?
└── ./a
└── ./a/superhero!

View File

@@ -0,0 +1,8 @@
I
└── am
└── a
└── superhero!
a
└── what?
a
└── superhero!

View File

@@ -0,0 +1,9 @@
.
├── I/
│ └── am/
│ └── a/
│ └── superhero!
├── a/
│ └── what?
└── a/
└── superhero!

View File

@@ -0,0 +1,6 @@
a
b
c
d
e
f

View File

@@ -0,0 +1,6 @@
SceneBase (Node2D)
GroundLayer (TileMapLayer)
Player (CharacterBody2D)
Enemy (CharacterBody2D)
Trees (TileMapLayer)
Rocks (TileMapLayer)

View File

@@ -0,0 +1,7 @@
.
SceneBase (Node2D)
GroundLayer (TileMapLayer)
Player (CharacterBody2D)
Enemy (CharacterBody2D)
Trees (TileMapLayer)
Rocks (TileMapLayer)

11
test_files/src/test_4.txt Normal file
View File

@@ -0,0 +1,11 @@
usr
local
bin
sh
bash
zsh
fish
sbin
sysctl
tcpdump

View File

@@ -0,0 +1,8 @@
I
am
a
superhero!
a
what?
a
superhero!

View File

@@ -0,0 +1,8 @@
I
am
a
superhero!
a
what?
a
superhero!

155
tree_test.go Normal file
View File

@@ -0,0 +1,155 @@
package main
import (
"os"
"strings"
"testing"
)
func TestDescribeTree(t *testing.T) {
input := "root\n child1\n child2\n grandchild1\n"
root := parseInput(input)
opts := Options{rootDot: true}
result := describeTree(root, &opts)
expected := ".\n└── root\n ├── child1\n └── child2\n └── grandchild1"
if result != expected {
t.Errorf("describeTree()\n actual = %q\nwant = %q", result, expected)
}
}
func TestRemovePrefix(t *testing.T) {
opts := Options{false, "", strings.Builder{}, "utf-8", false, false, true}
CHILD, LAST_CHILD, DIRECTORY, EMPTY := getPrefixes(&opts)
tests := []struct {
str string
expected string
}{
{CHILD + "node", "node"},
{LAST_CHILD + "node", "node"},
{DIRECTORY + "node", "node"},
{EMPTY + "node", "node"},
}
for _, test := range tests {
result := removePrefix(test.str, &opts)
if result != test.expected {
t.Errorf("removePrefix(%q)\n actual = %q\nwant = %q", test.str, result, test.expected)
}
}
}
func TestGetPrefixes(t *testing.T) {
tests := []struct {
charset string
expectedChild string
expectedLastChild string
expectedDirectory string
expectedEmpty string
}{
{"utf-8", UTF8_CHILD, UTF8_LAST_CHILD, UTF8_DIRECTORY, UTF8_EMPTY},
{"ascii", ASCII_CHILD, ASCII_LAST_CHILD, ASCII_DIRECTORY, ASCII_EMPTY},
}
for _, test := range tests {
opts := &Options{charset: test.charset}
child, lastChild, directory, empty := getPrefixes(opts)
if child != test.expectedChild {
t.Errorf("For charset %s, expected child prefix %s, but got %s", test.charset, test.expectedChild, child)
}
if lastChild != test.expectedLastChild {
t.Errorf("For charset %s, expected last child prefix %s, but got %s", test.charset, test.expectedLastChild, lastChild)
}
if directory != test.expectedDirectory {
t.Errorf("For charset %s, expected directory prefix %s, but got %s", test.charset, test.expectedDirectory, directory)
}
if empty != test.expectedEmpty {
t.Errorf("For charset %s, expected empty prefix %s, but got %s", test.charset, test.expectedEmpty, empty)
}
}
}
func TestMultiRoot(t *testing.T) {
input := "I\n am\n a\n superhero!\na\n what?\na\n superhero!\n"
root := parseInput(input)
opts := Options{rootDot: true}
result := describeTree(root, &opts)
expected := ".\n├── I\n│ └── am\n│ └── a\n│ └── superhero!\n├── a\n│ └── what?\n└── a\n └── superhero!"
if result != expected {
t.Errorf("describeTree()\n actual = %q\nwant = %q", result, expected)
}
}
func TestWinNewLines(t *testing.T) {
input := "root\r\n child1\r\n child2\r\n grandchild1\r\n"
root := parseInput(input)
opts := Options{rootDot: true}
result := describeTree(root, &opts)
expected := ".\n└── root\n ├── child1\n └── child2\n └── grandchild1"
if result != expected {
t.Errorf("describeTree()\n actual = %q\nwant = %q", result, expected)
}
}
func TestSnapshots(t *testing.T) {
// list all files in test_files/src
// cwd := os.Getenv("PWD")
dirPath := strings.Join([]string{"test_files", "src"}, string(os.PathSeparator))
dir, err := os.Open(dirPath)
if err != nil {
t.Errorf("Error opening directory: %v", err)
}
entries, err := dir.Readdir(-1)
if err != nil {
t.Errorf("Error reading directory: %v", err)
}
defer dir.Close()
for _, entry := range entries {
if entry.IsDir() {
continue
}
t.Logf("Testing %s", entry.Name())
tests := make(map[string]*Options)
// &Options{fromStdin, fromFile, extra, charset, trailingSlash, fullPath, rootDot}
tests[""] = &Options{false, "", strings.Builder{}, "utf-8", false, false, true}
tests["_ascii"] = &Options{false, "", strings.Builder{}, "ascii", false, false, true}
tests["_full_path"] = &Options{false, "", strings.Builder{}, "utf-8", false, true, true}
tests["_no_root"] = &Options{false, "", strings.Builder{}, "utf-8", false, false, false}
tests["_trailing_slash"] = &Options{false, "", strings.Builder{}, "utf-8", true, false, true}
contents, err := os.ReadFile(dirPath + string(os.PathSeparator) + entry.Name())
if err != nil {
t.Errorf("Error reading file: %v", err)
}
for suffix, opts := range tests {
fileName := entry.Name()[:len(entry.Name())-4] + "_snapshot" + suffix + ".txt"
filePath := strings.Join([]string{"test_files", "snapshots", fileName}, string(os.PathSeparator))
t.Logf("Testing snapshot %s", fileName)
want, err := os.ReadFile(filePath)
if err != nil {
t.Errorf("Error reading file: %v", err)
break
}
actual := describeTree(parseInput(string(contents)), opts)
if actual+"\n" != string(want) {
t.Errorf("describeTree()\nactual = %q\nwant = %q\n file %v", actual, want, filePath)
break
}
}
}
}

View File

@@ -1,184 +0,0 @@
package main
import (
"strings"
"testing"
)
func TestParseDepth(t *testing.T) {
tests := []struct {
line string
indentSize int
expected int
}{
{" node", 4, 1},
{" node", 4, 2},
{"node", 4, 0},
{"\tnode", 0, 1},
}
for _, test := range tests {
result := parseDepth(test.line, test.indentSize)
if result != test.expected {
t.Errorf("parseDepth(%q, %d) = %d; want %d", test.line, test.indentSize, result, test.expected)
}
}
}
func TestParseInput(t *testing.T) {
input := "root\n child1\n child2\n grandchild1\n"
root := parseInput(input)
if root.name != "." {
t.Errorf("Expected root name to be '.', got %s", root.name)
}
if len(root.children) != 1 {
t.Fatalf("Expected root to have 1 child, got %d", len(root.children))
}
child1 := root.children[0]
if child1.name != "root" {
t.Errorf("Expected child1 name to be 'root', got %s", child1.name)
}
if len(child1.children) != 2 {
t.Fatalf("Expected child1 to have 2 children, got %d", len(child1.children))
}
grandchild1 := child1.children[1].children[0]
if grandchild1.name != "grandchild1" {
t.Errorf("Expected grandchild1 name to be 'grandchild1', got %s", grandchild1.name)
}
}
func TestDescribeTree(t *testing.T) {
input := "root\n child1\n child2\n grandchild1\n"
root := parseInput(input)
opts := Options{rootDot: true}
result := describeTree(root, &opts)
expected := ".\n└── root\n ├── child1\n └── child2\n └── grandchild1"
if result != expected {
t.Errorf("describeTree() = %q; want %q", result, expected)
}
}
func TestGetAsciiLine(t *testing.T) {
root := &Node{name: ".", depth: 0, children: []*Node{}, parent: nil}
child := &Node{name: "child", depth: 1, children: []*Node{}, parent: root}
root.children = append(root.children, child)
opts := Options{rootDot: true}
result := getTreeLine(child, &opts)
expected := "└── child"
if result != expected {
t.Errorf("getTreeLine() = %q; want %q", result, expected)
}
}
func TestGetName(t *testing.T) {
node := &Node{name: "node", depth: 0, children: []*Node{}, parent: nil}
opts := Options{trailingSlash: true}
result := getName(node, &opts)
expected := "node"
if result != expected {
t.Errorf("getName() = %q; want %q", result, expected)
}
node.children = append(node.children, &Node{name: "child", depth: 1, children: []*Node{}, parent: node})
result = getName(node, &opts)
expected = "node/"
if result != expected {
t.Errorf("getName() = %q; want %q", result, expected)
}
}
func TestIsLastChild(t *testing.T) {
root := &Node{name: ".", depth: 0, children: []*Node{}, parent: nil}
child1 := &Node{name: "child1", depth: 1, children: []*Node{}, parent: root}
child2 := &Node{name: "child2", depth: 1, children: []*Node{}, parent: root}
root.children = append(root.children, child1, child2)
if isLastChild(child1) {
t.Errorf("Expected child1 to not be the last child")
}
if !isLastChild(child2) {
t.Errorf("Expected child2 to be the last child")
}
}
func TestRemovePrefix(t *testing.T) {
opts := Options{false, "", strings.Builder{}, "utf-8", false, false, true}
CHILD, LAST_CHILD, DIRECTORY, EMPTY := getPrefixes(&opts)
tests := []struct {
str string
expected string
}{
{CHILD + "node", "node"},
{LAST_CHILD + "node", "node"},
{DIRECTORY + "node", "node"},
{EMPTY + "node", "node"},
}
for _, test := range tests {
result := removePrefix(test.str, &opts)
if result != test.expected {
t.Errorf("removePrefix(%q) = %q; want %q", test.str, result, test.expected)
}
}
}
func TestGetPrefixes(t *testing.T) {
tests := []struct {
charset string
expectedChild string
expectedLastChild string
expectedDirectory string
expectedEmpty string
}{
{"utf-8", UTF8_CHILD, UTF8_LAST_CHILD, UTF8_DIRECTORY, UTF8_EMPTY},
{"ascii", ASCII_CHILD, ASCII_LAST_CHILD, ASCII_DIRECTORY, ASCII_EMPTY},
}
for _, test := range tests {
opts := &Options{charset: test.charset}
child, lastChild, directory, empty := getPrefixes(opts)
if child != test.expectedChild {
t.Errorf("For charset %s, expected child prefix %s, but got %s", test.charset, test.expectedChild, child)
}
if lastChild != test.expectedLastChild {
t.Errorf("For charset %s, expected last child prefix %s, but got %s", test.charset, test.expectedLastChild, lastChild)
}
if directory != test.expectedDirectory {
t.Errorf("For charset %s, expected directory prefix %s, but got %s", test.charset, test.expectedDirectory, directory)
}
if empty != test.expectedEmpty {
t.Errorf("For charset %s, expected empty prefix %s, but got %s", test.charset, test.expectedEmpty, empty)
}
}
}
func TestMultiRoot(t *testing.T) {
input := "I\n am\n a\n superhero!\na\n what?\na\n superhero!\n"
root := parseInput(input)
opts := Options{rootDot: true}
result := describeTree(root, &opts)
expected := ".\n├── I\n│ └── am\n│ └── a\n│ └── superhero!\n├── a\n│ └── what?\n└── a\n └── superhero!"
if result != expected {
t.Errorf("describeTree() = %q; want %q", result, expected)
}
}
func TestWinNewLines(t *testing.T) {
input := "root\r\n child1\r\n child2\r\n grandchild1\r\n"
root := parseInput(input)
opts := Options{rootDot: true}
result := describeTree(root, &opts)
expected := ".\n└── root\n ├── child1\n └── child2\n └── grandchild1"
if result != expected {
t.Errorf("describeTree() = %q; want %q", result, expected)
}
}