content for testimonials

content for testimonials

--- frontend/components/language_landing.cljs
+++ frontend/components/language_landing.cljs
@@ -10,21 +10,43 @@
             [frontend.utils :as utils :include-macros true]
             [om.core :as om :include-macros true])
   (:require-macros [frontend.utils :refer [defrender html]]))
+
+(defn arrow-class [selected-testimonial]
+  (case selected-testimonial
+    0 "arrowLeft"
+    1 "arrowCenter"
+    2 "arrowRight"
+    "arrowLeft"
+    ))
+
 (def templates {"ruby" {:language "Ruby"
                         :headline "CircleCI makes Continous Integration and Deployment for Ruby projects a breeze."
                         :logo-path "/assets/img/outer/languages/ruby-logo.png"
                         :ss-1 "/assets/img/outer/languages/ruby-ss-1.png"
                         :ss-2 "/assets/img/outer/languages/ruby-ss-1.png"
                         :ss-3 "/assets/img/outer/languages/ruby-ss-1.png"
-                        :testimonial-1 "Ruby and Circle are amazing!"
-                        :testimonial-2 "Ruby and Circle are spectacular!"
-                        :testimonial-3 "Ruby and Circle are badass!"}})
+                        :testimonial-author-1 "/assets/img/outer/stories/john.jpg"
+                        :testimonials [{:text "Nullam id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Integer posuere erat a ante venenatis."
+                                       :img "/assets/img/outer/stories/john.jpg"
+                                       :author "Kevin Rose"
+                                       :title "Entrepneur @Google"}
+                                       {:text "text 2"
+                                        :img "/assets/img/outer/stories/john.jpg"
+                                        :author "Clark Kent"
+                                        :title "superman"}
+                                       {:text "text 3"
+                                        :img "/assets/img/outer/stories/john.jpg"
+                                        :author "Bruce Wayne"
+                                        :title "Batman"}]}})
+
 (defn language-landing [app owner]
   (reify
     om/IRender
     (render [_]
             (let [subpage (get-in app [:navigation-data :language])
-                  template (get templates subpage)]
+                  template (get templates subpage)
+                  selected-testimonial (get-in app state/language-testimonial-tab-path 0)
+                  controls-ch (om/get-shared owner [:comms :controls])]
               (html
                 [:div.languages.page
                  [:div.languages-head
@@ -34,31 +56,71 @@
                    [:img {:src (:ss-1 template)}]
                    [:img {:src (:ss-2 template)}]
                    [:img {:src (:ss-3 template)}]]]
+                 [:div.languages-body.remove-margin
+                  [:div.languages-features
+                   [:div.center-text
+                    [:h3 "FEATURES"
+                     ]
+                    ]
+                   [:div.feature
+                    [:div.feature-image
+                     [:img {:src "/assets/img/outer/languages/gear-icon.png"}]
+                     ]
+                    [:div.feature-copy
+                     [:h4.feature-title "Testing Frameworks"
+                      ]
+                     [:p.feature-description "Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Maecenas faucibus mollis interdum. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur."]
+                     ]
+
+                    ]
+                   [:div.feature
+                    [:div.feature-copy
+                     [:h4.feature-title "Testing Frameworks"
+                      ]
+                     [:p.feature-description "Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Maecenas faucibus mollis interdum. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur."]
+                     ]
+                    [:div.feature-image
+                     [:img {:src "/assets/img/outer/languages/book-icon.png"}]
+                     ]
+                    ]
+                   [:div.feature
+                    [:div.feature-image
+                     [:img {:src "/assets/img/outer/languages/file-icon.png"}]
+                     ]
+                    [:div.feature-copy
+                     [:h4.feature-title "Testing Frameworks"
+                      ]
+                     [:p.feature-description "Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Maecenas faucibus mollis interdum. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur."]
+                     ]
+
+                    ]
+                   [:div.button
+                    [:a {:href="#"} "Read documentation on " (:language template)]]
+                   ]
+                  ]
+                 [:div.languages-testimonials
+                  [:div.languages-body.remove-margin
+                   [:div.center-text
+                    [:h3 "TESTIMONIALS"
+                     ]
+                    ]
+                   [:div.testimonial-authors
+                    (map-indexed (fn [i testimonial] [:img {:src (:img testimonial) :on-click #(put! controls-ch [:language-testimonial-tab-selected {:index i}])}])
+                                 (:testimonials template))]
+                   [:div.testimonial-box {:class (arrow-class selected-testimonial)}
+                    [:div.testimonial
+                     [:p.testimonial-text (get-in template [:testimonials selected-testimonial :text])]
+
+                     [:div.testimonial-author "- " (get-in template [:testimonials selected-testimonial :author])]
+                     [:div.testimonial-author-title (get-in template [:testimonials selected-testimonial :title])]]
+                    ;;[:div.testimonial
+                    ;;[:div.testimonial-text (:testimonial-2 template)]]
+                    ;;[:div.testimonial
+                    ;;[:div.testimonial-text (:testimonial-3 template)]]
+                    ]
+                   ]
+                  ]
                  [:div.languages-body
-                  [:div.languages-features
-                   "Features"
-                   [:div.feature
-                    "Feature 1"
-                    [:img {:src "/assets/img/outer/languages/gear-icon.png"}]]
-                   [:div.feature
-                    "Feature 2"
-                    [:img {:src "/assets/img/outer/languages/book-icon.png"}]]
-                   [:div.feature
-                    "Feature 3"
-                    [:img {:src "/assets/img/outer/languages/file-icon.png"}]]
-                   [:a {:href="#"}
-                    [:div.button "Read documentation on " (:language template)]]]
-                  [:div.languages-testimonials
-                   [:div.testimonial
-                    [:img {:src (:logo-path template)}]
-                    [:div.testimonial-text (:testimonial-1 template)]]
-                   [:div.testimonial
-                    [:img {:src (:logo-path template)}]
-                    [:div.testimonial-text (:testimonial-2 template)]]
-                   [:div.testimonial
-                    [:img {:src (:logo-path template)}]
-                    [:div.testimonial-text (:testimonial-3 template)]]
-                   ]
                   [:div.languages-cta
                    [:div.languages-cta-headline
                     "How do I start using my " (:language template) " app with Circle?"]
@@ -68,8 +130,8 @@
                     "Run one of your Ruby projects on Circle"]
                    [:div.languages-cta-step
                     "That's it! If you hit any problems just us a message and we'll help you out."]
-                  [:a.languages-cta-button {:href="#"}
+                   [:a.languages-cta-button {:href="#"}
                     "Sign Up With GitHub"]
-                   ]
-
-                  ]])))))
+                   ]]
+
+                 ])))))


fixed incorrect check for p = 2

fixed incorrect check for p = 2

--- euler-clj/test/euler_clj/core_test.clj
+++ euler-clj/test/euler_clj/core_test.clj
@@ -29,4 +29,6 @@

 (deftest test-problem-3
   (testing "problem-3 for n = 13195")
-    (is (= (problem-3 13195) 29)))
+    (is (= (problem-3 13195) 29))
+  (testing "problem-3 for n = 7")
+    (is (= (problem-3 7) 1)))


Force all d fields to lower case in Clojure

Force all d fields to lower case in Clojure

--- src/webapp/framework/server/db_helper.clj
+++ src/webapp/framework/server/db_helper.clj
@@ -11,17 +11,30 @@
 )

+
+
+
+
+
+(defn to-lower-case-keys [m]
+      (into (empty m) (for [[k v] m] [(keyword (.toLowerCase (name k))) v])))
+
+
+
+
 (defn db-count-records [table-name]
     (:cnt
+      (to-lower-case-keys
      (first
      (korma.core/exec-raw
                    [(str "SELECT COUNT(*) as CNT FROM " table-name)
                     []]
-                    :results)
+                    :results))
     )))

 (defn db-table-fields [table-name]
     (keys
+      (to-lower-case-keys
      (first
      (korma.core/exec-raw
                    [(str "SELECT * FROM " table-name
@@ -37,7 +50,7 @@
                              )                           )
                          )
                     []]
-                    :results)
+                    :results))
     )))

@@ -49,14 +62,16 @@
   ([sql-in params]
   (do
     (let [
-          lower           (.toLowerCase sql-in)
+          lower (.toLowerCase sql-in)
           ]
-      ;(println "SQL from client: " sql-in)
-      (cond
-       (.startsWith lower "select")  (do (comment println "SELECT") (korma.core/exec-raw [sql-in params] :results))
-       :else                         (do (comment println "INSERT") (korma.core/exec-raw [sql-in params]) [])
-   ; []
-    )))
+         ;(println "SQL from client: " sql-in)
+         ;
+           (cond
+             (.startsWith lower "select") (do (comment println "SELECT") (into [] (map   (fn [r] (to-lower-case-keys r));
+                                                                                (korma.core/exec-raw [sql-in params] :results))))
+             :else (do (comment println "INSERT") (korma.core/exec-raw [sql-in params]) [])
+             ; []
+             )))
   )
 )


typo!

typo!

--- src-cljs/qcon/main.cljs
+++ src-cljs/qcon/main.cljs
@@ -519,7 +519,7 @@
                       :range [17 34]}}

             {:subtitle "channels"
-             :bullets ["Form a one-way communcation path way between processes"
+             :bullets ["Form a one-way communcation pathway between processes"
                        "Supported by buffers (fixed buffers, dropping buffers, sliding buffers)"
                        ]
              }


added a test for generate-string with a nil object

--- test/clj_json/core_test.clj
+++ test/clj_json/core_test.clj
@@ -39,4 +39,11 @@
                                        (fn [x] (reduce (fn [acc x] (assoc acc x true)) {} x))}]
     (is (= {"foo" {"bang" true, "bar" true}}
            (json/parse-string
-            (json/generate-string {"foo" #{"bar" "bang"}}))))))+            (json/generate-string {"foo" #{"bar" "bang"}}))))))
+
+(deftest test-redefine-coercions-with-nil
+  (binding [clj-json.core/*coercions* {clojure.lang.PersistentHashSet
+                                       (fn [x] (reduce (fn [acc x] (assoc acc x true)) {} x))}]
+    (is (= nil
+           (json/parse-string
+            (json/generate-string nil))))))


fix publishedAt type

fix publishedAt type

--- ingestion-api/src/ingestion_api/route.clj
+++ ingestion-api/src/ingestion_api/route.clj
@@ -21,6 +21,16 @@
     {:status "OK"
      :warning "For completeness, please provide the 'X-Samsara-publishedTimestamp' header."}))

+
+(defn- to-long
+  "Convert a string to a number when possible, nil otherwhise."
+  [^String num]
+  (when num
+    (try
+      (Long/parseLong num)
+      (catch Exception x nil))))
+
+
 (defroutes app-routes

   (context "/v1" []
@@ -33,7 +43,7 @@
                       (track-distribution "ingestion.payload.size" (count events))
                       (->> events
                            (inject-receivedAt (System/currentTimeMillis))
-                           (inject-publishedAt postingTimestamp)
+                           (inject-publishedAt (to-long postingTimestamp))
                            apply-transformation
                            send!)
                       {:status 202


Fix connect tests to consider provides

Fix connect tests to consider provides

--- test/com/wsscode/pathom/connect_test.cljc
+++ test/com/wsscode/pathom/connect_test.cljc
@@ -3,7 +3,7 @@
             #?(:clj
                [com.wsscode.common.async-clj :refer [go-catch go-promise <!maybe <?]])
             [nubank.workspaces.core :refer [deftest]]
-            #?(:clj [clojure.core.async :as async :refer [go <! <!!]]
+            #?(:clj  [clojure.core.async :as async :refer [go <! <!!]]
                :cljs [cljs.core.async :as async :refer-macros [go] :refer [<!]])
             [com.wsscode.pathom.core :as p]
             [com.wsscode.pathom.connect :as pc]
@@ -219,19 +219,27 @@

 (deftest test-resolver-data
   (is (= (dissoc (pc/resolver-data indexes `user-by-id) ::pc/resolve)
-         #::pc{:input  #{:user/id}
-               :output [:user/name
-                        :user/id
-                        :user/login
-                        :user/age]
-               :sym    `user-by-id}))
+         #::pc{:input    #{:user/id}
+               :output   [:user/name
+                          :user/id
+                          :user/login
+                          :user/age]
+               :provides #:user{:age   {}
+                                :id    {}
+                                :login {}
+                                :name  {}}
+               :sym      `user-by-id}))
   (is (= (dissoc (pc/resolver-data {::pc/indexes indexes} `user-by-id) ::pc/resolve)
-         #::pc{:input  #{:user/id}
-               :output [:user/name
-                        :user/id
-                        :user/login
-                        :user/age]
-               :sym    `user-by-id})))
+         #::pc{:input    #{:user/id}
+               :output   [:user/name
+                          :user/id
+                          :user/login
+                          :user/age]
+               :provides #:user{:age   {}
+                                :id    {}
+                                :login {}
+                                :name  {}}
+               :sym      `user-by-id})))

 (deftest test-merge-io
   (is (= (pc/merge-io {:user/name {}}
@@ -354,12 +362,16 @@
                                          :index-oir        #:user{:age  {#{:user/login} #{user-by-login}}
                                                                   :id   {#{:user/login} #{user-by-login}}
                                                                   :name {#{:user/login} #{user-by-login}}}
-                                         :index-resolvers  {user-by-login #:com.wsscode.pathom.connect{:input  #{:user/login}
-                                                                                :output [:user/name
-                                                                                :user/id
-                                                                                :user/login
-                                                                                :user/age]
-                                                                                :sym    user-by-login}}})))
+                                         :index-resolvers  {user-by-login #:com.wsscode.pathom.connect{:input    #{:user/login}
+                                                                                :output   [:user/name
+                                                                                :user/id
+                                                                                :user/login
+                                                                                :user/age]
+                                                                                :provides #:user{:age   {}
+                                                                                :id    {}
+                                                                                :login {}
+                                                                                :name  {}}
+                                                                                :sym      user-by-login}}})))

   (testing "multiple inputs"
     (is (= (pc/add {} 'user-by-login
@@ -409,13 +421,17 @@
                                                                             :user/login} #{user-by-login}}
                                                                   :name  {#{:user/group
                                                                             :user/login} #{user-by-login}}}
-                                         :index-resolvers  {user-by-login #:com.wsscode.pathom.connect{:input  #{:user/group
-                                                                                :user/login}
-                                                                                :output [:user/name
-                                                                                :user/id
-                                                                                :user/login
-                                                                                :user/age]
-                                                                                :sym    user-by-login}}})))
+                                         :index-resolvers  {user-by-login #:com.wsscode.pathom.connect{:input    #{:user/group
+                                                                                :user/login}
+                                                                                :output   [:user/name
+                                                                                :user/id
+                                                                                :user/login
+                                                                                :user/age]
+                                                                                :provides #:user{:age   {}
+                                                                                :id    {}
+                                                                                :login {}
+                                                                                :name  {}}
+                                                                                :sym      user-by-login}}})))

   (testing "accumulating and nesting"
     (is (= (-> {}
@@ -474,16 +490,22 @@
                                                                   :login   {#{:user/id} #{user-by-id}}
                                                                   :name    {#{:user/id} #{user-by-id}}
                                                                   :network {#{:user/id} #{user-network}}}
-                                         :index-resolvers  {user-by-id   #:com.wsscode.pathom.connect{:input  #{:user/id}
-                                                                                :output [:user/name
-                                                                                :user/id
-                                                                                :user/login
-                                                                                :user/age]
-                                                                                :sym    user-by-id}
-                                                            user-network #:com.wsscode.pathom.connect{:input  #{:user/id}
-                                                                                :output [#:user{:network [:network/id
-                                                                                :network/name]}]
-                                                                                :sym    user-network}}})))
+                                         :index-resolvers  {user-by-id   #:com.wsscode.pathom.connect{:input    #{:user/id}
+                                                                                :output   [:user/name
+                                                                                :user/id
+                                                                                :user/login
+                                                                                :user/age]
+                                                                                :provides #:user{:age   {}
+                                                                                :id    {}
+                                                                                :login {}
+                                                                                :name  {}}
+                                                                                :sym      user-by-id}
+                                                            user-network #:com.wsscode.pathom.connect{:input    #{:user/id}
+                                                                                :output   [#:user{:network [:network/id
+                                                                                :network/name]}]
+                                                                                :provides #:user{:network #:network{:id   {}
+                                                                                :name {}}}
+                                                                                :sym      user-network}}})))

   ; disregards the resolver symbol, just testing nesting adding
   (testing "adding resolver derived from global item should be global"
@@ -503,9 +525,10 @@
                (pc/add 'globals
                  {::pc/input  #{}
                   ::pc/output [:global-value]}))
-           '{::pc/index-resolvers  {globals #::pc{:sym    globals
-                                                  :input  #{}
-                                                  :output [:global-value]}}
+           '{::pc/index-resolvers  {globals #::pc{:sym      globals
+                                                  :input    #{}
+                                                  :output   [:global-value]
+                                                  :provides {:global-value {}}}}
              ::pc/index-attributes {#{}           #::pc{:attribute     #{}
                                                         :attr-provides {:global-value #{globals}}
                                                         :attr-input-in #{globals}}
@@ -624,13 +647,25 @@
                                                  {#{:entity/id} #{com.wsscode.pathom.connect-test/union-root}}},
              :com.wsscode.pathom.connect/index-resolvers
                                                 {com.wsscode.pathom.connect-test/union-root
-                                                 {:com.wsscode.pathom.connect/input #{:entity/id},
-                                                  :com.wsscode.pathom.connect/output
-                                                                                {:address/id [:address/id :address/street :address/number],
-                                                                                :friend/id  [:friend/id :friend/name],
-                                                                                :place/id   [:place/id :place/title]},
-                                                  :com.wsscode.pathom.connect/sym
-                                                                                com.wsscode.pathom.connect-test/union-root}}})))
+                                                 {:com.wsscode.pathom.connect/input    #{:entity/id},
+                                                  :com.wsscode.pathom.connect/output   {:address/id [:address/id :address/street :address/number],
+                                                                                :friend/id  [:friend/id :friend/name],
+                                                                                :place/id   [:place/id :place/title]},
+                                                  :com.wsscode.pathom.connect/provides {:address/id                        {}
+                                                                                :address/number                    {}
+                                                                                :address/street                    {}
+                                                                                :com.wsscode.pathom.connect/unions {:address/id #:address{:id     {}
+                                                                                :number {}
+                                                                                :street {}}
+                                                                                :friend/id  #:friend{:id   {}
+                                                                                :name {}}
+                                                                                :place/id   #:place{:id    {}
+                                                                                :title {}}}
+                                                                                :friend/id                         {}
+                                                                                :friend/name                       {}
+                                                                                :place/id                          {}
+                                                                                :place/title                       {}}
+                                                  :com.wsscode.pathom.connect/sym      com.wsscode.pathom.connect-test/union-root}}})))

   (testing "adding union child"
     (is (= (-> {}
@@ -711,15 +746,29 @@
                                                                                :place/id                          {}
                                                                                :place/title                       {}}}}
                                          :index-oir        {:items {#{:entity/id} #{union-child}}}
-                                         :index-resolvers  {union-child #:com.wsscode.pathom.connect{:input  #{:entity/id}
-                                                                                :output [{:items {:address/id [:address/id
+                                         :index-resolvers  {union-child #:com.wsscode.pathom.connect{:input    #{:entity/id}
+                                                                                :output   [{:items {:address/id [:address/id
                                                                                :address/street
                                                                                :address/number]
                                                                                :friend/id  [:friend/id
                                                                                :friend/name]
                                                                                :place/id   [:place/id
                                                                                :place/title]}}]
-                                                                                :sym    union-child}}})))
+                                                                                :provides {:items {:address/id                        {}
+                                                                                :address/number                    {}
+                                                                                :address/street                    {}
+                                                                                :com.wsscode.pathom.connect/unions {:address/id #:address{:id     {}
+                                                                                :number {}
+                                                                                :street {}}
+                                                                                :friend/id  #:friend{:id   {}
+                                                                                :name {}}
+                                                                                :place/id   #:place{:id    {}
+                                                                                :title {}}}
+                                                                                :friend/id                         {}
+                                                                                :friend/name                       {}
+                                                                                :place/id                          {}
+                                                                                :place/title                       {}}}
+                                                                                :sym      union-child}}})))

   (testing "adding mutation"
     (is (= (pc/add-mutation {} 'do-it {})
@@ -1472,14 +1521,6 @@
            {:prospect/tags {}
             :prospect/cpf  {}}))))

-(comment
-  (pc/discover-attrs #::pc{:index-io {#{:customer/prospects} #:customer{:approved-prospect #:prospect{:tags {}
-                                                                                :cpf  {}}}
-                                      #{:customer/cpf}       #:customer{:prospects #:prospect{:tags {}
-                                                                                :cpf  {}}}}
-                           :idents   #{:customer/cpf}}
-    [:customer/prospects :customer/cpf]))
-
 (deftest test-reprocess-index
   (let [dirty-index (-> {}
                         (pc/add 'abc #::pc{:input #{:customer/wrong} :output [:customer/name]})
@@ -1507,10 +1548,11 @@
                                                               :customer/wrong} #:customer{:name {}}}
                                          :index-oir        #:customer{:name {#{:customer/id
                                                                                :customer/wrong} #{abc}}}
-                                         :index-resolvers  {abc #:com.wsscode.pathom.connect{:input  #{:customer/id
-                                                                                :customer/wrong}
-                                                                                :output [:customer/name]
-                                                                                :sym    abc}}}))))
+                                         :index-resolvers  {abc #:com.wsscode.pathom.connect{:input    #{:customer/id
+                                                                                :customer/wrong}
+                                                                                :output   [:customer/name]
+                                                                                :provides #:customer{:name {}}
+                                                                                :sym      abc}}}))))

 (deftest test-custom-dispatch
   (let [index  (-> {}
@@ -1999,10 +2041,10 @@
                      :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
                     {:com.wsscode.pathom.connect/plan    (([:multi-path
                                                             multi-path-blank])
-                                                           ([:multi-path
-                                                             multi-path-error])
-                                                           ([:multi-path
-                                                             multi-path-value]))
+                                                          ([:multi-path
+                                                            multi-path-error])
+                                                          ([:multi-path
+                                                            multi-path-value]))
                      :com.wsscode.pathom.core/path       [:multi-path]
                      :com.wsscode.pathom.parser/provides #{:multi-path}
                      :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
@@ -2027,8 +2069,8 @@
                      :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
                     {:com.wsscode.pathom.connect/plan    (([:multi-path
                                                             multi-path-error])
-                                                           ([:multi-path
-                                                             multi-path-value]))
+                                                          ([:multi-path
+                                                            multi-path-value]))
                      :com.wsscode.pathom.core/path       [:multi-path]
                      :com.wsscode.pathom.parser/provides #{:multi-path}
                      :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
@@ -2102,10 +2144,10 @@
                      :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
                     {:com.wsscode.pathom.connect/plan    (([:multi-path
                                                             multi-path-blank])
-                                                           ([:multi-path
-                                                             multi-path-value])
-                                                           ([:multi-path
-                                                             multi-path-error]))
+                                                          ([:multi-path
+                                                            multi-path-value])
+                                                          ([:multi-path
+                                                            multi-path-error]))
                      :com.wsscode.pathom.core/path       [:multi-path]
                      :com.wsscode.pathom.parser/provides #{:multi-path}
                      :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
@@ -2130,8 +2172,8 @@
                      :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
                     {:com.wsscode.pathom.connect/plan    (([:multi-path
                                                             multi-path-value])
-                                                           ([:multi-path
-                                                             multi-path-error]))
+                                                          ([:multi-path
+                                                            multi-path-error]))
                      :com.wsscode.pathom.core/path       [:multi-path]
                      :com.wsscode.pathom.parser/provides #{:multi-path}
                      :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
@@ -2206,8 +2248,8 @@
                      :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
                     {:com.wsscode.pathom.connect/plan    (([:multi-path-error
                                                             multi-path-error-error])
-                                                           ([:multi-path-error
-                                                             multi-path-error-blank]))
+                                                          ([:multi-path-error
+                                                            multi-path-error-blank]))
                      :com.wsscode.pathom.core/path       [:multi-path-error]
                      :com.wsscode.pathom.parser/provides #{:multi-path-error}
                      :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
@@ -2281,8 +2323,8 @@
                      :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
                     {:com.wsscode.pathom.connect/plan    (([:multi-path-error
                                                             multi-path-error-blank])
-                                                           ([:multi-path-error
-                                                             multi-path-error-error]))
+                                                          ([:multi-path-error
+                                                            multi-path-error-error]))
                      :com.wsscode.pathom.core/path       [:multi-path-error]
                      :com.wsscode.pathom.parser/provides #{:multi-path-error}
                      :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
@@ -2352,8 +2394,8 @@
                  :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
                 {:com.wsscode.pathom.connect/plan    (([:a
                                                         a]
-                                                        [:b
-                                                         a->b]))
+                                                       [:b
+                                                        a->b]))
                  :com.wsscode.pathom.core/path       [:b]
                  :com.wsscode.pathom.parser/provides #{:a
                                                        :b}
@@ -2398,61 +2440,60 @@
                  :com.wsscode.pathom.trace/event :com.wsscode.pathom.connect/merge-resolver-response
                  :key                            :b}])))

-     #_
-     (testing "multi step resolver waiting"
-       (let [kw (atom {})
-             e  (atom {})]
-         (go
-           (async/<! (async/timeout 10))
-           (swap! e assoc :a 2)
-           (async/>! (-> @kw :a first) {}))
-
-         (is (= (call-parallel-reader {::pp/waiting      #{:a}
-                                       ::pp/key-watchers kw
-                                       ::p/entity        e} :b)
-                #:com.wsscode.pathom.parser{:provides        #{:a
-                                                               :b}
-                                            :response-stream [#:com.wsscode.pathom.parser{:provides       #{:b}
-                                                                                :response-value {:b 12}}]}))
-
-         (is (= (comparable-trace @trace)
-                '[{:com.wsscode.pathom.core/path       [:b]
-                   :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
-                   :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
-                  {:com.wsscode.pathom.connect/plan    (([:a
-                                                          a]
-                                                          [:b
-                                                           a->b]))
-                   :com.wsscode.pathom.core/path       [:b]
-                   :com.wsscode.pathom.parser/provides #{:a
-                                                         :b}
-                   :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
-                   :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
-                  {:com.wsscode.pathom.connect/input-data  {}
-                   :com.wsscode.pathom.connect/sym         a
-                   :com.wsscode.pathom.connect/waiting-key :a
-                   :com.wsscode.pathom.core/path           [:b]
-                   :com.wsscode.pathom.trace/event         :com.wsscode.pathom.connect/waiting-resolver
-                   :key                                    :b}
-                  {:com.wsscode.pathom.connect/input-data {:a 2}
-                   :com.wsscode.pathom.connect/sym        a->b
-                   :com.wsscode.pathom.core/path          [:b]
-                   :com.wsscode.pathom.trace/event        :com.wsscode.pathom.connect/call-resolver-with-cache
-                   :key                                   :b}
-                  {:com.wsscode.pathom.connect/input-data {:a 2}
-                   :com.wsscode.pathom.connect/sym        a->b
-                   :com.wsscode.pathom.core/path          [:b]
-                   :com.wsscode.pathom.trace/direction    :com.wsscode.pathom.trace/enter
-                   :com.wsscode.pathom.trace/event        :com.wsscode.pathom.connect/call-resolver
-                   :com.wsscode.pathom.trace/label        a->b
-                   :key                                   :b}
-                  {:com.wsscode.pathom.core/path       [:b]
-                   :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
-                   :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/call-resolver}
-                  {:com.wsscode.pathom.connect/sym a->b
-                   :com.wsscode.pathom.core/path   [:b]
-                   :com.wsscode.pathom.trace/event :com.wsscode.pathom.connect/merge-resolver-response
-                   :key                            :b}]))))
+     #_(testing "multi step resolver waiting"
+         (let [kw (atom {})
+               e  (atom {})]
+           (go
+             (async/<! (async/timeout 10))
+             (swap! e assoc :a 2)
+             (async/>! (-> @kw :a first) {}))
+
+           (is (= (call-parallel-reader {::pp/waiting      #{:a}
+                                         ::pp/key-watchers kw
+                                         ::p/entity        e} :b)
+                  #:com.wsscode.pathom.parser{:provides        #{:a
+                                                                 :b}
+                                              :response-stream [#:com.wsscode.pathom.parser{:provides       #{:b}
+                                                                                :response-value {:b 12}}]}))
+
+           (is (= (comparable-trace @trace)
+                  '[{:com.wsscode.pathom.core/path       [:b]
+                     :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/enter
+                     :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
+                    {:com.wsscode.pathom.connect/plan    (([:a
+                                                            a]
+                                                           [:b
+                                                            a->b]))
+                     :com.wsscode.pathom.core/path       [:b]
+                     :com.wsscode.pathom.parser/provides #{:a
+                                                           :b}
+                     :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+                     :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
+                    {:com.wsscode.pathom.connect/input-data  {}
+                     :com.wsscode.pathom.connect/sym         a
+                     :com.wsscode.pathom.connect/waiting-key :a
+                     :com.wsscode.pathom.core/path           [:b]
+                     :com.wsscode.pathom.trace/event         :com.wsscode.pathom.connect/waiting-resolver
+                     :key                                    :b}
+                    {:com.wsscode.pathom.connect/input-data {:a 2}
+                     :com.wsscode.pathom.connect/sym        a->b
+                     :com.wsscode.pathom.core/path          [:b]
+                     :com.wsscode.pathom.trace/event        :com.wsscode.pathom.connect/call-resolver-with-cache
+                     :key                                   :b}
+                    {:com.wsscode.pathom.connect/input-data {:a 2}
+                     :com.wsscode.pathom.connect/sym        a->b
+                     :com.wsscode.pathom.core/path          [:b]
+                     :com.wsscode.pathom.trace/direction    :com.wsscode.pathom.trace/enter
+                     :com.wsscode.pathom.trace/event        :com.wsscode.pathom.connect/call-resolver
+                     :com.wsscode.pathom.trace/label        a->b
+                     :key                                   :b}
+                    {:com.wsscode.pathom.core/path       [:b]
+                     :com.wsscode.pathom.trace/direction :com.wsscode.pathom.trace/leave
+                     :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/call-resolver}
+                    {:com.wsscode.pathom.connect/sym a->b
+                     :com.wsscode.pathom.core/path   [:b]
+                     :com.wsscode.pathom.trace/event :com.wsscode.pathom.connect/merge-resolver-response
+                     :key                            :b}]))))

      (testing "multi step resolver when previous value is available"
        (is (= (call-parallel-reader {::pp/waiting #{:a}
@@ -2506,8 +2547,8 @@
                    :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
                   {:com.wsscode.pathom.connect/plan    (([:z2
                                                           no-path-z]
-                                                          [:z3
-                                                           no-path-z1]))
+                                                         [:z3
+                                                          no-path-z1]))
                    :com.wsscode.pathom.core/path       [:z3]
                    :com.wsscode.pathom.parser/provides #{:z2
                                                          :z3}
@@ -2549,8 +2590,8 @@
                  :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
                 {:com.wsscode.pathom.connect/plan    (([:a
                                                         a]
-                                                        [:b
-                                                         a->b]))
+                                                       [:b
+                                                        a->b]))
                  :com.wsscode.pathom.core/path       [:b]
                  :com.wsscode.pathom.parser/provides #{:a
                                                        :b}
@@ -2733,8 +2774,8 @@
                    :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
                   {:com.wsscode.pathom.connect/plan    (([:error
                                                           error]
-                                                          [:d
-                                                           error->d]))
+                                                         [:d
+                                                          error->d]))
                    :com.wsscode.pathom.core/path       [:d]
                    :com.wsscode.pathom.parser/provides #{:d
                                                          :error}
@@ -2782,8 +2823,8 @@
                    :com.wsscode.pathom.trace/event     :com.wsscode.pathom.connect/compute-plan}
                   {:com.wsscode.pathom.connect/plan    (([:error-trail-dep
                                                           error-trail-dep]
-                                                          [:error-trail-final
-                                                           error-trail]))
+                                                         [:error-trail-final
+                                                          error-trail]))
                    :com.wsscode.pathom.core/path       [:error-trail-final]
                    :com.wsscode.pathom.parser/provides #{:error-trail-dep
                                                          :error-trail-final}
@@ -3064,7 +3105,7 @@
              ::pc/input  #{:global}
              ::pc/output [:global-1]}])
          '#{([:global global]
-              [:global-1 global-1])}))
+             [:global-1 global-1])}))

   (is (= (compute-paths :global-2
            [{::pc/sym    'global
@@ -3076,8 +3117,8 @@
              ::pc/input  #{:global-1}
              ::pc/output [:global-2]}])
          '#{([:global global]
-              [:global-1 global-1]
-              [:global-2 global-2])}))
+             [:global-1 global-1]
+             [:global-2 global-2])}))

   (is (= (compute-paths :b
            #{:a}
@@ -3102,8 +3143,8 @@
              ::pc/input  #{:global-a :global-b}
              ::pc/output [:multi]}])
          '#{([:global-a global-a]
-              [:global-b global-b]
-              [:multi multi])}))
+             [:global-b global-b]
+             [:multi multi])}))

   (is (= (compute-paths :multi
            #{:id}
@@ -3114,7 +3155,7 @@
              ::pc/input  #{:a :b}
              ::pc/output [:multi]}])
          '#{([:b from-id]
-              [:multi multi])}))
+             [:multi multi])}))

   (is (= (compute-paths :multi
            #{:id}
@@ -3137,8 +3178,8 @@
              ::pc/input  #{:a :b}
              ::pc/output [:c]}])
          '#{([:dep dep]
-              [:a ab]
-              [:c c])}))
+             [:a ab]
+             [:c c])}))

   (is (= (compute-paths :complex-out
            #{:provided-a
@@ -3162,10 +3203,10 @@
                            :single-dep-b}
              ::pc/output [:complex-out]}])
          '#{([:single-dep-a res-dep-a]
-              [:multi-dep res-multi-dep]
-              [:single-dep-b res-dep-b]
-              [:global-dep global-dep]
-              [:complex-out complex])}))
+             [:multi-dep res-multi-dep]
+             [:single-dep-b res-dep-b]
+             [:global-dep global-dep]
+             [:complex-out complex])}))

   (is (= (compute-paths :account/next-close-date
            #{:customer/id}
@@ -3179,8 +3220,8 @@
              ::pc/input  #{:account/precise-credit-limit :account/id :account/next-due-date}
              ::pc/output [:account/next-close-date]}])
          '#{([:account/id customer]
-              [:account/precise-credit-limit account]
-              [:account/next-close-date balances])}))
+             [:account/precise-credit-limit account]
+             [:account/next-close-date balances])}))

   (is (= (compute-paths :account/id
            #{}
@@ -3218,7 +3259,7 @@
                                                    p/error-handler-plugin
                                                    p/request-cache-plugin
                                                    p/trace-plugin]})
-           res (async/<!! (parser {} query))]
+           res    (async/<!! (parser {} query))]
        (reset! quick-parser-trace* @trace)
        res)))

@@ -3275,7 +3316,7 @@
                                    ::pc/output [:guitar/name :guitar/factory-name]}
                                   (fn [_ {:keys [guitar/id]}]
                                     (Thread/sleep 100)
-                                    {:guitar/name (str id " name")
+                                    {:guitar/name         (str id " name")
                                      :guitar/factory-name "Guitar Factory"}))

                                 (pc/resolver 'camera-name
@@ -3461,11 +3502,11 @@
        (is (= {:com.wsscode.pathom.core/errors {[] "class clojure.lang.ExceptionInfo: Parallel read timeout - {:timeout 200}"}}
               (quick-parser {::p/env       {::pp/key-process-timeout 200}
                              ::pc/register [(pc/resolver 'a
-                                                         {::pc/input  #{}
-                                                          ::pc/output [:whatever]}
-                                                         (fn [_ _]
-                                                           {:whatever (Thread/sleep 210)}))]}
-                            [:whatever]))))
+                                              {::pc/input  #{}
+                                               ::pc/output [:whatever]}
+                                              (fn [_ _]
+                                                {:whatever (Thread/sleep 210)}))]}
+                [:whatever]))))

      (testing "rename ident reads"
        (is (= (async/<!!
@@ -3530,8 +3571,8 @@
                                                   (Thread/sleep 50)
                                                   {:works 42}))]}
                   '[:works :not])
-                {:not :com.wsscode.pathom.core/reader-error,
-                 :works 42,
+                {:not                            :com.wsscode.pathom.core/reader-error,
+                 :works                          42,
                  :com.wsscode.pathom.core/errors {[:not] "class clojure.lang.ExceptionInfo: Deu ruim - {}"}})))

        (testing "partial resolver data, request fully"


Improve the randomness of property space

--- test/com/wsscode/pathom/core_gen_test.clj
+++ test/com/wsscode/pathom/core_gen_test.clj
@@ -17,8 +17,14 @@
   (-> x hash (mod n) zero?))

 (defn key-ex-value [x {::keys [throw-errors?]}]
-  (if (and throw-errors? (hash-mod x 5))
+  (cond
+    (and throw-errors? (hash-mod x 5))
     (throw (ex-info "Demo error" {:x x}))
+
+    (hash-mod x 10)
+    nil
+
+    :else
     (str x)))

 (defn reader [{:keys [ast query depth-limit] :as env}]
@@ -85,7 +91,9 @@
    ::p/union-path (fn [env] (-> env :ast :children first :children first :union-key))})

 (defn base-gen []
-  (let [props (gen/sample gen/keyword 10)]
+  (let [props (gen/generate (gen/vector-distinct gen/keyword {:min-elements 8
+                                                              :max-elements 20})
+                8)]
     (s.query/make-gen {::s.query/gen-property
                        (fn [_] (gen/elements props))


fix tests

fix tests

--- test/tabby/cluster_test.clj
+++ test/tabby/cluster_test.clj
@@ -40,10 +40,10 @@
     (let [s1 (step 0 (test-cluster 3))] ; step 1 become candidate & send request-vote
       (is (= '(:candidate :follower :follower) (fields-by-id s1 :type)))
       (is (= '(1 0 0) (fields-by-id s1 :current-term)))
-      (is (= '({:dst 2 :src 0 :type :request-vote
+      (is (= '({:dst 1 :src 0 :type :request-vote
                 :body {:term 1 :candidate-id 0, :prev-log-index 0
                        :prev-log-term 0}}
-               {:dst 1 :src 0 :type :request-vote
+               {:dst 2 :src 0 :type :request-vote
                 :body {:term 1 :candidate-id 0, :prev-log-index 0
                        :prev-log-term 0}}) (:tx-queue (get (:servers s1) 0))))))
   (testing "step 2 - peers respond to request vote"
@@ -80,34 +80,34 @@
     (let [s (->> (test-cluster 3)
                  (step-times 0 4))]
       (is (= '({:dst 0 :src 1 :type :append-entries-response
-                :body {:term 1 :success true :count 0}}) (:tx-queue (srv 1))))
+                :body {:term 1 :success true :count 0}}) (:tx-queue (srv s 1))))
       (is (= '({:dst 0 :src 2 :type :append-entries-response
-                :body {:term 1 :success true :count 0}}) (:tx-queue (srv 2))))))
+                :body {:term 1 :success true :count 0}}) (:tx-queue (srv s 2))))))
   (testing "step 5 - heart beat response"
     (let [s (->> (test-cluster 3)
                  (step-times 0 5))]
-      (is (= {2 0 1 0} (:match-index (srv 0))))))
+      (is (= {2 0 1 0} (:match-index (srv s 0))))))

   (testing "step 6 - system write"
     (let [s (->> (test-cluster 3)
                  (until-empty)
                  (write {:a "a"}))]

-      (is (= '({:dst 2 :src 0
+      (is (= '({:dst 1 :src 0
                 :type :append-entries
                 :body {:term 1 :leader-id 0
                        :prev-log-index 0
                        :prev-log-term 0
                        :entries [{:term 1 :cmd {:a "a"}}]
                        :leader-commit 0}}
-               {:dst 1 :src 0
+               {:dst 2 :src 0
                 :type :append-entries
                 :body {:term 1 :leader-id 0
                        :prev-log-index 0
                        :prev-log-term 0
                        :entries [{:term 1 :cmd {:a "a"}}]
                        :leader-commit 0}})
-             (:tx-queue (srv 0))))))
+             (:tx-queue (srv s 0))))))

   (testing "step 7 wait for commit index"
     (let [s (->> (test-cluster 3)


Prevent top-bar items to wrap

Prevent top-bar items to wrap

--- frontend/styles/faceboard/css/topbar.clj
+++ frontend/styles/faceboard/css/topbar.clj
@@ -12,7 +12,8 @@
       :height header-height
       :line-height (px 18)
       :background-color signature-color
-      :font-size (px 12)]
+      :font-size (px 12)
+      :white-space :nowrap]
      (>> [> *]
        [:display :inline-block])
      (>> [logo "a"]


remove unused query

remove unused query

--- src/main/shadow/cljs/ui/components/inspect.cljs
+++ src/main/shadow/cljs/ui/components/inspect.cljs
@@ -313,9 +313,6 @@

   (bind stream-ref (sg/ref))

-  (bind {::m/keys [tap-latest]}
-    (sg/query-root [::m/tap-latest]))
-
   (event ::kb-select! [env {:keys [item]}]
     (sg/dispatch-up! env {:e ::inspect-object! :ident (:object-ident item)}))


Fixes #54

Fixes #54

--- kafka-clj/src/kafka_clj/redis/cluster.clj
+++ kafka-clj/src/kafka_clj/redis/cluster.clj
@@ -5,7 +5,7 @@
             [clojure.tools.logging :refer [info error]])
   (:import [kafka_clj.util Util]
            [org.redisson.api RedissonClient RBucket RLock RScript$Mode RScript$ReturnType]
-           [org.redisson.config ClusterServersConfig Config SentinelServersConfig]
+           [org.redisson.config ClusterServersConfig Config SentinelServersConfig ReadMode]
            [org.redisson Redisson]
            [java.nio ByteBuffer]
            (java.util Queue List)
@@ -141,7 +141,7 @@
     (.setSlaveSubscriptionConnectionPoolSize config (clojure.core/get redis-conf :slave-subscription-connection-pool-size 500))

     ;;we need read from slaves to be false, this otherwise produces connection issues
-    (.setReadFromSlaves config false)
+    (.setReadMode config ReadMode/MASTER)
     (.addNodeAddress config (into-array String (mapv #(Util/correctURI (str %)) hosts)))
     conf))

@@ -256,4 +256,4 @@

 (defn create
   ([redis-conf]
-    (->RedissonObj (connect redis-conf))))+    (->RedissonObj (connect redis-conf))))


First pass at not reallocating a preallocated group task.

--- src/onyx/scheduling/balanced_task_scheduler.clj
+++ src/onyx/scheduling/balanced_task_scheduler.clj
@@ -39,6 +39,10 @@
       0
       (min (get-in replica [:saturation job] Double/POSITIVE_INFINITY) n))))

+(defn preallocated-grouped-task? [replica job task]
+  (and (not (nil? (get-in replica [:flux-policies job task])))
+       (> (count (get-in replica [:allocations job task])) 0)))
+
 (defn reuse-spare-peers [replica job tasks spare-peers]
   (loop [[head & tail :as task-seq] (get-in replica [:tasks job])
          results tasks
@@ -46,7 +50,8 @@
     (let [tail (vec tail)]
       (cond (or (<= capacity 0) (not (seq task-seq)))
             results
-            (< (get results head) (or (get-in replica [:task-saturation job head] Double/POSITIVE_INFINITY)))
+            (and (< (get results head) (or (get-in replica [:task-saturation job head] Double/POSITIVE_INFINITY)))
+                 (not (preallocated-grouped-task? replica job head)))
             (recur (conj tail head) (update-in results [head] inc) (dec capacity))
             :else
             (recur tail results capacity)))))
@@ -63,9 +68,13 @@
             init
             (reduce
              (fn [all [task k]]
-               (assoc all task (min (get-in replica [:task-saturation job task] Double/POSITIVE_INFINITY)
-                                    (get-in replica [:min-required-peers job task] Double/POSITIVE_INFINITY)
-                                    (if (< k r) max-peers (max min-peers (get-in replica [:min-required-peers job task]))))))
+               ;; If it's a grouped task that has already been allocated,
+               ;; we can't add more peers since that would break the hashing algorithm.
+               (if (preallocated-grouped-task? replica job task)
+                 all
+                 (assoc all task (min (get-in replica [:task-saturation job task] Double/POSITIVE_INFINITY)
+                                      (get-in replica [:min-required-peers job task] Double/POSITIVE_INFINITY)
+                                      (if (< k r) max-peers (max min-peers (get-in replica [:min-required-peers job task])))))))
              {}
              (map vector tasks (range)))
             spare-peers (- n (apply + (vals init)))]


More deobfuscation of query operator definitions.

--- clj_record/query.clj
+++ clj_record/query.clj
@@ -2,32 +2,29 @@
   (:require [clojure.contrib.str-utils :as str-utils]))

-(defmacro query-operator
-  ([operator-format]               (query-operator operator-format '[value]))
-  ([operator-format args]          (query-operator operator-format args nil))
-  ([operator-format args join-with]
-    (let [params (if (= "&" (name (first args))) (symbol (name (second args))) args)]
-      `(fn ~args
-        (fn [attribute#]
-          (let [clause-params-vector#
-                  (reduce
-                    (fn [operator-params# value#]
-                      (conj operator-params# (if (nil? value#) (throw (Exception. "A query argument must not be nil.")) "?"))) [] ~params)
-                clause-params#
-                  (if (nil? ~join-with)
-                    (apply str clause-params-vector#)
-                    (str-utils/str-join ~join-with clause-params-vector#))]
-            [(format (str "%s " ~operator-format) (name attribute#) clause-params#) (filter (complement nil?) ~params)]))))))
+(defn- operator-fn
+  ([operator-format values] (operator-fn operator-format values nil))
+  ([operator-format values join-with]
+    (fn [attribute]
+      (let [clause-params-vector
+              (reduce
+                (fn [operator-params value]
+                  (conj operator-params (if (nil? value) (throw (Exception. "A query argument must not be nil.")) "?"))) [] values)
+            clause-params
+              (if (nil? join-with)
+                (apply str clause-params-vector)
+                (str-utils/str-join join-with clause-params-vector))]
+        [(format (str "%s " operator-format) (name attribute) clause-params) (filter (complement nil?) values)]))))

-(def equal (query-operator "= %s"))
-(def not-equal (query-operator "<> %s"))
-(def greater-than (query-operator "> %s"))
-(def greater-than-or-equal (query-operator ">= %s"))
-(def less-than (query-operator "< %s"))
-(def less-than-or-equal (query-operator "<= %s"))
-(def like (query-operator "LIKE %s" [pattern]))
-(def not-like (query-operator "NOT LIKE %s" [pattern]))
-(def between (query-operator "BETWEEN %s" [value1 value2] " AND "))
-(def not-between (query-operator "NOT BETWEEN %s" [value1 value2] " AND "))
-(def in (query-operator "IN (%s)" [& values] ", "))
-(def not-in (query-operator "NOT IN (%s)" [& values] ", "))
+(defn equal [value] (operator-fn "= %s" [value]))
+(defn not-equal [value] (operator-fn "<> %s" [value]))
+(defn greater-than  [value] (operator-fn "> %s" [value]))
+(defn greater-than-or-equal [value] (operator-fn ">= %s" [value]))
+(defn less-than [value] (operator-fn "< %s" [value]))
+(defn less-than-or-equal [value] (operator-fn "<= %s" [value]))
+(defn like [pattern] (operator-fn "LIKE %s" [pattern]))
+(defn not-like [pattern] (operator-fn "NOT LIKE %s" [pattern]))
+(defn between [value1 value2] (operator-fn "BETWEEN %s" [value1 value2] " AND "))
+(defn not-between [value1 value2] (operator-fn "NOT BETWEEN %s" [value1 value2] " AND "))
+(defn in [& values] (operator-fn "IN (%s)" values ", "))
+(defn not-in [& values] (operator-fn "NOT IN (%s)" values ", "))


avoids merge when old entry is an empty map (#1508)

--- waiter/src/waiter/service_description.clj
+++ waiter/src/waiter/service_description.clj
@@ -404,7 +404,7 @@
             provided-param-value (get provided-params parameter-key)]
         (recur remaining-parameter-keys
                (cond-> loop-params
-                 (and (map? default-param-value) (map? provided-param-value))
+                 (and (map? default-param-value) (seq default-param-value) (map? provided-param-value))
                  (assoc parameter-key (merge default-param-value provided-param-value)))))
       loop-params)))


Attempt to fix async test on Travis

Attempt to fix async test on Travis

--- test/clojurewerkz/cassaforte/async_test.clj
+++ test/clojurewerkz/cassaforte/async_test.clj
@@ -13,12 +13,12 @@
          result (atom nil)]
      (insert :users record)

+     (add-watch result :result
+                (fn [_ _ _ res]
+                  (is (= record (first res)))
+                  (is (= record
+                         (first (get-result (async (select :users))))))))
+
      (set-callbacks
       (async (select :users))
-      :success (fn [r] (reset! result r)))
-
-     (Thread/sleep 20)
-     (is (= record (first @result)))
-
-     (is (= record
-            (first (get-result (async (select :users)))))))))
+      :success (fn [r] (reset! result r))))))


Improve docstring for spider

Improve docstring for spider

--- src/attercop/spider.clj
+++ src/attercop/spider.clj
@@ -193,32 +193,33 @@
   Config
   ------

-    :name(str) - human readable name for the scraper
-
-    :allowed-domains(set) - urls of these will only be considered.
-
-    :start-urls(seq) - scraping/crawling will start with these
-
-    :rules(seq of vectors) - A rule is a vector of two elements, 1. a
-  regular expression or the keyword :default 2. a map with
-  fields :scrape (fn) and :follow (bool)
-
-    :pipeline(seq of functions) - functions transforming or doing
-  something with the scraped results.
-
-    :max-wait(integer) - Timeout for the HTTP requests in ms.
+    :name ; [str] human readable name for the scraper
+
+    :allowed-domains ; [set] urls of these will only be considered.
+
+    :start-urls ; [seq] scraping/crawling will start with these
+
+    :rules ; [seq] A rule is a vector of two elements, 1. a regular
+  expression or the keyword :default 2. a map with fields :scrape (fn)
+  and :follow (bool)
+
+    :pipeline ; [seq] functions transforming or doing something with
+  the scraped results.
+
+    :max-wait ; [integer] Timeout for the HTTP requests in ms.
   [Default: 5000]

-    :rate-limit(vector) - [m, i] which means, 'm' max-hits in 'i' ms
-  [Default: [5 3000]]
-
-    :handle-status-codes(set) - Additional status codes to be handled
-  by the scraper besides the standard valid ones ie. 2xx and 3xx.
-
-    :graceful-shutdown?(bool|integer) - If non-falsy, the spider will
-  be gracefully shutdown. Truthy values may be boolean or a number
-  representing time to wait in milliseconds. If boolean, the timeout
-  will be same as max-wait [default: 5000]
+    :rate-limit ; [vector] (Optional) eg. [m, i] which means, 'm'
+  max-hits in 'i' ms [Default: [5 3000]]
+
+    :handle-status-codes ; [set] (Optional) Additional status codes to
+  be handled by the scraper besides the standard valid ones ie. 2xx
+  and 3xx.
+
+    :graceful-shutdown? ; [bool|integer] (Optional) If non-falsy, the
+  spider will be gracefully shutdown. Truthy values may be boolean or
+  a number representing time to wait in milliseconds. If boolean, the
+  timeout will be same as max-wait [default: 5000]
   "
   [{:keys [graceful-shutdown? max-wait]
     :as config


Factoring out some OS specific code

Factoring out some OS specific code

--- src/brevis/ui/core.clj
+++ src/brevis/ui/core.clj
@@ -38,7 +38,7 @@

 ;; ## Globals

-(def workspace-directory (atom "/Users/kyle/git"))
+(def workspace-directory (atom (str (System/getProperty "user.home") File/separator "git") #_"/Users/kyle/git"))

 (def editor-window
   "Keeping track of the open editor window." (atom nil))
@@ -113,6 +113,7 @@

 ;;

+(def chooser (javax.swing.JFileChooser.)) ; FileChooser hack to get system icons
 (def current-filename (atom nil))

 (defn get-editor
@@ -324,6 +325,16 @@
            ;textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
            ;textArea.setCodeFoldingEnabled(true);
            sp (RTextScrollPane. textArea)
+           tabs (tabbed-panel :placement :top ;:overflow :wrap
+                              :tabs [{:title (label;; title is not a string but a label component
+                                                   :id (str (gensym "editor-panel"))
+                                                   ;; current-filename isn't set when this function is called
+                                                   :text "*current*"#_(last (string/split @current-filename #"/")) #_@current-filename;; with text set to txt
+                                                   :foreground :blue)
+                                      #_@current-filename
+                                      :tip @current-filename
+                                      :icon (.getIcon chooser (file @current-filename))
+                                      :content sp}])
            a-new (action :handler a-new :name "New" :tip "Create a new file.")
            a-open (action :handler a-open :name "Open" :tip "Open a file")
            a-save (action :handler a-save :name "Save" :tip "Save the current file.")
@@ -358,7 +369,6 @@
            #_(.put (.getActionMap textArea)
               (:name keybind)
               (:action keybind))))
-
        (.setSyntaxEditingStyle textArea (cond (= (:language params) :java)
                                               (SyntaxConstants/SYNTAX_STYLE_JAVA)
                                               :else
@@ -369,6 +379,7 @@
        #_(.setLocation f 0 0)
        {;:frame f
         :text-area textArea
+        :tabbed-panel tabs
         :scroll-pane sp
         :menus menus}))

@@ -553,7 +564,7 @@
                                            :text "> ")
           area (scrollable text-area)
           listener-thread (Thread. (fn []
-                                     (loop []
+                                     (loop [] ;; should probably at least check something for a termination condition
                                        (let [resp (nrepl.transport/recv (:client @repl) 20)]
                                          (when resp
                                            (when (:out resp) (write-stdout-repl (:out resp)))
@@ -576,8 +587,6 @@
     (fn [f] (filter #(or (.isDirectory %) (.isFile %)) (.listFiles f)))
     (File. @workspace-directory)
     #_(File. ".")))
-
-(def chooser (javax.swing.JFileChooser.)) ; FileChooser hack to get system icons

 (defn render-file-item
   [renderer {:keys [value]}]
@@ -627,7 +636,7 @@
                          :items [[#_(:scroll-pane (get-editor))
                                   (left-right-split
                                     (:scrollable @project-browser)
-                                    (:scroll-pane (get-editor))
+                                    (:tabbed-panel (get-editor)) #_(:scroll-pane (get-editor))
                                     :divider-location 0.2) "wrap, span 2, w 100%, h 75%"]
                                  [(:scroll-pane @repl-input-window) "w 50%, h 25%"]
                                  [(:scrollable @repl-output-window) "w 50%, h 25%"]]
@@ -664,7 +673,7 @@
         r-is System/in #_(java.io.ByteArrayInputStream.
                           #_(.getBytes "(println 'foobar)\nexit\n(println 'foobar)\n"))
         r-os (java.io.ByteArrayOutputStream.)
-        project (project/read (str (:current-project @current-profile) "/project.clj"))
+        project (project/read (str (:current-project @current-profile) File/separator "project.clj"))
         #_(project/read project-filename)
         #_(assoc (project/read (str (:current-project @current-profile) "/project.clj") #_project-filename)
                 :repl-options {:input-stream r-is :output-stream r-os})
@@ -699,7 +708,7 @@
     (reset! repl-output-window ro)
     (reset! current-filename (:current-filename @current-profile))
     (make-ui)
-    (load-file "src/brevis/ui/keybinds.clj")
+    (load-file (str "src" File/separator "brevis" File/separator "ui" File/separator "keybinds.clj"))
     (.setText (:text-area ew) (slurp @current-filename))))

 (when (find-ns 'ccw.complete)


(lexemes-before-phrases) should take into account max-total-depth

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -218,9 +218,8 @@

 (defn lexemes-before-phrases [depth]
   ;; takes depth as an argument; make phrases decreasingly likely as depth increases.
-  (let [result (> (rand-int (- 1 depth)) 0)]
-    (log/trace (str "lexemes-before-phrases: depth=" depth " => " result))
-    result))
+  (let [prob (- 1.0 (/ (- max-total-depth depth) max-total-depth))]
+    (> (* 10 prob) (rand-int 10))))

 (defn show-bolt [bolt path morph]
   (if (not (empty? path))


+(defn rules-for-spec)

+(defn rules-for-spec)

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -47,26 +47,52 @@
   (first (gen spec language-model)))

 (defn gen
-  "generate a potentially infinite (depending on given _model_) list of expressions that match the given _spec_."
+  "generate a potentially infinite (depending on given _spec_ and _model_)
+   list of expressions that match the given _spec_."
   [spec model]
   (grow (parent-with-head spec model 0) model))
+
+(defn rules-for-spec [spec model]
+  (->> (cond (and true (= spec)
+                {:synsem {:sem {:reflexive false
+                                :aspect :perfect
+                                :tense :present
+                                :subj {:null false
+                                       :city false
+                                       :can-be-subject true
+                                       :number :plur
+                                       :gender :fem
+                                       :human true
+                                       :pred :loro}
+                                :obj :unspec
+                                :pred :tell}
+                          :cat :verb
+                          :subcat []}
+                 :comp {:phrasal false}})
+             (map (fn [rule]
+                    (get (:grammar-map model) (keyword rule)))
+                  ["sentence-nonphrasal-head"])
+
+             true
+             (:grammar model))
+
+       (map #(unify % spec))
+       (filter #(not (= :fail %)))))

 (defn parent-with-head
   "Return every possible tree of depth 1 from the given spec and model."
   [spec model depth]
   ;; get all rules that match input _spec_:
   (if (nil? spec) (throw (Exception. (str "nope: spec was nil."))))
-  (->>
-   ;; 1: get all rules that satisfy _spec_.
-   (->> (shuffle (:grammar model))
-        (map #(unify % spec))
-        (filter #(not (= :fail %))))
-
-   ;; 2. try to add heads to each matching rule.
-   (parent-with-head-1 spec model depth)
-
-   (filter #(not (= % :fail)))
-   (map #(u/assoc-in! % [::started?] true))))
+  (let [matching-rules
+        (shuffle (rules-for-spec spec model))]
+    (->> matching-rules
+         (map #(unify % spec))
+         (filter #(not (= :fail %)))
+         ;; 2. try to add heads to each matching rule:
+         (parent-with-head-1 spec model depth)
+         (filter #(not (= % :fail)))
+         (map #(u/assoc-in! % [::started?] true)))))

 (defn parent-with-head-1 [spec model depth parent-rules]
   (if (not (empty? parent-rules))


more simplification

more simplification

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -48,13 +48,11 @@
     (log/debug (str "generate-all:" depth "/" max-depth ":         " (strip-refs spec)))
     (->>
      (lightning-bolts model spec depth max-depth)
+     (filter not-fail?)
      (map (fn [bolt]
-            (let [comp-paths-to-complements
-                  (comp-paths-to-complements bolt (find-comp-paths bolt) model depth max-depth)]
-              (if (and (not-fail? bolt)
-                       (not (some empty? comp-paths-to-complements)))
-                (assoc comp-paths-to-complements
-                       [] [bolt])))))
+            (assoc
+             (comp-paths-to-complements bolt (find-comp-paths bolt) model depth max-depth)
+             [] [bolt])))
      (mapcat (fn [each-bolt-and-comps]
                (map (fn [each-path-through-trellis]
                       (zipmap (keys each-bolt-and-comps)
@@ -65,12 +63,12 @@
                    (let [bolt (get bolt-and-comps [])
                          bolt-and-comps (dissoc bolt-and-comps [])]
                      (cons bolt
-                           (map (fn [path]
-                                  (let [result (assoc-in bolt path (get bolt-and-comps path))]
-                                    (if (= true truncate)
-                                      (dissoc-paths result [path])
-                                      result)))
-                                (keys bolt-and-comps)))))))
+                           (->> (keys bolt-and-comps)
+                                (map (fn [path]
+                                       (let [result (assoc-in bolt path (get bolt-and-comps path))]
+                                         (if (= true truncate)
+                                           (dissoc-paths result [path])
+                                           result))))))))))
      (map (fn [expression]
             (do-defaults expression model)))
      (filter not-fail?)


+require babel.italiano.lexicon/lexicon

+require babel.italiano.lexicon/lexicon

--- src/babel/italiano.cljc
+++ src/babel/italiano.cljc
@@ -3,6 +3,7 @@
    [babel.engine :as engine]
    [babel.forest :as forest]
    [babel.italiano.grammar :refer [medium]]
+   [babel.italiano.lexicon :refer [lexicon]]
    [babel.italiano.morphology :as morph :refer [fo]]
    [babel.parse :as parse]
    [clojure.string :as string]))


Add read/write float and double functions to IBuffer abstraction.

With corresponding implementations for NIO and Netty.

--- src/bytebuf/buffer.clj
+++ src/bytebuf/buffer.clj
@@ -12,6 +12,10 @@
   (write-int [_ pos value] "Write an integer to the buffer.")
   (read-long [_ pos] "Read an long (64 bits) from buffer.")
   (write-long [_ pos value] "Write a long to the buffer.")
+  (read-float [_ pos] "Read an float (32 bits) from buffer.")
+  (write-float [_ pos value] "Write a float to the buffer.")
+  (read-double [_ pos] "Read an double (64 bits) from buffer.")
+  (write-double [_ pos value] "Write a double to the buffer.")
   (read-byte [_ pos] "Read one byte from buffer.")
   (write-byte [_ pos value] "Write one byte to the buffer.")
   (read-bytes [_ pos size] "Read a byte array.")
@@ -36,6 +40,14 @@
     (.getLong buff pos))
   (write-long [buff pos value]
     (.putLong buff pos value))
+  (read-float [buff pos]
+    (.getFloat buff pos))
+  (write-float [buff pos value]
+    (.putFloat buff pos value))
+  (read-double [buff pos]
+    (.getDouble buff pos))
+  (write-double [buff pos value]
+    (.putDouble buff pos value))
   (read-byte [buff pos]
     (.get buff pos))
   (write-byte [buff pos value]
@@ -66,6 +78,14 @@
     (.getLong buff pos))
   (write-long [buff pos value]
     (.setLong buff pos value))
+  (read-float [buff pos]
+    (.getFloat buff pos))
+  (write-float [buff pos value]
+    (.setFloat buff pos value))
+  (read-double [buff pos]
+    (.getDouble buff pos))
+  (write-double [buff pos value]
+    (.setDouble buff pos value))
   (read-byte [buff pos]
     (.getByte buff pos))
   (write-byte [buff pos value]


RS | #89 | Add translation test for sign-up page - future-fact until masthead is translated

--- test/objective8/integration/front_end/index.clj
+++ test/objective8/integration/front_end/index.clj
@@ -225,3 +225,18 @@
                                                    :response)]
                status => 200
                body => helpers/no-untranslated-strings)))
+
+(def twitter-callback-url (str utils/host-url "/twitter-callback?oauth_verifier=VERIFICATION_TOKEN"))
+
+(facts "about rendering sign-up page"
+       (future-fact "there are no untranslated strings"
+             (against-background
+               (oauth/access-token anything anything anything) => {:user_id "TWITTER_ID"}
+               (http-api/find-user-by-twitter-id "twitter-TWITTER_ID") => {:status ::http-api/not-found})
+             (let [user-session (helpers/test-context)
+                   {status :status body :body} (-> user-session
+                                                   (p/request twitter-callback-url)
+                                                   p/follow-redirect
+                                                   :response)]
+               status => 200
+               body => helpers/no-untranslated-strings)))


(MAINT) Remove classname/subprotocol from tests

This specifically removes the fields from our "call-with-pdb-instance"
tests which leads test output like:

  The [database] classname setting has been retired and will be ignored.
  The [database] subprotocol setting has been retired and will be ignored.

--- test/puppetlabs/puppetdb/testutils/services.clj
+++ test/puppetlabs/puppetdb/testutils/services.clj
@@ -82,6 +82,9 @@
               x))
     metrics))

+(defn strip-retired-config [config]
+  (update config :database dissoc :classname :subprotocol))
+
 (defn call-with-puppetdb-instance
   "Stands up a puppetdb instance with the specified config, calls f,
   and then tears the instance down, binding *server* to the instance
@@ -103,6 +106,7 @@
    (when (zero? bind-attempts)
      (throw (RuntimeException. "Repeated attempts to bind port failed, giving up")))
    (let [config (-> config
+                    strip-retired-config
                     conf/adjust-and-validate-tk-config
                     assoc-open-port)
          port (or (get-in config [:jetty :port])


OM-692: om.next/update-query has apply misplaced

same as Om 1816c7d033ec08b1672b4a1d92fb1a9e93da76f4

--- src/cellophane/next.clj
+++ src/cellophane/next.clj
@@ -773,9 +773,9 @@
          :params (get-params component)}
        arg0 arg1 arg2)))
   ([component f arg0 arg1 arg2 arg3 & arg-rest]
-   (apply set-query! component
-     (f {:query  (get-unbound-query component)
-         :params (get-params component)}
+   (set-query! component
+     (apply f {:query  (get-unbound-query component)
+               :params (get-params component)}
        arg0 arg1 arg2 arg3 arg-rest))))

 ;; =============================================================================


remove unused copy

remove unused copy

--- src-cljs/frontend/components/landing.cljs
+++ src-cljs/frontend/components/landing.cljs
@@ -116,10 +116,7 @@
               (common/google-login :small)]]
             [:div.our-philosphy-wrap
              [:div.our-philosphy.content
-              ; [:h1 "Collaborating with your team should be easy from anywhere."]
               [:h1 "Collaboration should be simple."]
-              ; [:p "Prototype ideas anywhere, with anyone, and on any device. No nonsense, it's just what you need, when you need it."]
-              ; [:p "Prototype anywhere on any device. No nonsense, it's just what you need, when you need it."]
               [:p "Prototype anywhere on any device. No nonsense, just what you need when you need it."]
               [:div.call-to-action
                (om/build make-button app)]]]]
@@ -173,17 +170,11 @@
             [:div.our-claim
              [:div.our-philosphy-wrap
               [:div.our-philosphy.content
-               ; [:h1 "It's pure prototyping, just focus on your ideas."]
-               ; [:h1 "It's pure prototyping, that's it."]
-               ; [:h1 "Purely productive prototyping."]
                [:h1 "It's purely productive prototyping."]
-               ; [:p "Productive prototyping without all the nonsense."]
                [:p "Precursor is the easiest way to share ideas with your teammates, fast."]
                [:div.call-to-action
                 (common/google-login)
-                ; [:button {:on-click #(cast! :landing-closed)} "Or jump in first."]
-                (om/build make-button app)
-                ]]]
+                (om/build make-button app)]]]
              [:div.navigation
               [:div.content
                [:a {:role "button"} "Precursor"]


Box tests

Box tests

--- src/clj/brutha/geo.clj
+++ src/clj/brutha/geo.clj
@@ -1,13 +1,13 @@
 (ns clj.brutha.geo
   (:require [brutha.math :refer [sqrt]]))

-(defprotocol IPos
+(defprotocol IPoint
   (-x [p])
   (-y [p])
   (-vec [p]))

 (defrecord Point [x y]
-  IPos
+  IPoint
   (-x [_]
     x)
   (-y [_]
@@ -15,7 +15,10 @@
   (-vec [_]
     [x y]))

-(extend-protocol IPos
+(defn point? [p]
+  (satisfies? IPoint p))
+
+(extend-protocol IPoint
   clojure.lang.PersistentVector
   (-x [[x _]]
     x)
@@ -77,9 +80,14 @@

 (defprotocol IBox
   (-top-left [b])
+  (-top-right [b])
+  (-bottom-left [b])
   (-bottom-right [b])
   (-dims [b])
   (-center [b]))
+
+(defn box? [b]
+  (satisfies? IBox b))

 (defrecord Box [tl br]
   IBox
@@ -87,6 +95,14 @@
     tl)
   (-bottom-right [_]
     br)
+  (-top-right [_]
+    (let [[t l] (-vec tl)
+          [b r] (-vec br)]
+      (point t r)))
+  (-bottom-left [_]
+    (let [[t l] (-vec tl)
+          [b r] (-vec br)]
+      (point b l)))
   (-dims [_]
     (p- br tl))
   (-center [_]
@@ -101,6 +117,14 @@
     tl)
   (-bottom-right [_]
     (p+ tl dims))
+  (-top-right [_]
+    (let [[t l] (-vec tl)
+          [b r] (-vec (p+ tl dims))]
+      (point t r)))
+  (-bottom-left [_]
+    (let [[t l] (-vec tl)
+          [b r] (-vec (p+ tl dims))]
+      (point b l)))
   (-dims [_]
     dims)
   (-center [_]
@@ -115,3 +139,33 @@
 (defn rect [tl dims]
   {:pre [(p>= dims [0 0])]}
   (->Rect tl dims))
+
+(defn p-inside? [p b]
+  (let [tl (-top-left b)
+        br (-bottom-right b)]
+    (and (p<= tl p)
+         (p>= br p))))
+
+(defn b-inside? [b1 b2]
+  (let [tl (-top-left b1)
+        br (-bottom-right b1)]
+    (and (p-inside? b2 tl)
+         (p-inside? b2 br))))
+
+(defn inside? [x b]
+  (cond
+   (point? x) (p-inside? x b)
+   (box? x) (b-inside? x b)
+   :else false))
+
+(defn corners [b]
+  [(-top-left b)
+   (-top-right b)
+   (-bottom-right b)
+   (-bottom-left b)])
+
+(defn intersects? [b1 b2]
+  (->> b2
+       corners
+       (some #(inside? % b1))
+       some?))


fix beaucoup landing page rollbars

fix beaucoup landing page rollbars

- only immediate children are accessible by React `refs`
- use DOM lookup to find descendent node instead

--- src-cljs/frontend/components/landing.cljs
+++ src-cljs/frontend/components/landing.cljs
@@ -139,7 +139,7 @@

 (def view "home")

-(defn home-cta [{:keys [source]} owner]
+(defn home-cta [{:keys [source cta-class]} owner]
   (reify
     om/IDidMount
     (did-mount [_]
@@ -147,10 +147,10 @@
     om/IRender
     (render [_]
       (html
-        [:a.home-action {:href "/signup"
-                       :role "button"
-                       :ref "prolog-cta"
-                       :on-mouse-up #(analytics/track-signup-click {:view source})}
+       [:a.home-action {:class cta-class
+                        :href "/signup"
+                        :role "button"
+                        :on-mouse-up #(analytics/track-signup-click {:view source})}
        (str (common/sign-up-text))]))))

 (defn prolog [data owner {:keys [logo-visibility-callback
@@ -165,9 +165,11 @@
                                    :header-overlap-px (atom 0)})
     om/IDidMount
     (did-mount [_]
-      (scroll/register owner
+      (scroll/register
+       owner
        #(let [logo (om/get-node owner "center-logo")
-              cta (om/get-node owner "prolog-cta")
+              container (om/get-node owner)
+              cta (utils/sel1 container ".prolog-cta")
               prolog (om/get-node owner "home-prolog")
               logo-visible? (neg? (.-bottom (.getBoundingClientRect logo)))
               cta-visible? (neg? (.-bottom (.getBoundingClientRect cta)))
@@ -195,7 +197,8 @@
     (render [_]
       (html
        [:section.home-prolog {:ref "home-prolog"}
-        (om/build home-cta {:source view})
+        (om/build home-cta {:source view
+                            :cta-class "prolog-cta"})
         [:div.home-top-shelf]
         [:div.home-slogans
          [:h1.slogan.proverb {:item-prop "Ship better code, faster."}
@@ -380,9 +383,11 @@
                                    :header-overlap-px (atom 0)})
     om/IDidMount
     (did-mount [_]
-      (scroll/register owner
+      (scroll/register
+       owner
        #(let [vh (.-height (goog.dom/getViewportSize))
-              cta (om/get-node owner "epilog-cta")
+              container (om/get-node owner)
+              cta (utils/sel1 container ".epilog-cta")
               epilog (om/get-node owner "home-epilog")
               cta-visible? (< (.-top (.getBoundingClientRect cta)) vh)
               epilog-visible? (< (.-top (.getBoundingClientRect epilog)) nav-height)
@@ -405,7 +410,8 @@
     (render [_]
       (html
        [:section.home-epilog {:ref "home-epilog"}
-        (om/build home-cta {:source view})
+        (om/build home-cta {:source view
+                            :cta-class "epilog-cta"})
         [:div.home-top-shelf]
         [:div.home-slogans
          [:h2.slogan.proverb {:item-prop "So, ready to ship faster?"}


add proper loggin

add proper loggin

--- src/clj/ceres/core.clj
+++ src/clj/ceres/core.clj
@@ -13,6 +13,7 @@
             [clojure.core.async :refer [close! put! timeout sub chan <!! >!! <! >! go go-loop] :as async]
             [taoensso.timbre :as timbre]))

+(timbre/refer-timbre)

 (deftemplate static-page
   (io/resource "public/index.html")
@@ -45,10 +46,6 @@

 (def server-state (atom nil))
-
-(timbre/refer-timbre)
-(timbre/set-config! [:appenders :spit :enabled?] true)
-(timbre/set-config! [:shared-appender-config :spit-filename] (:logfile @server-state))

 (defn dispatch
@@ -124,8 +121,10 @@

 (defn -main [& args]
   (initialize server-state (first args))
+  (timbre/set-config! [:appenders :spit :enabled?] true)
+  (timbre/set-config! [:shared-appender-config :spit-filename] (:logfile @server-state))
   (info "Starting twitter collector...")
-  (info (clojure.pprint/pprint @server-state))
+  (info @server-state)
   (run-server (site #'all-routes) {:port (:port @server-state) :join? false})
   (let [{:keys [follow track handler credentials]} (:app @server-state)]
     (start-filter-stream follow track handler credentials)))


Kunal/Nathan Pricing page noun fix

Kunal/Nathan Pricing page noun fix

--- src-cljs/frontend/components/pricing.cljs
+++ src-cljs/frontend/components/pricing.cljs
@@ -84,10 +84,14 @@
                 [:p
                  [:span "You can run "]
                  [:strong {:class (when (> concurrent-count 9) "double-digits")} (str concurrent-count)]
-                 [:span " concurrent builds with "]
+                 [:span " concurrent build"]
+                 [:span (if (> concurrent-count 1) "s") ]
+                 [:span " with "]
                  [:strong {:class (when (> container-count 9) "double-digits")} (str container-count)]
-                 [:span " containers and "]
-                 [:strong (str pricing-parallelism)]
+                 [:span " container"]
+                 [:span (if (> container-count 1) "s") ]
+                 [:span "  and "]
+                 [:strong (str pricing-parallelism "x")]
                  [:span " parallelism."]]
                 [:div.parallelism-options
                  (for [p [1 4 8 12 16]]


export articles via rest

export articles via rest

--- src/clj/ceres/core.clj
+++ src/clj/ceres/core.clj
@@ -106,17 +106,24 @@

 (defn handle-export
   "Parse date from query and create edn-string"
-  [query]
+  [query type]
   (let [[m d] (mapv read-string (clojure.string/split (get query "date") #"-" ))]
-    (export-edn m d)))
+    (case type
+      :tweets (export-edn m d)
+      :articles (curator/export-articles m d)
+      "N/A")))

 (defroutes all-routes
   (resources "/")
+
   (GET "/tweets/ws" [] tweet-handler)

   (GET "/tweets/export" request (let [query-params (-> request :query-params)]
-                                  (handle-export query-params)))
+                                  (handle-export query-params :tweets)))
+
+  (GET "/articles/export" request (let [query-params (-> request :query-params)]
+                                    (handle-export query-params :articles)))

   (GET "/*" [] (if (= (:build @server-state) :prod)
                  (static-page)
@@ -154,4 +161,6 @@

   (stop-server)

+
+
 )


fix Comet message

fix Comet message

Comet was incorrectly using "install" in the message (it allows the play of events).

--- src/clj/game/cards.clj
+++ src/clj/game/cards.clj
@@ -325,7 +325,7 @@
                          :effect (effect (resolve-ability
                                           {:prompt "Choose an Event to play"
                                            :choices (req (filter #(has? % :type "Event") (:hand runner)))
-                                           :msg (msg "install " (:title target))
+                                           :msg (msg "play " (:title target))
                                            :effect (effect (play-instant target))} card nil))}}}}

    "Compromised Employee"
@@ -1391,7 +1391,7 @@
             :effect (effect (damage :meat (get-in runner [:register :stole-agenda])))}}

    "Push Your Luck"
-   {:player :corp :prompt "Guess the amount the Runner will spend on Push the Luck"
+   {:player :corp :prompt "Guess the amount the Runner will spend on Push Your Luck"
     :choices ["Even" "Odd"] :msg "make the Corp choose a guess"
     :effect (req (let [guess target]
                    (resolve-ability state :runner
@@ -1981,7 +1981,7 @@
     :effect (effect (move target :hand))}

    "Unorthodox Predictions"
-   {:prompt "Choose an ICE type for Unorthodox Prediction" :choices ["Sentry", "Code Gate", "Barrier"]
+   {:prompt "Choose an ICE type for Unorthodox Predictions" :choices ["Sentry", "Code Gate", "Barrier"]
     :msg (msg "prevent subroutines on " target " ICE from being broken until next turn.")}

    "Unregistered S&W 35"


Replace upper-case compare with .equalsIgnoreCase

--- src/compojure/core.clj
+++ src/compojure/core.clj
@@ -7,7 +7,6 @@
   This namespace provides functions and macros for concisely constructing
   routes and combining them together to form more complex functions."
   (:require [compojure.response :as response]
-            [clojure.string :as str]
             [clojure.tools.macro :as macro]
             [clout.core :as clout]
             [ring.util.codec :as codec]))
@@ -19,8 +18,7 @@
         form-method    (or (get-in request [:form-params "_method"])
                            (get-in request [:multipart-params "_method"]))]
     (if (and form-method (= request-method :post))
-      (= (str/upper-case (name method))
-         (str/upper-case form-method))
+      (.equalsIgnoreCase (name method) form-method)
       (= method request-method))))

 (defn- if-method


render-file

render-file

--- src/clabango/parser.clj
+++ src/clabango/parser.clj
@@ -1,6 +1,6 @@
 (ns clabango.parser
   (:use [clabango.filters :only [template-filter]]
-        [clabango.tags :only [template-tag]]))
+        [clabango.tags :only [load-template template-tag]]))

 (declare parse ast->parsed)

@@ -286,3 +286,8 @@
       (ast->parsed context)))

 (def render (comp realize parse))
+
+(defn render-file [filename context]
+  (-> filename
+      load-template
+      (render context)))


Use coercions to maintain type info from Redis

--- src/clj/shale/redis.clj
+++ src/clj/shale/redis.clj
@@ -97,15 +97,15 @@
 (defmodel SessionInRedis
   "A session, as represented in redis."
   :model-name "sessions"
-  {(s/optional-key :id)             s/Str
-   (s/optional-key :webdriver-id)   (s/maybe s/Str)
-   (s/optional-key :tags)           #{s/Str}
-   (s/optional-key :reserved)       s/Bool
-   (s/optional-key :current-url)    (s/maybe s/Str)
-   (s/optional-key :browser-name)   s/Str
-   (s/optional-key :node)           {:id s/Str
-                                     s/Any s/Any}
-   (s/optional-key :capabilities)   {s/Keyword s/Any}})
+  {:id             s/Str
+   :webdriver-id   (s/maybe s/Str)
+   :tags           #{s/Str}
+   :reserved       s/Bool
+   :current-url    (s/maybe s/Str)
+   :browser-name   s/Str
+   :node           {:id  s/Str
+                    :url s/Str}
+   :capabilities   {s/Keyword s/Any}})

 (defmodel NodeInRedis
   "A node, as represented in redis."
@@ -163,7 +163,14 @@

 (defn coerce-model
   [model-schema data]
-  ((coerce/coercer model-schema coerce/string-coercion-matcher) data))
+  (let [coercer (coerce/coercer model-schema coerce/string-coercion-matcher)
+        coerced (coercer data)]
+    (when (instance? schema.utils.ErrorContainer coerced)
+      (throw (ex-info "Cannot coerce Redis model"
+                      {:schema model-schema
+                       :data data
+                       :error coerced})))
+    coerced))

 (defn model
   "Return a model from a Redis key given a particular schema.