write test for parse-pull

write test for parse-pull

--- test/hu/ssh/github_changelog/conventional_test.clj
+++ test/hu/ssh/github_changelog/conventional_test.clj
@@ -1,14 +1,17 @@
 (ns hu.ssh.github-changelog.conventional-test
   (:require
     [hu.ssh.github-changelog.conventional :as conventional]
-    [hu.ssh.github-changelog.schema :refer [Config Pull]]
+    [hu.ssh.github-changelog.schema :refer [Config Pull Change]]
     [clojure.test :refer :all]
-    [schema.experimental.complete :as c]))
+    [clojure.string :refer [join]]
+    [schema.experimental.complete :as c]
+    [schema.core :as s]))
+
+(defn- gen-sha [] (join (repeatedly 40 #(rand-nth "0123456789ABCDEF"))))

 (def repo-url "https://github.company.com/user/repo")
 (def jira-url "http://dev.clojure.org/jira")
 (def config (c/complete {:jira jira-url} Config))
-(defn gen-sha [] (apply str (repeatedly 40 #(rand-nth "0123456789ABCDEF"))))

 (deftest parse-issues
   (testing "with a JIRA issue"
@@ -18,3 +21,17 @@
   (testing "with a GitHub issue"
     (let [pull (c/complete {:body "Fixes #1" :sha (gen-sha) :base {:repo {:html_url repo-url}}} Pull)]
       (is (= [["#1" (str repo-url "/issues/1")]] (conventional/parse-issues config pull))))))
+
+(defn- create-pull [title]
+  (c/complete {:title title :sha (gen-sha)} Pull))
+
+(deftest parse-pull
+  (testing "with a correct formats"
+    (are [title] (s/validate Change (conventional/parse-pull config (create-pull title)))
+                 "feat(scope): enhance this and that"
+                 "fix(scope): do not fail on invalid input"
+                 "chore: clean up the codebase"))
+  (testing "with invalid formats"
+    (are [title] (nil? (conventional/parse-pull config (create-pull title)))
+                 "this is just a PR"
+                 "does not follow the rules")))


Change the default format to DAISY202

Change the default format to DAISY202

--- src/mdr2/production.clj
+++ src/mdr2/production.clj
@@ -81,7 +81,7 @@
    :identifier (uuid)
    :volumes 1
    :type "Text"
-   :format "ANSI/NISO Z39.86-2005"})
+   :format "Daisy 2.02"}) ; "ANSI/NISO Z39.86-2005" for DAISY3

 (defn add-default-meta-data
   "Add the default meta data to a production"


Mixing both provide-contracts and defconstrained functions to give a flavor

--- examples/dream_date.clj
+++ examples/dream_date.clj
@@ -1,6 +1,6 @@
 (ns dream-date
   (:use [fogus.me.trammel :only [provide-contracts defconstrainedrecord
-                                 all-numbers?]]))
+                                 all-numbers? all-positive? defconstrainedfn]]))

 (in-ns 'fogus.me.trammel)

@@ -71,21 +71,23 @@
   [year]
   (quot (dec year) 100))

+(provide-contracts
+ [julian-leap-days-in-prior-years "Contract for JLD calculation"
+  [y] [number? pos? => integer? pos?]]
+
+ [prior-century-years "Contract for PCY"
+  [y] [number? pos? => integer? pos?]])

-(defn gregorian->absolute
-  ([date] (gregorian->absolute (:day date) (:month date) (:year date)))
-  ([day month year]
+
+(defconstrainedfn gregorian->absolute
+  "Given a Gregorian date, calculate the total number of days
+   since the start of the calendar."
+  ([date] [:day :month :year]
+     (gregorian->absolute (:day date) (:month date) (:year date)))
+  ([day month year] [all-positive? => (= (quot % 365) year)]
      (+ day
         (days-in-prior-months month year)
         (days-in-prior-years year)
         (julian-leap-days-in-prior-years year)
         (- (prior-century-years year))
         (quot (dec year) 400))))
-
-
-(gregorian->absolute {:day 16 :month 12 :year 1999})
-(gregorian->absolute (bean (java.util.Date.)))
-
-(-> (java.util.GregorianCalendar. (+ 1999 1899) 12 16)
-    (.getTime)
-    bean)


Update dependencies to match compojure test updates

--- http-kit/hello/project.clj
+++ http-kit/hello/project.clj
@@ -2,7 +2,7 @@
   :description "JSON/Database tests"
   :url "http://example.com/FIXME"
   :dependencies [[org.clojure/clojure "1.5.1"]
-                 [compojure "1.1.5"]
+                 [compojure "1.1.6"]
                  [ring/ring-json "0.2.0"]
                  [org.clojure/tools.cli "0.2.1"]
                  [http-kit/dbcp "0.1.0"]
@@ -12,4 +12,4 @@
   :main hello.handler
   :aot [hello.handler]
   :uberjar-name "http-kit-standalone.jar"
-  :profiles {:dev {:dependencies [[ring-mock "0.1.3"]]}})
+  :profiles {:dev {:dependencies [[ring-mock "0.1.5"]]}})


Simplify codec protocol names and add type hints.

--- src/multicodec/core.clj
+++ src/multicodec/core.clj
@@ -123,8 +123,8 @@
   "An encoder converts values to binary sequences and writes the results to an
   output stream."

-  (encode-to
-    [codec output value]
+  (encode
+    [codec ^java.io.OutputStream output value]
     "Write the value as a sequence of bytes to the output stream. Returns the
     number of bytes written."))

@@ -132,8 +132,8 @@
 (defprotocol Decoder
   "A decoder reads binary sequences and interpretes them as Clojure values."

-  (decode-from
-    [codec input]
+  (decode
+    [codec ^java.io.InputStream input]
     "Reads bytes from the input stream and returns the read value."))

@@ -153,7 +153,7 @@

   Encoder

-  (encode-to
+  (encode
     [this output value]
     ; TODO: select encoder, write out header, use codec to write value
     nil)
@@ -161,7 +161,7 @@

   Decoder

-  (decode-from
+  (decode
     [this input]
     ; TODO: read header, select decoder, use codec to read value
     nil))


KTO-235: clj-elasticsearch version nosto

--- clj-elasticsearch/project.clj
+++ clj-elasticsearch/project.clj
@@ -1,4 +1,4 @@
-(defproject oph/clj-elasticsearch "0.3.3-SNAPSHOT"
+(defproject oph/clj-elasticsearch "0.4.0-SNAPSHOT"
             :description "oph clojure elasticsearch utilities"
             :url "http://example.com/FIXME"
             :license {:name "EUPL"


workflow/reloaded controls for the plongeur server application

--- cljx/plongeur-clj/dev/dev.clj
+++ cljx/plongeur-clj/dev/dev.clj
@@ -1,2 +1,16 @@
 (ns dev
-  (:require [clojure.tools.namespace.repl :refer [refresh set-refresh-dirs]]))
+  (:require [clojure.tools.namespace.repl :refer [refresh set-refresh-dirs]]
+            [plongeur.system :as plongeur]))
+
+(def system nil)
+
+(defn cycle-off-on []
+  (alter-var-root #'system (fn [shutdown!]
+                             (when-let [f shutdown!] (f))
+                             (plongeur/launch-server))))
+
+(defn stop []
+  (alter-var-root #'system (fn [shutdown!]
+                             (when-let [f shutdown!] (f)))))
+
+(defn reset [] (refresh :after 'dev/cycle-off-on))


Reformat day8.re-frame-10x.view.debug ns

--- src/day8/re_frame_10x/view/debug.cljs
+++ src/day8/re_frame_10x/view/debug.cljs
@@ -29,11 +29,11 @@
             :let [match-info (:match-info match)]]
         ^{:key (:id (first match-info))}
         [rc/v-box
-         :style {:border "1px solid black"
+         :style {:border      "1px solid black"
                  :font-weight (if (= current-match match-info)
                                 "bold"
                                 "normal")}
-         :children (doall (map (fn [event] [rc/label :label (prn-str event)]) (metam/summarise-match match-info)))
-         ]))
-    ]]
-  )
+         :children (doall (map (fn [event] [rc/label :label (prn-str event)]) (metam/summarise-match match-info)))]))]])
+
+
+


refactor

refactor

--- src/leiningen/remote_test_refresh.clj
+++ src/leiningen/remote_test_refresh.clj
@@ -61,6 +61,62 @@

 ;;; MAIN

+(defn create-notify-command [notify-cmd msg]
+  (let [cmd (if (string? notify-cmd) [notify-cmd] notify-cmd)]
+    (concat cmd [(str/replace msg #"\*" "")])))
+
+(defn endless-loop []
+  (loop []
+    (Thread/sleep WAIT-TIME)
+    (recur)))
+
+(defn valid-port? [port]
+  (and (not= :empty port) (not= :invalid port) (> port 1023)))
+
+(defn has-port? [parameters]
+  (contains? parameters :forwarding-port))
+
+(defn run-cmd-remotely [{run-command :command repo :repo path :remote-path} session]
+  (let [output (->> {:cmd              (str "cd " path repo ";" run-command)
+                     :out              :stream
+                     :pty              true
+                     :agent-forwarding true}
+                    (ssh/ssh session)
+                    (:out-stream))]
+    (with-open [rdr (io/reader output)]
+      (doseq [line (line-seq rdr)] (m/info line)))))
+
+(defn notify [shell notify-cmd msg]
+  (let [should-notify? (not (empty? notify-cmd))]
+    (when should-notify?
+      (try
+        (apply shell (create-notify-command notify-cmd msg))
+        (catch Exception e (m/info "* Could not notify: " (.getMessage e))))))
+  (m/info "*" msg))
+
+(defn run-command-and-forward-port [session parameters]
+  (let [{port :forwarding-port cmd :command} parameters
+        has-cmd? (not (empty? cmd))]
+    (cond
+      (and (has-port? parameters) has-cmd?)
+      (ssh/with-local-port-forward [session port port] (run-cmd-remotely parameters session))
+
+      (and (not (has-port? parameters)) has-cmd?)
+      (run-cmd-remotely parameters session)
+
+      (has-port? parameters)
+      (ssh/with-local-port-forward [session port port] (endless-loop))
+
+      :else (endless-loop))))
+
+(defn notify-log [console parameters]
+  (async/go-loop [{msg :msg} (async/<! console)]
+    (notify sh/sh (:notify-command parameters) msg)
+    (recur (async/<! console))))
+
+(defn log-to [console msg]
+  (async/go (async/>! console msg)))
+
 (defn sync-code-change
   ([console session dirs parameters]
    (sync-code-change console session dirs parameters (apply dir/scan (t/tracker) dirs)))
@@ -69,61 +125,14 @@
      (if (not= new-tracker old-tracker)
        (->> TRANSFER-STEPS
             (transfer-per-ssh parameters session)
-            (async/>!! console))
+            (log-to console))
        (Thread/sleep WAIT-TIME))
      (recur console session dirs parameters new-tracker))))
-
-(defn run-command-remotely [{run-command :command repo :repo path :remote-path} session]
-  (let [output (->> {:cmd (str "cd " path repo ";" run-command ";") :out :stream :pty true :agent-forwarding true}
-                    (ssh/ssh session)
-                    (:out-stream))]
-    (with-open [rdr (io/reader output)]
-      (doseq [line (line-seq rdr)] (m/info line)))))
-
-(defn create-notify-command [notify-cmd msg]
-  (let [cmd (if (string? notify-cmd) [notify-cmd] notify-cmd)]
-    (concat cmd [(str/replace msg #"\*" "")])))
-
-(defn notify-log [console parameters]
-  (let [notify-cmd (:notify-command parameters)
-        should-notify? (and (not (nil? notify-cmd)) (not (empty? notify-cmd)))]
-    (while true
-      (let [{msg :msg} (async/<!! console)]
-        (m/info "*" msg)
-        (when should-notify?
-          (try
-            (apply sh/sh (create-notify-command notify-cmd msg))
-            (catch Exception e (m/info "* Could not notify: " (.getMessage e)))))
-        (Thread/sleep WAIT-TIME)))))
-
-(defn endless-loop []
-  (while true (Thread/sleep WAIT-TIME)))
-
-(defn valid-port? [port]
-  (and (not= :empty port) (not= :invalid port) (> port 1023)))
-
-(defn has-port? [parameters]
-  (contains? parameters :forwarding-port))
-
-(defn run-command-and-forward-port [session parameters]
-  (let [{port :forwarding-port command :command} parameters]
-    (cond
-      (and (has-port? parameters) (not (empty? command)))
-      (ssh/with-local-port-forward [session port port]
-        (run-command-remotely parameters session))
-
-      (and (not (has-port? parameters)) (not (empty? command)))
-      (run-command-remotely parameters session)
-
-      (has-port? parameters)
-      (ssh/with-local-port-forward [session port port] (endless-loop))
-
-      :else (endless-loop))))

 (defn start-remote-routine [session asset-paths parameters]
   (let [console (async/chan)]
     (future (sync-code-change console session asset-paths parameters))
-    (future (notify-log console parameters))
+    (notify-log console parameters)
     (run-command-and-forward-port session parameters)))

 (defn session-option [parameters with-system-agent?]
@@ -156,12 +165,15 @@
   (let [with-system-agent (or (get-in project [:remote-test :with-system-agent])
                               (u/ask-clear-text
                                "* ==> Do you want to use ssh system agent (y/n):"
-                               u/yes-or-no))]
-    (if (or (= "y" with-system-agent) (true? with-system-agent))
+                               u/yes-or-no))
+        should-use-system-agent? (or (= "y" with-system-agent)
+                                     (true? with-system-agent))]
+    (if should-use-system-agent?
       {:with-system-agent true}
       {:with-system-agent false
        :password          (u/ask-for-password
-                           "* ==> Please enter your ssh password:")})))
+                           "* ==> Please enter your ssh password:"
+                           #(not (empty? %)))})))

 (defn ask-for-parameters [project]
   (let [project-name (:name project)
@@ -197,14 +209,14 @@

         forwarding-parameter (if (= :empty forwarding-port) {} {:forwarding-port forwarding-port})

-        required-parameters {:repo            project-name
-                             :user            user
-                             :auth            auth
-                             :host            host
-                             :command         command
-                             :remote-path     (normalize-remote-path path)}
-
-        notify-parameter {:notify-command  (get-in project [:remote-test :notify-command])}]
+        required-parameters {:repo        project-name
+                             :user        user
+                             :auth        auth
+                             :host        host
+                             :command     command
+                             :remote-path (normalize-remote-path path)}
+
+        notify-parameter {:notify-command (get-in project [:remote-test :notify-command])}]

     (assert (not (empty? project-name)) project-name)
     (assert (not (empty? user)) user)


Fixed typo.

Fixed typo.

--- src/overtunes/pitch.clj
+++ src/overtunes/pitch.clj
@@ -78,7 +78,7 @@
 (def first-inversion #(update-values % (keys-except % [:i]) lower))
 (def second-inversion #(update-values % (keys-except % [:i :iii]) lower))

-; Paramatisesd transformations on chords
+; Paramatised transformations on chords
 (defn flattened [key] #(update-in % [key] flat))
 (defn sharpened [key] #(update-in % [key] sharp))
 (defn raised [key] #(update-in % [key] raise))


tweak externs inference to not warn about goog.*

no need to warn about

  (:import [goog.net ErrorCode])
  (.-EXCEPTION ErrorCode)

since that is safe to rename

--- src/main/shadow/build/cljs_hacks.cljc
+++ src/main/shadow/build/cljs_hacks.cljc
@@ -380,7 +380,7 @@
      )))

 (defn infer-externs-dot
-  [{:keys [form form-meta method field target-tag env prop tag] :as ast}
+  [{:keys [form form-meta method field target target-tag env prop tag] :as ast}
    {:keys [infer-externs] :as opts}]
   (when infer-externs
     (let [sprop
@@ -412,7 +412,12 @@
                    (not shadow-object-fn)
                    ;; no immediate ideas how to annotate these so it doesn't warn
                    (not= form '(. cljs.core/List -EMPTY))
-                   (not= form '(. cljs.core/PersistentVector -EMPTY-NODE)))
+                   (not= form '(. cljs.core/PersistentVector -EMPTY-NODE))
+
+                   ;; don't need to warn about anything from goog.*
+                   ;; {:op :js-var :name js/goog.net.ErrorCode}
+                   (not (and (= :js-var (:op target))
+                             (str/starts-with? (-> target :name name) "goog."))))

           (ana/warning :infer-warning env {:warn-type :target :form form}))


Only set the session-id if it exists

Only set the session-id if it exists

For the main window

--- src/webapp/framework/client/main.cljs
+++ src/webapp/framework/client/main.cljs
@@ -107,17 +107,19 @@

       (reset! client-session-atom  {:session-id   (:session-id create-session-response)
                                     :user         (:user create-session-response)})
-      (swap! client-sessions assoc (:session-id create-session-response) (atom {}))

       ;(js/alert (str "Retrieved session ID : " cookie-session-id))

-      (cookie/set  cookie-name  (:session-id create-session-response))

-      (om/root   view-window
+      (if (:session-id create-session-response)
+        (do
+          (swap! client-sessions assoc (:session-id create-session-response) (atom {}))
+          (cookie/set  cookie-name  (:session-id create-session-response))
+          (om/root   view-window

-                 app-state
+                     app-state

-                 {:target dom-element}))))
+                     {:target dom-element}))))))


Don't show comments section on posts with no comments, if the user isn't logged in

--- src/langnostic/pages.clj
+++ src/langnostic/pages.clj
@@ -21,31 +21,33 @@
       (next :title) "->"])])

 (defn post-comments [post]
-  [:div {:class "post-comments"}
-   [:hr]
-   [:h3 "Comments"]
-   (map
-    (fn rec [comment]
-      [:div {:class "comment" :path (str (:path comment))}
-       [:span {:class "comment-author"}
-        [:img {:class "author-image" :src (get-in comment [:user :image])}]
-        [:a {:class "author-link" :href (get-in comment [:user :url])} (get-in comment [:user :name])]]
-       [:pre {:class "comment-content"} (:content comment)]
+  (let [comment-tree (comments/get-comments-for (:id post))]
+    (when (or auth/USER (not (empty? comment-tree)))
+      [:div {:class "post-comments"}
+       [:hr]
+       [:h3 "Comments"]
+       (map
+        (fn rec [comment]
+          [:div {:class "comment" :path (str (:path comment))}
+           [:span {:class "comment-author"}
+            [:img {:class "author-image" :src (get-in comment [:user :image])}]
+            [:a {:class "author-link" :href (get-in comment [:user :url])} (get-in comment [:user :name])]]
+           [:pre {:class "comment-content"} (:content comment)]
+           (when auth/USER
+             [:form {:class "reply-form"
+                     :action (str "/posts/" (:id post) "/comment/reply?path="
+                                  (cod/url-encode (:path comment)))
+                     :method "POST"}
+              [:textarea {:name "comment"}]
+              [:input {:type "Submit" :value "Reply"}]])
+           (when (not (empty? (:replies comment)))
+             [:div {:class "replies"}
+              (map rec (:replies comment))])])
+        comment-tree)
        (when auth/USER
-         [:form {:class "reply-form"
-                 :action (str "/posts/" (:id post) "/comment/reply?path="
-                              (cod/url-encode (:path comment)))
-                 :method "POST"}
+         [:form {:class "post-comment-form" :action (str "/posts/" (:id post) "/comment") :method "POST"}
           [:textarea {:name "comment"}]
-          [:input {:type "Submit" :value "Reply"}]])
-       (when (not (empty? (:replies comment)))
-         [:div {:class "replies"}
-          (map rec (:replies comment))])])
-    (comments/get-comments-for (:id post)))
-   (when auth/USER
-     [:form {:class "post-comment-form" :action (str "/posts/" (:id post) "/comment") :method "POST"}
-      [:textarea {:name "comment"}]
-      [:input {:type "Submit" :value "Post"}]])])
+          [:input {:type "Submit" :value "Post"}]])])))

 (defn post [post]
   [:div


RS | #134 | log when safen-url alters the target-url

--- src/objective8/utils.clj
+++ src/objective8/utils.clj
@@ -7,6 +7,7 @@
             [endophile.hiccup :as eh]
             [hiccup.core :as hiccup]
             [hickory.core :as hickory]
+            [clojure.tools.logging :as log]
             [objective8.routes :as routes]
             [objective8.config :as config]
             [objective8.front-end.permissions :as permissions])
@@ -135,10 +136,13 @@
   (let [{:keys [path query fragment] :as url-map} (url->url-map target)
         safe-path (safen-path path)
         safe-query (safen-query query)
-        safe-fragment (safen-fragment fragment)]
-    (cond-> safe-path
-      safe-query (str "?" safe-query)
-      safe-fragment (str "#" safe-fragment))))
+        safe-fragment (safen-fragment fragment)
+        safe-url (cond-> safe-path
+                   safe-query (str "?" safe-query)
+                   safe-fragment (str "#" safe-fragment))]
+    (when-not (= target safe-url)
+      (log/warn (str "Unsafe-url safened: \"" target "\" became \"" safe-url "\"")))
+    safe-url))

 (defn referer-url [{:keys [uri query-string] :as ring-request}]
   (str uri (when query-string


Use date with year and comma for digest header.

--- src/oc/email/content.clj
+++ src/oc/email/content.clj
@@ -20,6 +20,7 @@
 (def date-format (time-format/formatter "MMM. d"))
 (def date-format-no-dot (time-format/formatter "MMM d"))
 (def date-format-year (time-format/formatter "MMM. d YYYY"))
+(def date-format-year-comma (time-format/formatter "MMM. d, YYYY"))
 (def day-month-date-year (time-format/formatter "EEEE, MMM. dd, YYYY"))
 (def reminder-date-format (time-format/formatter "EEEE, MMMM d"))
 (def reminder-date-format-year (time-format/formatter "EEEE, MMMM d YYYY"))
@@ -500,7 +501,7 @@
 "])

 (defn- digest-content-date []
-  (time-format/unparse date-format-year (t/now)))
+  (time-format/unparse date-format-year-comma (t/now)))

 (defn- board-block [board-name]
   [:table


Fix org logo on digest.

Fix org logo on digest.

--- src/oc/email/content.clj
+++ src/oc/email/content.clj
@@ -276,7 +276,7 @@
     (assoc board :posts (map #(assoc % :board-name board-name) (:posts board)))))

 (defn- digest-content [digest]
-  (let [logo-url (:org-logo-url digest)
+  (let [logo-url (:logo-url digest)
         logo? (not (s/blank? logo-url))
         weekly? (= "weekly" (:digest-frequency digest))
         org-name (:org-name digest)
@@ -285,7 +285,10 @@
         posts (mapcat :posts boards)]
     [:td {:class "small-10 large-8 columns"}
       (spacer 40)
-      (when logo? (org-logo digest))
+      (when logo? (org-logo {:org-name (:org-name digest)
+                             :org-logo-url logo-url
+                             :org-logo-width (:logo-width digest)
+                             :org-logo-height (:logo-height digest)}))
       (when logo? (spacer 40))
       (h1 title)
       (mapcat post posts)


target 태스크가 필수임

target 태스크가 필수임

--- src/ohucode/www/boot.clj
+++ src/ohucode/www/boot.clj
@@ -33,23 +33,21 @@
   "레이아웃 생성"
   []
   (let [tmp (b/tmp-dir!)]
-    (fn middleware [next-handler]
-      (fn handler [fileset]
-        (println "tmpdir: " (.getPath tmp))
-        (let [in  (b/input-files fileset)
-              mds (b/by-ext [".md" ".markdown"] in)]
-          (doseq [md mds]
-            (let [infile  (b/tmp-file md)
-                  inpath  (b/tmp-path md)
-                  outpath (s/replace inpath #"\.(md|markdown)$" ".html")
-                  outfile (io/file tmp outpath)]
-              (println "--- " inpath  " => " outpath " ---")
-              (convert identity infile outfile))))
-        (println (count fileset) (count (b/add-source fileset tmp)))
-        (println (b/add-resource fileset tmp))
-        (next-handler (b/commit! (b/add-resource fileset tmp)))))))
+    (b/with-pre-wrap fileset
+      (let [in  (b/input-files fileset)
+            mds (b/by-ext [".md" ".markdown"] in)]
+        (doseq [md mds]
+          (let [infile  (b/tmp-file md)
+                inpath  (b/tmp-path md)
+                outpath (s/replace inpath #"\.(md|markdown)$" ".html")
+                outfile (io/file tmp outpath)]
+            (println "--- " inpath  " => " outpath " ---")
+            (convert identity infile outfile))))
+      (-> fileset
+          (b/add-resource tmp)
+          b/commit!))))

 (b/deftask build
   "빌드 태스크"
   []
-  (comp (markdown)))
+  (comp (markdown) (task/target)))


make fix-text use new valid? flag returned from process-text

--- src/parinfer/editor.cljs
+++ src/parinfer/editor.cljs
@@ -89,9 +89,9 @@
                            overrides)
                          (infer/process-text overrides current-text))]

-             (when state
+             (when (:valid? state)
                (reset! prev-state state))
-             (if state
+             (if (:valid? state)
                (join "\n" (:lines state))
                current-text))


allow for data-* and aria-* attributes in html-attr?

--- src/re_com/validate.cljs
+++ src/re_com/validate.cljs
@@ -263,6 +263,23 @@
                  {:status  :warning
                   :message (str "Unknown CSS style(s): " (remove css-styles arg-keys))}))))))

+(defn extension-attribute?
+  "Returns true if the attribute name is an extension attribute, that is data-* or aria-*, otherwise false."
+  ([attr prefix]
+   (let [attr (name attr)]
+     (and (= (.indexOf attr prefix) 0)
+          (> (count attr) (count prefix)))))
+  ([attr]
+   (or (extension-attribute? attr "data-")
+       (extension-attribute? attr "aria-"))))
+
+(defn invalid-html-attrs
+  "Returns the subset of HTML attributes contained in the passed argument that are not valid HTML attributes."
+  [attrs]
+  (remove #(or (html-attrs %)
+               (extension-attribute? %))
+          attrs))
+
 (defn html-attr?
   "Returns true if the passed argument is a valid HTML, SVG or event attribute.
    Otherwise returns a warning map.
@@ -277,9 +294,10 @@
                  contains-class? (contains? arg-keys :class)
                  contains-style? (contains? arg-keys :style)
                  result   (cond
-                            contains-class?                       ":class not allowed in :attr argument"
-                            contains-style?                       ":style not allowed in :attr argument"
-                            (not (superset? html-attrs arg-keys)) (str "Unknown HTML attribute(s): " (remove html-attrs arg-keys)))]
+                            contains-class? ":class not allowed in :attr argument"
+                            contains-style? ":style not allowed in :attr argument"
+                            :else           (when-let [invalid (not-empty (invalid-html-attrs arg-keys))]
+                                              (str "Unknown HTML attribute(s): " invalid)))]
              (or (nil? result)
                  {:status  (if (or contains-class? contains-style?) :error :warning)
                   :message result}))))))


Welcome improvements

Welcome improvements

--- src/re_demo/welcome.cljs
+++ src/re_demo/welcome.cljs
@@ -13,7 +13,7 @@
                 :href "https://github.com/reagent-project/reagent"
                 :target "_blank"]
                "."]
-              [p "It contains the sort of layout and controls you'd need to build a desktop-class app."]]])
+              [p "It provides layouts and controls for building desktop-class apps (incomplete)."]]])

 (defn this-app
   []
@@ -24,12 +24,12 @@
               [h-box
                :gap "100px"
                :children [[v-box
-                           :children [[p "The demo app serves as:"
+                           :children [[p "The demo app is build using re-com and serves as:"
                                        [:ul
                                         [:li "a visual showcase of the components"]
                                         [:li "documentation for the components (parameters etc.)"]
                                         [:li "shows, via its own code, how to use the components"]
-                                        [:li "something of a test harness"]]]]]
+                                        [:li "a test harness"]]]]]
                           [v-box
                            :style {:font-size "13px" :color "#aaa"}
                            :children [[p {:style {:width "250px"}} [:br] [:br] [:br] "Most pages in this app have
@@ -41,26 +41,30 @@
   []
   [v-box
    :children [
-              [title :level :level2 :label "Named Parameters"]
+              [title :level :level2 :label "Component Parameters"]
               [p  "re-com components take " [:span.bold "named parameters"] ", rather than " [:span.bold "positional parameters"] "."]
-
+              [p  "Where a normal reagent component might be used like this:"]
+              [:pre
+               {:style {:width "450px"}}
+               "[:input {:type \"button\" :value \"Click me!\"
+         :on-click #(swap! click-count inc)
+         :style {:background-color \"blue\"}]"]
               [h-box
                :gap "100px"
                :children [[v-box
-                          :children [[p "When you use a re-com component, like " [:span.bold "checkbox"] ", it looks like this:"]
+                          :children [[p "When you use a re-com component, like " [:span.bold "button"] ", it looks like this:"]
                                      [:pre
                                       {:style {:width "450px"}}
-                                      "[checkbox
-  :label     \"Show Status Icon?\"
-  :model     status-icon?      ; a ratom
-  :on-change (fn [new-val] (reset! status-icon? new-val))]"]
+                                      "[button
+  :label     \"Click me!\"
+  :on-click #(swap! click-count inc)
+  :style    {:background-color \"blue\"}]"]
                                      [p "Each parameter has a leading keyword name."]
                                      [p "Now, our sausage fingers sometimes type onmouseover instead of on-mouse-over,
                                      or centre rather than center, and sometimes we pass in a string where  there should be keyword."]
-                                     [p "re-com tries to catch these kinds of mistakes by validating all parameter names and values."]
-                                     [p "But there is overhead in this checking which you'd like to avoid in production. So, to remove it,
-                                      be sure to
-                                     include the following in your project.clj for your productuion builds:"]
+                                     [p "re-com catches these errors early by validating parameter names and values."]
+                                     [p "To avoid the overhead in this checking,
+                                         include the following in your project.clj for your productuion builds:"]
                                      [:pre
                                       {:style {:width "450px"}}
                                       ":closure-defines {:goog.DEBUG false}"]]]


Also encode tags

Also encode tags

--- src/riemann/influxdb.clj
+++ src/riemann/influxdb.clj
@@ -26,7 +26,7 @@
   (let [encoded_fields (kv-encode (get event "fields"))
         encoded_tags  (kv-encode (get event "tags"))]

-    (str (get event "name") " " encoded_fields  "\n")))
+    (str (get event "name") "," encoded_tags " " encoded_fields  "\n")))

 (defn lineprotocol-encode-list [events]


CMR-8170 Create tests to verify user can delete collection subscriptions with valid permissions (#1554)

* CMR-8170 Adding validation test for deleting collection subscriptions

* CMR-8170 Added permission check test for collection subscription deletion

* CMR-8170 Shifted test case to remove redundant variable declaration

* CMR-8170 Removing unnecessary line

Co-authored-by: drewpesall <b4a367ba5e1ffb785616379a419018db148a6d7b@nasa.gov>

--- system-int-test/test/cmr/system_int_test/ingest/subscription_ingest_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/subscription_ingest_test.clj
@@ -545,6 +545,43 @@
           (is (= 200 status))
           (is (= 3 revision-id)))))))

+(deftest delete-collection-subscription-ingest-test
+  (mock-urs/create-users (system/context) [{:username "someSubId" :password "Password"}])
+  (testing "delete a collection subscription without valid permissions"
+    (let [coll1 (data-core/ingest-umm-spec-collection
+                  "PROV1"
+                   (data-umm-c/collection
+                    {:ShortName "coll1"
+                     :EntryTitle "entry-title1"})
+                   {:token "mock-echo-system-token"})]
+      (testing "delete on PROV3, guest is not granted update permission for SUBSCRIPTION_MANAGEMENT ACL"
+        (let [concept (subscription-util/make-subscription-concept {:Type "collection"}
+                                                                   {:provider-id "PROV3"
+                                                                    :CollectionConceptId (:concept-id coll1)})
+
+              guest-token (echo-util/login-guest (system/context))
+              response (ingest/delete-concept concept
+                                              {:token guest-token})]
+          (is (= ["You do not have permission to perform that action."] (:errors response)))))
+      (testing "delete a collection subscription"
+        (let [concept (subscription-util/make-subscription-concept
+                       {:Type "collection"}
+                       {}
+                       "coll-sub")
+              _ (subscription-util/ingest-subscription concept)
+              {:keys [status concept-id revision-id]}  (ingest/delete-concept concept)
+              fetched (mdb/get-concept concept-id revision-id)]
+          (is (= 200 status))
+          (is (= 2 revision-id))
+          (is (= (:native-id concept)
+                 (:native-id fetched)))
+          (is (:deleted fetched))
+          (testing "delete a deleted collection subscription"
+            (let [{:keys [status errors]} (ingest/delete-concept concept)]
+              (is (= [status errors]
+                     [404 [(format "Concept with native-id [%s] and concept-id [%s] is already deleted."
+                                   (:native-id concept) concept-id)]])))))))))
+
 (deftest roll-your-own-subscription-tests
   ;; Use cases coming from EarthData Search wanting to allow their users to create
   ;; subscriptions without the need to have any acls


Fix quit fn

Fix quit fn

--- src/robinson/update.clj
+++ src/robinson/update.clj
@@ -4211,7 +4211,7 @@
                :share-score
                           {\y          [identity               :start-inventory false]
                            \n          [identity               :start           false]}
-               :quit?     {\y          [(fn [state] (assoc :continue true)) :start false]
+               :quit?     {\y          [(fn [state] (assoc state :continue true)) :start false]
                            :else       [pass-state             :normal          false]}}
         expander-fn (fn [table] table)]
     (expander-fn table)))


Added response tests to ring-servlet (except body)

--- ring-servlet/test/ring/util/servlet_test.clj
+++ ring-servlet/test/ring/util/servlet_test.clj
@@ -31,44 +31,59 @@
     (setHeader [name value]
       (swap! response assoc-in [:headers name] value))
     (setCharacterEncoding [value]
-      (swap! response assoc-in [:headers "Content-Type"] value))))
+      (swap! response assoc :character-encoding value))
+    (setContentType [value]
+      (swap! response assoc :content-type value))))

 (defn- servlet-config []
   (proxy [javax.servlet.ServletConfig] []
     (getServletContext [] nil)))

+(defn- run-servlet [handler request response]
+  (doto (servlet handler)
+          (.init (servlet-config))
+          (.service (servlet-request request)
+                    (servlet-response response))))
+
 (deftest servlet-test
-  (testing "request"
-    (let [body (proxy [javax.servlet.ServletInputStream] [])
-          req  {:server-port    8080
-                :server-name    "foobar"
-                :remote-addr    "127.0.0.1"
-                :uri            "/foo"
-                :query-string   "a=b"
-                :scheme         :http
-                :request-method :get
-                :headers        {"X-Server" "Foo"}
-                :content-type   "text/plain"
-                :content-length 10
-                :character-encoding "UTF-8"
-                :body           body}
-          resp (atom {})
-          svlt (servlet (fn [r]
-                          (are [k v] (= (r k) v)
-                            :server-port    8080
-                            :server-name    "foobar"
-                            :remote-addr    "127.0.0.1"
-                            :uri            "/foo"
-                            :query-string   "a=b"
-                            :scheme         :http
-                            :request-method :get
-                            :headers        {"x-server" "Foo"}
-                            :content-type   "text/plain"
-                            :content-length 10
-                            :character-encoding "UTF-8"
-                            :body           body)
-                          {:status 200, :headers {}}))]
-      (doto svlt
-        (.init (servlet-config))
-        (.service (servlet-request req)
-                  (servlet-response resp))))))
+  (let [body (proxy [javax.servlet.ServletInputStream] [])
+        request {:server-port    8080
+                 :server-name    "foobar"
+                 :remote-addr    "127.0.0.1"
+                 :uri            "/foo"
+                 :query-string   "a=b"
+                 :scheme         :http
+                 :request-method :get
+                 :headers        {"X-Client" "Foo"}
+                 :content-type   "text/plain"
+                 :content-length 10
+                 :character-encoding "UTF-8"
+                 :body           body}
+          response (atom {})]
+    (testing "request"
+      (letfn [(handler [r]
+               (are [k v] (= (r k) v)
+                 :server-port    8080
+                 :server-name    "foobar"
+                 :remote-addr    "127.0.0.1"
+                 :uri            "/foo"
+                 :query-string   "a=b"
+                 :scheme         :http
+                 :request-method :get
+                 :headers        {"x-client" "Foo"}
+                 :content-type   "text/plain"
+                 :content-length 10
+                 :character-encoding "UTF-8"
+                 :body           body)
+               {:status 200, :headers {}})]
+        (run-servlet handler request response)))
+    (testing "response"
+      (letfn [(handler [r]
+               {:status  200
+                :headers {"Content-Type" "text/plain"
+                          "X-Server" "Bar"}
+                :body    nil})]
+        (run-servlet handler request response)
+        (is (= (@response :status) 200))
+        (is (= (@response :content-type) "text/plain"))
+        (is (= (get-in @response [:headers "X-Server"]) "Bar"))))))


[#11626] Group chat subtitle shows 'no members'

Signed-off-by: andrey <b713972e59b8e606e23253c4a13e948139fea4d1@gmail.com>

--- src/status_im/subs.cljs
+++ src/status_im/subs.cljs
@@ -774,6 +774,7 @@
  (fn [current-chat]
    (select-keys current-chat
                 [:community-id
+                 :contacts
                  :public?
                  :group-chat
                  :chat-type


CMR-200: added test to verify collections search by processing-level-id behavior

--- test/cmr/system_int_test/search/collection_identifier_search_test.clj
+++ test/cmr/system_int_test/search/collection_identifier_search_test.clj
@@ -199,4 +199,49 @@
                :collection
                {:entry-title "dummy" "options[entry-title][unsupported]" "unsupported"}))))))

-
+;; Create 2 collection sets of which only 1 set has processing-level-id
+(deftest processing-level-search-test
+  (let [[c1-p1 c2-p1 c3-p1 c4-p1] (for [p ["PROV1"]
+                                        n (range 1 5)]
+                                    (d/ingest p (dc/collection
+                                                  {:short-name (str "S" n)
+                                                   :version-id (str "V" n)
+                                                   :entry-title (str "ET" n)})))
+        ;; include preocessing level id
+        [c1-p2 c2-p2 c3-p2 c4-p2] (for [p ["PROV2"]
+                                        n (range 1 5)]
+                                    (d/ingest p (dc/collection
+                                                  {:short-name (str "S" n)
+                                                   :version-id (str "V" n)
+                                                   :entry-title (str "ET" n)
+                                                   :processing-level-id (str n "B")})))
+        all-prov2-colls [c1-p2 c2-p2 c3-p2 c4-p2]]
+    (index/flush-elastic-index)
+    (testing "processing level search"
+      (are [items id options]
+           (let [params (merge {:processing-level-id id}
+                               (when options
+                                 {"options[processing-level-id]" options}))]
+             (d/refs-match? items (search/find-refs :collection params)))
+
+           [c1-p2] "1B" {}
+           [] "1C" {}
+           ;; Multiple values
+           [c1-p2 c2-p2 c3-p2] ["1B" "2B" "3B"] {}
+           [c4-p2] ["4B" "4C"] {}
+           [c1-p2 c2-p2 c3-p2] ["1B" "2B" "3B"] {:and false}
+           [] ["B1" "B2"] {:and true}
+
+           ;; Wildcards
+           all-prov2-colls "*B" {:pattern true}
+           [] "B*" {:pattern false}
+           [] "B*" {}
+           all-prov2-colls "?B" {:pattern true}
+           [] "*Q*" {:pattern true}
+
+           ;; Ignore case
+           [c2-p2] "2b" {:ignore-case true}
+           [] "2b" {:ignore-case false}))))
+
+
+


add clean-entity

add clean-entity

--- src/hatch.clj
+++ src/hatch.clj
@@ -59,6 +59,12 @@
   [attr-map entity-type entity]
   (select-keys entity (conj (entity-type attr-map) :db/id)))

+(defn clean-entity
+  [partitions attr-map entity-type entity]
+  (->> entity
+       (ensure-db-id partitions entity-type)
+       (prune-entity attr-map entity-type)))
+
 (defn tx!
   "Transact with schematode constraints"
   [db-conn txs]
@@ -68,8 +74,7 @@
   "Clean up an entity (ensure it has a db/id and prune it), then transact it."
   [partitions attr-map db-conn entity-type entity]
   (->> entity
-       (ensure-db-id partitions entity-type)
-       (prune-entity attr-map entity-type)
+       (clean-entity partitions attr-map entity-type)
        (conj [])
        (tx! db-conn)))


Bumped lambda-blog minor version.

Bumped lambda-blog minor version.

--- lambda-blog/project.clj
+++ lambda-blog/project.clj
@@ -1,4 +1,4 @@
-(defproject lambda-blog/lambda-blog "1.1.2"
+(defproject lambda-blog/lambda-blog "1.2.0"
   :description "A static blog generator."
   :url "https://github.com/Idorobots/lambda-blog"
   :license {:name "MIT License"


Just testing to see if this is causing CI trouble

--- modules/messaging/src/main/clojure/immutant/messaging/core.clj
+++ modules/messaging/src/main/clojure/immutant/messaging/core.clj
@@ -148,7 +148,7 @@
         (stop-destination name))
       (log/warn "No topic found by that name:" name))))

-(defn start-queue [name & {:keys [durable selector] :or {durable true selector ""}}]
+(defn start-queue [name & {:keys [durable selector] :or {durable false selector ""}}]
   (if-let [manager (lookup/fetch "jboss.messaging.default.jms.manager")]
     (do (.createQueue manager false name selector durable (into-array String []))
         (at-exit #(stop-destination name)))


fix version

fix version

--- storm-kafka/project.clj
+++ storm-kafka/project.clj
@@ -1,4 +1,4 @@
-(defproject storm/storm-kafka "0.7.3-dynamic2-SNAPSHOT"
+(defproject storm/storm-kafka "0.7.3-dynamic-SNAPSHOT"
   :source-path "src/clj"
   :java-source-path "src/jvm"
   :javac-options {:debug "true" :fork "true"}


add missing scope test

add missing scope test

--- test/clj_money/authorization_test.clj
+++ test/clj_money/authorization_test.clj
@@ -11,6 +11,7 @@
             [clj-money.models.users :as users]
             [clj-money.models.entities :as entities]
             [clj-money.models.accounts :as accounts]
+            [clj-money.models.transactions :as transactions]
             [clj-money.models.budgets :as budgets]
             [clj-money.models.commodities :as commodities]
             [clj-money.authorization :refer [allowed?
@@ -142,6 +143,23 @@
                                       :account-id "Salary"
                                       :amount 1000M}]}])))

+(deftest transaction-list
+  (let [context (serialization/realize storage-spec transactions-context)
+        [john jane] (find-users context "john@doe.com" "jane@doe.com")
+        entity (find-entity context "Personal")]
+    (testing "A user has permission to list transactions in his entities"
+      (with-authentication john
+        (is (not= 0 (->> (apply-scope {:entity-id (:id entity)} :transaction)
+                         (transactions/search storage-spec)
+                         count))
+            "The transactions are returned")))
+    (testing "A user does not have permission list transactions in someone else's transaction"
+      (with-authentication jane
+        (is (thrown? NotAuthorizedException
+                     (->> (apply-scope {:entity-id (:id entity)} :transaction)
+                          (transactions/search storage-spec)
+                          count)))))))
+
 (deftest transaction-management
   (let [context (serialization/realize storage-spec transactions-context)
         [john jane] (find-users context "john@doe.com" "jane@doe.com")


more TODO

more TODO

--- test/com/billpiel/mem_tracer/core_test.clj
+++ test/com/billpiel/mem_tracer/core_test.clj
@@ -567,6 +567,8 @@
  - and deep search values for funcs?
 - re-exec traces
 - deep trace (inside fn)
+- bisect recording trees to find bugs
+- search fn syntax for dynamic vars to capture
+- use defn and docstring in core
 - tag vals w meta data and track?
-- search fn syntax for dynamic vars to capture
 ")


Added two tests into irc-bot-test module

--- test/emender_jenkins/irc_bot_test.clj
+++ test/emender_jenkins/irc_bot_test.clj
@@ -23,3 +23,17 @@
     [function-name]
     (clojure.test/function? function-name))

+;
+; Tests for function existence
+;
+
+(deftest test-message-to-channel?
+    "Check that the emender-jenkins.irc-bot/message-to-channel? definition exists."
+    (testing "if the emender-jenkins.irc-bot/message-to-channel? definition exists."
+        (is (callable? 'emender-jenkins.irc-bot/message-to-channel?))))
+
+(deftest test-message-for-me?
+    "Check that the emender-jenkins.irc-bot/message-for-me? definition exists."
+    (testing "if the emender-jenkins.irc-bot/message-for-me? definition exists."
+        (is (callable? 'emender-jenkins.irc-bot/message-for-me?))))
+


activate customer on hover

activate customer on hover

--- frontend/components/landing_b.cljs
+++ frontend/components/landing_b.cljs
@@ -351,8 +351,8 @@
             [:div.customers-brands {:class (str "selected-" (get-in customer-brands [selected-customer :position]))}
              (for [[customer template] customer-brands]
                (html
-                [:a.customers-brand {:on-click #(put! controls-ch [:customer-logo-clicked {:customer customer}])
-                                     :on-mouse-enter #(om/set-state! owner [:hovered-customer] customer)
+                [:a.customers-brand {:on-mouse-enter #(do (put! controls-ch [:customer-logo-clicked {:customer customer}])
+                                                          (om/set-state! owner [:hovered-customer] customer))
                                      :on-mouse-leave #(om/set-state! owner [:hovered-customer] nil)}
                  (get customer-logos customer)]))]
             [:div.quote-card


Use reagent render call from the new namespace

--- frameworks/keyed/reagent/src/demo/main.cljs
+++ frameworks/keyed/reagent/src/demo/main.cljs
@@ -1,5 +1,6 @@
 (ns demo.main
   (:require [reagent.core :as r]
+            [reagent.dom :as rdom]
             [demo.utils :as u]))

 (defn is-selected? [selected id]
@@ -106,4 +107,4 @@
        [:span.preloadicon.glyphicon.glyphicon-remove
         {:aria-hidden "true"}]])))

-(r/render [main] (.getElementById js/document "main"))
+(rdom/render [main] (.getElementById js/document "main"))


:bug: Fix wrong reference to page-id (cause of the race conditions).

--- frontend/src/uxbox/main/data/workspace.cljs
+++ frontend/src/uxbox/main/data/workspace.cljs
@@ -457,7 +457,7 @@
     ptk/WatchEvent
     (watch [_ state stream]
       (let [session-id (:session-id state)
-            page (:workspace-page state)
+            page (get-in state [:pages page-id])
             changes (->> changes
                          (mapcat identity)
                          (map #(assoc % :session-id session-id))
@@ -1606,10 +1606,8 @@
   (ptk/reify ::changes-commited
     ptk/UpdateEvent
     (update [_ state]
-      (let [page-id (::page-id state)
-            session-id (:session-id state)
+      (let [session-id (:session-id state)
             state (-> state
-                      (assoc-in [:workspace-page :revn] revn)
                       (assoc-in [:pages page-id :revn] revn))
             changes (filter #(not= session-id (:session-id %)) changes)]
         (-> state


:lipstick: Minor chages on workspace.

:lipstick: Minor chages on workspace.

--- frontend/src/uxbox/main/data/workspace.cljs
+++ frontend/src/uxbox/main/data/workspace.cljs
@@ -1235,7 +1235,7 @@
   (us/verify number? index)

   (ptk/reify ::relocate-shape
-    IUpdateGroup
+    dwc/IUpdateGroup
     (get-ids [_] [id])

     ptk/WatchEvent


Do not place the cider-nrepl plugin in the :user profile.

Breaks interaction with emacs when using standalone repl.

--- lein/.lein/profiles.clj
+++ lein/.lein/profiles.clj
@@ -11,16 +11,16 @@
             [lein-bikeshed "0.3.0"]
             [lein-ns-dep-graph "0.1.0-SNAPSHOT"]
             [refactor-nrepl "0.2.2"]]
- :repl {:dependencies [[acyclic/squiggly-clojure "0.1.6"]
-                       [cider/cider-nrepl "0.15.0-SNAPSHOT"]
-                       [datomic-schema-grapher "0.0.1"]
-                       [org.clojure/tools.nrepl "0.2.12"]]
-        :plugins [[cider/cider-nrepl "0.15.0-SNAPSHOT"]]}
- :repl-options {:init (set! *print-length* 10)}
- ;; VisualVM profiling opts
- ;; :jvm-opts ["-Dcom.sun.management.jmxremote"
- ;;            "-Dcom.sun.management.jmxremote.ssl=false"
- ;;            "-Dcom.sun.management.jmxremote.authenticate=false"
- ;;            "-Dcom.sun.management.jmxremote.port=43210"]}
-  }}
+  ;; VisualVM profiling opts
+  ;; :jvm-opts ["-Dcom.sun.management.jmxremote"
+  ;;            "-Dcom.sun.management.jmxremote.ssl=false"
+  ;;            "-Dcom.sun.management.jmxremote.authenticate=false"
+  ;;            "-Dcom.sun.management.jmxremote.port=43210"]}
+  :repl {:dependencies [[acyclic/squiggly-clojure "0.1.6"]
+                        [cider/cider-nrepl "0.15.0-SNAPSHOT"]
+                        [datomic-schema-grapher "0.0.1"]
+                        [org.clojure/tools.nrepl "0.2.12"]]
+         :plugins [[cider/cider-nrepl "0.15.0-SNAPSHOT"]]}
+  :repl-options {:init (set! *print-length* 10)}}}

+


Remove unused import on util.paths ns.

Remove unused import on util.paths ns.

--- src/uxbox/util/paths.clj
+++ src/uxbox/util/paths.clj
@@ -8,8 +8,7 @@
   "Paths related utils."
   (:refer-clojure :exclude [name])
   (:require [storages.core :as st])
-  (:import java.nio.file.Files
-           java.nio.file.Path
+  (:import java.nio.file.Path
            java.nio.file.Paths
            java.nio.file.SimpleFileVisitor
            java.nio.file.FileVisitResult


== Generalized XML select functions ==

== Generalized XML select functions ==

 * Fixed and documented assumptions
 * Extracted generic XML select functions where possible
 * Grouped PLIST-specific XML select functions
 * Added some "test" functions that demo using enliven to select text from XML

--- src/webloc_util/core.clj
+++ src/webloc_util/core.clj
@@ -2,22 +2,38 @@
   [:require [net.cgrand.enlive-html :as html]]
   (:gen-class))

-(defn has-text [s]
-  (html/pred #(= (html/text %) s)))
+;; GENERIC XML select functions

-(defn get-entries-for-key
-  "Gets sequence of 'dict' parent elements where text value of child 'key' element = k"
-  [plist k]
-  (html/select plist [:plist [:dict (html/has [(has-text k)])]]))
+(defn element-that-has-child-with-text
+  "Returns selector for element e that has child c where text = t"
+  [e c t]
+  [e (html/has [c]) (html/has [(html/pred #(= (html/text %) t))])])

-(defn get-value
-  [dict]
-  (let [string-el (html/select dict [:string])]
-    (map html/text string-el)))
+(defn select-text
+  "Returns seq of strings representing text values of nodes matched by selector 'sel'"
+  [node-or-nodes sel]
+  (let [child-node (html/select node-or-nodes [sel])]
+    (map html/text child-node)))

-(defn get-url
+;; PLIST-specific XML select functions
+
+(defn select-plist-dict-entries-by-key
+  "Returns sequence of 'dict' parent nodes where (text of 'dict/key' node) == key-text"
+  [plist key-text]
+  (html/select plist [:plist (element-that-has-child-with-text :dict :key key-text)]))
+
+(defn select-url
+  "Selects value of URL entry from plist (if exists). plist must be an html-snippet or be able to be parsed as an html-snippet (e.g. XML string)"
   [plist]
-  (get-value (first (get-entries-for-key plist "URL"))))
+  (if (seq? plist)
+    ; if plist a seq assume has been parsed by html/html-snippet
+    (let [dict-node (first (select-plist-dict-entries-by-key plist "URL"))]
+      (select-text dict-node :string))
+    ; if plist not a seq, assume it's a string and attempt to parse
+    (do
+      (recur (html/html-snippet plist)))))
+
+;; ENTRY POINT

 (defn -main
   "I don't do a whole lot ... yet."
@@ -33,10 +49,21 @@
 <key>URL</key>
 <string>http://google.com</string>
 </dict>
+<dict>
+<yek>URL</yek>
+<string>http://google.com/yek</string>
+</dict>
+<dict>
+<key>LRU</key>
+<string>http://google.com/LRU</string>
+</dict>
 <coocoo>
 <key>URL</key>
 </string>http://coocoo</string>
 </coocoo>
+<random>3.14</random>
 </plist>")

-(def sample-snippet (html/html-snippet sample))
+(defn test1 [] (html/select (html/html-snippet sample) [[:dict (html/has [:key]) (html/has [(html/pred #(= (html/text %) "LRU"))])]]))
+
+(defn test2 [] (select-text (test1) :string))


Comments

Comments

--- src/yada/negotiation.clj
+++ src/yada/negotiation.clj
@@ -107,6 +107,8 @@
      (map cs/to-charset-map (map str/trim (str/split accept-charset-header #"\s*,\s*"))))
    (map cs/to-charset-map candidates)))

+;; Unified negotiation
+
 (s/defschema NegotiationResult
   {:method s/Keyword
    (s/optional-key :content-type)
@@ -176,3 +178,17 @@
                         {:client-charset (first charset)
                          :server-charset (second charset)
                          }))))
+
+;; TODO: see rfc7231.html#section-3.4.1
+
+;; "including both the explicit
+;; negotiation fields of Section 5.3 and implicit characteristics, such
+;; as the client's network address or parts of the User-Agent field."
+
+;; selection of representation can be made based on the User-Agent header, IP address, other 'implicit' data in the request, etc., so this needs to be extensible and overrideable
+
+;; "In order to improve the server's guess, a user agent MAY send request header fields that describe its preferences."
+
+;;    "A Vary header field (Section 7.1.4) is often sent in a response
+;;    subject to proactive negotiation to indicate what parts of the
+;;    request information were used in the selection algorithm."


Correct href from atomic typos to list of users

--- src/zg/html_renderer.clj
+++ src/zg/html_renderer.clj
@@ -88,9 +88,10 @@
 (defn users-href
     "Generator for URL used by 'Users' menu item."
     [url-prefix mode]
-    (if (= mode :whitelist)
-        (str url-prefix "users-whitelist")
-        (str url-prefix "users-blacklist")))
+    (condp = mode
+        :whitelist (str url-prefix "users-whitelist")
+        :blacklist (str url-prefix "users-blacklist")
+        :atomic-typos (str url-prefix "users-atomic-typos")))

 (defn remember-me-href
     "Generator for URL used by 'remember me' button."


renamed 'circle.yml' tab in Builds pag to 'Configuration'

--- src-cljs/frontend/components/build_head.cljs
+++ src-cljs/frontend/components/build_head.cljs
@@ -642,7 +642,7 @@

                              true
                              (conj {:name :config
-                                    :label (str "circle.yml"
+                                    :label (str "Configuration"
                                                 (when-let [errors (-> build build-model/config-errors)]
                                                   (gstring/format " (%s)" (count errors))))})


stop an infinite ajax loop (#1274)

stop an infinite ajax loop (#1274)

stop an infinite ajax loop in the entity table

--- src/cljs/main/broadfcui/page/workspace/data/entity_viewer.cljs
+++ src/cljs/main/broadfcui/page/workspace/data/entity_viewer.cljs
@@ -35,8 +35,8 @@
    (fn [{:keys [this props]}]
      (this :-handle-props props))
    :component-will-receive-props
-   (fn [{:keys [this next-props]}]
-     (this :-handle-props next-props))
+   (fn [{:keys [this props next-props]}]
+     (this :-handle-props next-props props))
    :render
    (fn [{:keys [props state this]}]
      (let [{:keys [update-parent-state]} props
@@ -123,9 +123,10 @@
                                     :render :for-render}])}
                 :paginator :none}]]))
    :-handle-props
-   (fn [{:keys [this]} props]
-     (let [{:keys [entity-type entity-name]} props]
-       (this :-update-and-load entity-type entity-name)))
+   (fn [{:keys [this]} next-props props]
+     (when (utils/any-change [:entity-type :entity-name] props next-props)
+       (let [{:keys [entity-type entity-name]} next-props]
+         (this :-update-and-load entity-type entity-name))))
    :-update-and-load
    (fn [{:keys [state props]} item-type item-name]
      (let [update-viewer-state (fn [& args]


Add a white circular background to message delete button

--- src/braid/core/client/ui/styles/message.cljs
+++ src/braid/core/client/ui/styles/message.cljs
@@ -27,18 +27,17 @@
     [:>.border
      (mixins/card-border "9px")]]

-   [:&:hover
-    [:>button.delete
-     {:display "inline-block"
-      :position "absolute"
-      :line-height "1.25em"
-      :right pad}]]
-
    [:>button.delete
     {:display "none"
+     :position "absolute"
+     :right pad
+     :line-height "1.25em"
      :font-family "fontawesome"
      :color "#ccc"
-     :background "none"
+     :background "#fff"
+     :width "1.25em"
+     :height "1.25em"
+     :border-radius "50%"
      :border "none"
      :padding 0
      :cursor "pointer"
@@ -46,6 +45,10 @@

     [:&:hover
      {:color "red"}]]
+
+   [:&:hover
+    [:>button.delete
+     {:display "inline-block"}]]

    [:>.avatar
     [:>img


Start 2.5.5-SNAPSHOT

Start 2.5.5-SNAPSHOT

--- build.boot
+++ build.boot
@@ -29,7 +29,7 @@
 (task-options!
   sift {:include #{#"\.jar$"}}
   pom {:project 'nightcode
-       :version "2.5.4"
+       :version "2.5.5-SNAPSHOT"
        :description "An IDE for Clojure"
        :url "https://github.com/oakes/Nightcode"
        :license {"Public Domain" "http://unlicense.org/UNLICENSE"}}


Bump up version

Bump up version

--- build.boot
+++ build.boot
@@ -13,7 +13,7 @@
          '[adzerk.boot-cljs   :refer [cljs]]
          '[pandeiro.boot-http :refer [serve]])

-(def +version+ "1.7.170-1")
+(def +version+ "1.7.170-2-SNAPSHOT")

 (bootlaces! +version+)


build.boot: Update docs command

build.boot: Update docs command

--- build.boot
+++ build.boot
@@ -112,12 +112,19 @@
   (merge-env! :source-paths #{"src/test"})
   identity)

+(deftask building-docs
+  []
+  (merge-env! :source-paths #{"docs"})
+  identity)
+
 (deftask docs
   []
   (comp
+   (building-docs)
    (codox :name "workflo/macros"
           :source-paths #{"src/main"}
           :output-path "api-docs"
+          :doc-paths #{"docs/"}
           :metadata {:doc/format :markdown})
    (target)))


Update ClojureScript

Update ClojureScript

--- build.boot
+++ build.boot
@@ -4,10 +4,10 @@
   :source-paths #{"src/cljs" "src/less" "src/scss" "test/clj"}
   :resource-paths #{"src/clj" "src/cljc"}
   :dependencies '[[org.clojure/clojure    "1.7.0"]
-                  [org.clojure/clojurescript "1.7.166"]
+                  [org.clojure/clojurescript "1.7.170"]

                   [boot/core              "2.3.0"      :scope "test"]
-                  [adzerk/boot-cljs       "1.7.166-1"  :scope "test"]
+                  [adzerk/boot-cljs       "1.7.170-1"  :scope "test"]
                   [adzerk/boot-cljs-repl  "0.2.0"      :scope "test"]
                   [adzerk/boot-reload     "0.4.0"      :scope "test"]
                   [adzerk/boot-test       "1.0.4"      :scope "test"]


[PDOK-2056] close-event with attributes --> add extra update-event in event-stream

--- src/main/clojure/pdok/featured/processor.clj
+++ src/main/clojure/pdok/featured/processor.clj
@@ -125,12 +125,18 @@
   "Nested change is the same a nested new"
   (process-new-feature processor (assoc feature :action :change)))

-(defn- process-close-feature [{:keys [persistence projectors]} feature]
-  (let [enriched-feature (->> feature
-              (with-current-version persistence))]
+(defn- process-close-feature [{:keys [persistence projectors] :as processor} feature]
+  (let [change-before-close (if-not (empty? (:attributes feature))
+                               (process-change-feature processor
+                                                       (assoc feature :action :change
+                                                                      :version (random/UUID))))
+        enriched-feature (->> feature
+                              (with-current-version persistence))]
     (append-feature persistence enriched-feature)
     (doseq [p projectors] (proj/close-feature p enriched-feature))
-    enriched-feature))
+    (if change-before-close
+      (list change-before-close enriched-feature)
+      (list enriched-feature))))

 (defn- process-nested-close-feature [processor feature]
   (let [nw (process-new-feature processor (assoc feature :action :new))


Turn off logging when running tests

Turn off logging when running tests

Makes the test output much more readable. For example: Doesn't spit out
expected errors in passing tests (which are a real pain to sift through
when a different test is failing).

--- resources/leiningen/new/kraken_works/project.clj
+++ resources/leiningen/new/kraken_works/project.clj
@@ -28,4 +28,5 @@
   :profiles {:uberjar {:aot :all}
              :dev-common {:resource-paths ["dev-resources"]}
              :dev-overrides {}
-             :dev [:dev-common :dev-overrides]})
+             :dev [:dev-common :dev-overrides]
+             :test {:jvm-opts ["-Dlog-level=OFF"]}})


Buildcheck: report count only for VS warnings.

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

--- buildscripts/buildcheck/src/buildcheck/core.clj
+++ buildscripts/buildcheck/src/buildcheck/core.clj
@@ -47,6 +47,11 @@
        (map second)
        (apply str)))

+(defn vs-log-summary [text]
+  ; Assumption: the last line contains the error and warning counts.
+  (let [lines (clojure.string/split-lines text)]
+    (str (last lines) "\n")))
+
 (defn contains-errors? [log-text]
   (if (re-find #"\n[^\n]+\b([1-9]|[0-9][1-9]|[0-9][0-9][1-9])\b\serror\(s\)[^\n]+\n"
                log-text)
@@ -56,9 +61,17 @@
   (if (re-find #"\: warning" log-text)
     true false))

-(defn visual-studio-errors-and-warnings [bits]
-  (let [texts (map vs-log-text (vs-log-files bits))]
-    (filter #(or (contains-warnings? %) (contains-errors? %)) texts)))
+(defn visual-studio-errors-and-warnings [bits warnings? full-msgs? full-errors?]
+  (->> (vs-log-files bits)
+       (map vs-log-text)
+       (filter (if warnings? #(or (contains-warnings? %)
+                                  (contains-errors? %))
+                             contains-errors?))
+       (map #(if (or full-msgs?
+                     (and full-errors?
+                          (contains-errors? %)))
+                 %
+                 (vs-log-summary %)))))

 (defn javac-errors [result-text]
   (map first
@@ -209,7 +222,7 @@
   (let [f (result-file bits mode)
         svn-confs (svn-conflicts)
         result-txt (slurp f)
-        vs-errors (visual-studio-errors-and-warnings bits)
+        vs-errors (visual-studio-errors-and-warnings bits true false true)
         outdated-dlls (map #(.getName %) (old-dlls (bin-dir bits) 24))
         javac-errs (javac-errors result-txt)
         clojure-errors (clojure-errors result-txt)


Refactoring demo code.

Refactoring demo code.

--- umm-spec-lib/src/cmr/umm_spec/umm_json.clj
+++ umm-spec-lib/src/cmr/umm_spec/umm_json.clj
@@ -2,21 +2,7 @@
   "Contains functions for converting a UMM into JSON and back out of JSON."
   (:require [cheshire.core :as json]
             [cheshire.generate :as json-gen]
-            [cmr.umm-spec.json-schema :as js]
-
-            ;; Temporary require statements for demo
-
-            [cmr.umm-spec.xml-mappings.xml-generator :as xg]
-            [cmr.umm-spec.xml-mappings.iso19115-2 :as xm-iso2]
-            [cmr.umm-spec.xml-mappings.echo10 :as xm-echo10]
-            [cmr.umm-spec.umm-mappings.iso19115-2 :as um-iso2]
-            [cmr.umm-spec.umm-mappings.echo10 :as um-echo10]
-            [cmr.umm-spec.umm-mappings.parser :as xp]
-            [cmr.umm-spec.models.collection :as umm-c]
-            [cmr.umm-spec.models.common :as umm-cmn]
-            [cmr.umm-spec.json-schema :as js]
-
-            ))
+            [cmr.umm-spec.json-schema :as js]))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; UMM To JSON
@@ -71,30 +57,4 @@
   )

-;; Temporary Demo code

-(defn echo10->umm-json
-  [xml]
-  (umm->json (xp/parse-xml um-echo10/echo10-xml-to-umm-c xml)))
-
-(defn umm-json->echo10
-  [json-str]
-  (xg/generate-xml xm-echo10/umm-c-to-echo10-xml (json->umm json-str)))
-
-(defn iso19115->umm-json
-  [xml]
-  (umm->json (xp/parse-xml um-iso2/iso19115-2-xml-to-umm-c xml)))
-
-(defn umm-json->iso19115
-  [json-str]
-  (xg/generate-xml xm-iso2/umm-c-to-iso19115-2-xml (json->umm json-str)))
-
-
-(defn pretty-print-json
-  [json-str]
-  (println (json/generate-string (json/decode json-str) {:pretty true})))
-
-
-(defn pretty-print-xml
-  [xml]
-  (println (cmr.common.xml/pretty-print-xml xml)))


CMR-2815 removed acl service util file

CMR-2815 removed acl service util file

--- access-control-app/src/cmr/access_control/services/acl_service_util.clj
+++ access-control-app/src/cmr/access_control/services/acl_service_util.clj
@@ -1,17 +0,0 @@
-(ns cmr.access-control.services.acl-service-util
-  "Contains common utility functions used in ACL service"
-  (:require
-    [clojure.edn :as edn]
-    [clojure.set :as set]
-    [cmr.access-control.data.acl-schema :as schema]
-    [cmr.access-control.services.acl-service-messages :as acl-msg]
-    [cmr.access-control.services.group-service :as groups]
-    [cmr.common.concepts :as concepts]
-    [cmr.common.date-time-parser :as dtp]
-    [cmr.common.services.errors :as errors]
-    [cmr.acl.core :as acl]
-    [cmr.common.util :as util]
-    [cmr.transmit.echo.tokens :as tokens]
-    [cmr.transmit.metadata-db :as mdb1]
-    [cmr.transmit.metadata-db2 :as mdb]
-    [cmr.umm.acl-matchers :as acl-matchers]))


initial fn for generating ids on the frontend

--- src-cljs/frontend/datascript.cljs
+++ src-cljs/frontend/datascript.cljs
@@ -92,3 +92,20 @@
                  (mapv datom->reverse-transaction datoms)
                  {:undo true
                   :can-undo? true})))
+(defn id-generator
+  "Returns a function that generates unique ids. Only 1 generator per connection!
+   Assumes that each client has a different remainder and that all clients have
+   the same multiple.
+   Takes a connection to guard against duplicate ids, but is not meant to be a protection
+   against races. Only guards against a previous client with the same remainder skipping
+   ids (probably due to an error)."
+  [conn multiple remainder]
+  ;; TODO efficient algorithm for finding first next-id
+  (let [next-id (atom remainder)]
+    (fn []
+      (loop [res @next-id]
+        (if (first (d/datoms @conn :eavt res))
+          (recur (+ res remainder))
+          (do
+            (reset! next-id (+ res remainder))
+            res))))))


Don't create deployment error if k8s 409 conflict (#1330)

--- waiter/src/waiter/scheduler/kubernetes.clj
+++ waiter/src/waiter/scheduler/kubernetes.clj
@@ -645,11 +645,13 @@
         (ss/try+
           (api-request request-url scheduler :body (utils/clj->json rs-spec) :request-method :post)
           (catch Object response
-            (let [deployment-error (create-service-deployment-error response response->deployment-error-msg-fn)]
-              (log/info "creating deployment error for service" {:deployment-error deployment-error
-                                                                 :service-id service-id})
-              (cu/cache-put! service-id->deployment-error-cache service-id deployment-error)
-              (ss/throw+ response))))
+            ; Don't create deployment error for http-409-conflict (replicaset already exists)
+            (when-not (= (:status response) http-409-conflict)
+              (let [deployment-error (create-service-deployment-error response response->deployment-error-msg-fn)]
+                (log/info "creating deployment error for service" {:deployment-error deployment-error
+                                                                   :service-id service-id})
+                (cu/cache-put! service-id->deployment-error-cache service-id deployment-error)))
+            (ss/throw+ response)))
         {:keys [k8s/replicaset-uid] :as service} (some-> response-json replicaset->Service)]
     (if service
       (cu/cache-evict service-id->deployment-error-cache service-id)


Use instructions to calculate floor

Use instructions to calculate floor

--- day-01/src/solver/core.clj
+++ day-01/src/solver/core.clj
@@ -1,11 +1,14 @@
 (ns solver.core
   (:gen-class))

-(defn determine-floor [word]
-  "Determines which floor Santa should deliver presents"
-  (let [freqs (frequencies word)] (- (get freqs \( 0) (get freqs \) 0))))
+(defn determine-floor [xs]
+  (let [to-direction (fn [index direction] {:index index :direction direction})
+        determine-floor (fn [floor data] (+ floor  (case (data :direction)
+                                             "(" +1
+                                             ")" -1)))]
+    (reduce determine-floor 0  (map-indexed to-direction xs))))

 (defn -main
   "I don't do a whole lot ... yet."
   [& args]
-  (println (determine-floor (slurp "input"))))
+  (println (determine-floor (clojure.string/split (slurp "input") #""))))


Refine log ouput in 500 status

Refine log ouput in 500 status

--- backend/src/akvo/lumen/component/handler.clj
+++ backend/src/akvo/lumen/component/handler.clj
@@ -96,7 +96,7 @@
         (handler request)
         (catch Throwable t
           (log/error t "500 App Error")
-          (log/info :request-on-500 request)
+          (log/info :request-on-500 (dissoc request :reitit.core/match :data :result :reitit.core/router))
           (-> (compojure.res/render error-response request)
               (ring.response/content-type "text/html")
               (ring.response/status 500)))))))


Starting to figure out how to walk through the weird tag/attribute/body vector format from tagsoup

--- scraper/src/scraper/core.clj
+++ scraper/src/scraper/core.clj
@@ -13,5 +13,5 @@
   "Entry point to scraper methods. Pulls in data from project1999's wiki to insert into an SQLite DB."
   [& args]
   ;The main wiki page detailing the first 200 factions. This is where we will get a list of faction links to scrape
-  (tagsoup/parse "http://wiki.project1999.com/index.php?title=Category:Factions")
+  (dorun (map #(tag %) (next tagsoup/parse "http://wiki.project1999.com/index.php?title=Category:Factions")))
       )


Remove a little more noise from the id-generation code.

--- clj_record/test/main.clj
+++ clj_record/test/main.clj
@@ -4,19 +4,14 @@
             [clojure.contrib.str-utils :as str-utils]
             clj-record.test.model.config))

-;; Multiple DB Support
-;;--------------------------------------------------
+
 (defmulti get-id-key-spec :subprotocol)
-
 (defmethod get-id-key-spec "derby" [db-spec name]
   [:id :int (str "GENERATED ALWAYS AS IDENTITY CONSTRAINT " name " PRIMARY KEY")])
-
 (defmethod get-id-key-spec "postgresql" [db-spec name]
-  [:id (str "SERIAL UNIQUE PRIMARY KEY")])
-
+  [:id "SERIAL UNIQUE PRIMARY KEY"])
 (defmethod get-id-key-spec "mysql" [db-spec name]
   [:id :serial])
-;;--------------------------------------------------

 (defn drop-tables []
   (try


Add context to superfluous-parens

Add context to superfluous-parens

--- src/atom_finder/questions/superfluous_parens.clj
+++ src/atom_finder/questions/superfluous_parens.clj
@@ -45,7 +45,12 @@
         (fn [file]
           (merge
            {:file (atom-finder-relative-path file)}
-           (->> file parse-file find-parens (map-values (partial map #(dissoc (loc %) :length :start-line))))
+           (->> file parse-file find-parens
+                (map-values (partial map (fn [node]
+                                           (merge {:parent-type (opname-or-typename (parent node))
+                                                   :node-type (opname-or-typename node)}
+                                                  (dissoc (loc node) :length :start-line)
+                                                  )))))
            )))
        (map prn)
        dorun
@@ -55,8 +60,8 @@

 (defn main-superfluous-parens
   []
-  (let [edn-file "tmp/all-parens_2018-10-28_superfluous-parens.edn"
-        csv-file "src/analysis/data/all-parens_2018-10-28_superfluous-parens.csv"
+  (let [edn-file "tmp/all-parens_2018-10-28_context.edn"
+        csv-file "src/analysis/data/all-parens_2018-10-28_context.csv"
         ]
     (find-all-parens-in-project edn-file)
     ;(summarize-all-nodes edn-file csv-file)


update call to (analyze)

update call to (analyze)

--- test/babel/test/it.cljc
+++ test/babel/test/it.cljc
@@ -12,14 +12,14 @@
             [dag_unify.core :refer [get-in strip-refs]]))

 (deftest analyze-1
-  (let [singular (analyze "compito" (:lookup medium))
-        plural  (analyze "compiti" (:lookup medium))]
+  (let [singular (analyze "compito")
+        plural  (analyze "compiti")]
     (is (not (empty? singular)))
     (is (not (empty? plural)))))

 (deftest analyze-2
-  (let [singular (analyze "difficile" (:lookup medium))
-        plural  (analyze "difficili" (:lookup medium))]
+  (let [singular (analyze "difficile")
+        plural  (analyze "difficili")]
     (is (not (empty? singular)))
     (is (not (empty? plural)))))


whitespace

whitespace

--- test/babel/test/it.cljc
+++ test/babel/test/it.cljc
@@ -496,14 +496,14 @@
 (deftest davanti-il-tavolo
   (let [parse-result (mapcat :parses (parse "davanti il tavolo"))
         gen-result (generate {:synsem {:cat :prep
-                                                   :sem {:pred :in-front-of
-                                                         :obj {:pred :table
-                                                               :number :sing
-                                                               :mod '()
-                                                               :spec {:def :def}}}}
-                                          :comp {:synsem {:cat :noun
-                                                          :pronoun false
-                                                          :subcat '()}}})]
+                                       :sem {:pred :in-front-of
+                                             :obj {:pred :table
+                                                   :number :sing
+                                                   :mod '()
+                                                   :spec {:def :def}}}}
+                              :comp {:synsem {:cat :noun
+                                              :pronoun false
+                                              :subcat '()}}})]
     (is (not (empty? parse-result)))
     (is (= "davanti il tavolo"
            (morph gen-result)))))
@@ -511,27 +511,27 @@
 (deftest davanti-lo-studente
   (let [parse-result (mapcat :parses (parse "davanti lo studente"))
         gen-result (generate {:synsem {:cat :prep
-                                                   :sem {:pred :in-front-of
-                                                         :obj {:pred :student
-                                                               :number :sing
-                                                               :mod '()
-                                                               :spec {:def :def}}}}
-                                          :comp {:synsem {:cat :noun
-                                                          :pronoun false
-                                                          :subcat '()}}})]
+                                       :sem {:pred :in-front-of
+                                             :obj {:pred :student
+                                                   :number :sing
+                                                   :mod '()
+                                                   :spec {:def :def}}}}
+                              :comp {:synsem {:cat :noun
+                                              :pronoun false
+                                              :subcat '()}}})]
     (is (not (empty? parse-result)))
     (is (= "davanti lo studente"
            (morph gen-result)))))

 (deftest davanti-il-tavolo
   (let [expr (generate {:synsem {:cat :prep
-                                             :sem {:pred :in-front-of
-                                                   :reflexive false
-                                                   :obj {:pred :table
-                                                         :mod '()
-                                                         :number :sing
-                                                         :spec {:def :def
-                                                                :pred :definite}}}}})]
+                                 :sem {:pred :in-front-of
+                                       :reflexive false
+                                       :obj {:pred :table
+                                             :mod '()
+                                             :number :sing
+                                             :spec {:def :def
+                                                    :pred :definite}}}}})]
     (is (= (morph expr)
            "davanti il tavolo"))))


Fix test :require form

Fix test :require form

--- test/clum/core_test.clj
+++ test/clum/core_test.clj
@@ -1,7 +1,7 @@
 (ns clum.core-test
-  (:require [clojure.test :refer :all]
-            [clum.core :refer :all]))
+  (:require [org.httpkit.client :as http]
+            [clojure.test       :refer :all]))

-(deftest a-test
+(deftest api-test
   (testing "FIXME, I fail."
     (is (= 0 1))))


WIP: async test make the script terminate before it should

--- test/doo/core-test.cljs
+++ test/doo/core-test.cljs
@@ -3,5 +3,15 @@

 (enable-console-print!)

-(deftest js-envs
+(deftest sync-test
   (is (= 2 1)))
+
+;; Only works in browsers because it uses setTimeout
+(deftest async-test
+  (async done
+    (is (= 1 1))
+    (let [a 1]
+      (js/setTimeout (fn []
+                       (is (= a 2))
+                       (done))
+        500))))


A second solution to the exercise "Word Count" from Exercism in the Clojure Track

--- exercism/clojure/word-count/src/word_count.clj
+++ exercism/clojure/word-count/src/word_count.clj
@@ -6,8 +6,7 @@
    A word here is an alphanumeric sequence of 1 character or more. All non-alphanumeric characters are ignored and the case of each word is normalized to lowercase.
    For example 'word' 'WORD' 'WorD' 'word!,' are considered the same word occurence."
   [s]
-  (as-> s input
-    (str/replace input #"\W+" " ")
-    (str/split  input #"\s")
-    (map str/lower-case input)
-    (frequencies input)))+  (->> s
+       (re-seq #"\w+")
+       (map str/lower-case)
+       (frequencies)))


CMR-3274 Finish PR fixes

CMR-3274 Finish PR fixes

--- umm-spec-lib/src/cmr/umm_spec/migration/contact_information_migration.clj
+++ umm-spec-lib/src/cmr/umm_spec/migration/contact_information_migration.clj
@@ -5,7 +5,7 @@
 (defn first-contact-info
   "Update the array of contact infos to be a single instance using the first contact info in the list"
   [c]
-  (update-in c [:ContactInformation] first))
+  (update c :ContactInformation first))

 (defn contact-info-to-array
   "Update the contact info field to be an array. If contact info is nil, leave it as nil."
@@ -20,8 +20,8 @@
   [data-center]
   (-> data-center
       (contact-info-to-array)
-      (update-in [:ContactPersons] #(mapv contact-info-to-array %))
-      (update-in [:ContactGroups] #(mapv contact-info-to-array %))))
+      (update :ContactPersons #(mapv contact-info-to-array %))
+      (update :ContactGroups #(mapv contact-info-to-array %))))

 (defn update-data-center-contact-info
   "Update data center contact infos to be a single instance - this includes the contact info on the
@@ -29,5 +29,5 @@
   [data-center]
   (-> data-center
       first-contact-info
-      (update-in [:ContactPersons] #(mapv first-contact-info %))
-      (update-in [:ContactGroups] #(mapv first-contact-info %))))
+      (update :ContactPersons #(mapv first-contact-info %))
+      (update :ContactGroups #(mapv first-contact-info %))))


Added wildcards :* and :** like zsh

Added wildcards :* and :** like zsh

--- test/tst/parse/demo.clj
+++ test/tst/parse/demo.clj
@@ -880,51 +880,98 @@
     )))

+(defn- ^:no-doc find-tag* [result path tree tgt-path]
+  (when (empty? tgt-path)
+    (throw (IllegalStateException. "find*: tgt-path is empty")))
+  (when (sequential? tree)
+    (let [tgt          (first tgt-path)
+          tgt-path-new (rest tgt-path)
+          [tag & contents] tree]
+      (when (or (= tag :*) (= tag :**))
+        (throw (IllegalArgumentException. (str "fing-tag*: found reserved tag " tag " in tree"))))
+      (if (or (= tgt tag) (= tgt :*))
+        (if (empty? tgt-path-new)
+          (do
+            (let [soln {:path  path
+                        :found tree}]
+              (swap! result t/glue #{soln})))
+          (do
+            (let [path-new (t/append path tag)]
+              (doseq [child-tree contents]
+                (find-tag* result path-new child-tree tgt-path-new))))))
+      (when (= tgt :**)
+        (let [path-new (t/append path tag)] ; non-consuming recursion
+          (doseq [child-tree contents]
+            (find-tag* result path-new child-tree tgt-path)))
+        (if (empty? tgt-path-new)
+          (let [soln {:path  path
+                      :found tree}]
+            (swap! result t/glue #{soln}))
+          (let [path-new (t/append path tag)]
+            (doseq [child-tree contents]
+              (find-tag* result path-new child-tree tgt-path-new))))))))
+(defn find-tag [tree tgt-path]
+  (let [result (atom #{})]
+    (find-tag* result [] tree tgt-path)
+    @result))
+
 (def tree-1 [:a
              [:b 1]
              [:b 2]
              [:b
               [:c 1]
               [:c 2] ] ] )
-(defn- ^:no-doc find-paths* [result path tree tgt-path]
-  (when (empty? tgt-path)
-    (throw (IllegalStateException. "find*: tgt-path is empty")))
-  (when (sequential? tree)
-    (let [tgt          (first tgt-path)
-          tgt-path-new (rest tgt-path)
-          [tag & contents] tree]
-      (if (= tag tgt)
-        (if (empty? tgt-path-new)
-          (do
-            (let [soln {:path  path
-                        :found tree}]
-              (swap! result t/append soln)))
-          (do
-            (let [path-new (t/append path tag)]
-              (doseq [child-tree contents]
-                (do
-                  (find-paths* result path-new child-tree tgt-path-new))))))))))
-(defn find-paths [tree tgt-path]
-  (let [result (atom [])]
-    (find-paths* result [] tree tgt-path)
-    @result))
-
-(dotest
-  (is= (find-paths tree-1 [:z]) [])
-  (is= (find-paths tree-1 [:z :b]) [])
-  (is= (find-paths tree-1 [:z :b :c]) [])
-  (is= (find-paths tree-1 [:a :z]) [])
-  (is= (find-paths tree-1 [:a :z :c]) [])
-  (is= (find-paths tree-1 [:a :b :z]) [])
-
-  (is= (find-paths tree-1 [:a])
-    [{:path [] :found [:a [:b 1] [:b 2] [:b [:c 1] [:c 2]]]}])
-  (is= (find-paths tree-1 [:a :b])
-    [{:path [:a] :found [:b 1]}
-     {:path [:a] :found [:b 2]}
-     {:path [:a] :found [:b [:c 1] [:c 2]]} ])
-
-  (is= (find-paths tree-1 [:a :b :c])
-    [{:path [:a :b] :found [:c 1]}
-     {:path [:a :b] :found [:c 2]} ])
+
+(dotest
+  (is (empty? (find-tag tree-1 [:z])))
+  (is (empty? (find-tag tree-1 [:z :b])))
+  (is (empty? (find-tag tree-1 [:z :b :c])))
+  (is (empty? (find-tag tree-1 [:a :z])))
+  (is (empty? (find-tag tree-1 [:a :z :c])))
+  (is (empty? (find-tag tree-1 [:a :b :z])))
+
+  (is= (find-tag tree-1 [:a])
+    #{{:path [] :found [:a [:b 1] [:b 2] [:b [:c 1] [:c 2]]]}})
+  (is= (find-tag tree-1 [:a :b])
+    #{{:path [:a] :found [:b 1]}
+      {:path [:a] :found [:b 2]}
+      {:path [:a] :found [:b [:c 1] [:c 2]]}})
+
+  (is= (find-tag tree-1 [:a :b :c])
+    #{ {:path [:a :b] :found [:c 1]}
+       {:path [:a :b] :found [:c 2]} })
+
+  (is= (find-tag tree-1 [:* :b])
+    #{{:path [:a], :found [:b 1]}
+      {:path [:a], :found [:b 2]}
+      {:path [:a], :found [:b [:c 1] [:c 2]]}})
+  (is= (find-tag tree-1 [:a :*])
+    #{{:path [:a], :found [:b 1]}
+      {:path [:a], :found [:b 2]}
+      {:path [:a], :found [:b [:c 1] [:c 2]]} })
+  (is= (find-tag tree-1 [:a :* :c])
+    #{{:path [:a :b], :found [:c 1]}
+      {:path [:a :b], :found [:c 2]}})
+
+  (is= (find-tag tree-1 [:a :**])
+    #{{:path [:a], :found [:b 1]}
+      {:path [:a], :found [:b 2]}
+      {:path [:a], :found [:b [:c 1] [:c 2]]}
+      {:path [:a :b], :found [:c 1]}
+      {:path [:a :b], :found [:c 2]}})
+  (is= (find-tag tree-1 [:a :** :c])
+    #{{:path [:a :b], :found [:c 1]}
+      {:path [:a :b], :found [:c 2]}})
+  (is= (find-tag tree-1 [:** :c])
+    #{{:path [:a :b], :found [:c 1]}
+      {:path [:a :b], :found [:c 2]}})
+
+  (let [bad-tree [:a
+                  [:* 1]
+                  [:b 2]]]
+    (throws? (find-tag bad-tree [:a :b])))
+  (let [bad-tree [:a
+                  [:** 1]
+                  [:b 2]]]
+    (throws? (find-tag bad-tree [:a :b])))
 )


Put expected result in correct position

Put expected result in correct position

--- test/datemo/arb_test.clj
+++ test/datemo/arb_test.clj
@@ -18,28 +18,31 @@
   (testing "html->arb"
     (testing "with empty div"
       (is (=
-           (html->arb (html [:div]))
-           [:arb {:original-tag :div} nil])))
+           [:arb {:original-tag :div} nil]
+           (html->arb (html [:div])))))
     (testing "with div with text"
       (is (=
-           (html->arb (html [:div {} "Text"]))
-           [:arb {:original-tag :div} "Text"])))
+           [:arb {:original-tag :div} "Text"]
+           (html->arb (html [:div {} "Text"])))))
     (testing "with two sibling tags"
       (is (=
-           (html->arb (html [:div "A"] [:div "B"]) false)
            (build-arb [[:arb {:original-tag :div} "A"]
-                       [:arb {:original-tag :div} "B"]]))))
+                       [:arb {:original-tag :div} "B"]])
+           (html->arb (html [:div "A"] [:div "B"]) false))))
     (testing "nested tags"
       (is (=
            [:arb {:original-tag :div} "parent"
             [:arb {:original-tag :p} "child"]]
            (html->arb (html [:div "parent" [:p "child"]])))))
     (testing "with nested tag in middle of text"
-      (is (= (html->arb (html [:p "Paragraph with " [:strong "bold"] " text."]))
-             [:arb {:original-tag :p}
-                         "Paragraph with "
-                         [:arb {:original-tag :strong} "bold"]
-                         " text."]))))
+      (is (=
+            [:arb
+             {:original-tag :p}
+             "Paragraph with "
+             [:arb {:original-tag :strong} "bold"]
+             " text."]
+            (html->arb
+              (html [:p "Paragraph with " [:strong "bold"] " text."]))))))

   (testing "arb->tx"
     (testing "single arb node with nil value"


Key-down refactored to event system

Key-down refactored to event system

--- desktop/src-common/con_world/screen-main.clj
+++ desktop/src-common/con_world/screen-main.clj
@@ -61,6 +61,17 @@
            (and (= z-side :bottom) (= normal (vector-2 0.0 -1.0)))
            (and (= z-side :left) (= normal (vector-2 -1.0 0.0)))))))

+(defmulti apply-event (fn [_ _ [type & _]] type))
+
+(defmethod apply-event :player-moved [screen entities [_ direction]]
+  (on-key-move-cell entities direction))
+
+(defn apply-events [{:keys [events] :as screen} entities]
+  (reduce (fn [entities evt]
+            (apply-event screen entities evt))
+          entities
+          events))
+
 (defscreen main-screen

            :on-show
@@ -76,7 +87,8 @@
                                 :music (memo-sound "sound/fond.mp3")
                                 :bg-width (:width background)
                                 :bg-height (:height background)
-                                :last-spawn 0))]
+                                :last-spawn 0
+                                :events []))]

                (add-timer! screen :ambiant-sound 3 3)
                (sound! (:music screen) :loop)
@@ -87,8 +99,8 @@
                 (create-player-entity screen)]))

            :on-render
+           (fn [screen entities]

-           (fn [screen entities]

              (clear!)

@@ -98,20 +110,24 @@

                  (game-over screen)

-                 (->> entities
-                      (step! screen)
-                      change-player-level
-                      (animate-player screen)
-                      (animate-plante screen)
-                      (animate-enemies screen)
-                      (map set-enemy-in-zone)
-                      (map move-enemy)
-                      (render! screen)))))
+                 (let [result-entities (->> entities
+                                            (apply-events screen)
+                                            (step! screen)
+                                            change-player-level
+                                            (animate-player screen)
+                                            (animate-plante screen)
+                                            (animate-enemies screen)
+                                            (map set-enemy-in-zone)
+                                            (map move-enemy)
+                                            (render! screen))]
+                   (update! screen :events [])
+                   result-entities))))

            :on-key-down
-           (fn [{:keys [key]} entities]
+           (fn [{:keys [key] :as screen} entities]
              (when-let [direction (key->direction key)]
-               (on-key-move-cell entities direction)))
+               (update! screen :events (conj (:events screen) [:player-moved direction])))
+             entities)

            :on-resize
            (fn [screen _]


write is a better functino name. Add conn reset.

--- src/onyx/messaging/aeron/publication_manager.clj
+++ src/onyx/messaging/aeron/publication_manager.clj
@@ -13,16 +13,18 @@
 (def ^:const publication-not-connected (long -1))

 (defprotocol PPublicationManager
-  (connect [_ channel stream-id])
-  (send-pub [this buf start end])
+  (write [this buf start end])
+  (connect [_])
   (close [_])
   (reset [_]))

-(defrecord PublicationManager [messenger connection publication pending-ch]
+(defrecord PublicationManager [messenger channel stream-id connection publication pending-ch]
   PPublicationManager
-  (reset [this])
+  (reset [this]
+    (close this)
+    (connect this))

-  (send-pub [this buf start end]
+  (write [this buf start end]
     (let [pub ^Publication @publication
           offer-f (fn [] (.offer pub buf start end))]
       (while (let [result ^long (offer-f)]
@@ -37,12 +39,12 @@
     (reset! connection nil)
     this)

-  (connect [this channel stream-id]
+  (connect [this]
     (let [conn (Aeron/connect (.errorHandler (Aeron$Context.) no-op-error-handler))
           pub (.addPublication conn channel stream-id)]
       (reset! publication pub)
       (reset! connection conn)
       this)))

-(defn new-publication-manager [messenger]
-  (->PublicationManager messenger (atom nil) (atom nil) nil #_(chan 1000)))
+(defn new-publication-manager [messenger channel stream-id]
+  (->PublicationManager messenger channel stream-id (atom nil) (atom nil) nil #_(chan 1000)))


updating doc to clarify that it is for control busses

--- src/overtone/sc/machinery/ugen/metadata/info.clj
+++ src/overtone/sc/machinery/ugen/metadata/info.clj
@@ -21,7 +21,7 @@

    {:name "ControlDur"
     :rates #{:ir}
-    :doc "returns the current block duration of the server in seconds"}
+    :doc "returns the current control rate block duration of the server in seconds"}

    {:name "SubsampleOffset"
     :rates #{:ir}