Refactor internal api

Refactor internal api

--- src/etaoin/api.clj
+++ src/etaoin/api.clj
@@ -72,7 +72,7 @@
 ;; api
 ;;

-(defmacro with-resp
+(defn execute
   "Executes an HTTP request to a driver's server. Performs the body
   within result data bound to the `result` clause.

@@ -99,17 +99,12 @@
   Example:

   (def driver (firefox))
-  (with-resp driver :get
-    [:session (:session @driver) :element :active]
-    nil resp
-    (print resp))
-"
-  [driver method path data result & body]
-  `(let [~result (client/call ~driver
-                              ~method
-                              ~path
-                              ~data)]
-     ~@body))
+  (println (execute {:driver driver
+                     :method :get
+                     :path [:session (:session @driver) :element :active])))
+  "
+  [{:keys [driver method path data result]}]
+  (client/call driver method path data))

 ;;
 ;; session and status
@@ -119,10 +114,9 @@
   "Returns the current Webdriver status info. The content depends on
   specific driver."
   [driver]
-  (with-resp driver :get
-    [:status]
-    nil resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:status]})))

 (defn create-session
   "Initiates a new session for a driver. Opens a browser window as a
@@ -130,20 +124,18 @@
   session. Some drivers may work with only one active session. Returns
   a long string identifier."
   [driver & [capabilities]]
-  (with-resp driver
-    :post
-    [:session]
-    {:desiredCapabilities (or capabilities {})}
-    result
-    (or (:sessionId result)             ;; default
-        (:sessionId (:value result))))) ;; firefox
+  (let [result (execute {:driver driver
+                         :method :post
+                         :path [:session]
+                         :data {:desiredCapabilities (or capabilities {})}})]
+    (or (:sessionId result)               ;; default
+        (:sessionId (:value result)))))   ;; firefox

 (defn delete-session [driver]
   "Deletes a session. Closes a browser window."
-  (with-resp driver
-    :delete
-    [:session (:session @driver)]
-    nil _))
+  (execute {:driver driver
+            :method :delete
+            :path [:session (:session @driver)]}))

 ;;
 ;; active element
@@ -156,18 +148,19 @@

 (defmethod get-active-element* :firefox
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :element :active]
-    nil resp
-    (-> resp :value first second)))
+  (-> (execute {:driver driver
+                :method :get
+                :path [:session (:session @driver) :element :active]})
+      :value first second))

 (defmethods get-active-element*
   [:chrome :phantom :safari]
   [driver]
-  (with-resp driver :post
-    [:session (:session @driver) :element :active]
-    nil resp
-    (-> resp :value :ELEMENT)))
+  (-> (execute {:driver driver
+                :method :post
+                :path [:session (:session @driver) :element :active]})
+      :value
+      :ELEMENT))

 ;;
 ;; windows
@@ -180,19 +173,15 @@

 (defmethod get-window-handle :default
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :window_handle]
-    nil
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :window_handle]})))

 (defmethod get-window-handle :firefox
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :window]
-    nil
-    resp
-    (-> resp :value)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :window]})))

 (defmulti get-window-handles
   "Returns a vector of all window handlers."
@@ -201,37 +190,29 @@

 (defmethod get-window-handles :firefox
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :window :handles]
-    nil resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :window :handles]})))

 (defmethods get-window-handles
   [:chrome :phantom]
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :window_handles]
-    nil resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :window_handles]})))

 (defmulti switch-window
   "Switches a browser to another window."
   {:arglists '([driver handle])}
   dispatch-driver)

-(defmethod switch-window
-  :default
+(defmethods switch-window
+  [:default :chrome]
   [driver handle]
-  (with-resp driver :post
-    [:session (:session @driver) :window]
-    {:handle handle} _))
-
-(defmethod switch-window
-  :chrome
-  [driver handle]
-  (with-resp driver :post
-    [:session (:session @driver) :window]
-    {:name handle} _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :window]
+            :data {:handle handle}}))

 (defmulti close-window
   "Closes the current browser window."
@@ -239,9 +220,9 @@

 (defmethod close-window :default
   [driver]
-  (with-resp driver :delete
-    [:session (:session @driver) :window]
-    nil _))
+  (execute {:driver driver
+            :method :delete
+            :path [:session (:session @driver) :window]}))

 (defmulti maximize
   "Makes the browser window as wide as your screen allows."
@@ -250,17 +231,17 @@

 (defmethod maximize :firefox
   [driver]
-  (with-resp driver :post
-    [:session (:session @driver) :window :maximize]
-    nil _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :window :maximize]}))

 (defmethods maximize
   [:chrome :safari]
   [driver]
   (let [h (get-window-handle driver)]
-    (with-resp driver :post
-      [:session (:session @driver) :window h :maximize]
-      nil _)))
+    (execute {:driver driver
+              :method :post
+              :path [:session (:session @driver) :window h :maximize]})))

 (defmulti get-window-size
   "Returns a window size a map with `:width` and `:height` keys."
@@ -269,20 +250,19 @@

 (defmethod get-window-size :firefox
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :window :size]
-    nil
-    resp
-    (-> resp (select-keys [:width :height]))))
+  (-> (execute {:driver driver
+                :method :get
+                :path [:session (:session @driver) :window :size]})
+      (select-keys [:width :height])))

 (defmethod get-window-size :default
   [driver]
   (let [h (get-window-handle driver)]
-    (with-resp driver :get
-      [:session (:session @driver) :window h :size]
-      nil
-      resp
-      (-> resp :value (select-keys [:width :height])))))
+    (-> (execute {:driver driver
+                  :method :get
+                  :path [:session (:session @driver) :window h :size]})
+        :value
+        (select-keys [:width :height]))))

 (defmulti get-window-position
   "Returns a window position relative to your screen as a map with
@@ -292,35 +272,36 @@

 (defmethod get-window-position :firefox
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :window :position]
-    nil
-    resp
-    (-> resp (select-keys [:x :y]))))
+  (-> (execute {:driver driver
+                :method :get
+                :path [:session (:session @driver) :window :position]})
+      (select-keys [:x :y])))

 (defmethod get-window-position :default
   [driver]
   (let [h (get-window-handle driver)]
-    (with-resp driver :get
-      [:session (:session @driver) :window h :position]
-      nil
-      resp
-      (-> resp :value (select-keys [:x :y])))))
+    (-> (execute {:driver driver
+                  :method :get
+                  :path [:session (:session @driver) :window h :position]})
+        :value
+        (select-keys [:x :y]))))

 (defmulti ^:private set-window-size* dispatch-driver)

 (defmethod set-window-size* :firefox
   [driver width height]
-  (with-resp driver :post
-    [:session (:session @driver) :window :size]
-    {:width width :height height} _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :window :size]
+            :data {:width width :height height}}))

 (defmethod set-window-size* :default
   [driver width height]
   (let [h (get-window-handle driver)]
-    (with-resp driver :post
-      [:session (:session @driver) :window h :size]
-      {:width width :height height} _)))
+    (execute {:driver driver
+              :method :post
+              :path [:session (:session @driver) :window h :size]
+              :data {:width width :height height}})))

 (defn set-window-size
   "Sets new size for a window. Absolute precision is not guaranteed."
@@ -333,16 +314,19 @@

 (defmethod set-window-position* :firefox
   ([driver x y]
-   (with-resp driver :post
-     [:session (:session @driver) :window :position]
-     {:x x :y y} _)))
+   (execute {:driver driver
+             :method :post
+             :path [:session (:session @driver) :window :position]
+             :data {:x x :y y}})))

 (defmethod set-window-position* :default
   ([driver x y]
    (let [h (get-window-handle driver)]
-     (with-resp driver :post
-       [:session (:session @driver) :window h :position]
-       {:x x :y y} _))))
+     (execute {:driver driver
+               :method :post
+               :path [:session (:session @driver) :window h :position]
+               :data {:x x :y y}
+               }))))

 (defn set-window-position
   "Sets new position for a window. Absolute precision is not
@@ -363,34 +347,35 @@

   (def ff (firefox))
   (go ff \"http://google.com\")
-"
+  "
   [driver url]
-  (with-resp driver :post
-    [:session (:session @driver) :url]
-    {:url url} _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :url]
+            :data {:url url}}))

 (defn back
   "Move backwards in a browser's history."
   [driver]
-  (with-resp driver :post
-    [:session (:session @driver) :back]
-    nil _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :back]}))

 (defn refresh
   "Reloads the current window."
   [driver]
-  (with-resp driver :post
-    [:session (:session @driver) :refresh]
-    nil _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :refresh]}))

 (def reload refresh) ;; just an alias

 (defn forward
   "Move forwards in a browser's history."
   [driver]
-  (with-resp driver :post
-    [:session (:session @driver) :forward]
-    nil _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :forward]}))

 ;;
 ;; URL and title
@@ -399,18 +384,16 @@
 (defn get-url
   "Returns the current URL string."
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :url]
-    nil resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :url]})))

 (defn get-title
   "Returns the current window's title."
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :title]
-    nil resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :title]})))

 ;;
 ;; Finding element(s)
@@ -420,57 +403,64 @@

 (defmethod find-element* :firefox
   [driver locator term]
-  (with-resp driver :post
-    [:session (:session @driver) :element]
-    {:using locator :value term}
-    resp
-    (-> resp :value first second)))
+  (-> (execute {:driver driver
+                :method :post
+                :path [:session (:session @driver) :element]
+                :data {:using locator :value term}})
+      :value
+      first
+      second))

 (defmethod find-element* :default
   [driver locator term]
-  (with-resp driver :post
-    [:session (:session @driver) :element]
-    {:using locator :value term}
-    resp
-    (-> resp :value :ELEMENT)))
+  (-> (execute {:driver driver
+                :method :post
+                :path [:session (:session @driver) :element]
+                :data {:using locator :value term}})
+      :value :ELEMENT))

 (defmulti find-elements* dispatch-driver)

 (defmethod find-elements* :default
   [driver locator term]
-  (with-resp driver :post
-    [:session (:session @driver) :elements]
-    {:using locator :value term}
-    resp
-    (->> resp :value (mapv (comp second first)))))
+  (->> (execute {:driver driver
+                 :method :post
+                 :path [:session (:session @driver) :elements]
+                 :data {:using locator :value term}})
+       :value
+       (mapv (comp second first))))

 (defmulti find-element-from* dispatch-driver)

 (defmethod find-element-from* :firefox
   [driver el locator term]
-  (with-resp driver :post
-    [:session (:session @driver) :element el :element]
-    {:using locator :value term}
-    resp
-    (-> resp :value first second)))
+  (-> (execute {:driver driver
+                :method :post
+                :path [:session (:session @driver) :element el :element]
+                :data {:using locator :value term}})
+      :value
+      first
+      second))

 (defmethod find-element-from* :default
   [driver el locator term]
-  (with-resp driver :post
-    [:session (:session @driver) :element el :element]
-    {:using locator :value term}
-    resp
-    (-> resp :value :ELEMENT)))
+  (-> (execute {:driver driver
+                :method :post
+                :path [:session (:session @driver) :element el :element]
+                :data {:using locator :value term}})
+      :value
+      :ELEMENT))

 (defmulti find-elements-from* dispatch-driver)

 (defmethod find-elements-from* :default
   [driver el locator term]
-  (with-resp driver :post
-    [:session (:session @driver) :element el :elements]
-    {:using locator :value term}
-    resp
-    (->> resp :value (mapv (comp second first)))))
+  (->> (execute {:driver driver
+                 :method :post
+                 :path [:session (:session @driver) :element el :elements]
+                 :data {:using locator :value term}})
+       :value
+       (mapv (comp second first))))

 ;;
 ;; Querying elements (high-level API)
@@ -543,9 +533,9 @@
 (defmethods mouse-btn-down
   [:chrome :phantom :safari]
   [driver]
-  (with-resp driver :post
-    [:session (:session @driver) :buttondown]
-    nil _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :buttondown]}))

 (defmulti mouse-btn-up
   "Puts up a button of a virtual mouse."
@@ -555,9 +545,9 @@
 (defmethods mouse-btn-up
   [:chrome :phantom :safari]
   [driver]
-  (with-resp driver :post
-    [:session (:session @driver) :buttonup]
-    nil _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :buttonup]}))

 (defmulti mouse-move-to
   "Moves a virtual mouse pointer either to an element
@@ -568,13 +558,15 @@
 (defmethods mouse-move-to
   [:chrome :phantom :safari]
   ([driver q]
-   (with-resp driver :post
-     [:session (:session @driver) :moveto]
-     {:element (query driver q)} _))
+   (execute {:driver driver
+             :method :post
+             :path [:session (:session @driver) :moveto]
+             :data {:element (query driver q)}}))
   ([driver x y]
-   (with-resp driver :post
-     [:session (:session @driver) :moveto]
-     {:xoffset x :yoffset y} _)))
+   (execute {:driver driver
+             :method :post
+             :path [:session (:session @driver) :moveto]
+             :data {:xoffset x :yoffset y}})))

 (defmacro with-mouse-btn
   "Performs the body keeping mouse botton pressed."
@@ -619,9 +611,9 @@
 ;;

 (defn click-el [driver el]
-  (with-resp driver :post
-    [:session (:session @driver) :element el :click]
-    nil _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :element el :click]}))

 (defn click
   "Clicks on an element (a link, a button, etc)."
@@ -633,9 +625,9 @@
 (defmethods double-click-el
   [:chrome :phantom]
   [driver el]
-  (with-resp driver :post
-    [:session (:session @driver) :element el :doubleclick]
-    nil _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :element el :doubleclick]}))

 (defn double-click
   "Performs double click on an element.
@@ -657,19 +649,18 @@
 (defmethods get-element-size-el
   [:chrome :phantom :safari]
   [driver el]
-  (with-resp driver :get
-    [:session (:session @driver) :element el :size]
-    nil
-    resp
-    (-> resp :value (select-keys [:width :height]))))
+  (-> (execute {:driver driver
+                :method :get
+                :path [:session (:session @driver) :element el :size]})
+      :value
+      (select-keys [:width :height])))

 (defmethod get-element-size-el :firefox
   [driver el]
-  (with-resp driver :get
-    [:session (:session @driver) :element el :rect]
-    nil
-    resp
-    (-> resp (select-keys [:width :height]))))
+  (-> (execute {:driver driver
+                :method :get
+                :path [:session (:session @driver) :element el :rect]})
+      (select-keys [:width :height])))

 (defn get-element-size
   "Returns an element size as a map with :width and :height keys."
@@ -685,19 +676,18 @@
 (defmethods get-element-location-el
   [:chrome :phantom :safari]
   [driver el]
-  (with-resp driver :get
-    [:session (:session @driver) :element el :location]
-    nil
-    resp
-    (-> resp :value (select-keys [:x :y]))))
+  (-> (execute {:driver driver
+                :method :get
+                :path [:session (:session @driver) :element el :location]})
+      :value
+      (select-keys [:x :y])))

 (defmethod get-element-location-el :firefox
   [driver el]
-  (with-resp driver :get
-    [:session (:session @driver) :element el :rect]
-    nil
-    resp
-    (-> resp (select-keys [:x :y]))))
+  (-> (execute {:driver driver
+                :method :get
+                :path [:session (:session @driver) :element el :rect]})
+      (select-keys [:x :y])))

 (defn get-element-location [driver q]
   "Returns an element location on a page as a map with :x and :x keys."
@@ -757,11 +747,9 @@

 (defn- get-element-property-el
   [driver el property]
-  (with-resp driver :get
-    [:session (:session @driver) :element el :property (name property)]
-    nil
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :element el :property (name property)]})))

 (defn get-element-property
   "Returns a property of an element (value, etc).
@@ -794,11 +782,9 @@

 (defn get-element-attr-el
   [driver el attr]
-  (with-resp driver :get
-    [:session (:session @driver) :element el :attribute (name attr)]
-    nil
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :element el :attribute (name attr)]})))

 (defn get-element-attr
   "Returns an HTTP attribute of an element (class, id, href, etc).
@@ -841,11 +827,11 @@

 (defn- get-element-css-el
   [driver el name*]
-  (with-resp driver :get
-    [:session (:session @driver) :element el :css (name name*)]
-    nil
-    resp
-    (-> resp :value not-empty)))
+  (-> (execute {:driver driver
+                :method :get
+                :path [:session (:session @driver) :element el :css (name name*)]})
+      :value
+      not-empty))

 (defn get-element-css
   "Returns a CSS property of an element. The property might be both
@@ -890,11 +876,9 @@
 (defn get-element-tag-el
   "Returns element's tag name by its identifier."
   [driver el]
-  (with-resp driver :get
-    [:session (:session @driver) :element el :name]
-    nil
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :element el :name]})))

 (defn get-element-tag
   "Returns element's tag name (\"div\", \"input\", etc)."
@@ -904,11 +888,9 @@
 (defn get-element-text-el
   "Returns element's inner text by its identifier."
   [driver el]
-  (with-resp driver :get
-    [:session (:session @driver) :element el :text]
-    nil
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :element el :text]})))

 (defn get-element-text
   "Returns inner element's text.
@@ -925,11 +907,9 @@
 (defn- get-element-value-el
   "Low level: returns element's value by its identifier."
   [driver el]
-  (with-resp driver :get
-    [:session (:session @driver) :element el :value]
-    nil
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :element el :value]})))

 (defmulti get-element-value
   "Returns the current element's value (input text)."
@@ -961,19 +941,17 @@
   Each cookie is a map with structure:

   {:name \"cookie1\",
-   :value \"test1\",
-   :path \"/\",
-   :domain \"\",
-   :expiry nil,
-   :secure false,
-   :httpOnly false}
-"
-  [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :cookie]
-    nil
-    resp
-    (:value resp)))
+  :value \"test1\",
+  :path \"/\",
+  :domain \"\",
+  :expiry nil,
+  :secure false,
+  :httpOnly false}
+  "
+  [driver]
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :cookie]})))

 (defn get-cookie
   "Returns the first cookie with such name.
@@ -999,19 +977,19 @@

   - `cookie`: a map with structure described in `get-cookies`. At
   least `:name` and `:value` fields should be populated.
-"
+  "
   [driver cookie]
-  (with-resp driver :post
-    [:session (:session @driver) :cookie]
-    {:cookie cookie}
-    _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :cookie]
+            :data {:cookie cookie}}))

 (defn delete-cookie
   "Deletes a cookie by its name."
   [driver cookie-name]
-  (with-resp driver :delete
-    [:session (:session @driver) :cookie (name cookie-name)]
-    nil _))
+  (execute {:driver driver
+            :method :delete
+            :path [:session (:session @driver) :cookie (name cookie-name)]}))

 (defmulti delete-cookies
   "Deletes all the cookies for all domains."
@@ -1020,9 +998,9 @@

 (defmethod delete-cookies :default
   [driver]
-  (with-resp driver :delete
-    [:session (:session @driver) :cookie]
-    nil _))
+  (execute {:driver driver
+            :method :delete
+            :path [:session (:session @driver) :cookie]}))

 (defmethod delete-cookies :safari
   ;; For some reason, Safari hangs forever when trying to delete
@@ -1038,11 +1016,9 @@
 (defn get-source
   "Returns browser's current HTML markup as a string."
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :source]
-    nil
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :source]})))

 ;;
 ;; Javascript
@@ -1106,19 +1082,17 @@

 (defmethod js-execute :default
   [driver script & args]
-  (with-resp driver :post
-    [:session (:session @driver) :execute]
-    {:script script :args (vec args)}
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :post
+                    :path [:session (:session @driver) :execute]
+                    :data {:script script :args (vec args)}})))

 (defmethod js-execute :firefox
   [driver script & args]
-  (with-resp driver :post
-    [:session (:session @driver) :execute :sync]
-    {:script script :args (vec args)}
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :post
+                    :path [:session (:session @driver) :execute :sync]
+                    :data {:script script :args (vec args)}})))

 (defmulti js-async
   "Executes an asynchronous script in the browser and returns the result.
@@ -1163,20 +1137,17 @@

 (defmethod js-async :default
   [driver script & args]
-  (with-resp driver :post
-    [:session (:session @driver) :execute_async]
-    {:script script :args (vec args)}
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :post
+                    :path [:session (:session @driver) :execute_async]
+                    :data {:script script :args (vec args)}})))

 (defmethod js-async :firefox
   [driver script & args]
-  (with-resp driver :post
-    [:session (:session @driver) :execute :async]
-    {:script script :args (vec args)}
-    resp
-    (:value resp)))
-
+  (:value (execute {:driver driver
+                    :method :post
+                    :path [:session (:session @driver) :execute :async]
+                    :data {:script script :args (vec args)}})))
 ;;
 ;; Javascript helpers
 ;;
@@ -1288,10 +1259,10 @@
 (defn switch-frame*
   "Switches to an (i)frame by its index or an element reference."
   [driver id]
-  (with-resp driver :post
-    [:session (:session @driver) :frame]
-    {:id id}
-    _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :frame]
+            :data {:id id}}))

 (defn switch-frame
   "Switches to an (i)frame quering the page for it."
@@ -1307,10 +1278,9 @@
 (defn switch-frame-parent
   "Switches to the parent of the current (i)frame."
   [driver]
-  (with-resp driver :post
-    [:session (:session @driver) :frame :parent]
-    nil
-    _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :frame :parent]}))

 (defn switch-frame-top
   "Switches to the most top of the page."
@@ -1339,11 +1309,9 @@
 (defmethods get-log-types
   [:chrome :phantom]
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :log :types]
-    nil
-    result
-    (:value result)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :log :types]})))

 (defn- process-log
   "Remaps some of the log's fields."
@@ -1384,11 +1352,12 @@
 (defmethods get-logs
   [:chrome :phantom]
   [driver]
-  (with-resp driver :post
-    [:session (:session @driver) :log]
-    {:type :browser}
-    result
-    (mapv process-log (:value result))))
+  (->> (execute {:driver driver
+                 :method :post
+                 :path [:session (:session @driver) :log]
+                 :data {:type :browser}})
+       :value
+       (mapv process-log)))

 (defn supports-logs?
   "Checks whether a driver supports getting console logs."
@@ -1478,20 +1447,16 @@

 (defmethod get-alert-text :firefox
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :alert :text]
-    nil
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :alert :text]})))

 (defmethods get-alert-text
   [:chrome :safari]
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :alert_text]
-    nil
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :alert_text]})))

 (defmulti dismiss-alert
   "Simulates cancelling an alert dialog (pressing cross button)."
@@ -1499,16 +1464,16 @@

 (defmethod dismiss-alert :firefox
   [driver]
-  (with-resp driver :post
-    [:session (:session @driver) :alert :dismiss]
-    nil _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :alert :dismiss]}))

 (defmethods dismiss-alert
   [:chrome :safari]
   [driver]
-  (with-resp driver :post
-    [:session (:session @driver) :dismiss_alert]
-    nil _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :dismiss_alert]}))

 (defmulti accept-alert
   "Simulates submitting an alert dialog (pressing OK button)."
@@ -1516,16 +1481,16 @@

 (defmethod accept-alert :firefox
   [driver]
-  (with-resp driver :post
-    [:session (:session @driver) :alert :accept]
-    nil _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :alert :accept]}))

 (defmethods accept-alert
   [:chrome :safari]
   [driver]
-  (with-resp driver :post
-    [:session (:session @driver) :accept_alert]
-    nil _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :accept_alert]}))

 ;;
 ;; network
@@ -1625,11 +1590,9 @@

 (defmethod displayed-el? :default
   [driver el]
-  (with-resp driver :get
-    [:session (:session @driver) :element el :displayed]
-    nil
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :element el :displayed]})))

 (defmethod displayed-el? :safari
   [driver el]
@@ -1657,11 +1620,9 @@
   invisible? (complement visible?))

 (defn enabled-el? [driver el]
-  (with-resp driver :get
-    [:session (:session @driver) :element el :enabled]
-    nil
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :element el :enabled]})))

 (defn enabled?
   "Checks whether an element is enabled."
@@ -1925,9 +1886,10 @@
 (defmethod touch-tap
   :chrome
   [driver q]
-  (with-resp driver :post
-    [:session (:session @driver) :touch :click]
-    {:element (query driver q)} _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :touch :click]
+            :data {:element (query driver q)}}))

 (defmulti touch-down dispatch-driver)

@@ -1938,9 +1900,10 @@
          (get-element-location driver q)]
      (touch-down driver x y)))
   ([driver x y]
-   (with-resp driver :post
-     [:session (:session @driver) :touch :down]
-     {:x (int x) :y (int y)} _)))
+   (execute {:driver driver
+             :method :post
+             :path [:session (:session @driver) :touch :down]
+             :data {:x (int x) :y (int y)}})))

 (defmulti touch-up dispatch-driver)

@@ -1951,9 +1914,10 @@
          (get-element-location driver q)]
      (touch-down driver x y)))
   ([driver x y]
-   (with-resp driver :post
-     [:session (:session @driver) :touch :up]
-     {:x (int x) :y (int y)} _)))
+   (execute {:driver driver
+             :method :post
+             :path [:session (:session @driver) :touch :up]
+             :data {:x (int x) :y (int y)}})))

 (defmulti touch-move dispatch-driver)

@@ -1964,9 +1928,10 @@
          (get-element-location driver q)]
      (touch-move driver x y)))
   ([driver x y]
-   (with-resp driver :post
-     [:session (:session @driver) :touch :move]
-     {:x (int x) :y (int y)} _)))
+   (execute {:driver driver
+             :method :post
+             :path [:session (:session @driver) :touch :move]
+             :data {:x (int x) :y (int y)}})))

 ;;
 ;; skip/when driver
@@ -2054,16 +2019,18 @@
 (defmethod fill-el
   :default
   [driver el text & more]
-  (with-resp driver :post
-    [:session (:session @driver) :element el :value]
-    {:value (apply make-input* text more)} _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :element el :value]
+            :data {:value (apply make-input* text more)}}))

 (defmethod fill-el
   :firefox ;; todo support the old version for :default
   [driver el text & more]
-  (with-resp driver :post
-    [:session (:session @driver) :element el :value]
-    {:text (str/join (apply make-input* text more))} _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :element el :value]
+            :data {:text (str/join (apply make-input* text more))}}))

 (defmulti fill-active*
   {:arglists '([driver text & more])}
@@ -2072,9 +2039,10 @@
 (defmethod fill-active*
   :chrome
   [driver text & more]
-  (with-resp driver :post
-    [:session (:session @driver) :keys]
-    {:value (apply make-input* text more)} _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :keys]
+            :data {:value (apply make-input* text more)}}))

 (defmethod fill-active*
   :firefox
@@ -2151,9 +2119,9 @@
 (defn clear-el
   "Clears an element by its identifier."
   [driver el]
-  (with-resp driver :post
-    [:session (:session @driver) :element el :clear]
-    nil _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :element el :clear]}))

 (defn clear
   "Clears an element (input, textarea) found with a query.
@@ -2217,16 +2185,18 @@
 (defmethod set-timeout*
   :default
   [driver type sec]
-  (with-resp driver :post
-    [:session (:session @driver) :timeouts]
-    {type (util/sec->ms sec)} _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :timeouts]
+            :data {type (util/sec->ms sec)}}))

 (defmethod set-timeout*
   :chrome
   [driver type sec]
-  (with-resp driver :post
-    [:session (:session @driver) :timeouts]
-    {:type type :ms (util/sec->ms sec)} _))
+  (execute {:driver driver
+            :method :post
+            :path [:session (:session @driver) :timeouts]
+            :data {:type type :ms (util/sec->ms sec)}}))

 (defmulti set-script-timeout
   "Sets timeout for executing JS sctipts."
@@ -2271,11 +2241,9 @@
 (defmethod get-timeout*
   :default
   [driver]
-  (with-resp driver :get
-    [:session (:session @driver) :timeouts]
-    nil
-    resp
-    (:value resp)))
+  (:value (execute {:driver driver
+                    :method :get
+                    :path [:session (:session @driver) :timeouts]})))

 (defn get-script-timeout
   "Returns the current script timeout in seconds."
@@ -2339,11 +2307,11 @@

 (defmethod screenshot :default
   [driver file]
-  (with-resp driver :get
-    [:session (:session @driver) :screenshot]
-    nil
-    resp
-    (if-let [b64str (-> resp :value not-empty)]
+  (let [resp (execute {:driver driver
+                       :method :get
+                       :path [:session (:session @driver) :screenshot]})
+        b64str (-> resp :value not-empty)]
+    (when b64str
       (b64-to-file b64str file)
       (util/error "Empty screenshot"))))

@@ -2360,14 +2328,14 @@
 (defmethod screenshot-element
   :firefox
   [driver q file]
-  (let [el (query driver q)]
-    (with-resp driver :get
-      [:session (:session @driver) :element el :screenshot]
-      nil
-      resp
-      (if-let [b64str (-> resp :value not-empty)]
-        (b64-to-file b64str file)
-        (util/error "Empty screenshot, query: %s" q)))))
+  (let [el (query driver q)
+        resp (execute {:driver driver
+                       :method :get
+                       :path [:session (:session @driver) :element el :screenshot]})
+        b64str (-> resp :value not-empty)]
+    (when b64str
+      (b64-to-file b64str file)
+      (util/error "Empty screenshot, query: %s" q))))

 ;;
 ;; postmortem


fixed multiline output

fixed multiline output

--- main/src/dda/pallet/dda_serverspec_crate/infra/fact/command.clj
+++ main/src/dda/pallet/dda_serverspec_crate/infra/fact/command.clj
@@ -38,23 +38,21 @@
   "creates a keyword from a bash command"
   [command :- s/Str] (keyword (string/replace command #"[:/;\\' ]" "-")))

-(defn parse-single-command-output
+(defn parse-command-output
   [command-output]
   (let [result-lines (filter #(not (string/blank? %))
                        (string/split-lines command-output))
         result-key (first result-lines)
-        result-out (second result-lines)
+        result-out (next (drop-last result-lines))
         code (int (read-string (last result-lines)))]
-      (logging/info "----------")
-      (logging/info result-key)
-      (logging/info (str command-output))
+      (logging/info (str "----------" "\n" result-key "\n" (string/join "\n" result-out) "\n" code "\n"))
       {(keyword result-key) {:exit-code code
                              :stout result-out}}))

 (s/defn parse-command-outputs :- CommandFactResult
   [script-result]
   (apply merge
-    (map parse-single-command-output
+    (map parse-command-output
          (filter #(not (string/blank? %))
            (string/split script-result (re-pattern output-separator))))))


CMR-4432 Fixed indentation.

CMR-4432 Fixed indentation.

--- collection-renderer-lib/test/cmr/collection_renderer/test/services/collection_renderer.clj
+++ collection-renderer-lib/test/cmr/collection_renderer/test/services/collection_renderer.clj
@@ -22,9 +22,9 @@

 (deftest render-default-collection
   (let [coll expected-conversion/example-collection-record
-          ^String html (cr/render-collection (renderer-context) coll)]
-      (is html "Expected some HTML to be returned")
-      (is (.contains html (:EntryTitle coll)))))
+        ^String html (cr/render-collection (renderer-context) coll)]
+    (is html "Expected some HTML to be returned")
+    (is (.contains html (:EntryTitle coll)))))

 ;; This checks that we can render any UMM collection without getting an exception.
 ;; A small number of tries is done to avoid making tests take a long time.
@@ -36,6 +36,6 @@
 ;; Verify that the title of the html is the entry title
 (deftest render-title-as-entry-title
   (let [coll expected-conversion/example-collection-record
-            ^String html (cr/render-collection (renderer-context) coll)]
-        (is html "Expected a title containing the entry title")
-        (is (.contains html (str "<title>" (:EntryTitle coll) "</title>")))))+         ^String html (cr/render-collection (renderer-context) coll)]
+    (is html "Expected a title containing the entry title")
+    (is (.contains html (str "<title>" (:EntryTitle coll) "</title>")))))


updated test case name

updated test case name

--- test/clinvar_submitter/core_test.clj
+++ test/clinvar_submitter/core_test.clj
@@ -18,7 +18,7 @@
     (is (= (map #(construct-variant t %) interps) (construct-variant-table interp-path context-path))
     (println "Expectedvalue" (map #(construct-variant t %) interps)))))

-(deftest test-variant-table
+(deftest test-construct-variant
   (testing "Testing correctness ovariant construction"
     (is (= expectedvalue (construct-variant t i))
     (println "Expectedvalue" expectedvalue))))


fix tests to match :owner bug fix

fix tests to match :owner bug fix

--- test/gh_waiting_room/github_test.clj
+++ test/gh_waiting_room/github_test.clj
@@ -4,7 +4,7 @@
             [gh-waiting-room.github :as github]
             [echo.test.mock :refer [expect has-args times once]]))

-(def valid-issue {:id "cldwalker/repo#10" :user "cldwalker" :name "repo" :type "issue" :position 10})
+(def valid-issue {:id "cldwalker/repo#10" :owner "cldwalker" :name "repo" :type "issue" :position 10})

 (defn create-comment
   [& {:keys [id issues body-expects]


incrementing clj version

incrementing clj version

--- clojure/project.clj
+++ clojure/project.clj
@@ -1,4 +1,4 @@
-(defproject limelight/limelight-clj "0.6.11"
+(defproject limelight/limelight-clj "0.6.12"
   :description "FIXME: write"
   :dependencies [[org.clojure/clojure "1.2.1"]]
   :dev-dependencies [[speclj "2.0.1"]


make scroll wheel on threads scroll window

--- src/chat/client/views/pages/inbox.cljs
+++ src/chat/client/views/pages/inbox.cljs
@@ -10,7 +10,15 @@
     (render [_]
       (dom/div #js {:className "page inbox"}
         (dom/div #js {:className "title"} "Inbox")
-        (apply dom/div #js {:className "threads"}
+        (apply dom/div #js {:className "threads"
+                            :ref "threads-div"
+                            :onWheel (fn [e]
+                                       (let [target-classes (.. e -target -classList)
+                                             this-elt (om/get-node owner "threads-div")]
+                                         ; TODO: check if threads-div needs to scroll?
+                                         (when (and (or (.contains target-classes "thread") (.contains target-classes "threads"))
+                                                 (= 0 (.-deltaX e) (.-deltaZ e)))
+                                           (set! (.-scrollLeft this-elt) (- (.-scrollLeft this-elt) (.-deltaY e))))))}
           (concat
             [(new-thread-view {})]
             (map (fn [t] (om/build thread-view t {:key :id}))


.parent is a function on jquery objects

.parent is a function on jquery objects

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -118,9 +118,9 @@

 (defn wishlist-delete-clicker []
   (delegate $content ".delete" :click
-    (fn []
+    (fn [e]
       (this-as me
-        (remove (.parent me))
+        (remove (.parent ($ me)))
         (update-wishlist-rem)))))


Using the smarter function

Using the smarter function

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -130,7 +130,7 @@
                 (remove parent)
                 (delete-wish-rem parent))
               (if (.hasClass parent "last")
-                (create-wish-last-rem parent)
+                (create-wish-rem parent)
                 (update-wish-rem parent)))))))))

 (defn wishlist-wish-url-changer []


WIP break down item results into chunks

WIP break down item results into chunks

--- src/cljs/clj_money/views/accounts.cljs
+++ src/cljs/clj_money/views/accounts.cljs
@@ -282,7 +282,6 @@
 (defn- show-account [id]
   (let [account (r/atom {})
         transaction-items (r/atom nil)]
-    (query-items)
     (accounts/get-one id
                       (fn [a]
                         (reset! account a)


CxMR-6024: fix and cleanup code to help improve new concept creation(Part1) (#818)

* CxMR-6024: fix and cleanup code to help improve new concept creation - part1

* CMR-6024: Addressed the PR comment

--- indexer-app/src/cmr/indexer/services/index_service.clj
+++ indexer-app/src/cmr/indexer/services/index_service.clj
@@ -288,8 +288,8 @@

 (defmethod get-elastic-version :service
   [context concept]
-  (let [service-associations (meta-db/get-associations-for-variable context concept)]
-    (get-elastic-version-with-associations context concept nil service-associations nil)))
+  (let [service-associations (meta-db/get-associations-for-service context concept)]
+    (get-elastic-version-with-associations context concept nil nil service-associations)))

 (defmulti get-tag-associations
   "Returns the tag associations of the concept"


fix non-deterministic test

fix non-deterministic test

--- test/strictly_specking/core_test.clj
+++ test/strictly_specking/core_test.clj
@@ -178,9 +178,9 @@
            '{:in-path (:source-paths), :error-focus :key, :missing-key true}))
     (is (= (::ss/missing-keys e)
            [:source-paths :compiler]))
-    (is (= (ss/keys-to-document e)
-           [:strictly-specking.test-schema/compiler
-            :strictly-specking.test-schema/source-paths]))
+    (is (= (sort (ss/keys-to-document e))
+           (sort [:strictly-specking.test-schema/compiler
+                  :strictly-specking.test-schema/source-paths])))
     (is (ep/error-message e))
     ;; there is no inline message
     ;; (is (ep/inline-message e))


fix an unrelated test

fix an unrelated test

incorrect regex in a test that only runs when you specify :all or
:integration while running tests

--- test/runbld/main_test.clj
+++ test/runbld/main_test.clj
@@ -417,7 +417,7 @@
                     (is (= "6.0" (git-branch repo)))
                     (is (= "6.0" (get-in res [:store-result :build-doc
                                               :build :branch])))
-                    (is (re-find #"foo 6.0" slack-msg)))))
+                    (is (re-find #"foo.6.0" slack-msg)))))
               (testing "wiping the workspace"
                 (wipe-workspace-orig opts)
                 ;; Should only have the top-level workspace dir left


Update alfa.clj

Update alfa.clj

--- practice/alfa.clj
+++ practice/alfa.clj
@@ -1,7 +1,7 @@
 (ns euler.practice.alfa)

 ;;take''
-(defn a-take [a b]
+(defn take'' [a b]
   (loop [la (dec a)
          lb '()]
     (if (= la -1)


Fixed docstring for find-maximal

Fixed docstring for find-maximal

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

--- src/conexp/contrib/factor_analysis.clj
+++ src/conexp/contrib/factor_analysis.clj
@@ -136,7 +136,7 @@
                              ((incidence context) [k l]))])))

 (defn- find-maximal
-  "Find the maximal [m v], where m is an attribute and v in (0,1],
+  "Find a pair [m v], where m is an attribute and v in (0,1],
   such that the cardinality of the set returned by fuzzy-oplus-a is
   maximal. Returns the pair [[m v], count], where count is the
   aforementioned cardinality."


fix merge conflict

fix merge conflict

--- frontend/core.cljs
+++ frontend/core.cljs
@@ -175,14 +175,11 @@
       (put! controls-ch [:container-selected (get-in @app-state [:current-build :current-container-id] 0)]))))

 (defn ^:export setup! []
-  (main app-state (sel1 :body))
-  (dispatch-to-current-location!)
-  (handle-browser-resize app-state)
-  (when-let [user (:current-user @app-state)]
-    (subscribe-to-user-channel user (get-in @app-state [:comms :ws])))
-  (when (env/development?)
-    (setup-browser-repl)))
-
-;; Wait for the page to finish loading before we kick off the setup
-;; process
-(set! (.-onload js/window) setup!)
+  (let [state (app-state)]
+    (main state (sel1 :body))
+    (dispatch-to-current-location!)
+    (handle-browser-resize state)
+    (when-let [user (:current-user @state)]
+      (subscribe-to-user-channel user (get-in @state [:comms :ws])))
+    (when (env/development?)
+      (setup-browser-repl))))


fix for implicit type parameters

fix for implicit type parameters

--- src/latte/core.clj
+++ src/latte/core.clj
@@ -149,7 +149,7 @@
                         (u/fetch-implicit-type-parameter-handler itypes def-env-var ctx-var param)]
                     [itypes' (if (nil? lt-clause)
                                lt-clauses
-                               (conj lt-clauses lt-clause))])) [implicit-types []] targs)]
+                               (conj lt-clauses (first lt-clause) (second lt-clause)))])) [implicit-types []] targs)]
     (when-not (empty? remaining-implicit-types)
       (throw (ex-info "Unsolved implicit type parameters" {:statement def-name
                                                            :implicit-type-params implicit-types
@@ -157,7 +157,7 @@
     `(defimplicit ~def-name
        ~ndoc
        [~def-env-var ~ctx-var ~@defparams]
-       (let ~@lt-clauses
+       (let [~@lt-clauses]
          (list (var ~explicit-def-name) ~@(concat implicit-types
                                                   (map first defparams)))))))


Ignore collectionFormat when parsing body. Fixes #61.

--- src/io/sarnowski/swagger1st/parser.clj
+++ src/io/sarnowski/swagger1st/parser.clj
@@ -204,7 +204,9 @@
   (let [items-definition (get definition "items")
         items-parser (create-value-parser items-definition path parser-options)]
     (fn [value]
-      (let [vals (if value (split-array definition value) [])
+      (let [vals (if (and value (not= "body" (first path)))
+                   (split-array definition value)
+                   [])
             err (partial throw-value-error value definition path)
             check-count (fn [value]
                           (if-let [max-items (get definition "maxItems")]


Fix a problem with the delete button

Fix a problem with the delete button

--- src/mdr2/views.clj
+++ src/mdr2/views.clj
@@ -51,8 +51,8 @@
               ;;                    (layout/menu-item "#" (state/to-str next)))
               ;;                  (layout/glyphicon "transfer"))
               (when (friend/authorized? #{:admin} identity)
-                (layout/button (layout/glyphicon "trash")
-                               (str "/production/" id "/delete")))]))]])]])))
+                (layout/button (str "/production/" id "/delete")
+                               (layout/glyphicon "trash")))]))]])]])))
 (defn production [request id]
   (let [p (prod/find id)
         user (friend/current-authentication request)]


fix gpg ownership through ssh

fix gpg ownership through ssh

--- main/src/dda/pallet/dda_user_crate/infra/gpg.clj
+++ main/src/dda/pallet/dda_user_crate/infra/gpg.clj
@@ -51,42 +51,38 @@
         {:keys [public-key public-key-id private-key passphrase]} trusted-key
         user-home (ssh-common/user-home-dir user-name)]
     (actions/remote-file
-      (str user-home "/pub.key")
-      :content public-key
-      :mode "600"
-      :owner user-name
-      :group user-name
-      :action :create)
+     (str user-home "/pub.key")
+     :content public-key
+     :mode "600"
+     :owner user-name
+     :group user-name
+     :action :create)
     (actions/remote-file
-      (str user-home "/priv.key")
-      :content private-key
-      :mode "600"
-      :owner user-name
-      :group user-name
-      :action :create)
+     (str user-home "/priv.key")
+     :content private-key
+     :mode "600"
+     :owner user-name
+     :group user-name
+     :action :create)
     (actions/directory
-      (str user-home "/.gnupg")
-      :mode "700"
-      :owner user-name
-      :group user-name
-      :action :create)
+     (str user-home "/.gnupg")
+     :mode "700"
+     :owner user-name
+     :group user-name
+     :action :create)
     (actions/remote-file
-      (str user-home "/.gnupg/gpg-agent.conf")
-      :mode "600"
-      :content (slurp (io/resource "gpg-agent.conf"))
-      :owner user-name
-      :group user-name
-      :action :create)
-    (action/with-action-options
-     {:sudo-user user-name
-      :script-dir user-home
-      :script-env {:HOME user-home}}
-     (actions/exec-checked-script
-      "import & trust gpg key"
-      ("su" ~user-name "-c" "\"gpg" "--import" ~(str user-home "/pub.key\""))
-      ("su" ~user-name "-c" "\"gpgconf" "--kill" "gpg-agent\"")
-      ("su" ~user-name "-c" "\"gpgconf" "--launch" "gpg-agent\"")
-      ("su" ~user-name "-c" "\"echo" ~passphrase "|"
-            "/usr/lib/gnupg/gpg-preset-passphrase" "--preset" ~public-key-id "\"")
-      ("su" ~user-name "-c" "\"gpg" "--batch" "--import" ~(str user-home "/priv.key\""))
-      ("su" ~user-name "-c" "\"/usr/lib/gpg-trust-all.sh\"")))))
+     (str user-home "/.gnupg/gpg-agent.conf")
+     :mode "600"
+     :content (slurp (io/resource "gpg-agent.conf"))
+     :owner user-name
+     :group user-name
+     :action :create)
+    (actions/exec-checked-script
+     "import & trust gpg key"
+     ("su" ~user-name "-c" "\"gpg" "--import" ~(str user-home "/pub.key\""))
+     ("su" ~user-name "-c" "\"gpgconf" "--kill" "gpg-agent\"")
+     ("su" ~user-name "-c" "\"gpgconf" "--launch" "gpg-agent\"")
+     ("su" ~user-name "-c" "\"echo" ~passphrase "|"
+           "/usr/lib/gnupg/gpg-preset-passphrase" "--preset" ~public-key-id "\"")
+     ("su" ~user-name "-c" "\"gpg" "--batch" "--import" ~(str user-home "/priv.key\""))
+     ("su" ~user-name "-c" "\"/usr/lib/gpg-trust-all.sh\""))))


migrate to sablono

migrate to sablono

--- ui/ringo/components/typeahead.cljs
+++ ui/ringo/components/typeahead.cljs
@@ -4,6 +4,7 @@
   (:refer-clojure :exclude [chars])
   (:require [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true]
+            [sablono.core :as html :refer-macros [html]]
             [clojure.string :as string]))

 (defn- hidden [^boolean bool]
@@ -13,28 +14,31 @@

 (defn- word-index [index owner]
   (om/component
-    (dom/span #js {:className "word-index"} (om/value index))))
+    (html
+     [:span {:class "word-index"} (om/value index)])))

 (defn- word-count [count owner]
   (om/component
-    (dom/span #js {:className "word-count"} (om/value count))))
+    (html
+     [:span {:class "word-count"} (om/value count)])))

 (defn- word [the-word owner]
   (om/component
-    (dom/span #js {:className "word"} (om/value the-word))))
+    (html
+     [:span {:class "word"} (om/value the-word)])))

 (defn- item [the-item owner]
   (om/component
-    (dom/li #js {:style (hidden (:hidden the-item))}
+    (html
+     [:li {:style (hidden (:hidden the-item))}
       (om/build word-index (:index the-item))
-      (dom/span #js {:className "word-index-sep"} " ")
       (om/build word (:word the-item))
-      (dom/span #js {:className "word-count-sep"} " ")
-      (om/build word-count (:count the-item)))))
+      (om/build word-count (:count the-item))])))

 (defn- stripe [text bgc]
   (let [st #js {:backgroundColor bgc}]
-    (dom/li #js {:style st} text)))
+    (html
+     [:li {:style st} text])))

 (defn- change [e owner]
   (om/set-state! owner :text (.. e -target -value)))
@@ -46,19 +50,18 @@
     om/IRenderState
     (render-state [_ {:keys [text]}]
       (let [words (:words data)]
-        (dom/div nil
-          (dom/h2 #js {:className "typeahead"} "Search")
-          (dom/input
-            #js {:type "text"
-                 :ref "text-field"
-                 :value text
-                 :className "search"
-                 :onChange #(change % owner)})
-          (apply dom/ul nil
-            (om/build-all item words
-              {:fn (fn [x]
-                     (if-not (string/blank? text)
-                       (cond-> x
-                         (not (zero? (.indexOf (:word x) text)))
-                         (assoc :hidden true))
-                       x))})))))))
+        (html
+         [:div
+          [:h2 {:class "typeahead"} "Search"]
+          [:input {:type "text"
+                   :ref "text-field"
+                   :value text
+                   :class "search"
+                   :on-change #(change % owner)}]
+          [:ul (om/build-all item words
+                             {:fn (fn [x]
+                                    (if-not (string/blank? text)
+                                      (cond-> x
+                                        (not (zero? (.indexOf (:word x) text)))
+                                        (assoc :hidden true))
+                                      x))})]])))))


Remove unused local

Remove unused local

--- src/main/cljc/mikron/runtime/core.cljc
+++ src/main/cljc/mikron/runtime/core.cljc
@@ -60,13 +60,12 @@
   (defmacro schema
     "Returns a reified schema for the given schema definition."
     [& args]
-    (macrowbar/with-syms {:gen [rschema]}
-      (let [{:keys [schema-name schema global-options]} (util/enforce-spec ::runtime.core-spec/schema-args args)]
-        (if-not schema-name
-          (schema* schema global-options)
-          (let [schema-name' (keyword (str (namespace schema-name))
-                                      (str (gensym (name schema-name))))]
-            `(registered-local-schema! ~schema-name' ~(schema* schema global-options {schema-name schema-name'})))))))
+    (let [{:keys [schema-name schema global-options]} (util/enforce-spec ::runtime.core-spec/schema-args args)]
+      (if-not schema-name
+        (schema* schema global-options)
+        (let [schema-name' (keyword (str (namespace schema-name))
+                                    (str (gensym (name schema-name))))]
+          `(registered-local-schema! ~schema-name' ~(schema* schema global-options {schema-name schema-name'}))))))

   (defmacro defschema
     "Globally registers a reified schema for the given schema definition, with the given name."


fix cljs.analyzer.api, can run tests again

--- src/main/clojure/cljs/analyzer/api.clj
+++ src/main/clojure/cljs/analyzer/api.clj
@@ -145,14 +145,16 @@
 (defn all-ns
   "Return all namespaces. Analagous to clojure.core/all-ns but
   returns symbols identifying namespaces not Namespace instances."
-  ([] (all-ns env/*compiler*))
+  ([]
+   (all-ns env/*compiler*))
   ([state]
    (keys (get @state ::ana/namespaces))))

 (defn find-ns
   "Given a namespace return the corresponding namespace analysis map. Analagous
   to clojure.core/find-ns."
-  ([sym] (find-ns env/*compiler* sym))
+  ([sym]
+   (find-ns env/*compiler* sym))
   ([state sym]
    {:pre [(symbol? sym)]}
    (get-in @state [::ana/namespaces sym])))
@@ -160,7 +162,8 @@
 (defn ns-interns
   "Given a namespace return all the var analysis maps. Analagous to
   clojure.core/ns-interns but returns var analysis maps not vars."
-  ([ns] (ns-interns env/*compiler*))
+  ([ns]
+   (ns-interns env/*compiler* ns))
   ([state ns]
    {:pre [(symbol? ns)]}
    (merge
@@ -170,7 +173,8 @@
 (defn ns-publics
   "Given a namespace return all the public var analysis maps. Analagous to
   clojure.core/ns-publics but returns var analysis maps not vars."
-  ([ns] (ns-publics env/*compiler*))
+  ([ns]
+   (ns-publics env/*compiler* ns))
   ([state ns]
    {:pre [(symbol? ns)]}
    (->> (merge
@@ -182,14 +186,16 @@
 (defn ns-resolve
   "Given a namespace and a symbol return the corresponding var analysis map.
   Analagous to clojure.core/ns-resolve but returns var analysis map not Var."
-  ([ns sym] (ns-resolve env/*compiler* ns sym))
+  ([ns sym]
+   (ns-resolve env/*compiler* ns sym))
   ([state ns sym]
    {:pre [(symbol? ns) (symbol? sym)]}
    (get-in @state [::ana/namespaces ns :defs sym])))

 (defn remove-ns
   "Removes the namespace named by the symbol."
-  ([ns] (remove-ns env/*compiler* ns))
+  ([ns]
+   (remove-ns env/*compiler* ns))
   ([state ns]
    {:pre [(symbol? ns)]}
    (swap! state update-in [::ana/namespaces] dissoc ns)))


fix issue concerning nodes without edges

--- src/main/clojure/conexp/util/graph.clj
+++ src/main/clojure/conexp/util/graph.clj
@@ -40,7 +40,7 @@
    for either (u,v) or (v,u) or both."
   [nodes condition]
   (uber/add-undirected-edges*
-    (uber/graph)
+    (apply lg/add-nodes (uber/graph) nodes)
     (mapcat
       (fn [x] (map
                 (fn [y] [x y])
@@ -52,7 +52,7 @@
    if two nodes shall get an edge."
   [nodes condition]
   (uber/add-directed-edges*
-    (uber/digraph)
+    (apply lg/add-nodes (uber/digraph) nodes)
     (mapcat
       (fn [x] (map
                 (fn [y] [x y])


CMR-1805: Added tests based on review comments.

--- system-int-test/test/cmr/system_int_test/search/collection_concept_revision_search_test.clj
+++ system-int-test/test/cmr/system_int_test/search/collection_concept_revision_search_test.clj
@@ -19,9 +19,9 @@
                                                   :version-id "v1"
                                                   :short-name "s1"}))
         concept1 {:provider-id "PROV1"
-                 :concept-type :collection
-                 :native-id (:entry-title coll1-1)}
-        coll1-tombstone (merge (ingest/delete-concept concept1) concept1 {:deleted true})
+                  :concept-type :collection
+                  :native-id (:entry-title coll1-1)}
+        coll1-2-tombstone (merge (ingest/delete-concept concept1) concept1 {:deleted true})
         coll1-3 (d/ingest "PROV1" (dc/collection {:entry-title "et1"
                                                   :entry-id "eid1"
                                                   :version-id "v2"
@@ -36,14 +36,14 @@
                                                   :version-id "v2"
                                                   :short-name "s2"}))
         concept2 {:provider-id "PROV1"
-                 :concept-type :collection
-                 :native-id (:entry-title coll2-2)}
-        coll2-tombstone (merge (ingest/delete-concept concept2) concept2 {:deleted true})
+                  :concept-type :collection
+                  :native-id (:entry-title coll2-2)}
+        coll2-3-tombstone (merge (ingest/delete-concept concept2) concept2 {:deleted true})

         coll3 (d/ingest "PROV2" (dc/collection {:entry-title "et3"
-                                                  :entry-id "eid3"
-                                                  :version-id "v4"
-                                                  :short-name "s1"}))]
+                                                :entry-id "eid3"
+                                                :version-id "v4"
+                                                :short-name "s1"}))]
     (index/wait-until-indexed)
     (testing "find-references-with-all-revisions parameter"
       (are2 [collections params]
@@ -59,7 +59,7 @@
             {:provider-id "PROV1"}

             "provider-id all-revisions=true"
-            [coll1-1 coll1-tombstone coll1-3 coll2-1 coll2-2 coll2-tombstone]
+            [coll1-1 coll1-2-tombstone coll1-3 coll2-1 coll2-2 coll2-3-tombstone]
             {:provider-id "PROV1" :all-revisions true}

             "native-id all-revisions=false"
@@ -71,7 +71,7 @@
             {:native-id "et1"}

             "native-id all-revisions=true"
-            [coll1-1 coll1-tombstone coll1-3]
+            [coll1-1 coll1-2-tombstone coll1-3]
             {:native-id "et1" :all-revisions true}

             "version all-revisions=false"
@@ -83,11 +83,11 @@
             {:version "v2"}

             "version all-revisions=true"
-            [coll1-3 coll2-2 coll2-tombstone]
+            [coll1-3 coll2-2 coll2-3-tombstone]
             {:version "v2" :all-revisions true}

             ;; verify that "finding latest", i.e., all-revisions=false, does not return old revisions
-            "version all-revsions=false - no match to latest"
+            "version all-revisions=false - no match to latest"
             []
             {:version "v1" :all-revisions false}

@@ -101,7 +101,7 @@
             {:short-name "s1"}

             "short-name all-revisions true"
-            [coll1-1 coll1-tombstone coll1-3 coll3]
+            [coll1-1 coll1-2-tombstone coll1-3 coll3]
             {:short-name "s1" :all-revisions true}

             "concept-id all-revisions false"
@@ -113,14 +113,30 @@
             {:concept-id "C1200000000-PROV1"}

             "concept-id all-revisions true"
-            [coll1-1 coll1-tombstone coll1-3]
-            {:concept-id "C1200000000-PROV1" :all-revisions true}))))
+            [coll1-1 coll1-2-tombstone coll1-3]
+            {:concept-id "C1200000000-PROV1" :all-revisions true}

-(deftest search-granule-all-revisions
+            "all-revisions true"
+            [coll1-1 coll1-2-tombstone coll1-3 coll2-1 coll2-2 coll2-3-tombstone coll3]
+            {:all-revisions true}))))
+
+(deftest search-all-revisions-error-cases
+  (testing "collection search with all_revisions bad value"
+    (let [{:keys [status errors]} (search/get-search-failure-data
+                                    (search/find-refs :collection {:all-revisions "foo"}))]
+      (is (= [400 ["Parameter all_revisions must take value of true, false, or unset, but was [foo]"]]
+             [status errors]))))
   (testing "granule search with all_revisions parameter is not supported"
     (let [{:keys [status errors]} (search/get-search-failure-data
                                     (search/find-refs :granule {:provider-id "PROV1"
                                                                 :all-revisions false}))]
       (is (= [400 ["Parameter [all_revisions] was not recognized."]]
+             [status errors]))))
+  (testing "granule search with all_revisions bad value"
+    (let [{:keys [status errors]} (search/get-search-failure-data
+                                    (search/find-refs :granule {:provider-id "PROV1"
+                                                                :all-revisions "foo"}))]
+      (is (= [400 ["Parameter [all_revisions] was not recognized."
+                   "Parameter all_revisions must take value of true, false, or unset, but was [foo]"]]
              [status errors])))))


CMR-3812: Added v2 facets science keywords tests.

--- system-int-test/test/cmr/system_int_test/search/facets/collection_facets_v2_search_test.clj
+++ system-int-test/test/cmr/system_int_test/search/facets/collection_facets_v2_search_test.clj
@@ -430,6 +430,88 @@
         (assert-facet-field-not-exist facets-result "Instruments" "I3")
         (assert-facet-field-not-exist facets-result "Projects" "proj3")))))

+(deftest science-keywords-facets-v2-test
+  (let [coll (d/ingest "PROV1" (dc/collection
+                                {:entry-title "coll1"
+                                 :short-name "S1"
+                                 :version-id "V1"
+                                 :platforms (dc/platforms "P1")
+                                 :science-keywords [(dc/science-keyword
+                                                     {:category "Earth Science"
+                                                      :topic "Topic1"
+                                                      :term "Term1"
+                                                      :variable-level-1 "Level1-1"
+                                                      :variable-level-2 "Level1-2"
+                                                      :variable-level-3 "Level1-3"
+                                                      :detailed-variable "Detail1"})]}))
+        coll2 (d/ingest "PROV1" (dc/collection
+                                 {:entry-title "coll2"
+                                  :short-name "S2"
+                                  :version-id "V2"
+                                  :platforms (dc/platforms "P2")
+                                  :science-keywords [(dc/science-keyword
+                                                      {:category "Earth Science"
+                                                       :topic "Topic2"
+                                                       :term "Term2"
+                                                       :variable-level-1 "Level2-1"
+                                                       :variable-level-2 "Level2-2"})]}))
+        coll3 (d/ingest "PROV1" (dc/collection
+                                 {:entry-title "coll3"
+                                  :short-name "S3"
+                                  :version-id "V3"
+                                  :platforms (dc/platforms "P3")
+                                  :science-keywords [(dc/science-keyword
+                                                      {:category "Earth Science"
+                                                       :topic "Topic1"
+                                                       :term "Term3"})
+                                                     (dc/science-keyword
+                                                      {:category "Earth Science"
+                                                       :topic "Topic2"
+                                                       :term "Term3"})]}))]
+    ;; We only check the topic level science keywords facet for convenience since the whole
+    ;; hierarchical structure of science keywords facet has been covered in all facets test.
+    (testing "search by science-keywords param filters the other facets, but not science-keywords facets"
+      (let [facets-result (search-and-return-v2-facets
+                           {:science-keywords-h {:0 {:topic "Topic1"
+                                                     :term "Term1"
+                                                     :variable-level-1 "Level1-1"
+                                                     :variable-level-2 "Level1-2"
+                                                     :variable-level-3 "Level1-3"}}})]
+        (assert-facet-field facets-result "Keywords" "Topic1" 2)
+        (assert-facet-field facets-result "Keywords" "Topic2" 2)
+        (assert-facet-field facets-result "Platforms" "P1" 1)
+        (assert-facet-field-not-exist facets-result "Platforms" "P2")
+        (assert-facet-field-not-exist facets-result "Platforms" "P3")))
+
+    (testing "search by both science-keywords param and regular param"
+      (let [facets-result (search-and-return-v2-facets
+                           {:short-name "S1"
+                            :science-keywords-h {:0 {:topic "Topic1"}}})]
+        (assert-facet-field facets-result "Keywords" "Topic1" 1)
+        (assert-facet-field facets-result "Platforms" "P1" 1)
+        (assert-facet-field-not-exist facets-result "Keywords" "Topic2")
+        (assert-facet-field-not-exist facets-result "Platforms" "P2")
+        (assert-facet-field-not-exist facets-result "Platforms" "P3")))
+    (testing "search by both science-keywords param and a facet field param, with science keywords match a collection"
+      (let [facets-result (search-and-return-v2-facets
+                           {:platform-h "P1"
+                            :science-keywords-h {:0 {:topic "Topic1"
+                                                     :term "Term1"}}})]
+        (assert-facet-field facets-result "Keywords" "Topic1" 1)
+        (assert-facet-field facets-result "Platforms" "P1" 1)
+        (assert-facet-field-not-exist facets-result "Keywords" "Topic2")
+        (assert-facet-field-not-exist facets-result "Platforms" "P2")
+        (assert-facet-field-not-exist facets-result "Platforms" "P3")))
+    (testing "search by both science-keywords param and a facet field param, with science keywords match two collections"
+      (let [facets-result (search-and-return-v2-facets
+                           {:platform-h "P3"
+                            :science-keywords-h {:0 {:topic "Topic1"}}})]
+        (assert-facet-field facets-result "Keywords" "Topic1" 1)
+        (assert-facet-field facets-result "Keywords" "Topic2" 1)
+        (assert-facet-field facets-result "Platforms" "P1" 1)
+        (assert-facet-field facets-result "Platforms" "P3" 1)
+        (assert-facet-field-not-exist facets-result "Platforms" "P2")))))
+
 (comment
  ;; Good for manually testing applying links
  (do


CMR-3207: Remove OBE comment

CMR-3207: Remove OBE comment

--- system-int-test/test/cmr/system_int_test/search/facets/collection_facets_v2_search_test.clj
+++ system-int-test/test/cmr/system_int_test/search/facets/collection_facets_v2_search_test.clj
@@ -270,7 +270,7 @@
   (testing (str "When there are multiple fields selected at the same level of the hierarchy they "
                 "each have different indexes")
     (fu/make-coll 1 "PROV1" (fu/science-keywords sk-all sk-same-vl1 sk-diff-vl1))
-    (let [expected #{0 1 2 3} ;; Went from 3 to 4 values - Not sure why 2 is not included TODO add unit tests for has-siblings?
+    (let [expected #{0 1 2 3}
           actual (->> (search-and-return-v2-facets)
                       fu/traverse-hierarchical-links-in-order
                       fu/get-all-links


More Tom & Dan debugging

More Tom & Dan debugging

--- src/pamela/htn.clj
+++ src/pamela/htn.clj
@@ -1208,7 +1208,7 @@
         (doseq [[mname method] (seq methods)]
           (if mname ;; else (println "no more methods")
             (let [{:keys [temporal-constraints args primitive display-name body]} method]
-              ;; (println "  METHOD" mname "PRIMITIVE" primitive)
+              (println "  METHOD" mname "PRIMITIVE" primitive)
               (if (and (not primitive) body)
                 (make-htn-methods ir pclass-name mname display-name args body))
               )))))))
@@ -1372,7 +1372,8 @@
                      (irks->bounds ir irks))
             m-task-expansions (count task-expansions)
             ;; DEBUG
-            _ (println "ST#" i "of" n-subtasks "IRKS" irks)
+            _ (println "ST#" i "of" n-subtasks "IRKS" irks
+                       "type" type "pclass" pclass "name" name)
             ;; resolve pclass if (= type :htn-nonprimitive-task)
             ;; to determine if this was really an unresolved primitive task
             ;; DEBUG plant-class (if (htn-isa? type :htn-nonprimitive-task)
@@ -1591,13 +1592,13 @@
               {:keys [type name field method args
                       primitive body temporal-constraints]} f
               ;; DEBUG
-              ;; _ (println "MAKE-HTN-METHODS" i "TYPE" type
-              ;;     "NAME" name "METHOD" method
-              ;;     "PCLASS" pclass "MNAME" mname
-              ;;     "PRIMITIVE" primitive
-              ;;     "\nMARGS" margs "ARGS" args
-              ;;     "BODY" body
-              ;;     "TC" temporal-constraints)
+              _ (println "MAKE-HTN-METHODS" i "TYPE" type
+                  "NAME" name "FIELD" field "METHOD" method
+                  "\nPCLASS" pclass "MNAME" mname
+                  "PRIMITIVE" primitive
+                  "\nMARGS" margs "ARGS" args
+                  "BODY" body
+                  "TC" temporal-constraints)
               subtask
               (cond
                 (#{:plant-fn-symbol :plant-fn-field} type)
@@ -1620,9 +1621,10 @@
                 ;; has true or false)
                 (let [plant-class (if (= :plant-fn-symbol type)
                                     (if (= name 'this) pclass name)
-                                    (get-in ir [pclass :fields :field :initial :pclass]))
+                                    (get-in ir [pclass :fields field :initial :pclass]))
                       plant-fn-primitive?
                       (get-in ir [plant-class :methods method :primitive])
+                      _ (println "plant-class" plant-class "plant-fn-primitive?" plant-fn-primitive?)
                       [plant-class non-primitive?]
                       (if (nil? plant-fn-primitive?)  ;;TODO - Should error here
                         [::unknown false]
@@ -1631,7 +1633,8 @@
                       ;; functions, but the HEM logic does not support it.
                       ;; make-htn-method? (or (symbol? mname)
                       ;;                    (nil? plant-fn-primitive?))
-                      make-htn-method? (symbol? mname)
+                      ;; NOTE: We will make an htn-method, if (not plant-fn-primitive?)
+                      ;;make-htn-method? (symbol? mname)
                       ;; DEBUG
                       ;; _ (println "  make-htn-method?" make-htn-method?
                       ;;     "plant-class" plant-class
@@ -1645,23 +1648,30 @@
                              :arguments args
                              :temporal-constraints temporal-constraints
                              :irks irks-i})
-                      nt (if make-htn-method?
+                      nt (if (not plant-fn-primitive?)
                            (htn-nonprimitive-task
                              {:pclass pclass
                               :name mname
                               :arguments margs
                               :irks irks-i}))
-                      st (if make-htn-method? [task])]
+                      st (if (not plant-fn-primitive?) [task])
+                      ;; st (if (not plant-fn-primitive?)
+                      ;;      (make-htn-methods ir plant-class method
+                      ;;                        (str method) ;;(str type) ;;TODO: Not sure this will be necessary
+                      ;;                        args (get-in ir [plant-class :methods method :body])))
+                      ]
                   ;; (println "  PLANT-FN-SYMBOL TASK" task)
-                  ;; (println "  PLANT-FN-SYMBOL SUBTASKS" st)
-                  (when make-htn-method? ;; make htn-method
-                    (let [hm (htn-method {:pclass pclass
+                  (println "  PLANT-FN-XXX SUBTASKS" st)
+                  (when (not plant-fn-primitive?) ;; make htn-method
+                    (let [hm (htn-method {:pclass plant-class
                                           :name mname
                                           :display-name display-name
                                           :nonprimitive-task nt
                                           :subtasks st
-                                          :irks irks-i})]
-                      ;; (println "HTN-METHOD" (with-out-str (pprint hm)))
+                                          :irks (if (= plant-class pclass)
+                                                  irks-i
+                                                  [plant-class :methods method :body])})]
+                      (println "HTN-METHOD" (with-out-str (pprint hm)))
                       ;; (pprint-htn-methods)
                       hm))
                   task)


Logging that is removed with IE8.

Logging that is removed with IE8.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -16,7 +16,14 @@
      [kixi.hecuba.model :refer (app-model)]
      [sablono.core :as html :refer-macros [html]]))

-;; (enable-console-print!)
+(when (or (not agent/IE)
+          (agent/isVersionOrHigher 9))
+  (enable-console-print!))
+
+(defn log [& msgs]
+  (when (or (not agent/IE)
+            (agent/isVersionOrHigher 9))
+    (apply println msgs)))

 ;; our banner is 50px so we need to tweak the scrolling
 (defn fixed-scroll-to-element [element]
@@ -118,7 +125,7 @@
   (om/update! data [:programmes :fetching] :fetching)
   (GET (str "/4/programmes/")
        {:handler  (fn [x]
-                    ;; (println "Fetching programmes.")
+                    (log "Fetching programmes.")
                     (om/update! data [:programmes :data] (mapv slugify-programme x))
                     (om/update! data [:programmes :fetching] (if (empty? x) :no-data :has-data)))
         :error-handler (fn [{:keys [status status-text]}]
@@ -132,7 +139,7 @@
   (om/update! data [:projects :fetching] :fetching)
   (GET (str "/4/programmes/" programme-id "/projects/")
        {:handler  (fn [x]
-                    ;; (println "Fetching projects for programme: " programme-id)
+                    (log "Fetching projects for programme: " programme-id)
                     (om/update! data [:projects :data] (mapv slugify-project x))
                     (om/update! data [:projects :fetching] (if (empty? x) :no-data :has-data)))
         :error-handler (fn [{:keys [status status-text]}]
@@ -146,7 +153,7 @@
   (om/update! data [:properties :fetching] :fetching)
   (GET (str "/4/projects/" project-id "/properties/")
        {:handler  (fn [x]
-                    ;; (println "Fetching properties for project: " project-id)
+                    (log "Fetching properties for project: " project-id)
                     (om/update! data [:properties :data] (mapv slugify-property x))
                     (om/update! data [:properties :fetching] (if (empty? x) :no-data :has-data)))
         :error-handler (fn [{:keys [status status-text]}]
@@ -192,26 +199,26 @@
           old-programmes (:programmes old-nav)
           old-projects (:projects old-nav)
           old-properties (:properties old-nav)]
-      ;; (println "Old Programmes: " old-programmes " Old Projects: " old-projects " Old Properties: " old-properties)
-      ;; (println "New Programmes: " programmes " New Projects: " projects " New Properties: " properties)
+      (log "Old Programmes: " old-programmes " Old Projects: " old-projects " Old Properties: " old-properties)
+      (log "New Programmes: " programmes " New Projects: " projects " New Properties: " properties)

       ;; Clear down
       (when (or (nil? programmes)
                 (empty? (-> @data :programmes :data)))
-        ;; (println "Clearing projects.")
+        (log "Clearing projects.")
         (om/update! data [:programmes :selected] nil)
         (om/update! data [:projects :data] [])
         (om/update! data [:projects :programme_id] nil)
         (fetch-programmes data))

       (when-not projects
-        ;; (println "Clearing properties.")
+        (log "Clearing properties.")
         (om/update! data [:projects :selected] nil)
         (om/update! data [:properties :data] [])
         (om/update! data [:properties :project_id] nil))

       (when-not properties
-        ;; (println "Clearing devices, sensors and measurements.")
+        (log "Clearing devices, sensors and measurements.")
         (om/update! data [:properties :selected] nil)
         (om/update! data [:property-details :data] {})
         (om/update! data [:property-details :property_id] nil)
@@ -224,21 +231,21 @@

       (when (and (not= programmes old-programmes)
                  programmes)
-        ;; (println "Setting selected programme to: " programmes)
+        (log "Setting selected programme to: " programmes)
         (om/update! data [:programmes :selected] programmes)
         (om/update! data [:projects :programme_id] programmes)
         (fetch-projects programmes data))

       (when (and (not= projects old-projects)
                  projects)
-        ;; (println "Setting selected project to: " projects)
+        (log "Setting selected project to: " projects)
         (om/update! data [:projects :selected] projects)
         (om/update! data [:properties :project_id] projects)
         (fetch-properties projects data))

       (when (and (not= properties old-properties)
                  properties)
-        ;; (println "Setting property details to: " properties)
+        (log "Setting property details to: " properties)
         (om/update! data [:properties :selected] properties))

       (when sensors


(PE-5888) increase test coverage for stupid PSON

Add a couple of assertions to indicate that GETs to
/certificate_status(es) with 'Accept: text/pson' return a response with
'Content-Type: text/pson'.

--- test/puppetlabs/services/ca/certificate_authority_core_test.clj
+++ test/puppetlabs/services/ca/certificate_authority_core_test.clj
@@ -267,7 +267,8 @@
                          :headers {"accept" "text/pson"}}
                 response (test-app request)]
             (is (= 200 (:status response))
-                (ks/pprint-to-string response)))))
+                (ks/pprint-to-string response))
+            (is (.startsWith (get-in response [:headers "Content-Type"]) "text/pson")))))

       (testing "GET /certificate_statuses"
         (let [response (test-app
@@ -292,6 +293,7 @@
                          :request-method :get
                          :headers {"accept" "text/pson"}})]
           (is (= 200 (:status response)))
+          (is (.startsWith (get-in response [:headers "Content-Type"]) "text/pson"))
           (is (= #{localhost-status test-agent-status revoked-agent-status}
                  (set (json/parse-string (:body response) true)))))))))


Add tests for nil values as check function params.

--- test/buddy/hashers_tests.clj
+++ test/buddy/hashers_tests.clj
@@ -65,3 +65,10 @@
     (is (hashers/check plain-password
                        (hashers/encrypt plain-password {:algorithm :md5})))))

+(deftest buddy-hashers-nil
+  (let [plain-password "my-test-password"
+        encrypted-password (hashers/encrypt plain-password {:algorithm :pbkdf2+sha256})]
+    (is (= nil (hashers/check nil encrypted-password)))
+    (is (= nil (hashers/check plain-password nil)))
+    (is (= nil (hashers/check nil nil)))))
+


cleaning up tests from atom removal

cleaning up tests from atom removal

--- test/cartagena/core_test.clj
+++ test/cartagena/core_test.clj
@@ -17,12 +17,12 @@
         (is (not (nil? (:pirates space))))
         (is (empty? (:pirates space)))
         (is (some #{(:icon space)} icons))
-        (is (> (:index space) 0)))
+        (is (pos? (:index space))))
       (doseq [icon icons]
         (is (= 6 (count (filter #(= icon (:icon %)) player-spaces)))))))
   ;; fragile test follows: it's possible that three draws in a row would be the same...
   (testing "Boards are not exactly alike"
-    (is (not (= (initialize-board) (initialize-board) (initialize-board))))))
+    (is (not= (initialize-board) (initialize-board)))))

 (deftest initialize-cards-test
   (testing "Returns a pile of 102 cards, 17 of each icon"
@@ -36,7 +36,7 @@
     (let [cards [:key :key :knife :knife :skull :skull :gun :gun :bottle :bottle :hat :hat]
           shuffled (shuffle-cards cards)]
       (is (= (count cards) (count shuffled)))
-      (is (not (= cards shuffled))))))
+      (is (not= cards shuffled)))))

 (deftest initialize-player-test
   (testing "Returns a player data structure full of initial state data"
@@ -64,27 +64,27 @@
         (is (filter #(= card %) (:cards player))))
       (is (= 2 (count (:draw-pile actual)))))))

-(defn assert-player-state []
-  (is (= 2 (count (:players @game-state))))
-  (is (= "tanya" (get-in @game-state [:players 0 :name]))))
-(defn assert-card-state []
-  (is (= 6 (count (get-in @game-state [:players 0 :cards]))))
-  (is (= 90 (count (:draw-pile @game-state))))
-  (is (= 0 (count (:discard-pile @game-state)))))
-(defn assert-board-state []
-  (is (= 38 (count (:board @game-state))))
-  (is (= 12 (count (:pirates (first (:board @game-state))))) "Should have 12 pirates in jail"))
+(defn assert-player-state [game-state]
+  (is (= 2 (count (:players game-state))))
+  (is (= "tanya" (get-in game-state [:players 0 :name]))))
+(defn assert-card-state [game-state]
+  (is (= 6 (count (get-in game-state [:players 0 :cards]))))
+  (is (= 90 (count (:draw-pile game-state))))
+  (is (zero? (count (:discard-pile game-state)))))
+(defn assert-board-state [game-state]
+  (is (= 38 (count (:board game-state))))
+  (is (= 12 (count (:pirates (first (:board game-state))))) "Should have 12 pirates in jail"))

 (deftest new-game-test
   (testing "All game state is initialized correctly"
-    (let [players [{:name "tanya" :color :orange} {:name "rusty" :color :black}]]
-      (new-game! players)
+    (let [players [{:name "tanya" :color :orange} {:name "rusty" :color :black}]
+          game-state (new-game! players)]
       (testing "Player state is correct"
-        (assert-player-state))
+        (assert-player-state game-state))
       (testing "Card state is correct"
-        (assert-card-state))
+        (assert-card-state game-state))
       (testing "Board state is correct"
-        (assert-board-state)))))
+        (assert-board-state game-state)))))

 (deftest is-open-target?-test
   (is (is-open-target? {:icon :hat :pirates [:orange :orange]} :hat))


more notes

more notes

--- test/cartagena/core_test.clj
+++ test/cartagena/core_test.clj
@@ -73,7 +73,7 @@
         (assert-board-state)))))

 (deftest play-card-test
-  ; board-spaces becomes a vector of vectors that contain keys for pirate colors they contain? or players?  maybe players should be color-based?
+  ; board-spaces becomes a vector of vectors that contain keys for pirate colors they contain? or players?  maybe players should be color-based? {:orange {:name "tanya"...) :black {:name "rusty"...}}
   (let [expected {:player {:cards updated-cards
                            :pirates updated-pirates}
                   :board-spaces updated-spaces


test first entry in example data set

test first entry in example data set

--- test/cloogling/core_test.clj
+++ test/cloogling/core_test.clj
@@ -6,5 +6,18 @@

 (def miles_davis_data (slurp "test/cloogling/miles_davis_bing.json"))

-;; Parsing entries in bing json format to a list
+;; 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"
+               (-> miles_davis_data
+                   get-entries
+                   first
+                   (:url)
+                   )
+        )
+
+
+;; "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 ..."


Don't run new test on CLJS

Don't run new test on CLJS

--- test/expound/alpha_test.cljc
+++ test/expound/alpha_test.cljc
@@ -1071,15 +1071,29 @@
    :simple :expound.ds/simple-specs
    :maybe :expound.ds/maybe-spec))

-(deftest generated-data-specs
-  (checking
-   "generated data specs"
-   num-tests
-   [data-spec (s/gen :expound.ds/spec)
-    form any-printable-wo-nan
-    prefix (s/gen qualified-keyword?)
-    :let [gen-spec (ds/spec prefix (real-spec data-spec))]]
-   (is (string? (expound/expound-str gen-spec form)))))
+(def data-spec-compat?
+  #?(:cljs
+     (do
+       ;; FIXME - anything including or after 1.9.908
+       ;; should work, but seems to fail, possibly due to?
+       ;; https://dev.clojure.org/jira/browse/CLJS-1297?
+       (not= "1.9.562"
+             *clojurescript-version*)
+       ;; Just force false for now
+       false)
+     :clj
+     true))
+
+(when data-spec-compat?
+  (deftest generated-data-specs
+    (checking
+     "generated data specs"
+     num-tests
+     [data-spec (s/gen :expound.ds/spec)
+      form any-printable-wo-nan
+      prefix (s/gen qualified-keyword?)
+      :let [gen-spec (ds/spec prefix (real-spec data-spec))]]
+     (is (string? (expound/expound-str gen-spec form))))))

 ;; FIXME - keys
 ;; FIXME - cat + alt, + ? *


silence react error for undefined keys

silence react error for undefined keys

--- src/show/core.cljs
+++ src/show/core.cljs
@@ -46,8 +46,8 @@
   "Returns the value of the components owned state nested associative structure.
   ks is an optional property that gives quick access to a get-in call"
   ([component]
-  (if-let [state (or (.-_pendingState component)
-                     (.-state component))]
+  (when-let [state (or (.-_pendingState component)
+                       (.-state component))]
     (aget state "__show")))
   ([component ks]
    (let [ks (if (sequential? ks) ks [ks])]
@@ -232,7 +232,7 @@

         component-class   (js/React.createFactory
                             (js/React.createClass (clj->js lifecycle-methods)))
-        ret-fn            #(component-class #js {:key    (get % :key)
+        ret-fn            #(component-class #js {:key    (or (get % :key) js/undefined)
                                                  :__show (dissoc % :key)})]

     ;; Inject lifecycle methods into the fn just for mixin loading


Updated classmap doc and not joining with a comma

--- src/show/core.cljs
+++ src/show/core.cljs
@@ -4,8 +4,13 @@
   (:import [goog.ui IdGenerator]))

 ;; Utils
-(defn class-map [cmap]
-  (clojure.string/join ", " (map first (filter #(second %) cmap))))
+(defn class-map
+  "Simple helper function for quickly adding/removing classNames to components.
+  It is analgous to React's classSet helper. The map argument should be a map
+  containing a key for the className and an expression that evaluates truthy or
+  falsey."
+  [cmap]
+  (clojure.string/join " " (map first (filter #(second %) cmap))))

 ;; Getters and setters
 (defn get-node


diff test after pull in place

diff test after pull in place

--- test/mirthsync/core_test.clj
+++ test/mirthsync/core_test.clj
@@ -9,7 +9,7 @@
 ;;; note that these tests will only work in unix'ish environments with
 ;;; appropriate commands in the path

-(programs mkdir sha256sum curl tar cp rm rmdir echo diff sed)
+(programs mkdir sha256sum curl tar cp rm rmdir diff) ;; sed ;; echo

 ;;;; starting data and accessor fns
 (def mirths-dir "target/mirths")
@@ -152,21 +152,20 @@
                                    "-u" "admin" "-p" "admin" "-t" "target/tmp"
                                    "-i" "-f" "pull"))))

-  (testing "Pull diff from baseline is identical to expected diff"
-    (is (= "7af9473e4b277ea4ef138d99ae218727d7aadb4787dadf8480502912da807f03  -\n"
-           (let-programs [native-sort "sort"] ; don't shadow clojure sort
-             (sha256sum
-              {:in
-               (native-sort {:seq true :in
-                             (sed "s/<time>.*<\\/time>//"
-                                  {:seq true :in
-                                   (diff "-r" "target/tmp/" "dev-resources/mirth-8-baseline"
-                                         {:seq true :throw false})})})}))))))
-;; "003aec63ba454f2b158d0bd6151917928bea6a6fc20aa1018815f8382f2773c9  -\n"
-
-;; "161701a6dbbcbc5711f00ebac3f78512bf3070ad68d57ef3848413f2e5042eab  -\n"
+  (testing "Pull diff from baseline has only inconsequential differences (ordering, etc)"
+    (is (= "" (diff "--recursive" "--suppress-common-lines" "-I .*<contextType>.*" "-I .*<time>.*" "-I .*<revision>.*" "target/tmp" "dev-resources/mirth-8-baseline")))))

+;;;;; original approach till the proper diff params were found
+;; (is (= "cf447090a77086562eb0d6d9eb6e03703c936ed2a10c3afe02e51587171a665b  -\n"
+;;        (let-programs [native-sort "sort"] ; don't shadow clojure sort
+;;          (sha256sum
+;;           {:in
+;;            (native-sort "-bfi" {:seq true :in
+;;                                 (sed "s/<time>.*<\\/time>//"
+;;                                      {:seq true :in
+;;                                       (diff "--rcs" "--suppress-common-lines" "target/tmp/" "dev-resources/mirth-8-baseline"
+;;                                             {:seq true :throw false})})})}))))

 ;; (sed "'s/diff -r.*\\/\\(target.*\\/ \\).*\\/\\(dev-resources.*\\)/diff -r \\1 \\2/'"
 ;;      (diff "-r" "target/tmp/" "dev-resources/mirth-8-baseline" {:seq true :throw false}))


stats ring buffer should batch subvec calls

--- src/spq/server.clj
+++ src/spq/server.clj
@@ -51,8 +51,20 @@
   (let [[stats size] (if (nil? stats)
                        [[] 0]
                        [stats (count stats)])]
-    (subvec (conj stats (System/nanoTime))
-            (max 0 (inc (- size (conf :stats :count)))))))
+    ;; ring buffer, but batches up rollover so we dont call subvec
+    ;; every time. this means the consumer has to subvec is they care
+    ;; about the exact size of the buffer, so use (-get-current-stats stats).
+    (if (< size (* 1.2 (conf :stats :count)))
+      (conj stats (System/nanoTime))
+      (subvec (conj stats (System/nanoTime))
+              (max 0 (inc (- size (conf :stats :count))))))))
+
+(defn -get-current-stats
+  [v]
+  (when v
+    (let [size (count v)
+          desired-count (min size (conf :stats :count))]
+      (subvec v (max 0 (- size desired-count))))))

 (defhandler post-complete
   [req]
@@ -114,6 +126,15 @@
     (timbre/debug "put!" queue-name item)
     {:status 200}))

+(defn -rate-per-sec
+  [now s ks]
+  (let [num-events (->> ks
+                     (get-in s)
+                     -get-current-stats
+                     (drop-while #(> (- now %) (* 1e9 (conf :stats :window-seconds))))
+                     count)]
+    (double (/ num-events (conf :stats :window-seconds)))))
+
 (defhandler get-stats
   [req]
   {:status 200
@@ -127,8 +148,8 @@
                        ;; (max 0), is this a bug upstream? can be negative? data race?
                        {:queued (max 0 (- (:enqueued v) (:completed v)))
                         :active (max 0 (:in-progress v))
-                        :puts/sec      (double (/ (count (drop-while #(> (- now %) (* 1e9 (conf :stats :window-seconds))) (get-in s [:stats k :puts])))      (conf :stats :window-seconds)))
-                        :completes/sec (double (/ (count (drop-while #(> (- now %) (* 1e9 (conf :stats :window-seconds))) (get-in s [:stats k :completes]))) (conf :stats :window-seconds)))})))
+                        :puts/sec      (-rate-per-sec now s [:stats k :puts])
+                        :completes/sec (-rate-per-sec now s [:stats k :completes])})))
             {})
            lib/json-dumps)})


explicit require of goog.object

explicit require of goog.object

--- src/tick/core.cljc
+++ src/tick/core.cljc
@@ -32,7 +32,8 @@
     [cljc.java-time.temporal.chrono-unit]
     [cljc.java-time.format.date-time-formatter]
     #?@(:cljs
-        [[java.time.format :refer [DateTimeFormatter]]
+        [[goog.object]
+         [java.time.format :refer [DateTimeFormatter]]
          [java.time :refer [Clock ZoneId ZoneOffset Instant Duration Period DayOfWeek Month ZonedDateTime LocalTime
                             LocalDateTime LocalDate Year YearMonth OffsetDateTime OffsetTime]]
          [cljs.java-time.extend-eq-and-compare]]))


Returning job (JobDetail instance) from schedule-job.

--- src/twarc/core.clj
+++ src/twarc/core.clj
@@ -132,7 +132,8 @@
   [scheduler var arguments & {:keys [job trigger replace] :or {replace false}}]
   (let [job (job-from-var var (assoc job :arguments arguments))
         trigger (make-trigger trigger)]
-    (.scheduleJob (:twarc/quartz scheduler) job #{trigger} replace)))
+    (.scheduleJob (:twarc/quartz scheduler) job #{trigger} replace)
+    job))

 (defn delete-job
   [scheduler & key]


auto-complete tags

auto-complete tags

--- src/chat/client/views/new_message.cljs
+++ src/chat/client/views/new_message.cljs
@@ -44,6 +44,29 @@

 (def engines
   [
+   ; ... #<tag>   -> autocompletes tag
+   (fn [text thread-id]
+     (let [pattern #"\B#(\S{1,})$"]
+       (when-let [query (second (re-find pattern text))]
+         (->> (store/all-tags)
+              (filter (fn [t]
+                        (fuzzy-matches? (t :name) query)))
+              (map (fn [tag]
+                     {:action
+                      (fn [thread-id])
+                      :message-transform
+                      (fn [text]
+                        (string/replace text pattern (str "#" (tag :name) " ")))
+                      :html
+                      (fn []
+                        (dom/div #js {:className "tag-match"}
+                          (dom/div #js {:className "color-block"
+                                        :style #js {:backgroundColor (helpers/tag->color tag)}})
+                          (dom/div #js {:className "tag-name"}
+                            (tag :name))
+                          (dom/div #js {:className "group-name"}
+                            (:name (store/id->group (tag :group-id))))))}))))))
+
    ; /<tag-name>  ->  adds tag to message
    (fn [text thread-id]
      (when-let [query (second (re-matches #"^/(\S{1,})" text))]


Re-added description class to show avatar due to nested CSS styles.

--- src/chat/client/views/pages/users.cljs
+++ src/chat/client/views/pages/users.cljs
@@ -40,7 +40,7 @@
         (dom/div #js {:className "content"}
           (let [users-by-status (->> (group-users data)
                                      (group-by :status))]
-            (dom/div nil
+            (dom/div #js {:className "description"}
               (dom/h2 nil "Online")
               (om/build user-list-view (users-by-status :online))