using floating-ips object and seperating addresses from first ip

--- src/openstack/networking.clj
+++ src/openstack/networking.clj
@@ -12,16 +12,18 @@
 (ns openstack.networking
   "openstack networking management"
   (:require
+    [celestial.common :refer (import-logging)]
     [clojure.java.data :refer [from-java]]
-    [celestial.persistency.systems :as s]
-    )
+    [celestial.persistency.systems :as s]))

- )
+(import-logging)

-(defn first-ip [server network]
-  (first
-    (map (comp :addr from-java)
-       (get-in (from-java server) [:addresses :addresses network]))))
+(defn addresses-ip
+   "grab addresses from server"
+   [server network]
+   (map (comp :addr from-java) (get-in (from-java server) [:addresses :addresses network])))
+
+(defn first-ip [server network] (first (addresses-ip server network)))

 (defn update-ip [spec ip]
   "update instance ip"
@@ -30,11 +32,13 @@

 (defn assoc-floating
    "assoc floating ip with instance"
-   [compute server ip]
-   (-> compute (.floatingIps) (.addFloatingIP server ip)))
+   [floating-ips server ip]
+     (debug "assoc" ip "to" (:id (from-java server)))
+     (.addFloatingIP floating-ips server ip))

-(defn dissoc-ip
+(defn dissoc-floating
    "dissoc ip for instance"
-   [compute server ip]
-    (-> compute (.floatingIps) (.removeFloatingIP server ip))
-  )
+   [floating-ips server ip]
+     (debug "dissoc" ip "from" (:id (from-java server)))
+     (.removeFloatingIP floating-ips server ip))
+


Return results for some mocked fns

Return results for some mocked fns

--- test/desdemona/cli_test.clj
+++ test/desdemona/cli_test.clj
@@ -128,6 +128,8 @@
           group (gensym)
           peers (for [_ (range n-peers)] (gensym))
           events (atom [])
+          fn-results {'onyx.api/start-peer-group group
+                      'onyx.api/start-peers peers}
           redef-pairs (for [sym ['onyx.api/start-peer-group
                                  'onyx.api/start-env
                                  'onyx.api/start-peers
@@ -139,7 +141,8 @@
                         [(resolve sym)
                          (fn [& args]
                            (let [event (into [sym] args)]
-                             (swap! events conj event)))])
+                             (swap! events conj event)
+                             (fn-results sym)))])
           redefs (into {} redef-pairs)]
       (with-redefs-fn redefs
         (fn []


util/date.clj: re-fixed NullPointerException when format-long-date gets empty string

--- src/org/altlaw/util/date.clj
+++ src/org/altlaw/util/date.clj
@@ -22,10 +22,11 @@
       "Converts a String date from YYYY-MM-DD format to
       'January 1, 2009' format."
       [string]
-      (str (.format *long-date-format*
-                    (parse-iso-date string)
-                    (StringBuffer.)
-                    (FieldPosition. 0))))
+      (when (seq string)
+        (str (.format *long-date-format*
+                      (parse-iso-date string)
+                      (StringBuffer.)
+                      (FieldPosition. 0)))))
   (is (= "January 1, 2009" (format-long-date "2009-01-01")))
   (is (= nil (format-long-date ""))))


CMR-3357: Removed a ToBeDone umm-json validation because it's already covered.

--- system-int-test/test/cmr/system_int_test/ingest/collection_validation_end_point_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/collection_validation_end_point_test.clj
@@ -23,7 +23,6 @@
 ;; The following tests are included in validation-endpoint-test
 ;; 1. successful case
 ;; 2. invalid collection xml fails validation with appropriate message
-;; 3. invalid umm-json fails validation with appropriate message (ToBeDone)
 ;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (deftest validation-endpoint-test


Improved color picker.

Improved color picker.

--- src/uxbox/ui/colorpicker.cljs
+++ src/uxbox/ui/colorpicker.cljs
@@ -17,6 +17,13 @@
    {:picker {:width 165 :height 165}
     :bar {:width 15 :height 165 :img "/images/color-bar-options.png"}}})

+(defn- get-mouse-pos
+  [own ref event]
+  (let [canvas (mx/get-ref-dom own ref)
+        brect (.getBoundingClientRect canvas)
+        x (- (.-clientX event) (.-left brect))
+        y (- (.-clientY event) (.-top brect))]
+    [x y]))

 (defn- draw-color-gradient
   [context type color]
@@ -43,6 +50,34 @@
     (set! (.-fillStyle context) gradient1)
     (.fillRect context 0 0 width width)))

+(defn- get-selection-border-color
+  [color]
+  (let [[r g b] (color/hex->rgb color)
+        x1 (+ (* 0.299 r) (* 0.587 g) (* 0.114 b))
+        darkness (- 1 (/ x1 255))]
+    (if (> darkness 0.5)
+      "#FFFFFF"
+      "#000000")))
+
+(defn- draw-current-selection
+  [own color type event]
+  (let [canvas (mx/get-ref-dom own "colorpicker")
+        context (.getContext canvas "2d")
+        local (:rum/local own)
+        [x y :as pos] (get-mouse-pos own "colorpicker" event)
+        border-color (get-selection-border-color color)]
+
+    (.clearRect context 0 0 (.-width canvas) (.-height canvas))
+    (draw-color-gradient context type (:color @local))
+
+    (.beginPath context)
+    (.arc context x y 5 0 (* js/Math.PI 2) false)
+    (set! (.-fillStyle context) color)
+    (.fill context)
+    (set! (.-lineWidth context) 1)
+    (set! (.-strokeStyle context) border-color)
+    (.stroke context)))
+
 (defn- initialize
   [own type]
   (let [canvas1 (mx/get-ref-dom own "colorpicker")
@@ -56,21 +91,14 @@
     (add-watch local ::key
                (fn [_ _ o v]
                  (when (not= (:color o) (:color v))
+                   (println "KAKAKA" v)
                    (draw-color-gradient context1 type (:color v)))))
-
-    (draw-color-gradient context1 type "#FF0000")
+    (reset! local {:color "#FF0000"})
+    ;; (draw-color-gradient context1 type "#FF0000")

     (set! (.-src img) img-path)
-    (let [key (events/listen img EventType.LOAD #(.drawImage context2 img 0 0))]
+    (let [key1 (events/listen img EventType.LOAD #(.drawImage context2 img 0 0))]
       {::key key})))
-
-(defn- get-mouse-pos
-  [own ref event]
-  (let [canvas (mx/get-ref-dom own ref)
-        brect (.getBoundingClientRect canvas)
-        x (- (.-clientX event) (.-left brect))
-        y (- (.-clientY event) (.-top brect))]
-    [x y]))

 (defn- get-color
   [own ref [x y]]
@@ -95,6 +123,7 @@
             (on-picker-click [event]
               (let [[x y :as pos] (get-mouse-pos own "colorpicker" event)
                     color (get-color own "colorpicker" pos)]
+                (draw-current-selection own color type event)
                 (callback {:hex color
                            :rgb (color/hex->rgb color)})))
             (on-bar-click [event]


letting some fns isntead of defn-

letting some fns isntead of defn-

--- src/midje/internal_ideas/fakes.clj
+++ src/midje/internal_ideas/fakes.clj
@@ -29,15 +29,13 @@
 (defn implements-a-fake? [function]
   (:midje/faked-function (meta function)))

-(defn- function-fake? [form]
-  (first-named? form "fake"))
-
-(defn- data-fake? [form]
-  (first-named? form "data-fake"))
-
 (defn fake? [form]
-  (or (function-fake? form)
-    (data-fake? form)))
+  (letfn [(function-fake? [form]
+            (first-named? form "fake"))
+          (data-fake? [form]
+            (first-named? form "data-fake"))]
+    (or (function-fake? form)
+      (data-fake? form))))

 (defn- fake-form-funcall [[fake funcall => value & overrides]]
   funcall)


Make sure its a vec and not a seq

Make sure its a vec and not a seq

--- src/midje/parsing/lexical_maps.clj
+++ src/midje/parsing/lexical_maps.clj
@@ -64,7 +64,7 @@

 (defn- arg-matchers [arg-matchers]
   (if (= (str (first arg-matchers)) "&")
-    `(from-fake-maps/mkfn:arity-arg-matchers ~(rest (vec arg-matchers)))
+    `(from-fake-maps/mkfn:arity-arg-matchers ~(vec (rest arg-matchers)))
     `(from-fake-maps/mkfn:arg-matchers ~(vec arg-matchers))))


Test for file not found handling

Test for file not found handling

--- test/clj_fileutils/fileutils_test.clj
+++ test/clj_fileutils/fileutils_test.clj
@@ -176,7 +176,7 @@
 (deftest test-slurp-
     "Check the function clj-fileutils.fileutils/slurp-."
     (testing "Check the function clj-fileutils.fileutils/slurp-."
-        (are [x y] (= x (slurp- y))
+        (are [expected filename] (= expected (slurp- filename))
             ""           "test/test1.txt"
             "test\n"     "test/test2.txt"
             "1\n2\n3\n"  "test/test3.txt")))
@@ -184,8 +184,15 @@
 (deftest test-slurp-2
     "Check the function clj-fileutils.fileutils/slurp-."
     (testing "Check the function clj-fileutils.fileutils/slurp-."
-        (are [x y z] (= x (slurp- y z))
+        (are [expected directory filename] (= expected (slurp- directory filename))
             ""           "test" "test1.txt"
             "test\n"     "test" "test2.txt"
             "1\n2\n3\n"  "test" "test3.txt")))

+(deftest test-slurp-file-not-found
+    "Check the function clj-fileutils.fileutils/slurp-."
+    (testing "Check the function clj-fileutils.fileutils/slurp-."
+        (is (nil? (slurp- "unknown.txt")))
+        (is (nil? (slurp- "directory" "unknown.txt")))
+        (is (nil? (slurp- "test" "unknown.txt")))))
+


[#2262] Adapt a.l.lib.collection

[#2262] Adapt a.l.lib.collection

--- backend/src/akvo/lumen/lib/collection.clj
+++ backend/src/akvo/lumen/lib/collection.clj
@@ -1,6 +1,7 @@
 (ns akvo.lumen.lib.collection
   (:refer-clojure :exclude [update])
   (:require [akvo.lumen.lib :as lib]
+            [akvo.lumen.db.collection :as db.collection]
             [clojure.java.jdbc :as jdbc]
             [clojure.set :as set]
             [hugsql.core :as hugsql])
@@ -8,18 +9,16 @@

 (alias 'core 'clojure.core)

-(hugsql/def-db-fns "akvo/lumen/lib/collection.sql")
-
 (defn all
   ([tenant-conn]
    (all tenant-conn nil))
   ([tenant-conn ids]
    (mapv (fn [collection]
            (core/update collection :entities #(vec (.getArray %))))
-         (all-collections tenant-conn (if ids {:ids ids} {})))))
+         (db.collection/all-collections tenant-conn (if ids {:ids ids} {})))))

 (defn fetch [tenant-conn id]
-  (if-let [collection (fetch-collection tenant-conn {:id id})]
+  (if-let [collection (db.collection/fetch-collection tenant-conn {:id id})]
     (lib/ok (core/update collection :entities #(vec (.getArray %))))
     (lib/not-found {:id id})))

@@ -41,10 +40,10 @@
   [conn entities]
   (let [entity-array (text-array conn entities)]
     (->> (concat
-           (fetch-dataset-ids conn {:ids entity-array})
-           (fetch-visualisation-ids conn {:ids entity-array})
-           (fetch-dashboard-ids conn {:ids entity-array})
-           (fetch-raster-dataset-ids conn {:ids entity-array}))
+           (db.collection/fetch-dataset-ids conn {:ids entity-array})
+           (db.collection/fetch-visualisation-ids conn {:ids entity-array})
+           (db.collection/fetch-dashboard-ids conn {:ids entity-array})
+           (db.collection/fetch-raster-dataset-ids conn {:ids entity-array}))
       (map #(merge {:dataset-id nil :visualisation-id nil :dashboard-id nil
                     :raster-dataset-id nil} %)))))

@@ -59,10 +58,10 @@
     :else
     (jdbc/with-db-transaction [tx-conn tenant-conn]
       (try
-        (let [{:keys [id]} (create-collection tenant-conn {:title title})]
+        (let [{:keys [id]} (db.collection/create-collection tenant-conn {:title title})]
           (when entities
             (doseq [entity (categorize-entities tx-conn entities)]
-              (insert-collection-entity tx-conn (assoc entity :collection-id id))))
+              (db.collection/insert-collection-entity tx-conn (assoc entity :collection-id id))))
           (lib/created (second (fetch tx-conn id))))
         (catch SQLException e
           (if (unique-violation? e)
@@ -76,18 +75,18 @@
   (let [{:keys [entities title]} collection]
     (jdbc/with-db-transaction [tx-conn tenant-conn]
       (when title
-        (update-collection-title tx-conn {:id id :title title}))
+        (db.collection/update-collection-title tx-conn {:id id :title title}))

       ;; Replace entity ids
       (when entities
-        (delete-collection-entities tx-conn {:id id})
+        (db.collection/delete-collection-entities tx-conn {:id id})
         (doseq [entity (categorize-entities tx-conn entities)]
-          (insert-collection-entity tx-conn (assoc entity :collection-id id))))
+          (db.collection/insert-collection-entity tx-conn (assoc entity :collection-id id))))

       (fetch tx-conn id))))

 (defn delete
   "Delete a collection by id"
   [tenant-conn id]
-  (delete-collection tenant-conn {:id id})
+  (db.collection/delete-collection tenant-conn {:id id})
   (lib/no-content))


Tests for functions: compute-job-status, compute-job-disabled, parse-int, and parse-test-results

--- test/emender_jenkins/results_test.clj
+++ test/emender_jenkins/results_test.clj
@@ -66,3 +66,27 @@
         (is (callable? 'emender-jenkins.results/job-name->environment))))

+(deftest test-compute-job-status-existence
+    "Check that the emender-jenkins.results/compute-job-status definition exists."
+    (testing "if the emender-jenkins.results/compute-job-status definition exists."
+        (is (callable? 'emender-jenkins.results/compute-job-status))))
+
+
+(deftest test-compute-job-disabled-existence
+    "Check that the emender-jenkins.results/compute-job-disabled definition exists."
+    (testing "if the emender-jenkins.results/compute-job-disabled definition exists."
+        (is (callable? 'emender-jenkins.results/compute-job-disabled))))
+
+
+(deftest test-parse-int-existence
+    "Check that the emender-jenkins.results/parse-int definition exists."
+    (testing "if the emender-jenkins.results/parse-int definition exists."
+        (is (callable? 'emender-jenkins.results/parse-int))))
+
+
+(deftest test-parse-test-results-existence
+    "Check that the emender-jenkins.results/parse-test-results definition exists."
+    (testing "if the emender-jenkins.results/parse-test-results definition exists."
+        (is (callable? 'emender-jenkins.results/parse-test-results))))
+
+


Passing notify-command a more descriptive message; trigger on initial build

this fixes PR #376

--- sidecar/src/figwheel_sidecar/components/cljs_autobuild.clj
+++ sidecar/src/figwheel_sidecar/components/cljs_autobuild.clj
@@ -52,9 +52,26 @@
                       "\" in " (elapsed started-at) "." reset-color))
         (flush)))))

+
+(defn handle-notify-command [build-state s]
+  (when-let [notify-command (-> build-state :build-config :notify-command)]
+    (apply sh (concat notify-command [s]))))
+
+(defn notify-command-hook [build-fn]
+  (fn [build-state]
+    (try
+      (build-fn build-state)
+      (handle-notify-command build-state (str "Successfully compiled ClojureScript build: "
+                                              (name (-> build-state :build-config :id))))
+      (catch Throwable e
+        (handle-notify-command build-state (str "Failed compiling ClojureScript build: "
+                                                (name (-> build-state :build-config :id))))
+        (throw e)))))
+
 (def figwheel-build
   (-> cljs-build
       injection/hook
+      notify-command-hook
       notifications/hook
       clj-reloading/hook
       javascript-reloading/hook
@@ -63,6 +80,7 @@
 (def figwheel-build-without-javascript-reloading
   (-> cljs-build
       injection/hook
+      notify-command-hook
       notifications/hook
       clj-reloading/hook
       figwheel-start-and-end-messages))
@@ -70,6 +88,7 @@
 (def figwheel-build-without-clj-reloading
   (-> cljs-build
       injection/hook
+      notify-command-hook
       notifications/hook
       javascript-reloading/hook
       figwheel-start-and-end-messages))
@@ -115,9 +134,7 @@
                  *err* log-writer]
          (cljs-build-fn
           (assoc cljs-autobuild
-            :changed-files (map str files))))
-       (when-let [notify-command (-> cljs-autobuild :build-config :notify-command)]
-         (println (:out (apply sh notify-command))))))))
+                 :changed-files (map str files))))))))

 (defrecord CLJSAutobuild [build-config figwheel-server]
   component/Lifecycle
@@ -139,6 +156,7 @@
           ;; first build shouldn't send notifications
           ((if (= cljs-build-fn figwheel-build)
              (-> cljs-build
+                 notify-command-hook
                  catch-print-hook
                  injection/hook
                  figwheel-start-and-end-messages)


Make the Link header parsing test less flaky.

--- test/github_changelog/github_test.clj
+++ test/github_changelog/github_test.clj
@@ -9,7 +9,7 @@

 (deftest http-get
   (is (= {:href "https://api.github.com/gists?page=2"}
-         (get-in (http/get "https://api.github.com/gists") [:links :next]))))
+         (get-in (http/get "http://www.mocky.io/v2/5dd82f43310000b77b055dbc") [:links :next]))))

 (def config (sgen/complete-config {:user "raszi"
                                    :repo "changelog-test"}))


string rotation list

string rotation list

--- src/hackerrank/fp/rotate_string.clj
+++ src/hackerrank/fp/rotate_string.clj
@@ -34,7 +34,10 @@
   ([]
    (let [t (parseInt (read-line))
          strings (lines t)]
-     strings))
+     (doseq [string strings]
+       (let [output (string-rotation string t)]
+         (println output)
+         output)))

   ([string-input]
    (with-in-str string-input


Be less specific to avoid potential confusion.

--- modules/web/src/main/clojure/immutant/web/internal.clj
+++ modules/web/src/main/clojure/immutant/web/internal.clj
@@ -123,16 +123,16 @@
   nil)

 (defn stop*
-  "Deregisters the Ring handler attached to the given sub-context-path."
+  "Deregisters the request handler attached to the given sub-context-path."
   [sub-context-path]
   (util/if-in-immutant
    (let [sub-context-path (normalize-subcontext-path sub-context-path)]
      (if-let [{:keys [wrapper destroy]} (remove-servlet-info! (servlet-name sub-context-path))]
        (do
-         (log/info "Deregistering ring handler at sub-context path:" sub-context-path)
+         (log/info "Deregistering request handler at sub-context path:" sub-context-path)
          (remove-servlet sub-context-path wrapper)
          (and destroy (destroy)))
-       (log/warn "Attempted to deregister ring handler at sub-context path:" sub-context-path ", but none found")))
+       (log/warn "Attempted to deregister request handler at sub-context path:" sub-context-path ", but none found")))
    (log/warn "web/stop called outside of Immutant, ignoring")))

 (defn start*


with-temp* macro :unamused:

with-temp* macro :unamused:

--- test/metabase/api/foreignkey_test.clj
+++ test/metabase/api/foreignkey_test.clj
@@ -1,40 +0,0 @@
-(ns metabase.api.foreignkey-test
-  "tests for /api/foreignkey api endpoints"
-  (:require [clojure.tools.macro :refer [symbol-macrolet]]
-            [expectations :refer :all]
-            [metabase.db :as db]
-            (metabase [http-client :as http]
-                      [middleware :as middleware])
-            (metabase.models [database :refer [Database]]
-                             [field :refer [Field]]
-                             [foreign-key :refer :all]
-                             [table :refer [Table]])
-            [metabase.test.util :as tu]
-            [metabase.test.data.users :refer :all]))
-
-
-;; ## /api/segment/* AUTHENTICATION Tests
-;; We assume that all endpoints for a given context are enforced by the same middleware, so we don't run the same
-;; authentication test on every single individual endpoint
-
-(expect (get middleware/response-unauthentic :body) (http/client :delete 401 "foreignkey/123"))
-
-
-;; ## DELETE /api/foreignkey/:id
-
-;; test security.  requires superuser perms
-(expect "You don't have permissions to do that."
-  ((user->client :rasta) :delete 403 "foreignkey/1"))
-
-
-(expect
-  [{:success true}
-   nil]
-  (tu/with-temp* [Database   [{database-id :id}]
-                  Table      [{table-id :id} {:db_id database-id}]
-                  Field      [{field-id :id} {:table_id table-id}]
-                  ForeignKey [{:keys [id]}   {:destination_id field-id
-                                              :origin_id      field-id
-                                              :relationship   "whoot"}]]
-    [((user->client :crowberto) :delete 200 (format "foreignkey/%d" id))
-     (db/sel :one ForeignKey :id id)]))


Changed r.m.session-test to use c.c.mock.test-adapter for clojure.test integration

--- test/ring/middleware/session_test.clj
+++ test/ring/middleware/session_test.clj
@@ -1,6 +1,6 @@
 (ns ring.middleware.session-test
   (:use clojure.test
-        clojure.contrib.mock
+        clojure.contrib.mock.test-adapter
         ring.middleware.session))

 (declare reader writer deleter)


Typo.

Typo.

--- modules/messaging/src/main/clojure/immutant/messaging.clj
+++ modules/messaging/src/main/clojure/immutant/messaging.clj
@@ -201,11 +201,11 @@
    same options as listen."
   [queue f & {:keys [decode?] :or {decode? true} :as opts}]
   {:pre [(queue? queue)]}
-  (let-fn [(respond* [^javax.jms.Message msg]
-                     (publish (.getJMSDestination msg)
-                              (f (codecs/decode-if decode? msg))
-                              :correlation-id (.getJMSMessageID msg)
-                              :encoding (codecs/get-encoding msg)))]
+  (letfn [(respond* [^javax.jms.Message msg]
+            (publish (.getJMSDestination msg)
+                     (f (codecs/decode-if decode? msg))
+                     :correlation-id (.getJMSMessageID msg)
+                     :encoding (codecs/get-encoding msg)))]
     (mapply listen queue respond*
             (assoc (update-in opts [:selector]
                               #(str "synchronous = 'true'"


Make model test timezone independent

Make model test timezone independent

java.sql.Timestamp/valueOf converts between local time and UTC, so the
result can be different when using #inst, depending on your timezone.

--- test/toucan/models_test.clj
+++ test/toucan/models_test.clj
@@ -5,7 +5,7 @@
             [toucan.test-setup :as test]
             (toucan.test-models [category :refer [Category], :as category]
                                 [user :refer [User]]
-                                [venue :refer [Venue]])
+                                [venue :refer [Venue map->VenueInstance]])
             [toucan.util.test :as tu]))

 ;; Test types (keyword)
@@ -139,7 +139,7 @@

 ;; check that we can still override default-fields
 (expect
- #toucan.test_models.venue.VenueInstance{:created-at #inst "2017-01-01T08:00:00.000000000-00:00"}
+ (map->VenueInstance {:created-at test/jan-first-2017})
  (db/select-one [Venue :created-at] :id 1))

 ;; Test invoking model as a function (no args)


CMR-3488: Fixing failing unit test.

CMR-3488: Fixing failing unit test.

--- search-app/test/cmr/search/test/validators/validation.clj
+++ search-app/test/cmr/search/test/validators/validation.clj
@@ -12,7 +12,7 @@
     :case-sensitive? true,
     :pattern? false},
    :page-size 10,
-   :page-num 1,
+   :offset 10,
    :sort-keys
    [{:field :provider-id, :order :asc}
     {:field :start-date, :order :asc}],


124 modify selectors

124 modify selectors

--- stuf/src/sandbox/4clojure.clj
+++ stuf/src/sandbox/4clojure.clj
@@ -891,22 +891,26 @@
 #(Integer/parseInt % 2)

 ;;
+(def r '[[e e e e]
+         [e w b e]
+         [e b w e]
+         [e e e e]])
 (defn ray [f1 f2 s] (rest (iterate (fn [[y x]] [(f1 y) (f2 x)]) s)))
 (defn d1 [s]
-  (for [p (ray inc inc s) :let [[y x] p] :while (and (< y 4) (< x 4))] p))
+  (for [p (ray inc inc s) :while (not= 'e (get-in r p))] (get-in r p)))
 (defn d2 [s]
-  (for [p (ray dec dec s) :let [[y x] p] :while (and (>= y 0) (>= x 0))] p))
+  (for [p (ray dec dec s) :when (get-in r p)] (get-in r p)))
 (defn d3 [s]
-  (for [p (ray inc dec s) :let [[y x] p] :while (and (< y 4) (>= x 0))] p))
+  (for [p (ray inc dec s) :when (get-in r p)] (get-in r p)))
 (defn d4 [s]
-  (for [p (ray dec inc s) :let [[y x] p] :while (and (>= y 0) (< x 4))] p))
+  (for [p (ray dec inc s) :when (get-in r p)] (get-in r p)))
 (defn v1 [s]
-  (for [p (ray dec identity s) :let [[y x] p] :while (>= y 0)] p))
+  (for [p (ray dec identity s) :when (get-in r p)] (get-in r p)))
 (defn v2 [s]
-  (for [p (ray inc identity s) :let [[y x] p] :while (< y 4)] p))
+  (for [p (ray inc identity s) :when (get-in r p)] (get-in r p)))
 (defn h1 [s]
-  (for [p (ray identity dec s) :let [[y x] p] :while (>= x 0)] p))
+  (for [p (ray identity dec s) :when (get-in r p)] (get-in r p)))
 (defn h2 [s]
-  (for [p (ray identity inc s) :let [[y x] p] :while (< x 4)] p))
-
-
+  (for [p (ray identity inc s) :when (get-in r p)] (get-in r p)))
+
+


Update project description

Update project description

--- airline.dow/project.clj
+++ airline.dow/project.clj
@@ -1,5 +1,5 @@
 (defproject airline.dow "0.1.0"
-  :description "Library for transforming airline day-of-week strings."
+  :description "Library for transforming airline timetable day-of-week strings."
   :url "https://github.com/devstopfix/airline/airline.dow"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}


Figwheel server on port 3449.

Figwheel server on port 3449.

--- client/project.clj
+++ client/project.clj
@@ -25,14 +25,7 @@
               [{:id "dev"
                 :source-paths ["src"]

-                ;; the presence of a :figwheel configuration here
-                ;; will cause figwheel to inject the figwheel client
-                ;; into your build
                 :figwheel {:on-jsload "client.core/on-js-reload"
-                           ;; :open-urls will pop open your application
-                           ;; in the default browser once Figwheel has
-                           ;; started and complied your application.
-                           ;; Comment this out once it no longer serves you.
                            :open-urls ["http://localhost:3449/index.html"]
                            :websocket-host :js-client-host}

@@ -41,12 +34,7 @@
                            :output-to "resources/public/js/compiled/client.js"
                            :output-dir "resources/public/js/compiled/out"
                            :source-map-timestamp true
-                           ;; To console.log CLJS data-structures make sure you enable devtools in Chrome
-                           ;; https://github.com/binaryage/cljs-devtools
                            :preloads [devtools.preload]}}
-               ;; This next build is an compressed minified build for
-               ;; production. You can build this with:
-               ;; lein cljsbuild once min
                {:id "min"
                 :source-paths ["src"]
                 :compiler {:output-to "resources/public/js/compiled/client.js"
@@ -54,57 +42,13 @@
                            :optimizations :advanced
                            :pretty-print false}}]}

-  :figwheel {;; :http-server-root "public" ;; default and assumes "resources"
-             :server-port 8080
-             ;; :server-ip "127.0.0.1"
+  :figwheel {:server-port 3449
+             :css-dirs ["resources/public/css"]}

-             :css-dirs ["resources/public/css"] ;; watch and update CSS
-
-             ;; Start an nREPL server into the running figwheel process
-             ;; :nrepl-port 7888
-
-             ;; Server Ring Handler (optional)
-             ;; if you want to embed a ring handler into the figwheel http-kit
-             ;; server, this is for simple ring servers, if this
-
-             ;; doesn't work for you just run your own server :) (see lein-ring)
-
-             ;; :ring-handler hello_world.server/handler
-
-             ;; To be able to open files in your editor from the heads up display
-             ;; you will need to put a script on your path.
-             ;; that script will have to take a file path and a line number
-             ;; ie. in  ~/bin/myfile-opener
-             ;; #! /bin/sh
-             ;; emacsclient -n +$2 $1
-             ;;
-             ;; :open-file-command "myfile-opener"
-
-             ;; if you are using emacsclient you can just use
-             ;; :open-file-command "emacsclient"
-
-             ;; if you want to disable the REPL
-             ;; :repl false
-
-             ;; to configure a different figwheel logfile path
-             ;; :server-logfile "tmp/logs/figwheel-logfile.log"
-
-             ;; to pipe all the output to the repl
-             ;; :server-logfile false
-             }
-
-
-  ;; setting up nREPL for Figwheel and ClojureScript dev
-  ;; Please see:
-  ;; https://github.com/bhauman/lein-figwheel/wiki/Using-the-Figwheel-REPL-within-NRepl
   :profiles {:dev {:dependencies [[binaryage/devtools "0.9.2"]
                                   [figwheel-sidecar "0.5.10"]
                                   [com.cemerick/piggieback "0.2.1"]]
-                   ;; need to add dev source path here to get user.clj loaded
                    :source-paths ["src" "dev"]
-                   ;; for CIDER
-                   ;; :plugins [[cider/cider-nrepl "0.12.0"]]
                    :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}
-                   ;; need to add the compliled assets to the :clean-targets
                    :clean-targets ^{:protect false} ["resources/public/js/compiled"
                                                      :target-path]}})


update at most once per second

update at most once per second

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@10170 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- plugins/DataBrowser/src/org/micromanager/browser/core.clj
+++ plugins/DataBrowser/src/org/micromanager/browser/core.clj
@@ -23,7 +23,7 @@
            [java.io BufferedReader File FileReader PrintWriter]
            [java.util Comparator Vector]
            [java.util.prefs Preferences]
-           [java.util.concurrent LinkedBlockingQueue]
+           [java.util.concurrent LinkedBlockingQueue ScheduledThreadPoolExecutor]
            [java.awt Color Dimension Font Insets]
            [java.awt.event ItemEvent ItemListener KeyAdapter MouseAdapter
                            WindowAdapter WindowListener]
@@ -89,7 +89,7 @@
       (.setTitle
         (str "Micro-Manager Data Set Browser ("
              (if (and (empty? pending-data-sets)
-                      ;(empty? pending-locations)
+                      (empty? pending-locations)
                       )
                "Idle" "Scanning")
              " \u2014 " (count @current-data) " images)"))))
@@ -196,6 +196,8 @@
       data
       (conj data new-row))))

+(def last-table-update (atom 0))
+
 (defn update-browser-table []
   (let [table (@browser :table)
         selected-rows (.getSelectedRows table)
@@ -247,7 +249,8 @@
              (->> (.listFiles f)
                   (remove #(.isDirectory %))
                   (map #(.getName %))
-                  (filter #(.contains % "_MMImages"))
+                  (filter #(or (.contains % "_images")
+                               (.contains % "_MMImages")))
                   seq)))))

 (defn find-data-sets [root-dir]
@@ -682,6 +685,14 @@
       (.addItemListener
         (proxy [ItemListener] []
           (itemStateChanged [_] (reset! value-atom (.isSelected cb))))))))
+
+(defn update-no-faster-than [run-function interval]
+  (let [now (System/currentTimeMillis)]
+    (future
+      (Thread/sleep interval)
+      (when (> (- now @last-table-update) interval)
+        (reset! last-table-update now)
+        (run-function)))))

 (defn create-browser []
   (let [frame (JFrame.)
@@ -736,7 +747,7 @@
     (persist-window-shape prefs "browser-shape" frame)
     (add-watch current-data "updater" (fn [_ _ old new]
                                         (when (not= old new)
-                                          (.post table-updater update-browser-table))))
+                                          (update-no-faster-than update-browser-table 1000))))
     (gen-map frame table scroll-pane settings-button search-field
              collection-menu refresh-button)))


more logging

more logging


Add constructors

Add constructors


Document get-schema

Document get-schema


(maint) Fix tests that depend on multiple clients

The test client can't determine when the broker registers a connection
without session association. Force it on tests that depend on multiple
clients being connected at once.

--- test/integration/puppetlabs/pcp/broker/service_test.clj
+++ test/integration/puppetlabs/pcp/broker/service_test.clj
@@ -541,6 +541,7 @@
                (with-open [client01 (client/connect :certname "client01.example.com"
                                                     :version version)
                            client02 (client/connect :certname "client02.example.com"
+                                                    :force-association true
                                                     :version version)]
                  (testing "client01 -> client02 should work"
                    (let [message (client/make-message
@@ -568,6 +569,7 @@
                (with-open [sender   (client/connect :certname "client01.example.com"
                                                     :version sender-version)
                            receiver (client/connect :certname "client02.example.com"
+                                                    :force-association true
                                                     :version receiver-version)]
                  (let [message (client/make-message
                                 sender-version


Test for function print-configuration

Test for function print-configuration

--- test/hurvinek/config_test.clj
+++ test/hurvinek/config_test.clj
@@ -12,6 +12,7 @@

 (ns hurvinek.config-test
   (:require [clojure.test    :refer :all]
+            [clojure.pprint  :as    pprint]
             [hurvinek.config :refer :all]))

 ;
@@ -158,17 +159,24 @@
         -1e10 (parse-float "-1e10")))

 (deftest test-parse-float-min-value
-    "Check the behaviour of function emender-jenkins.config/parse-int."
+    "Check the behaviour of function hurvinek.config/parse-int."
     (is (== Float/MIN_VALUE (parse-float "0x0.000002P-126f"))))

 (deftest test-parse-float-max-value
-    "Check the behaviour of function emender-jenkins.config/parse-int."
+    "Check the behaviour of function hurvinek.config/parse-int."
     (is (== Float/MAX_VALUE (parse-float "0x1.fffffeP+127f"))))

 (deftest test-parse-float-bad-input
-    "Check the behaviour of function emender-jenkins.config/parse-float."
+    "Check the behaviour of function hurvinek.config/parse-float."
     (are [x] (thrown? NumberFormatException x)
         (parse-float "")
         (parse-float "xyzzy")
         (parse-float "-1xyzzy")))

+(deftest test-print-configuration
+    "Check the behaviour of function hurvinek.config/print-configuration."
+        ; use mock instead of clojure.pprint/pprint
+        (with-redefs [pprint/pprint (fn [configuration] (str configuration))]
+            (is (not (nil? (print-configuration {:first 1 :second 2}))))
+            (is (= (type (print-configuration   {:first 1 :second 2})) java.lang.String))))
+


Update session unit tests to ensure we don't leak existence of users

--- test/metabase/api/session_test.clj
+++ test/metabase/api/session_test.clj
@@ -25,7 +25,8 @@
   (client :post 400 "session" {:email "anything@metabase.com"}))

 ;; Test for inactive user (user shouldn't be able to login if :is_active = false)
-(expect {:errors {:email "no account found for the given email"}}
+;; Return same error as incorrect password to avoid leaking existence of user
+(expect {:errors {:password "did not match stored password"}}
   (client :post 400 "session" (user->credentials :trashbird)))

 ;; Test for password checking
@@ -62,9 +63,9 @@
 (expect {:errors {:email "field is a required param."}}
   (client :post 400 "session/forgot_password" {}))

-;; Test that email not found gives 404
-(expect {:errors {:email "no account found for the given email"}}
-  (client :post 400 "session/forgot_password" {:email "not-found@metabase.com"}))
+;; Test that email not found also gives 200 as to not leak existence of user
+(expect nil
+  (client :post 200 "session/forgot_password" {:email "not-found@metabase.com"}))

 ;; POST /api/session/reset_password


Use distinct ports for tests.

Use distinct ports for tests.

--- test/replikativ/replicate_test.clj
+++ test/replikativ/replicate_test.clj
@@ -29,7 +29,7 @@
 (deftest test-replication-protocol
   (let [;; remote server to sync to
         remote-store (<?? S (new-mem-store))
-        _ (def remote-peer (<?? S (server-peer S remote-store "ws://127.0.0.1:9090/"
+        _ (def remote-peer (<?? S (server-peer S remote-store "ws://127.0.0.1:9080/"
                                                :id "SERVER"
                                                :middleware (comp (partial block-detector :remote)
                                                                  fetch))))
@@ -75,12 +75,12 @@
               :id :ignored})
     ;; connect to the remote-peer
     (>!! out {:type :connect/peer
-              :url "ws://127.0.0.1:9090/"
+              :url "ws://127.0.0.1:9080/"
               :id 101})
     ;; ack
     (is (= (<?? S in)
            {:type :connect/peer-ack,
-            :url "ws://127.0.0.1:9090/",
+            :url "ws://127.0.0.1:9080/",
             :peer-id nil
             :id 101}))
     ;; publish a new value of CDVCS '42' of user 'john'


Only return the arrow after info box if no wishlist is displayed


Fix argument order in integration test

Fix argument order in integration test

--- test/comic_reader/sites/integration_test.clj
+++ test/comic_reader/sites/integration_test.clj
@@ -27,7 +27,7 @@
                comic-mfm)))))

 (deftest ^:integration get-chapter-list-test
-  (let [chapters (get-chapter-list "the_gamer" manga-fox)]
+  (let [chapters (get-chapter-list manga-fox "the_gamer")]
     (is (>= (count chapters)
             97)))


Test refs resolution on a real spec

Test refs resolution on a real spec

--- test/io/sarnowski/swagger1st/mapper_test.clj
+++ test/io/sarnowski/swagger1st/mapper_test.clj
@@ -1,6 +1,8 @@
 (ns io.sarnowski.swagger1st.mapper-test
   (:require [clojure.test :refer :all]
-            [io.sarnowski.swagger1st.mapper :as m]))
+            [io.sarnowski.swagger1st.mapper :as m]
+            [io.sarnowski.swagger1st.core :as s1st]
+            [schema.core :as s]))

 ; TODO tests for definition inheritance

@@ -109,4 +111,15 @@
     (is (=                     {"a" {"$ref" "#/a"}}
            (m/denormalize-refs {"a" {"$ref" "#/a"}})))
     (is (=                     {"a" {"$ref" "#/a"} "b" {"$ref" "#/b"}}
-           (m/denormalize-refs {"a" {"$ref" "#/b"} "b" {"$ref" "#/a"}})))))+           (m/denormalize-refs {"a" {"$ref" "#/b"} "b" {"$ref" "#/a"}})))))
+
+(s/defschema NotRef
+  (s/pred #(not= "$ref" %)))
+
+(s/defschema NoRefs
+  (s/cond-pre {NotRef (s/recursive #'NoRefs)} [(s/recursive #'NoRefs)] s/Any))
+
+(deftest semi-integration-smoke-check
+  (testing "There should be no unresolved refs in the requests spec"
+    (let [ctx (m/setup (s1st/context :yaml-cp (str "io/sarnowski/swagger1st/" "integration.yaml")))]
+      (is (nil? (s/check NoRefs (:requests ctx)))))))


Update scala.clj

Update scala.clj

--- src/swagger_gen/language/scala.clj
+++ src/swagger_gen/language/scala.clj
@@ -51,7 +51,7 @@

 (defn escape-if-reserved
   "Compiler errors will occur if Scala case classes contain reserved words.
-   This will automatically put reversed words in backticks"
+   This will automatically put reserved words in backticks"
   [word]
   (if (contains? scala-language-reserved-words word)
     (format "`%s`" word)


indenting

indenting

--- src/aws/provider.clj
+++ src/aws/provider.clj
@@ -94,10 +94,10 @@
   [(provider-validation spec) (-> endpoint nil? not)  (-> uuid nil? not)]
   Vm
   (create [this]
-         (let [{:keys [aws]} spec]
-           (debug "creating" uuid)
-           (swap! (ids) assoc uuid
-             (-> (ec2 run-instances aws) :instances first :id))
+        (let [{:keys [aws]} spec]
+          (debug "creating" uuid)
+          (swap! (ids) assoc uuid
+            (-> (ec2 run-instances aws) :instances first :id))
           (when (= (image-desc endpoint (aws :image-id) :root-device-type) "ebs")
             (wait-for-attach endpoint uuid [10 :minute]))
           (update-pubdns this)
@@ -119,9 +119,9 @@
         (ec2 stop-instances  (instance-id uuid))
         (wait-for-status this "stopped" [5 :minute]))
   (status [this]
-          (try+
-            (instance-desc endpoint uuid :state :name)
-            (catch [:type ::aws:missing-id] e false))))
+        (try+
+          (instance-desc endpoint uuid :state :name)
+          (catch [:type ::aws:missing-id] e false))))

 (def defaults {:aws {:min-count 1 :max-count 1}})


clarify error message

clarify error message

--- src/babel/parse.cljc
+++ src/babel/parse.cljc
@@ -172,6 +172,6 @@
         (get (create-xgram-map arg (count arg) 0 grammar)
              [0 (count arg)])
         true
-        :error))
+        (str "unexpected input: type: " (type arg))))

 ;(log/info (str "parse: " (it/fo (parse "il gatto ha dormito" it/lexicon it-g/grammar))))


whitespace

whitespace

--- src/babel/reader.clj
+++ src/babel/reader.clj
@@ -24,7 +24,7 @@
   (let [results (db/exec-raw [(str "SELECT serialized::text AS structure FROM expression WHERE id=?")
                               [id]]
                              :results)]
-    (deserialize (read-string(:structure (first results))))))
+    (deserialize (read-string (:structure (first results))))))

 (defn generate-question-and-correct-set [target-spec source-language source-locale target-language target-locale]
   "Return a set of semantically-equivalent expressions, for a given spec in the target language, and


remove :dag_unify.core/serialized

remove :dag_unify.core/serialized

--- src/babel/writer.clj
+++ src/babel/writer.clj
@@ -335,6 +335,10 @@
   (let [language (:language model)
         debug (log/debug (str "fill-language-by-spec: language: " language))
         debug (log/debug (str "fill-language-by-spec: spec: " spec))
+        ;; remove metadata (if any)
+        ;; that's not relevant to query:
+        spec (dissoc spec
+                     :dag_unify.core/serialized)
         json-spec (json/write-str (remove-top-values spec))
         current-count
         (:count


Rename schedulers as in rxjs 5.x.

Rename schedulers as in rxjs 5.x.

--- src/beicon/core.cljs
+++ src/beicon/core.cljs
@@ -639,8 +639,9 @@
   [s]
   (js/Rx.Scheduler.isScheduler s))

-(def immediate-scheduler js/Rx.Scheduler.immediate)
-(def current-thread-scheduler js/Rx.Scheduler.currentThread)
+(def ^:static asap js/Rx.Scheduler.default)
+(def ^:static queue js/Rx.Scheduler.currentThread)
+(def ^:static immediate js/Rx.Scheduler.immediate)

 (defn observe-on
   [scheduler ob]


Another code fetch benchmark.

Another code fetch benchmark.

--- test/cavm/benchmark/core.clj
+++ test/cavm/benchmark/core.clj
@@ -73,6 +73,14 @@
                                                         [:= :dataset_id {:select [:id]
                                                                          :from [:dataset]
                                                                          :where [:= :name id]}]]}]})))
+; This is fastest.
+(defn code-fetch3 [xena {id :id} field]
+  (timeit (cdb/run-query xena
+                         {:select [:value]
+                          :order-by [:ordering]
+                          :from [:code]
+                          :join [:field [:= :field_id :field.id] :dataset [:= :dataset_id :dataset.id]]
+                          :where [:and [:= :field.name field] [:= :dataset.name id]]})))

 (defn sort-genes [genes]
   (sort (fn [x y]
@@ -211,6 +219,12 @@
     :params (fn [] [])
     :body (fn [xena]
             (code-fetch2 xena (dataset-map :matrix-medium) "sampleID"))}
+   ^:codes
+   {:desc "500 codes, #3"
+    :id :codes-medium3
+    :params (fn [] [])
+    :body (fn [xena]
+            (code-fetch3 xena (dataset-map :matrix-medium) "sampleID"))}
    ])

 (def test-map


Test adding to the DB.

Test adding to the DB.

--- test/circle/web/test_web.clj
+++ test/circle/web/test_web.clj
@@ -3,8 +3,7 @@
   (:require [clj-http.client :as http])
   (:require [clj-http.core :as core])
   (:require [uuid])
-  (:use [circle.db :only (with-conn)])
-  (:require [circle.model.beta-notify :as beta])
+  (:require [somnium.congomongo :as mongo])
   (:use midje.sweet))

 (def site "http://localhost:8080")
@@ -16,30 +15,25 @@
     body => #"Sign up"
     body => #"Continuous Integration made easy"
     body => #"form"
-    body =not=> #"Thanks"
-    ))
+    body =not=> #"Thanks"))

 (fact "posting works"
   (let [session (uuid/uuid)
         email (str session "@test.com")
-;        db-entries-before (with-conn beta/find-one :where {:email email})
+        db-entries-before (mongo/fetch-count :signups :where {:email email})
         post-request {:form-params {:email email :contact true}}
         post-response (http/post site post-request)
         get-request {:cookies (post-response :cookies)
                      :url (get-in post-response [:headers "location"])}
         get-response (http/get site get-request)
         body (get-response :body)
-;        db-entries-after (with-conn beta/find-one :where {:email email})
-        ]
+        db-entries-after (mongo/fetch-count :signups :where {:email email})]

     post-response => (contains {:status 302})
     (:headers post-response) => (contains {"location" "/"})
     get-response => (contains {:status 200})
     body => #"Thanks"
     body =not=> #"form"
-;    (println db-entries-after)
-;    (println db-entries-after)
-;    (count db-entries-before) => 0
-;    (count db-entries-after) => 1
-    ))
+    db-entries-before => 0
+    db-entries-after => 1))


Adds tests for rebinding write defs

Adds tests for rebinding write defs

--- test/ring_curl/core_test.clj
+++ test/ring_curl/core_test.clj
@@ -161,4 +161,11 @@
                     (subject/to-curl {} {:retry 3}) => (contains " --retry 3 "))

               (fact "dump headers"
-                    (subject/to-curl {} {:dump-headers "some-other-file.txt"}) => (contains " -D \"some-other-file.txt\" "))))+                    (subject/to-curl {} {:dump-headers "some-other-file.txt"}) => (contains " -D \"some-other-file.txt\" "))))
+
+(facts "rebinding allows custom writers"
+       (fact "write-json can be bound to another function"
+             (binding [subject/write-json identity] (subject/write-json ..body..)) => ..body..)
+
+       (fact "write-xml can be bound to another function"
+             (binding [subject/write-xml identity] (subject/write-xml ..body..)) => ..body..))


Create dummy jar for tests

Create dummy jar for tests

--- test/carambar/cache_test.clj
+++ test/carambar/cache_test.clj
@@ -1,6 +1,8 @@
 (ns carambar.cache-test
   (:require [midje.sweet :refer :all]
-            [carambar.cache :refer :all]))
+            [carambar.cache :refer :all]
+            [clojure.java.io :as io])
+  (:import [java.util.zip ZipEntry ZipOutputStream]))

 (fact (add-entry {:name "/path/test.jar" :values []}) => (contains {:name "/path/test.jar" :values []}))
@@ -13,3 +15,47 @@
 (fact (:values (parse jarfile-with-two-classes)) => (contains ["org.carambar.App" "org.carambar.MyClass"] :in-any-order))

 (fact (filename->javaclass "a/b/c/MyClass.class") => "a.b.c.MyClass")
+
+
+(def tmpdir (System/getProperty "java.io.tmpdir"))
+
+
+
+
+;;(.mkdir (java.io.File. (str tmpdir "/carambar")))
+
+;;(map #(.mkdir (java.io.File. (str  tmpdir "/carambar/" %))) ["a" "a/b" "a/b/c"])
+
+;;(map  #(spit (str tmpdir "/carambar/a/b/c/" %) "CONTENT") ["A.class"])
+
+
+(defmacro ^:private with-entry
+  [zip entry-name & body]
+  `(let [^ZipOutputStream zip# ~zip]
+     (.putNextEntry zip# (ZipEntry. ~entry-name))
+     ~@body
+     (flush)
+     (.closeEntry zip#)))
+
+(defn jarfile [filename]
+  (with-open [file (io/output-stream (str tmpdir "/" filename))
+              zip  (ZipOutputStream. file)
+              wrt  (io/writer zip)]
+    (binding [*out* wrt]
+      (doto zip
+        (with-entry "Foo.class"
+          (println "foo"))
+        (with-entry "bar/Baz.class"
+          (println "baz"))))))
+
+
+;; (with-open [output (ZipOutputStream. (io/output-stream "foo.zip"))
+;;             input  (io/input-stream "foo")]
+;;   (with-entry output "foo"
+;;     (io/copy input output)))
+
+
+(jarfile "test.jar")
+
+
+(parse (str tmpdir "/" "test.jar"))


Add matrix for benchmarks.

Add matrix for benchmarks.

--- test/cavm/benchmark/data.clj
+++ test/cavm/benchmark/data.clj
@@ -31,6 +31,10 @@
                 :remote-id "20170119_final_consensus_copynumber_donor"
                 :host "\017\021\000\007\033\133\133\126\037\026\017\022\002\112\037\000\032\026\000\024\026\012\101\033\013\021"}])

+(def matrix [{:id "AgilentG4502A_07_3"
+              :remote-id "TCGA.BRCA.sampleMap/AgilentG4502A_07_3"
+              :host "https://tcga.xenahubs.net"}])
+
 (defn tsv-lines [txt]
   (map #(s/split % #"\t") (s/split txt #"\n")))

@@ -43,4 +47,4 @@
 (def genes
   (map gene-line (tsv-lines (slurp (io/resource "benchmark/600genes")))))

-(def datasets (concat probemaps cnv))
+(def datasets (concat probemaps cnv matrix))


testing snippet of first entry

testing snippet of first entry

--- test/cloogling/core_test.clj
+++ test/cloogling/core_test.clj
@@ -9,6 +9,7 @@

 ;; Counting entries in standard test data
 (expect 10 (count (get-entries miles_davis_data)))
+

 ;; test on the first entry's url
 (expect "https://en.wikipedia.org/wiki/Miles_Davis"
@@ -27,7 +28,10 @@
             (:title))
         )

-
-
-;; "Miles Davis - Wikipedia, the free encyclopedia"
-;; "Miles Dewey Davis III (May 26, 1926 – September 28, 1991) was an American jazz trumpeter, bandleader, and composer. He is among the most influential and acclaimed ..."
+;; test on the first entry's snippet
+(expect "Miles Dewey Davis III (May 26, 1926 – September 28, 1991) was an American jazz trumpeter, bandleader, and composer. He is among the most influential and acclaimed ..."
+        (-> miles_davis_data
+            get-entries
+            first
+            (:snippet))
+        )


New tests: test-third-not-NPE

New tests: test-third-not-NPE

--- test/clouseau/test_utils.clj
+++ test/clouseau/test_utils.clj
@@ -168,3 +168,9 @@
             nil (third [1 2])
             nil (third '(1 2)))))

+(deftest test-third-not-NPE
+    "Check the function clouseau.utils/third."
+    (testing "the function clouseau.utils/third."
+        (are [x y] (= x y)
+            nil (third nil))))
+


fix account creation

fix account creation

Signed-off-by: yenda <96f164ad4d9b2b0dacf8ebee2bb1eeb3aa69adf1@status.im>

--- src/status_im/node/core.cljs
+++ src/status_im/node/core.cljs
@@ -100,7 +100,7 @@

       current-fleet
       (assoc :NoDiscovery   false
-             :Rendezvous    (seq rendezvous-nodes)
+             :Rendezvous    (boolean (seq rendezvous-nodes))
              :ClusterConfig {:Enabled true
                              :Fleet              (name current-fleet-key)
                              :BootNodes


Force node restart during initialization on desktop

Remove log

Signed-off-by: Goran Jovic <fc686822162e6f379ea05b6f92d78d206147085c@gmail.com>

--- src/status_im/node/core.cljs
+++ src/status_im/node/core.cljs
@@ -146,7 +146,10 @@
   (let [restart {:db (assoc db :node/restart? true :node/address address)}]
     (case status
       :started (stop cofx)
-      :starting restart
+      :starting (do
+                  (when utils.platform/desktop?
+                    (status/stop-node))
+                  restart)
       :stopping restart
       (start cofx address))))


tidy up the unit test lifecycle functions so that we just have a single setup & teardown function which reuse as much of the normal app setup process as possible.

--- test/metabase/test_utils.clj
+++ test/metabase/test_utils.clj
@@ -3,14 +3,11 @@
   (:require [clojure.java.io :as io]
             [clojure.tools.logging :as log]
             [expectations :refer :all]
-            [ring.adapter.jetty :as ring]
             (metabase [core :as core]
-                      [db :refer :all]
+                      [db :as db]
                       [test-data :refer :all])))

-(declare load-test-data
-         setup-test-db
-         start-jetty)
+(declare clear-test-db)

 ;; # SETTINGS

@@ -24,57 +21,36 @@
 (defn test-setup
   {:expectations-options :before-run}
   []
-  ;; Disable debug logging since it clutters up our output
-  (setup-test-db)
-  (load-test-data)
-  (start-jetty))
+  (log/info "Starting up Metabase unit test runner")
+  ;; clear out any previous test data that's lying around
+  (clear-test-db)
+  ;; setup the db and migrate up to current schema
+  (db/setup-db :auto-migrate true)
+  ;; this causes the test data to be loaded
+  @test-db
+  ;; startup test web server
+  (core/start-jetty))
+
+
+(defn test-teardown
+  {:expectations-options :after-run}
+  []
+  (log/info "Shutting down Metabase unit test runner")
+  (core/stop-jetty))
+

 ;; ## DB Setup
 ;; WARNING: BY RUNNING ANY UNIT TESTS THAT REQUIRE THIS FILE OR BY RUNNING YOUR ENTIRE TEST SUITE YOU WILL EFFECTIVELY BE WIPING OUT YOUR DATABASE.
 ;; SETUP-DB DELETES YOUR DATABASE FILE, AND GETS RAN AUTOMATICALLY BY EXPECTATIONS. USE AT YOUR OWN RISK!

-(defn- setup-test-db
-  "Setup database schema."
+(defn- clear-test-db
+  "Delete the test db file if it's still lying around."
   []
-  (let [filename (-> (re-find #"file:(\w+\.db).*" (db-file)) second)] ; db-file is prefixed with "file:", so we strip that off
+  (let [filename (-> (re-find #"file:(\w+\.db).*" (db/db-file)) second)] ; db-file is prefixed with "file:", so we strip that off
     (map (fn [file-extension]                                         ; delete the database files, e.g. `metabase.db.h2.db`, `metabase.db.trace.db`, etc.
            (let [file (str filename file-extension)]
              (when (.exists (io/file file))
                (io/delete-file file))))
          [".h2.db"
           ".trace.db"
-          ".lock.db"]))
-  (log/info "tearing down database and resetting to empty schema")
-  (migrate (setup-jdbc-db) :down)
-  (log/info "setting up database and running all migrations")
-  (setup-db :auto-migrate true)
-  (log/info "database setup complete"))
-
-(defn- load-test-data []
-  @test-db)
-
-
-;; ## Jetty (Web) Server
-
-
-(def ^:private jetty-instance
-  (atom nil))
-
-(defn- start-jetty
-  "Start the Jetty web server."
-  []
-  (log/info "STARTING THE JETTY SERVER...")
-  (when-not @jetty-instance
-    (try (->> (ring/run-jetty core/app {:port 3000
-                                        :join? false}) ; detach the thread
-              (reset! jetty-instance))
-        (catch java.net.BindException e                ; assume server is already running if port's already bound
-          (log/warn "ALREADY RUNNING!")))))            ; e.g. if someone is running `lein ring server` locally. Tests should still work normally.
-
-(defn stop-jetty
-  "Stop the Jetty web server."
-  {:expectations-options :after-run}
-  []
-  (when @jetty-instance
-    (.stop ^org.eclipse.jetty.server.Server @jetty-instance)
-    (reset! jetty-instance nil)))
+          ".lock.db"])))


use printable? instead of core-java-class?

--- src/cake/project.clj
+++ src/cake/project.clj
@@ -1,7 +1,7 @@
 (ns cake.project
   (:use cake
         [classlojure :exclude [with-classloader]]
-        [classlojure :only [core-java-class?]]
+        [classlojure :only [printable?]]
         [cake.deps :only [deps]]
         [bake.core :only [debug?]]
         [cake.file :only [file global-file path-string]]
@@ -146,9 +146,9 @@
   which is then invoked on the provided arguments."
   [form & args]
   (let [named-args (for [arg args]
-                     (if (core-java-class? arg)
-                       [(gensym "arg") arg]
-                       [arg]))
+                     (if (printable? arg)
+                       [arg]
+                       [(gensym "arg") arg]))
         core-args (filter #(= 2 (count %)) named-args)
         form `(do (in-ns '~*bake-ns*)
                   (fn [ins# outs# ~@(map first core-args)]


more calendar-state stuff

more calendar-state stuff

--- src/callie/core.cljs
+++ src/callie/core.cljs
@@ -111,7 +111,7 @@
   (cond-> []
     (is-today? d) (conj "today")
     (is-active-month? d calendar-state) (conj "active-month")
-    (not (is-active-month? d)) (conj "not-active-month")))
+    (not (is-active-month? d calendar-state)) (conj "not-active-month")))

 (defn event-div [ev calendar-state]
   [:div {:class ["event"]}


remove extraneous logging

remove extraneous logging

--- src/client/chat.cljs
+++ src/client/chat.cljs
@@ -109,8 +109,6 @@
 (defn- on-time-left
   "Called when server sends a time-left update."
   [seconds]
-  (js/console.log seconds)
-    (js/console.log (util/seconds->time-str seconds))
   (.html ($ ".time-left-8a651")
     (cond
       (pos? seconds) (str "Time Until Next Game: " (util/seconds->time-str seconds))


add logic to set earliest-partition-date

--- src/clj_money/db.clj
+++ src/clj_money/db.clj
@@ -1,15 +1,28 @@
 (ns clj-money.db
+  (:refer-clojure :exclude [update])
   (:require [clojure.pprint :refer [pprint]]
             [clojure.tools.cli :refer [parse-opts]]
-            [ragtime.jdbc :as jdbc]
+            [clj-time.core :as t]
+            [clojure.java.jdbc :as jdbc]
+            [honeysql.core :as sql]
+            [honeysql.helpers :refer [select
+                                      update
+                                      sset
+                                      from
+                                      where
+                                      values
+                                      insert-into]]
+            [ragtime.jdbc :refer [sql-database
+                                  load-resources]]
             [ragtime.repl :as rt]
             [environ.core :refer [env]]
+            [clj-money.core]
             [clj-money.util :refer [parse-local-date]]
             [clj-money.partitioning :refer [create-partition-tables]]))

 (defn ragtime-config []
-  {:datastore (jdbc/sql-database (env :db))
-   :migrations (jdbc/load-resources "migrations")})
+  {:datastore (sql-database (env :db))
+   :migrations (load-resources "migrations")})

 (defn migrate
   []
@@ -23,10 +36,30 @@
   [["-n" "--dry-run" "Dry run"]
    ["-s" "--silent" "Do not output SQL commands"]])

+(defn- update-earliest-partition-date
+  [date]
+  (let [setting-name "earliest-partition-date"
+        existing (when-let [record (first (jdbc/query (env :db) (-> (select :value)
+                                                                    (from :settings)
+                                                                    (where [:= :name setting-name])
+                                                                    sql/format)))]
+                   (read-string (:value record)))
+        sql (if existing
+              (when (t/before? date existing)
+                (-> (update :settings)
+                    (sset {:value (prn-str date)})
+                    (where [:= :name setting-name])))
+              (-> (insert-into :settings)
+                  (values [{:name setting-name
+                            :value (prn-str date)}])))]
+    (when sql
+      (jdbc/execute! (env :db) (sql/format sql)))))
+
 (defn create-partitions
   [& args]
   (let [{:keys [arguments options]} (parse-opts args create-partitions-options)
         start-date (-> arguments first parse-local-date)
         end-date (or (-> arguments second parse-local-date)
                      start-date)]
-    (create-partition-tables start-date end-date options)))
+    (create-partition-tables start-date end-date options)
+    (update-earliest-partition-date start-date)))


Исправления

Исправления

--- radiolamp-6P3S/src/r6p3s/cpt/select_time_interval.cljs
+++ radiolamp-6P3S/src/r6p3s/cpt/select_time_interval.cljs
@@ -48,7 +48,7 @@

-(defn component [app own {:keys [placeholder selected-fn] :as opts}]
+(defn component [app own {:keys [placeholder on-selected-fn] :as opts}]
   (reify
     om/IRender
     (render [_]
@@ -99,7 +99,7 @@
                                                                      :onChange-valid?-fn common-input/vldfn-not-empty-date}}})

                                       (form-group/render
-                                       {:label "Установлена продолжитльность"
+                                       {:label "продолжитльность"
                                         :body  (dom/b #js {:className "text-primary"}
                                                       (interval-as-string from-time to-time))}))

@@ -110,7 +110,7 @@
                                         {:from-time from-time
                                          :to-time   to-time})
                                        (modal/hide app-modal)
-                                       (when selected-fn (selected-fn)))
+                                       (when on-selected-fn (on-selected-fn)))
                                      }})))))))


bugfix

bugfix

--- src/dartbot/core.clj
+++ src/dartbot/core.clj
@@ -122,24 +122,7 @@
     (if (= next-player current)
       nil
       next-player
-      )
-    ;    (println "current" current "players" players "index" index "throws" throws)
-    ;    (if (= current (last players)) ;last player in player order?
-    ;      (if (apply = throws) ;all players have same amount of throws?
-    ;        (first players) ;first player
-    ;        (apply first (filter #(< (second %) (get-throws current)) (map list players throws))) ;first player with fewer throws
-    ;        )
-    ;      (if (< (get-throws (nth players (inc index))) (get-throws current)) ;next player has fewer throws?
-    ;        (nth players (inc index)) ;next player in order is next
-    ;        (if (apply = throws) ;next player with fewer throws is next
-    ;          (if (empty? (:currentthrows game))
-    ;            (first players)
-    ;            (nth players (inc index)))
-    ;          (nth players (inc index)))
-    ;        )
-    ;      )
-
-    ))
+      )))

 (defn set-next-player [game payload]
   (if (nil? (:player payload))
@@ -273,6 +256,7 @@

 (defn end-game [world gid]
   (http/upload-game gid (get world gid))
+  (spit (str "games/" gid ".game") (get world gid))
   ;(delete-game gid world)
   world
   )
@@ -299,7 +283,7 @@

 (add-watch world-atom :watch-change (fn [key a old-val new-val]
                                       (spit "world-data" new-val)
-                                      (print-world-to-file new-val)
+                                      ;(print-world-to-file new-val)
                                       (ws/ws-send-data new-val)
                                       ))


dat_contribution: totally unneccesary

dat_contribution: totally unneccesary

--- functions/src/wort/core.clj
+++ functions/src/wort/core.clj
@@ -10,5 +10,5 @@

 (defn get_key_as_list
   [payload key]
-  (str/split (get payload key) #"\s|[\.\,\!\?]")
+  (str/split (get payload key) #"\s|[.,!?]")
 )


check in some more patterns

check in some more patterns

--- src/xrosslexior/patterns.clj
+++ src/xrosslexior/patterns.clj
@@ -1,4 +1,5 @@
 (ns xrosslexior.patterns)
+

 (def seven-eleven-pattern  [[nil nil nil nil nil :█  nil nil nil nil nil]
                             [nil nil nil nil nil :█  nil nil nil nil nil]
@@ -7,6 +8,20 @@
                             [:█  nil nil nil nil nil :█  nil nil nil :█ ]
                             [:█  nil nil nil nil :█  nil nil nil nil :█ ]
                             [:█  :█  nil nil nil :█  nil nil nil :█  :█ ]])
+
+(def thirteen-eleven-pattern  [[nil nil nil nil nil :█  nil nil nil nil nil]
+                               [nil nil nil nil nil :█  nil nil nil nil nil]
+                               [nil nil nil nil :█  nil nil nil nil nil nil]
+                               [nil nil nil :█  nil nil nil :█  nil nil nil]
+                               [:█  nil nil nil nil nil :█  nil nil nil :█ ]
+                               [:█  :█  nil nil nil :█  nil nil nil :█  :█ ]
+                               [:█  :█  nil nil nil :█  nil nil nil :█  :█ ]
+                               [nil nil :█  nil nil :█  nil nil :█  nil nil]
+                               [nil nil nil nil nil :█  nil nil nil nil nil]
+                               [nil nil nil nil :█  nil nil nil nil nil nil]
+                               [nil nil nil :█  nil nil nil :█  nil nil nil]
+                               [:█  nil nil nil nil nil :█  nil nil nil :█ ]
+                               [:█  :█  nil nil nil :█  nil nil nil :█  :█ ]])

 (def my-first-standard-size-pattern
   ;; after the classic Dell Puzzler's Crossword Puzzles March 2015 #5 easy
@@ -25,3 +40,40 @@
    [nil nil nil nil nil nil :█  nil nil nil nil :█  nil nil nil]
    [:█  nil nil nil nil nil :█  nil nil nil nil :█  nil nil nil]
    [:█  :█  nil nil nil nil :█  nil nil nil nil :█  nil nil nil]])
+
+(def standard-pattern-extra-black
+  ;; again as Dell's March 2015 #5 but with extra black squares
+  ;; inserted
+  [[nil nil nil :█  :█  nil nil nil :█  nil nil nil :█  :█  :█ ]
+   [nil nil nil :█  nil nil nil nil :█  nil nil nil nil nil :█ ]
+   [nil nil nil :█  nil nil nil nil :█  nil nil nil nil nil :█ ]
+   [:█  :█  nil nil nil nil :█  nil nil nil nil :█  nil nil nil]
+   [:█  nil nil nil nil :█  :█  nil nil nil :█  nil nil nil nil]
+   [nil nil nil nil :█  nil nil nil nil :█  nil nil nil nil nil]
+   [nil nil nil :█  nil nil nil nil :█  nil nil nil :█  :█  :█ ]
+   [nil nil nil nil nil nil nil :█  nil nil nil nil nil nil nil]
+   [:█  :█  :█  nil nil nil :█  nil nil nil nil :█  nil nil nil]
+   [nil nil nil nil nil :█  nil nil nil nil :█  nil nil nil nil]
+   [nil nil nil nil :█  nil nil nil :█  :█  nil nil nil nil :█ ]
+   [nil nil nil :█  nil nil nil nil :█  nil nil nil nil :█  :█ ]
+   [:█  nil nil nil nil nil :█  nil nil nil nil :█  nil nil nil]
+   [:█  nil nil nil nil nil :█  nil nil nil nil :█  nil nil nil]
+   [:█  :█  :█  nil nil nil :█  nil nil nil :█  :█  nil nil nil]])
+
+(def another-standard-pattern
+  ;; after Dell Puzzler's Crossword Puzzles March 2015 #1 easy
+  [[nil nil nil :█  :█  :█  nil nil nil :█  :█  :█  nil nil nil]
+   [nil nil nil nil :█  nil nil nil nil nil :█  nil nil nil nil]
+   [nil nil nil nil :█  nil nil nil nil nil :█  nil nil nil nil]
+   [nil nil nil nil nil nil nil nil :█  nil nil nil nil nil :█ ]
+   [:█  nil nil nil nil nil nil :█  nil nil nil nil :█  :█  :█ ]
+   [:█  :█  :█  nil nil nil :█  nil nil nil nil nil nil nil nil]
+   [nil nil nil :█  :█  :█  nil nil nil nil :█  nil nil nil nil]
+   [nil nil nil nil :█  nil nil nil nil nil :█  nil nil nil nil]
+   [nil nil nil nil :█  nil nil nil nil :█  :█  :█  nil nil nil]
+   [nil nil nil nil nil nil nil nil :█  nil nil nil :█  :█  :█ ]
+   [:█  :█  :█  nil nil nil nil :█  nil nil nil nil nil nil :█ ]
+   [:█  nil nil nil nil nil :█  nil nil nil nil nil nil nil nil]
+   [nil nil nil nil :█  nil nil nil nil nil :█  nil nil nil nil]
+   [nil nil nil nil :█  nil nil nil nil nil :█  nil nil nil nil]
+   [nil nil nil :█  :█  :█  nil nil nil :█  :█  :█  nil nil nil]])


Oops!

Oops!

--- namespaces/common/src/main/clojure/immutant/registry.clj
+++ namespaces/common/src/main/clojure/immutant/registry.clj
@@ -17,7 +17,7 @@

 (ns immutant.registry
   "Functions for working with Immutant's internal per-app registry."
-  (:refer-clojure :exclude (get))
+  (:refer-clojure :exclude (get keys))
   (:import org.jboss.msc.service.ServiceName))

 (defonce ^{:private true} registry (atom {}))


remove allocations, some cleanup more to come

Signed-off-by: Chris Granger <5654cde260ae99bc4d30054171b8bcd902efd19a@gmail.com>

--- src/aurora/join.cljs
+++ src/aurora/join.cljs
@@ -125,18 +125,17 @@
                   (loop [ix 0]
                     (if (< ix len)
                       (let [cur (aget nil-ixs ix)
-                            rewind? (and (not= nil (aget prev-seek cur))
-                                         (not= (aget key cur) (aget prev-seek cur)))]
+                            rewind? (and (not (identical? nil (aget prev-seek cur)))
+                                         (not (identical? (aget key cur) (aget prev-seek cur))))]
                         (cond
                          (and (identical? cur 0) rewind?) (.rewind this cur)
-                         (> cur 0) (let [store? (not= (aget key (- cur 1)) (aget prev-seek (- cur 1)))]
+                         (> cur 0) (let [store? (not (identical? (aget key (- cur 1)) (aget prev-seek (- cur 1))))]
                                      (if store?
                                        (.seek-and-mark this cur key)
                                        (if (and rewind? (not (== (+ cur 1) map-len)))
                                          (.rewind this cur)
                                          (recur (+ 1 ix)))))
-                         :else (recur (+ 1 ix))))
-                      #js [0 false false])))
+                         :else (recur (+ 1 ix)))))))
                 )
   (seek [this key]
         ;(println "SEEK KEY: " key prev-seek)
@@ -187,109 +186,110 @@
      (ainto (.-prev-seek magic) (.key magic))
      magic)))

-(defn ->keys [iterators keys len]
-  (dotimes [x len]
-    (aset keys x (.key (aget iterators x)))))
-
-(defn find-least [keys len tuple-len min-fill]
-  (loop [ix 1
-         col 0
-         least (-> (aget keys 0)
-                   (aget 0))]
-    (if (>= ix len)
-      (do
-        (aset min-fill col least)
-        (let [next (+ 1 col)]
-          (if (< next tuple-len)
-            (recur 0 next nil))))
-      (let [cur (-> (aget keys ix)
-                    (aget col))]
-        (recur (+ 1 ix) col (if (nilless-lt cur least)
-                              cur
-                              least))))))
-
-(defn iters-next [iterators len min-fill]
-  (let [last (aget iterators (- len 1))]
-    (.next last)
-    (if-not (.-end? last)
-      (reverse-fill! (.key last) min-fill)
-      (loop [ix (- len 2)]
-        (when (>= ix 0)
-          (let [cur (aget iterators ix)]
-            (.next cur)
-            (if (.-end? cur)
-              (recur (- ix 1))
-              (reverse-fill-with! (.key cur) min-fill false))))))))
-
-(defn find-greatest [iterators keys len min-fill]
-  ;(println "GREATEST: " keys min-fill)
-  (loop [ix 1
-         greatest (aget keys 0)
-         found? true]
-    (if (>= ix len)
-      (if found?
-        (let [greatest (fill! (.slice greatest 0) min-fill)]
-          (iters-next iterators len min-fill)
-          #js [greatest min-fill])
-        #js [nil (reverse-fill! greatest min-fill)])
-      (let [comped (filled-key-compare greatest (aget keys ix) min-fill)
-            comped-v (or comped greatest)]
-        ;(println "g: " comped (and found? (not comped)) min-fill)
-        (recur (+ 1 ix) comped-v (and found? (not comped)))))))
-
-
-
-(defn seek-all [iterators len okey]
-  (loop [ix 0]
-    (if (< ix len)
-      (let [cur (aget iterators ix)
-            cur-key (.key cur)]
-        ;(println "searching for: " okey)
-        ;(println "    iterator " ix ": " cur-key)
-        (.seek cur okey)
-        ;(println "    post iterator " ix ": " (.key cur))
-        (when-not (.-iterator.end? cur)
-          (reverse-fill! (.key cur) okey)
-          (recur (+ 1 ix))))
-      (do
-        ;(println "    final search key: " okey)
-        true))))
-
-(defn join-with-start [iterators start-key len tuple-len keys min-fill]
-  (loop [key start-key]
-    (if (or (identical? (aget key 1) nil)
-            (not (identical? (aget key 0) nil)))
-      key
-      (if-not (seek-all iterators len (aget key 1))
-        #js [nil nil]
-        (do
-          (->keys iterators keys len)
-          (find-least keys len tuple-len min-fill)
-          ;(println "MIN FILL: " min-fill)
-          (recur (find-greatest iterators keys len min-fill)))))))
-
-(defn join [iterators len tuple-len keys min-fill]
-  (->keys iterators keys len)
-  (find-least keys len tuple-len min-fill)
-  (join-with-start iterators (find-greatest iterators keys len min-fill) len tuple-len keys min-fill))
-
 (deftype JoinIterator [iterators ^:mutable cur-key ^:mutable next-key ^:mutable end? len tuple-len keys min-fill]
   Object
   (key [this]
        cur-key)
+
+  (fillkeys [this]
+          (dotimes [x len]
+            (aset keys x (.key (aget iterators x)))))
+
+  (find-least [this]
+              (loop [ix 1
+                     col 0
+                     least (-> (aget keys 0)
+                               (aget 0))]
+                (if (>= ix len)
+                  (do
+                    (aset min-fill col least)
+                    (let [next (+ 1 col)]
+                      (if (< next tuple-len)
+                        (recur 0 next nil))))
+                  (let [cur (-> (aget keys ix)
+                                (aget col))]
+                    (recur (+ 1 ix) col (if (nilless-lt cur least)
+                                          cur
+                                          least))))))
+  (iters-next [this]
+              (let [last (aget iterators (- len 1))]
+                (.next last)
+                (if-not (.-end? last)
+                  (reverse-fill! (.key last) min-fill)
+                  (loop [ix (- len 2)]
+                    (when (>= ix 0)
+                      (let [cur (aget iterators ix)]
+                        (.next cur)
+                        (if (.-end? cur)
+                          (recur (- ix 1))
+                          (reverse-fill-with! (.key cur) min-fill false))))))))
+  (find-greatest ^:boolean [this]
+                 ;(println keys)
+                 (loop [ix 1
+                        greatest (aget keys 0)
+                        found? true]
+                   (if (>= ix len)
+                     (if found?
+                       (let [greatest (fill! (.slice greatest 0) min-fill)]
+                        ;(println "    ***setting greatest: " greatest)
+                         (.iters-next this)
+                         (set! cur-key greatest)
+                         (ainto next-key min-fill)
+                         false)
+                       (do
+                         (ainto next-key (reverse-fill! greatest min-fill))
+                         true))
+                     (let [comped (filled-key-compare greatest (aget keys ix) min-fill)
+                           comped-v (or comped greatest)]
+                      ;(println "g: " comped (and found? (not comped)) min-fill)
+                       (recur (+ 1 ix) comped-v (and found? (not comped))))))
+                )
+  (seek-all [this]
+            (loop [ix 0]
+              (if (< ix len)
+                (let [cur (aget iterators ix)
+                      cur-key (.key cur)]
+                 ;(println "searching for: " next-key)
+                 ;(println "    iterator " ix ": " cur-key)
+                  (.seek cur next-key)
+                 ;(println "    post iterator " ix ": " (.key cur))
+                  (if-not (.-iterator.end? cur)
+                    (do
+                      (reverse-fill! (.key cur) next-key)
+                      (recur (+ 1 ix)))
+                    (do
+                      (set! end? true)
+                      false)))
+                (do
+                 ;(println "    final search key: " okey)
+                  true)))
+            )
+  (init-join [this]
+             (.fillkeys this)
+             (.find-least this)
+             (when (identical? true (.find-greatest this))
+               (.seek-join this)))
+
+  (seek-join [this]
+             (loop [continue? true]
+               (when (identical? true continue?)
+                 (when (.seek-all this)
+                   (.fillkeys this)
+                   (.find-least this)
+                  ;(println "MIN FILL: " min-fill)
+                   (recur (.find-greatest this))
+                   )))
+             )
+
   (next [this]
         (if end?
           (set! cur-key nil)
-          (let [val (join-with-start iterators next-key len tuple-len keys min-fill)]
-            ;(println val)
-            (when (identical? (aget val 1) nil)
-              (set! end? true))
-            (set! cur-key (aget val 0))
-            (aset val 0 nil)
-            (ainto next-key val))))
+          (.seek-join this)
+          ))
+
   (seek [this key]
         (when (key-lt cur-key key)
-          (aset next-key 1 key)
+          (ainto next-key key)
           (.next this))))

 (defn join-iterator [iterators]
@@ -306,17 +306,16 @@
       (do
         (.next root)
         root)
-      (let [key-and-next (join iterators len tuple-len keys min-fill)]
-        (JoinIterator. iterators (aget key-and-next 0) #js [nil (aget key-and-next 1)] (identical? (aget key-and-next 1) nil)  len tuple-len keys min-fill)))))
+      (let [itr (JoinIterator. iterators (array) (array) false len tuple-len keys min-fill)]
+        (.init-join itr)
+        itr
+        ))))

 (defn all-join-results [join-itr]
   (let [results (array)]
     (while (and (not (.-end? join-itr)))
       (.push results (.key join-itr))
       (.next join-itr))
-    (when-not (or (== nil (.key join-itr))
-                  (== 0 (alength (.key join-itr))))
-      (.push results (.key join-itr)))
     results))

 (comment


+require [babel.directory]

+require [babel.directory]

--- src/babel/reader.clj
+++ src/babel/reader.clj
@@ -1,6 +1,7 @@
 (ns babel.reader
   [:refer-clojure :exclude [get-in resolve]]
   [:require
+   [babel.directory :refer [models]]
    [babel.engine :as engine]
    [babel.korma :as korma]
    [clojure.string :as string]


Fixing the time keeper

Fixing the time keeper

--- common-lib/src/cmr/common/time_keeper.clj
+++ common-lib/src/cmr/common/time_keeper.clj
@@ -17,7 +17,7 @@
   "Sets the override time to the current real time. This 'freezes' the time so that it won't advance
   until the advance time is called or the time is 'unfrozen' by calling clear-current-time!."
   []
-  (set-current-time! (t/now)))
+  (set-time-override! (t/now)))

 (defn advance-time!
   "Increases the time override by a number of seconds"


Changed get-find and get-aggregation to return a QueryResult record instead of a map

--- src/cfpb/qu/data.clj
+++ src/cfpb/qu/data.clj
@@ -23,6 +23,7 @@

 (defn disconnect-mongo []
   (mongo/disconnect!))
+

 (defn get-datasets
   "Get metadata for all datasets. Information about the datasets is
@@ -53,8 +54,10 @@
 (defn- strip-id [data]
   (map #(dissoc % :_id) data))

+(defrecord QueryResult [total size data])
+
 (defn get-find
-  "Given a collection and a Mongo find map, return a map of the form:
+  "Given a collection and a Mongo find map, return a QueryResult of the form:
    :total - Total number of documents for the input query irrespective of skip or limit
    :size - Number of documents for the input query after skip and limit are applied
    :data - Seq of maps with the IDs stripped out"
@@ -65,14 +68,13 @@
     (.limit (:limit find-map))
     (.skip (:skip find-map))
     (.sort (conv/to-db-object (:sort find-map))))]
-    {
-      :total (.count cursor)
-      :size (.size cursor)
-      :data (strip-id (map (fn [x] (conv/from-db-object x true)) cursor))
-    }))
+    (->QueryResult
+      (.count cursor)
+      (.size cursor)
+      (strip-id (map (fn [x] (conv/from-db-object x true)) cursor)))))

 (defn get-aggregation
-  "Given a collection and a Mongo aggregation, return a map of the form:
+  "Given a collection and a Mongo aggregation, return a QueryResult of the form:
    :total - Total number of results returned
    :size - Same as :total
    :data - Seq of maps with the IDs stripped out"
@@ -80,9 +82,7 @@
   (log/info (str "Mongo aggregation: " aggregation))
   (let [data (strip-id (coll/aggregate collection aggregation))
         size (count data)]
-    {:total size
-     :size size
-     :data data}))
+    (->QueryResult size size data)))

 (defn get-data-table
   "Given retrieved data (a seq of maps) and the columns you want from


Ensuring mongo.port is an integer, as it's a string when set via Java system properties

--- src/cfpb/qu/data.clj
+++ src/cfpb/qu/data.clj
@@ -12,7 +12,7 @@
              json]))

 (defn connect-mongo []
-  (let [address (mongo/server-address (env :mongo-host) (env :mongo-port))
+  (let [address (mongo/server-address (env :mongo-host)  (Integer/parseInt(str (env :mongo-port))))
         options (mongo/mongo-options)]
     (mongo/connect! address options)))


Check for a valid obi directory in the recording path

--- src/clj/mdr2/obi.clj
+++ src/clj/mdr2/obi.clj
@@ -59,14 +59,14 @@
   named `obiconfig.xml`. If true this is a strong indication that
   something isn't quite right."
   [production]
-  (let [root-dir (path/structured-path production)]
+  (let [root-dir (path/recording-path production)]
     (some? (seq (fs/glob root-dir "**/obiconfig.xml")))))

 (defn contains-necessary-files?
   "Return true if a `production` contains at least `obiconfig.xml`,
   `project.obi`, a `Data` and a `Backup` directory."
   [production]
-  (let [root-dir (path/structured-path production)]
+  (let [root-dir (path/recording-path production)]
     (and (->> ["obiconfig.xml" "project.obi"]
               (map (partial fs/path root-dir))
               (every? fs/exists?))
@@ -76,10 +76,12 @@

 (defn directory-valid?
   "Validate an Obi working directory for given production. Return true
-  if the production contains all necessary files,
-  see [[contains-necessary-files?]] and does not contains any subdirs
-  containing a `obiconfig.xml`, see [[contains-obi-subdirs?]]"
+  if the [[path/recording-path]] is a directory, the production
+  contains all necessary files (see [[contains-necessary-files?]]) and
+  it does not contains any subdirs containing a
+  `obiconfig.xml` (see [[contains-obi-subdirs?]])"
   [production]
   (and
+   (fs/directory? (path/recording-path production))
    (contains-necessary-files? production)
    (not (contains-obi-subdirs? production))))


Whitelist .asc files.

Whitelist .asc files.

--- src/clojars/repo.clj
+++ src/clojars/repo.clj
@@ -29,7 +29,7 @@
           {:status 201 :headers {} :body nil})))
   (PUT ["/:group/:artifact/:version/:file"
         :group #"[^\.]+" :artifact #"[^/]+" :version #"[^/]+"
-        :file #"[^/]+(\.pom|\.jar|\.sha1|\.md5)$"]
+        :file #"[^/]+(\.pom|\.jar|\.sha1|\.md5|\.asc)$"]
        {body :body {:keys [group artifact version file]} :params}
        (let [groupname (string/replace group "/" ".")]
          (with-account


set default :type to early_vote_site on early vote site form

--- src/cljs/early_vote_site/early_vote_site_form/events.cljs
+++ src/cljs/early_vote_site/early_vote_site_form/events.cljs
@@ -14,9 +14,9 @@
         fips (first (get-in db [:user :fipsCodes]))]
     (if (contains? roles "data-centralization")
       (-> db (assoc :active-panel :early-vote-site-form/main)
-          (assoc :early-vote-site-form {:county-fips fips}))
+          (assoc :early-vote-site-form {:county-fips fips :type "early_vote_site"}))
       (-> db (assoc :active-panel :early-vote-site-form/main)
-             (assoc :early-vote-site-form {})))))
+             (assoc :early-vote-site-form {:type "early_vote_site"})))))

 (defn navigate-edit
   [{:keys [db]} [_ id]]


RS & ML | 161 | Remove old requires

RS & ML | 161 | Remove old requires

--- src/stonecutter/controller/user.clj
+++ src/stonecutter/controller/user.clj
@@ -2,14 +2,11 @@
   (:require [clauth.endpoints :as cl-ep]
             [ring.util.response :as r]
             [stonecutter.routes :as routes]
-            [stonecutter.view.confirmation-sign-in :as sign-in]
             [stonecutter.validation :as v]
             [stonecutter.db.user :as user]
             [stonecutter.db.client :as c]
             [stonecutter.db.confirmation :as conf]
-            [stonecutter.db.token :as token]
             [stonecutter.email :as email]
-            [stonecutter.view.register :as register]
             [stonecutter.view.index :as index]
             [stonecutter.view.profile-created :as profile-created]
             [stonecutter.view.profile :as profile]
@@ -27,9 +24,6 @@
   (if (common/signed-in? request)
     (r/redirect (routes/path :show-profile))
     (sh/enlive-response (index/index request) (:context request))))
-
-(defn show-registration-form [request]
-  (sh/enlive-response (register/registration-form request) (:context request)))

 (defn send-confirmation-email! [email-sender user email confirmation-id config-m]
   (let [app-name (config/app-name config-m)


get converted trailing output from the terminal converter

--- frontend/models/action.cljs
+++ frontend/models/action.cljs
@@ -48,7 +48,8 @@
     (-> action
         (assoc-in [:output output-index :converted-message] (.append converter escaped-message))
         (assoc-in [:output output-index :react-key] (utils/uuid))
-        (assoc-in [:converters-state (keyword (:type output))] (utils/js->clj-kw (.currentState converter))))))
+        (assoc-in [:converters-state (keyword (:type output))] (merge (utils/js->clj-kw (.currentState converter))
+                                                                      {:converted-output (.get_trailing converter)})))))

 (defn format-latest-output [action]
   (if-let [output (seq (:output action))]
@@ -61,5 +62,5 @@
     action))

 (defn trailing-output [converters-state]
-  (str (get-in converters-state [:out :trailing_out])
-       (get-in converters-state [:err :trailing_out])))
+  (str (get-in converters-state [:out :converted-output])
+       (get-in converters-state [:err :converted-output])))


improved error reporting a bit

improved error reporting a bit

--- src/test/visual_regression_spec.clj
+++ src/test/visual_regression_spec.clj
@@ -24,7 +24,7 @@

 (defn capture-cards
   "Take screen shots of every devcard and write them to the output-dir
-  dir. Returns a vector of the file names of all the images captured."
+  dir. Returns a vector of the file names of all the images captured or :FAILED if there was an error."
   [output-dir]
   (try (let [driver             (start-browser)
              _                  (touch-dir output-dir)
@@ -43,12 +43,12 @@
                  card-title (taxi/text (str selector " span:nth-child(2)"))]
              (taxi/click selector)
              (timbre/info "navigated to " selector)
-             (Thread/sleep 300)
+             (Thread/sleep 1000)
              (let [cards     (taxi/elements "div.com-rigsomelight-devcards-panel-heading > a")
                    subtitles (mapv (fn [e] (-> e :webelement .getText)) cards)]
                (timbre/info "found " (count cards) " titled " subtitles)
                (doseq [subtitle subtitles]
-                 (let [ img-path (str output-dir card-title "-" subtitle ".png")]
+                 (let [img-path (str output-dir card-title "-" subtitle ".png")]
                    (timbre/info "navigating to " subtitle)
                    (taxi/get-url (str "http://localhost:8001/visuals.html#!/" card-title "/" subtitle))
                    (Thread/sleep 1000)
@@ -60,7 +60,7 @@
          (taxi/quit)
          @file-names)
        (catch Exception e (taxi/quit)
-                          [{:FAILED e}])))
+                          :FAILED)))

 (defn compare-cards
   "Compares screenshots in the expected and actual directories (generates the actual).
@@ -77,21 +77,23 @@
     (timbre/info "Expected directory" expected-dir)
     (timbre/info "Actual directory" actual-dir)
     (timbre/info "Diff directory" diff-dir)
-    (doseq [img-name imgs]
-      (let [expected-file    (io/as-file (str expected-dir img-name))
-            expected-exists? (.exists expected-file)
-            expected         (when expected-exists? (ImageIO/read ^File expected-file))
-            actual           (ImageIO/read ^File (io/as-file (str actual-dir img-name)))
-            differ           (ImageDiffer.)
-            diff             (when expected-exists? (.makeDiff differ expected actual))]
-        (when-not expected-exists?
-          (swap! diffs conj {:img-name img-name :no-expectation "Be sure to copy verified actual images to expected directory."})
-          (timbre/info (str "UNABLE TO DIFF VISUAL REGRESSIONS for " img-name ". Check actual, then copy them to expected.")))
-        (when (and diff (.hasDiff diff))
-          (swap! diffs conj {:img-name img-name})
-          (ImageIO/write (.getMarkedImage diff)
-            "png"
-            (io/as-file (str diff-dir img-name))))))
+    (if (= :FAILED imgs)
+      (reset! diffs [{:no-expectation "Image Capture failed. See log output."}])
+      (doseq [img-name imgs]
+        (let [expected-file    (io/as-file (str expected-dir img-name))
+              expected-exists? (.exists expected-file)
+              expected         (when expected-exists? (ImageIO/read ^File expected-file))
+              actual           (ImageIO/read ^File (io/as-file (str actual-dir img-name)))
+              differ           (ImageDiffer.)
+              diff             (when expected-exists? (.makeDiff differ expected actual))]
+          (when-not expected-exists?
+            (swap! diffs conj {:img-name img-name :no-expectation "Be sure to copy verified actual images to expected directory."})
+            (timbre/warn (str "UNABLE TO DIFF VISUAL REGRESSIONS for " img-name ". Check actual, then copy them to expected.")))
+          (when (and diff (.hasDiff diff))
+            (swap! diffs conj {:img-name img-name})
+            (ImageIO/write (.getMarkedImage diff)
+              "png"
+              (io/as-file (str diff-dir img-name)))))))
     @diffs))

 (specification "Visual Regressions"


Add better http client for test helpers.

--- test/uxbox/tests/helpers.clj
+++ test/uxbox/tests/helpers.clj
@@ -1,7 +1,6 @@
 (ns uxbox.tests.helpers
   (:refer-clojure :exclude [await])
-  (:require [clojure.test :as t]
-            [clj-http.client :as http]
+  (:require [clj-http.client :as http]
             [buddy.hashers :as hashers]
             [buddy.core.codecs :as codecs]
             [catacumba.serializers :as sz]
@@ -10,7 +9,7 @@
             [suricatta.core :as sc]
             [uxbox.services.auth :as usa]
             [uxbox.services.users :as usu]
-            [uxbox.util.transit :as transit]
+            [uxbox.util.transit :as t]
             [uxbox.migrations :as umg]
             [uxbox.media :as media]
             [uxbox.db :as db]
@@ -67,7 +66,7 @@
   [{:keys [status headers body]}]
   (if (= (get headers "content-type") "application/transit+json")
     [status (-> (codecs/str->bytes body)
-                (transit/decode))]
+                (t/decode))]
     [status body]))

 (defn http-get
@@ -87,7 +86,7 @@
   ([uri params]
    (http-post nil uri params))
   ([user uri {:keys [body] :as params}]
-   (let [body (-> (transit/encode body)
+   (let [body (-> (t/encode body)
                   (codecs/bytes->str))
          headers (merge
                   {"content-type" "application/transit+json"}
@@ -115,7 +114,7 @@
   ([uri params]
    (http-put nil uri params))
   ([user uri {:keys [body] :as params}]
-   (let [body (-> (transit/encode body)
+   (let [body (-> (t/encode body)
                   (codecs/bytes->str))
          headers (merge
                   {"content-type" "application/transit+json"}
@@ -139,10 +138,38 @@
        (catch clojure.lang.ExceptionInfo e
          (strip-response (ex-data e)))))))

-(defn data-encode
-  [data]
-  (-> (transit/encode data)
-      (codecs/bytes->str)))
+(defn- decode-response
+  [{:keys [status headers body] :as response}]
+  (if (= (get headers "content-type") "application/transit+json")
+    (assoc response :body (-> (codecs/str->bytes body)
+                              (t/decode)))
+    response))
+
+(defn request
+  [{:keys [path method body user headers raw?]
+    :or {raw? false}
+    :as request}]
+  {:pre [(string? path) (keyword? method)]}
+  (let [body (if (and body (not raw?))
+               (-> (t/encode body)
+                   (codecs/bytes->str))
+               body)
+        headers (cond-> headers
+                  body (assoc "content-type" "application/transit+json")
+                  raw? (assoc "content-type" "application/octet-stream")
+                  user (assoc "authorization"
+                              (str "Token " (usa/generate-token user))))
+        params {:headers headers :body body}
+        uri (str +base-url+ path)]
+    (try
+      (let [response (case method
+                       :get (http/get uri (dissoc params :body))
+                       :post (http/post uri params)
+                       :put (http/put uri params)
+                       :delete (http/delete uri params))]
+        (decode-response response))
+      (catch clojure.lang.ExceptionInfo e
+        (decode-response (ex-data e))))))

 (defn create-user
   "Helper for create users"


(PLATFORM-2817) Force the webp format option based on the Accept header

--- src/vignette/http/route_helpers.clj
+++ src/vignette/http/route_helpers.clj
@@ -8,6 +8,14 @@
             [vignette.util.thumbnail :as u]))

 (def blocked-placeholder-param "bp")
+
+(def webp-accept-header-name "accept")
+(def webp-accept-header-value "image/webp")
+(def force-webp-options {:format "webp"})
+
+(defn force-webp? [request]
+  (if-let [vary-string (get-in request [:headers webp-accept-header-name])]
+    (.contains vary-string webp-accept-header-value)))

 (defn handle-thumbnail
   [store image-params request]
@@ -35,10 +43,16 @@
                             #"^\/(.*)"
                             "$1")))

+(defn route->forced-image-options
+  [request options]
+  (if (force-webp? request)
+    (merge options force-webp-options)
+    options))
+
 (defn route->options
   "Extracts the query options and moves them to 'request-map'"
   [request-map request]
-  (assoc request-map :options (extract-query-opts request)))
+  (assoc request-map :options (merge (route->forced-image-options request (extract-query-opts request)))))

 (defn route->image-type
   [request-map]


fix logout with expired token

fix logout with expired token

--- ui/src/plant_care_ui/pages/users/events.cljs
+++ ui/src/plant_care_ui/pages/users/events.cljs
@@ -168,9 +168,16 @@
                    :on-success [:log-out/success]
                    :on-failure [:log-out/failure]}})))

+(defn handle-log-out [{:keys [db]}]
+  {:db (update-in db [:users] dissoc :current)
+   :dispatch [:clear-tokens]})
+
 (re-frame/reg-event-fx
  :log-out/success
  [utils/common-interceptors]
- (fn [{:keys [db]}]
-   {:db (update-in db [:users] dissoc :current)
-    :dispatch [:clear-tokens]}))
+ handle-log-out)
+
+(re-frame/reg-event-fx
+ :log-out/failure
+ [utils/common-interceptors]
+ handle-log-out)


upgrade lein-{ancient,kibit,eastwood}

upgrade lein-{ancient,kibit,eastwood}


Log a message if Twilio not configured, instead of trying to send SMS

--- src/deadman/core.clj
+++ src/deadman/core.clj
@@ -12,11 +12,18 @@
 (def twilio-auth-token (System/getenv "TWILIO_AUTH_TOKEN"))
 (def twilio-from-number (System/getenv "TWILIO_FROM_NUMBER"))

+(defn twilio-configured? []
+  (and twilio-sid
+       twilio-auth-token
+       twilio-from-number))
+
 (defn send-sms [number message]
-  (let [client (new TwilioRestClient twilio-sid twilio-auth-token)
-        message-factory (.getSmsFactory (.getAccount client))
-        message-params {"Body" message "To" number "From" twilio-from-number}]
-    (.create message-factory message-params)))
+  (if (twilio-configured?)
+    (let [client (new TwilioRestClient twilio-sid twilio-auth-token)
+          message-factory (.getSmsFactory (.getAccount client))
+          message-params {"Body" message "To" number "From" twilio-from-number}]
+      (.create message-factory message-params)))
+    (prn "Twilio not configured"))

 (defn build-timer-thread [{timeout "timeout", number "number", message "message", :as timer-data}]
   (Thread.


Works! :D

Works! :D

--- src/doctopus/web.clj
+++ src/doctopus/web.clj
@@ -76,8 +76,7 @@
                   "index.html"   {:get serve-index}
                   "add-head"     {:get serve-add-head-form :post add-head}
                   "add-tentacle" {:get serve-add-tentacle-form :post add-tentacle}
-                  "docs/"        [(load-routes doctopus)]}
-             ])
+                  "docs/"         [(load-routes doctopus)]}])

 (def application-handlers
   (bidi/make-handler routes))


in progress

in progress

--- src/epicea/utils.clj
+++ src/epicea/utils.clj
@@ -14,3 +14,15 @@
       i
       (recur (pop S) (pop I) (+ (* i (last S)) (last I))))))

+;; Macro to define an initial value and the keys
+(defmacro def-map [map-name empty-map]
+  `(do
+     (def ~(symbol (str "empty-" map-name)) ~empty-map)
+     (defn ~(symbol (str map-name "?")) [x#]
+       (map-with-keys? x# ~(set (keys empty-map))))))
+
+(defn provide-argument [fun index value]
+  (fn [& args0]
+    (let [args (vec args0)
+          args2 (concat (subvec args 0 index) [value] (subvec args index))]
+      (apply fun args2))))


Attach direction metadata to blocks

Attach direction metadata to blocks

--- src/fatlip/plot.cljs
+++ src/fatlip/plot.cljs
@@ -211,15 +211,23 @@
   greater index in the past. Continue finding these alignments until we've
   assigned every node into a horizontally aligned block"
   [flat-graph]
-  (take 2 (reduce (fn [[roots blocks pred-layer] layer]
-                    (let [[rs bs] (blockify-layer layer pred-layer roots blocks
-                                                  (:preds flat-graph)
-                                                  (:top-idxs flat-graph)
-                                                  (:marked flat-graph))]
-                      [rs bs layer]))
-                  [{} {} nil]
-                  (:layers flat-graph))))
-
+  (let [[roots blocks'] (->> (:layers flat-graph)
+                             (cons nil) ;; the first partition needs to have layer 1 in the second position
+                             (partition 2 1)
+                             (reduce (fn [[roots blocks] [pred-layer layer]]
+                                       (blockify-layer layer pred-layer roots blocks
+                                                       (:preds flat-graph)
+                                                       (:top-idxs flat-graph)
+                                                       (:marked flat-graph)))
+                                     [{} {}]))
+        reversed (:reversed (meta flat-graph))
+        blocks (->> blocks'
+                    (map (fn [[root block]]
+                           [root (if reversed
+                                   (with-meta block {:reversed true})
+                                   block)]))
+                    (into {}))]
+    [roots blocks]))

 (defn topo-sort
   "An implementation of a Kahn topological sort, cribbed with modification from