summaryrefslogtreecommitdiffstats
path: root/src/process/testutil/process_module_test.rs
blob: 5316114fde8d5d5f2255d1d281ccc2d426a0e908 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use std::{cell::Cell, path::Path};

use config::{testutil::create_config, Config};
use tempfile::{Builder, NamedTempFile};

use crate::{
	input::{
		testutil::{with_event_handler, TestContext as EventHandlerTestContext},
		Event,
	},
	module::{Module, ProcessResult, State},
	todo_file::{Line, TodoFile},
	view::{
		testutil::{with_view_sender, TestContext as ViewSenderContext},
		RenderContext,
		ViewData,
	},
};

pub struct TestContext<'t> {
	pub config: &'t Config,
	pub event_handler_context: EventHandlerTestContext,
	pub view_sender_context: ViewSenderContext,
	pub rebase_todo_file: TodoFile,
	pub render_context: RenderContext,
	todo_file: Cell<NamedTempFile>,
}

impl<'t> TestContext<'t> {
	fn get_build_data<'tc>(&self, module: &'tc mut dyn Module) -> &'tc ViewData {
		module.build_view_data(&self.render_context, &self.rebase_todo_file)
	}

	pub fn activate(&self, module: &'_ mut dyn Module, state: State) -> ProcessResult {
		module.activate(&self.rebase_todo_file, state)
	}

	#[allow(clippy::unused_self)]
	pub fn deactivate(&mut self, module: &'_ mut dyn Module) {
		module.deactivate();
	}

	pub fn build_view_data<'tc>(&self, module: &'tc mut dyn Module) -> &'tc ViewData {
		self.get_build_data(module)
	}

	pub fn handle_event(&mut self, module: &'_ mut dyn Module) -> ProcessResult {
		module.handle_events(
			&self.event_handler_context.event_handler,
			&self.view_sender_context.sender,
			&mut self.rebase_todo_file,
		)
	}

	pub fn handle_n_events(&mut self, module: &'_ mut dyn Module, n: usize) -> Vec<ProcessResult> {
		let mut results = vec![];
		for _ in 0..n {
			results.push(module.handle_events(
				&self.event_handler_context.event_handler,
				&self.view_sender_context.sender,
				&mut self.rebase_todo_file,
			));
		}
		results
	}

	pub fn handle_all_events(&mut self, module: &'_ mut dyn Module) -> Vec<ProcessResult> {
		let mut results = vec![];
		for _ in 0..self.event_handler_context.number_events {
			results.push(module.handle_events(
				&self.event_handler_context.event_handler,
				&self.view_sender_context.sender,
				&mut self.rebase_todo_file,
			));
		}
		results
	}

	pub fn new_todo_file(&self) -> TodoFile {
		TodoFile::new(self.get_todo_file_path().as_str(), 1, "#")
	}

	pub fn get_todo_file_path(&self) -> String {
		let t = self.todo_file.replace(NamedTempFile::new().unwrap());
		let path = t.path().to_str().unwrap().to_owned();
		self.todo_file.replace(t);
		path
	}

	pub fn delete_todo_file(&self) {
		self.todo_file
			.replace(Builder::new().tempfile().unwrap())
			.close()
			.unwrap();
	}

	pub fn set_todo_file_readonly(&self) {
		let t = self.todo_file.replace(NamedTempFile::new().unwrap());
		let todo_file = t.as_file();
		let mut permissions = todo_file.metadata().unwrap().permissions();
		permissions.set_readonly(true);
		todo_file.set_permissions(permissions).unwrap();
		self.todo_file.replace(t);
	}
}

pub fn process_module_test<C>(lines: &[&str], events: &[Event], callback: C)
where C: for<'p> FnOnce(TestContext<'p>) {
	with_event_handler(events, |event_handler_context| {
		with_view_sender(|view_sender_context| {
			let git_repo_dir = Path::new(env!("CARGO_MANIFEST_DIR"))
				.join("test")
				.join("fixtures")
				.join("simple")
				.to_str()
				.unwrap()
				.to_owned();
			let todo_file = Builder::new()
				.prefix("git-rebase-todo-scratch")
				.suffix("")
				.tempfile_in(git_repo_dir.as_str())
				.unwrap();

			let mut rebase_todo_file = TodoFile::new(todo_file.path().to_str().unwrap(), 1, "#");
			rebase_todo_file.set_lines(lines.iter().map(|l| Line::new(l).unwrap()).collect());
			callback(TestContext {
				config: &create_config(),
				event_handler_context,
				rebase_todo_file,
				view_sender_context,
				todo_file: Cell::new(todo_file),
				render_context: RenderContext::new(300, 120),
			});
		});
	});
}