Skip to content

Commit 405e181

Browse files
committed
[Testsing] Adds test data files
Scope: introduces a test data files that are created alongside with code files. Those files are pre-filled with sample tests from leetcode and could be extended with the custom values. CLI test input has always a priority over test files. If test file is missing and test input is not provided, sample test case is used as was previously. Changes: - Fixes a bug with missing Vec<> inside of optional - Adds runtime error message to the output - Generates a test file when test is created
1 parent 1601f03 commit 405e181

File tree

6 files changed

+58
-10
lines changed

6 files changed

+58
-10
lines changed

src/cache/mod.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ impl Cache {
202202
testcase: Option<String>,
203203
) -> Result<(HashMap<&'static str, String>, [String; 2]), Error> {
204204
trace!("pre run code...");
205-
use crate::helper::code_path;
205+
use crate::helper::{code_path, test_cases_path};
206206
use std::fs::File;
207207
use std::io::Read;
208208

@@ -218,6 +218,24 @@ impl Cache {
218218
let mut json: HashMap<&'static str, String> = HashMap::new();
219219
let mut code: String = "".to_string();
220220

221+
let maybe_file_testcases: Option<String> = test_cases_path(&p)
222+
.map(|filename| {
223+
let mut tests = "".to_string();
224+
File::open(filename)
225+
.and_then(|mut file_descriptor| file_descriptor.read_to_string(&mut tests))
226+
.map(|_| Some(tests))
227+
.unwrap_or(None)
228+
})
229+
.unwrap_or(None);
230+
231+
// Takes test cases using following priority
232+
// 1. cli parameter
233+
// 2. test cases from the file
234+
// 3. sample test case from the task
235+
let testcase = testcase
236+
.or(maybe_file_testcases)
237+
.unwrap_or(d.case);
238+
221239
File::open(code_path(&p, None)?)?.read_to_string(&mut code)?;
222240

223241
json.insert("lang", conf.code.lang.to_string());
@@ -226,10 +244,7 @@ impl Cache {
226244

227245
// pass manually data
228246
json.insert("name", p.name.to_string());
229-
match testcase {
230-
Some(case) => json.insert("data_input", case),
231-
_ => json.insert("data_input", d.case),
232-
};
247+
json.insert("data_input", testcase);
233248

234249
let url = match run {
235250
Run::Test => conf.sys.urls.get("test")?.replace("$slug", &p.slug),

src/cache/models.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ mod question {
166166
#[derive(Debug, Default, Serialize, Deserialize)]
167167
pub struct MetaData {
168168
pub name: Option<String>,
169-
pub params: Option<Param>,
169+
pub params: Option<Vec<Param>>,
170170
pub r#return: Return,
171171
}
172172

@@ -378,7 +378,7 @@ impl std::fmt::Display for VerifyResult {
378378
// if anybody reach this, welcome to fix this!
379379
13 | 14 => write!(f, "\n{}\n", &self.status.status_msg.yellow().bold(),)?,
380380
// Runtime error
381-
15 => write!(f, "\n{}\n", &self.status.status_msg.red().bold())?,
381+
15 => write!(f, "\n{}\n{}\n'", &self.status.status_msg.red().bold(), &self.status.runtime_error)?,
382382
// Compile Error
383383
20 => write!(
384384
f,
@@ -479,6 +479,8 @@ mod verify {
479479
pub status_memory: String,
480480
#[serde(default)]
481481
pub status_runtime: String,
482+
#[serde(default)]
483+
pub runtime_error: String
482484
}
483485

484486
#[derive(Debug, Default, Deserialize)]

src/cache/parser.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ pub fn desc(q: &mut Question, v: Value) -> Result<(), Error> {
4343
stats: serde_json::from_str(o.get("stats")?.as_str()?)?,
4444
defs: serde_json::from_str(o.get("codeDefinition")?.as_str()?)?,
4545
case: o.get("sampleTestCase")?.as_str()?.to_string(),
46+
all_cases: o.get("exampleTestcases")
47+
.unwrap_or(o.get("sampleTestCase")?) // soft fail to the sampleTestCase
48+
.as_str()?
49+
.to_string(),
4650
metadata: serde_json::from_str(o.get("metaData")?.as_str()?)?,
4751
test: o.get("enableRunCode")?.as_bool()?,
4852
t_content: o

src/cmds/edit.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,24 +64,33 @@ impl Command for EditCommand {
6464

6565
let lang = conf.code.lang;
6666
let path = crate::helper::code_path(&target, Some(lang.to_owned()))?;
67+
let tests_path = crate::helper::test_cases_path(&target)?;
68+
6769
if !Path::new(&path).exists() {
6870
let mut qr = serde_json::from_str(&target.desc);
6971
if qr.is_err() {
7072
qr = Ok(cache.get_question(id).await?);
7173
}
7274

7375
let question: Question = qr?;
74-
let mut f = File::create(&path)?;
76+
77+
let mut file_code = File::create(&path)?;
78+
let mut file_tests = File::create(&tests_path)?;
79+
7580
let mut flag = false;
7681
for d in question.defs.0 {
7782
if d.value == lang {
7883
flag = true;
79-
f.write_all(d.code.to_string().as_bytes())?;
84+
file_code.write_all(d.code.to_string().as_bytes())?;
85+
file_tests.write_all(question.all_cases.as_bytes())?;
8086
}
8187
}
8288

89+
// if language is not found in the list of supported languges clean up files
8390
if !flag {
8491
std::fs::remove_file(&path)?;
92+
std::fs::remove_file(&tests_path)?;
93+
8594
return Err(crate::Error::FeatureError(format!(
8695
"This question doesn't support {}, please try another",
8796
&lang

src/helper.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! A set of helper traits
22
pub use self::digit::Digit;
3-
pub use self::file::{code_path, load_script};
3+
pub use self::file::{code_path, load_script, test_cases_path};
44
pub use self::filter::{filter, squash};
55
pub use self::html::HTML;
66

@@ -282,6 +282,23 @@ mod file {
282282
}
283283

284284
use crate::cache::models::Problem;
285+
286+
/// Generate test casese path by fid
287+
pub fn test_cases_path(target: &Problem) -> Result<String, crate::Error> {
288+
let conf = crate::cfg::locate()?;
289+
290+
let mut path = format!(
291+
"{}/{}.tests.dat",
292+
conf.storage.code()?,
293+
conf.code.pick,
294+
);
295+
296+
path = path.replace("${fid}", &target.fid.to_string());
297+
path = path.replace("${slug}", &target.slug.to_string());
298+
299+
Ok(path)
300+
}
301+
285302
/// Generate code path by fid
286303
pub fn code_path(target: &Problem, l: Option<String>) -> Result<String, crate::Error> {
287304
let conf = crate::cfg::locate()?;

src/plugins/leetcode.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ impl LeetCode {
135135
" stats",
136136
" codeDefinition",
137137
" sampleTestCase",
138+
" exampleTestcases",
138139
" enableRunCode",
139140
" metaData",
140141
" translatedContent",

0 commit comments

Comments
 (0)