Refactor tests

Refactor tests

--- test/buildviz/testsuites_test.clj
+++ test/buildviz/testsuites_test.clj
@@ -204,6 +204,10 @@
   (a-testsuite "a suite"
                (a-testcase "a class" "the testcase" status)))

+(defn- another-testcase [status]
+  (a-testsuite "some suite"
+               (a-testcase "some class" "another testcase" status)))
+
 (deftest test-flaky-testcases-as-list
   (testing "flaky-testcases-as-list"
     (is (= []
@@ -227,17 +231,13 @@
              :flaky-count 1}]
            (flaky-testcases-as-list {"passed-run-id" build-input-1
                                      "failed-run-id" another-build-input-1}
-                                    (dummy-test-lookup {"passed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :pass))]
-                                                        "failed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :error))]}))))
+                                    (dummy-test-lookup {"passed-run-id" [(the-testcase :pass)]
+                                                        "failed-run-id" [(the-testcase :error)]}))))
     (is (= []
            (flaky-testcases-as-list {"passed-run-id" build-input-1
                                      "failed-run-id" another-build-input-1}
-                                    (dummy-test-lookup {"passed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :pass))]
-                                                        "failed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :pass))]}))))
+                                    (dummy-test-lookup {"passed-run-id" [(the-testcase :pass)]
+                                                        "failed-run-id" [(the-testcase :pass)]}))))
     (is (= [{:testsuite ["some suite"]
              :classname "some class"
              :name "another testcase"
@@ -246,25 +246,18 @@
              :flaky-count 1}]
            (flaky-testcases-as-list {"passed-run-id" build-input-1
                                      "failed-run-id" another-build-input-1}
-                                    (dummy-test-lookup {"passed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :pass))
-                                                                         (a-testsuite "some suite"
-                                                                                (a-testcase "some class" "another testcase" :pass))]
-                                                        "failed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :pass))
-                                                                         (a-testsuite "some suite"
-                                                                                (a-testcase "some class" "another testcase" :fail))]}))))
+                                    (dummy-test-lookup {"passed-run-id" [(the-testcase :pass)
+                                                                         (another-testcase :pass)]
+                                                        "failed-run-id" [(the-testcase :pass)
+                                                                         (another-testcase :fail)]}))))
     (is (= []
            (flaky-testcases-as-list {"failed-run-id" build-input-1}
-                                    (dummy-test-lookup {"failed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :fail))]}))))
+                                    (dummy-test-lookup {"failed-run-id" [(the-testcase :fail)]}))))
     (is (= []
            (flaky-testcases-as-list {"passed-run-id" build-input-2
                                      "failed-run-id" build-input-1}
-                                    (dummy-test-lookup {"passed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :pass))]
-                                                        "failed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :fail))]}))))
+                                    (dummy-test-lookup {"passed-run-id" [(the-testcase :pass)]
+                                                        "failed-run-id" [(the-testcase :fail)]}))))
     (is (= [{:testsuite ["a suite"]
              :classname "a class"
              :name "the testcase"
@@ -274,22 +267,18 @@
            (flaky-testcases-as-list {"passed-run-id" build-input-1
                                      "failed-run-id" another-build-input-1
                                      "another-failed-run-id" build-input-2}
-                                    (dummy-test-lookup {"passed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :pass))
-                                                                         (a-testsuite "another suite"
-                                                                                (a-testcase "another class" "another testcase" :pass))]
-                                                        "failed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :fail))]
-                                                        "another-failed-run-id" [(a-testsuite "another suite"
-                                                                                (a-testcase "another class" "another testcase" :fail))]}))))
+                                    (dummy-test-lookup {"passed-run-id" [(the-testcase :pass)
+                                                                         (another-testcase :pass)]
+                                                        "failed-run-id" [(the-testcase :fail)]
+                                                        "another-failed-run-id" [(another-testcase :fail)]}))))
     (is (= [{:testsuite ["a suite"]
              :classname "a class"
              :name "the testcase"
              :build-id "failed-run-id"
              :latest-failure (:start build-input-1)
              :flaky-count 1}
-            {:testsuite ["another suite"]
-             :classname "another class"
+            {:testsuite ["some suite"]
+             :classname "some class"
              :name "another testcase"
              :build-id "another-failed-run-id"
              :latest-failure (:start another-build-input-1)
@@ -297,14 +286,10 @@
            (flaky-testcases-as-list {"passed-run-id" build-input-1
                                      "failed-run-id" build-input-1
                                      "another-failed-run-id" another-build-input-1}
-                                    (dummy-test-lookup {"passed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :pass))
-                                                                         (a-testsuite "another suite"
-                                                                                (a-testcase "another class" "another testcase" :pass))]
-                                                        "failed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :fail))]
-                                                        "another-failed-run-id" [(a-testsuite "another suite"
-                                                                                (a-testcase "another class" "another testcase" :fail))]}))))
+                                    (dummy-test-lookup {"passed-run-id" [(the-testcase :pass)
+                                                                         (another-testcase :pass)]
+                                                        "failed-run-id" [(the-testcase :fail)]
+                                                        "another-failed-run-id" [(another-testcase :fail)]}))))
     (is (= [{:testsuite ["a suite"]
              :classname "a class"
              :name "the testcase"
@@ -338,29 +323,22 @@
                                      "failed-run-id" another-build-input-1
                                      "another-passed-run-id" build-input-2
                                      "another-failed-run-id" build-input-2}
-                                    (dummy-test-lookup {"passed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :pass))]
-                                                        "failed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :fail))]
-                                                        "another-passed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :pass))]
-                                                        "another-failed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :fail))]}))))
+                                    (dummy-test-lookup {"passed-run-id" [(the-testcase :pass)]
+                                                        "failed-run-id" [(the-testcase :fail)]
+                                                        "another-passed-run-id" [(the-testcase :pass)]
+                                                        "another-failed-run-id" [(the-testcase :fail)]}))))
     (is (= []
            (flaky-testcases-as-list {"passed-run-id" {}
                                      "failed-run-id" {}}
-                                    (dummy-test-lookup {"passed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :pass))]
-                                                        "failed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "the testcase" :fail))]})))))
+                                    (dummy-test-lookup {"passed-run-id" [(the-testcase :pass)]
+                                                        "failed-run-id" [(the-testcase :fail)]})))))
+
   (testing "should not find flaky tests in two failing builds where tests fails consistently"
     (is (= []
            (flaky-testcases-as-list {"first-failed-run-id" build-input-1
                                      "second-failed-run-id" another-build-input-1}
-                                    (dummy-test-lookup {"first-failed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "const failing testcase" :fail))]
-                                                        "second-failed-run-id" [(a-testsuite "a suite"
-                                                                                (a-testcase "a class" "const failing testcase" :fail))]})))))
+                                    (dummy-test-lookup {"first-failed-run-id" [(the-testcase :fail)]
+                                                        "second-failed-run-id" [(the-testcase :fail)]})))))

   (testing "should find flaky test in two failing builds"
     (is (= [{:testsuite ["a suite"]


tidy up magic number definition

tidy up magic number definition

--- test/digitalocean_expect/test.clj
+++ test/digitalocean_expect/test.clj
@@ -12,21 +12,27 @@
 (def stopped-nodes (nodes-by-status "stopped"))
 (def active-nodes (nodes-by-status "active"))

-; these magic numbers are unfortunate details
-; of the DigitalOcean API
+(def DIGITALOCEAN-SIZES
+  {:small  66
+   :medium 62
+   :large  60})

-(def DIGITALOCEAN-SMALL-ID 66)
-(def DIGITALOCEAN-MEDIUM-ID 62)
-(def DIGITALOCEAN-LARGE-ID 60)
+(def DIGITALOCEAN-LOCATIONS
+  {:london       7
+   :sanfrancisco 3})

-(def DIGITALOCEAN-LONDON-ID 7)
-(def DIGITALOCEAN-SANFRANCISCO-ID 3)
+(defn size-id [size id]
+  (= (size DIGITALOCEAN-SIZES) id))

-(defn small? [size] (= DIGITALOCEAN-SMALL-ID size))
-(defn medium? [size] (= DIGITALOCEAN-MEDIUM-ID size))
-(defn large? [size] (= DIGITALOCEAN-LARGE-ID size))
-(defn london? [region] (= DIGITALOCEAN-LONDON-ID region))
-(defn sf? [region] (= DIGITALOCEAN-SANFRANCISCO-ID region))
+(defn small? [id] (size-id :small id))
+(defn medium? [id] (size-id :medium id))
+(defn large? [id] (size-id :large id))
+
+(defn location-id [location region-id]
+  (= (location DIGITALOCEAN-LOCATIONS) region-id))
+
+(defn london? [region] (location-id :london region))
+(defn sf? [region] (location-id :sanfrancisco region))

 ; not more than 100 nodes
 (expect (< (count nodes) 100))


RS & GG | #5 | Ensure psqlexceptions are not caught in comments.clj

--- test/objective8/comments_test.clj
+++ test/objective8/comments_test.clj
@@ -22,3 +22,9 @@
        (storage/pg-retrieve {:entity :comment
                              :objective-id OBJECTIVE_ID}
                             {:limit 50}) => []))
+
+(fact "Postgresql exceptions are not caught"
+      (comments/store-comment! {:comment "something"}) => (throws org.postgresql.util.PSQLException)
+      (provided
+        (storage/pg-store! {:entity :comment :comment "something"}) =throws=> (org.postgresql.util.PSQLException.
+                                                                               (org.postgresql.util.ServerErrorMessage. "" 0))))


Fix text case on some tests

Fix text case on some tests

--- test/reagenttest/testreagent.cljs
+++ test/reagenttest/testreagent.cljs
@@ -288,10 +288,10 @@
   ;; (is (not (re-find #"enctype"
   ;;                   (as-string [:div {"enc-type" "x"}])))
   ;;     "Strings are passed through to React.")
-  (is (re-find #"enctype"
+  (is (re-find #"encType"
                (as-string [:div {"encType" "x"}]))
       "Strings are passed through to React, and have to be camelcase.")
-  (is (re-find #"enctype"
+  (is (re-find #"encType"
                (as-string [:div {:enc-type "x"}]))
       "Strings are passed through to React, and have to be camelcase."))


Restore profile macro.

Restore profile macro.

--- src/clj/c2/util.clj
+++ src/clj/c2/util.clj
@@ -13,6 +13,15 @@
   `(let [res# ~x]
      (.log js/console (prn-str res#))
      res#))
+
+(defmacro profile
+  "Profile `body` and print `descr`.
+   Returns result of body."
+  [descr & body]
+  `(let [start# (.getTime (js/Date.))
+         ret# (do ~@body)]
+    (print (str ~descr ": " (- (.getTime (js/Date.)) start#) " msecs"))
+    ret#))

 (defmacro timeout [delay & body]
   `(js/setTimeout (fn [] ~@body) ~delay))


Minor changes on text tool.

Minor changes on text tool.

--- frontend/src/uxbox/main/ui/shapes/text.cljs
+++ frontend/src/uxbox/main/ui/shapes/text.cljs
@@ -149,22 +149,31 @@
     own))

 (mx/defc text-shape-wrapper
-  {:mixins [mx/static]
+  {
    :did-mount text-shape-wrapper-did-mount
    :did-remount text-shape-wrapper-did-remount}
-  [{:keys [id tmp-resize-xform tmp-displacement] :as shape}]
+  [{:keys [id tmp-resize-xform tmp-displacement drawing?] :as shape}]
+  (println "text-shape-wrapper" shape)
   (let [xfmt (cond-> (gmt/matrix)
                 tmp-displacement (gmt/translate tmp-displacement)
                 tmp-resize-xform (gmt/multiply tmp-resize-xform))

         {:keys [x1 y1 width height] :as shape} (-> (geom/transform shape xfmt)
-                                                   (geom/size))]
-    [:foreignObject {:x x1
-                     :y y1
-                     :id (str id)
-                     :ref "fobject"
-                     :width width
-                     :height height}]))
+                                                   (geom/size))
+        attrs {:x x1
+               :y y1
+               :id (str id)
+               :ref "fobject"
+               :width width
+               :height height}
+        props (merge attrs
+                     (when drawing?
+                       {:style {:stroke "#333"
+                                :stroke-width "0.5"
+                                :stroke-opacity "0.5"
+                                :fill "transparent"}}))]
+
+    [:foreignObject props]))

 ;; --- Text Shape Html


Improve printing

Improve printing

Former-commit-id: e3e80b69670da209a4b5c502fa4ba6d04ba97735

--- planck-cljs/src/planck/core.cljs
+++ planck-cljs/src/planck/core.cljs
@@ -203,10 +203,13 @@
                   (repl/print-doc
                     (let [sym (second expression-form)]
                           (with-compiler-env st (resolve env sym)))))
-            pst (let [sym (or (second expression-form) '*e)]
-                  (read-eval-print (str "(planck.core/print-error " sym ")")
-                                   expression?
-                                   false)))
+            pst (let [expr (or (second expression-form) '*e)]
+                  (try (cljs/eval st
+                                  (list 'identity expr)
+                                  {:ns   @current-ns
+                                   :eval cljs/js-eval}
+                                  print-error)
+                       (catch js/Error e (prn :caught e)))))
           (prn nil))
         (try
           (cljs/eval-str


Fix symbol lookup for planck.repl ns

Fix symbol lookup for planck.repl ns

If you invoked `(doc doc)` you the output would
indicate that `doc` is in `planck.core`.

Fixes #194

--- planck-cljs/src/planck/repl.cljs
+++ planck-cljs/src/planck/repl.cljs
@@ -620,7 +620,7 @@
                   :name #(symbol "cljs.core" (name %))))
               (if-let [macro-var (with-compiler-env st
                                    (resolve env (symbol "planck.repl$macros" (name sym))))]
-                (update (assoc macro-var :ns 'planck.core)
+                (update (assoc macro-var :ns 'planck.repl)
                   :name #(symbol "planck.repl" (name %)))))]
     (if (= (namespace (:name var)) (str (:ns var)))
       (update var :name #(symbol (name %)))


flesh out missing text

flesh out missing text

--- docs/src/cljs/om_bootstrap/docs.cljs
+++ docs/src/cljs/om_bootstrap/docs.cljs
@@ -132,11 +132,35 @@
   (section
    "btn-dropdowns"
    "Button dropdowns"
-   (d/h3 "Single button dropdowns (TODO)")
-   (d/h3 "Split button dropdowns (TODO)")
-   (d/h3 "Sizing (TODO)")
-   (d/h3 "Dropup variation (TODO)")
-   (d/h3 "Dropdown right variation (TODO)")))
+   (d/p {:class "lead"}
+        "Use " (d/code "b/dropdown") " or " (d/code "b/split") "
+        components to display a button with a dropdown menu.")
+
+
+
+   (d/h3 "Single button dropdowns")
+   (d/p "Create a dropdown button with the " (d/code "b/dropdown") " component.")
+   (TODO)
+
+   (d/h3 "Split button dropdowns")
+   (d/p "Similarly, create split button dropdowns with
+   the " (d/code "b/split") " component.")
+   (TODO)
+
+   (d/h3 "Sizing")
+   (d/p "Button dropdowns work with buttons of all sizes.")
+   (TODO)
+
+   (d/h3 "Dropup variation")
+   (d/p "Trigger dropdown menus that site above the button by adding
+   the " (d/code ":dropup? true") " option.")
+   (TODO)
+
+
+   (d/h3 "Dropdown right variation")
+   (d/p "Trigger dropdown menus that align to the right of the button
+   using the " (d/code ":pull-right? true") " option.")
+   (TODO)))

 (defn button-main []
   (section
@@ -214,7 +238,18 @@
    (d/h3 "A static example")
    (d/p "A rendered modal with header, body, and set of actions in the footer.")
    (d/p "The header is added automatically if you pass in
-   a " (d/code ":title") " option.")))
+   a " (d/code ":title") " option.")
+   (TODO)
+
+   (d/h3 "Live Demo")
+   (d/p "Use " (d/code "overlay-trigger") " to create a real modal
+   that's added to the document body when opened.")
+   (TODO)
+
+   (d/h3 "Custom trigger")
+   (d/p "Use " (d/code "overlay-mixin") " in a custom component to
+   manage the modal's state yourself.")
+   (TODO)))

 ;; ## Tooltips


add lot test for commodity sale

add lot test for commodity sale

--- test/clj_money/trading_test.clj
+++ test/clj_money/trading_test.clj
@@ -197,7 +197,7 @@
     (is (empty? (-> result :transaction validation/error-messages))
         "Thhe transaction is valid")))

-(deftest selling-a-commodity-increases-the-balance-of-the-account
+(deftest selling-a-commodity-for-a-profit-increases-the-balance-of-the-account
   (let [context (serialization/realize storage-spec purchase-context)
         ira (-> context :accounts first)
         commodity (-> context :commodities first)
@@ -215,6 +215,25 @@
                          :balance)]
     (is (= 1560M new-balance) "The account balance decreases by the amount of the purchase")))

+(deftest selling-a-commodity-updates-a-lot-record
+  (let [context (serialization/realize storage-spec sell-context)
+        ira (-> context :accounts first)
+        commodity (-> context :commodities first)
+        _ (trading/sell storage-spec {:commodity-id (:id commodity)
+                                      :account-id (:id ira)
+                                      :trade-date (t/local-date 2017 3 2)
+                                      :shares 25M
+                                      :value 375M})
+        lots (map #(dissoc % :id :created-at :updated-at)
+                  (lots/search storage-spec {:account-id (:id ira)
+                                             :commodity-id (:id commodity)}))
+        expected [{:purchase-date (t/local-date 2016 3 2)
+                   :account-id (:id ira)
+                   :commodity-id (:id commodity)
+                   :shares-purchased 100M
+                   :shares-owned 75M}]]
+    (is (= expected lots) "The lot is updated to reflect the sale")))
+
 ; Selling a commodity updates a lot record (FILO updates the most recent, FIFO updates the oldest)
 ; Selling a commodity creates a lot transaction record
 ; Selling a commodity creates a transaction record


change dummy directory used in safe-path? tests to avoid automountd /home dir on OS X; .getCanonicalPath tosses IOExceptions on File objs for nonexistent paths under /home in that env

--- test/compojure/http/helpers.clj
+++ test/compojure/http/helpers.clj
@@ -17,5 +17,5 @@
          {:headers {"Content-Type" "text/html"}})))

 (deftest test-safe-path
-  (is (not (safe-path? "/home/compojure" "../private/secret.txt")))
-  (is (safe-path? "/home/compojure" "public/index.html")))
+  (is (not (safe-path? "/basedir/compojure" "../private/secret.txt")))
+  (is (safe-path? "/basedir/compojure" "public/index.html")))


Added a couple more session tests

Added a couple more session tests

--- test/compojure/http/session.clj
+++ test/compojure/http/session.clj
@@ -1,6 +1,8 @@
 (ns test.compojure.http.session
   (:use compojure.http.session)
   (:use clojure.contrib.test-is))
+
+;; Memory sessions

 (deftest create-memory-session
   (binding [*session-store* :memory]
@@ -32,6 +34,8 @@
       (destroy-session mock-session)
       (is (not (contains? @memory-sessions ::mock-id))))))

+;; Session routes
+
 (deftest session-nil-response
   (let [handler  (with-session (constantly nil))
         response (handler {})]
@@ -42,16 +46,28 @@

 (defmethod write-session ::mock [session])

+(defmethod read-session ::mock [id]
+  (is (= id ::mock-id))
+  {:id ::mock-id})
+
 (defmethod session-cookie ::mock [new? session]
   "mock-session-cookie")

+(defn- mock-session-response
+  [request response]
+  (let [handler (with-session (constantly response))]
+    (handler request)))
+
+(deftest new-session-cookie
+  (binding [*session-store* ::mock]
+    (let [response (mock-session-response {} {})]
+      (is (= (get-in response [:headers "Set-Cookie"])
+             "session=mock-session-cookie")))))
+
 (deftest response-session-cookie
   (binding [*session-store* ::mock]
-    (let [handler  (with-session (constantly {:session {}}))
-          response (handler {})
-          headers  (:headers response)]
-      (is (contains? headers "Set-Cookie"))
-      (is (= (headers "Set-Cookie")
+    (let [response (mock-session-response {} {:session {}})]
+      (is (= (get-in response [:headers "Set-Cookie"])
              "session=mock-session-cookie")))))

 (deftest session-store-test


No changes - no update

No changes - no update

--- src/joiner/main.clj
+++ src/joiner/main.clj
@@ -4,12 +4,16 @@
   (:use joiner.core)
   (:use joiner.user)
   (:use clojure.contrib.json)
+  (:use [clojure.contrib.http.agent :only [http-agent string]])
   (:use clojure.contrib.command-line))

 (defn- update-doc [id doc file]
   (let [existing (get-document (:_id (merge {:_id id} doc)))
-	updated-doc (update-document (merge existing doc))]
+	updated-doc (if (empty? doc)
+		      ;;If document is empty - don't bother updating it
+		      existing
+		      (update-document (merge existing doc)))]
     (if (nil? file)
       updated-doc
       (update-attachment updated-doc file))))


azulenoids.clj: cleaned up the on-template function

--- clojure/org/gavrog/clojure/azulenoids.clj
+++ clojure/org/gavrog/clojure/azulenoids.clj
@@ -2,7 +2,6 @@
   (:import (org.gavrog.jane.numbers Whole)
            (org.gavrog.joss.dsyms.basic DSymbol DynamicDSymbol)
            (org.gavrog.joss.dsyms.generators CombineTiles DefineBranching2d))
-  (:use [clojure.set :only [map-invert]])
   (:gen-class))

 (defn iterate-cycle [coll x]
@@ -56,13 +55,12 @@
               (take 16 template-boundary)))))

 (defn on-template [ds oct2tmp]
-  (let [tmp2oct (map-invert oct2tmp)
-        tmp (DynamicDSymbol. template)]
-    (doseq [D (keys tmp2oct) :when (not (.definesOp tmp 2 D))]
-      (.redefineOp tmp 2 D (oct2tmp (.op ds 2 (tmp2oct D)))))
-    (doseq [D (keys tmp2oct) :when (not (.definesV tmp 1 2 D))]
-      (.redefineV tmp 1 2 D (.v ds 1 2 (tmp2oct D))))
-    tmp))
+  (let [result (DynamicDSymbol. template)]
+    (doseq [[D D*] oct2tmp :when (not (.definesOp result 2 D*))]
+      (.redefineOp result 2 D* (oct2tmp (.op ds 2 D))))
+    (doseq [[D D*] oct2tmp :when (not (.definesV result 1 2 D*))]
+      (.redefineV result 1 2 D* (.v ds 1 2 D)))
+    result))

 (def octa-sets (filter #(-> %1 max-curvature .isNegative not)
                        (lazy-seq (CombineTiles. octagon))))


more detailed log/debug logging

more detailed log/debug logging

--- src/babel/forest.cljc
+++ src/babel/forest.cljc
@@ -113,7 +113,11 @@
         debug (log/debug (str "looking for candidate parents with parent: " (:rule parent) " and spec: " (strip-refs spec)))
         candidate-parents (filter #(not (fail? %))
                                   (map (fn [rule]
-                                         (do (log/debug (str "testing rule: " (:rule rule)))
+                                         (do (log/debug (str "testing rule::: " (:rule rule)))
+                                             (log/debug (str " result: " (unifyc spec rule)))
+                                             (log/debug (if (fail? (unifyc spec rule))
+                                                          (str "fail path: " (fail-path-between spec rule))
+                                                          (str "rule: " (:rule rule) " successfully unified with spec: " (strip-refs spec))))
                                              (unifyc spec rule)))
                                        (if parent (get-head-phrases-of parent index)
                                            grammar)))


Remove usage of potemkin (for cljs compatibility).

--- src/bytebuf/core.cljx
+++ src/bytebuf/core.cljx
@@ -2,29 +2,24 @@
   (:refer-clojure :exclude [read byte float double short long bytes])
   (:require [bytebuf.spec :as spec]
             [bytebuf.buffer :as buffer]
-            [bytebuf.proto :as proto]
-            [potemkin.namespaces :refer [import-vars]]))
+            [bytebuf.proto :as proto]))

-(import-vars
- [bytebuf.spec
-  compose-type
-  spec
-  string
-  string*
-  int32
-  int64
-  short
-  integer
-  long
-  float
-  double
-  byte
-  bytes
-  bool]
- [bytebuf.buffer
-  allocate]
- [bytebuf.proto
-  size])
+(def compose-type spec/compose-type)
+(def spec spec/spec)
+;; (def string spec/string)
+;; (def string* spec/string*)
+(def int32 spec/int32)
+(def int64 spec/int64)
+(def short spec/short)
+(def integer spec/integer)
+(def long spec/long)
+(def float spec/float)
+(def double spec/double)
+(def byte spec/byte)
+(def bytes spec/bytes)
+(def bool spec/bool)
+(def allocate buffer/allocate)
+(def size proto/size)

 (defn write!
   "Write data into buffer following the specified


Don't forget to copy price and product number info

into the new item

--- src/catalog/vubis.clj
+++ src/catalog/vubis.clj
@@ -192,6 +192,7 @@
   translate the language tag into proper ISO 639-1 codes"
   [{:keys [record-id source description source-publisher
            library-signature title creator
+           price product-number
            genre genre-code language format producer
            produced-commercially? source-date general-note
            series-title series-volume duration
@@ -216,7 +217,9 @@
                   :format fmt
                   :producer-brief (producer-raw-to-producer (Integer/parseInt producer))
                   :source-date (get-year source-date)
-                  :library-signature library-signature))]
+                  :library-signature library-signature
+                  :product-number product-number
+                  :price price))]
     (case fmt
       :hörbuch (-> item
                    (assoc-some


Remove dead code

Remove dead code

--- src/catalog/vubis.clj
+++ src/catalog/vubis.clj
@@ -407,7 +407,7 @@
   grouped under `:literatur-in-fremdsprachen`, even kids books, so we
   need to group not only by `format`, `genre` and `sub-genre` but also
   by `language`."
-  [{fmt :format genre :genre subgenre :sub-genre language :language :as item}]
+  [{fmt :format language :language :as item}]
   (cond
     (and (= fmt :hörbuch)
          (not (#{"de" "de-CH"} language))) [fmt :belletristik :literatur-in-fremdsprachen]
@@ -416,7 +416,7 @@
 (defn get-update-keys-hörfilm
   "Return the update keys for a given item (see `get-update-keys`).
   For the hörfilm catalog we need to group the :hörfilm items by genre."
-  [{fmt :format genre :genre subgenre :sub-genre language :language :as item}]
+  [{fmt :format genre :genre :as item}]
   (cond
     (#{:hörfilm} fmt) [fmt genre]
     :else (get-update-keys item)))
@@ -425,7 +425,7 @@
   "Return the update keys for a given item (see `get-update-keys`).
   For the ludo catalog we need to group all other formats under the
   genre :bücher-über-spiel."
-  [{fmt :format genre :genre subgenre :sub-genre language :language :as item}]
+  [{fmt :format genre :genre :as item}]
   (cond
     (not= fmt :ludo) [:ludo :bücher-über-spiel]
     :else [fmt genre]))


Emit package name.

Emit package name.

--- src/cbfg/zgo/core.clj
+++ src/cbfg/zgo/core.clj
@@ -8,7 +8,7 @@
 (def OUT-WIDTH 50)

 (defn word-wrap [width s] ; Returns a sequence of strings from word-wrapping s.
-  (re-seq (re-pattern (str ".{0," width "}\\s")) s))
+  (re-seq (re-pattern (str ".{0," width "}\\s")) (str s " ")))

 (defn ljust [width s] ; Left justify a string.
   (format (str "%-" width "s:") s))
@@ -45,6 +45,7 @@

 (defn c2g-sym [sym]
   (-> (str sym)
+      (string/replace "." "_")
       (string/replace "-" "_")
       (string/replace "?" "p")))

@@ -61,7 +62,8 @@

 (defn process-fn-params [params]
   ["(" (interpose "," (map (fn [sym] [(c2g-sym sym) (c2g-type sym)])
-                           params)) ")"])
+                           params))
+   ")"])

 (defn process-fn-body [params forms]
   (map-indexed (fn [idx form]
@@ -77,10 +79,11 @@

 (defn process-top-level-form [smodel form]
   (let [[op name & more] form]
-    (case (str op)
-      "ns" [(j ["package" name]) (line-range form)]
-      "defn" [(j (process-defn name (first more) (rest more))) (line-range form)]
-      "UNKNOWN-TOP-LEVEL-FORM")))
+    [(case (str op)
+      "ns" (j ["package" (c2g-sym name)])
+      "defn" (j (process-defn name (first more) (rest more)))
+      "UNKNOWN-TOP-LEVEL-FORM")
+     (line-range form)]))

 (defn process-top-level-forms [smodel]
   (map #(process-top-level-form smodel %)


* src/clj/cljs/core.clj: fix doseq so that all loop bindings are visible. Fixes CLJS-39

--- src/clj/cljs/core.clj
+++ src/clj/cljs/core.clj
@@ -486,8 +486,9 @@
                  [true `(do ~@body)]
                  (let [k (first exprs)
                        v (second exprs)
+
                        seqsym (when-not (keyword? k) (gensym))
-                       recform (if (keyword? k) recform `(recur (next ~seqsym)))
+                       recform (if (keyword? k) recform `(recur (first ~seqsym) ~seqsym))
                        steppair (step recform (nnext exprs))
                        needrec (steppair 0)
                        subform (steppair 1)]
@@ -501,11 +502,12 @@
                                              ~subform
                                              ~@(when needrec [recform]))
                                            ~recform)]
-                     :else [true `(loop [~seqsym (seq ~v)]
+                     :else [true `(let [~seqsym (seq ~v)]
                                     (when ~seqsym
-                                      (let [~k (first ~seqsym)]
-                                        ~subform
-                                        ~@(when needrec [recform]))))]))))]
+                                      (loop [~k (first ~seqsym) ~seqsym ~seqsym]
+                                       ~subform
+                                       (when-let [~seqsym (next ~seqsym)]
+                                        ~@(when needrec [recform])))))]))))]
     (nth (step nil (seq seq-exprs)) 1)))

 (defmacro amap


use regex check for virus type

use regex check for virus type

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -1375,7 +1375,7 @@
         (doseq [card (concat rig-cards hosted-cards hosted-on-ice)]
           ;Clear the added-virus-counter flag for each virus in play.
           ;We do this even on the corp's turn to prevent shenanigans with something like Gorman Drip and Surge
-          (when (or (has? card :subtype "Virus") (= (:counter-type card) "Virus"))
+          (when (re-find #"Virus" (:subtype card))
             (set-prop state :runner card :added-virus-counter false))))
       (swap! state assoc :end-turn true)
       (swap! state dissoc :turn-events))))
@@ -1505,7 +1505,10 @@
                                             (when host-card (str " on " (:title host-card)))
                                             (when no-cost " at no cost")))))
                  ;Apply added-virus-counter flag for this turn if the card enters play with a counter
-                 (if (and (= (:subtype installed-card) "Virus") (> (:counter installed-card) 0))
+                 (if (and
+                       (re-find #"Virus" (:subtype card))
+                       (contains? installed-card :counter)
+                       (> (:counter installed-card) 0))
                    (update! state side (assoc installed-card :added-virus-counter true))
                    )
                  (trigger-event state side :runner-install installed-card)


Retain counters/credits on derezzed Corp cards

Per the Official FAQ (page 4), a derezzed Corp card needs to *retain* all hosted credits, cards, and counters.

This is relevant now with the introduction of Test Ground, which is useful for reloading an Adonis or Eve Campaign with credits prior to them running out and self-trashing (and if you're really on the ball you'll re-rez for free with Breaker Bay Grid).

Currently we're only keeping advancement tokens on things like the advanceable Weyland ice. What I *think* this will do is stop dissociating `;counter` no matter what, then only proceed to dissociate them if it's a Runner card (Imps, Gravediggers, et al) or if `keep-counter true` has been passed via the `derez` function.

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -63,9 +63,9 @@
 (defn desactivate
   ([state side card] (desactivate state side card nil))
   ([state side card keep-counter]
-   (let [c (dissoc card :counter :current-strength :abilities :rezzed :special)
-         c (if (= (:side c) "Runner") (dissoc c :installed) c)
-         c (if keep-counter c (dissoc c :advance-counter))]
+   (let [c (dissoc card :current-strength :abilities :rezzed :special)
+         c (if (= (:side c) "Runner") (dissoc c :installed :counter) c)
+         c (if keep-counter c (dissoc c :counter :advance-counter))]
      (when-let [leave-effect (:leave-play (card-def card))]
        (when (or (= (:side card) "Runner") (:rezzed card))
          (leave-effect state side card nil)))


encode as ByteArrayBody

encode as ByteArrayBody

--- src/clj_http/core.clj
+++ src/clj_http/core.clj
@@ -7,6 +7,7 @@
            (org.apache.http.util EntityUtils)
            (org.apache.http.entity ByteArrayEntity)
            (org.apache.http.entity.mime MultipartEntity)
+           (org.apache.http.entity.mime.content ByteArrayBody)
            (org.apache.http.client HttpClient)
            (org.apache.http.client.methods HttpGet HttpHead HttpPut
                                            HttpPost HttpDelete
@@ -96,7 +97,7 @@
         (if multipart
           (let [mp-entity (MultipartEntity.)]
             (doseq [[k v] multipart]
-              (.addPart mp-entity (name k) v))
+              (.addPart mp-entity (name k) (ByteArrayBody. v (name k))))
             (.setEntity #^HttpEntityEnclosingRequest http-req mp-entity))
           (when body
             (let [http-body (ByteArrayEntity. body)]


Only add to cache if the response was successful

--- src/cljs/app/app.cljs
+++ src/cljs/app/app.cljs
@@ -23,7 +23,8 @@
   (swap! state assoc :results results))

 (defn update-cache [key new-results]
-  (swap! state assoc-in [:cache key] new-results))
+  (if (seq new-results)
+    (swap! state assoc-in [:cache key] new-results)))

 (defn load-all-results [url]
   (go


im feeling lucky

im feeling lucky

--- src/complico/core.clj
+++ src/complico/core.clj
@@ -12,7 +12,7 @@
             [hiccup.core :as hiccup]))

 ; url of the external search engine to use
-(def external-search-url "https://duckduckgo.com/?iac=1&q=")
+(def external-search-url "https://www.google.co.uk/search?btnI=1&q=")

 (def home-page
   (selmer/render-file "templates/index.html" {}))
@@ -54,10 +54,16 @@
 (defn build-search-url-from-params [params]
   (str external-search-url (params "search-term")))

+(defn get-redirected-location [url]
+  (-> url
+    (client/head)
+    (:trace-redirects)
+    (last)))
+
 (defn get-search-url [cookies params]
   (if (contains? cookies "test")
     (get-search-url-from-cookie cookies)
-    (build-search-url-from-params params)))
+    (get-redirected-location (build-search-url-from-params params))))

 (defroutes my-handler
   (GET "/" []


dummy passing test

dummy passing test

--- test/ruuvi_server/test/core.clj
+++ test/ruuvi_server/test/core.clj
@@ -2,5 +2,5 @@
   (:use [ruuvi-server.core])
   (:use [clojure.test]))

-(deftest replace-me ;; FIXME: write
-  (is false "No tests have been written."))
+(deftest dummy-test ;; FIXME: write
+  (is test "Dummy passing test."))


Added casting tests

Added casting tests

--- test/semantic_csv/core_test.clj
+++ test/semantic_csv/core_test.clj
@@ -15,3 +15,22 @@
              {"this" "x" "that" "y"})))))

+(deftest casting-test
+  (let [data [["this" "that"]
+              ["1" "y"]]]
+    (testing "should work with mappify"
+      (is (= (->> data
+                  mappify
+                  (cast-cols {:this ->int})
+                  first)
+             {:this 1 :that "y"}))))
+  (let [data [["1" "this"]
+              ["2" "that"]]]
+    (testing "should work without mappify"
+      (is (= (->> data
+                  (cast-cols {0 ->int})
+                  second)
+             [2 "that"])))))
+
+
+


Added test for except-first

Added test for except-first

--- test/semantic_csv/core_test.clj
+++ test/semantic_csv/core_test.clj
@@ -120,3 +120,20 @@
                {:this "dandstuff" :that "e" :more "f"}))))))

+(deftest except-first-test
+  (let [parsed-data [["this" "that" "more"]
+                     ["a" "b" "c"]
+                     ["d" "e" "f"]]]
+    (testing "Should leave first row unchanged"
+      (is (= (->> parsed-data
+                  (except-first (cast-with {0 (partial str "X")}))
+                  (first))
+             ["this" "that" "more"])))
+    (testing "Should generally work on remaining rows"
+      (is (= (->> parsed-data
+                  (except-first (cast-with {0 (partial str "X")})
+                                (remove #(= (first %) "Xa")))
+                  (second))
+             ["Xd" "e" "f"])))))
+
+


Update to ClojureScript 1.9.946

Update to ClojureScript 1.9.946

And allow ClojureScript to determine tools.reader dep

--- ClojureScript/replete/project.clj
+++ ClojureScript/replete/project.clj
@@ -7,8 +7,7 @@
                  [tailrecursion/cljson "1.0.7"]
                  [malabarba/lazy-map "1.1"]
                  [org.clojure/clojure "1.8.0"]
-                 [org.clojure/clojurescript "1.9.908"]
-                 [org.clojure/tools.reader "1.0.0"]
+                 [org.clojure/clojurescript "1.9.946"]
                  [org.clojure/test.check "0.10.0-alpha2"]] ; Clone and build test.check master (ref'd in script/build)
   :clean-targets ["out" "target"]
   :plugins [[lein-cljsbuild "1.1.5"]]


CMR-1436 Adds and updates nREPL tests.

CMR-1436 Adds and updates nREPL tests.

--- common-lib/test/cmr/common/test/nrepl.clj
+++ common-lib/test/cmr/common/test/nrepl.clj
@@ -6,12 +6,16 @@
             [cmr.common.nrepl :as nrepl-component]))

 (deftest test-nrepl-component
-  (let [component (lifecycle/start (nrepl-component/create-nrepl 0) nil)
-        port (:port component)
-        response (with-open [conn (nrepl/connect :port port)]
+  (let [repl (lifecycle/start (nrepl-component/create-nrepl 0) nil)
+        response (with-open [conn (nrepl/connect :port (:port repl))]
                    (-> (nrepl/client conn 1000)
                        (nrepl/message {:op :eval :code "(+ 21 21)"})
                        nrepl/response-values
                        first))]
     (is (= 42 response))
-    (lifecycle/stop component nil)))
+    (lifecycle/stop repl nil)))
+
+(deftest test-nrepl-port-in-use
+  (let [repl (lifecycle/start (nrepl-component/create-nrepl 0) nil)]
+    (is (thrown? java.net.BindException (lifecycle/start (nrepl-component/create-nrepl (:port repl)) nil)))
+    (lifecycle/stop repl nil)))


Also log in which compute cluster and pool we generate offers for kub… (#1278)

--- scheduler/src/cook/kubernetes/compute_cluster.clj
+++ scheduler/src/cook/kubernetes/compute_cluster.clj
@@ -221,8 +221,8 @@
           ; TODO: We are generating offers for every pool here, and filtering out only offers for this one pool.
           ; TODO: We should be smarter here and generate once, then reuse for each pool, instead of generating for each pool each time and only keeping one
           offers-this-pool (get offers-all-pools pool-name)]
-      (log/info (str "Generated offers " (count offers-this-pool) " for pool " pool-name " "
-                     (into [] (map #(into {} (select-keys % [:hostname :resources])) offers-this-pool))))
+      (log/info "Generated" (count offers-this-pool) "offers for pool" pool-name "in compute cluster" name
+                     (into [] (map #(into {} (select-keys % [:hostname :resources])) offers-this-pool)))
       offers-this-pool))

   (restore-offers [this pool-name offers]))


Don't shadow derive

Don't shadow derive

--- src/icecap/crypto.clj
+++ src/icecap/crypto.clj
@@ -11,6 +11,7 @@
   ;; (:require [caesium.crypto.generichash :refer [blake2b]]
   ;;           [caesium.crypto.secretbox :as secretbox])
   ;; (:import java.util Arrays)
+  (:refer-clojure :exclude [derive])
   (:require [crypto.random :as csprng]))

 (def cap-bits


bugfixes

bugfixes

--- src/notehub/views.clj
+++ src/notehub/views.clj
@@ -32,7 +32,7 @@
                      (reduce (fn [acc e]
                                (if-let [font (style e)]
                                  (str acc "|" (sreplace font #" " "+"))
-                                 "")) "" ["text-font" "header-font"]))}]
+                                 acc)) "" ["text-font" "header-font"]))}]
      [:style (css/generate style)]
      (if (= :js js?)
        (html
@@ -51,7 +51,7 @@
 (defn- input-form [form-url command fields content passwd-msg]
   (let [css-class (when (= :publish command) :hidden)]
     (layout :js {} (get-message :new-page)
-            [:article#preview ""]
+            [:article#preview {:style "flex: none"} ""]
             [:div#dashed-line {:class css-class}]
             [:div.central-element.helvetica {:style "margin-bottom: 3em"}
              (form-to {:autocomplete :off} [:post form-url]


Bug squashing in core

Bug squashing in core

- Properly pass extra tx info along to job-assertion
- Properly convert entity ids to job ids in transitive-dependents

--- src/overseer/core.clj
+++ src/overseer/core.clj
@@ -20,7 +20,7 @@
   [job-types tx]
   (zipmap
     (map identity job-types)
-    (map #(job-assertion %) job-types)))
+    (map #(job-assertion % tx) job-types)))

 (defn job-dep-edges [graph jobs-by-type]
   (for [[job deps] graph
@@ -60,7 +60,7 @@
            visited #{}
            to-visit #{job-ent-id}]
       (if (empty? to-visit)
-        (map #(:job/id (->job-entity db %)) all-dependents)
+        (map #(:job/id (d/entity db %)) all-dependents)
         (let [ent (first to-visit)
               dependents (ent-dependents db ent)
               all-dependents' (set/union all-dependents dependents)


faster scope check

faster scope check

--- src/pc/http/sente.clj
+++ src/pc/http/sente.clj
@@ -65,11 +65,12 @@
 (defn notify-document-transaction [db {:keys [read-only-data admin-data]}]
   (let [doc (:transaction/document read-only-data)
         doc-id (:db/id doc)]
-    (doseq [[uid {:keys [auth]}] (dissoc (get @document-subs doc-id) (:session/client-id read-only-data))]
+    (doseq [[uid {:keys [auth]}] (dissoc (get @document-subs doc-id) (:session/client-id read-only-data))
+            :let [max-scope (auth/max-document-scope db doc auth)]]
       (log/infof "notifying %s about new transactions for %s" uid doc-id)
-      ((:send-fn @sente-state) uid [:datomic/transaction (cond (auth/has-document-permission? db doc auth :admin)
+      ((:send-fn @sente-state) uid [:datomic/transaction (cond (auth/contains-scope? auth/scope-heirarchy max-scope :admin)
                                                                admin-data
-                                                               (auth/has-document-permission? db doc auth :read)
+                                                               (auth/contains-scope? auth/scope-heirarchy max-scope :read)
                                                                read-only-data)]))
     (when-let [server-timestamps (seq (filter #(= :server/timestamp (:a %)) (:tx-data admin-data)))]
       (log/infof "notifying %s about new server timestamp for %s" (:session/uuid admin-data) doc-id)
@@ -156,7 +157,7 @@
          (fn [subs]
            (-> subs
              (assoc-in [uuid :client-id] uuid)
-             (assoc-in [uuid :auth] cust)
+             (assoc-in [uuid :auth] {:cust cust})
              (update-in [uuid] merge (select-keys cust [:cust/uuid :cust/color-name :cust/name]))
              (assoc-in [uuid :show-mouse?] true)
              (assoc-in [uuid :frontend-id-seed] (choose-frontend-id-seed db document-id subs requested-remainder))))))


Complete DBFile implementation

Complete DBFile implementation

--- src/photon/filedb.clj
+++ src/photon/filedb.clj
@@ -5,11 +5,23 @@

 (defrecord DBFile [file-name]
   db/DB
-  (db/fetch [this id] {})
-  (db/delete! [this id])
-  (db/delete-all! [this])
-  (db/put [this data])
-  (db/search [this id] [])
+  (db/fetch [this id]
+    (first (db/search this id)))
+  (db/delete! [this id]
+    (let [all (db/lazy-events this "__all__" 0)
+          filtered (remove #(= id (:local-id %)) all)]
+      (db/delete-all! this)
+      (dorun (map #(db/store this (:stream-name %) "" %) filtered))))
+  (db/delete-all! [this]
+    (.delete (java.io.File. file-name))
+    (java.io.File. file-name))
+  (db/put [this data]
+    (db/delete! this (:local-id data))
+    (db/store this (:stream-name data) "" data))
+  (db/search [this id]
+    (let [all (db/lazy-events this "__all__" 0)
+          filtered (filter #(= id (:local-id %)) all)]
+      filtered))
   (db/store [this stream-name event-name payload]
     (log/info "Payload" payload)
     (let [server-timestamp (:server-timestamp payload)
@@ -19,7 +31,8 @@
                                (long server-timestamp)))]
       (with-open [w (clojure.java.io/writer file-name :append true)]
         (.write w (str (json/write-str new-payload) "\n")))))
-  (db/event [this id] {})
+  (db/event [this id]
+    (db/fetch this id))
   (db/distinct-values [this k]
     (into #{} (map #(get % k)
                    (db/lazy-events this "__all__" 0))))


Scumbag programmer: Writes lots of code, leaves print statements.

--- src/picard/client.clj
+++ src/picard/client.clj
@@ -24,7 +24,7 @@
        (if (instance? HttpResponse msg)
          (resp :respond (netty-resp->resp msg))
          (if (.isLast msg)
-           (and (resp :done nil) (println "Finishing the response"))
+           (resp :done nil)
            (resp :body (.getContent msg)))))
      nil)))


Use the exact same start and playhead when we init an instrument

--- src/playmary/one.cljs
+++ src/playmary/one.cljs
@@ -104,12 +104,13 @@

 (defn create-instrument
   [scale]
-  {:piano-keys (into (sorted-map) (map-indexed (fn [i freq] [freq {:n i}])
-                                               scale))
-   :notes [] :w 0 :h 0 :sound-ready false
-   :px-per-ms 0.04
-   :start (.getTime (js/Date.))
-   :playhead (.getTime (js/Date.))})
+  (let [start (.getTime (js/Date.))]
+    {:piano-keys (into (sorted-map) (map-indexed (fn [i freq] [freq {:n i}])
+                                                 scale))
+     :notes [] :w 0 :h 0 :sound-ready false
+     :px-per-ms 0.04
+     :start start
+     :playhead start}))

 (defn add-synths-to-instrument
   [instrument]


Docstring

Docstring

--- src/re_view/core.cljs
+++ src/re_view/core.cljs
@@ -204,6 +204,25 @@
     (apply js-obj (mapcat identity (wrap-lifecycle-methods methods)))))

 (defn component
+  "Returns a React component factory for supplied lifecycle methods.
+   Expects a single map of functions, or any number of key-function pairs,
+
+   (component {:render (fn [this] [:div ...])})
+
+   -or-
+
+   (component
+
+     :get-initial-state
+     (fn [this] {:apple-state :ripe})
+
+     :render
+     (fn [this] [:div ...]))
+
+   See other functions in this namespace for how to work with props and state.
+   Result of :render function is automatically wrapped in sablono.core/html,
+   unless it is already a valid React element.
+   "
   [& methods]
   (let [methods (if (and (= 1 (count methods)) (map? (first methods)))
                   (first methods)


Update as per @otfrom's comments.

Update as per @otfrom's comments.

--- src-cljs/kixi/hecuba/tabs/hierarchy/datasets.cljs
+++ src-cljs/kixi/hecuba/tabs/hierarchy/datasets.cljs
@@ -208,53 +208,45 @@
              [:option {:value (:value item) :selected "selected"} (:display item)]
              [:option {:value (:value item)} (:display item)]))]]]))))

-(defmulti filter-series (fn [operation selected-series all-series] operation))
-
-(defmethod filter-series "sum" [operation selected-series all-series]
+(defmulti filter-by-period (fn [selected-series all-series]
+                          (let [[device_id sensor_id period unit] (string/split selected-series #"~")]
+                            period)))
+
+(defmethod filter-by-period "INSTANT" [selected-series all-series]
   (let [[device_id sensor_id period unit] (string/split selected-series #"~")
-        filtered-series (case period
-                          "INSTANT" (->> all-series
-                                         (filter #(= (:unit %) unit))
-                                         (filter #(= (:period %) "INSTANT"))
-                                         (into [])
-                                         (concat [{:display "Select series" :value "none"}] ))
-                          "CUMULATIVE" (->> all-series
-                                            (filter #(= (:unit %) unit))
-                                            (filter #(not= (:period %) "INSTANT"))
-                                            (into [])
-                                            (concat [{:display "Select series" :value "none"}] ))
-                          "PULSE" (->> all-series
-                                       (filter #(= (:unit %) unit))
-                                       (filter #(not= (:period %) "INSTANT"))
-                                       (into [])
-                                       (concat [{:display "Select series" :value "none"}] ))
-                          all-series)]
+        filtered-series (->> all-series
+                             (filter #(= (:unit %) unit))
+                             (filter #(= (:period %) "INSTANT"))
+                             (into [])
+                             (concat [{:display "Select series" :value "none"}]))]
     (into [] (remove #(= selected-series (:value %)) filtered-series))))

-(defmethod filter-series "subtract" [operation selected-series all-series]
+(defmethod filter-by-period "CUMULATIVE" [selected-series all-series]
   (let [[device_id sensor_id period unit] (string/split selected-series #"~")
-        filtered-series (case period
-                          "INSTANT" (->> all-series
-                                         (filter #(= (:unit %) unit))
-                                         (filter #(= (:period %) "INSTANT"))
-                                         (into [])
-                                         (concat [{:display "Select series" :value "none"}] ))
-                          "CUMULATIVE" (->> all-series
-                                            (filter #(= (:unit %) unit))
-                                            (filter #(not= (:period %) "INSTANT"))
-                                            (into [])
-                                            (concat [{:display "Select series" :value "none"}] ))
-                          "PULSE" (->> all-series
-                                       (filter #(= (:unit %) unit))
-                                       (filter #(not= (:period %) "INSTANT"))
-                                       (into [])
-                                       (concat [{:display "Select series" :value "none"}] ))
-                          all-series)]
+        filtered-series (->> all-series
+                             (filter #(= (:unit %) unit))
+                             (filter #(not= (:period %) "INSTANT"))
+                             (into [])
+                             (concat [{:display "Select series" :value "none"}]))]
     (into [] (remove #(= selected-series (:value %)) filtered-series))))

-(defmethod filter-series "divide" [operation selected-series all-series]
+(defmethod filter-by-period  "PULSE" [selected-series all-series]
+  (let [[device_id sensor_id period unit] (string/split selected-series #"~")
+        filtered-series (->> all-series
+                             (filter #(= (:unit %) unit))
+                             (filter #(not= (:period %) "INSTANT"))
+                             (into [])
+                             (concat [{:display "Select series" :value "none"}]))]
+    (into [] (remove #(= selected-series (:value %)) filtered-series))))
+
+(defmethod filter-by-period :default [selected-series all-series]
+  all-series)
+
+(defn filter-series [operation selected-series all-series]
   (let [[device_id sensor_id period unit] (string/split selected-series #"~")]
-    (into [] (remove #(= selected-series (:value %)) all-series))))
+    (if (= operation "divide")
+      (into [] (remove #(= selected-series (:value %)) all-series))
+      (filter-by-period selected-series all-series))))

 (defmulti dropdowns (fn [cursor owner opts] (:operation cursor)))


figwheel.core: source-file may not be a file

--- figwheel-core/src/figwheel/core.cljc
+++ figwheel-core/src/figwheel/core.cljc
@@ -394,7 +394,8 @@
   (let [files (set files)]
     (filter
      #(when-let [source-file (:source-file %)]
-        (files (.getCanonicalPath source-file)))
+        (when (instance? java.io.File source-file)
+          (files (.getCanonicalPath source-file))))
      sources)))

 (defn js-dependencies-with-file-urls [js-dependency-index]
@@ -640,27 +641,28 @@
    (js-dependencies-with-file-urls (:js-dependency-index compiler-env))))

 (defn source-file [source-o-js-dep]
-  (cond
-    (:url source-o-js-dep) (io/file (.getFile (:url source-o-js-dep)))
-    (:source-file source-o-js-dep) (:source-file source-o-js-dep)))
+  (let [f (cond
+            (:url source-o-js-dep) (io/file (.getFile (:url source-o-js-dep)))
+            (:source-file source-o-js-dep) (:source-file source-o-js-dep))]
+    (when (instance? java.io.File f) f)))

 (defn sources->modified-map [sources]
   (into {}
-        (map (comp
-              (juxt #(.getCanonicalPath %) #(.lastModified %))
-              source-file))
+        (comp
+         (keep source-file)
+         (map (juxt #(.getCanonicalPath %) #(.lastModified %))))
         sources))

 (defn sources-modified [compiler-env last-modifieds]
   (doall
    (keep
     (fn [source]
-      (let [file' (source-file source)
-            path  (.getCanonicalPath file')
-            last-modified' (.lastModified file')
-            last-modified (get last-modifieds path 0)]
-        (when (> last-modified' last-modified)
-          (vary-meta source assoc ::last-modified last-modified'))))
+      (when-let [file' (source-file source)]
+        (let [path  (.getCanonicalPath file')
+              last-modified' (.lastModified file')
+              last-modified (get last-modifieds path 0)]
+          (when (> last-modified' last-modified)
+            (vary-meta source assoc ::last-modified last-modified')))))
     (all-sources compiler-env))))

 (defn sources-modified! [compiler-env last-modified-vol]


Remove fixtures.cljs

Remove fixtures.cljs

--- frontend/src/faceboard/fixtures.cljs
+++ frontend/src/faceboard/fixtures.cljs
@@ -1,36 +0,0 @@
-(ns faceboard.fixtures)
-
-; just some sample data until we get editing working...
-
-; country codes: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
-
-(def hackerparadise-people
-  [{:name "Tony"
-    :photo-url "https://media.licdn.com/mpr/mpr/shrink_200_200/p/3/000/000/340/25abdea.jpg"
-    :full-name "Antonin Hildebrand"
-    :email "antonin@hildebrand.cz"
-    :nick "darwin"
-    :country "cz"
-    :tags ["objective-c" "c++" "clojure" "coffeescript" "ruby" "bitcoin" "totalfinder" "binaryage"]
-    :twitter "dr_win"
-    :github "darwin"
-    :facebook "antonin.hildebrand"
-    :web "http://about.me/darwin"}
-   {:name "Alexey"
-    :full-name "Alexey Komissarouk"
-    :photo-url "https://dl.dropboxusercontent.com/u/559047/alexey.png"
-    :country "ua"
-    :tags ["python" "ruby" "coffeescript"]}
-   {:name "Casey"
-    :photo-url "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xfa1/v/t1.0-1/p320x320/10922481_10203659752437972_2370943592623339289_n.jpg?oh=1ac1307dfc8d82940d72d88180647a99&oe=55596ACD&__gda__=1430872829_0a138cd9d51b45e5a64ecab91eb7c6ed"
-    :tags ["go"]}
-   {:name "Nicole"
-    :photo-url "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xfa1/v/t1.0-1/p320x320/10881546_10152973877694314_4257642747410385209_n.jpg?oh=b8d2a194c71b1a1717fd95d2ed58c0d9&oe=5588B5AD&__gda__=1435535261_13840be1f86414a6fe6b67ff99c84839"
-    :country "us"
-    :tags ["design"]}])
-
-(def hackerparadise-places
-  [{:name "An's"
-    :description "Great coffee"}
-   {:name "Tam's"
-    :description "Best burgers in the town"}])


Modify ->spec* impl for s/spec so that it accepts nil

--- src/specium/core.cljc
+++ src/specium/core.cljc
@@ -27,7 +27,8 @@
         :else (->spec* x)))

 (defmethod ->spec* `s/spec [[_ form]]
-  (s/spec-impl form (->spec form) nil nil))
+  (when form
+    (s/spec-impl form (->spec form) nil nil)))

 (defmethod ->spec* `s/and [[_ & pred-forms]]
   (s/and-spec-impl pred-forms (mapv ->spec pred-forms) nil))


fix indentation in meta/contains? doc string

--- src/such/metadata.clj
+++ src/such/metadata.clj
@@ -34,7 +34,7 @@
   "Answer whether the metadata contains the given key. A key with
    a `nil` value counts as being contained.

-      (meta/contains? o :author) => true
+        (meta/contains? o :author) => true
 "
   [o key]
   (clojure.core/contains? (meta o) key))


class name

class name

--- src/tango/export2.clj
+++ src/tango/export2.clj
@@ -70,9 +70,7 @@
     (fn [form]
       (cond
         (= (:tag form) :Results) (merge form {:attrs   {:Qty (inc (count (:content form)))}
-                                              ;; TODO - ML fixar och noterar saknad data
                                               :content (conj (vec (:content form))
-                                                             ;(xml/element :Foo {})
                                                              (make-result-node
                                                               (get-in class-result [:result :result-array] )
                                                               (get-in class-result [:result :round] )
@@ -89,7 +87,7 @@
     (fn [form]
       (cond
         (= (:tag form) :Class) (if (= (:Name (:attrs form))
-                                      "Disco Freestyle B-klass J Po")
+                                      (:class-name class-result))
                                  (fix-class form class-result)
                                  ;(xml/element :Class {:Name "Changed Class"})
                                  form)


fix accidental joins

fix accidental joins

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

--- src/aurora/editor/core.cljs
+++ src/aurora/editor/core.cljs
@@ -187,17 +187,19 @@
        (rule "draw draw preview elem"
              (when "ui/editor-elem" {:clause-id 'clause})
              (when "editor clause fields" {:clause-id clause :constant|variable|expression 'cv :val 'tag :key "tag"})
-             (when "editor clause fields" {:clause-id clause :constant|variable|expression 'cv :val 'id :key "elem-id"})
+             (when "editor clause fields" {:clause-id clause :constant|variable|expression 'cv2 :val 'id :key "elem-id"})
              (func 'pid "\"tag\" + id")
              (draw [:div {:id 'id :className "preview-elem"}
                     [:span {:id 'pid :className "preview-elem-tag"} 'tag]
                     ])
               )

+
+
        (rule "draw draw preview text"
              (when "ui/editor-text" {:clause-id 'clause})
              (when "editor clause fields" {:clause-id clause :constant|variable|expression 'cv :val 'text :key "text"})
-             (when "editor clause fields" {:clause-id clause :constant|variable|expression 'cv :val 'id :key "elem-id"})
+             (when "editor clause fields" {:clause-id clause :constant|variable|expression 'cv2 :val 'id :key "elem-id"})
              (draw [:span {:id 'id :className 'cv} 'text])

               )
@@ -205,8 +207,8 @@
          (rule "translate draw preview child"
              (when "ui/editor-child" {:clause-id 'clause})
              (when "editor clause fields" {:clause-id clause :constant|variable|expression 'cv :val 'pos :key "pos"})
-             (when "editor clause fields" {:clause-id clause :constant|variable|expression 'cv :val 'pid :key "parent-id"})
-             (when "editor clause fields" {:clause-id clause :constant|variable|expression 'cv :val 'cid :key "child-id"})
+             (when "editor clause fields" {:clause-id clause :constant|variable|expression 'cv2 :val 'pid :key "parent-id"})
+             (when "editor clause fields" {:clause-id clause :constant|variable|expression 'cv3 :val 'cid :key "child-id"})
              (pretend "ui/child" {:parent-id 'pid :pos 'pos :child-id 'cid})

               )
@@ -225,6 +227,7 @@
      (do (defaults editor)
        (re-run editor)))))

+(run)

 (comment


Strip namespace-qualification from symbols since we're not smart enough to deal with them anyway and they make matching difficult

--- src/cake/tasks/coverage.clj
+++ src/cake/tasks/coverage.clj
@@ -22,7 +22,7 @@
     [namespaces namespaces]
     (for [n namespaces
           [sym var] (ns-publics (find-ns (doto n require)))
-          :when (and (bound? var) (fn? @var) (-> var meta (get :needs-test true)))]
+          :when (and (bound? var) (fn? @var) (not (-> var meta :dont-test)))]
       (apply symbol (map str [n sym])))))

 (defn clj-test-files []
@@ -37,7 +37,10 @@
          (catch Throwable _))))

 (defn used-symbols [file]
-  (filter symbol? (flatten (read-all (java.io.PushbackReader. (reader file))))))
+  (->> (read-all (java.io.PushbackReader. (reader file)))
+       flatten
+       (filter symbol?)
+       (map (comp symbol name)))) ;; strip namespace - too hard to do right

 (defn un-tested-symbols [testables]
   (let [tested (set (mapcat used-symbols (clj-test-files)))


layout

layout

--- src/celestial/workflows.clj
+++ src/celestial/workflows.clj
@@ -17,8 +17,12 @@
     [slingshot.slingshot :only  [throw+ try+]]
     [celestial.model :only (vconstruct pconstruct rconstruct)])
   (:require ; loading defmethods
-    proxmox.provider aws.provider vc.provider
-    physical.provider docker.provider
+    proxmox.provider
+    aws.provider
+    vc.provider
+    physical.provider
+    docker.provider
+    openstack.provider
     celestial.puppet_standalone
     remote.capistrano remote.ruby
     ;cloning


Add PATCH to the node resource allowed methods.

Refs #63.

--- src/clj/shale/resources.clj
+++ src/clj/shale/resources.clj
@@ -270,7 +270,7 @@
            (nodes/refresh-nodes (->node-pool context))))

 (defresource node-resource [id]
-  :allowed-methods [:get :put :delete]
+  :allowed-methods [:get :patch :delete]
   :available-media-types ["application/json"]
   :known-content-type? is-json-or-unspecified?
   :malformed? #(parse-request-data


Updating to latest DataScript (0.12.1) means we don't need to implement IComparable for everything

--- src/cljs/dato/lib/core.cljs
+++ src/cljs/dato/lib/core.cljs
@@ -20,19 +20,6 @@
   (atom true))

 (set! (.-networkEnabled js/window) network-enabled?)
-
-;; Extend protocols for transit/datascript reasons.  This should
-;; *possibly* be pushed off to user-land code, but needs to be there
-;; to optimize (not solve) Datomic/DataScript compatibility.
-(extend-type goog.Uri
-  IComparable
-  (-compare [x y]
-    (compare (.toString x) (.toString y))))
-
-(extend-type cljs.core/PersistentHashSet
-  IComparable
-  (-compare [x y]
-    (compare (hash x) (hash y))))

 (def transit-reader
   (transit/reader :json


Cleanup logging

Cleanup logging

--- src/cljs/dato/lib/core.cljs
+++ src/cljs/dato/lib/core.cljs
@@ -89,9 +89,7 @@
                               (cast! payload nil))
                              ([payload meta]
                               (if @cast-bootstrapped?
-                                (do
-                                  (js/console.log "cast! " (pr-str payload))
-                                  (put! dato-ch payload))
+                                (put! dato-ch payload)
                                 (js/console.log "Not yet bootstrapped, ignoring cast"))
                               true))
         history            (atom {:current-path nil
@@ -173,7 +171,6 @@
                               ([event payload]
                                (broadcast! event payload nil))
                               ([event payload meta]
-                               (js/console.log "broadcast! " (pr-str event) (pr-str payload))
                                (dato-send! event payload)
                                true))
                 :bootstrap! (fn []


Add function to translate to english names

--- src/cljs/movement/data.cljs
+++ src/cljs/movement/data.cljs
@@ -56,6 +56,13 @@

 (defn get-movements-map []
   (into {} (map (fn [m] [(:name m) m]) all-movements)))
+
+(defn all-movements-english []
+  (mapv #(assoc % :name (-> (:image %)
+                            clojure.string/capitalize
+                            (clojure.string/replace "-" " ")
+                            (clojure.string/replace ".png" "")))
+        all-movements))

 (def all-movements [{:name "Beinsving sideveis",
                      :image "side-leg-swing.png",


rename, etc

rename, etc

--- src/clojure_fabric/core.clj
+++ src/clojure_fabric/core.clj
@@ -15,8 +15,6 @@
             [clojure.core.cache :as cache])
   (:import [org.hyperledger.fabric.sdk User Enrollment]
            [org.bouncycastle.jcajce.provider.asymmetric.ec BCECPrivateKey]))
-
-(defrecord Client [client channel])

 (defonce client-lru-cache
   ;; FIXME: magic number
@@ -39,23 +37,37 @@
                                (getMspId [this] msp-id)))
     new-client))

-(defn make-key+cert-hash [priv-key cert]
+(defn priv-key+cert->hash [priv-key cert]
   (hash (str (.toString ^BCECPrivateKey priv-key) cert)))

 (defn evict-client-from-cache [client]
   (let [enrollment (.getEnrollment ^User (client/get-user-context client))
-        cache-key (make-key+cert-hash (.getKey ^Enrollment enrollment)
+        cache-key (priv-key+cert->hash (.getKey ^Enrollment enrollment)
                                       (.getCert ^Enrollment enrollment))]
     (swap! client-lru-cache cache/evict cache-key)))

-(defn make-client [msp-id name priv-key cert & opts]
-  (let [cache-key (make-key+cert-hash priv-key cert)
+(defn get-or-make-client [msp-id name priv-key cert & opts]
+  (let [cache-key (priv-key+cert->hash priv-key cert)
         lru-cache (swap! client-lru-cache cache/hit cache-key)]
     (if-let [existing-client (cache/lookup lru-cache cache-key)]
       existing-client
       (let [new-client (really-make-client msp-id name priv-key cert opts)]
         (swap! client-lru-cache cache/miss cache-key new-client)
         new-client))))
+
+(defn get-or-make-channel [client channel-id]
+  (or (client/get-channel client channel-id) (client/new-channel client channel-id)))
+
+#_
+(defn add-orderer
+  ([client channel-id orderer-opts-map]
+   ))
+
+;;;
+;;; Peers
+;;;     Endorser
+;;;     Commiter
+;;;     (Submitter)

 ;;;;;;;;;;; Ex


Check loaded namespaces before searching filesystem

--- src/clojurescript/core.cljs
+++ src/clojurescript/core.cljs
@@ -118,7 +118,8 @@
 (defn load?
   [name macros]
   (let [do-not-load (or (@loaded name)
-                      (skip-load? name macros))]
+                      (skip-load? name macros)
+                      (js/goog.getObjectByName (str name)))]
     (swap! loaded conj name)
     (not do-not-load)))


Extended make-context-from-matrix

Extended make-context-from-matrix

to allow arbitray objects and attributes (not only numbers).

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/fca/contexts.clj
+++ src/conexp/fca/contexts.clj
@@ -157,16 +157,6 @@
 (defmethod make-context-nc :default [obj att inz]
   (illegal-argument "The arguments " obj ", " att " and " inz " are not valid for a Context."))

-(defn make-context-from-matrix
-  "Given two numbers m, n and a sequence of 0s and 1s of length m*n
-  returns a context represented by the corresponding boolean
-  matrix. Thereby m is the number of objects and n is the number of
-  attributes of the resulting context."
-  [m n bits]
-  (assert (= (* m n) (count bits)))
-  (make-context (range m) (range n) (fn [i j]
-                                      (not (zero? (nth bits (+ (* n i) j)))))))
-
 ;;; Common Operations in Contexts

 (defn context-size
@@ -193,6 +183,23 @@
   (let [atts (map old-to-new (attributes ctx))
 	inz (set-of [g (old-to-new m)] [[g m] (incidence ctx)])]
     (make-context-nc (objects ctx) atts inz)))
+
+(defn make-context-from-matrix
+  "Given objects G and attribute M and an incidence matrix contstructs
+  the corresponding context. G and M may also be numbers where they
+  represent (range G) and (range M) respectively."
+  [G M bits]
+  (let [G (if (number? G) (range G) G),
+        M (if (number? M) (range M) M),
+        m (count G),
+        n (count M)]
+    (assert (= (* m n) (count bits)))
+    (make-context G M
+                  (set-of [a b] [i (range (count G)),
+                                 j (range (count M)),
+                                 :when (= 1 (nth bits (+ (* n i) j)))
+                                 :let [a (nth G i),
+                                       b (nth M j)]]))))

 (defn object-derivation
   "Computes set of attributes common to all objects in context."


Added some functions for bonds

Added some functions for bonds

namely bond?, smallest-bond and all-bonds. smallest-bond's
implementation is as naïve as it can be...

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/fca/contexts.clj
+++ src/conexp/fca/contexts.clj
@@ -22,6 +22,11 @@
     (generic-equals [this other] Context [objects attributes incidence]))
   (hashCode [this]
     (hash-combine-hash Context objects attributes incidence)))
+
+(defn context?
+  "Returns true iff thing is a context."
+  [thing]
+  (instance? Context thing))

 (defmulti objects
   "Returns the objects of a formal context.."
@@ -582,7 +587,7 @@
 				     (I_2 [g_2,m_2]))])]
     (make-context-nc new-objs new-atts new-inz)))

-;;;
+;;; Subcontexts

 (defn subcontext?
   "Tests whether ctx-1 is a subcontext ctx-2 or not."
@@ -643,6 +648,50 @@
   [(intersection (first concept) (objects subcontext)),
    (intersection (second concept) (attributes subcontext))])

+;;; Bonds
+
+(defn smallest-bond
+  "Returns the smallest bond between ctx-1 and ctx-2 that has the
+  elements of rel as crosses."
+  [ctx-1 ctx-2 rel]
+  (loop [ctx-rel (make-context-nc (objects ctx-1) (attributes ctx-2) rel)]
+    (let [next-rel (union (set-of [g m] [m (attributes ctx-2),
+                                         g (attribute-derivation
+                                            ctx-1
+                                            (object-derivation
+                                             ctx-1
+                                             (attribute-derivation
+                                              ctx-rel
+                                              #{m})))])
+                          (set-of [g m] [g (objects ctx-1),
+                                         m (object-derivation
+                                            ctx-2
+                                            (attribute-derivation
+                                             ctx-2
+                                             (object-derivation
+                                              ctx-rel
+                                              #{g})))]))]
+      (if (= next-rel (incidence ctx-rel))
+        ctx-rel
+        (recur (make-context-nc (objects ctx-1) (attributes ctx-2) next-rel))))))
+
+(defn bond?
+  "Checks whether context ctx is a context between ctx-1 and ctx-2."
+  [ctx-1 ctx-2 ctx]
+  (and (context? ctx)
+       (context? ctx-1)
+       (context? ctx-2)
+       (= (objects ctx-1) (objects ctx))
+       (= (attributes ctx-2) (attributes ctx))
+       (= (incidence ctx) (incidence (smallest-bond ctx-1 ctx-2 (incidence ctx))))))
+
+(defn all-bonds
+  "Returns all bonds between ctx-1 and ctx-2."
+  [ctx-1 ctx-2]
+  (map #(make-context (objects ctx-1) (attributes ctx-2) %)
+       (all-closed-sets (cross-product (objects ctx-1) (attributes ctx-2))
+                        #(incidence (smallest-bond ctx-1 ctx-2 %)))))
+
 ;;;

 nil


Add support for key/value assignment in tables

--- src/luaclj/core.clj
+++ src/luaclj/core.clj
@@ -147,10 +147,11 @@
   )

 (defn var-fn [& args]
+  (println "var-fn args:" args)
   (cond (or (contains? (set args) "[")
             (contains? (set args) "."))
     ; Table access
-    (get (first args) (nth args 2))
+    `(assoc ~(first args) ~(nth args 2))
     :else
     (first args)))

@@ -212,14 +213,23 @@
     ))
 (defn stat-fn [& args]
   (println "stat-fn:" args)
-  (let [r (cond (= (safe-some-> args first) "local")
+  (let [var-set-fn (fn [local? name value]
+                     (let [set-stmt (if (= (safe-some-> name first) 'clojure.core/assoc)
+                                      `(set! ~(second name)
+                                             ~(apply list (conj (vec name) value)))
+                                      `(set! ~name ~value))
+                           set-stmt (if local?
+                                      (conj set-stmt :local)
+                                      set-stmt)]
+                       set-stmt))
+        r (cond (= (safe-some-> args first) "local")
               (apply concat (apply
-                (partial map #(list :local 'set! %1 %2))
+                (partial map (partial var-set-fn true))
                 (map next (leave :even (next args)))))
               (= (safe-some-> args first first)
                  :varlist)
               `(do ~@(apply
-                (partial map #(list 'set! %1 %2))
+                (partial map (partial var-set-fn false))
                 (map next (leave :even args))))
               (= "while" (first args))
               (get-while-statement args)
@@ -316,7 +326,7 @@

 (comment

-(pprint (lua-parser (slurp "resources/test/basic.lua")))
+(pprint (lua-parser (slurp "resources/test/for.lua")))

 (eval (insta/transform transform-map (lua-parser (slurp "resources/test/for.lua"))))
   (try (pprint (insta/transform transform-map (lua-parser (slurp "resources/test/for.lua"))))


Change cd icon

Change cd icon

--- frontend/components/language_landing.cljs
+++ frontend/components/language_landing.cljs
@@ -60,7 +60,7 @@
                          :icon (utils/cdn-path "/img/outer/languages/file-icon.svg")}
                         {:feature "CircleCI makes setting up Continuous Delivery for your Python application simple and easy. We offer first-class support for deployment to platforms like with Heroku, Elastic Beanstalk, and Google App Engine as well as using tools like Fabric, Ansible, Salt, and others."
                          :title "Easy Continuous Delivery"
-                         :icon (utils/cdn-path "/img/outer/languages/book-icon.svg")}]
+                         :icon (utils/cdn-path "/img/outer/languages/cycle.svg")}]
              :docs-link "/docs/language-python"
              :testimonials [{:text "The speed is really impressive, the rspec suite alone takes 6 minutes to run on my Macbook Air, but only 2 minutes on Circle."
                              :img (utils/cdn-path "/img/outer/languages/olivier.jpg")


Simplify grid call arguments.

Simplify grid call arguments.

--- frontend/uxbox/ui/workspace/workarea.cljs
+++ frontend/uxbox/ui/workspace/workarea.cljs
@@ -55,14 +55,14 @@
 (def ^:static grid-color "#cccccc")

 (defn grid-render
-  [own enabled? width height start-width start-height zoom]
+  [own enabled? zoom]
   (letfn [(vertical-line [position value padding]
             (let [ticks-mod (/ 100 zoom)
                   step-size (/ 10 zoom)]
               (if (< (mod value ticks-mod) step-size)
                 (html [:line {:key position
                               :y1 padding
-                              :y2 width
+                              :y2 wb/viewport-width
                               :x1 position
                               :x2 position
                               :stroke grid-color
@@ -70,7 +70,7 @@
                               :opacity 0.75}])
                 (html [:line {:key position
                               :y1 padding
-                              :y2 width
+                              :y2 wb/viewport-width
                               :x1 position
                               :x2 position
                               :stroke grid-color
@@ -84,7 +84,7 @@
                               :y1 position
                               :y2 position
                               :x1 padding
-                              :x2 height
+                              :x2 wb/viewport-height
                               :stroke grid-color
                               :stroke-width (/ 0.5 zoom)
                               :opacity 0.75}])
@@ -92,29 +92,30 @@
                               :y1 position
                               :y2 position
                               :x1 padding
-                              :x2 height
+                              :x2 wb/viewport-height
                               :stroke grid-color
                               :stroke-width (/ 0.5 zoom)
                               :opacity 0.25}]))))]
     (let [padding (* 20 zoom)
           ticks-mod (/ 100 zoom)
           step-size (/ 10 zoom)
-          vertical-ticks (range (- padding start-height)
-                                (- height start-height padding) step-size)
-          horizontal-ticks (range (- padding start-width)
-                                  (- width start-width padding) step-size)]
+          vertical-ticks (range (- padding wb/document-start-y)
+                                (- wb/viewport-height wb/document-start-y padding)
+                                step-size)
+          horizontal-ticks (range (- padding wb/document-start-x)
+                                  (- wb/viewport-width wb/document-start-x padding)
+                                  step-size)]
       (html
        [:g.grid
         {:style {:display (if enabled? "block" "none")}}
         (for [tick vertical-ticks]
-          (let [position (+ tick start-width)
+          (let [position (+ tick wb/document-start-x)
                 line (vertical-line position tick padding)]
             (rum/with-key line (str "tick-" tick))))
         (for [tick horizontal-ticks]
-          (let [position (+ tick start-height)
+          (let [position (+ tick wb/document-start-y)
                 line (horizontal-line position tick padding)]
             (rum/with-key line (str "tick-" tick))))]))))
-

 (def grid
   (util/component
@@ -198,19 +199,7 @@
       [:g.zoom
        {:transform (str "scale(" zoom ", " zoom ")")}
        (canvas)
-       #_(canvas conn
-                 page
-                 shapes
-                 {:viewport-height wb/viewport-height
-                  :viewport-width wb/viewport-width
-                  :document-start-x wb/document-start-x
-                  :document-start-y wb/document-start-y})
-       (grid (:grid-enabled workspace false)
-             wb/viewport-width
-             wb/viewport-height
-             wb/document-start-x
-             wb/document-start-y
-             zoom)]])))
+       (grid (:grid-enabled workspace false) zoom)]])))

 (def viewport
   (util/component


Add Clojure static tools

Add Clojure static tools

--- ssclj/jar/project.clj
+++ ssclj/jar/project.clj
@@ -40,7 +40,9 @@
   :plugins [[lein-expectations                              "0.0.7"]
             [lein-autoexpect                                "1.4.2"]
             [lein-environ                                   "1.0.0"]
-            [com.jakemccrary/lein-test-refresh              "0.5.5"]]
+            [com.jakemccrary/lein-test-refresh              "0.5.5"]
+            [jonase/eastwood                                "0.2.1"]
+            [lein-cloverage                                 "1.0.3"]]

   :profiles {
     :provided
@@ -68,4 +70,4 @@
                         [expectations/expectations "2.0.9"]]}})

-  +


Drop field 278 from export to ABACUS

Drop field 278 from export to ABACUS

Fixes #58

--- src/mdr2/abacus.clj
+++ src/mdr2/abacus.clj
@@ -187,7 +187,6 @@
         (create-row 281 multimedia_type)
         (create-row 256 (and produced_date
                              (format date-format produced_date))) ; Date of production end
-        (create-row 278 (format date-format date)) ; Date of production start
         (create-row 4 (prod/dam-number production))] ; for legacy purposes
        (remove nil?) ; remove empty rows
        wrap-rows ; wrap the payload


Big is more authentic.

Big is more authentic.

--- src/african_polyphony_and_polyrhythm/talk.clj
+++ src/african_polyphony_and_polyrhythm/talk.clj
@@ -88,15 +88,15 @@
     (comp (split 3/2 1/4) (split 9/4 5/4))
     (comp (split 14/4 1/4) (split 3/2 1/4) (split 9/4 5/4))))

-(defn up [notes]
+(defn big [notes]
   (->> notes
        (map (partial where :pitch #(+ % 5)))))

 (def balendoro
   (->> [tete ta ha tulule bongo
-        (up tete) (up ta) (up ha) (up tulule) (up bongo)
-        (up (up tete)) (up (up ta)) (up (up ha)) (up (up tulule)) (up (up bongo))
-        (up (up (up tete))) (up (up (up ta))) (up (up (up ha)))]
+        (big tete) (big ta) (big ha) (big tulule) (big bongo)
+        (big (big tete)) (big (big ta)) (big (big ha)) (big (big tulule)) (big (big bongo))
+        (big (big (big tete))) (big (big (big ta))) (big (big (big ha)))]
        (map rand-variations)
        (reduce with)))