Way better scrolling

Way better scrolling

* Song follows finger.
* Higher friction for faster slowdown.

--- src/playmary/one.cljs
+++ src/playmary/one.cljs
@@ -51,10 +51,19 @@
   [{w :w h :h playhead :playhead :as instrument}]
   {:x 0 :y (t->px instrument playhead) :w w :h h})

+(defn finger-pushing?
+  [instrument]
+  (not (nil? (-> instrument :scroll :touch-id))))
+
+(defn scrolling?
+  [instrument]
+  (or (finger-pushing? instrument)
+      (not= (-> instrument :scroll :speed) 0)))
+
 (defn draw-note
   [draw-ctx instrument note]
   (let [{x :x y :y w :w h :h} (note-rect note instrument)]
-    (set! (.-fillStyle draw-ctx) "white")
+    (set! (.-fillStyle draw-ctx) "#FFFFFF")
     (.fillRect draw-ctx x y w h)))

 (defn colliding?
@@ -118,7 +127,7 @@
      :w 0 :h 0
      :sound-on? true
      :px-per-ms 0.1
-     :scroll {:distance 0 :speed 0 :friction 0.9 :touch-id nil}
+     :scroll {:speed 0 :friction 0.75 :touch-id nil}
      :start start
      :playhead start}))

@@ -179,15 +188,6 @@
        :off nil
        :touch-id (touch :touch-id)})))

-(defn finger-pushing?
-  [instrument]
-  (not (nil? (-> instrument :scroll :touch-id))))
-
-(defn scrolling?
-  [instrument]
-  (or (finger-pushing? instrument)
-      (not= (-> instrument :scroll :speed) 0)))
-
 (defn start-note
   [touch {notes :notes :as instrument}]
   (if-let [new-note (touch->note instrument touch)]
@@ -209,31 +209,32 @@
   (.sqrt js/Math (+ (.pow js/Math (- x2 x1) 2) (.pow js/Math (- y2 y1) 2))))

 (defn finger-push
-  [{touch-id :touch-id touch-y-distance :y-distance} instrument]
-  (-> instrument
-      (assoc-in [:scroll :distance] touch-y-distance)
-      (assoc-in [:scroll :touch-id] touch-id)))
+  [{touch-id :touch-id touch-y-distance :y-distance} {playhead :playhead :as instrument}]
+  (let [speed (/ touch-y-distance (instrument :px-per-ms))]
+    (-> instrument
+        (assoc-in [:scroll :speed] speed)
+        (assoc-in [:scroll :touch-id] touch-id)
+        (assoc :playhead (+ playhead speed)))))

 (defn stop-finger-push
   [{touch-y-distance :y-distance} instrument]
-  (-> instrument
-      (assoc-in [:scroll :distance] 0)
-      (assoc-in [:scroll :touch-id] nil)))
+  (assoc-in instrument [:scroll :touch-id] nil))

 (defn stop-scroll
   [touch instrument]
   (assoc-in instrument [:scroll :speed] 0))

-(defn scroll
-  [{{distance :distance speed :speed friction :friction} :scroll
-    playhead :playhead :as instrument}
+(defn inertial-scroll
+  [{{speed :speed friction :friction} :scroll
+    playhead :playhead px-per-ms :px-per-ms :as instrument}
    delta]
-  (let [pre-zeno-speed (* (+ speed distance)
-                          (if (finger-pushing? instrument) 1 friction))
-        speed (if (< (.abs js/Math pre-zeno-speed) 1) 0 pre-zeno-speed)]
-    (-> instrument
-        (assoc :playhead (+ playhead speed))
-        (assoc-in [:scroll :speed] speed))))
+  (if (not (finger-pushing? instrument))
+    (let [pre-zeno-speed (* speed friction)
+          speed (if (< (.abs js/Math pre-zeno-speed) 1) 0 pre-zeno-speed)]
+      (-> instrument
+          (assoc :playhead (+ playhead speed))
+          (assoc-in [:scroll :speed] speed)))
+    instrument))

 (defn fire-touch-hold-on-instrument
   [touch instrument]
@@ -330,7 +331,7 @@
   [instrument delta]
   (-> instrument
       (step-time delta)
-      (scroll delta)))
+      (inertial-scroll delta)))

 (prevent-scrolling)
 (set-up-web-audio-on-first-touch)


Revert "Add a hack for make work the promise in nodejs."

This reverts commit a1ee962872bb28ac7a7055ef158c476c7654e3fa.

--- src/promesa/core.cljc
+++ src/promesa/core.cljc
@@ -44,10 +44,6 @@
               java.util.function.Function
               java.util.function.Supplier)))

-#?(:cljs
-   (when (= *target* "nodejs")
-     (set! js/Promise js/module.exports.Promise)))
-
 #?(:clj
    (do
      (def ^:dynamic ^:no-doc


storing tx-log triplets correclty

storing tx-log triplets correclty

--- core/src/samsara_core/samza.clj
+++ core/src/samsara_core/samza.clj
@@ -158,7 +158,7 @@
          (->> event
               from-json
               vector
-              (kv/restore *store*))))
+              (kv/restore (var-get *store*)))))

@@ -184,7 +184,7 @@
   (let [kvstore-topic (kvstore-topic!)]
     (->> txlog
          (map (fn [[k ver v]]
-                [kvstore-topic k (to-json v)])))))
+                [kvstore-topic k (to-json [k ver v])])))))


s/pred=/io/I/

s/pred=/io/I/

--- test/babel/test/es.clj
+++ test/babel/test/es.clj
@@ -13,7 +13,7 @@
 (deftest generate-conditional
   (let [result (engine/generate {:synsem {:subcat '()
                                           :sem {:pred :sleep
-                                                :subj {:pred :io}
+                                                :subj {:pred :I}
                                                 :tense :conditional}}}
                                 es/small
                                 :enrich true)]


New test for the function format-date-using-desired-format

--- test/clj_calendar/calendar_test.clj
+++ test/clj_calendar/calendar_test.clj
@@ -271,6 +271,24 @@
             (is (= "PM"           (format-date-using-desired-format calendar "aa")))
             (is (= "PM 2 AD"      (format-date-using-desired-format calendar "aa u GG"))))))

+(deftest test-format-date-using-desired-format-5
+    "Check the function clj-calendar.calendar/format-date-using-desired-format"
+    (testing "the function clj-calendar.calendar/format-date-using-desired-format."
+        (let [calendar (get-calendar)]
+            (.set calendar 1000 01 01 10 20 30)
+            (is (= "1000" (format-date-using-desired-format calendar "yyyy")))
+            (is (= "00"   (format-date-using-desired-format calendar "yy")))
+            (is (= "02"   (format-date-using-desired-format calendar "MM")))
+            (is (= "01"   (format-date-using-desired-format calendar "dd")))
+            (is (= "032"  (format-date-using-desired-format calendar "DDD")))   ; day in year
+            (is (= "10"   (format-date-using-desired-format calendar "hh")))    ; hour 0..11
+            (is (= "10"   (format-date-using-desired-format calendar "HH")))    ; hour 0..23
+            (is (= "20"   (format-date-using-desired-format calendar "mm")))
+            (is (= "30"   (format-date-using-desired-format calendar "ss")))
+            (is (= "AM"   (format-date-using-desired-format calendar "aa")))    ; AM/PM
+            (is (= "4"    (format-date-using-desired-format calendar "u")))     ; day number
+            (is (= "AD"   (format-date-using-desired-format calendar "GG")))))) ; era
+
 (deftest test-format-date-time-1
     "Check the function clj-calendar.calendar/format-date-time"
     (testing "the function clj-calendar.calendar/format-date-time"


Fix #23

Fix #23

--- src/clojure/clojurewerkz/cassaforte/utils.clj
+++ src/clojure/clojurewerkz/cassaforte/utils.clj
@@ -1,5 +1,5 @@
 (ns clojurewerkz.cassaforte.utils
-  (:refer [clojurewerkz.cassaforte.cql :refer :all]))
+  (:require [clojurewerkz.cassaforte.cql :refer :all]))

 (defn- group-map
   "Groups by and applies f to each group"


Added float precision tolerance to round?

--- src/clojure/uncomplicate/neanderthal/math.clj
+++ src/clojure/uncomplicate/neanderthal/math.clj
@@ -37,8 +37,11 @@
 (defn round ^double [^double x]
   (Math/floor (+ 0.5 x)))

-(defn round? [^double x]
-  (= x (Math/floor (+ 0.5 x))))
+(defn round?
+  ([^double x]
+   (f= x (Math/floor (+ 0.5 x))))
+  ([^double x ^double nepsilons]
+   (f= x (Math/floor (+ 0.5 x)) nepsilons)))

 (defn floor ^double [^double x]
   (Math/floor x))


Add :unsolved-subset for knock-off-chip-off-the-old-block

--- src/clojush/pushgp/selection/preselection.clj
+++ src/clojush/pushgp/selection/preselection.clj
@@ -84,9 +84,10 @@
   (int (* maxfrac outof)). If the first item in (:knock-off-chip-off-the-old-block argmap)
   is :unsolved, then the remainder are interpreted as above, but only errors
   that are not solved for a given individual are considered in the filtering.
-  If the first item in (:knock-off-chip-off-the-old-block argmap)
-  is :min2, then the remainder are interpreted as above, but the minimum
-  for random values is 2 rather than 1."
+  If it is :unsolved-subset, then only a random subset of those considered
+  with :unsolved will be considered. If the first item in
+  (:knock-off-chip-off-the-old-block argmap) is :min2, then the remainder are
+  interpreted as above, but the minimum for random values is 2 rather than 1."
   [pop argmap]
   (let [knock-spec (:knock-off-chip-off-the-old-block argmap)]
     (if (not knock-spec)
@@ -98,23 +99,41 @@
         (let [knock-spec (if (= true knock-spec) [true] knock-spec)
               min2? (= :min2 (first knock-spec))
               knock-spec (if min2? (rest knock-spec) knock-spec)
-              unsolved? (= :unsolved (first knock-spec))
+              unsolved? (or (= :unsolved (first knock-spec))
+                            (= :unsolved-subset (first knock-spec)))
+              subset? (= :unsolved-subset (first knock-spec))
               knock-spec (if unsolved? (rest knock-spec) knock-spec)
-              filtered-history (if unsolved?
-                                 (fn [ind]
-                                   (let [hist (:history ind)
-                                         keep? (map #(not (zero? %))
-                                                    (first hist))]
-                                     (map (fn [errs]
-                                            (filter identity
-                                                    (map (fn [e k?]
-                                                           (if k? e nil))
-                                                         errs
-                                                         keep?)))
-                                          hist)))
-                                 :history)]
+              filtered-history
+              (if unsolved?
+                (fn [ind]
+                  (let [hist (:history ind)
+                        keep? (map #(not (zero? %))
+                                   (first hist))
+                        keep? (if (and subset?
+                                       (> (count (filter identity keep?)) 1))
+                                (let [keep-indices
+                                      (filter identity
+                                              (map (fn [k i]
+                                                     (if k i nil))
+                                                   keep?
+                                                   (iterate inc 0)))
+                                      keep-indices (shuffle keep-indices)
+                                      keep-indices (cons (first keep-indices)
+                                                         (take (rand-int (count keep-indices))
+                                                               (rest keep-indices)))]
+                                  (for [i (range (count keep?))]
+                                    (some #{i} keep-indices)))
+                                keep?)]
+                    (map (fn [errs]
+                           (filter identity
+                                   (map (fn [e k?]
+                                          (if k? e nil))
+                                        errs
+                                        keep?)))
+                         hist)))
+                :history)]
           (if (= true (first knock-spec))
-            (let [changed (vec (filter #(not= (first (filtered-history %))
+            (let [changed (vec (filter #(not= (first (filtered-history %))
                                               (second (filtered-history %)))
                                        pop))]
               (if (empty? changed)
@@ -123,7 +142,7 @@
             (let [diffs (first knock-spec)
                   outof (second knock-spec)
                   limit (if (= outof :random) (nth knock-spec 2) nil)
-                  outof (if (= outof :random)
+                  outof (if (= outof :random)
                           (if min2?
                             (inc (inc (lrand-int (dec limit))))
                             (inc (lrand-int limit)))
@@ -140,7 +159,7 @@
                                    (lrand-int outof))))
                           diffs)
                   changed (vec (filter #(or (< (count (filtered-history %)) diffs)
-                                            (>= (count (distinct (take outof
+                                            (>= (count (distinct (take outof
                                                                        (filtered-history %))))
                                                 diffs))
                                        pop))]


Use the `:conn` from a reliable-connection to start a reliable-chan

--- src/com/farmlogs/conduit/reliable_channel.clj
+++ src/com/farmlogs/conduit/reliable_channel.clj
@@ -187,7 +187,7 @@

   component/Lifecycle
   (start [{:keys [rmq-connection timeout-window] :as this}]
-    (let [rmq-chan (rmq.chan/open rmq-connection)
+    (let [rmq-chan (rmq.chan/open (:conn rmq-connection))
           confirmation-chan (a/chan)
           await-chan (a/chan)
           await-process (->await-process confirmation-chan await-chan timeout-window)]


Replace attach/group fns with get/set descriptor

--- src/main/clojure/com/stuartsierra/lazytest/attach.clj
+++ src/main/clojure/com/stuartsierra/lazytest/attach.clj
@@ -1,57 +1,25 @@
-(ns com.stuartsierra.lazytest.attach
-  (:use [com.stuartsierra.lazytest.groups
-         :only (group?)]))
+(ns com.stuartsierra.lazytest.attach)

-(defn groups
-  "Get the set of example groups from obj's metadata."
-  [obj]
-  (::groups (meta obj)))
+(defn descriptor-name
+  "Returns the symbol name of the descriptor assigned to iref, a
+  namespace or Var."
+  [iref]
+  (::descriptor (meta iref)))

-(defn set-groups!
-  "Set iref's set of example groups to grps, which must be a set."
-  [iref grps]
-  {:pre [(set? grps)
-         (every? group? grps)]}
-  (alter-meta! iref assoc ::groups grps))
+(defn set-descriptor-name
+  "Sets the descriptor of iref (a namespace or Var) to sym."
+  [iref sym]
+  {:pre [(symbol? sym)
+         (or (var? iref)
+             (instance? clojure.lang.Namespace iref))]}
+  (alter-meta! iref assoc ::descriptor sym))

-(defn add-group!
-  "Add grp to the set of example groups on iref."
-  [iref grp]
-  {:pre [(group? grp)]}
-  (alter-meta! iref assoc ::groups
-               (conj (::groups (meta iref) #{}) grp)))
-
-(defn remove-group!
-  "Remove grp from the set of example groups on iref."
-  [iref grp]
-  {:pre [(group? grp)]}
-  (alter-meta! iref update-in [::groups] disj grp))
-
-(defn clear-groups!
-  "Remove all example groups from iref."
+(defn descriptor
+  "Returns the descriptor, either a Var or a namespace, of iref."
   [iref]
-  (alter-meta! iref dissoc ::groups))
-
-
-
-;;; Assertions
-
-(let [g1 (com.stuartsierra.lazytest.groups/group
-          [] (com.stuartsierra.lazytest.groups/group-examples (= 1 1))
-          [])
-      g2 (com.stuartsierra.lazytest.groups/group
-          [] (com.stuartsierra.lazytest.groups/group-examples (= 2 2))
-          [])]
-  (assert (nil? (groups *ns*)))
-
-  (set-groups! *ns* #{g1 g2})
-  (assert (= #{g1 g2} (groups *ns*)))
-
-  (remove-group! *ns* g1)
-  (assert (= #{g2} (groups *ns*)))
-
-  (add-group! *ns* g1)
-  (assert (= #{g1 g2} (groups *ns*)))
-
-  (clear-groups! *ns*)
-  (assert (nil? (groups *ns*))))
+  (let [sym (descriptor-name iref)]
+    (if (namespace sym)
+      ;; qualified symbol means it's a Var
+      (resolve sym)
+      ;; else, it's a namespace
+      (the-ns sym))))


Added more requires.

Added more requires.

Also a banner function.


Fix dumb markup mistake

Fix dumb markup mistake


tempos start at 1

tempos start at 1

--- src/temperaments/core.clj
+++ src/temperaments/core.clj
@@ -941,7 +941,7 @@
 (def tempo-slider
   (slider :orientation :horizontal
           ;:value 120
-          :min 20
+          :min 0
           :max 360
           :snap-to-ticks? false
           :paint-labels? true
@@ -999,7 +999,9 @@
 (listen tempo-slider
         :change
         (fn [e]
-          (reset! tempo (value tempo-slider))))
+          (let [newval (value tempo-slider)
+                newval (if (= 0 newval) 1 newval)]
+            (reset! tempo newval))))

 (value! tempo-slider 120)


automatically start NRPE on all servers

automatically start NRPE on all servers

--- src/terraboot/cluster.clj
+++ src/terraboot/cluster.clj
@@ -22,7 +22,8 @@
                     {:name "confd.service" :command "start" :content (snippet "systemd/confd.service") :enable true}
                     {:name "install-awscli.service" :command "start" :content (snippet "systemd/install-awscli.service") :enable true}
                     {:name "dcos-gen-resolvconf.timer" :command "stop" :mask true}
-                    {:name "filebeat.service" :command "start" :content (snippet "systemd/filebeat.service") :enable true}]
+                    {:name "filebeat.service" :command "start" :content (snippet "systemd/filebeat.service") :enable true}
+                    {:name "nrpe.service" :command "start" :content (snippet "systemd/nrpe.service") :enable true}]
             :update {:reboot-strategy "off"}}
    :write_files [{:path "/etc/mesosphere/setup-packages/dcos-provider-aws--setup/pkginfo.json"
                   :content "{}\n"}
@@ -357,7 +358,8 @@
                                        :number-of-masters min-number-of-masters
                                        :influxdb-dns (str "influxdb." (vpc-unique "kixi") ".mesos")
                                        :dns dns-host
-                                       :mesos-dns "127.0.0.1"}
+                                       :mesos-dns "127.0.0.1"
+                                       :alerts-server (str "alerts." (vpc-unique "kixi.mesos"))}
                                 :lifecycle { :create_before_destroy true }
                                 })

@@ -425,7 +427,8 @@
                                        :number-of-masters min-number-of-masters
                                        :influxdb-dns (str "influxdb." (vpc-unique "kixi") ".mesos")
                                        :dns dns-host
-                                       :mesos-dns (cluster-output-of "aws_elb" "internal-lb" "dns_name")}
+                                       :mesos-dns (cluster-output-of "aws_elb" "internal-lb" "dns_name")
+                                       :alerts-server (str "alerts." (vpc-unique "kixi.mesos"))}
                                 :lifecycle { :create_before_destroy true }})

              (vpc/private_route53_record (str cluster-name "-masters") vpc-name
@@ -490,7 +493,8 @@
                                        :number-of-masters min-number-of-masters
                                        :influxdb-dns (str "influxdb." (vpc-unique "kixi") ".mesos")
                                        :dns dns-host
-                                       :mesos-dns (cluster-output-of "aws_elb" "internal-lb" "dns_name")}
+                                       :mesos-dns (cluster-output-of "aws_elb" "internal-lb" "dns_name")
+                                       :alerts-server (str "alerts." (vpc-unique "kixi.mesos"))}
                                 :lifecycle { :create_before_destroy true }

                                 })


Removes util ns.

Removes util ns.

--- test/onyx/log/util.clj
+++ test/onyx/log/util.clj
@@ -1,18 +0,0 @@
-(ns onyx.log.util
-  (:require [com.stuartsierra.component :as component]
-            [taoensso.timbre :refer [info]]))
-
-(defrecord StubbedTaskLifeCycle [args state]
-  component/Lifecycle
-
-  (start [component]
-    (info (format "[%s] Starting stubbed Task Lifecycle for job %s task %s" (:id state) (:job args) (:task args)))
-    component)
-
-  (stop [component]
-    (info (format "[%s] Stopping stubbed Task Lifecycle for job %s task %s" (:id state) (:job args) (:task args)))
-    component))
-
-(defn stub-task-lifecycle [args state]
-  (map->StubbedTaskLifeCycle {:args args :state state}))
-


Initialize some state keys as nil instead of empty hash-map.

--- src/uxbox/main/state.cljs
+++ src/uxbox/main/state.cljs
@@ -33,12 +33,12 @@
    :undo {}
    :profile nil
    :workspace nil
-   :shapes-by-id {}
-   :elements-by-id {}
-   :colors-by-id {}
-   :icons-by-id {}
-   :projects-by-id {}
-   :pages-by-id {}})
+   :shapes-by-id nil
+   :elements-by-id nil
+   :colors-by-id nil
+   :icons-by-id nil
+   :projects-by-id nil
+   :pages-by-id nil})

 (defn init
   "Initialize the state materialization."


Add correct color conversion and little endian-ness.

--- src/videotest/buffers.clj
+++ src/videotest/buffers.clj
@@ -39,9 +39,9 @@
   (q/frame-rate 60)
   {:b-array (byte-array PIX-CNT1)
    :i-array (int-array PIX-CNT2)
-   :frame-mat (Mat. WIDTH HEIGHT CvType/CV_8UC4)
+   :frame-mat (Mat. WIDTH HEIGHT CvType/CV_8UC3)
    :camera (camera 0)
-   :p-image (q/create-image WIDTH HEIGHT :argb)})
+   :p-image (q/create-image WIDTH HEIGHT :rgb)})

 (defn update-frame [state]
   (let [{:keys [camera]} state]
@@ -51,11 +51,12 @@

 (defn mat->p-img [mat b-array i-array p-img]
   (let [n-mat (Mat. WIDTH HEIGHT CvType/CV_8UC4)]
-    (Imgproc/cvtColor mat n-mat Imgproc/COLOR_BGRA2RGBA 0)
+    (Imgproc/cvtColor mat n-mat Imgproc/COLOR_RGB2RGBA 4)
     (.get n-mat 0 0 b-array)
     (-> (ByteBuffer/wrap b-array)
-       (.asIntBuffer)
-       (.get i-array)))
+        (.order ByteOrder/LITTLE_ENDIAN)
+        (.asIntBuffer)
+        (.get i-array)))
   (.loadPixels p-img)
   (set! (.pixels p-img) (aclone i-array))
   (.updatePixels p-img)


Update io.prometheus/simpleclient_dropwizard to "0.6.0"

--- backend/project.clj
+++ backend/project.clj
@@ -49,7 +49,7 @@
                  [net.postgis/postgis-jdbc "2.2.1" :exclusions [org.postgresql/postgresql]]
                  [iapetos "0.1.8" :exclusions [io.prometheus/simpleclient]]
                  [io.prometheus/simpleclient_hotspot "0.6.0"]
-                 [io.prometheus/simpleclient_dropwizard "0.5.0"]
+                 [io.prometheus/simpleclient_dropwizard "0.6.0"]
                  [org.clojure/test.check "0.10.0-alpha3"]]
   :source-paths   ["src" "specs"]
   :uberjar-name "akvo-lumen.jar"


Set the default to false explicitly for -C

--- src/vignette/core.clj
+++ src/vignette/core.clj
@@ -12,7 +12,8 @@
   (:gen-class))

 (def cli-specs [["-h" "--help" "Show help"]
-                ["-C" "--cache-thumbnails" "Enable thumbnail caching"]
+                ["-C" "--cache-thumbnails" "Enable thumbnail caching"
+                 :default false]
                 ["-m" "--mode running mode" "Object storage to use (s3 or local)"
                  :default "local"
                  :validate [#(contains? #{"local" "s3"} %) "Supported modes are \"local\" and \"s3\""]]


use proper mouse events (mouseleave is propietery to IE)

--- src/frontend/cljs/alibi/activity_graphic.cljs
+++ src/frontend/cljs/alibi/activity_graphic.cljs
@@ -330,7 +330,7 @@
                     :y1 (:y-offset draw-result)
                     :y2 (:y-offset draw-result)

-                    :onMouseEnter
+                    :onMouseOver
                     (fn [ev]
                       (let [rect (get-abs-bounding-client-rect
                                    (.-target ev))]
@@ -338,7 +338,7 @@
                           {:entry-id (get-in bar [:bar :entry-id])
                            :pos rect})))

-                    :onMouseLeave #(on-mouse-leave-bar)
+                    :onMouseOut #(on-mouse-leave-bar)

                     :onClick
                     (fn [ev]


Slightly tweaked valid-link? regex as it was overly strict and excluding valid Amazon links. The old formula assumed product ids would only be numeric, which was incorrect.

--- src/hackerati_interval_web_app/views/util.clj
+++ src/hackerati_interval_web_app/views/util.clj
@@ -6,7 +6,7 @@

 (defn valid-link? [link]
   "Returns vector if successful of [link amzn-productid]"
-  (re-find #"[a-z/.]+amazon[a-z/.]+([0-9]{10})[a-z/=_?&-]+" (lower-case link)))
+  (re-find #"[a-z/.]+amazon[a-z/.]+([a-z0-9]{10})[a-z/=_?&-]+" (lower-case link)))

 (defn valid-username? [u]
   (re-find #"^\w{1,30}$" u))


Fix test

Fix test

--- test/fatlip/order_test.cljs
+++ test/fatlip/order_test.cljs
@@ -364,26 +364,28 @@
                     node-2-1 [:b]
                     node-2-2 [:c]}
         succ (Edge. node-0-1 node-2-1 #{:b} 1)
-        pred (Edge. node-2-1 node-0-1 #{:b} 1)
-        marked-1 (Edge. node-0-0 node-1-0 #{:a} 1)
-        marked-2 (Edge. node-1-0 node-0-0 #{:a} 1)
-        marked #{marked-1 marked-2}
-        succs {node-0-0 #{marked-1}
+        marked-1 (Edge. node-0-2 node-1-0 #{:c} 1)
+        marked-2 (Edge. node-1-0 node-0-2 #{:c} 1)
+        marked-3 (Edge. node-1-0 node-2-2 #{:c} 1)
+        marked-4 (Edge. node-2-2 node-1-0 #{:c} 1)
+        marked #{marked-1 marked-2 marked-3 marked-4}
+        succs {node-0-0 #{(Edge. node-0-0 node-1-0 #{:a} 1)}
                node-0-1 #{succ}
-               node-0-2 #{(Edge. node-0-2 node-1-0 #{:c} 1)}
+               node-0-2 #{marked-1}
                node-1-0 #{(Edge. node-1-0 node-2-0 #{:a} 1)
-                          (Edge. node-1-0 node-2-2 #{:c} 1)}}
-        preds {node-1-0 #{marked-2
-                          (Edge. node-1-0 node-0-2 #{:c} 1)}
+                          marked-3}}
+        preds {node-1-0 #{(Edge. node-1-0 node-0-0 #{:a} 1)
+                          marked-2}
                node-2-0 #{(Edge. node-2-0 node-1-0 #{:a} 1)}
-               node-2-1 #{pred}
-               node-2-2 #{(Edge. node-2-2 node-1-0 #{:c} 1)}}
+               node-2-1 #{(Edge. node-2-1 node-0-1 #{:b} 1)}
+               node-2-2 #{marked-4}}
         layers [(f/OrderedLayer. 0 0 [node-0-0 node-0-1 node-0-2])
                 (f/OrderedLayer. 1 0 [node-1-0 [succ]])
                 (f/OrderedLayer. 2 0 [node-2-0 node-2-1 node-2-2])]
-        o-graph (f/OrderedGraph. layers succs preds :ps :qs :rs :minus-ps :minus-qs characters)
         succ-seg (Edge->Segment succ 1)
-        pred-seg (Edge->Segment pred 1)]
+        minus-ps [[node-0-0 [succ] node-0-2] [node-1-0 [succ]]]
+        minus-qs [[node-1-0 [succ]] [node-2-0 [succ] node-2-2]]
+        o-graph (f/OrderedGraph. layers succs preds #{} #{} #{} minus-ps minus-qs characters)]
     (is (= (f/OrderedGraph->FlatGraph o-graph)
            (f/map->FlatGraph {:layers [(f/FlatLayer. 0 0 [node-0-0 node-0-1 node-0-2])
                                        (f/FlatLayer. 1 0 [node-1-0 succ-seg])
@@ -417,6 +419,6 @@
                                          node-2-1 1
                                          node-2-2 0}
                               :marked marked
-                              :crossings 0
+                              :crossings 2
                               :characters characters}))
         "Counted and marked graphs are converted to flat graphs")))


delete dummy tests

delete dummy tests

--- test/greybear/core_test.clj
+++ test/greybear/core_test.clj
@@ -1,7 +0,0 @@
-(ns greybear.core-test
-  (:use clojure.test
-        greybear.core))
-
-(deftest a-test
-  (testing "FIXME, I fail."
-    (is (= 0 1))))


Fixing publish

Fixing publish

--- server/src/spacon/components/mqtt/core.clj
+++ server/src/spacon/components/mqtt/core.clj
@@ -113,7 +113,7 @@
   (log/debugf "Publishing to topic %s %nmessage: %s" topic message)
   (prn message)
   (try
-    (mh/publish (:conn mqtt-comp) topic message)
+    (mh/publish (:conn mqtt-comp) topic (msg/message->bytes message))
     (catch Exception e
       (log/error "Could not publish b/c" (.getLocalizedMessage e)))))


updated tests for previous commits

updated tests for previous commits

--- test/papaline/core_test.clj
+++ test/papaline/core_test.clj
@@ -73,6 +73,9 @@
 (deftest test-fork-join
   (let [fork-stage (fn [] (fork (take 5 (repeat [1]))))
         join-inc-stage (fn [i] (join (inc i)))
-        combine-stage (fn [l] (reduce + (flatten l)))]
+        combine-stage (fn [& l] (reduce + l))]
     (is (= 10 (run-pipeline-wait
-               (pipeline [fork-stage join-inc-stage combine-stage]))))))
+               (pipeline [fork-stage join-inc-stage combine-stage]))))
+    (is (= [2 2 2 2 2]
+           (run-pipeline-wait
+            (pipeline [fork-stage join-inc-stage]))))))


print-method for JSValue

print-method for JSValue

--- test/cljs/go_test.clj
+++ test/cljs/go_test.clj
@@ -5,7 +5,13 @@
             [clojure.string :as s]
             [clojure.java.io :as io]
             [clojure.java.shell :as sh])
-  (:import [java.io File]))
+  (:import [java.io File Writer]
+           [cljs.tagged_literals JSValue]))
+
+(defmethod print-method cljs.tagged_literals.JSValue
+  [^JSValue d ^Writer w]
+  (.write w "#js ")
+  (print-method (.val d) w))

 (defmacro emit [& body]
   `(let [res# (emit-go* '~body)]


Improved test documentation

Improved test documentation

--- test/hyjinks_test.clj
+++ test/hyjinks_test.clj
@@ -3,34 +3,66 @@
 (use 'hyjinks)
 (use 'clojure.test)

-(defn is=str [& xs] (is (apply = (map str xs))))
+(defn is=str
+	"Asserts that all values in `xs` have equivalent `str` values"
+	[& xs] (is (apply = (map str xs))))

-(deftest to-str
+(defmacro should-fail [expr]
+	`(try ~expr false (catch java.lang.AssertionError e# true)))
+
+(deftest feature-tour
+
+	; Each tag has a function named for it
 	(is=str
 		(p "Content")
 		"
Content
")
 	(is=str
+		(ol (li "Monday") (li "Tuesday") (li "Wednesday"))
+		"

Monday

Tuesday

Wednesday

")
+
+	; Tag attributes can be specified with hash-maps
+	(is=str
 		(p {:attr :value} "Content")
 		"
Content
")
+
+	; Tags can be composed like normal functions
 	(is=str
 		(ul (map li ["A" "B" "C"]))
 		"

A

B

C

")
+
+	; String content gets escaped, unless it's a literal
 	(is=str
 		(p "<Content>")
 		"
<Content>
")
 	(is=str
 		(p (literal "<Content>"))
 		"
<Content>
")
+
+	; Empty tags have trailing '/' for XHTML compliance
 	(is=str
 		(p (tag "Content"))
 		"
<Content />
")
+
+	; CSS can be applied with a CSS object
 	(is=str
 		(div (css :color :red) (br))
 		"

")
-	(is=str (p) (p "") (p nil) (p "" nil))
+
+	; Empty strings and nil get ignored
+	(is=str
+		(p)
+		(p "")
+		(p nil)
+		(p "" nil))
+	(is=str
+		(div "A" "" nil "B" "")
+		(div nil nil "A" "B" ""))

 	; Tag can just be a constant if it doesn't need arguments
-	(is=str (br) br)
+	(is=str
+		(br)
+		br
+		"
")

 	; CSS properties can be constants if they don't need arguments
 	; And can be used as functions
@@ -49,7 +81,7 @@
 		(div (transform (rotate 45) (skew 10 15))))

 	; But Tags shouldn't be anywhere else
-	(is (thrown? java.lang.AssertionError (transform (rotate 45) div (skew 10 15))))
+	(should-fail (transform (rotate 45) div (skew 10 15)))

 	; This test is essentially broken as attributes are sorted
 	; by hash function and not in any user-reasonable manner.
@@ -72,6 +104,8 @@
 	(is=str
 		((div (center)) (color :red))
 		(div (center) (color :red)))
+
+	; This allows for easy specialization of tags
 	(def special-div (div {:class "special"} (center)))
 	(is=str
 		(special-div "Hi")


fix misplaced parentheis in test/symbol_solver

--- test/app/test/symbol_solver.clj
+++ test/app/test/symbol_solver.clj
@@ -11,9 +11,9 @@
   (first (filter (fn [c] (= name (.getName c))) sampleClasses)))

 (deftest testPreceedingChildren
-  (is (= '(1 2 3 4)) (preceedingChildren [1 2 3 4 5] 5))
-  (is (= '(1 2)) (preceedingChildren [1 2 3 4 5] 3))
-  (is (= '()) (preceedingChildren [1 2 3 4 5] 1)))
+  (is (= '(1 2 3 4) (preceedingChildren [1 2 3 4 5] 5)))
+  (is (= '(1 2) (preceedingChildren [1 2 3 4 5] 3)))
+  (is (= '() (preceedingChildren [1 2 3 4 5] 1))))

 (deftest testSolveNameInVariableDeclarator
   (let [aClassResolvingToLocalVar (sampleClass "AClassResolvingToLocalVar")


adds tests for template functions

adds tests for template functions

--- test/doctopus/template_test.clj
+++ test/doctopus/template_test.clj
@@ -6,6 +6,24 @@
             [net.cgrand.enlive-html :as enlive]))

 (deftest template
-  (testing "add-frame injects an iframe in the body element"
-    (is (not (nil? (re-find #"\\\"
-                            (add-frame "")))))))
+  (testing "append inserts html at end of selection"
+    (is (= "
test

inserted
"
+           (#'doctopus.template/append-to-element
+             "
test
"
+             :body
+             (enlive/html [:div "inserted"])))))
+
+  (testing "prepend inserts html at beginning of selection"
+    (is (= "
inserted

test
"
+           (#'doctopus.template/prepend-to-element
+             "
test
"
+             :body
+             (enlive/html [:div "inserted"])))))
+
+  (testing "add-omnibar inserts omnibar and context into existing html"
+    (is (not (nil? (re-find #"omnibar"
+                            (add-omnibar "" {})))))
+    (is (not (nil? (re-find #"muh-context"
+                            (add-omnibar ""
+                                         {:muh-context true})))))))
+


Improve the way `sel` and `sel-fn` handle runtime entity resolution (an edge case, but needed in certain situations to avoid circular dependencies). Now correctly applies `default-fields` (etc.)

--- src/metabase/db.clj
+++ src/metabase/db.clj
@@ -91,12 +91,7 @@
    By default, `sel` will return `default-fields` for `entity` (or all fields if `default-fields` isn't specified),
    but you can override this behavior by passing `entity` as a vector like `[entity & field-keys]`.

-   `(sel :many [OrgPerm :admin :id] :user_id 1)` -> return admin and id of OrgPerms whose user_id is 1
-
-   If you run into issues with cyclic dependencies, you can optionally pass ENTITY as a fully-qualified string.
-   `(sel :one \"metabase.models.user/User\" :id user_id)`
-   This should be avoided when possible since ENTITY is resolved at runtime, which adds overhead.
-   NOTE: currently, `default-fields` functionality doesn't work if you pass entity as a string :/"
+   `(sel :many [OrgPerm :admin :id] :user_id 1) -> return admin and id of OrgPerms whose user_id is 1"
   [one-or-many entity & kwargs]
   (let [quantity-fn (case one-or-many
                       :one first
@@ -104,20 +99,25 @@
         [entity & field-keys] (if (vector? entity) entity
                                   [entity])
         field-keys (or field-keys
-                       (default-fields (eval entity)))
-        entity (if (string? entity) `(fn [] (resolve-symbol-with-name ~entity))
-                   `(fn [] ~entity))]
-    `(let [entity# (~entity)]
-       (->> (select entity#
-                    (where ~(apply assoc {} kwargs))
-                    ~@(when field-keys
-                        `[(fields ~@field-keys)]))
-            (map (partial post-select entity#))
-            ~quantity-fn))))
+                       (default-fields (eval entity)))]
+    `(->> (select ~entity
+                  (where ~(apply assoc {} kwargs))
+                  ~@(when field-keys
+                      `[(fields ~@field-keys)]))
+          (map (partial post-select ~entity))
+          ~quantity-fn)))

 (defmacro sel-fn
-  "Returns a memoized fn that calls `sel`"
+  "Returns a memoized fn that calls `sel`.
+
+   ENTITY may optionally be a fully-qualified string name of an entity; in this case, the symbol's namespace
+   will be required and the symbol itself resolved at runtime. This is sometimes neccesary to avoid circular
+   dependencies in the model files. This is slower, however, due to added runtime overhead."
   [one-or-many entity & kwargs]
   `(memoize
     (fn []
-      (sel ~one-or-many ~entity ~@kwargs))))
+      ~@(if (string? entity)
+          `((require '~(-> entity (^String .split "/") first symbol)) ; require the namespace
+            (let [entity# (symbol ~entity)]
+              (eval `(sel ~~one-or-many ~entity# ~~@kwargs))))
+          `((sel ~one-or-many ~entity ~@kwargs))))))


removed bad test.

removed bad test.

--- test/forma/source/fire_test.clj
+++ test/forma/source/fire_test.clj
@@ -2,8 +2,6 @@
   (:use forma.source.fire
         cascalog.api
         midje.sweet))
-
-(fact (+ 1 1) => 3)

 (def fire-tap
   (memory-source-tap


Fixed issue #25

Fixed issue #25

--- src/alfresco_technical_validation/impl/binary_validation.clj
+++ src/alfresco_technical_validation/impl/binary_validation.clj
@@ -307,10 +307,12 @@
                            AND NOT(n.package =~ 'com.sap..*')
                            AND NOT(n.package =~ 'com.sun..*')
                            AND HAS(m.package)
-                           AND m.package IN [
-                                              'javax.servlet',
-                                              'javax.servlet.http'
-                                            ]
+                           AND m.name IN [
+                                           'javax.servlet.Servlet',
+                                           'javax.servlet.GenericServlet',
+                                           'javax.servlet.http.HttpServlet',
+                                           'javax.servlet.Filter'
+                                         ]
                         RETURN n.name AS ClassName, COLLECT(DISTINCT m.name) AS APIs
                          ORDER BY n.name
                        ")]


Ensure autocommit is off

Ensure autocommit is off

--- src/rdf-repository/grafter/rdf/repository.clj
+++ src/rdf-repository/grafter/rdf/repository.clj
@@ -318,7 +318,9 @@
   [^Repository repo]
   (if (instance? RepositoryConnection repo)
     repo
-    (.getConnection repo)))
+    (let [c (.getConnection repo)]
+      (.setAutoCommit c false)
+      c)))

 (defn prepare-query
   "Low level function to prepare (parse, but not process) a sesame RDF


Improve test brittleness.

Improve test brittleness.

--- test/onyx/metrics/send_test.clj
+++ test/onyx/metrics/send_test.clj
@@ -122,5 +122,6 @@
                 (is (= :done (last results)))
                 (is (> (count @events) (* 3 ; number of tasks
                                           (/ (- end-time start-time) 1000)
-                                          ;; 4 events every second + 8 events ever 10 seconds, round up a little
-                                          4.2)))))))))))
+                                          ;; 4 events every second + 8 events ever 10 seconds, round down a little
+                                          ;; because of test brittleness
+                                          4.1)))))))))))


Add a few more tests for track

Add a few more tests for track

--- test/reagenttest/testtrack.cljs
+++ test/reagenttest/testtrack.cljs
@@ -227,3 +227,70 @@
        (is (= @catch-count 1))))
     (dispose c)
     (is (= runs (running)))))
+
+(deftest track-equality
+  (let [f1 (fn [])
+        f2 (fn [])
+        t r/track]
+    (is (= (t f1) (t f1)))
+    (is (not= (t f1) (t f2)))
+    (is (not= (hash (t f1)) (hash (t f2))))
+    (is (= (t f1 "foo") (t f1 "foo")))
+    (is (not= (t f2 "foo") (t f1 "foo")))
+    (is (not= (t f1 "foo") (t f1 "foobar")))
+    (is (= (t f1 "foo" 1) (t f1 "foo" 1)))
+    (is (not= (t f1 "foo" 2) (t f1 "foo" 1)))
+    (is (= (t f1 2 "foo" 1) (t f1 2 "foo" 1)))
+    (is (not= (t f1 2 "foo" 1) (t f2 2 "foo" 1)))
+    (is (not= (t f1 2 "foo" 1) (t f1 2 "foo" 3)))
+    (is (not= (hash (t f1 2 "foo" 1)) (hash (t f1 2 "foo" 3))))))
+
+(deftest track-identity
+  (let [runs (running)
+        ts (atom {})
+        t r/track
+        trigger (r/atom 1)
+        f1 (fn [& args]
+             (r/with-let [k [:f1 args]
+                          _ (is (nil? (@ts k)))
+                          _ (swap! ts assoc k k)]
+               @trigger
+               (finally
+                 (is (= k (@ts k)))
+                 (swap! ts dissoc k))))
+        f2' (fn [& args]
+              (r/with-let [k [(t f1) args]
+                           _ (is (nil? (@ts k)))
+                           _ (swap! ts assoc k k)]
+                @trigger
+                (finally
+                  (is (= k (@ts k)))
+                  (swap! ts dissoc k))))
+        f2 (fn [& args]
+             @(apply t f2' args))
+        refs (r/atom nil)
+        run (r/track! #(doseq [i @refs]
+                         @i))
+        check (fn [n & args]
+                (reset! refs args)
+                (r/flush)
+                (is (= (count @ts) n))
+                (swap! trigger inc)
+                (r/flush)
+                (is (= (count @ts) n)))]
+    (check 1 (t f1))
+    (check 1 (t f1) (t f1))
+    (check 2 (t f1) (t f1 1))
+    (check 2 (t f1 1) (t f1 1) (t f1 2))
+    (check 2 (t f1 1) (t f1 1) (t f2 1))
+    (check 0)
+    (check 2 (t f2 1) (t f2 1) (t f1 1))
+    (check 2 (t f2 2) (t f2 2) (t f1 2))
+    (check 2 (t f2 2 3) (t f2 2 3) (t f1 2 3))
+    (check 1 (t f2 2 3) (t f2 2 3) (t f2 2 3))
+    (check 5 (t f1) (t f1 1) (t f1 2) (t f1 1 2) (t f1 1 2 3))
+    (check 4 (t f1) (t f1 1) (t f1 2) (t f1 1 2) (t f1 1 2))
+
+    (r/dispose! run)
+    (is (= 0 (count @ts)))
+    (is (= runs (running)))))


CMR-348: Added additional tests with rational numbers.

--- test/cmr/system_int_test/search/granule_orbit_number_search_test.clj
+++ test/cmr/system_int_test/search/granule_orbit_number_search_test.clj
@@ -16,63 +16,39 @@
   (let [coll1 (d/ingest "CMR_PROV1" (dc/collection {}))
         gran1 (d/ingest "CMR_PROV1"
                         (dg/granule coll1
-                                    {:granule-ur "Granule1"
-                                     :orbit-calculated-spatial-domains [ {:orbital-model-name "OrbitalModelName"
-                                                                          :orbit-number  1
+                                    {:orbit-calculated-spatial-domains [ {:orbit-number  1
                                                                           :start-orbit-number 1.0
                                                                           :stop-orbit-number 1.0
-                                                                          :equator-crossing-longitude 0
                                                                           :equator-crossing-date-time "2011-02-01T12:00:00Z"}]}))
         gran2 (d/ingest "CMR_PROV1"
                         (dg/granule coll1
-                                    {:granule-ur "Granule2"
-                                     :orbit-calculated-spatial-domains [{:orbital-model-name "OrbitalModelName"
-                                                                         :orbit-number  1
-                                                                         :start-orbit-number nil
-                                                                         :stop-orbit-number nil
-                                                                         :equator-crossing-longitude 0
+                                    {:orbit-calculated-spatial-domains [{:orbit-number  1
                                                                          :equator-crossing-date-time "2011-02-01T12:00:00Z"}]}))
         gran3 (d/ingest "CMR_PROV1"
                         (dg/granule coll1
-                                    {:granule-ur "Granule3"
-                                     :orbit-calculated-spatial-domains [{:orbital-model-name "OrbitalModelName"
-                                                                         :orbit-number  nil
-                                                                         :start-orbit-number 1.0
+                                    {:orbit-calculated-spatial-domains [{:start-orbit-number 1.0
                                                                          :stop-orbit-number 1.0
-                                                                         :equator-crossing-longitude 0
                                                                          :equator-crossing-date-time "2011-02-01T12:00:00Z"}]}))
         gran4 (d/ingest "CMR_PROV1"
                         (dg/granule coll1
-                                    {:granule-ur "Granule4"
-                                     :orbit-calculated-spatial-domains [{:orbital-model-name "OrbitalModelName"
-                                                                         :orbit-number  2
+                                    {:orbit-calculated-spatial-domains [{:orbit-number  2
                                                                          :start-orbit-number 2.0
                                                                          :stop-orbit-number 3.0
-                                                                         :equator-crossing-longitude 0
                                                                          :equator-crossing-date-time "2011-02-01T12:00:00Z"}]}))
         gran5 (d/ingest "CMR_PROV1"
                         (dg/granule coll1
-                                    {:granule-ur "Granule5"
-                                     :orbit-calculated-spatial-domains [{:orbital-model-name "OrbitalModelName"
-                                                                         :orbit-number  nil
-                                                                         :start-orbit-number 2.0
-                                                                         :stop-orbit-number 3.0
+                                    {:orbit-calculated-spatial-domains [{:start-orbit-number 2.7
+                                                                         :stop-orbit-number 3.5
                                                                          :equator-crossing-longitude 0
                                                                          :equator-crossing-date-time "2011-02-01T12:00:00Z"}]}))
         gran6 (d/ingest "CMR_PROV1"
                         (dg/granule coll1
-                                    {:granule-ur "Granule6"
-                                     :orbit-calculated-spatial-domains [{:orbital-model-name "OrbitalModelName"
-                                                                         :orbit-number  nil
-                                                                         :start-orbit-number 4.0
+                                    {:orbit-calculated-spatial-domains [{:start-orbit-number 4.0
                                                                          :stop-orbit-number 5.0
-                                                                         :equator-crossing-longitude 0
                                                                          :equator-crossing-date-time "2011-02-01T12:00:00Z"}]}))
         gran7 (d/ingest "CMR_PROV1"
                         (dg/granule coll1
-                                    {:granule-ur "Granule6"
-                                     :orbit-calculated-spatial-domains [{:orbital-model-name "OrbitalModelName"
-                                                                         :orbit-number  nil
+                                    {:orbit-calculated-spatial-domains [{:orbital-model-name "OrbitalModelName"
                                                                          :start-orbit-number 7.0
                                                                          :stop-orbit-number 10.0
                                                                          :equator-crossing-longitude 0
@@ -80,24 +56,25 @@
     (index/flush-elastic-index)

     (testing "search by exact orbit number"
-      (let [references (search/find-refs :granule
-                                         {:orbit-number 1})]
+      (let [references (search/find-refs :granule {:orbit-number 1})]
         (is (d/refs-match? [gran1 gran2 gran3] references))))
     (testing "search by orbit number range"
-      (let [references (search/find-refs :granule
-                                         {:orbit-number "1,2"})]
-        (is (d/refs-match? [gran1, gran2, gran3, gran4, gran5] references))))
+      (let [references (search/find-refs :granule {:orbit-number "1,2"})]
+        (is (d/refs-match? [gran1, gran2, gran3, gran4] references))))
+    (testing "search by orbit number range with rational numbers"
+      (let [references (search/find-refs :granule {:orbit-number "2,2.8"})]
+        (is (d/refs-match? [gran4, gran5] references))))
+    (testing "search by orbit number range with min and max rational numbers"
+      (let [references (search/find-refs :granule {:orbit-number "4.5,7.7"})]
+        (is (d/refs-match? [gran6 gran7] references))))
     (testing "search by orbit number range inside"
-      (let [references (search/find-refs :granule
-                                         {:orbit-number "8,9"})]
+      (let [references (search/find-refs :granule {:orbit-number "8,9"})]
         (is (d/refs-match? [gran7] references))))
     (testing "search by unused orbit number returns nothing"
-      (let [references (search/find-refs :granule
-                                         {:orbit-number "15"})]
+      (let [references (search/find-refs :granule {:orbit-number "15"})]
         (is (d/refs-match? [] references))))
     (testing "search by unused orbit number range returns nothing"
-      (let [references (search/find-refs :granule
-                                         {:orbit-number "17,18"})]
+      (let [references (search/find-refs :granule {:orbit-number "17,18"})]
         (is (d/refs-match? [] references))))
     (testing "invalid orbit number range"
       (let [{:keys [status errors]} (search/find-refs :granule {:orbit-number "2,1"})]


Fix a test that was slightly wrong

Fix a test that was slightly wrong

The ex-fn is not supposed to throw the exception; the test was
passing anyways though since it couldn't tell who was throwing it.

--- src/test/clojure/clojure/test/check/test.cljc
+++ src/test/clojure/clojure/test/check/test.cljc
@@ -309,7 +309,7 @@
                           (gen/vector gen/boolean 5)
                           {:ex-fn (fn [{:keys [pred gen max-tries]}]
                                     (is (and pred gen max-tries))
-                                    (throw (#?(:clj Exception. :cljs js/Error.) "Oh well!")))})))))
+                                    (#?(:clj Exception. :cljs js/Error.) "Oh well!"))})))))

 ;; Distinct collections
 ;; --------------------------------------------------------------------------


Use assert-no-problems in no-error Source tests

--- test/vip/data_processor/validation/v5/source_test.clj
+++ test/vip/data_processor/validation/v5/source_test.clj
@@ -23,7 +23,7 @@
                           xml/load-xml-ltree
                           v5.source/validate-one-source]}
           out-ctx (pipeline/run-pipeline ctx)]
-      (is (not (get-in out-ctx [:fatal :source "VipObject.0.Source" :count]))))))
+      (assert-no-problems out-ctx []))))

 (deftest ^:postgres validate-name-test
   (testing "missing Name is a fatal error"
@@ -40,14 +40,14 @@
                           xml/load-xml-ltree
                           v5.source/validate-name]}
           out-ctx (pipeline/run-pipeline ctx)]
-      (is (not (:fatal out-ctx)))))
+      (assert-no-problems out-ctx [])))
   (testing "Name present is OK even if it's not first"
     (let [ctx {:input (xml-input "v5-source-second-with-name-second.xml")
                :pipeline [psql/start-run
                           xml/load-xml-ltree
                           v5.source/validate-name]}
           out-ctx (pipeline/run-pipeline ctx)]
-      (is (not (:fatal out-ctx))))))
+      (assert-no-problems out-ctx []))))

 (deftest ^:postgres validate-date-time-test
   (testing "missing DateTime is a fatal error"
@@ -64,14 +64,14 @@
                           xml/load-xml-ltree
                           v5.source/validate-date-time]}
           out-ctx (pipeline/run-pipeline ctx)]
-      (is (not (:fatal out-ctx)))))
+      (assert-no-problems out-ctx [])))
   (testing "DateTime present is OK even if it's not first"
     (let [ctx {:input (xml-input "v5-source-second-with-date-time-second.xml")
                :pipeline [psql/start-run
                           xml/load-xml-ltree
                           v5.source/validate-date-time]}
           out-ctx (pipeline/run-pipeline ctx)]
-      (is (not (:fatal out-ctx))))))
+      (assert-no-problems out-ctx []))))

 (deftest ^:postgres validate-vip-id-test
   (testing "missing VipId is a fatal error"
@@ -88,7 +88,7 @@
                           xml/load-xml-ltree
                           v5.source/validate-vip-id]}
           out-ctx (pipeline/run-pipeline ctx)]
-      (is (not (:fatal out-ctx))))))
+      (assert-no-problems out-ctx []))))

 (deftest ^:postgres validate-vip-id-valid-fips-test
   (testing "invalid 2-digit FIPS in VipId is a critical error"
@@ -105,7 +105,7 @@
                           xml/load-xml-ltree
                           v5.source/validate-vip-id-valid-fips]}
           out-ctx (pipeline/run-pipeline ctx)]
-      (is (not (:critical out-ctx)))))
+      (assert-no-problems out-ctx [])))
   (testing "invalid 5-digit FIPS in VipId is a critical error"
     (let [ctx {:input (xml-input "v5-source-vip-id-invalid-5-digit-fips.xml")
                :pipeline [psql/start-run
@@ -120,4 +120,4 @@
                           xml/load-xml-ltree
                           v5.source/validate-vip-id-valid-fips]}
           out-ctx (pipeline/run-pipeline ctx)]
-      (is (not (:critical out-ctx))))))
+      (assert-no-problems out-ctx []))))


Fix other tests.

Fix other tests.


clojure.spec: Can use arbitrary functions as specs

--- test/com/nomistech/clojure_the_language/c_200_clojure_basics/s_600_clojure_spec.clj
+++ test/com/nomistech/clojure_the_language/c_200_clojure_basics/s_600_clojure_spec.clj
@@ -1,6 +1,7 @@
 (ns com.nomistech.clojure-the-language.c-200-clojure-basics.s-600-clojure-spec
   (:require [clojure.spec.alpha :as s]
-            [midje.sweet :refer :all]))
+            [midje.sweet :refer :all])
+  (:import java.util.Date))

 ;;;; ___________________________________________________________________________
 ;;;; Stuff from https://clojure.org/guides/spec
@@ -12,3 +13,15 @@
 (fact "Intro to `valid?`: spec X value -> boolean"
   (fact (s/valid? even? 1000) => true)
   (fact (s/valid? even? 1001) => false))
+
+(fact "Can use arbitrary functions as specs"
+  (fact (s/valid? nil? nil) => true)
+  (fact (s/valid? string? "abc") => true)
+  (fact (s/valid? #(> % 5) 10) => true)
+  (fact (s/valid? #(> % 5) 0) => false)
+  (fact (s/valid? inst? (Date.)) => true))
+
+(fact "Can use sets as predicates (because sets are functions)"
+  (fact (s/valid? #{:club :diamond :heart :spade} :club) => true)
+  (fact (s/valid? #{:club :diamond :heart :spade} 42) => false)
+  (fact (s/valid? #{42} 42) => true))


insights: print *median* timings

insights: print *median* timings

--- src-cljs/frontend/components/insights.cljs
+++ src-cljs/frontend/components/insights.cljs
@@ -219,10 +219,17 @@
        (map add-queued-time)
        (take (:max-bars plot-info))))

-(defn average-builds [builds f]
+(defn median-builds [builds f]
   (let [nums (->> builds
-                  (map f))]
-    (/ (apply + nums) (count nums))))
+                  (map f)
+                  sort)
+        c (count nums)
+        mid-i (js/Math.floor (/ c 2))]
+    (if (odd? c)
+      (nth nums mid-i)
+      (/ (+ (nth nums mid-i)
+            (nth nums (dec mid-i)))
+         2))))

 (defn project-insights-bar [builds owner]
   (reify
@@ -250,11 +257,11 @@
           [:h4 "Branch: " branch]
           [:div.above-info
            [:dl
-            [:dt "AVG BUILD"]
-            [:dd (datetime/as-duration (average-builds builds :build_time_millis))]]
-           [:dl
-            [:dt "AVG QUEUE"]
-            [:dd (datetime/as-duration (average-builds builds :queued_time_millis))]]
+            [:dt "MEDIAN BUILD"]
+            [:dd (datetime/as-duration (median-builds builds :build_time_millis))]]
+           [:dl
+            [:dt "MEDIAN QUEUE"]
+            [:dd (datetime/as-duration (median-builds builds :queued_time_millis))]]
            [:dl
             [:dt "LAST BUILD"]
             [:dd (datetime/as-time-since (-> builds last :start_time))]]]


cleanup; Loader alignment

cleanup; Loader alignment

--- src/visuals/untangled/ui/element_visuals.cljs
+++ src/visuals/untangled/ui/element_visuals.cljs
@@ -164,11 +164,11 @@

 (defcard loader-visual-regressions
   (l/row {}
-    (l/col {:width 4}
+    (l/col {:width 4 :halign :center}
       (e/ui-loader {}))
-    (l/col {:width 4}
+    (l/col {:width 4 :halign :center}
       (e/ui-loader {:color :primary}))
-    (l/col {:width 4}
+    (l/col {:width 4 :halign :center}
       (e/ui-loader {:color :accent}))))


test the rest of voke.input

test the rest of voke.input

--- test/voke/input_test.cljs
+++ test/voke/input_test.cljs
@@ -143,6 +143,24 @@
                        nil)))))))
       (done))))

+(deftest remove-conflicting-directions
+  (is (= (input/remove-conflicting-directions #{:down :left :right})
+         #{:down}))
+  (is (= (input/remove-conflicting-directions #{:down :left :right :up})
+         #{}))
+  (is (= (input/remove-conflicting-directions #{:down})
+         #{:down}))
+  (is (= (input/remove-conflicting-directions #{:down :up})
+         #{}))
+  (is (= (input/remove-conflicting-directions #{})
+         #{})))

-; test handle-conflicting
-; test intended->angle
+(deftest intended-directions->angle
+  (is (= (input/intended-directions->angle [:left])
+         Math/PI))
+  (is (= (input/intended-directions->angle [:right])
+         0))
+  (is (= (input/intended-directions->angle [:up :right])
+         (- (/ Math/PI 4))))
+  (is (= (input/intended-directions->angle [:down :left])
+         (/ (* 3 Math/PI) 4))))


(PE-2557) Update shutdown-app to use new run API

--- test-resources/shutdown_app/test_shutdown.clj
+++ test-resources/shutdown_app/test_shutdown.clj
@@ -8,9 +8,9 @@

 (defn -main
   [& args]
-  (trapperkeeper/bootstrap
-    {:config "./test-resources/config/empty.ini"
-     :bootstrap-config "test-resources/shutdown_app/bootstrap.cfg"})
-  (println "Waiting 60 seconds for a shutdown signal - use Ctrl-C or kill.")
-  (println "You should see a message printed out when services are being shutdown.")
-  (Thread/sleep 60000))
+  (let [app (trapperkeeper/bootstrap
+              {:config "./test-resources/config/empty.ini"
+               :bootstrap-config "test-resources/shutdown_app/bootstrap.cfg"})]
+    (println "Waiting for a shutdown signal - use Ctrl-C or kill.")
+    (println "You should see a message printed out when services are being shutdown.")
+    (trapperkeeper/run-app app)))


lets validate even edit form

lets validate even edit form

--- src/cljs/swarmpit/component/service/edit.cljs
+++ src/cljs/swarmpit/component/service/edit.cljs
@@ -139,9 +139,10 @@
    (comp/form-section "Deployment")
    (deployment/form)])

-(rum/defc form < rum/static
+(rum/defc form < rum/reactive
                  init-state-mixin [data]
-  (let [{:keys [service]} data]
+  (let [{:keys [service]} data
+        resources (state/react resources/cursor)]
     [:div
      [:div.form-panel
       [:div.form-panel-left
@@ -152,6 +153,7 @@
          (comp/raised-button
            {:onTouchTap #(update-service-handler (:id service))
             :label      "Save"
+            :disabled   (not (:isValid resources))
             :primary    true}))
        [:span.form-panel-delimiter]
        (comp/mui


CMR-2891 pull request comments

CMR-2891 pull request comments

--- access-control-app/src/cmr/access_control/services/acl_validation.clj
+++ access-control-app/src/cmr/access_control/services/acl_validation.clj
@@ -179,7 +179,7 @@
     permission))

 (defn get-acls-by-condition
-  ""
+  "Returns user in context, sids of user, and search items returned using condition"
   [context condition]
   (let [token (:token context)
         user (if token (tokens/get-user-id context token) "guest")
@@ -227,15 +227,18 @@
   [context key-path system-identity]
   (let [condition (qm/string-condition :identity-type "System" true false)
         response (get-acls-by-condition context condition)
-        any-acl-system-acl (acl/echo-style-acl (first (filter #(= "ANY_ACL" (:target (:system-identity %))) (:items response))))]
-    (when-not (or (transmit-config/echo-system-token? context) (acl/acl-matches-sids-and-permission? (:sids response) "create" any-acl-system-acl))
+        any-acl-system-acl (acl/echo-style-acl
+                             (first (filter #(= "ANY_ACL" (:target (:system-identity %))) (:items response))))]
+    (when-not (or (transmit-config/echo-system-token? context)
+                  (acl/acl-matches-sids-and-permission? (:sids response) "create" any-acl-system-acl))
       {key-path [(format "User [%s] does not have permission to create a system level ACL" (:user response))]})))

 (defn make-system-identity-validations
   "Returns validations for ACLs with a System identity"
   [context action]
   (when (= :create action)
-    [#(system-identity-create-permission-validation context %1 %2)]))
+    [(fn [key-path system-identity]
+       (system-identity-create-permission-validation context key-path system-identity))]))

 (defn validate-provider-exists
   "Validates that the acl provider exists."


`shuffle` is not like `like`

`shuffle` is not like `like`

--- cljs/sledge/core.cljs
+++ cljs/sledge/core.cljs
@@ -432,15 +432,19 @@
 (defn parse-search-term [string]
   (let [[term value] (string/split string #": *")]
     (if value
-      [:like term value]
+      (if (= term "shuffle")
+        [:shuffle value]
+        [:like term value])
       [:like "_content" string])))

 (deftest parse-search-test
   (is (= (parse-search-term "hello") [:like "_content" "hello"]))
-  (is (= (parse-search-term "shuffle: wibble fish")
-         [:like "shuffle" "wibble fish"]))
-  (is (= (parse-search-term "shuffle:noblank pshaw")
-         [:like "shuffle" "noblank pshaw"])))
+  (is (= (parse-search-term "artist: wibble fish")
+         [:like "artist" "wibble fish"]))
+  (is (= (parse-search-term "shuffle: clockwork orange")
+         [:shuffle "clockwork orange"]))
+  (is (= (parse-search-term "artist:noblank pshaw")
+         [:like "artist" "noblank pshaw"])))

 (defn search-entry-view [term owner]
   (reify


Display pretty circles.

Display pretty circles.

--- src/ai_playground/client/core.cljs
+++ src/ai_playground/client/core.cljs
@@ -13,17 +13,35 @@
 (pm/defpartial canvas []
   [:svg:svg {:width 800 :height 400}])

-(pm/defpartial item [x]
-  [:svg:circle {:r (* 2 x)}])
+(pm/defpartial item [[x y]]
+  [:svg:circle {:r (+ 4 (rand 4)) :cx x :cy y}])

 (dom/append (dom/query "body") (canvas))

-(def items (range 10))
+(def lines (for [x (range 0 780 20)
+                 y (range 0 380 20)
+                 d [0 20]]
+             [(+ x 10) (+ y 10) (+ x 10 d) (+ y 10 (- 20 d))]))
+
+(pm/defpartial line [[x1 y1 x2 y2]]
+  [:svg:line {:x1 x1 :y1 y1 :x2 x2 :y2 y2}])
+
+(-> (vis/visual lines)
+    (vis/elem line)
+    (vis/attr :stroke "#333")
+    (vis/enter (partial dom/append (dom/query "svg"))))
+
+(def items (for [x (range 0 800 20)
+                 y (range 0 400 20)]
+             [(+ x 10) (+ y 10)]))
+
+(def colors ["#b58900" "#cb4b16" "#dc322f" "#d33682" "#6c71c4" "#268bd2" "#2aa198" "#859900"])

 (-> (vis/visual items)
   (vis/elem item)
   (vis/attr :stroke "#333")
-  (vis/attr :fill "#777")
-  (vis/attr :cx #(+ 20 (rand-int 800)))
-  (vis/attr :cy #(+ 80 (* 10 (mod % 4))))
-  (vis/enter (partial dom/append (dom/query "svg"))))+  (vis/attr :fill #(rand-nth colors))
+;  (vis/attr :cx first)
+;  (vis/attr :cy second)
+  (vis/enter (partial dom/append (dom/query "svg"))))
+


role needs to be removed from instance profile

--- src/shuppet/iam.clj
+++ src/shuppet/iam.clj
@@ -184,4 +184,5 @@
     (doseq [p-name p-names]
       (process :DeleteRolePolicy {"RoleName" r-name
                                   "PolicyName" p-name}))
+    (process :RemoveRoleFromInstanceProfile {"InstanceProfileName" r-name "RoleName" r-name})
     (process :DeleteRole {"RoleName" r-name})))


added notes to predicate.

added notes to predicate.

--- src/clj/forma/hadoop/predicate.clj
+++ src/clj/forma/hadoop/predicate.clj
@@ -89,6 +89,11 @@

 ;; TODO: Test this in the 3d case. I don't think it's actually doing
 ;; what I want it to be doing. In fact, it fails in any case but 2d.
+;;
+;; I think we need outpos, outval, and then n + 1 other values to
+;; cycle around. We should take in a map of positions <-> dimension
+;; length.
+
 (defn sparse-windower
   "Aggregates cascalog generator values up into multidimensional
   windows of nested vectors of `split-length` based on the supplied


fix Darwin start of turn bug

fix Darwin start of turn bug

--- src/clj/game/cards-icebreakers.clj
+++ src/clj/game/cards-icebreakers.clj
@@ -218,7 +218,7 @@
                                  (strength-pump 1 5)]})

    "Darwin"
-   {:flags {:runner-phase-12 true}
+   {:flags {:runner-phase-12 (req true)}
     :events {:purge {:effect (effect (update-breaker-strength card))}}
     :abilities [(break-sub 2 1 "ice")
                 {:label "Place 1 virus counter (start of turn)"


make it dry

make it dry

--- src/clj/memoria/handlers/cards.clj
+++ src/clj/memoria/handlers/cards.clj
@@ -8,13 +8,17 @@
             [clojure.walk :refer [keywordize-keys]]
             [ring.middleware.json :refer [wrap-json-response]]))

+
+(defn- page-number [params]
+  (Integer. (get params "page" 1)))
+
 (defn index [{:keys [params] :as req}]
   {:status 200
-   :body (cards/latest db/*conn* (Integer. (get params "page" 1)) 10)})
+   :body (cards/latest db/*conn* (page-number params) 10)})

 (defn search [{:keys [params] :as req}]
   (let [q (get params "q")
-        page (Integer. (get params "page" 1))
+        page (page-number params)
         cards (if (nil? q)
                 (cards/latest db/*conn* page 10)
                 (cards/search db/*conn* q page 10))]


Fixed bug in badge assertion

Fixed bug in badge assertion

--- src/clj/salava/badge/assertion.clj
+++ src/clj/salava/badge/assertion.clj
@@ -107,11 +107,11 @@
         verify (or (:verify assertion) {:type "hosted"
                                         :url assertion-url})
         issued-on-raw (or (:issuedOn assertion) (:issued-on assertion) "0")
-        issued-on (if (re-find #"\D" issued-on-raw)
+        issued-on (if (re-find #"\D" (str issued-on-raw))
                     (iso8601-to-unix-time issued-on-raw)
                     issued-on-raw)
         expires-raw (or (:expires assertion) "0")
-        expires (if (re-find #"\D" expires-raw)
+        expires (if (re-find #"\D" (str expires-raw))
                   (iso8601-to-unix-time expires-raw)
                   expires-raw)
         recipient (if (string? (:recipient assertion))


RR: set default lang as current lang on IWillMount

--- src/cljs/hatti/views/dataview.cljs
+++ src/cljs/hatti/views/dataview.cljs
@@ -38,12 +38,15 @@
     om/IWillMount
     (will-mount [_]
       (let [form (om/get-shared owner :flat-form)
-            langs (f/get-languages form)]
+            langs (f/get-languages form)
+            default-lang (f/default-lang langs)]
         (when (f/multilingual? form)
           (shared/transact-app-state!
            shared/app-state
            [:languages]
-           (fn [_] {:all langs :default (f/default-lang langs)})))))
+           (fn [_] {:all langs
+                    :default default-lang
+                    :current default-lang})))))
     om/IRender
     (render [_]
       (let [form (om/get-shared owner :flat-form)


Refactor: wrap in quotes

Refactor: wrap in quotes

--- src/archi/core.clj
+++ src/archi/core.clj
@@ -85,6 +85,8 @@
                            without-desc-path
                            (rest without-desc-path)))))))

+(defn wrap-in-quotes [x]
+  (str "'" x "'"))

 (defn make-scripts [edges]
   (let [edges-by-feature (group-by (comp :feature #(nth % 2)) edges)]
@@ -101,10 +103,10 @@
                             (let [nodes (distinct (sort (mapcat #(take 2 %) edges)))
                                   edges (distinct (sort (map (fn [[n1 n2 m]] (:id m)) edges)))]
                               (str "var nodes = ["
-                                   (apply str (interpose ", " (map (fn [n] (str "'" n "'")) nodes)))
+                                   (apply str (interpose ", " (map wrap-in-quotes nodes)))
                                    "];\n"
                                    "var edges = ["
-                                   (apply str (interpose ", " (map (fn [e] (str "'" e "'")) edges)))
+                                   (apply str (interpose ", " (map wrap-in-quotes edges)))
                                    "];\n"
                                    "var d = {nodes: nodes, edges: edges};\n"
                                    (apply str (for [e edges]


Target guard is no longer nescessary on map db parser

--- src/com/wsscode/pathom/map_db.cljc
+++ src/com/wsscode/pathom/map_db.cljc
@@ -2,9 +2,6 @@
   (:require [com.wsscode.pathom.core :as p]
             [com.wsscode.pathom.specs.query :as spec.query]
             [clojure.spec.alpha :as s]))
-
-(defn target-guard-reader [{:keys [target]}]
-  (when-not target ::p/continue))

 (defn map-db-ident-reader
   [{:keys    [ast]
@@ -53,7 +50,7 @@
         v)
       ::p/continue)))

-(def readers [target-guard-reader map-db-ident-reader map-db-reader])
+(def readers [map-db-ident-reader map-db-reader])

 (s/def ::sort-by-expr
   (s/cat :attr keyword? :direction (s/? #{::asc ::desc})))


fix bug in display of head-initial trees

--- src/babel/html.clj
+++ src/babel/html.clj
@@ -261,7 +261,7 @@
       "
"
       "      "

-      (if (ref? arg)
+      (if (ref? (:head arg))
         (str
          "
"
          (fs/path-to-ref-index serialized (concat path '(:head)) 0)
@@ -270,7 +270,7 @@
       "      	"
       "      H	"

-      (tablize (if (ref? arg)
+      (tablize (if (ref? (:head arg))
                  @(:head arg)
                  (:head arg))
                (concat path '(:head)) serialized opts)


Move notification for stub outputs to ts

--- src/angelic/search/implicit/dash_astar.clj
+++ src/angelic/search/implicit/dash_astar.clj
@@ -176,13 +176,7 @@
     (let [b  (summaries/get-bound stb)
           ts (tree-summarizer stb)]
       (summaries/connect-subsumed! ts sp)
-      (connect-and-watch! ts sp
-        (fn [child-sp]
-          (let [child-ts (sp-ts child-sp)]
-            (assert (tree-summarizer? child-ts))
-            (summaries/connect! ts child-ts)
-            (summaries/connect-subsumed! ts child-ts)
-            (summaries/summary-changed! ts))))
+      (summaries/connect! ts sp)
       (summaries/add-bound! ts b) ;; TODO: ???
       (summaries/summary-changed! ts)))
   (add-output! stb sp))
@@ -253,10 +247,16 @@
 ;; Doing it all with stubs makes subsumption forwarding easier.
 (defn- add-sp-child-stub! [sp child-stub up?]
   (assert (not (terminal? sp)))
-  (connect-and-watch-stub! sp child-stub up?
-    (fn [child-sp]
-      (summaries/summary-changed-local! sp)
-      (add-output! sp child-sp))))
+  (let [ts (sp-ts sp)]
+   (connect-and-watch-stub! sp child-stub up?
+     (fn [child-sp]
+       (summaries/summary-changed-local! sp)
+       (when (identical? (ts-stub ts) (stub sp))
+         (let [child-ts (sp-ts child-sp)]
+           (summaries/connect! ts child-ts)
+           (summaries/connect-subsumed! ts child-ts)
+           (summaries/summary-changed! ts)))
+       (add-output! sp child-sp)))))

 (comment
 ;; TODO: propagation could be done more efficiently using a separate,


flush immediately when forwarding Node process out & err

--- src/main/clojure/cljs/repl/node.clj
+++ src/main/clojure/cljs/repl/node.clj
@@ -86,7 +86,8 @@
         (try
           (let [len (.read in buf)]
             (when-not (neg? len)
-              (.write out buf 0 len)))
+              (.write out buf 0 len)
+              (.flush out)))
           (catch IOException e
             (when (and (.isAlive proc) (not (.contains (.getMessage e) "Stream closed")))
               (.printStackTrace e *err*))))


Cleanup

Cleanup


Simplify condition in sith-lords/start-requests!

--- src/cljs/flux_challenge_reagent/sith_lords.cljs
+++ src/cljs/flux_challenge_reagent/sith_lords.cljs
@@ -35,7 +35,7 @@

 (defn- start-request! [item]
   (if-let [id (:id item)]
-    (if (not (or (contains? item :sith-lord) (contains? item :request)))
+    (if (not (some item '(:sith-lord :request)))
       (let [url (str "http://localhost:3000/dark-jedis/" id)
             request (ajax/GET url :response-format :json :handler handle-sith-lord-response!)]
         (assoc item :request request))


add build debug

add build debug

--- kafka-clj/src/kafka_clj/pool.clj
+++ kafka-clj/src/kafka_clj/pool.clj
@@ -73,7 +73,9 @@
   [create-f validate-f destroy-f conf]
   (reify KeyedPooledObjectFactory
     (makeObject [_ k] (DefaultPooledObject. (create-f k conf)))
-    (destroyObject [_ _ v] (destroy-f (lift v) conf))
+    (destroyObject [_ _ v]
+      (prn "destroyObject >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> v " v " lifted " (lift v))
+      (destroy-f (lift v) conf))
     (validateObject [_ _ v] (validate-f (lift v) conf))
     (activateObject [_ _ _])
     (passivateObject [_ _ _])))


Cleans up duplication around select-keys

--- src/yuubin/mail.clj
+++ src/yuubin/mail.clj
@@ -23,16 +23,14 @@

 ;; Convert JSON to format required by Mailgun.
 (defn format-for-mailgun [json]
-  (let [{body "body" template "template"} json]
+  (let [{body "body" template "template"} json
+        message (select-keys json valid-keys)]
     (cond
-      body (assoc
-             (select-keys json valid-keys)
-             "html" body)
+      body
+        (assoc message "html" body)
       (and template (contains? templates template))
-        (assoc
-          (select-keys json valid-keys)
-          "html" (load-template template))
-      :else (select-keys json valid-keys))))
+        (assoc message "html" (load-template template))
+      :else message)))

 (defn post-message
   "POST the JSON message to the Mailgun mailbox using the provided key.


fix children collection

fix children collection

--- src/cljss/core.clj
+++ src/cljss/core.clj
@@ -70,7 +70,7 @@
 (defmacro make-styled []
   '(defn styled [cls static vars attrs create-element]
     (fn [props & children]
-      (let [[props children] (if (map? props) (array props children) (array {} (.concat (array props) (to-array children))))
+      (let [[props children] (if (map? props) [props children] [{} (apply vector props children)])
             var-class (->> vars (map (fn [[cls v]] (if (ifn? v) (array cls (v props)) (array cls v)))) (cljss.core/css cls static))
             className (:className props)
             className (str (when className (str className " ")) var-class)


Code style of Cassandra component fixed

Code style of Cassandra component fixed

--- src/clj/hellhound/components/cassandra.clj
+++ src/clj/hellhound/components/cassandra.clj
@@ -13,13 +13,14 @@
    [hellhound.core                 :as hellhound]))

+(declare ->Cassandra)
+
+;; Specs ---------------------------------------------------
 (spec/def ::cassanda-configuration
   (spec/keys :req [::connection ::keyspace]))

-(defn cassandra-config
-  []
-  (:cassandra (:db (hellhound/application-config))))

+;; Private functions ---------------------------------------
 (defn- connect
   [config]
   (let [cluster (alia/cluster (:connecttion config))]
@@ -32,7 +33,11 @@
             (format "'%s' component is not started yet." name)
             {:cause "Cassandra component"}))))

+
+;; Public functions ----------------------------------------
 (defn select-keyspace
+  "Use the given keyspace name or throw an exception if the keyspace was
+  missing"
   [session keyspace]
   (try
     (alia/execute session (format "USE %s;" keyspace))
@@ -40,6 +45,32 @@
       (throw
        (ex-info "Keyspace is not present. You need to migrate first." {})))))

+(defn cassandra-config
+  "Returns the cassandra configuration"
+  []
+  (:cassandra (:db (hellhound/application-config))))
+
+
+(defn make-cassandra-client
+  "Create an instance of `Cassandra` record to be used with a `component`
+  compatible system."
+  ([]
+   (make-cassandra-client {}))
+  ([options]
+   (let [config (merge (cassandra-config) options)]
+     (->Cassandra config))))
+
+(defn new-cassandra-client
+  "Create an instance from cassandra component. This function is meant
+  to be used with `hellhound.system.defsystem` macro."
+  ([system-map]
+   (new-cassandra-client system-map {}))
+  ([system-map options]
+   (let [config (merge (cassandra-config) options)]
+     (update-in system-map [:components :cassandra] (->Cassandra config)))))
+
+
+;; Component record ----------------------------------------
 (defrecord Cassandra [options]

   ;; Lifecycle implementation.
@@ -84,22 +115,3 @@
         (assoc this :keyspace (:name keyspace-config)))))

   (teardown [this]))
-
-
-(defn make-cassandra-client
-  "Create an instance of `Cassandra` record to be used with a `component`
-  compatible system."
-  ([]
-   (make-cassandra-client {}))
-  ([options]
-   (let [config (merge (cassandra-config) options)]
-     (->Cassandra config))))
-
-(defn new-cassandra-client
-  "Create an instance from cassandra component. This function is meant
-  to be used with `hellhound.system.defsystem` macro."
-  ([system-map]
-   (new-cassandra-client system-map {}))
-  ([system-map options]
-   (let [config (merge (cassandra-config) options)]
-     (update-in system-map [:components :cassandra] (->Cassandra config)))))


dashboard view for pinned service/node #387

--- src/cljs/swarmpit/component/dashboard.cljs
+++ src/cljs/swarmpit/component/dashboard.cljs
@@ -8,6 +8,8 @@
             [swarmpit.component.progress :as progress]
             [swarmpit.component.common :as common]
             [swarmpit.component.plot :as plot]
+            [swarmpit.component.service.list :as services]
+            [swarmpit.component.node.list :as nodes]
             [swarmpit.event.source :as event]
             [swarmpit.ajax :as ajax]
             [swarmpit.routes :as routes]
@@ -66,11 +68,25 @@
   []
   (ajax/get
     (routes/path-for-backend :nodes)
-    {:state      [:loading?]
-     :on-success (fn [{:keys [response]}]
+    {:on-success (fn [{:keys [response]}]
                    (nodes-ts-handler)
                    (state/update-value [:nodes] response state/form-value-cursor))}))

+(defn- services-handler
+  []
+  (ajax/get
+    (routes/path-for-backend :services)
+    {:on-success (fn [{:keys [response origin?]}]
+                   (state/update-value [:services] response state/form-value-cursor))}))
+
+(defn- me-handler
+  []
+  (ajax/get
+    (routes/path-for-backend :me)
+    {:on-success (fn [{:keys [response]}]
+                   (state/update-value [:services-dashboard] (set (:service-dashboard response)) state/form-value-cursor)
+                   (state/update-value [:nodes-dashboard] (set (:node-dashboard response)) state/form-value-cursor))}))
+
 (defn- init-form-state
   []
   (state/set-value {:loading?            true
@@ -78,9 +94,12 @@

 (defn- init-form-value
   []
-  (state/set-value {:stats    {}
-                    :nodes    []
-                    :nodes-ts []} state/form-value-cursor))
+  (state/set-value {:stats              {}
+                    :services           []
+                    :services-dashboard #{}
+                    :nodes              []
+                    :nodes-dashboard    #{}
+                    :nodes-ts           []} state/form-value-cursor))

 (def mixin-init-form
   (mixin/init-form
@@ -88,7 +107,9 @@
       (init-form-state)
       (init-form-value)
       (stats-handler)
-      (nodes-handler))))
+      (nodes-handler)
+      (services-handler)
+      (me-handler))))

 (defn- resource-chip
   [name count]
@@ -194,9 +215,12 @@
       {:className "Swarmpit-table-card-content"}
       (html [:div {:id plot-node-cpu-id}]))))

-(rum/defc form-info < rum/reactive [item]
+(rum/defc form-info < rum/reactive
+  [{:keys [stats services services-dashboard nodes nodes-dashboard] :as item}]
   (let [{:keys [node-stats-loading?]} (state/react state/form-state-cursor)
-        node-stats-empty? (empty? (:nodes-ts item))]
+        node-stats-empty? (empty? (:nodes-ts item))
+        pinned-services (filter #(contains? services-dashboard (:id %)) services)
+        pinned-nodes (filter #(contains? nodes-dashboard (:id %)) nodes)]
     (comp/mui
       (html
         [:div.Swarmpit-form
@@ -210,33 +234,44 @@
                :sm   6
                :lg   3
                :xl   3}
-              (dashboard-cluster
-                (:nodes item)))
+              (dashboard-cluster nodes))
             (comp/grid
               {:item true
                :xs   12
                :sm   6
                :lg   3
                :xl   3}
-              (dashboard-disk
-                (get-in item [:stats :disk])))
+              (dashboard-disk (:disk stats)))
             (comp/grid
               {:item true
                :xs   12
                :sm   6
                :lg   3
                :xl   3}
-              (dashboard-memory
-                (get-in item [:stats :memory])))
+              (dashboard-memory (:memory stats)))
             (comp/grid
               {:item true
                :xs   12
                :sm   6
                :lg   3
                :xl   3}
-              (dashboard-cpu
-                (get-in item [:stats :cpu])
-                (:nodes item)))
+              (dashboard-cpu (:cpu stats) nodes))
+            (when (not-empty pinned-services)
+              (comp/grid
+                {:item true
+                 :xs   12
+                 :sm   12
+                 :lg   12
+                 :xl   12}
+                (services/pinned pinned-services)))
+            (when (not-empty pinned-nodes)
+              (comp/grid
+                {:item true
+                 :xs   12
+                 :sm   12
+                 :lg   12
+                 :xl   12}
+                (nodes/pinned pinned-nodes)))
             (comp/grid
               (merge {:item true
                       :xs   12


cleanup node list + key for correct rendering

--- src/cljs/swarmpit/component/node/list.cljs
+++ src/cljs/swarmpit/component/node/list.cljs
@@ -20,24 +20,32 @@
   [items predicate]
   (filter #(string/includes? (:nodeName %) predicate) items))

-(defn node-item-state [value]
+(defn- node-item-state [value]
   (case value
     "ready" (comp/label-green value)
     "down" (comp/label-red value)))

+(defn- node-item-states [item]
+  [:div.node-item-states
+   [:span.node-item-state (node-item-state (:state item))]
+   (if (:leader item)
+     [:span.node-item-state (comp/label-blue "leader")])])
+
+(defn- node-item-header [item]
+  [:div
+   [:span
+    [:svg.node-item-ico {:width  "24"
+                         :height "24"
+                         :fill   "rgb(117, 117, 117)"}
+     [:path {:d icon/docker}]]]
+   [:span [:b (:nodeName item)]]])
+
 (defn- node-item
   [item]
   (html
-    [:div.mdl-cell.node-item
-     [:div
-      [:span
-       [:svg.node-item-ico {::width "24" :height "24" :fill "rgb(117, 117, 117)"}
-        [:path {:d icon/docker}]]]
-      [:span [:b (:nodeName item)]]]
-     [:div.node-item-states
-      [:span.node-item-state (node-item-state (:state item))]
-      (if (:leader item)
-        [:span.node-item-state (comp/label-blue "leader")])]
+    [:div.mdl-cell.node-item {:key (:id item)}
+     (node-item-header item)
+     (node-item-states item)
      [:div
       [:span "[ " (:role item) " ]"]]
      [:div


Throw exception on unhandled re-initiate packets

And add a comment.

Really just a leftover from last night. Only committing now because I
found a bug that needs to be fixed/merged into master separately.

--- src/clojure/frereth_cp/server/initiate.clj
+++ src/clojure/frereth_cp/server/initiate.clj
@@ -615,12 +615,13 @@
                                                                        ex
                                                                        ::do-handle
                                                                        "Initiate packet looked good enough to establish client session, but failed later")})))
+                                   ;; Just log a quick message about the failure for now.
+                                   ;; It seems likely that we should really gather more info, especially in terms
+                                   ;; of identifying the source of garbage.
                                    {::log2/state (log2/error log-state
                                                              ::do-handle
                                                              "FIXME: Debug only: cookie extraction failed")}))
-                               {::log2/state (log2/warn log-state
-                                                        ::do-handle
-                                                        "TODO: Handle additional Initiate packets from " client-short-pk)})))
+                               (throw (RuntimeException. "TODO: Handle additional Initiate packets from " client-short-pk)))))
                          {::log2/state (log2/warn log-state
                                                   ::do-handle
                                                   (str "Truncated initiate packet. Only received " n " bytes"))})]


:fish_cake:

:fish_cake:

port stuff

--- src/main/clj/agency/irl/instagrammer/core.clj
+++ src/main/clj/agency/irl/instagrammer/core.clj
@@ -64,21 +64,19 @@
   (println "***")
   (println)

-
-  (run-server app {:port (Integer. (or port (env :port) 5000))})
+  (let [server-port (Integer. (or port (env :port) 5000))]
+    (run-server app {:port server-port}))

   ;; Bing all that jazz
   (binding [*client-id*     (:client-id client-options)
             *client-secret* (:client-secret client-options)
             *callback-url*  (:callback-url client-options)]

-    (println *client-id*)
-    (println *client-secret*)
-    (println *callback-url*)
-
-    (let [sub-geo (subscribe/geo :lat 40.7903 :lng 73.9597 :radius 5000)
-          sub-tag (subscribe/tag :tag "yolo")]
-      (println @sub-geo @sub-tag)
+    (let [
+          ;sub-geo (subscribe/geo :lat 40.7903 :lng 73.9597 :radius 5000)
+          ;sub-tag (subscribe/tag :tag "yolo")
+          ]
+      ;(println @sub-geo @sub-tag)
       ))

 ; (with-instagram client-options


fixing clojure build file to complile java src

--- clojure/project.clj
+++ clojure/project.clj
@@ -5,5 +5,6 @@
                      [speclj-growl "1.0.0-SNAPSHOT"]]
   :repositories {"local" "file://m2"}
   :test-path "spec/"
+  :java-source-path "src/"
 ;  :jvm-opts ["-Djava.awt.headless=true"]
   )


reformated ...

reformated ...

--- src/dda/pallet/crate/managed_vm/basics.clj
+++ src/dda/pallet/crate/managed_vm/basics.clj
@@ -8,9 +8,7 @@
     [pallet.stevedore :as stevedore]
     [pallet.crate.git :as git]
     [org.domaindrivenarchitecture.pallet.crate.util :as util]
-    [org.domaindrivenarchitecture.pallet.crate.package :as dda-package]
-    ))
-
+    [org.domaindrivenarchitecture.pallet.crate.package :as dda-package]))

 (defn install-virtualbox-guest-additions
@@ -24,22 +22,23 @@
   "configures virtual-box guest additions"
   [config]
   (let [os-user-name (name (-> config :vm-user))]
-    (actions/exec-script ("usermod" "-G vboxsf" (str "-a " ~os-user-name)))
-    ))
+    (actions/exec-script ("usermod" "-G vboxsf" (str "-a " ~os-user-name)))))

-(defn install-xfce-desktop
+
+(defn install-xfce-desktop
   "Install the xubuntu desktop."
   []
   (actions/package "xfce4")
   (actions/package "xfce4-goodies"))

-(defn install-linus-basics
+(defn install-linus-basics
   "Install tools for linus."
   []
   (actions/package "bash-completion")
   (actions/package "lsof")
   (actions/package "strace"))

+;TODO: remove after factoring git out
 (defn install-git
   "installs the git package"
   []


Weave initial state through to item-adder

--- fulcro-todo/src/main/app/ui.cljs
+++ fulcro-todo/src/main/app/ui.cljs
@@ -1,28 +1,42 @@
 (ns app.ui
   (:require [om.dom :as dom]
-            [om.next :as om :refer [defui]]))
+            [om.next :as om :refer [defui]]
+            [fulcro.client.core :as fc]))

 (defui ^:once ItemAdder
+  static
+  fc/InitialAppState
+  (initial-state [c params] {:input-value ""
+                             :valid-input-value? false})
   Object
   (render [this]
-          (dom/form
-           #js {:className "item-adder"
-                :onSubmit #(.preventDefault %)}
-           (dom/input
-            #js {:className "item-adder__input"
-                 :type "text"
-                 :value "hey"})
-           (dom/input
-            #js {:className "item-adder__button"
-                 :type "submit"
-                 :value "add"}))))
+          (let [{:keys [input-value valid-input-value?]} (om/props this)]
+            (dom/form
+             #js {:className "item-adder"
+                  :onSubmit #(.preventDefault %)}
+             (dom/input
+              #js {:className "item-adder__input"
+                   :type "text"
+                   :value input-value})
+             (dom/input
+              #js {:className (if valid-input-value?
+                                "item-adder__button"
+                                "item-adder__button item-adder__button--disabled")
+                   :type "submit"
+                   :value "add"
+                   :disabled (not valid-input-value?)})))))

 (def ui-item-adder (om/factory ItemAdder))

 (defui ^:once App
+  static
+  fc/InitialAppState
+  (initial-state [c params] {:item-adder (fc/get-initial-state ItemAdder {})})
+
   Object
   (render [this]
-          (let [{:keys [ui/react-key]} (om/props this)]
+          (let [{:keys [ui/react-key]} (om/props this)
+                {:keys [item-adder]} (fc/get-initial-state App {})]
             (dom/div
              #js {:key react-key
                   :className "app"}
@@ -38,6 +52,6 @@
               #js {:className "app__body"}
               (dom/div
                #js {:className "app__body__divider"})
-              (ui-item-adder)
+              (ui-item-adder item-adder)
               (dom/div
                #js {:className "app__body__divider"}))))))


117 query functions refactored

117 query functions refactored

--- src/etaoin/api.clj
+++ src/etaoin/api.clj
@@ -506,85 +506,66 @@
     css [locator-css css]
     :else [locator-xpath (xpath/expand q)]))

-#_(defmethod q-expand :default
-  [q] ;; todo
-  (throw+ {:type :etaoin/query
-           :q q
-           :driver @driver
-           :message "Unsupported query clause"}))
+(defmethod q-expand :default
+  [q]
+  (throw (Exception. (format "Wrong query: %s" q))))

 (defn query
   "Finds an element on a page.

    A query might be:

-   - a string, so the current browser's locator will be used. Examples:
-
-   //div[@id='content'] for XPath,
-   div.article for CSS selector
-
-   - a keyword `:active` that means the current active element
-
-   - any keyword `value` that is converted to XPath `.//*[@id='<value>']`
-
-   - a map with either :xpath or :css keys with a string term, e.g:
-   {:xpath \"//div[@id='content']\"} or
-   {:css \"div.article\"}
-
-   - a map that will turn into an XPath expression:
-   {:tag :div} => .//div
-   {:id :container} => .//*[@id='container']
-   {:tag :a :class :external :index 2} => .//a[@class='external'][2]
-
-   - a vector of any clause mentioned above. In that case,
-   every next term is searched inside the previous one. Example:
-   [{:id :footer} {:tag :a}] => finds the first hyperlink
-   inside a div with id 'footer'.
-
-   Returns an element's unique identifier as a string."
-  [driver q]
-  (cond
-    (= q :active)
-    (get-active-element* driver)
-
-    (vector? q)
-    (loop [el (query driver (first q))
-           q-rest (rest q)]
-      (if (empty? q-rest)
-        el
-        (let [q (first q-rest)
-              [loc term] (q-expand q)]
-          (recur (find-element-from* driver el loc term)
-                 (rest q-rest)))))
-
-    :else
-    (let [[loc term] (q-expand q)]
-      (find-element* driver loc term))))
+   - a string with an XPath expression;
+   - a keyword `:active` that means to get the current active element;
+   - any other keyword which stands for an element's ID attribute;
+   - a map with either `:xpath` or `:css` key with a string value
+     of corresponding selector type (XPath or CSS);
+   - any other map that will be expanded into XPath term (see README.md);
+   - a vector of any expressions mentioned above. In that case, each next
+     term is searched from the previous one.
+
+   Returns a element's unique identifier."
+
+  ([driver q]
+   (cond
+
+     (= q :active)
+     (get-active-element* driver)
+
+     (vector? q)
+     (apply query driver q)
+
+     :else
+     (let [[loc term] (q-expand q)]
+       (find-element* driver loc term))))
+
+  ([driver q & more]
+   (letfn [(folder [el q]
+             (let [[loc term] (q-expand q)]
+               (if el
+                 (find-element-from* driver el loc term)
+                 (query driver q))))]
+     (reduce folder nil (cons q more)))))

 (defn query-all
-  "Finds multiple elements by a single query.
-
-  If a query is a vector, it finds the first element for all the terms
-  except the last one, then all the elements for the last term from
-  the element got from the previous terms.
-
-  See `query` function for more info.
-
-  Returns a vector of element identifiers.
-"
-  [driver q]
-  (cond
-    (vector? q)
-    (let [q-but-last (vec (butlast q))
-          q-last (last q)
-          el (query driver q-but-last)
-          [loc term] (q-expand q-last)]
-
-      (find-elements-from* driver el loc term))
-
-    :else
-    (let [[loc term] (q-expand q)]
-      (find-elements* driver loc term))))
+  "Finds multiple elements on a page.
+  See `query` function for incoming params.
+  Returns a vector of element identifiers."
+
+  ([driver q]
+   (cond
+
+     (vector? q)
+     (apply query-all driver q)
+
+     :else
+     (let [[loc term] (q-expand q)]
+       (find-elements* driver loc term))))
+
+  ([driver q & more]
+   (let [[loc term] (q-expand (last more))
+         el (apply query driver q (butlast more))]
+     (find-elements-from* driver el loc term))))

 ;;
 ;; mouse