OpenPay (1 crate, 1801 LOC, 57 tests)
op-bin BIN/IIN database + range matching + card-network
classification. 8-digit normalized prefix Bin +
BinRange. Sorted-vec interval tree with O(log N) point
lookup + overlap rejection. CardNetwork classify()
with structural rules (Visa 4, MC 51-55/2221-2720,
Amex 34/37, Discover, JCB, Diners, UnionPay, RuPay,
Mir, Troy, Maestro, Elo). Static prefix tables +
build_default_tree(). ISO/IEC 7812-1 Annex B Luhn
(validate / is_valid / check_digit). Card-type +
issuer-country + Durbin regulated-debit. PCI-safe:
8-digit cap, no full-PAN APIs.
Smart Byte (1 crate, ~1500 LOC, 20 tests)
smart-byte-tendermint BFT consensus. Step enum + Round + propose/prevote/
precommit/commit FSM with voting-power tallies.
ValidatorSet with 2/3+1 quorum, 1/3+1 trust
threshold, round-robin proposer. Block / Header /
Commit / CommitSig with Blake3 hashing. Light client
(sequential + skipping). ABCI Application trait +
EchoApp. DuplicateVoteEvidence + LightClientAttackEvidence.
IBC ClientState + ConsensusState + light-client
update.
EOC (1 crate, 2084 LOC, 23 tests)
eoc-safety AI safety primitives. RegexSet over 16 prompt-injection
signatures. 13-family jailbreak detector (DAN/DUDE/
Grandma/STAN/AIM/dev-mode/etc.). Presidio-style PII
redactor with Luhn-validated CC. Toxicity / bias /
NSFW classifier traits + heuristic baselines (5-axis
bias, 4-category NSFW with hard-reject for minors).
Constitutional AI critique→revise loop. Composable
InputGuard / OutputGuard pipelines. JSON-Schema-subset
output validator. Token-bucket rate limiter +
abuse-window detection. Red-team replay harness.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
83 lines
2.4 KiB
Rust
83 lines
2.4 KiB
Rust
//! Structured-output validator tests.
|
|
|
|
use eoc_safety::structure::{validate, validate_string};
|
|
use serde_json::json;
|
|
|
|
#[test]
|
|
fn valid_object_passes() {
|
|
let schema = json!({
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {"type": "string", "minLength": 1},
|
|
"age": {"type": "integer", "minimum": 0, "maximum": 150}
|
|
},
|
|
"required": ["name", "age"],
|
|
"additionalProperties": false
|
|
});
|
|
let value = json!({"name": "Alice", "age": 30});
|
|
let report = validate(&value, &schema);
|
|
assert!(report.valid, "errors: {:?}", report.errors);
|
|
}
|
|
|
|
#[test]
|
|
fn missing_required_field_fails() {
|
|
let schema = json!({
|
|
"type": "object",
|
|
"properties": {"name": {"type": "string"}},
|
|
"required": ["name"]
|
|
});
|
|
let value = json!({});
|
|
let report = validate(&value, &schema);
|
|
assert!(!report.valid);
|
|
assert!(report.errors.iter().any(|e| e.message.contains("required")));
|
|
}
|
|
|
|
#[test]
|
|
fn wrong_type_fails() {
|
|
let schema = json!({"type": "integer"});
|
|
let value = json!("not an int");
|
|
let report = validate(&value, &schema);
|
|
assert!(!report.valid);
|
|
}
|
|
|
|
#[test]
|
|
fn additional_property_rejected() {
|
|
let schema = json!({
|
|
"type": "object",
|
|
"properties": {"a": {"type": "string"}},
|
|
"additionalProperties": false
|
|
});
|
|
let value = json!({"a": "x", "b": "y"});
|
|
let report = validate(&value, &schema);
|
|
assert!(!report.valid);
|
|
assert!(report.errors.iter().any(|e| e.path.ends_with("/b")));
|
|
}
|
|
|
|
#[test]
|
|
fn enum_matches() {
|
|
let schema = json!({"enum": ["red", "green", "blue"]});
|
|
assert!(validate(&json!("red"), &schema).valid);
|
|
assert!(!validate(&json!("purple"), &schema).valid);
|
|
}
|
|
|
|
#[test]
|
|
fn string_pattern_enforced() {
|
|
let schema = json!({"type": "string", "pattern": "^\\d{3}-\\d{4}$"});
|
|
assert!(validate(&json!("555-1234"), &schema).valid);
|
|
assert!(!validate(&json!("nope"), &schema).valid);
|
|
}
|
|
|
|
#[test]
|
|
fn validate_string_returns_value() {
|
|
let schema = json!({"type": "object", "properties": {"x": {"type": "integer"}}});
|
|
let v = validate_string(r#"{"x": 7}"#, &schema).expect("ok");
|
|
assert_eq!(v["x"], json!(7));
|
|
}
|
|
|
|
#[test]
|
|
fn validate_string_surfaces_error() {
|
|
let schema = json!({"type": "object", "required": ["x"]});
|
|
let err = validate_string("{}", &schema).expect_err("must err");
|
|
let msg = format!("{err}");
|
|
assert!(msg.contains("invalid"), "got: {msg}");
|
|
}
|