github.com/arr-ai/arrai@v0.319.0/pkg/test/runner_test.go (about) 1 //go:build !windows 2 // +build !windows 3 4 package test 5 6 import ( 7 "bytes" 8 "context" 9 "os" 10 "testing" 11 12 "github.com/stretchr/testify/require" 13 14 "github.com/arr-ai/arrai/pkg/ctxfs" 15 "github.com/arr-ai/arrai/pkg/ctxrootcache" 16 ) 17 18 func TestRunTests_Pass(t *testing.T) { 19 t.Parallel() 20 21 fsContent := map[string]string{"/test/1_test.arrai": "(test1: 1 = 1)"} 22 buf := &bytes.Buffer{} 23 err := RunTests(withFs(t, fsContent), buf, "/test") 24 25 require.NoError(t, err) 26 shouldContain(t, buf.String(), "PASS", "test1") 27 } 28 29 func TestRunTests_EmptyPath(t *testing.T) { 30 t.Parallel() 31 32 fsContent := map[string]string{"/test/1_test.arrai": "(test1: 1 = 1)"} 33 buf := &bytes.Buffer{} 34 err := RunTests(withFs(t, fsContent), buf, "") 35 36 require.NoError(t, err) 37 shouldContain(t, buf.String(), "PASS", "test1") 38 } 39 40 func TestRunTests_Fail(t *testing.T) { 41 t.Parallel() 42 43 fsContent := map[string]string{"/test/1_test.arrai": "(test1: 1 = 1, test2: 2 = 3)"} 44 buf := &bytes.Buffer{} 45 err := RunTests(withFs(t, fsContent), buf, "/test") 46 47 require.Error(t, err) 48 shouldContain(t, buf.String(), "PASS", "test1", "FAIL", "test2") 49 } 50 51 func TestRunTests_Invalid(t *testing.T) { 52 t.Parallel() 53 54 fsContent := map[string]string{"/test/1_test.arrai": "(test1: 1 = 1, test2: 2)"} 55 buf := &bytes.Buffer{} 56 err := RunTests(withFs(t, fsContent), buf, "/test") 57 58 require.Error(t, err) 59 shouldContain(t, buf.String(), "PASS", "test1", "??", "test2") 60 } 61 62 func TestRunTests_BadArrai(t *testing.T) { 63 t.Parallel() 64 65 fsContent := map[string]string{"/test/1_test.arrai": "x"} 66 buf := &bytes.Buffer{} 67 err := RunTests(withFs(t, fsContent), buf, "/test") 68 69 require.Error(t, err) 70 } 71 72 func TestRunTests_InvalidDir(t *testing.T) { 73 t.Parallel() 74 75 fsContent := map[string]string{} 76 buf := &bytes.Buffer{} 77 err := RunTests(withFs(t, fsContent), buf, "/nowhere") 78 79 require.Error(t, err) 80 } 81 82 func TestGetTestFiles_NoFiles(t *testing.T) { 83 t.Parallel() 84 85 fsContent := map[string]string{"/test/placeholder.txt": ""} 86 _, err := getTestFiles(withFs(t, fsContent), "/test") 87 require.Error(t, err) 88 } 89 90 func TestGetTestFiles_InvalidDir(t *testing.T) { 91 t.Parallel() 92 93 fsContent := map[string]string{"/test/placeholder.txt": ""} 94 _, err := getTestFiles(withFs(t, fsContent), "/nowhere") 95 require.Error(t, err) 96 } 97 98 func TestGetTestFiles_OneFile(t *testing.T) { 99 t.Parallel() 100 101 fsContent := map[string]string{"/test/1_test.arrai": "source1"} 102 files, err := getTestFiles(withFs(t, fsContent), "/test") 103 require.NoError(t, err) 104 require.Equal(t, []File{{Path: "/test/1_test.arrai", Source: "source1"}}, files) 105 } 106 107 func TestGetTestFiles_PathIsFile(t *testing.T) { 108 t.Parallel() 109 110 fsContent := map[string]string{ 111 "/test/1_test.arrai": "source1", 112 "/test/2_test.arrai": "source2", 113 } 114 files, err := getTestFiles(withFs(t, fsContent), "/test/1_test.arrai") 115 require.NoError(t, err) 116 require.Equal(t, []File{{Path: "/test/1_test.arrai", Source: "source1"}}, files) 117 } 118 119 func TestGetTestFiles_NestedDir(t *testing.T) { 120 t.Parallel() 121 122 fsContent := map[string]string{ 123 "/test/1_test.arrai": "source1", 124 "/test/must/go/deeper/2_test.arrai": "source2", 125 } 126 files, err := getTestFiles(withFs(t, fsContent), "/test") 127 require.NoError(t, err) 128 require.Equal(t, []File{ 129 {Path: "/test/1_test.arrai", Source: "source1"}, 130 {Path: "/test/must/go/deeper/2_test.arrai", Source: "source2"}, 131 }, files) 132 } 133 134 func TestGetTestFiles_SkipHiddenDir(t *testing.T) { 135 t.Parallel() 136 137 fsContent := map[string]string{ 138 "/test/1_test.arrai": "source1", 139 "/test/.must/go/deeper/2_test.arrai": "source2", 140 "/test/must/.go/deeper/3_test.arrai": "source3", 141 "/test/must/go/.deeper/4_test.arrai": "source4", 142 } 143 files, err := getTestFiles(withFs(t, fsContent), "/test") 144 require.NoError(t, err) 145 require.Equal(t, []File{{Path: "/test/1_test.arrai", Source: "source1"}}, files) 146 } 147 148 func withFs(t *testing.T, files map[string]string) context.Context { 149 err := os.Chdir("/") 150 require.NoError(t, err) 151 fs := ctxfs.CreateTestMemMapFs(t, files) 152 ctx := ctxfs.SourceFsOnto(context.Background(), fs) 153 return ctxrootcache.WithRootCache(ctx) 154 } 155 156 func TestRunFile_InvalidArrai(t *testing.T) { 157 t.Parallel() 158 159 file := File{Source: "invalid arr.ai code"} 160 err := runFile(context.Background(), &file) 161 require.Error(t, err) 162 } 163 164 func TestRunFile_AssertFails(t *testing.T) { 165 t.Parallel() 166 167 file := File{Source: "//test.assert.equal(1, 2)"} 168 err := runFile(context.Background(), &file) 169 require.Error(t, err) 170 } 171 172 func TestRunFile_TwoPass(t *testing.T) { 173 t.Parallel() 174 175 file := File{Source: "(test1: 1 = 1, test2: //test.assert.equal(2, 2))"} 176 err := runFile(context.Background(), &file) 177 require.NoError(t, err) 178 require.NotZero(t, file.WallTime) 179 require.ElementsMatch(t, file.Results, []Result{ 180 {Name: "test1", Outcome: Passed}, 181 {Name: "test2", Outcome: Passed}}) 182 } 183 184 func TestRunFile_OneFailOnePass(t *testing.T) { 185 t.Parallel() 186 187 file := File{Source: "(test1: 1 < 1, test2: 5 < 7)"} 188 err := runFile(context.Background(), &file) 189 require.NoError(t, err) 190 require.NotZero(t, file.WallTime) 191 require.ElementsMatch(t, file.Results, []Result{ 192 {Name: "test1", Outcome: Failed, Message: "Expected: true. Actual: false."}, 193 {Name: "test2", Outcome: Passed}}) 194 } 195 196 func TestRunFile_OneInvalidOnePass(t *testing.T) { 197 t.Parallel() 198 199 file := File{Source: "(test1: 1, test2: 5 < 7)"} 200 err := runFile(context.Background(), &file) 201 require.NoError(t, err) 202 require.NotZero(t, file.WallTime) 203 require.ElementsMatch(t, file.Results, []Result{ 204 {Name: "test1", Outcome: Invalid, 205 Message: "Could not determine test Outcome due to non-boolean result of type number: 1"}, 206 {Name: "test2", Outcome: Passed}}) 207 } 208 209 func TestRunFile_TestInSet(t *testing.T) { 210 t.Parallel() 211 212 file := File{ 213 Path: "some_test.arrai", 214 Source: "(test1: 1 = 1, category1: { 5 < 7 })", 215 } 216 err := runFile(context.Background(), &file) 217 require.NoError(t, err) 218 require.NotZero(t, file.WallTime) 219 require.ElementsMatch(t, file.Results, []Result{ 220 {Name: "test1", Outcome: Passed}, 221 {Name: "category1", Outcome: Invalid, Message: "Sets are not allowed as test containers. " + 222 "Please use tuples, dictionaries or arrays."}}) 223 }