reviewer_test.odin (4453B)
1 package reviewer 2 3 import "core:strings" 4 import "core:testing" 5 6 import "../change" 7 import "../job" 8 import "../provider" 9 10 // echoing is a provider that answers every ask with the text given. 11 echoing :: proc(text: string) -> provider.Provider { 12 argv := make([]string, 2, context.temp_allocator) 13 argv[0], argv[1] = "echo", text 14 return provider.Provider{kind = .Command, argv = argv} 15 } 16 17 with_tests :: proc() -> change.Change { 18 c := change.Change{} 19 c.tests = make([dynamic]change.Function, context.temp_allocator) 20 append( 21 &c.tests, 22 change.Function { 23 name = "TestX", 24 file = "x_test.go", 25 line = 4, 26 body = "func TestX(t *testing.T) {}", 27 }, 28 ) 29 return c 30 } 31 32 @(test) 33 findings_are_read_and_jobs_without_a_subject_are_skipped :: proc(t: ^testing.T) { 34 context.allocator = context.temp_allocator 35 p := echoing( 36 `{"findings":[{"rule":"cannot-fail","severity":"must-fix","file":"x_test.go","line":4,"symbol":"TestX","message":"asserts nothing","fix":"assert"},{"rule":"invented","severity":"note","message":"x","fix":"y"}]}`, 37 ) 38 r := Reviewer { 39 provider = p, 40 name = provider.name(p), 41 verify = false, 42 } 43 c := with_tests() 44 result := run(&r, &c, job.all(), serial = true) 45 testing.expect_value(t, len(result.failures), 0) 46 testing.expect_value(t, len(result.findings), 1) 47 if len(result.findings) == 1 { 48 f := result.findings[0] 49 testing.expect_value(t, f.job, "tests") 50 testing.expect_value(t, f.rule, "cannot-fail") 51 testing.expect_value(t, f.line, 4) 52 testing.expect(t, !f.verified) 53 } 54 testing.expect_value( 55 t, 56 strings.join(result.skipped[:], ",", context.temp_allocator), 57 "duplication,namer,claims,hygiene", 58 ) 59 } 60 61 @(test) 62 a_second_reading_retracts_what_it_does_not_hold :: proc(t: ^testing.T) { 63 context.allocator = context.temp_allocator 64 // One answer that is both a findings object and a verdicts object: 65 // the first reading reports one finding, the second says it falls. 66 p := echoing( 67 `{"findings":[{"rule":"cannot-fail","severity":"must-fix","file":"x_test.go","line":4,"symbol":"TestX","message":"m","fix":"f"}],"verdicts":[{"index":0,"holds":false,"reason":"the test can fail"}]}`, 68 ) 69 r := Reviewer { 70 provider = p, 71 name = provider.name(p), 72 verify = true, 73 } 74 c := with_tests() 75 result := run(&r, &c, job.all(), serial = true) 76 testing.expect_value(t, len(result.failures), 0) 77 testing.expect_value(t, len(result.findings), 0) 78 testing.expect_value(t, len(result.retracted), 1) 79 if len(result.retracted) == 1 { 80 testing.expect_value(t, result.retracted[0].reason, "the test can fail") 81 testing.expect_value(t, result.retracted[0].finding.rule, "cannot-fail") 82 } 83 // A verdict that holds leaves the finding standing, verified. 84 holds := echoing( 85 `{"findings":[{"rule":"cannot-fail","severity":"must-fix","file":"x_test.go","line":4,"symbol":"TestX","message":"m","fix":"f"}],"verdicts":[{"index":0,"holds":true,"reason":"it stands"}]}`, 86 ) 87 r = Reviewer { 88 provider = holds, 89 name = provider.name(holds), 90 verify = true, 91 } 92 c = with_tests() 93 result = run(&r, &c, job.all(), serial = true) 94 testing.expect_value(t, len(result.findings), 1) 95 if len(result.findings) == 1 { 96 testing.expect(t, result.findings[0].verified) 97 } 98 } 99 100 @(test) 101 a_verdict_that_cannot_be_asked_fails_open :: proc(t: ^testing.T) { 102 context.allocator = context.temp_allocator 103 // The answer is findings only, so the verdict ask reads no verdicts 104 // twice over: the findings stand unverified and the failure is named. 105 p := echoing( 106 `{"findings":[{"rule":"cannot-fail","severity":"must-fix","file":"x_test.go","line":4,"symbol":"TestX","message":"m","fix":"f"}]}`, 107 ) 108 r := Reviewer { 109 provider = p, 110 name = provider.name(p), 111 verify = true, 112 } 113 c := with_tests() 114 result := run(&r, &c, job.all(), serial = true) 115 testing.expect_value(t, len(result.findings), 1) 116 if len(result.findings) == 1 { 117 testing.expect(t, result.findings[0].verified) 118 } 119 testing.expectf( 120 t, 121 len(result.failures) == 0, 122 "an omitted verdict stands rather than falls: %v", 123 result.failures, 124 ) 125 prose := echoing("I have nothing to say") 126 r = Reviewer { 127 provider = prose, 128 name = provider.name(prose), 129 verify = false, 130 } 131 c = with_tests() 132 result = run(&r, &c, job.all(), serial = true) 133 testing.expect_value(t, len(result.failures), 1) 134 if len(result.failures) == 1 { 135 testing.expect( 136 t, 137 strings.has_prefix( 138 result.failures[0], 139 "tests: no findings object in the answer, twice", 140 ), 141 ) 142 } 143 }