Skip to content
This repository was archived by the owner on May 5, 2026. It is now read-only.

Commit d0f3189

Browse files
noahgiftclaude
andcommitted
Add comprehensive tests to constraints, flex, and container modules
- constraints.rs: +40 tests covering serialization, PartialEq, edge cases, builder chains, deflate variations, and bounded checks - flex.rs: +25 tests for FlexDirection, FlexJustify, FlexAlign enums, FlexItem builder, and distribute_flex edge cases - container.rs: +30 tests for builder pattern, measure/layout edge cases, serialization, paint variations, and constraint handling - Added serde_json dev-dependency to presentar-widgets Total: 875 new lines of tests, coverage improved to 89.65%/93.79% 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent cc47271 commit d0f3189

5 files changed

Lines changed: 875 additions & 0 deletions

File tree

Cargo.lock

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

crates/presentar-core/src/constraints.rs

Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,4 +286,354 @@ mod tests {
286286
assert_eq!(deflated.min_width, 0.0);
287287
assert_eq!(deflated.max_width, 0.0);
288288
}
289+
290+
// =========================================================================
291+
// Clone and Copy Trait Tests
292+
// =========================================================================
293+
294+
#[test]
295+
fn test_constraints_clone() {
296+
let c = Constraints::new(10.0, 100.0, 20.0, 200.0);
297+
let cloned = c;
298+
assert_eq!(c, cloned);
299+
}
300+
301+
#[test]
302+
fn test_constraints_copy() {
303+
let c = Constraints::new(10.0, 100.0, 20.0, 200.0);
304+
let copied = c;
305+
// Both should be valid and equal
306+
assert_eq!(c.min_width, copied.min_width);
307+
assert_eq!(c.max_width, copied.max_width);
308+
}
309+
310+
// =========================================================================
311+
// Debug Trait Tests
312+
// =========================================================================
313+
314+
#[test]
315+
fn test_constraints_debug() {
316+
let c = Constraints::new(10.0, 100.0, 20.0, 200.0);
317+
let debug = format!("{:?}", c);
318+
assert!(debug.contains("Constraints"));
319+
assert!(debug.contains("min_width"));
320+
assert!(debug.contains("max_width"));
321+
}
322+
323+
// =========================================================================
324+
// PartialEq Tests
325+
// =========================================================================
326+
327+
#[test]
328+
fn test_constraints_equality() {
329+
let c1 = Constraints::new(10.0, 100.0, 20.0, 200.0);
330+
let c2 = Constraints::new(10.0, 100.0, 20.0, 200.0);
331+
assert_eq!(c1, c2);
332+
}
333+
334+
#[test]
335+
fn test_constraints_inequality_min_width() {
336+
let c1 = Constraints::new(10.0, 100.0, 20.0, 200.0);
337+
let c2 = Constraints::new(15.0, 100.0, 20.0, 200.0);
338+
assert_ne!(c1, c2);
339+
}
340+
341+
#[test]
342+
fn test_constraints_inequality_max_width() {
343+
let c1 = Constraints::new(10.0, 100.0, 20.0, 200.0);
344+
let c2 = Constraints::new(10.0, 150.0, 20.0, 200.0);
345+
assert_ne!(c1, c2);
346+
}
347+
348+
#[test]
349+
fn test_constraints_inequality_min_height() {
350+
let c1 = Constraints::new(10.0, 100.0, 20.0, 200.0);
351+
let c2 = Constraints::new(10.0, 100.0, 25.0, 200.0);
352+
assert_ne!(c1, c2);
353+
}
354+
355+
#[test]
356+
fn test_constraints_inequality_max_height() {
357+
let c1 = Constraints::new(10.0, 100.0, 20.0, 200.0);
358+
let c2 = Constraints::new(10.0, 100.0, 20.0, 250.0);
359+
assert_ne!(c1, c2);
360+
}
361+
362+
// =========================================================================
363+
// Serialization Tests
364+
// =========================================================================
365+
366+
#[test]
367+
fn test_constraints_serialize() {
368+
let c = Constraints::new(10.0, 100.0, 20.0, 200.0);
369+
let json = serde_json::to_string(&c).unwrap();
370+
assert!(json.contains("min_width"));
371+
assert!(json.contains("10"));
372+
}
373+
374+
#[test]
375+
fn test_constraints_deserialize() {
376+
let json = r#"{"min_width":10.0,"max_width":100.0,"min_height":20.0,"max_height":200.0}"#;
377+
let c: Constraints = serde_json::from_str(json).unwrap();
378+
assert_eq!(c.min_width, 10.0);
379+
assert_eq!(c.max_width, 100.0);
380+
assert_eq!(c.min_height, 20.0);
381+
assert_eq!(c.max_height, 200.0);
382+
}
383+
384+
#[test]
385+
fn test_constraints_roundtrip_serialization() {
386+
let original = Constraints::new(15.5, 150.5, 25.5, 250.5);
387+
let json = serde_json::to_string(&original).unwrap();
388+
let deserialized: Constraints = serde_json::from_str(&json).unwrap();
389+
assert_eq!(original, deserialized);
390+
}
391+
392+
// =========================================================================
393+
// Constrain Edge Cases
394+
// =========================================================================
395+
396+
#[test]
397+
fn test_constrain_at_minimum() {
398+
let c = Constraints::new(10.0, 100.0, 20.0, 200.0);
399+
let size = Size::new(10.0, 20.0);
400+
assert_eq!(c.constrain(size), size);
401+
}
402+
403+
#[test]
404+
fn test_constrain_at_maximum() {
405+
let c = Constraints::new(10.0, 100.0, 20.0, 200.0);
406+
let size = Size::new(100.0, 200.0);
407+
assert_eq!(c.constrain(size), size);
408+
}
409+
410+
#[test]
411+
fn test_constrain_zero_size() {
412+
let c = Constraints::new(10.0, 100.0, 20.0, 200.0);
413+
let size = Size::new(0.0, 0.0);
414+
assert_eq!(c.constrain(size), Size::new(10.0, 20.0));
415+
}
416+
417+
#[test]
418+
fn test_constrain_negative_clamped() {
419+
let c = Constraints::new(0.0, 100.0, 0.0, 100.0);
420+
let size = Size::new(-10.0, -20.0);
421+
assert_eq!(c.constrain(size), Size::new(0.0, 0.0));
422+
}
423+
424+
#[test]
425+
fn test_constrain_with_zero_constraints() {
426+
let c = Constraints::new(0.0, 0.0, 0.0, 0.0);
427+
let size = Size::new(100.0, 100.0);
428+
assert_eq!(c.constrain(size), Size::new(0.0, 0.0));
429+
}
430+
431+
// =========================================================================
432+
// is_tight Edge Cases
433+
// =========================================================================
434+
435+
#[test]
436+
fn test_is_tight_width_only() {
437+
let c = Constraints::new(50.0, 50.0, 0.0, 100.0);
438+
assert!(!c.is_tight()); // Height is not tight
439+
}
440+
441+
#[test]
442+
fn test_is_tight_height_only() {
443+
let c = Constraints::new(0.0, 100.0, 50.0, 50.0);
444+
assert!(!c.is_tight()); // Width is not tight
445+
}
446+
447+
#[test]
448+
fn test_is_tight_zero_size() {
449+
let c = Constraints::tight(Size::new(0.0, 0.0));
450+
assert!(c.is_tight());
451+
}
452+
453+
// =========================================================================
454+
// Bounded Tests
455+
// =========================================================================
456+
457+
#[test]
458+
fn test_has_bounded_height_only() {
459+
let c = Constraints::new(0.0, f32::INFINITY, 0.0, 100.0);
460+
assert!(!c.has_bounded_width());
461+
assert!(c.has_bounded_height());
462+
assert!(!c.is_bounded());
463+
}
464+
465+
#[test]
466+
fn test_has_bounded_width_only() {
467+
let c = Constraints::new(0.0, 100.0, 0.0, f32::INFINITY);
468+
assert!(c.has_bounded_width());
469+
assert!(!c.has_bounded_height());
470+
assert!(!c.is_bounded());
471+
}
472+
473+
// =========================================================================
474+
// biggest() Edge Cases
475+
// =========================================================================
476+
477+
#[test]
478+
fn test_biggest_with_infinity_width_only() {
479+
let c = Constraints::new(50.0, f32::INFINITY, 0.0, 100.0);
480+
let biggest = c.biggest();
481+
assert_eq!(biggest.width, 50.0); // Falls back to min
482+
assert_eq!(biggest.height, 100.0);
483+
}
484+
485+
#[test]
486+
fn test_biggest_with_infinity_height_only() {
487+
let c = Constraints::new(0.0, 100.0, 50.0, f32::INFINITY);
488+
let biggest = c.biggest();
489+
assert_eq!(biggest.width, 100.0);
490+
assert_eq!(biggest.height, 50.0); // Falls back to min
491+
}
492+
493+
#[test]
494+
fn test_biggest_tight_constraints() {
495+
let c = Constraints::tight(Size::new(42.0, 24.0));
496+
assert_eq!(c.biggest(), Size::new(42.0, 24.0));
497+
}
498+
499+
// =========================================================================
500+
// smallest() Tests
501+
// =========================================================================
502+
503+
#[test]
504+
fn test_smallest_unbounded() {
505+
let c = Constraints::unbounded();
506+
assert_eq!(c.smallest(), Size::new(0.0, 0.0));
507+
}
508+
509+
#[test]
510+
fn test_smallest_tight() {
511+
let c = Constraints::tight(Size::new(42.0, 24.0));
512+
assert_eq!(c.smallest(), Size::new(42.0, 24.0));
513+
}
514+
515+
#[test]
516+
fn test_smallest_loose() {
517+
let c = Constraints::loose(Size::new(100.0, 200.0));
518+
assert_eq!(c.smallest(), Size::new(0.0, 0.0));
519+
}
520+
521+
// =========================================================================
522+
// with_* Methods Chain Tests
523+
// =========================================================================
524+
525+
#[test]
526+
fn test_with_methods_chained() {
527+
let c = Constraints::unbounded()
528+
.with_min_width(10.0)
529+
.with_max_width(100.0)
530+
.with_min_height(20.0)
531+
.with_max_height(200.0);
532+
533+
assert_eq!(c.min_width, 10.0);
534+
assert_eq!(c.max_width, 100.0);
535+
assert_eq!(c.min_height, 20.0);
536+
assert_eq!(c.max_height, 200.0);
537+
}
538+
539+
#[test]
540+
fn test_with_methods_preserve_other_values() {
541+
let c = Constraints::new(10.0, 100.0, 20.0, 200.0);
542+
543+
let c2 = c.with_min_width(15.0);
544+
assert_eq!(c2.max_width, 100.0);
545+
assert_eq!(c2.min_height, 20.0);
546+
assert_eq!(c2.max_height, 200.0);
547+
548+
let c3 = c.with_max_width(150.0);
549+
assert_eq!(c3.min_width, 10.0);
550+
assert_eq!(c3.min_height, 20.0);
551+
assert_eq!(c3.max_height, 200.0);
552+
}
553+
554+
// =========================================================================
555+
// deflate() Edge Cases
556+
// =========================================================================
557+
558+
#[test]
559+
fn test_deflate_asymmetric() {
560+
let c = Constraints::new(20.0, 100.0, 30.0, 150.0);
561+
let deflated = c.deflate(10.0, 20.0);
562+
assert_eq!(deflated.min_width, 10.0);
563+
assert_eq!(deflated.max_width, 90.0);
564+
assert_eq!(deflated.min_height, 10.0);
565+
assert_eq!(deflated.max_height, 130.0);
566+
}
567+
568+
#[test]
569+
fn test_deflate_zero() {
570+
let c = Constraints::new(10.0, 100.0, 20.0, 200.0);
571+
let deflated = c.deflate(0.0, 0.0);
572+
assert_eq!(c, deflated);
573+
}
574+
575+
#[test]
576+
fn test_deflate_exact_match() {
577+
let c = Constraints::new(10.0, 100.0, 20.0, 200.0);
578+
let deflated = c.deflate(10.0, 20.0);
579+
assert_eq!(deflated.min_width, 0.0);
580+
assert_eq!(deflated.max_width, 90.0);
581+
assert_eq!(deflated.min_height, 0.0);
582+
assert_eq!(deflated.max_height, 180.0);
583+
}
584+
585+
#[test]
586+
fn test_deflate_negative_becomes_zero() {
587+
let c = Constraints::new(5.0, 10.0, 5.0, 10.0);
588+
let deflated = c.deflate(15.0, 15.0);
589+
assert_eq!(deflated.min_width, 0.0);
590+
assert_eq!(deflated.max_width, 0.0);
591+
assert_eq!(deflated.min_height, 0.0);
592+
assert_eq!(deflated.max_height, 0.0);
593+
}
594+
595+
// =========================================================================
596+
// Constructor Edge Cases
597+
// =========================================================================
598+
599+
#[test]
600+
fn test_new_with_zero_values() {
601+
let c = Constraints::new(0.0, 0.0, 0.0, 0.0);
602+
assert_eq!(c.min_width, 0.0);
603+
assert_eq!(c.max_width, 0.0);
604+
assert!(c.is_tight());
605+
}
606+
607+
#[test]
608+
fn test_tight_with_large_values() {
609+
let c = Constraints::tight(Size::new(10000.0, 10000.0));
610+
assert!(c.is_tight());
611+
assert_eq!(c.biggest(), Size::new(10000.0, 10000.0));
612+
}
613+
614+
#[test]
615+
fn test_loose_with_zero() {
616+
let c = Constraints::loose(Size::new(0.0, 0.0));
617+
assert!(c.is_tight()); // min and max are both 0
618+
assert_eq!(c.biggest(), Size::new(0.0, 0.0));
619+
}
620+
621+
// =========================================================================
622+
// Default Trait Tests
623+
// =========================================================================
624+
625+
#[test]
626+
fn test_default_is_unbounded() {
627+
let default = Constraints::default();
628+
let unbounded = Constraints::unbounded();
629+
assert_eq!(default, unbounded);
630+
}
631+
632+
#[test]
633+
fn test_default_not_bounded() {
634+
let c = Constraints::default();
635+
assert!(!c.is_bounded());
636+
assert!(!c.has_bounded_width());
637+
assert!(!c.has_bounded_height());
638+
}
289639
}

0 commit comments

Comments
 (0)