review

review patchsets using your default editor
Log | Files | Refs

job_test.odin (7343B)


      1 package job
      2 
      3 import "core:strings"
      4 import "core:testing"
      5 
      6 import "../change"
      7 import "../txt"
      8 
      9 dyn :: proc(items: []$T) -> [dynamic]T {
     10 	out := make([dynamic]T, context.temp_allocator)
     11 	append(&out, ..items)
     12 	return out
     13 }
     14 
     15 @(test)
     16 jobs_carry_their_criteria :: proc(t: ^testing.T) {
     17 	jobs := all(context.temp_allocator)
     18 	testing.expect_value(t, len(jobs), 5)
     19 	for j in jobs {
     20 		testing.expectf(t, len(rules(j.criteria)) >= 4, "%s cites too few rules", j.name)
     21 		testing.expect(t, strings.contains(j.criteria, "- `"))
     22 	}
     23 	allowed := rules(jobs[1].criteria)
     24 	testing.expect(t, allowed["cannot-fail"], "the tests criteria name cannot-fail")
     25 	picked, err := chosen("tests, hygiene", context.temp_allocator)
     26 	testing.expect_value(t, err, "")
     27 	testing.expect_value(t, len(picked), 2)
     28 	_, err = chosen("nothing", context.temp_allocator)
     29 	testing.expect(t, strings.contains(err, "no job called"))
     30 }
     31 
     32 @(test)
     33 subjects_render_the_part_each_job_reads :: proc(t: ^testing.T) {
     34 	context.allocator = context.temp_allocator
     35 	c := change.Change {
     36 		message    = "x: do the thing",
     37 		stat       = " a.go | 2 +-",
     38 		convention = {"x: earlier"},
     39 		symbols    = dyn(
     40 			[]change.Symbol {
     41 				{
     42 					name = "Parse",
     43 					kind = "func",
     44 					file = "a.go",
     45 					line = 3,
     46 					exported = true,
     47 					signature = "func Parse() {",
     48 					doc = "Parse reads.\nMore.",
     49 				},
     50 			},
     51 		),
     52 		tests      = dyn(
     53 			[]change.Function {
     54 				{
     55 					name = "TestParse",
     56 					file = "a_test.go",
     57 					line = 9,
     58 					body = "func TestParse(t *testing.T) {\n\tt.Skip()\n\tParse()\n}",
     59 					skips = 10,
     60 				},
     61 			},
     62 		),
     63 		comments   = dyn(
     64 			[]change.Located {
     65 				{text = "one", file = "a.go", line = 1, below = "x := 1"},
     66 				{text = "two", file = "a.go", line = 2, below = "y := 2\nz := 3"},
     67 				{text = "parse the input", file = "a.go", line = 7, below = "func parseInput() {"},
     68 			},
     69 		),
     70 		index      = {
     71 			{
     72 				name = "Parse",
     73 				kind = "func",
     74 				file = "a.go",
     75 				line = 3,
     76 				body = "func Parse() {\n\treturn\n}",
     77 			},
     78 		},
     79 	}
     80 	c.candidates = make(map[string][]string)
     81 	c.candidates["Parse"] = []string{"b.go:4: func parse() {"}
     82 	c.twins = make(map[string][]string)
     83 	c.twins["Parse"] = []string{"b.go:1: const Parse = 1   <- same value"}
     84 	namer := namer_subject(&c, context.temp_allocator)
     85 	for want in ([]string{"a.go:3  func Parse  (exported)", "doc: Parse reads.", "names already in this repository: b.go:4: func parse() {"}) {
     86 		testing.expectf(
     87 			t,
     88 			strings.contains(namer, want),
     89 			"%q missing from namer:\n%s",
     90 			want,
     91 			namer,
     92 		)
     93 	}
     94 	dup := duplication_subject(&c, context.temp_allocator)
     95 	for want in ([]string{"Judge every pair on this list.", "      b.go:1: const Parse = 1\n", "NEW  a.go:3  func Parse", "       b.go:4: func parse() {"}) {
     96 		testing.expectf(
     97 			t,
     98 			strings.contains(dup, want),
     99 			"%q missing from duplication:\n%s",
    100 			want,
    101 			dup,
    102 		)
    103 	}
    104 	tests := tests_subject(&c, context.temp_allocator)
    105 	for want in ([]string{"--- a_test.go:9 TestParse  (skips itself at line 10)", "Functions the tests call", "--- a.go:3 Parse\nfunc Parse() {"}) {
    106 		testing.expectf(
    107 			t,
    108 			strings.contains(tests, want),
    109 			"%q missing from tests:\n%s",
    110 			want,
    111 			tests,
    112 		)
    113 	}
    114 	claims := claims_subject(&c, context.temp_allocator)
    115 	for want in ([]string{"a.go:1  one\na.go:2  two\n    code: y := 2\n    code: z := 3\n"}) {
    116 		testing.expectf(
    117 			t,
    118 			strings.contains(claims, want),
    119 			"%q missing from claims:\n%s",
    120 			want,
    121 			claims,
    122 		)
    123 	}
    124 	testing.expect(
    125 		t,
    126 		!strings.contains(claims, "parse the input"),
    127 		"a restating comment is not a claim",
    128 	)
    129 	hygiene := hygiene_subject(&c, context.temp_allocator)
    130 	for want in ([]string{"Commit message:\n\nx: do the thing", "Files changed:\n a.go | 2 +-", "  x: earlier"}) {
    131 		testing.expectf(
    132 			t,
    133 			strings.contains(hygiene, want),
    134 			"%q missing from hygiene:\n%s",
    135 			want,
    136 			hygiene,
    137 		)
    138 	}
    139 	empty := change.Change{}
    140 	testing.expect_value(t, namer_subject(&empty, context.temp_allocator), "")
    141 	testing.expect_value(t, hygiene_subject(&empty, context.temp_allocator), "")
    142 }
    143 
    144 @(test)
    145 answers_are_decoded_and_held_to_the_criteria :: proc(t: ^testing.T) {
    146 	allowed := rules("- `cannot-fail` x\n- `other` y\n", context.temp_allocator)
    147 	raw, found := txt.object(
    148 		"Sure! {\"findings\":[{\"rule\":\"cannot-fail\",\"severity\":\"must-fix\",\"file\":\"a_test.go\",\"line\":4,\"symbol\":\"TestX\",\"message\":\"m\",\"fix\":\"f\"},{\"rule\":\"invented\",\"severity\":\"note\",\"message\":\"n\"}]} thanks",
    149 	)
    150 	testing.expect(t, found)
    151 	got, ok := decode(raw, "tests", allowed, context.temp_allocator)
    152 	testing.expect(t, ok)
    153 	testing.expect_value(t, len(got), 1)
    154 	if len(got) == 1 {
    155 		testing.expect_value(t, got[0].job, "tests")
    156 		testing.expect_value(t, got[0].rule, "cannot-fail")
    157 		testing.expect_value(t, got[0].line, 4)
    158 		testing.expect_value(t, got[0].severity_name, "must-fix")
    159 	}
    160 	testing.expect(t, readable(`{"findings":[]}`))
    161 	testing.expect(t, !readable("no json here"))
    162 	_, none := txt.object("prose")
    163 	testing.expect(t, !none)
    164 	testing.expect_value(t, len(calls("f(); g.h(x); if (y) {", context.temp_allocator)), 2)
    165 }
    166 
    167 @(test)
    168 parts_cut_a_large_subject_by_file :: proc(t: ^testing.T) {
    169 	context.allocator = context.temp_allocator
    170 	c := change.Change {
    171 		files = {"a.go", "b.go", "c.md", "d.go"},
    172 	}
    173 	c.symbols = make([dynamic]change.Symbol)
    174 	long := strings.repeat("x", 9000)
    175 	for name in ([]string{"a.go", "b.go", "d.go"}) {
    176 		append(
    177 			&c.symbols,
    178 			change.Symbol{name = "S", kind = "func", file = name, line = 1, signature = long},
    179 		)
    180 	}
    181 	j := all(context.temp_allocator)[2]
    182 	pieces := parts(j, &c, context.temp_allocator)
    183 	testing.expect_value(t, len(pieces), 3)
    184 	if len(pieces) == 3 {
    185 		testing.expect_value(t, len(pieces[0].symbols), 1)
    186 		testing.expect_value(t, pieces[0].files[0], "a.go")
    187 		testing.expect_value(t, pieces[2].files[0], "d.go")
    188 	}
    189 	small := change.Change {
    190 		files = {"a.go"},
    191 	}
    192 	small.symbols = make([dynamic]change.Symbol)
    193 	append(
    194 		&small.symbols,
    195 		change.Symbol{name = "S", kind = "func", file = "a.go", line = 1, signature = "short"},
    196 	)
    197 	testing.expect_value(t, len(parts(j, &small, context.temp_allocator)), 1)
    198 	// A file the job reads nothing from is in no part: the tests job
    199 	// reads a test file, the namer does not.
    200 	tests_only := change.Change{files = {"a.go", "a_test.go"}}
    201 	tests_only.symbols = make([dynamic]change.Symbol)
    202 	append(&tests_only.symbols, change.Symbol{name = "S", kind = "func", file = "a.go", line = 1, signature = strings.repeat("x", 17000)})
    203 	tests_only.tests = make([dynamic]change.Function)
    204 	append(&tests_only.tests, change.Function{name = "TestS", file = "a_test.go", line = 1, body = strings.repeat("y", 17000)})
    205 	namer_pieces := parts(all(context.temp_allocator)[2], &tests_only, context.temp_allocator)
    206 	testing.expect_value(t, len(namer_pieces), 1)
    207 	if len(namer_pieces) == 1 {
    208 		testing.expect_value(t, len(namer_pieces[0].files), 1)
    209 		testing.expect_value(t, namer_pieces[0].files[0], "a.go")
    210 	}
    211 	for piece in namer_pieces {
    212 		testing.expect(t, strings.trim_space(all(context.temp_allocator)[2].subject(piece, context.temp_allocator)) != "", "an empty part is never asked")
    213 	}
    214 	tests_pieces := parts(all(context.temp_allocator)[1], &tests_only, context.temp_allocator)
    215 	testing.expect_value(t, len(tests_pieces), 1)
    216 	if len(tests_pieces) == 1 {
    217 		testing.expect_value(t, tests_pieces[0].files[0], "a_test.go")
    218 	}
    219 }