From 42123f7765417c835419c02c9503d2eaeea49c7e Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 30 Jun 2014 21:30:39 -0700 Subject: [PATCH] Extract tests to a separate crate This ensures that we're only testing public API and speeds up the development process. --- Cargo.toml | 2 +- Makefile.in | 9 +- src/{ => lib}/error.rs | 0 src/{ => lib}/io.rs | 0 src/{ => lib}/lib.rs | 2 - src/{ => lib}/message.rs | 0 src/{ => lib}/pool.rs | 0 src/{ => lib}/types/array.rs | 141 ----------------------- src/{ => lib}/types/mod.rs | 0 src/{ => lib}/types/range.rs | 0 src/{ => test}/test.rs | 70 +++++++----- src/test/types/array.rs | 137 ++++++++++++++++++++++ src/test/types/mod.rs | 2 + src/test/types/range.rs | 213 +++++++++++++++++++++++++++++++++++ 14 files changed, 397 insertions(+), 179 deletions(-) rename src/{ => lib}/error.rs (100%) rename src/{ => lib}/io.rs (100%) rename src/{ => lib}/lib.rs (99%) rename src/{ => lib}/message.rs (100%) rename src/{ => lib}/pool.rs (100%) rename src/{ => lib}/types/array.rs (75%) rename src/{ => lib}/types/mod.rs (100%) rename src/{ => lib}/types/range.rs (100%) rename src/{ => test}/test.rs (96%) create mode 100644 src/test/types/array.rs create mode 100644 src/test/types/mod.rs create mode 100644 src/test/types/range.rs diff --git a/Cargo.toml b/Cargo.toml index 12e99ab4..4e615422 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ authors = [ "Steven Fackler " ] [[lib]] name = "postgres" -path = "src/lib.rs" +path = "src/lib/lib.rs" [dependencies.openssl] diff --git a/Makefile.in b/Makefile.in index dd0d74de..4fd3533b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -23,9 +23,10 @@ $(OPENSSL): | $(BUILDDIR) ############################################################################### # Main targets ############################################################################### -POSTGRES_LIB_FILE := src/lib.rs +POSTGRES_LIB_FILE := src/lib/lib.rs POSTGRES_LIB := $(foreach file,$(shell $(RUSTC) --crate-file-name $(POSTGRES_LIB_FILE)),$(BUILDDIR)/$(file)) -POSTGRES_TEST := $(BUILDDIR)/$(shell $(RUSTC) --test --crate-file-name $(POSTGRES_LIB_FILE)) +POSTGRES_TEST_FILE := src/test/test.rs +POSTGRES_TEST := $(BUILDDIR)/$(shell $(RUSTC) --test --crate-file-name $(POSTGRES_TEST_FILE)) POSTGRES_LIB_DEPS := $(BUILDDIR)/postgres.d POSTGRES_TEST_DEPS := $(BUILDDIR)/postgres_test.d @@ -43,8 +44,8 @@ $(POSTGRES_LIB): $(POSTGRES_LIB_FILE) $(PHF) $(OPENSSL) | $(BUILDDIR) $(RUSTC) $(RUSTFLAGS) $(LINK_ARGS) --dep-info $(POSTGRES_LIB_DEPS) \ --out-dir $(@D) $< -$(POSTGRES_TEST): $(POSTGRES_LIB_FILE) $(PHF) $(OPENSSL) | $(BUILDDIR) - $(RUSTC) $(RUSTFLAGS) $(LINK_ARGS) --dep-info $(POSTGRES_TEST_DEPS) \ +$(POSTGRES_TEST): $(POSTGRES_TEST_FILE) $(POSTGRES_LIB) | $(BUILDDIR) + $(RUSTC) $(RUSTFLAGS) $(LINK_ARGS) -L $(BUILDDIR) --dep-info $(POSTGRES_TEST_DEPS) \ --out-dir $(@D) --test $< all: $(POSTGRES_LIB) diff --git a/src/error.rs b/src/lib/error.rs similarity index 100% rename from src/error.rs rename to src/lib/error.rs diff --git a/src/io.rs b/src/lib/io.rs similarity index 100% rename from src/io.rs rename to src/lib/io.rs diff --git a/src/lib.rs b/src/lib/lib.rs similarity index 99% rename from src/lib.rs rename to src/lib/lib.rs index 493f3d6c..55b883f0 100644 --- a/src/lib.rs +++ b/src/lib/lib.rs @@ -192,8 +192,6 @@ mod io; pub mod pool; mod message; pub mod types; -#[cfg(test)] -mod test; static CANARY: u32 = 0xdeadbeef; diff --git a/src/message.rs b/src/lib/message.rs similarity index 100% rename from src/message.rs rename to src/lib/message.rs diff --git a/src/pool.rs b/src/lib/pool.rs similarity index 100% rename from src/pool.rs rename to src/lib/pool.rs diff --git a/src/types/array.rs b/src/lib/types/array.rs similarity index 75% rename from src/types/array.rs rename to src/lib/types/array.rs index 77246b86..4095f17d 100644 --- a/src/types/array.rs +++ b/src/lib/types/array.rs @@ -338,144 +338,3 @@ impl<'parent, T> InternalMutableArray for MutArraySlice<'parent, T> { } } } - -#[cfg(test)] -mod tests { - use super::{DimensionInfo, ArrayBase, Array, MutableArray}; - - #[test] - fn test_from_vec() { - let a = ArrayBase::from_vec(vec!(0i, 1, 2), -1); - assert!([DimensionInfo { len: 3, lower_bound: -1 }] == - a.dimension_info()); - assert_eq!(&0, a.get(-1)); - assert_eq!(&1, a.get(0)); - assert_eq!(&2, a.get(1)); - } - - #[test] - #[should_fail] - fn test_get_2d_fail() { - let mut a = ArrayBase::from_vec(vec!(0i, 1, 2), -1); - a.wrap(1); - a.get(1); - } - - #[test] - #[should_fail] - fn test_2d_slice_range_fail_low() { - let mut a = ArrayBase::from_vec(vec!(0i, 1, 2), -1); - a.wrap(1); - a.slice(0); - } - - #[test] - #[should_fail] - fn test_2d_slice_range_fail_high() { - let mut a = ArrayBase::from_vec(vec!(0i, 1, 2), -1); - a.wrap(1); - a.slice(2); - } - - #[test] - fn test_2d_slice_get() { - let mut a = ArrayBase::from_vec(vec!(0i, 1, 2), -1); - a.wrap(1); - let s = a.slice(1); - assert_eq!(&0, s.get(-1)); - assert_eq!(&1, s.get(0)); - assert_eq!(&2, s.get(1)); - } - - #[test] - #[should_fail] - fn test_push_move_wrong_lower_bound() { - let mut a = ArrayBase::from_vec(vec!(1i), -1); - a.push_move(ArrayBase::from_vec(vec!(2), 0)); - } - - #[test] - #[should_fail] - fn test_push_move_wrong_dims() { - let mut a = ArrayBase::from_vec(vec!(1i), -1); - a.wrap(1); - a.push_move(ArrayBase::from_vec(vec!(1, 2), -1)); - } - - #[test] - #[should_fail] - fn test_push_move_wrong_dim_count() { - let mut a = ArrayBase::from_vec(vec!(1i), -1); - a.wrap(1); - let mut b = ArrayBase::from_vec(vec!(2), -1); - b.wrap(1); - a.push_move(b); - } - - #[test] - fn test_push_move_ok() { - let mut a = ArrayBase::from_vec(vec!(1i, 2), 0); - a.wrap(0); - a.push_move(ArrayBase::from_vec(vec!(3, 4), 0)); - let s = a.slice(0); - assert_eq!(&1, s.get(0)); - assert_eq!(&2, s.get(1)); - let s = a.slice(1); - assert_eq!(&3, s.get(0)); - assert_eq!(&4, s.get(1)); - } - - #[test] - fn test_3d() { - let mut a = ArrayBase::from_vec(vec!(0i, 1), 0); - a.wrap(0); - a.push_move(ArrayBase::from_vec(vec!(2, 3), 0)); - a.wrap(0); - let mut b = ArrayBase::from_vec(vec!(4, 5), 0); - b.wrap(0); - b.push_move(ArrayBase::from_vec(vec!(6, 7), 0)); - a.push_move(b); - let s1 = a.slice(0); - let s2 = s1.slice(0); - assert_eq!(&0, s2.get(0)); - assert_eq!(&1, s2.get(1)); - let s2 = s1.slice(1); - assert_eq!(&2, s2.get(0)); - assert_eq!(&3, s2.get(1)); - let s1 = a.slice(1); - let s2 = s1.slice(0); - assert_eq!(&4, s2.get(0)); - assert_eq!(&5, s2.get(1)); - let s2 = s1.slice(1); - assert_eq!(&6, s2.get(0)); - assert_eq!(&7, s2.get(1)); - } - - #[test] - fn test_mut() { - let mut a = ArrayBase::from_vec(vec!(1i, 2), 0); - a.wrap(0); - { - let mut s = a.slice_mut(0); - *s.get_mut(0) = 3; - } - let s = a.slice(0); - assert_eq!(&3, s.get(0)); - } - - #[test] - #[should_fail] - fn test_base_overslice() { - let a = ArrayBase::from_vec(vec!(1i), 0); - a.slice(0); - } - - #[test] - #[should_fail] - fn test_slice_overslice() { - let mut a = ArrayBase::from_vec(vec!(1i), 0); - a.wrap(0); - let s = a.slice(0); - s.slice(0); - } -} diff --git a/src/types/mod.rs b/src/lib/types/mod.rs similarity index 100% rename from src/types/mod.rs rename to src/lib/types/mod.rs diff --git a/src/types/range.rs b/src/lib/types/range.rs similarity index 100% rename from src/types/range.rs rename to src/lib/types/range.rs diff --git a/src/test.rs b/src/test/test.rs similarity index 96% rename from src/test.rs rename to src/test/test.rs index 1b8b0563..3a080762 100644 --- a/src/test.rs +++ b/src/test/test.rs @@ -1,7 +1,16 @@ +#![feature(macro_rules, phase)] + +#[phase(plugin, link)] +extern crate postgres; +extern crate serialize; +extern crate time; +extern crate url; +extern crate uuid; +extern crate openssl; + use serialize::json; use std::comm; use std::sync::Future; -use time; use time::Timespec; use uuid::Uuid; use openssl::ssl::{SslContext, Sslv3}; @@ -9,35 +18,34 @@ use std::collections::HashMap; use std::f32; use std::f64; use std::io::timer; -use url; -use {PostgresNoticeHandler, - PostgresNotification, - PostgresConnection, - ResultDescription, - RequireSsl, - PreferSsl, - NoSsl}; -use error::{PgConnectDbError, - PgDbError, - PgWrongConnection, - PgWrongParamCount, - PgWrongType, - PgInvalidColumn, - PgWasNull, - MissingPassword, - Position, - PostgresDbError, - SyntaxError, - InvalidPassword, - QueryCanceled, - UndefinedTable, - InvalidCatalogName, - PgWrongTransaction}; -use types::{ToSql, FromSql, PgInt4, PgVarchar}; -use types::array::{ArrayBase}; -use types::range::{Range, Inclusive, Exclusive, RangeBound}; -use pool::PostgresConnectionPool; +use postgres::{PostgresNoticeHandler, + PostgresNotification, + PostgresConnection, + ResultDescription, + RequireSsl, + PreferSsl, + NoSsl}; +use postgres::error::{PgConnectDbError, + PgDbError, + PgWrongConnection, + PgWrongParamCount, + PgWrongType, + PgInvalidColumn, + PgWasNull, + MissingPassword, + Position, + PostgresDbError, + SyntaxError, + InvalidPassword, + QueryCanceled, + UndefinedTable, + InvalidCatalogName, + PgWrongTransaction}; +use postgres::types::{ToSql, FromSql, PgInt4, PgVarchar}; +use postgres::types::array::{ArrayBase}; +use postgres::types::range::{Range, Inclusive, Exclusive, RangeBound}; +use postgres::pool::PostgresConnectionPool; macro_rules! or_fail( ($e:expr) => ( @@ -966,8 +974,8 @@ fn test_cancel_query() { spawn(proc() { timer::sleep(500); - assert!(super::cancel_query("postgres://postgres@localhost", &NoSsl, - cancel_data).is_ok()); + assert!(postgres::cancel_query("postgres://postgres@localhost", &NoSsl, + cancel_data).is_ok()); }); match conn.execute("SELECT pg_sleep(10)", []) { diff --git a/src/test/types/array.rs b/src/test/types/array.rs new file mode 100644 index 00000000..82351b0f --- /dev/null +++ b/src/test/types/array.rs @@ -0,0 +1,137 @@ +use postgres::types::array::{DimensionInfo, ArrayBase, Array, MutableArray}; + +#[test] +fn test_from_vec() { + let a = ArrayBase::from_vec(vec!(0i, 1, 2), -1); + assert!([DimensionInfo { len: 3, lower_bound: -1 }] == + a.dimension_info()); + assert_eq!(&0, a.get(-1)); + assert_eq!(&1, a.get(0)); + assert_eq!(&2, a.get(1)); +} + +#[test] +#[should_fail] +fn test_get_2d_fail() { + let mut a = ArrayBase::from_vec(vec!(0i, 1, 2), -1); + a.wrap(1); + a.get(1); +} + +#[test] +#[should_fail] +fn test_2d_slice_range_fail_low() { + let mut a = ArrayBase::from_vec(vec!(0i, 1, 2), -1); + a.wrap(1); + a.slice(0); +} + +#[test] +#[should_fail] +fn test_2d_slice_range_fail_high() { + let mut a = ArrayBase::from_vec(vec!(0i, 1, 2), -1); + a.wrap(1); + a.slice(2); +} + +#[test] +fn test_2d_slice_get() { + let mut a = ArrayBase::from_vec(vec!(0i, 1, 2), -1); + a.wrap(1); + let s = a.slice(1); + assert_eq!(&0, s.get(-1)); + assert_eq!(&1, s.get(0)); + assert_eq!(&2, s.get(1)); +} + +#[test] +#[should_fail] +fn test_push_move_wrong_lower_bound() { + let mut a = ArrayBase::from_vec(vec!(1i), -1); + a.push_move(ArrayBase::from_vec(vec!(2), 0)); +} + +#[test] +#[should_fail] +fn test_push_move_wrong_dims() { + let mut a = ArrayBase::from_vec(vec!(1i), -1); + a.wrap(1); + a.push_move(ArrayBase::from_vec(vec!(1, 2), -1)); +} + +#[test] +#[should_fail] +fn test_push_move_wrong_dim_count() { + let mut a = ArrayBase::from_vec(vec!(1i), -1); + a.wrap(1); + let mut b = ArrayBase::from_vec(vec!(2), -1); + b.wrap(1); + a.push_move(b); +} + +#[test] +fn test_push_move_ok() { + let mut a = ArrayBase::from_vec(vec!(1i, 2), 0); + a.wrap(0); + a.push_move(ArrayBase::from_vec(vec!(3, 4), 0)); + let s = a.slice(0); + assert_eq!(&1, s.get(0)); + assert_eq!(&2, s.get(1)); + let s = a.slice(1); + assert_eq!(&3, s.get(0)); + assert_eq!(&4, s.get(1)); +} + +#[test] +fn test_3d() { + let mut a = ArrayBase::from_vec(vec!(0i, 1), 0); + a.wrap(0); + a.push_move(ArrayBase::from_vec(vec!(2, 3), 0)); + a.wrap(0); + let mut b = ArrayBase::from_vec(vec!(4, 5), 0); + b.wrap(0); + b.push_move(ArrayBase::from_vec(vec!(6, 7), 0)); + a.push_move(b); + let s1 = a.slice(0); + let s2 = s1.slice(0); + assert_eq!(&0, s2.get(0)); + assert_eq!(&1, s2.get(1)); + let s2 = s1.slice(1); + assert_eq!(&2, s2.get(0)); + assert_eq!(&3, s2.get(1)); + let s1 = a.slice(1); + let s2 = s1.slice(0); + assert_eq!(&4, s2.get(0)); + assert_eq!(&5, s2.get(1)); + let s2 = s1.slice(1); + assert_eq!(&6, s2.get(0)); + assert_eq!(&7, s2.get(1)); +} + +#[test] +fn test_mut() { + let mut a = ArrayBase::from_vec(vec!(1i, 2), 0); + a.wrap(0); + { + let mut s = a.slice_mut(0); + *s.get_mut(0) = 3; + } + let s = a.slice(0); + assert_eq!(&3, s.get(0)); +} + +#[test] +#[should_fail] +fn test_base_overslice() { + let a = ArrayBase::from_vec(vec!(1i), 0); + a.slice(0); +} + +#[test] +#[should_fail] +fn test_slice_overslice() { + let mut a = ArrayBase::from_vec(vec!(1i), 0); + a.wrap(0); + let s = a.slice(0); + s.slice(0); +} diff --git a/src/test/types/mod.rs b/src/test/types/mod.rs new file mode 100644 index 00000000..f1bf40e6 --- /dev/null +++ b/src/test/types/mod.rs @@ -0,0 +1,2 @@ +mod array; +mod range; diff --git a/src/test/types/range.rs b/src/test/types/range.rs new file mode 100644 index 00000000..b055385e --- /dev/null +++ b/src/test/types/range.rs @@ -0,0 +1,213 @@ +use std::i32; + +use postgres::types::range::{RangeBound, + Range, + Inclusive, + Exclusive, + UpperBound, + LowerBound, + Normalizable, + BoundType}; + +#[test] +fn test_range_bound_lower_lt() { + fn check(val1: int, inc1: BoundType, val2: int, inc2: BoundType, expected: bool) { + let a: RangeBound = RangeBound::new(val1, inc1); + let b: RangeBound = RangeBound::new(val2, inc2); + assert_eq!(expected, a < b); + } + + check(1, Inclusive, 2, Exclusive, true); + check(1, Exclusive, 2, Inclusive, true); + check(1, Inclusive, 1, Exclusive, true); + check(2, Inclusive, 1, Inclusive, false); + check(2, Exclusive, 1, Exclusive, false); + check(1, Exclusive, 1, Inclusive, false); + check(1, Exclusive, 1, Exclusive, false); + check(1, Inclusive, 1, Inclusive, false); +} + +#[test] +fn test_range_bound_upper_lt() { + fn check(val1: int, inc1: BoundType, val2: int, inc2: BoundType, expected: bool) { + let a: RangeBound = RangeBound::new(val1, inc1); + let b: RangeBound = RangeBound::new(val2, inc2); + assert_eq!(expected, a < b); + } + + check(1, Inclusive, 2, Exclusive, true); + check(1, Exclusive, 2, Exclusive, true); + check(1, Exclusive, 1, Inclusive, true); + check(2, Inclusive, 1, Inclusive, false); + check(2, Exclusive, 1, Exclusive, false); + check(1, Inclusive, 1, Exclusive, false); + check(1, Inclusive, 1, Inclusive, false); + check(1, Exclusive, 1, Exclusive, false); +} + +#[test] +fn test_range_bound_lower_in_bounds() { + fn check(bound: int, inc: BoundType, val: int, expected: bool) { + let b: RangeBound = RangeBound::new(bound, inc); + assert_eq!(expected, b.in_bounds(&val)); + } + + check(1, Inclusive, 1, true); + check(1, Exclusive, 1, false); + check(1, Inclusive, 2, true); + check(1, Inclusive, 0, false); +} + +#[test] +fn test_range_bound_upper_in_bounds() { + fn check(bound: int, inc: BoundType, val: int, expected: bool) { + let b: RangeBound = RangeBound::new(bound, inc); + assert_eq!(expected, b.in_bounds(&val)); + } + + check(1, Inclusive, 1, true); + check(1, Exclusive, 1, false); + check(1, Inclusive, 2, false); + check(1, Inclusive, 0, true); +} + +#[test] +fn test_range_contains() { + let r = range!('[' 1i32, 3i32 ']'); + assert!(!r.contains(&4)); + assert!(r.contains(&3)); + assert!(r.contains(&2)); + assert!(r.contains(&1)); + assert!(!r.contains(&0)); + + let r = range!('(' 1i32, 3i32 ')'); + assert!(!r.contains(&4)); + assert!(!r.contains(&3)); + assert!(r.contains(&2)); + assert!(!r.contains(&1)); + assert!(!r.contains(&0)); + + let r = range!('(', 3i32 ']'); + assert!(!r.contains(&4)); + assert!(r.contains(&2)); + assert!(r.contains(&i32::MIN)); + + let r = range!('[' 1i32, ')'); + assert!(r.contains(&i32::MAX)); + assert!(r.contains(&4)); + assert!(!r.contains(&0)); + + let r = range!('(', ')'); + assert!(r.contains(&i32::MAX)); + assert!(r.contains(&0i32)); + assert!(r.contains(&i32::MIN)); +} + +#[test] +fn test_normalize_lower() { + let r: RangeBound = RangeBound::new(10i32, Inclusive); + assert_eq!(RangeBound::new(10i32, Inclusive), Normalizable::normalize(r)); + + let r: RangeBound = RangeBound::new(10i32, Exclusive); + assert_eq!(RangeBound::new(11i32, Inclusive), Normalizable::normalize(r)); +} + +#[test] +fn test_normalize_upper() { + let r: RangeBound = RangeBound::new(10i32, Inclusive); + assert_eq!(RangeBound::new(11i32, Exclusive), Normalizable::normalize(r)); + + let r: RangeBound = RangeBound::new(10i32, Exclusive); + assert_eq!(RangeBound::new(10i32, Exclusive), Normalizable::normalize(r)); +} + +#[test] +fn test_range_normalizes() { + let r1 = range!('(' 10i32, 15i32 ']'); + let r2 = range!('[' 11i32, 16i32 ')'); + assert_eq!(r1, r2); +} + +#[test] +fn test_range_empty() { + assert!((range!('(' 9i32, 10i32 ')')).is_empty()); + assert!((range!('[' 10i32, 10i32 ')')).is_empty()); + assert!((range!('(' 10i32, 10i32 ']')).is_empty()); + assert!((range!('[' 10i32, 9i32 ']')).is_empty()); +} + +#[test] +fn test_intersection() { + let r1 = range!('[' 10i32, 15i32 ')'); + let r2 = range!('(' 20i32, 25i32 ']'); + assert!(r1.intersect(&r2).is_empty()); + assert!(r2.intersect(&r1).is_empty()); + assert_eq!(r1, r1.intersect(&range!('(', ')'))); + assert_eq!(r1, (range!('(', ')')).intersect(&r1)); + + let r2 = range!('(' 10i32, ')'); + let exp = Range::new(r2.lower().map(|v| v.clone()), + r1.upper().map(|v| v.clone())); + assert_eq!(exp, r1.intersect(&r2)); + assert_eq!(exp, r2.intersect(&r1)); + + let r2 = range!('(', 15i32 ']'); + assert_eq!(r1, r1.intersect(&r2)); + assert_eq!(r1, r2.intersect(&r1)); + + let r2 = range!('[' 11i32, 14i32 ')'); + assert_eq!(r2, r1.intersect(&r2)); + assert_eq!(r2, r2.intersect(&r1)); +} + +#[test] +fn test_union() { + let r1 = range!('[' 10i32, 15i32 ')'); + let r2 = range!('(' 20i32, 25i32 ']'); + assert_eq!(None, r1.union(&r2)); + assert_eq!(None, r2.union(&r1)); + + let r2 = range!('(', ')'); + assert_eq!(Some(r2), r1.union(&r2)); + assert_eq!(Some(r2), r2.union(&r1)); + + let r2 = range!('[' 13i32, 50i32 ')'); + assert_eq!(Some(range!('[' 10i32, 50i32 ')')), r1.union(&r2)); + assert_eq!(Some(range!('[' 10i32, 50i32 ')')), r2.union(&r1)); + + let r2 = range!('[' 3i32, 50i32 ')'); + assert_eq!(Some(range!('[' 3i32, 50i32 ')')), r1.union(&r2)); + assert_eq!(Some(range!('[' 3i32, 50i32 ')')), r2.union(&r1)); + + let r2 = range!('(', 11i32 ')'); + assert_eq!(Some(range!('(', 15i32 ')')), r1.union(&r2)); + assert_eq!(Some(range!('(', 15i32 ')')), r2.union(&r1)); + + let r2 = range!('(' 11i32, ')'); + assert_eq!(Some(range!('[' 10i32, ')')), r1.union(&r2)); + assert_eq!(Some(range!('[' 10i32, ')')), r2.union(&r1)); + + let r2 = range!('(' 15i32, 20i32 ')'); + assert_eq!(None, r1.union(&r2)); + assert_eq!(None, r2.union(&r1)); + + let r2 = range!('[' 15i32, 20i32 ']'); + assert_eq!(Some(range!('[' 10i32, 20i32 ']')), r1.union(&r2)); + assert_eq!(Some(range!('[' 10i32, 20i32 ']')), r2.union(&r1)); +} + +#[test] +fn test_contains_range() { + assert!(Range::::empty().contains_range(&Range::empty())); + + let r1 = range!('[' 10i32, 15i32 ')'); + assert!(r1.contains_range(&r1)); + + let r2 = range!('(' 10i32, ')'); + assert!(!r1.contains_range(&r2)); + assert!(!r2.contains_range(&r1)); + + let r2 = range!('(', 15i32 ']'); + assert!(!r1.contains_range(&r2)); + assert!(r2.contains_range(&r1)); +}