Back

< (clj)

(source)

protocol

(< x y)
Is x before y?

Examples

tick
(ns tick.api-test
  (:require
    [clojure.test
     :refer [deftest is testing run-tests]
     :refer-macros [deftest is testing run-tests]]
    [tick.core :as t]
    [tick.locale-en-us]
    [tick.protocols :as p]
    [cljc.java-time.clock]
    [cljc.java-time.instant]
    [cljc.java-time.day-of-week]
    [cljc.java-time.month]
    [cljc.java-time.year]
    #?@(:cljs [[java.time :refer [Instant]]]))
  #?(:clj
     (:import [java.time Instant])))

(deftest clock-test
  (testing "clock"
    (t/with-clock (-> (t/date "2018-02-14") (t/at "10:00") (t/in "America/New_York"))
      (testing "(clock) return type"
        (is (t/clock? (t/clock))))
      (testing "Time shifting the clock back by 2 hours"
        (is (= "2018-02-14T13:00:00Z" (str (t/instant (t/<< (t/clock) (t/new-duration 2 :hours)))))))
      (testing "with instant"
        (is (= (t/zone (t/clock (t/instant)))
              (t/zone "America/New_York"))))))

  (let [now (t/instant)
        from (t/<< now (t/new-duration 10 :seconds))
        to (t/>> now (t/new-duration 10 :seconds))]
    (is (= (t/new-duration 20 :seconds) (t/between from to) ))
    (is (= 20 (t/between from to :seconds))))
  (is
    (= (t/new-duration 48 :hours)
      (t/between (t/beginning (t/today)) (t/end (t/tomorrow)))))
  (let [start (t/date-time "2020-01-01T12:00") 
        end (t/date-time "2020-01-01T12:02")]
    (is
      (=
        (t/new-duration 2 :minutes)
        (t/between start end))
      (= 2 (t/between start end :minutes))))
  (is
    (=
      (t/new-duration 30 :minutes)
      (t/between (t/new-time 11 0 0) (t/new-time 11 30 0))))
  (testing "LocalDate"
    (let [start (t/date "2020-01-01")
          end (t/date "2020-01-02")]
      (is (= (t/new-period 1 :days)
            (t/between start end)))
      (is (= 1 (t/between start end :days))))))

(deftest comparison-test
  (let [point (t/truncate (t/instant) :millis)
        later (t/>> point (t/new-duration 1 :millis))]
    (testing "shifting inst"
      (let [i (t/inst)]
        (is (= i (-> i
                     (t/>> (t/new-duration 10 :seconds))
                     (t/<< (t/new-duration 10 :seconds)))))))
    (testing "max-min"
      (is (= later (t/max point later point later)))
      (is (= point (t/min point later point later))))
    (testing "max-min key"
      (is (= {:foo later} (t/max-key :foo {:foo point} {:foo later} {:foo point} {:foo later})))
      (is (= {:foo point} (t/min-key :foo {:foo point} {:foo later} {:foo point} {:foo later}))))
    (testing "comparables not="
      (doseq [point (point-in-time-comparable point)]
        (testing "comparables ="
          (is (apply t/= point (point-in-time-comparable point)))
          (is (apply t/>= point (point-in-time-comparable point))))
        (is (apply t/<= point (point-in-time-comparable later))))
      (doseq [later (point-in-time-comparable later)]
        (is (apply t/>= later (point-in-time-comparable point))))

      (doseq [point (point-in-time-comparable point)
              later (point-in-time-comparable later)]
        (is (t/<= point later))
        (is (t/< point later))
        (is (t/>= later point))
        (is (t/> later point)))))

  (testing "Instants and ZonedDateTimes should be equals if represents the same point in time"
    (is (t/=
          (t/instant (t/clock (t/instant "2017-10-31T16:00:00Z")))
          (t/zoned-date-time "2017-10-31T16:00:00Z[UTC]"))))
  (is
    (t/<
      (t/now)
      (t/>> (t/now) (t/new-duration 10 :seconds))
      (t/>> (t/now) (t/new-duration 20 :seconds))))
  (is
    (t/>
      (t/>> (t/now) (t/new-duration 20 :seconds))
      (t/>> (t/now) (t/new-duration 10 :seconds))
      (t/now)))
  (is (not
        (t/<
          (t/now)
          (t/>> (t/now) (t/new-duration 20 :seconds))
          (t/>> (t/now) (t/new-duration 10 :seconds)))))
  (let [at (t/now)]
    (is (t/<= at at (t/>> at (t/new-duration 1 :seconds))))
    (is (t/>= at at (t/<< at (t/new-duration 10 :seconds)))))

  (testing "durations"
    (is (t/> (t/new-duration 20 :seconds) (t/new-duration 10 :seconds)))
    (is (t/>= (t/new-duration 20 :seconds) (t/new-duration 20 :seconds)))
    (is (t/>= (t/new-duration 20 :seconds) (t/new-duration 19 :seconds)))
    (is (not (t/>= (t/new-duration 19 :seconds) (t/new-duration 20 :seconds))))
    (is (t/< (t/new-duration 10 :seconds) (t/new-duration 20 :seconds)))
    (is (t/<= (t/new-duration 20 :seconds) (t/new-duration 20 :seconds)))
    (is (t/<= (t/new-duration 19 :seconds) (t/new-duration 20 :seconds)))
    (is (not (t/<= (t/new-duration 20 :seconds) (t/new-duration 19 :seconds))))))

    (is (t/< t1 t2))
    (is (not (t/< t1 t1)))
    (is (not (t/< t2 t1)))

    (is (t/<= t1 t2))
    (is (t/<= t1 t1))
    (is (not (t/<= t2 t1)))

(deftest coincidence-test
  (let [int-beginning (t/instant "2020-02-02T00:00:00Z")
        int-end (t/>> int-beginning (t/of-hours 2))
        interval {:tick/beginning int-beginning
                  :tick/end       int-end}]
    (is (t/coincident? interval (t/>> int-beginning (t/of-hours 1))))
    (is (not (t/coincident? interval (t/<< int-beginning (t/of-hours 1)))))
    (is (t/coincident? interval int-beginning))
    (is (t/coincident? interval int-end))
    (is (t/coincident? interval interval))
    (is (not (t/coincident? interval (-> interval
                                         (update :tick/end #(t/>> % (t/of-nanos 1))))))))
  (testing "non-interval coincidence"
    (doseq [[start-f new-amount] [[t/date t/of-days] [t/date-time t/of-hours]]]
      (let [start (start-f)
            end (t/>> start (new-amount 2))]
        (is (t/coincident? start end (t/>> start (new-amount 1))))
        (is (not (t/coincident? start end (t/<< start (new-amount 1)))))
        (is (t/coincident? start end start))
        (is (t/coincident? start end end))))))
tick
(ns tick.alpha.interval-test
  (:require
   [clojure.spec.alpha :as s]
   [tick.core :as t]
   [tick.protocols :as p]
   [clojure.test
    :refer [deftest is testing run-tests]
    :refer-macros [deftest is testing run-tests]]
   [tick.alpha.interval :as ti]
   #?@(:cljs [[java.time :refer [Instant LocalDateTime LocalTime]]]))
  #?(:clj
     (:import [java.time LocalDateTime Instant LocalTime])))

;; Distinct: because no pair of definite intervals can be related by more than one of the relationships.
;; From [ALSPAUGH-2009]
(deftest distinct-test
  (is
    (= [1]   ; Each interval should have just one relation that is true
       (distinct
         (let [f (apply juxt ti/basic-relations)]
           (for [x1 instants
                 x2 instants
                 y1 instants
                 y2 instants
                 :when (t/< x1 x2)
                 :when (t/< y1 y2)
                 :let [x (ti/new-interval x1 x2)
                       y (ti/new-interval y1 y2)]]
             ;; For each combination, count how many relations are true
             ;; (should be just one each time)
             (count (filter true? (f x y)))))))))

;; Exhaustive: because any pair of definite intervals are described by one of the relations.
(deftest exhaustive-test []
  (is
    (= 13 ; Thirteen basic relations
       (count
         (distinct
           (for [x1 instants
                 x2 instants
                 y1 instants
                 y2 instants
                 :when (t/< x1 x2)
                 :when (t/< y1 y2)
                 :let [x (ti/new-interval x1 x2)
                       y (ti/new-interval y1 y2)]]
             ;; For each combination, count how many relations are true
             ;; (should be just one each time)
             (ti/relation x y)))))))