Skip to content

Commit da1d142

Browse files
committed
Tidy up checkorder madness, make siblings work in WASM
1 parent 10430e5 commit da1d142

File tree

5 files changed

+111
-84
lines changed

5 files changed

+111
-84
lines changed

fontspector-checkapi/src/context.rs

+23
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,26 @@ pub struct Context {
66
pub network_timeout: Option<u64>,
77
pub configuration: Map<String, Value>,
88
}
9+
10+
impl Context {
11+
/// Extract a specialized context for a specific check using a configuration map
12+
///
13+
/// For example, if the check is `googlefonts/has_metadata`, the configuration map
14+
/// will be searched for a key `googlefonts/has_metadata` and the value will be used
15+
/// as the configuration for this check.
16+
pub fn specialize(
17+
&self,
18+
checkname: &str,
19+
configuration: &Map<String, serde_json::Value>,
20+
) -> Self {
21+
Context {
22+
skip_network: self.skip_network,
23+
network_timeout: self.network_timeout,
24+
configuration: configuration
25+
.get(checkname)
26+
.and_then(|x| x.as_object())
27+
.cloned()
28+
.unwrap_or_default(),
29+
}
30+
}
31+
}

fontspector-checkapi/src/profile.rs

+57-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use serde::{Deserialize, Serialize};
2+
use serde_json::Map;
23

3-
use crate::{CheckId, Registry, StatusCode};
4+
use crate::{Check, CheckId, Context, Registry, StatusCode, TestableType};
45
use std::collections::HashMap;
56

67
#[derive(Serialize, Deserialize)]
@@ -70,4 +71,59 @@ impl Profile {
7071
}
7172
Ok(())
7273
}
74+
75+
pub fn check_order<'t, 'r>(
76+
&self,
77+
include_checks: &Option<Vec<String>>,
78+
exclude_checks: &Option<Vec<String>>,
79+
registry: &'r Registry<'r>,
80+
general_context: Context,
81+
configuration: Map<String, serde_json::Value>,
82+
testables: &'t Vec<TestableType>,
83+
) -> Vec<(String, &'t TestableType<'t>, &'r Check<'r>, Context)> {
84+
self.sections
85+
.iter()
86+
.flat_map(|(sectionname, checknames)| {
87+
#[allow(clippy::unwrap_used)]
88+
// We previously ensured the check exists in the registry
89+
checknames
90+
.iter()
91+
.filter(|checkname| {
92+
included_excluded(checkname, include_checks, exclude_checks)
93+
})
94+
.map(|checkname| {
95+
(
96+
sectionname.clone(),
97+
registry.checks.get(checkname).unwrap(),
98+
general_context.specialize(checkname, &configuration),
99+
)
100+
})
101+
})
102+
.flat_map(|(sectionname, check, context): (String, &Check, Context)| {
103+
testables
104+
.iter()
105+
.filter(|testable| check.applies(testable, registry))
106+
.map(move |testable| (sectionname.clone(), testable, check, context.clone()))
107+
})
108+
.collect()
109+
}
110+
}
111+
112+
/// Filter out checks that don't apply
113+
fn included_excluded(
114+
checkname: &str,
115+
include_checks: &Option<Vec<String>>,
116+
exclude_checks: &Option<Vec<String>>,
117+
) -> bool {
118+
if let Some(checkids) = &include_checks {
119+
if !checkids.iter().any(|id| checkname.contains(id)) {
120+
return false;
121+
}
122+
}
123+
if let Some(exclude_checkids) = &exclude_checks {
124+
if exclude_checkids.iter().any(|id| checkname.contains(id)) {
125+
return false;
126+
}
127+
}
128+
true
73129
}

fontspector-checkapi/src/testable.rs

+4
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ impl TestableCollection {
9494
})
9595
}
9696

97+
pub fn from_testables(testables: Vec<Testable>) -> Self {
98+
Self { testables }
99+
}
100+
97101
pub fn iter(&self) -> impl Iterator<Item = &Testable> {
98102
self.testables.iter()
99103
}

fontspector-cli/src/main.rs

+12-54
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,6 @@ use reporters::{
2121
};
2222
use serde_json::Map;
2323

24-
/// Filter out checks that don't apply
25-
fn included_excluded(checkname: &str, args: &Args) -> bool {
26-
if let Some(checkids) = &args.checkid {
27-
if !checkids.iter().any(|id| checkname.contains(id)) {
28-
return false;
29-
}
30-
}
31-
if let Some(exclude_checkids) = &args.exclude_checkid {
32-
if exclude_checkids.iter().any(|id| checkname.contains(id)) {
33-
return false;
34-
}
35-
}
36-
true
37-
}
38-
3924
fn main() {
4025
// Command line handling
4126
let args = Args::parse();
@@ -112,29 +97,18 @@ fn main() {
11297
let configuration: Map<String, serde_json::Value> = load_configuration(&args);
11398

11499
// Establish a check order
115-
let checkorder: Vec<(String, &TestableType, &Check, Context)> = profile
116-
.sections
117-
.iter()
118-
.flat_map(|(sectionname, checknames)| {
119-
#[allow(clippy::unwrap_used)] // We previously ensured the check exists in the registry
120-
checknames
121-
.iter()
122-
.filter(|checkname| included_excluded(checkname, &args))
123-
.map(|checkname| {
124-
(
125-
sectionname.clone(),
126-
registry.checks.get(checkname).unwrap(),
127-
context_for(checkname, &args, &configuration),
128-
)
129-
})
130-
})
131-
.flat_map(|(sectionname, check, context): (String, &Check, Context)| {
132-
testables
133-
.iter()
134-
.filter(|testable| check.applies(testable, &registry))
135-
.map(move |testable| (sectionname.clone(), testable, check, context.clone()))
136-
})
137-
.collect();
100+
let checkorder: Vec<(String, &TestableType, &Check, Context)> = profile.check_order(
101+
&args.checkid,
102+
&args.exclude_checkid,
103+
&registry,
104+
Context {
105+
skip_network: args.skip_network,
106+
network_timeout: Some(10), // XXX
107+
configuration: Map::new(),
108+
},
109+
configuration,
110+
&testables,
111+
);
138112

139113
// The testables are the collection object plus the files; only count the files.
140114
let count_of_files = testables.iter().filter(|x| x.is_single()).count();
@@ -246,19 +220,3 @@ fn load_configuration(args: &Args) -> Map<String, serde_json::Value> {
246220
})
247221
.unwrap_or_default()
248222
}
249-
250-
fn context_for(
251-
checkname: &str,
252-
args: &Args,
253-
configuration: &Map<String, serde_json::Value>,
254-
) -> Context {
255-
Context {
256-
skip_network: args.skip_network,
257-
network_timeout: args.timeout,
258-
configuration: configuration
259-
.get(checkname)
260-
.and_then(|x| x.as_object())
261-
.cloned()
262-
.unwrap_or_default(),
263-
}
264-
}

fontspector-web/src/lib.rs

+15-29
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use js_sys::{Reflect, Uint8Array};
22
use wasm_bindgen::prelude::*;
33
extern crate console_error_panic_hook;
4-
use fontspector_checkapi::{Check, CheckResult, Context, Plugin, Registry, Testable};
4+
use fontspector_checkapi::{
5+
Check, CheckResult, Context, Plugin, Registry, Testable, TestableCollection, TestableType,
6+
};
57
use profile_googlefonts::GoogleFonts;
68
use profile_universal::Universal;
79

@@ -32,45 +34,29 @@ pub fn check_fonts(fonts: &JsValue) -> Result<String, JsValue> {
3234
}
3335
})
3436
.collect();
37+
let collection = TestableCollection::from_testables(testables);
38+
3539
let profile = registry.get_profile("googlefonts").unwrap();
3640
let context = Context {
3741
skip_network: true,
3842
network_timeout: None,
3943
configuration: serde_json::Map::new(),
4044
};
45+
let all_testables = collection.collection_and_files().collect();
4146

42-
let checkorder: Vec<(String, &Testable, &Check, Context)> = profile
43-
.sections
44-
.iter()
45-
.flat_map(|(sectionname, checknames)| {
46-
#[allow(clippy::unwrap_used)] // We previously ensured the check exists in the registry
47-
checknames
48-
.iter()
49-
// .filter(|checkname| included_excluded(checkname, &args))
50-
.map(|checkname| {
51-
(
52-
sectionname.clone(),
53-
registry.checks.get(checkname).unwrap(),
54-
context.clone(),
55-
)
56-
})
57-
})
58-
.flat_map(|(sectionname, check, context): (String, &Check, Context)| {
59-
testables
60-
.iter()
61-
.filter(|testable| check.applies(testable, &registry))
62-
.map(move |testable| (sectionname.clone(), testable, check, context.clone()))
63-
})
64-
.collect();
47+
let checkorder: Vec<(String, &TestableType, &Check, Context)> = profile.check_order(
48+
&None,
49+
&None,
50+
&registry,
51+
context,
52+
serde_json::Map::new(),
53+
&all_testables,
54+
);
6555

6656
let results: Vec<CheckResult> = checkorder
6757
.iter()
6858
.map(|(sectionname, testable, check, context)| {
69-
(
70-
testable,
71-
check,
72-
check.run_one(testable, context, sectionname),
73-
)
59+
(testable, check, check.run(testable, context, sectionname))
7460
})
7561
.flat_map(|(_, _, result)| result)
7662
.collect();

0 commit comments

Comments
 (0)