diff --git a/source/expectations/matchers/ut_be_within.tpb b/source/expectations/matchers/ut_be_within.tpb index 40bcfbab0..7e90ff4e6 100644 --- a/source/expectations/matchers/ut_be_within.tpb +++ b/source/expectations/matchers/ut_be_within.tpb @@ -52,6 +52,60 @@ create or replace type body ut_be_within as return l_result; end; + member procedure of_(self in ut_be_within, a_expected timestamp) is + l_result ut_be_within := self; + begin + l_result.expected := ut_data_value_timestamp(a_expected); + if l_result.is_negated_flag = 1 then + l_result.expectation.not_to(l_result ); + else + l_result.expectation.to_(l_result ); + end if; + end; + + member function of_(self in ut_be_within, a_expected timestamp) return ut_be_within is + l_result ut_be_within := self; + begin + l_result.expected := ut_data_value_timestamp(a_expected); + return l_result; + end; + + member procedure of_(self in ut_be_within, a_expected timestamp_tz_unconstrained) is + l_result ut_be_within := self; + begin + l_result.expected := ut_data_value_timestamp_tz(a_expected); + if l_result.is_negated_flag = 1 then + l_result.expectation.not_to(l_result ); + else + l_result.expectation.to_(l_result ); + end if; + end; + + member function of_(self in ut_be_within, a_expected timestamp_tz_unconstrained) return ut_be_within is + l_result ut_be_within := self; + begin + l_result.expected := ut_data_value_timestamp_tz(a_expected); + return l_result; + end; + + member procedure of_(self in ut_be_within, a_expected timestamp_ltz_unconstrained) is + l_result ut_be_within := self; + begin + l_result.expected := ut_data_value_timestamp_ltz(a_expected); + if l_result.is_negated_flag = 1 then + l_result.expectation.not_to(l_result ); + else + l_result.expectation.to_(l_result ); + end if; + end; + + member function of_(self in ut_be_within, a_expected timestamp_ltz_unconstrained) return ut_be_within is + l_result ut_be_within := self; + begin + l_result.expected := ut_data_value_timestamp_ltz(a_expected); + return l_result; + end; + overriding member function run_matcher(self in out nocopy ut_be_within, a_actual ut_data_value) return boolean is l_result boolean; function l_result_from_number return boolean is @@ -78,12 +132,39 @@ create or replace type body ut_be_within as end; end; + function l_result_from_timestamp (a_distance ut_data_value) return boolean is + l_expected timestamp := case when self.expected is of ( ut_data_value_timestamp) then + treat(self.expected as ut_data_value_timestamp).data_value + when self.expected is of ( ut_data_value_timestamp_tz) then + treat(self.expected as ut_data_value_timestamp_tz).data_value + when self.expected is of ( ut_data_value_timestamp_ltz) then + treat(self.expected as ut_data_value_timestamp_ltz).data_value + end; + l_actual timestamp with time zone := treat(a_actual as ut_data_value_date).data_value; + l_distance_ym yminterval_unconstrained := case when self.distance_from_expected is of ( ut_data_value_yminterval) + then treat(self.distance_from_expected as ut_data_value_yminterval).data_value + end; + l_distance_ds dsinterval_unconstrained := case when self.distance_from_expected is of ( ut_data_value_dsinterval) + then treat(self.distance_from_expected as ut_data_value_dsinterval).data_value + end; + begin + return case when l_distance_ym is not null + then l_actual between l_expected - l_distance_ym and l_expected + l_distance_ym + else l_actual between l_expected - l_distance_ds and l_expected + l_distance_ds + end; + end; + + begin if self.expected.data_type = a_actual.data_type then if self.expected is of (ut_data_value_number) then l_result := l_result_from_number; elsif self.expected is of (ut_data_value_date)then l_result := l_result_from_date(self.distance_from_expected); + elsif self.expected is of (ut_data_value_timestamp_tz)then + l_result := l_result_from_date(self.distance_from_expected); + elsif self.expected is of (ut_data_value_timestamp_ltz)then + l_result := l_result_from_date(self.distance_from_expected); end if; else l_result := (self as ut_matcher).run_matcher(a_actual); diff --git a/source/expectations/matchers/ut_be_within.tps b/source/expectations/matchers/ut_be_within.tps index 5090d3414..0b14bce44 100644 --- a/source/expectations/matchers/ut_be_within.tps +++ b/source/expectations/matchers/ut_be_within.tps @@ -22,6 +22,12 @@ create or replace type ut_be_within under ut_be_within_pct( constructor function ut_be_within(self in out nocopy ut_be_within, a_distance_from_expected yminterval_unconstrained) return self as result, member procedure of_(self in ut_be_within, a_expected date), member function of_(self in ut_be_within, a_expected date) return ut_be_within, + member procedure of_(self in ut_be_within, a_expected timestamp), + member function of_(self in ut_be_within, a_expected timestamp) return ut_be_within, + member procedure of_(self in ut_be_within, a_expected timestamp_tz_unconstrained ), + member function of_(self in ut_be_within, a_expected timestamp_tz_unconstrained) return ut_be_within, + member procedure of_(self in ut_be_within, a_expected timestamp_ltz_unconstrained), + member function of_(self in ut_be_within, a_expected timestamp_ltz_unconstrained) return ut_be_within, overriding member function run_matcher(self in out nocopy ut_be_within, a_actual ut_data_value) return boolean, overriding member function failure_message(a_actual ut_data_value) return varchar2, overriding member function failure_message_when_negated(a_actual ut_data_value) return varchar2 diff --git a/test/ut3_user/expectations/binary/test_to_be_within.pkb b/test/ut3_user/expectations/binary/test_to_be_within.pkb index b845bb26a..2ea90bd6b 100644 --- a/test/ut3_user/expectations/binary/test_to_be_within.pkb +++ b/test/ut3_user/expectations/binary/test_to_be_within.pkb @@ -74,6 +74,12 @@ create or replace package body test_to_be_within is test_to_be_within_success('to_be_within','date', 'sysdate', 'sysdate+1','''1 0:00:11.333''','interval day to second'); test_to_be_within_success('to_be_within','date', 'sysdate', 'sysdate+200','''1-0''','interval year to month'); test_to_be_within_success('to_be_within','date', 'sysdate+200', 'sysdate','''1-0''','interval year to month'); + + test_to_be_within_success('to_be_within','timestamp_tz_unconstrained', q'[TIMESTAMP '2017-08-09 07:00:00 -7:00']', 'sysdate','''1 0:00:11.333''','interval day to second'); + test_to_be_within_success('to_be_within','timestamp_tz_unconstrained', q'[TIMESTAMP '2017-08-09 07:00:00 -7:00']', 'sysdate+1','''1 0:00:11.333''','interval day to second'); + test_to_be_within_success('to_be_within','timestamp_ltz_unconstrained', q'[TIMESTAMP '2017-08-09 07:00:00 -7:00']', 'sysdate+200','''1-0''','interval year to month'); + test_to_be_within_success('to_be_within','timestamp_ltz_unconstrained', 'sysdate+200', 'sysdate','''1-0''','interval year to month'); + test_to_be_within_success('to_( ut3_develop.be_within','number', '2', '4','2','number', ')'); test_to_be_within_success('to_( ut3_develop.be_within','number', '4', '2','2','number', ')'); test_to_be_within_success('to_( ut3_develop.be_within','date', 'sysdate+1', 'sysdate','''1 0:00:11.333''','interval day to second', ')');