view_test.v

4.3 KB · raw

1module view23import src.events4import src.history5import src.snapshot67fn save(id string, message string, checkpoint bool) history.Save {8	return history.Save{9		id:            id10		message:       message11		created_at:    179000000012		size_bytes:    102413		is_checkpoint: checkpoint14	}15}1617fn line_map(ids []string) map[string]bool {18	mut out := map[string]bool{}19	for id in ids {20		out[id] = true21	}22	return out23}2425fn test_tabs_filter_by_what_is_on_the_line() {26	on_the_line := line_map(['aaa', 'ccc'])27	mut replayed := save('bbb', 'replayed away', false)28	replayed.replayed_from = 'aaa'29	items := [save('aaa', 'first', false), replayed, save('ccc', 'before things', true)]3031	assert filter_saves(items, .all, on_the_line, '').len == 332	// A replayed-away save exists in history but is on neither live list.33	assert filter_saves(items, .saves, on_the_line, '').map(it.id) == ['aaa', 'ccc']34	assert filter_saves(items, .checkpoints, on_the_line, '').map(it.id) == ['ccc']35}3637fn test_search_is_case_insensitive_across_the_fields() {38	on_the_line := line_map(['aaa', 'bbb', 'ccc'])39	mut with_agent := save('bbb', 'fix chunk boundary', false)40	with_agent.agent = 'DeepSeek/Flash'41	mut with_session := save('ccc', 'other work', false)42	with_session.session = 'phase one'43	items := [save('aaa', 'add storage', false), with_agent, with_session]4445	assert filter_saves(items, .all, on_the_line, 'STORAGE').map(it.id) == ['aaa']46	assert filter_saves(items, .all, on_the_line, 'chunk').map(it.id) == ['bbb']47	assert filter_saves(items, .all, on_the_line, 'deepseek').map(it.id) == ['bbb']48	assert filter_saves(items, .all, on_the_line, 'PHASE').map(it.id) == ['ccc']49	assert filter_saves(items, .all, on_the_line, 'nothing here').len == 050}5152fn test_move_selection_clamps_at_both_ends() {53	assert move_selection(0, 1, 3) == 154	assert move_selection(2, 1, 3) == 255	assert move_selection(0, -1, 3) == 056	assert move_selection(0, 0, 0) == 057	assert move_selection(5, 1, 0) == 058	// G asks for a move past the end and lands on the last entry.59	assert move_selection(3, -1, 3) == 260}6162fn test_detail_lists_files_with_stats_and_notes_binaries() {63	target := save('aaa', 'change two files', false)64	flag := events.Flag{65		save_id: 'aaa'66		flagged: true67		reason:  'sketchy'68	}69	deltas := [70		snapshot.Delta{71			path:    'src/main.v'72			kind:    'modified'73			added:   474			removed: 275		},76		snapshot.Delta{77			path:   'logo.png'78			kind:   'added'79			binary: true80		},81	]82	text := detail_lines(target, deltas, flag).join('\n')83	assert text.contains('checksum  aaa')84	assert text.contains('flag      sketchy')85	assert text.contains('src/main.v')86	assert text.contains('+4')87	assert text.contains('-2')88	assert text.contains('logo.png')89	assert text.contains('(binary)')90	assert text.contains('2 files changed against the parent')91}9293fn test_detail_says_so_when_nothing_changed() {94	target := save('aaa', 'first save', false)95	text := detail_lines(target, [], events.Flag{96		save_id: 'aaa'97	}).join('\n')98	assert text.contains('nothing changed against the parent')99}100101fn test_frame_shows_counts_the_selected_entry_and_the_status_bar() {102	on_the_line := line_map(['aaa', 'ccc'])103	items := [save('aaa', 'first', false), save('ccc', 'before storage', true)]104	screen := Screen{105		tab:      .all106		items:    items107		selected: 1108		on_line:  on_the_line109		counts:   count_tabs(items, on_the_line)110		rows:     24111		cols:     100112		status:   '3 shown'113	}114	text := frame_lines(screen).join('\n')115	assert text.contains('all (2)')116	assert text.contains('checkpoints (1)')117	assert text.contains('before storage')118	assert text.contains('aaa')119	// The selected entry carries its extra line.120	assert text.contains('agent')121	assert text.contains('◐')122	assert text.contains('3 shown')123}124125fn test_frame_says_no_results_when_the_search_matches_nothing() {126	screen := Screen{127		tab:    .all128		rows:   24129		cols:   80130		query:  'nothing matches this'131		counts: TabCounts{}132	}133	text := frame_lines(screen).join('\n')134	assert text.contains('no results')135	assert text.contains('/nothing matches this')136}137138fn test_render_clears_each_line_before_drawing_it() {139	screen := Screen{140		tab:  .saves141		rows: 6142		cols: 60143	}144	frame := render(screen)145	assert frame.starts_with('\x1b[H')146	// One line-clear per row drawn, so a shorter frame cannot leave the tail of147	// a longer one behind.148	assert frame.count('\x1b[2K') == frame_lines(screen).len149}