Skip to content

Commit 9b35e55

Browse files
authored
补充单元测试 (#24)
* test(matcher): 添加 matcher 组件的单元测试 * test(service): 添加 service 组件的单元测试
1 parent a3598bd commit 9b35e55

File tree

22 files changed

+822
-30
lines changed

22 files changed

+822
-30
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/core/src/expression.rs

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ pub enum Expression {
1111
Equals(Value),
1212
NotEquals(Value),
1313
StartsWith(Value),
14+
NotStartsWith(Value),
1415
EndsWith(Value),
16+
NotEndsWith(Value),
1517
Contains(Value),
1618
NotContains(Value),
1719
Exists,
@@ -32,10 +34,18 @@ impl Expression {
3234
Expression::StartsWith(Value::new(value, sensitive))
3335
}
3436

37+
pub fn not_starts_with(value: impl AsRef<str>, sensitive: bool) -> Self {
38+
Expression::NotStartsWith(Value::new(value, sensitive))
39+
}
40+
3541
pub fn ends_with(value: impl AsRef<str>, sensitive: bool) -> Self {
3642
Expression::EndsWith(Value::new(value, sensitive))
3743
}
3844

45+
pub fn not_ends_with(value: impl AsRef<str>, sensitive: bool) -> Self {
46+
Expression::NotEndsWith(Value::new(value, sensitive))
47+
}
48+
3949
pub fn contains(value: impl AsRef<str>, sensitive: bool) -> Self {
4050
Expression::Contains(Value::new(value, sensitive))
4151
}
@@ -50,12 +60,22 @@ impl Expression {
5060
.map_err(Error::new)
5161
}
5262

63+
pub fn exists() -> Self {
64+
Self::Exists
65+
}
66+
67+
pub fn not_exists() -> Self {
68+
Self::NotExists
69+
}
70+
5371
pub fn matches(&self, text: Option<&str>) -> bool {
5472
match self {
5573
Expression::Equals(value) => value.equals(text),
5674
Expression::NotEquals(value) => value.not_equals(text),
5775
Expression::StartsWith(value) => value.starts_with(text),
76+
Expression::NotStartsWith(value) => value.not_starts_with(text),
5877
Expression::EndsWith(value) => value.ends_with(text),
78+
Expression::NotEndsWith(value) => value.not_ends_with(text),
5979
Expression::Contains(value) => value.contains(text),
6080
Expression::NotContains(value) => value.not_contains(text),
6181
Expression::Exists => text.is_some(),
@@ -83,10 +103,18 @@ impl Display for Expression {
83103
f.write_str("StartsWith")?;
84104
<Value as Display>::fmt(value, f)
85105
}
106+
Expression::NotStartsWith(value) => {
107+
f.write_str("NotStartWith")?;
108+
<Value as Display>::fmt(value, f)
109+
}
86110
Expression::EndsWith(value) => {
87111
f.write_str("EndsWith")?;
88112
<Value as Display>::fmt(value, f)
89113
}
114+
Expression::NotEndsWith(value) => {
115+
f.write_str("NotEndsWith")?;
116+
<Value as Display>::fmt(value, f)
117+
}
90118
Expression::Contains(value) => {
91119
f.write_str("Contains")?;
92120
<Value as Display>::fmt(value, f)
@@ -121,8 +149,12 @@ impl FromStr for Expression {
121149
"?NotEquals" => Ok(Expression::not_equals(value, false)),
122150
"StartsWith" => Ok(Expression::starts_with(value, true)),
123151
"?StartsWith" => Ok(Expression::starts_with(value, false)),
152+
"NotStartsWith" => Ok(Expression::not_starts_with(value, true)),
153+
"?NotStartsWith" => Ok(Expression::not_starts_with(value, false)),
124154
"EndsWith" => Ok(Expression::ends_with(value, true)),
125155
"?EndsWith" => Ok(Expression::ends_with(value, false)),
156+
"NotEndsWith" => Ok(Expression::not_ends_with(value, true)),
157+
"?NotEndsWith" => Ok(Expression::not_ends_with(value, false)),
126158
"Contains" => Ok(Expression::contains(value, true)),
127159
"?Contains" => Ok(Expression::contains(value, false)),
128160
"NotContains" => Ok(Expression::not_contains(value, true)),
@@ -200,67 +232,57 @@ impl Value {
200232
}
201233

202234
pub fn not_equals(&self, value: Option<&str>) -> bool {
203-
match value {
204-
Some(value) => {
205-
if self.sensitive {
206-
self.raw.as_ref() != value
207-
} else {
208-
!self.raw.as_ref().eq_ignore_ascii_case(value)
209-
}
210-
}
211-
None => true,
212-
}
235+
!self.equals(value)
213236
}
214237

215238
pub fn starts_with(&self, value: Option<&str>) -> bool {
216239
match value {
217240
Some(value) => {
218241
if self.sensitive {
219-
self.raw.starts_with(value)
242+
value.starts_with(self.raw.as_ref())
220243
} else {
221-
self.raw.starts_with(&value.to_lowercase())
244+
value.to_lowercase().starts_with(self.raw.as_ref())
222245
}
223246
}
224247
None => false,
225248
}
226249
}
227250

251+
pub fn not_starts_with(&self, value: Option<&str>) -> bool {
252+
!self.starts_with(value)
253+
}
254+
228255
pub fn ends_with(&self, value: Option<&str>) -> bool {
229256
match value {
230257
Some(value) => {
231258
if self.sensitive {
232-
self.raw.ends_with(value)
259+
value.ends_with(self.raw.as_ref())
233260
} else {
234-
self.raw.ends_with(&value.to_lowercase())
261+
value.to_lowercase().ends_with(self.raw.as_ref())
235262
}
236263
}
237264
None => false,
238265
}
239266
}
240267

268+
pub fn not_ends_with(&self, value: Option<&str>) -> bool {
269+
!self.ends_with(value)
270+
}
271+
241272
pub fn contains(&self, value: Option<&str>) -> bool {
242273
match value {
243274
Some(value) => {
244275
if self.sensitive {
245-
self.raw.contains(value)
276+
value.contains(self.raw.as_ref())
246277
} else {
247-
self.raw.contains(&value.to_lowercase())
278+
value.to_lowercase().contains(self.raw.as_ref())
248279
}
249280
}
250281
None => false,
251282
}
252283
}
253284

254285
pub fn not_contains(&self, value: Option<&str>) -> bool {
255-
match value {
256-
Some(value) => {
257-
if self.sensitive {
258-
!self.raw.contains(value)
259-
} else {
260-
!self.raw.contains(&value.to_lowercase())
261-
}
262-
}
263-
None => true,
264-
}
286+
!self.contains(value)
265287
}
266288
}

crates/core/tests/expression.rs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
use satex_core::expression::Expression;
2+
3+
#[test]
4+
fn equals() {
5+
let expression = Expression::equals("hello", true);
6+
assert!(expression.matches(Some("hello")));
7+
assert!(!expression.matches(Some("Hello")));
8+
assert!(!expression.matches(Some("world")));
9+
assert!(!expression.matches(None));
10+
11+
let expression = Expression::equals("hello", false);
12+
assert!(expression.matches(Some("hello")));
13+
assert!(expression.matches(Some("Hello")));
14+
assert!(!expression.matches(Some("world")));
15+
assert!(!expression.matches(None));
16+
}
17+
18+
#[test]
19+
fn not_equals() {
20+
let expression = Expression::not_equals("hello", true);
21+
assert!(!expression.matches(Some("hello")));
22+
assert!(expression.matches(Some("Hello")));
23+
assert!(expression.matches(Some("world")));
24+
assert!(expression.matches(None));
25+
26+
let expression = Expression::not_equals("hello", false);
27+
assert!(!expression.matches(Some("hello")));
28+
assert!(!expression.matches(Some("Hello")));
29+
assert!(expression.matches(Some("world")));
30+
assert!(expression.matches(None));
31+
}
32+
33+
#[test]
34+
fn starts_with() {
35+
let expression = Expression::starts_with("hello", true);
36+
assert!(expression.matches(Some("hello world")));
37+
assert!(!expression.matches(Some("Hello world")));
38+
assert!(!expression.matches(Some("world")));
39+
assert!(!expression.matches(None));
40+
41+
let expression = Expression::starts_with("hello", false);
42+
assert!(expression.matches(Some("hello world")));
43+
assert!(expression.matches(Some("Hello world")));
44+
assert!(!expression.matches(Some("world")));
45+
assert!(!expression.matches(None));
46+
}
47+
48+
#[test]
49+
fn not_starts_with() {
50+
let expression = Expression::not_starts_with("hello", true);
51+
assert!(!expression.matches(Some("hello world")));
52+
assert!(expression.matches(Some("Hello world")));
53+
assert!(expression.matches(Some("world")));
54+
assert!(expression.matches(None));
55+
56+
let expression = Expression::not_starts_with("hello", false);
57+
assert!(!expression.matches(Some("hello world")));
58+
assert!(!expression.matches(Some("Hello world")));
59+
assert!(expression.matches(Some("world")));
60+
assert!(expression.matches(None));
61+
}
62+
63+
#[test]
64+
fn ends_with() {
65+
let expression = Expression::ends_with("world", true);
66+
assert!(expression.matches(Some("hello world")));
67+
assert!(!expression.matches(Some("hello World")));
68+
assert!(!expression.matches(Some("World")));
69+
assert!(!expression.matches(None));
70+
71+
let expression = Expression::ends_with("world", false);
72+
assert!(expression.matches(Some("hello world")));
73+
assert!(expression.matches(Some("Hello World")));
74+
assert!(expression.matches(Some("World")));
75+
assert!(!expression.matches(None));
76+
}
77+
78+
#[test]
79+
fn not_ends_with() {
80+
let expression = Expression::not_ends_with("world", true);
81+
assert!(!expression.matches(Some("hello world")));
82+
assert!(expression.matches(Some("hello World")));
83+
assert!(expression.matches(Some("World")));
84+
assert!(expression.matches(None));
85+
86+
let expression = Expression::not_ends_with("world", false);
87+
assert!(!expression.matches(Some("hello world")));
88+
assert!(!expression.matches(Some("hello World")));
89+
assert!(!expression.matches(Some("World")));
90+
assert!(expression.matches(None));
91+
}
92+
93+
#[test]
94+
fn contains() {
95+
let expression = Expression::contains("hello", true);
96+
assert!(expression.matches(Some("hello world")));
97+
assert!(!expression.matches(Some("Hello world")));
98+
assert!(!expression.matches(Some("world")));
99+
assert!(!expression.matches(None));
100+
101+
let expression = Expression::contains("hello", false);
102+
assert!(expression.matches(Some("hello world")));
103+
assert!(expression.matches(Some("Hello world")));
104+
assert!(!expression.matches(Some("world")));
105+
assert!(!expression.matches(None));
106+
}
107+
108+
#[test]
109+
fn not_contains() {
110+
let expression = Expression::not_contains("hello", true);
111+
assert!(!expression.matches(Some("hello world")));
112+
assert!(expression.matches(Some("Hello world")));
113+
assert!(expression.matches(Some("world")));
114+
assert!(expression.matches(None));
115+
116+
let expression = Expression::not_contains("hello", false);
117+
assert!(!expression.matches(Some("hello world")));
118+
assert!(!expression.matches(Some("Hello world")));
119+
assert!(expression.matches(Some("world")));
120+
assert!(expression.matches(None));
121+
}
122+
123+
#[test]
124+
fn exists() {
125+
let expression = Expression::exists();
126+
assert!(expression.matches(Some("hello")));
127+
assert!(!expression.matches(None));
128+
}
129+
130+
#[test]
131+
fn not_exists() {
132+
let expression = Expression::not_exists();
133+
assert!(!expression.matches(Some("hello")));
134+
assert!(expression.matches(None));
135+
}
136+
137+
#[test]
138+
fn regex() {
139+
let expression = Expression::regex("^hello$").unwrap();
140+
assert!(expression.matches(Some("hello")));
141+
assert!(!expression.matches(Some("world")));
142+
}

crates/macro/src/make.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub(crate) fn expand(args: Args, input: ItemStruct) -> syn::Result<TokenStream>
2323
.fields
2424
.iter()
2525
.flat_map(|field| &field.ident)
26-
.map(|ident| ident.to_string());
26+
.map(|field| field.to_string().replace("_", "-"));
2727

2828
let make_name = &input.ident;
2929
let generics = input.generics;

crates/matcher/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,8 @@ cookie = { workspace = true }
1616
http = { workspace = true }
1717
matchit = { workspace = true }
1818
qstring = { workspace = true }
19-
serde = { workspace = true, features = ["derive"] }
19+
serde = { workspace = true, features = ["derive"] }
20+
21+
[dev-dependencies]
22+
serde_yaml = { workspace = true }
23+
tokio = { workspace = true, features = ["rt", "macros"] }

crates/matcher/src/query.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ pub struct QueryRouteMatcher {
1515
}
1616

1717
impl QueryRouteMatcher {
18-
pub fn new(name: String, value: Expression) -> Self {
19-
Self { name, value }
18+
pub fn new(name: impl Into<String>, value: Expression) -> Self {
19+
Self {
20+
name: name.into(),
21+
value,
22+
}
2023
}
2124
}
2225

crates/matcher/src/remote_addr.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ fn in_addrs(client_addr: &ClientAddr, addrs: &[(IpAddr, u16)]) -> bool {
5454
match client_addr.ip() {
5555
IpAddr::V4(client_ip) => {
5656
for (addr, cidr) in addrs {
57+
if *cidr == 0 {
58+
return true;
59+
}
5760
match addr {
5861
IpAddr::V4(addr) => {
5962
let mask: [u8; 4] = (-1_i32 << (32 - cidr)).to_be_bytes();
@@ -65,6 +68,9 @@ fn in_addrs(client_addr: &ClientAddr, addrs: &[(IpAddr, u16)]) -> bool {
6568
}
6669
IpAddr::V6(client_ip) => {
6770
for (addr, cidr) in addrs {
71+
if *cidr == 0 {
72+
return true;
73+
}
6874
match addr {
6975
IpAddr::V4(_) => continue,
7076
IpAddr::V6(addr) => {

0 commit comments

Comments
 (0)