Skip to content

Commit 6f04b1a

Browse files
committed
Refactor and add unit tests
1 parent 1551159 commit 6f04b1a

File tree

4 files changed

+68
-16
lines changed

4 files changed

+68
-16
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ libc = "0.2"
2222
time = "0.1"
2323
enum-primitive-derive = "^0.1"
2424
num-traits = "^0.1"
25+
failure = "0.1"
2526

2627
[build-dependencies]
2728
bindgen = "0.47"

examples/hello.rs

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
//#[macro_use]
2+
//extern crate failure;
3+
4+
#[macro_use]
5+
extern crate redismodule;
6+
17
use std::iter;
28
use std::ffi::CString;
39

4-
//#[macro_use]
5-
extern crate redismodule;
10+
//use failure::Error;
611

712
use redismodule::{Context, Command, RedisResult, RedisValue, RedisError};
813

@@ -11,27 +16,25 @@ fn hello_mul(_: &Context, args: Vec<String>) -> RedisResult {
1116
return Err(RedisError::WrongArity);
1217
}
1318

14-
let mut nums = vec![];
15-
16-
for arg in args.into_iter().skip(1) {
17-
nums.push(parse_integer(&arg)?);
18-
}
19+
let nums = args
20+
.into_iter()
21+
.skip(1)
22+
.map(parse_integer)
23+
.collect::<Result<Vec<i64>, RedisError>>()?;
1924

2025
let product = nums.iter().product();
2126

22-
let results = nums
23-
.into_iter()
24-
.chain(iter::once(product));
25-
2627
return Ok(RedisValue::Array(
27-
results
28+
nums
29+
.into_iter()
30+
.chain(iter::once(product))
2831
.map(RedisValue::Integer)
2932
.collect()));
3033
}
3134

3235
//////////////////////////////////////////////////////
3336

34-
fn parse_integer(arg: &str) -> Result<i64, RedisError> {
37+
fn parse_integer(arg: String) -> Result<i64, RedisError> {
3538
arg.parse::<i64>()
3639
.map_err(|_| RedisError::String(format!("Couldn't parse as integer: {}", arg)))
3740
}
@@ -41,8 +44,51 @@ fn parse_integer(arg: &str) -> Result<i64, RedisError> {
4144
const MODULE_NAME: &str = "hello";
4245
const MODULE_VERSION: u32 = 1;
4346

44-
/*
4547
redis_module!(MODULE_NAME, MODULE_VERSION, [
4648
Command::new("hello.mul", hello_mul, "write"),
4749
]);
48-
*/
50+
51+
//////////////////////////////////////////////////////
52+
53+
#[cfg(test)]
54+
mod tests {
55+
use super::*;
56+
57+
fn run_hello_mul(args: &[&str]) -> RedisResult {
58+
hello_mul(
59+
&Context::dummy(),
60+
args
61+
.iter()
62+
.map(|v| String::from(*v))
63+
.collect(),
64+
)
65+
}
66+
67+
#[test]
68+
fn hello_mul_valid_integer_args() {
69+
let result = run_hello_mul(&vec!["hello.mul", "10", "20", "30"]);
70+
71+
match result {
72+
Ok(RedisValue::Array(v)) => {
73+
assert_eq!(v, vec![10, 20, 30, 6000]
74+
.into_iter()
75+
.map(RedisValue::Integer)
76+
.collect::<Vec<_>>());
77+
}
78+
_ => assert!(false, "Bad result: {:?}", result)
79+
}
80+
}
81+
82+
#[test]
83+
fn hello_mul_bad_integer_args() {
84+
let result = run_hello_mul(&vec!["hello.mul", "10", "xx", "30"]);
85+
86+
match result {
87+
Err(RedisError::String(s)) => {
88+
assert_eq!(s, "Couldn't parse as integer: xx");
89+
}
90+
_ => assert!(false, "Bad result: {:?}", result)
91+
}
92+
}
93+
}
94+

src/context.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::ptr;
12
use std::os::raw::c_long;
23
use std::ffi::CString;
34

@@ -17,6 +18,10 @@ impl Context {
1718
Self { ctx }
1819
}
1920

21+
pub fn dummy() -> Self {
22+
Self { ctx: ptr::null_mut() }
23+
}
24+
2025
pub fn log(&self, level: LogLevel, message: &str) {
2126
let level = CString::new(format!("{:?}", level).to_lowercase()).unwrap();
2227
let fmt = CString::new(message).unwrap();

src/redismodule.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub enum RedisError {
1313
String(String),
1414
}
1515

16-
#[derive(Debug)]
16+
#[derive(Debug, PartialEq)]
1717
pub enum RedisValue {
1818
String(String),
1919
Integer(i64),

0 commit comments

Comments
 (0)