(ns yorck-ratings.core-test
  (:use org.httpkit.fake
        midje.sweet)
  (:require [yorck-ratings.core :refer :all]
            [yorck-ratings.fixtures :as fixtures]))

(fact "return rated movie infos sorted by rating"
      (with-fake-http [fixtures/yorck-list-url fixtures/yorck-list-page
                       fixtures/hateful-8-search-url fixtures/hateful-8-search-page
                       fixtures/hateful-8-detail-url fixtures/hateful-8-detail-page
                       fixtures/carol-search-url fixtures/carol-search-page
                       fixtures/carol-detail-url fixtures/carol-detail-page]
                      (let [expected [fixtures/hateful-8-rated-movie
                                      fixtures/carol-rated-movie]
                            actual (atom [])]
                        (rated-movies (fn [movies] (swap! actual concat movies)))
                        (Thread/sleep 200)
                        @actual => expected)))

(ns yorck-ratings.core-test
  (:use org.httpkit.fake
        midje.sweet)
  (:require [yorck-ratings.core :refer :all]
            [yorck-ratings.fixtures :as fixtures]))

(fact "return rated movie infos sorted by rating"
      (with-fake-http [fixtures/yorck-list-url fixtures/yorck-list-page
                       fixtures/hateful-8-search-url fixtures/hateful-8-search-page
                       fixtures/hateful-8-detail-url fixtures/hateful-8-detail-page
                       fixtures/carol-search-url fixtures/carol-search-page
                       fixtures/carol-detail-url fixtures/carol-detail-page]
                      (let [expected [fixtures/hateful-8-rated-movie
                                      fixtures/carol-rated-movie]
                            actual (atom [])]
                        (rated-movies (fn [movies] (swap! actual concat movies)))
                        (Thread/sleep 500)
                        @actual => expected)))

Increase timeout for end-to-end test

Increase timeout for end-to-end test


(ns schedule.web.db
  (:use [korma.db]
        [korma.core]))

;(defdb db (sqlite3 {:db "resources/db/korma.db"}))

(defentity conventions)

(ns schedule.web.db
  (:require [korma.db :as db]
            [korma.core :as core]))

;(defdb db (sqlite3 {:db "resources/db/korma.db"}))

(core/defentity conventions)

Fix update import with korma and clojure 1.8


(ns icecap.handlers.http
  (:require [schema.core :as s]
            [aleph.http :refer [request]]
            [clojure.core.async :refer [to-chan]]
            [icecap.handlers.core :refer [defstep]]
            [manifold.stream :refer [connect]]
            [schema-contrib.core :as sc]
            [taoensso.timbre :refer [info spy]])
  (:import [java.net URI]))

(defn scheme
  "Get the scheme of a (string) URL."
  [^String s]
  (.getScheme (URI. s)))

(defn valid-scheme?
  "Checks if the given URL has a valid scheme."
  [^String url]
  (#{"http" "https"} (scheme url)))

(defstep :http
  {:url (s/conditional valid-scheme? sc/URI)
   :method (s/enum :GET :POST :DELETE :PUT :PATCH :HEAD)}
  [step]
  (let [req (spy (request step))]
    (to-chan [(spy @req)])))

(ns icecap.handlers.http
  (:require [schema.core :as s]
            [aleph.http :refer [request]]
            [clojure.core.async :refer [to-chan]]
            [icecap.handlers.core :refer [defstep]]
            [manifold.stream :refer [connect]]
            [schema-contrib.core :as sc]
            [taoensso.timbre :refer [info spy]])
  (:import [java.net URI]))

(defn scheme
  "Get the scheme of a (string) URL."
  [^String s]
  (.getScheme (URI. s)))

(defn valid-scheme?
  "Checks if the (string) URL has a valid scheme."
  [^String s]
  (#{"http" "https"} (scheme s)))

(defstep :http
  {:url (s/conditional valid-scheme? sc/URI)
   :method (s/enum :GET :POST :DELETE :PUT :PATCH :HEAD)}
  [step]
  (let [req (spy (request step))]
    (to-chan [(spy @req)])))

Clarify that you need a str

Clarify that you need a str


(ns real-dashboard.core
  (:use [compojure.core :only (defroutes GET)]
  ring.util.response
  ring.middleware.cors
  org.httpkit.server)
  (:require [compojure.route :as route]
            [compojure.handler :as handler]
            [ring.middleware.reload :as reload]
            [cheshire.core :refer :all]))

(def clients (atom {}))

(defn ws [req]
  (with-channel req con
    (swap! clients assoc con true)
    (println con " connected")
    (on-close con (fn [status]
                    (swap! clients dissoc con)
                    (println con " disconnected. status: " status)))))

(future (loop []
          (doseq [client @clients]
            (println "sending message to client...")
            (send! (key client) (generate-string
                                  {:happiness (rand 10)})
                   false))
          (Thread/sleep 5000)
          (recur)))

(defroutes routes
  (GET "/happiness" [] ws))

(def application (-> (handler/site routes)
                   reload/wrap-reload
                   (wrap-cors
                     :access-control-allow-origin #".+")))

(defn -main [& args]
  (let [port (Integer/parseInt
               (or (System/getenv "PORT") "8080"))]
    (run-server application {:port port :join? false})))

(ns real-dashboard.core
  (:use [compojure.core :only (defroutes GET)]
  ring.util.response
  ring.middleware.cors
  org.httpkit.server)
  (:require [compojure.route :as route]
            [compojure.handler :as handler]
            [ring.middleware.reload :as reload]
            [cheshire.core :refer :all]))

(def clients (atom {}))

(defstruct msgbuff :msg :count)

(def msg_handler (agent (struct msgbuff "" 0)))

; append message, increment count
(defn send_message[c msg]
  {:msg (str (:msg c) msg) :count (inc (:count c))}
)

(defn ws [req]
  (with-channel req con
    (swap! clients assoc con true)
    (println con " connected")
    (on-close con (fn [status]
                    (swap! clients dissoc con)
                    (println con " disconnected. status: " status)))))

(future (loop []
          (doseq [client @clients]
            (println "sending message to client...")
            (send msg_handler send_message "happiness")
            (send! (key client) (generate-string
                                  {:happiness (:count @msg_handler)})
                   false))
          (Thread/sleep 5000)
          (recur)))

(defroutes routes
  (GET "/happiness" [] ws))

(def application (-> (handler/site routes)
                   reload/wrap-reload
                   (wrap-cors
                     :access-control-allow-origin #".+")))

(defn -main [& args]
  (let [port (Integer/parseInt
               (or (System/getenv "PORT") "8080"))]
    (run-server application {:port port :join? false})))

Introduce notion of message handler

Introduce notion of message handler


(ns repmgr-to-zk.repmgr
  (:require [clojure.java.jdbc :as j]
            [clojure.string :as s]
            [repmgr-to-zk.config :as config])
  (:import [java.sql SQLException]))

(def default-db-config
  {:dbtype "postgresql"
   :dbname "repmgr"
   :host "localhost"
   :user "repmgr"
   :password "repmgr"
   :port "5432"})

(def db
  (merge default-db-config (config/lookup :repmgr)))

(defn read-cluster-status []
  (let [suffix (config/lookup :repmgr :suffix)
        query (format "SELECT conninfo, type, name, upstream_node_name, id
                       FROM repmgr_%s.repl_show_nodes;"
                      suffix)]
    (j/query db query)))

(defn master []
  (let [cluster-status (read-cluster-status)]
    (:name (first (filter #(= "master" (:type %)) cluster-status)))))

(ns repmgr-to-zk.repmgr
  (:require [clojure.java.jdbc :as j]
            [clojure.string :as s]
            [repmgr-to-zk.config :as config])
  (:import [java.sql SQLException]))

(def default-db-config
  {:dbtype "postgresql"
   :dbname "repmgr"
   :host "localhost"
   :user "repmgr"
   :password "repmgr"
   :port "5432"})

(def db
  (merge default-db-config (config/lookup :repmgr)))

(defn read-cluster-status []
  (let [suffix (config/lookup :repmgr :suffix)
        query (format "SELECT conninfo, type, name, upstream_node_name, id
                       FROM repmgr_%s.repl_show_nodes;"
                      suffix)]
    (j/query db query)))

;; TODO: this is not correct. we should be shelling out to repmgr cluster show --csv.
(defn master []
  (let [cluster-status (read-cluster-status)]
    (:name (first (filter #(= "master" (:type %)) cluster-status)))))

Add a note about using `cluster show`.

Add a note about using `cluster show`.


(ns edge.kick.builder
  (:require
    [integrant.core :as ig]
    [juxt.kick.alpha.core :as kick]))

(defn load-provider-namespaces
  [kick-config]
  (doseq [provider (keys kick-config)
          :when (= (namespace provider) "kick")]
    (when (= (namespace provider) "kick")
      (let [sym (symbol (str "juxt.kick.alpha.providers." (name provider)))]
        (try (do (require sym) sym)
             (catch java.io.FileNotFoundException _))))))

(defmethod ig/init-key :edge.kick/builder
  [_ v]
  (load-provider-namespaces v)
  (kick/watch v))

(defmethod ig/halt-key! :edge.kick/builder
  [_ close]
  (close))

(defmethod ig/suspend-key! :edge.kick/builder [_ _])

(defmethod ig/resume-key :edge.kick/builder
  [key opts old-opts old-impl]
  (prn opts old-opts)
  (if (= opts old-opts)
    old-impl
    (do (ig/halt-key! key old-impl)
        (ig/init-key key opts))))

(ns edge.kick.builder
  (:require
    [integrant.core :as ig]
    [juxt.kick.alpha.core :as kick]))

(defn load-provider-namespaces
  [kick-config]
  (doseq [provider (keys kick-config)
          :when (= (namespace provider) "kick")]
    (when (= (namespace provider) "kick")
      (let [sym (symbol (str "juxt.kick.alpha.providers." (name provider)))]
        (try (do (require sym) sym)
             (catch java.io.FileNotFoundException _))))))

(defmethod ig/init-key :edge.kick/builder
  [_ v]
  (load-provider-namespaces v)
  (kick/watch v))

(defmethod ig/halt-key! :edge.kick/builder
  [_ close]
  (close))

(defmethod ig/suspend-key! :edge.kick/builder [_ _])

(defmethod ig/resume-key :edge.kick/builder
  [key opts old-opts old-impl]
  (if (= opts old-opts)
    old-impl
    (do (ig/halt-key! key old-impl)
        (ig/init-key key opts))))

Remove debug code from edge.kick

Remove debug code from edge.kick


rcutorture: Test both RCU-sched and RCU-bh for Tiny RCU

Tiny RCU supports both RCU-sched and RCU-bh, but only RCU-sched is
currently tested by the rcutorture scripts.  This commit therefore
changes the TINY02 configuration to test RCU-bh, with TINY01 continuing
to test RCU-sched.

This shortcoming of the current rcutorture tests was located by mutation
testing by Iftekhar.  The idea behind mutation testing is to automatically
mutate the code under test.  If a given mutant is not caught by testing,
this is a hint that the testing might need to be improved, as was the
case here.  Note that this is only a hint because it is possible to mutate
the code into something else that still works.  For example, a mutation
that removes (say) a WARN_ON() will not normally result in a test failure.

This change resulted in the test failure caused by list mishandling,
which is fixed by the next commit.

Reported-by: "Ahmed, Iftekhar" <d6b14ad555ad69fc2fad2d68e30fd1d0ed7a3226@onid.oregonstate.edu>
Signed-off-by: Paul E. McKenney <1e0ce936bb9b355d257bf5790d2513c3f28be22b@linux.vnet.ibm.com>
Reviewed-by: Josh Triplett <c028c213ed5efcf30c3f4fc7361dbde0c893c5b7@joshtriplett.org>


(ns clojournal.models.tag
  (:require [monger.collection :as mc]
            [monger.query :as mq]
            [monger.operators :as mo]
            [clojournal.db :refer [db]]))

(defn upsert-tags! [tags]
  (doseq [tag tags]
    (mc/update db "tags" {:_id tag} {mo/$inc {:refs 1}} {:upsert true})))

(defn all-tags
  ([] (all-tags 20))
  ([num]
   (mq/with-collection db "tags"
     (mq/find {})
     (mq/sort {:refs -1})
     (mq/limit num))))

(defn tag-cloud
  ([] (tag-cloud 100))
  ([num]
   (let [tags (mq/with-collection db "tags"
                (mq/find {})
                (mq/sort {:_id 1})
                (mq/limit num))
         refs (map :refs tags)]
     (when (seq refs)
       (let [min (double (apply min refs))
             max (double (apply max refs))
             f (fn [n] (/ (- n min) (- max min)))]
         (map #(assoc % :group (f (:refs %))) tags))))))

(ns clojournal.models.tag
  (:require [monger.collection :as mc]
            [monger.query :as mq]
            [monger.operators :as mo]
            [clojournal.db :refer [db]]))

(defn upsert-tags! [tags]
  (doseq [tag tags]
    (mc/update db "tags" {:_id tag} {mo/$inc {:refs 1}} {:upsert true})))

(defn all-tags
  ([] (all-tags 20))
  ([num]
   (mq/with-collection db "tags"
     (mq/find {})
     (mq/sort {:refs -1})
     (mq/limit num))))

(defn tag-cloud
  ([] (tag-cloud 100))
  ([num]
   (let [tags (mq/with-collection db "tags"
                (mq/find {})
                (mq/sort {:_id 1})
                (mq/limit num))
         refs (map :refs tags)]
     (when (seq refs)
       (let [min (double (apply min refs))
             max (double (apply max refs))
             f (fn [n] (if (= min max) 1 (/ (- n min) (- max min))))]
         (map #(assoc % :group (f (:refs %))) tags))))))

Fix bug found when every article has the same refs


(defproject lacinia-tut "0.1.0"
  :description "A simple Lacinia tutorial"
  :license {:name "MIT License"}
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [honeysql "0.9.1"]
                 [org.clojure/java.jdbc "0.3.5"]
                 [org.xerial/sqlite-jdbc "3.7.2"]
                 [com.walmartlabs/lacinia-pedestal "0.3.0"]
                 [com.walmartlabs/lacinia "0.21.0"]
                 [environ "1.1.0"]
		 [cheshire "5.8.0"]]
  :main ^:skip-aot lacinia-tut.run
  :plugins [[lein-environ "1.1.0"]]
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}
             :dev  {:env {:database "dev.db"}}
             :test {:env {:database "test.db"}}})

(defproject lacinia-tut "0.1.0"
  :description "A simple Lacinia tutorial"
  :license {:name "MIT License"}
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [honeysql "0.9.1"]
                 [org.clojure/java.jdbc "0.3.5"]
                 [org.xerial/sqlite-jdbc "3.7.2"]
                 [com.walmartlabs/lacinia-pedestal "0.3.0"]
                 [com.walmartlabs/lacinia "0.21.0"]
                 [environ "1.1.0"]
		 [cheshire "5.8.0"]]
  :main ^:skip-aot lacinia-tut.run
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}
             :dev  {:env {:database "dev.db"}}
             :test {:env {:database "test.db"}
                    :plugins [[lein-environ "1.1.0"]]}})

Make lein environ plugin as test dependency


(ns catacumba.utils
  (:import ratpack.func.Action
           ratpack.func.Function))

(def ^{:doc "Transducer for lowercase headers keys."}
  lowercase-keys-t (map (fn [[^String key value]]
                          [(.toLowerCase key) value])))

(defn action
  "Coerce a plain clojure function into
  ratpacks's Action interface."
  [callable]
  (reify Action
    (^void execute [_ x]
      (callable x))))

(defn function
  "Coerce a plain clojure function into
  ratpacks's Function interface."
  [callable]
  (reify Function
    (apply [_ x]
      (callable x))))

(ns catacumba.utils
  (:import ratpack.func.Action
           ratpack.func.Function
           java.nio.file.Paths))

(def ^{:doc "Transducer for lowercase headers keys."}
  lowercase-keys-t (map (fn [[^String key value]]
                          [(.toLowerCase key) value])))

(defn action
  "Coerce a plain clojure function into
  ratpacks's Action interface."
  [callable]
  (reify Action
    (^void execute [_ x]
      (callable x))))

(defn function
  "Coerce a plain clojure function into
  ratpacks's Function interface."
  [callable]
  (reify Function
    (apply [_ x]
      (callable x))))

(defn str->path
  [^String path]
  (Paths/get path (into-array String [])))

Add missing str->path util function.

Add missing str->path util function.


(ns akvo.lumen.lib.multiple-column
  (:require [clojure.tools.logging :as log]
            [ring.util.response :refer [response not-found]]))

(defn- extract
  [caddisfly id]
  (when id
    (if-let [schema (get (:schema caddisfly) id)]
      (let [res (select-keys schema [:hasImage])]
        (assoc res :columns (map (fn [r]
                                   {:id   (:id r)
                                    :name (:name r)
                                    :type "text" ;; TODO will be improved after design discussions
                                    }) (:results schema)))))))

(defn details
  "depending of type of multiple columns we dispatch to different logic impls"
  [{:keys [caddisfly] :as deps} multiple-type multiple-id]
  (log/debug ::all :multiple-type multiple-type :multiple-id multiple-id)
  (condp = multiple-type
    "caddisfly" (if-let [res (extract caddisfly multiple-id)]
                  (response res)
                  (not-found {:message "caddisfly id not found"
                              :multiple-id multiple-id}))
    (not-found {:type multiple-type})))

(ns akvo.lumen.lib.multiple-column
  (:require [clojure.tools.logging :as log]
            [ring.util.response :refer [response not-found]]))

(defn- extract
  [caddisfly id]
  (when id
    (if-let [schema (get (:schema caddisfly) id)]
      (let [res (select-keys schema [:hasImage])]
        (assoc res :columns (map (fn [r]
                                   {:id   (:id r)
                                    :name (format "%s (%s)" (:name r) (:unit r))
                                    :type "text" ;; TODO will be improved after design discussions
                                    }) (:results schema)))))))

(defn details
  "depending of type of multiple columns we dispatch to different logic impls"
  [{:keys [caddisfly] :as deps} multiple-type multiple-id]
  (log/debug ::all :multiple-type multiple-type :multiple-id multiple-id)
  (condp = multiple-type
    "caddisfly" (if-let [res (extract caddisfly multiple-id)]
                  (response res)
                  (not-found {:message "caddisfly id not found"
                              :multiple-id multiple-id}))
    (not-found {:type multiple-type})))

Add "unit" to caddisfly "name" response

Add "unit" to caddisfly "name" response


(ns wishlistd.models.init
  (:require [clojure.java.jdbc :as sql]))

(def db {:classname "org.postgresql.Driver"
         :subprotocol "postgresql"
         :subname "//localhost:5432/cwl"
         :user "cwl"
         :password "wish"})

(defn create-wishlist []
  (sql/with-connection db
    (sql/create-table :wishlist
      [:code :varchar "PRIMARY KEY"]
      [:title :varchar "NOT NULL"]
      [:created_at :timestamp "NOT NULL" "DEFAULT CURRENT_TIMESTAMP"])))

(defn create-wish []
  (sql/with-connection db
    (sql/create-table :wish
      [:id :serial "PRIMARY KEY"]
      [:description :varchar "NOT NULL"]
      [:created_at :timestamp "NOT NULL" "DEFAULT CURRENT_TIMESTAMP"]
      [:url :varchar]
      [:wishlist_code :varchar]
      ["constraint fk_wish_wishlist foreign key(wishlist_code) references wishlist(code) on delete cascade"])))

(defn drop-tables []
  (sql/with-connection db
    (sql/drop-table :wish)
    (sql/drop-table :wishlist)))

(defn -main []
  (print "Migrating database...") (flush)
  (drop-tables)
  (create-wishlist)
  (create-wish)
  (println " done"))

(ns wishlistd.models.init
  (:require [clojure.java.jdbc :as sql]))

(def db {:classname "org.postgresql.Driver"
         :subprotocol "postgresql"
         :subname "//localhost:5432/cwl"
         :user "cwl"
         :password "wish"})

(defn create-wishlist []
  (sql/with-connection db
    (sql/create-table :wishlist
      [:code :varchar "PRIMARY KEY"]
      [:title :varchar "NOT NULL"]
      [:created_at :timestamp "NOT NULL" "DEFAULT CURRENT_TIMESTAMP"])))

(defn create-wish []
  (sql/with-connection db
    (sql/create-table :wish
      [:id :serial "PRIMARY KEY"]
      [:description :varchar "NOT NULL"]
      [:created_at :timestamp "NOT NULL" "DEFAULT CURRENT_TIMESTAMP"]
      [:url :varchar]
      [:wishlist_code :varchar]
      ["constraint fk_wish_wishlist foreign key(wishlist_code) references wishlist(code) on delete cascade"])))

(defn drop-tables []
  (sql/with-connection db
    (sql/drop-table :wish)
    (sql/drop-table :wishlist)))

(defn -main [cmd]
  (when (= cmd "drop" (drop-tables))) ; optionally drop tables before creating
  (create-wishlist)
  (create-wish)
  (println "Done!"))

Drop tables first option added

Drop tables first option added


(ns dashboard-clj.widgets.github-repo-stats
  (:require [reagent.core :as r :refer [atom]]
            [dashboard-clj.widgets.core :as widget-common]
            [dashboard-clj.widgets.line-chart :as charts]))

(defmethod widget-common/widget :github-repo-stats [{:keys [text data options] :as w}]
  [:div {:class "github-repo-stats"}
   [:div.header {:style {:background  (:color options)}}
    [:img {:class "github-logo" :src "/images/github_mark.png"}]
    [:h2 {:class "title" }(str "Hello: " (:repo-name w))]]
   [:div#total-commits
    [:p {:class "subheading"} "Total commits"]
    [:h4 {:class "total-commits" :style {:background (:color options)}} (get-in @data [:data :total-commits])]]
    [:table {:class "contributors"}
     [:tbody
      [:tr
       [:th {:class "subheading" }"contributors"]]
      (doall (for [contributor (get-in @data [:data :contributors])]
               [:tr {:key contributor}
                [:td (str contributor)]]))]]
   [:div {:class "commit-chart" :style { :width "95%" :height "40%"}}
    [charts/line-chart {:chart-options
                        {:title {:text text}
                         :xAxis {:categories (mapv first (get-in @data [:data :weekly-commit-breakdown]))}
                         :series [{:name "commits"
                                   :data (mapv second (get-in @data [:data :weekly-commit-breakdown]))}]}}]]])

(ns dashboard-clj.widgets.github-repo-stats
  (:require [reagent.core :as r :refer [atom]]
            [dashboard-clj.widgets.core :as widget-common]
            [dashboard-clj.widgets.line-chart :as charts]))

(defmethod widget-common/widget :github-repo-stats [{:keys [text data options] :as w}]
  [:div {:class "github-repo-stats"}
   [:div.header {:style {:background  (:color options)}}
    [:img {:class "github-logo" :src "/images/github_mark.png"}]
    [:h2 {:class "title" } (:repo-name w)]]
   [:div#total-commits
    [:p {:class "subheading"} "Total commits"]
    [:h4 {:class "total-commits" :style {:background (:color options)}} (get-in @data [:data :total-commits])]]
   [:table {:class "contributors"}
    [:tbody
     [:tr
      [:th {:class "subheading" }"contributors"]]
     (doall (for [contributor (get-in @data [:data :contributors])]
              [:tr {:key contributor}
               [:td (str contributor)]]))]]
   [:div {:class "commit-chart" :style { :width "95%" :height "40%"}}
    [charts/line-chart {:chart-options
                        {:title {:text text}
                         :xAxis {:categories (mapv first (get-in @data [:data :weekly-commit-breakdown]))}
                         :series [{:name "commits"
                                   :data (mapv second (get-in @data [:data :weekly-commit-breakdown]))}]}}]]])

Fix typo in github repo stats widget

Fix typo in github repo stats widget


(ns faceboard.whitelabel
  (:require [faceboard.env :as env]
            [faceboard.helpers.utils :as utils]
            [faceboard.logging :refer [log log-err log-warn log-info]]))

(def domain-mappings
  [[#"fb\.local.*" "test-localhost-whitelabel"]             ; just a test local host
   [#"hackerparadise\.org" "hp"]])                          ; http://faceboard.hackerparadise.org

(defn domain->boad-id [domain]
  (if-let [match (utils/find-first #(re-matches (first %) domain) domain-mappings)]
    (second match)))

(defn whitelabel-board []
  (domain->boad-id env/domain))

(ns faceboard.whitelabel
  (:require [faceboard.env :as env]
            [faceboard.helpers.utils :as utils]
            [faceboard.logging :refer [log log-err log-warn log-info]]))

(def domain-mappings
  [[#"fb\.local.*" "test-localhost-whitelabel"]             ; just a test local host
   [#".*hackerparadise\.org" "hp"]])                          ; http://faceboard.hackerparadise.org

(defn domain->boad-id [domain]
  (if-let [match (utils/find-first #(re-matches (first %) domain) domain-mappings)]
    (second match)))

(defn whitelabel-board []
  (domain->boad-id env/domain))

Fix url matcher for hackerparadise

Fix url matcher for hackerparadise


(ns incise.core
  (:require (incise [server :refer [serve stop-server defserver]]
                    [watcher :refer [start-watching stop-watching]])
            [incise.parsers.core :refer [parse]]
            [clojure.java.classpath :refer [classpath]]
            [clojure.tools.namespace.find :as ns-tools]))

(def ^:const core-namespace-symbols
  "Namespaces which are the core parser and layouts."
  #{'incise.parsers.core
    'incise.layouts.core})

(defn namespace-is-layout-or-parser [namespace-sym]
  (and (not (contains? core-namespace-symbols namespace-sym))
       (re-find #"incise\.(layouts|parsers)\..+" (str namespace-sym))))

(defn load-parsers-and-layouts []
  (doseq [ns-sym (filter namespace-is-layout-or-parser
                         (ns-tools/find-namespaces (classpath)))]
    (require ns-sym)))

(load-parsers-and-layouts)

(def parse-on-watch (partial start-watching parse))

(defn -main
  "Start the development server and watcher."
  [& args]
  (apply serve args)
  (parse-on-watch))

(defn defserver-and-watch
  [& args]
  (stop-server)
  (apply defserver args)
  (stop-watching)
  (parse-on-watch))

(ns incise.core
  (:require (incise [server :refer [serve stop-server defserver]]
                    [watcher :refer [start-watching stop-watching]])
            [incise.parsers.core :refer [parse]]
            [clojure.java.classpath :refer [classpath]]
            [clojure.tools.namespace.find :as ns-tools]))

(def ^:const core-namespace-symbols
  "Namespaces which are the core parser and layouts."
  #{'incise.parsers.core
    'incise.layouts.core})

(defn namespace-is-layout-or-parser?
  "Predicate to determine if the given symbol is a namespace for a layout or
   parser. It would be a namespace under incise.layouts or incise.parsers."
  [namespace-sym]
  (re-find #"incise\.(layouts|parsers)\..+" (str namespace-sym)))

(defn load-parsers-and-layouts
  "Require with reload all namespaces under incise.layouts and incise.parsers."
  []
  (doseq [ns-sym (->> (classpath)
                      (ns-tools/find-namespaces)
                      (remove (partial contains? core-namespace-symbols))
                      (filter namespace-is-layout-or-parser?)) ]
    (require :reload ns-sym)))

(load-parsers-and-layouts)

(def parse-on-watch (partial start-watching parse))

(defn -main
  "Start the development server and watcher."
  [& args]
  (apply serve args)
  (parse-on-watch))

(defn defserver-and-watch
  [& args]
  (stop-server)
  (apply defserver args)
  (stop-watching)
  (parse-on-watch))

Rewrite and add docs to load-parses-and-layouts.


(ns com.wsscode.pathom.book.async.js-promises
  (:require [com.wsscode.common.async-cljs :refer [go-catch <!p]]
            [goog.object :as gobj]
            [com.wsscode.pathom.core :as p]
            [com.wsscode.pathom.profile :as pp]))

(def reader
  {:dog.ceo/random-dog-url
   (fn [_]
     (go-catch
       (-> (js/fetch "https://dog.ceo/api/breeds/image/random") <!p
           (.json) <!p
           (gobj/get "message"))))})

(def parser
  (p/async-parser {::p/plugins [(p/env-plugin {::p/reader reader})
                                p/error-handler-plugin
                                pp/profile-plugin]}))

(ns com.wsscode.pathom.book.async.js-promises
  (:require [com.wsscode.common.async-cljs :refer [go-catch <!p]]
            [com.wsscode.pathom.core :as p]
            [goog.object :as gobj]))

(def reader
  {:dog.ceo/random-dog-url
   (fn [_]
     (go-catch
       (-> (js/fetch "https://dog.ceo/api/breeds/image/random") <!p
           (.json) <!p
           (gobj/get "message"))))})

(def parser
  (p/async-parser {::p/plugins [(p/env-plugin {::p/reader reader})
                                p/error-handler-plugin
                                p/trace-plugin]}))

Fix js promises example in the book

Fix js promises example in the book


(ns onyx.log.commands.assign-bookkeeper-log-id
  (:require [clojure.core.async :refer [>!!]]
            [clojure.data :refer [diff]]
            [onyx.log.commands.common :as common]
            [onyx.log.entry :refer [create-log-entry]]
            [schema.core :as s]
            [onyx.schema :refer [Replica LogEntry Reactions ReplicaDiff State]]
            [onyx.extensions :as extensions]))

(s/defmethod extensions/apply-log-entry :signal-ready :- Replica
  [{:keys [args]} :- LogEntry replica]
  (update-in replica
             [:state-logs (:job-id args) (:task-id args) (:slot-id args)]
             (fn [logs]
               (conj (vec logs) (:ledger-id args)))))

(s/defmethod extensions/replica-diff :signal-ready :- ReplicaDiff
  [{:keys [args]} :- LogEntry old new]
  (second (diff (:state-logs old) (:state-logs new))))

(s/defmethod extensions/reactions :signal-ready :- Reactions
  [{:keys [args]} :- LogEntry old new diff peer-args]
  [])

(s/defmethod extensions/fire-side-effects! :signal-ready :- State
  [{:keys [args message-id]} :- LogEntry old new diff state]
  state)

(ns onyx.log.commands.assign-bookkeeper-log-id
  (:require [clojure.core.async :refer [>!!]]
            [clojure.data :refer [diff]]
            [onyx.log.commands.common :as common]
            [onyx.log.entry :refer [create-log-entry]]
            [schema.core :as s]
            [onyx.schema :refer [Replica LogEntry Reactions ReplicaDiff State]]
            [onyx.extensions :as extensions]))

(s/defmethod extensions/apply-log-entry :assign-bookkeeper-log-id :- Replica
  [{:keys [args]} :- LogEntry replica]
  (update-in replica
             [:state-logs (:job-id args) (:task-id args) (:slot-id args)]
             (fn [logs]
               (conj (vec logs) (:ledger-id args)))))

(s/defmethod extensions/replica-diff :assign-bookkeeper-log-id :- ReplicaDiff
  [{:keys [args]} :- LogEntry old new]
  (second (diff (:state-logs old) (:state-logs new))))

(s/defmethod extensions/reactions :assign-bookkeeper-log-id :- Reactions
  [{:keys [args]} :- LogEntry old new diff peer-args]
  [])

(s/defmethod extensions/fire-side-effects! :assign-bookkeeper-log-id :- State
  [{:keys [args message-id]} :- LogEntry old new diff state]
  state)

Fix bookkeeper log command name

Fix bookkeeper log command name


(ns kixi.eventlog.web-server
  (:require [compojure.core :refer [defroutes POST GET]]
            [compojure.route :refer [not-found]]
            [ring.middleware.defaults :refer [wrap-defaults api-defaults]]
            [kixi.eventlog.api :refer [index-resource]]
            [org.httpkit.server :as http-kit]
            [com.stuartsierra.component :as component]))

(defroutes all-routes
  (POST "/events" []  index-resource)
  (not-found {:headers {"Content-Type" "application/json"}
              :body "{\"error\": \"No Such Endpoint\"}"}))

(defrecord WebServer []
  component/Lifecycle
  (start [this]
    (println "Starting Webserver")
    (let [server (http-kit/run-server (wrap-defaults #'all-routes api-defaults) {:verbose? true :port 80 :max-body (* 16 1024 1024)})]
      (assoc this ::server server)))
  (stop [this]
    (println "Stopping Webserver")
    ((::server this))))

(defn new-server []
  (->WebServer))

(ns kixi.eventlog.web-server
  (:require [compojure.core :refer [defroutes POST GET]]
            [compojure.route :refer [not-found]]
            [ring.middleware.defaults :refer [wrap-defaults api-defaults]]
            [kixi.eventlog.api :refer [index-resource]]
            [org.httpkit.server :as http-kit]
            [com.stuartsierra.component :as component]))

(defroutes all-routes
  (POST "/events" []  index-resource)
  (GET "/_elb_status" []  "ALL GOOD")
  (POST "/_elb_status" []  "ALL GOOD")
  (not-found {:headers {"Content-Type" "application/json"}
              :body "{\"error\": \"No Such Endpoint\"}"}))

(defrecord WebServer []
  component/Lifecycle
  (start [this]
    (println "Starting Webserver")
    (let [server (http-kit/run-server (wrap-defaults #'all-routes api-defaults) {:verbose? true :port 80 :max-body (* 16 1024 1024)})]
      (assoc this ::server server)))
  (stop [this]
    (println "Stopping Webserver")
    ((::server this))))

(defn new-server []
  (->WebServer))

Add a ping point for ELB.

Add a ping point for ELB.


(ns comic-reader.main
  (:require [figwheel.client :as fw]))

(enable-console-print!)

(fw/start {
           ;; configure a websocket url if you are using your own server
           ;; :websocket-url "ws://localhost:3449/figwheel-ws"

           ;; optional callback
           :on-jsload (fn [] (print "reloaded"))

           ;; The heads up display is enabled by default
           ;; to disable it:
           ;; :heads-up-display false

           ;; when the compiler emits warnings figwheel
           ;; blocks the loading of files.
           ;; To disable this behavior:
           ;; :load-warninged-code true

           ;; if figwheel is watching more than one build
           ;; it can be helpful to specify a build id for
           ;; the client to focus on
           ;; :build-id "example"
           })

(ns comic-reader.main
  (:require [figwheel.client :as fw]))

(enable-console-print!)

(fw/start {
           ;; configure a websocket url if you are using your own server
           :websocket-url "ws://localhost:3449/figwheel-ws"

           ;; optional callback
           :on-jsload (fn [] (print "reloaded"))

           ;; The heads up display is enabled by default
           ;; to disable it:
           ;; :heads-up-display false

           ;; when the compiler emits warnings figwheel
           ;; blocks the loading of files.
           ;; To disable this behavior:
           ;; :load-warninged-code true

           ;; if figwheel is watching more than one build
           ;; it can be helpful to specify a build id for
           ;; the client to focus on
           ;; :build-id "example"
           })

Configure things for running the ring server


(ns domain.core
  (:require [compojure.core :refer :all]
            [compojure.route :as route]
            [ring.middleware.defaults :refer [wrap-defaults api-defaults]]
            [ring.middleware.json :refer [wrap-json-body wrap-json-response]]
            [ring.util.response :refer [response]])
  (:gen-class))

(defroutes app-routes
  (GET "/status" [] "OMG HI!")
  (route/not-found "Not Found"))

(def app
  (-> app-routes
      (wrap-defaults api-defaults)
      (wrap-json-body {:keywords? true})
      (wrap-json-response)))

(ns domain.core
  (:require [compojure.core :refer :all]
            [compojure.route :as route]
            [ring.middleware.defaults :refer [wrap-defaults api-defaults]]
            [ring.middleware.json :refer [wrap-json-body wrap-json-response]]
            [ring.util.response :refer [response]])
  (:gen-class))

(def features
  "A map that holds features and their possible values"
  {:ethnicity [:asian :black :hispanic :white]
   :location  [:prime :average]
   :gender    [:male :female]
   :age       [:young :mid :old]
   :weather   [:sunny :rainny]})

(def ads->features-example
  "An example of a map that holds each ad and its preferred features"
  {:ad1 {:ethnicity :asian
         :weather   :sunny
         :location  :prime
         :url       "http://example.com/1.jpg"}
   :ad2 {:age       :mid
         :location  :average
         :url       "http://example.com/2.jpg"}
   :ad3 {:weather   :sunny
         :url       "http://example.com/3.jpg"}
   :ad4 {:gender    :male
         :age       :old
         :location :prime
         :url       "http://example.com/4.jpg"}})

(def result-features-example
  "An example of a resulting map obtained from Tobiaz' UI and CV"
  {:location  :prime
   :ethnicity :asian
   :weather   :sunny
   :gender    :male})

; Maybe we can add this information to the resulting response
(def advertisers->ads
  "A map that holds ads per advertiser"
  {:advertiser1 #{:ad1 :ad2}
   :advertiser2 #{:ad3}
   :advertiser3 #{:ad4}})

(defroutes app-routes
  (GET "/status" [] "OMG HI!")
  (route/not-found "Not Found"))

(def app
  (-> app-routes
      (wrap-defaults api-defaults)
      (wrap-json-body {:keywords? true})
      (wrap-json-response)))

Add some sample data structures.

Add some sample data structures.


(ns clj-gatling.core
  (:import (org.joda.time LocalDateTime))
  (:require [clj-gatling.chart :as chart]
            [clj-gatling.report :as report]
            [clj-gatling.simulation :as simulation]))

(def results-dir "target/results")

(defn create-dir [dir]
  (.mkdirs (java.io.File. dir)))

(defn run-simulation [scenario users]
 (let [start-time (LocalDateTime.)
       result (simulation/run-simulation scenario users)
       csv (csv/write-csv (report/create-result-lines start-time result) :delimiter "\t" :end-of-line "\n")]
   (create-dir (str results-dir "/input"))
   (spit (str results-dir "/input/simulation.log") csv)
   (chart/create-chart results-dir)
   (println (str "Open " results-dir "/output/index.html"))))

(ns clj-gatling.core
  (:import (org.joda.time LocalDateTime))
  (:require [clojure-csv.core :as csv]
            [clj-gatling.chart :as chart]
            [clj-gatling.report :as report]
            [clj-gatling.simulation :as simulation]))

(def results-dir "target/results")

(defn create-dir [dir]
  (.mkdirs (java.io.File. dir)))

(defn run-simulation [scenario users]
 (let [start-time (LocalDateTime.)
       result (simulation/run-simulation scenario users)
       csv (csv/write-csv (report/create-result-lines start-time result) :delimiter "\t" :end-of-line "\n")]
   (create-dir (str results-dir "/input"))
   (spit (str results-dir "/input/simulation.log") csv)
   (chart/create-chart results-dir)
   (println (str "Open " results-dir "/output/index.html"))))

Add missing csv library require

Add missing csv library require


(require 'cljs.repl)
(require 'cljs.repl.rhino)

(cljs.repl/repl
  (cljs.repl.rhino/repl-env)
  :watch "src"
  :output-dir "target")

(require 'cljs.repl)
(require 'cljs.repl.node)

(cljs.repl/repl
  (cljs.repl.node/repl-env)
  :watch "src"
  :output-dir "target")

Switch back to node repl for now.

Switch back to node repl for now.


(ns circle.web.test-web
  (:require circle.init)
  (:require [clj-http.client :as http])
  (:use midje.sweet))

(circle.init/init)

(def site "http://localhost:8080")

(fact "/ returns 200"
  (http/get site) => (contains {:status 200}))

(ns circle.web.test-web
  (:require circle.init)
  (:require [clj-http.client :as http])
  (:require [clj-http.core :as core])
  (:use midje.sweet))

(circle.init/init)

(def site "http://localhost:8080")

(fact "/ returns 200"
  (let [response (http/get site)]
    response => (contains {:status 200 :body #"Sign up"})))

(fact "posting works"
      (let [post-request {:form-params {:email "mytest@test.com" :contact true}}
            post-response (http/post site post-request)
            get-request {:cookies (post-response :cookies)
                         :url (get-in post-response [:headers "location"])}
            get-response (http/get site get-request)]

        post-response => (contains {:status 302})
        (:headers post-response) => (contains {"location" "/"})
        get-response => (contains {:status 200 :body #"Thanks"})))

Expand test coverage of web site.

Expand test coverage of web site.


(ns asciinema-player.util)

(defn adjust-to-range [value min-value max-value]
  (.min js/Math max-value (.max js/Math value min-value)))

; Optimized js->clj implementation by Darrick Wiebe (http://dev.clojure.org/jira/browse/CLJS-844)
(defn faster-js->clj
  "Recursively transforms JavaScript arrays into ClojureScript
  vectors, and JavaScript objects into ClojureScript maps.  With
  option ':keywordize-keys true' will convert object fields from
  strings to keywords."
  ([x] (faster-js->clj x {:keywordize-keys false}))
  ([x & opts]
   (cond
     (satisfies? IEncodeClojure x)
     (-js->clj x (apply array-map opts))
     (seq opts)
     (let [{:keys [keywordize-keys]} opts
           keyfn (if keywordize-keys keyword str)
           f (fn thisfn [x]
               (cond
                 (seq? x)
                 (doall (map thisfn x))
                 (coll? x)
                 (into (empty x) (map thisfn) x)
                 (array? x)
                 (persistent!
                  (reduce #(conj! %1 (thisfn %2))
                          (transient []) x))
                 (identical? (type x) js/Object)
                 (persistent!
                  (reduce (fn [r k] (assoc! r (keyfn k) (thisfn (aget x k))))
                          (transient {}) (js-keys x)))
                 :else x))]
       (f x)))))

(ns asciinema-player.util)

(defn adjust-to-range [value min-value max-value]
  (min max-value (max value min-value)))

; Optimized js->clj implementation by Darrick Wiebe (http://dev.clojure.org/jira/browse/CLJS-844)
(defn faster-js->clj
  "Recursively transforms JavaScript arrays into ClojureScript
  vectors, and JavaScript objects into ClojureScript maps.  With
  option ':keywordize-keys true' will convert object fields from
  strings to keywords."
  ([x] (faster-js->clj x {:keywordize-keys false}))
  ([x & opts]
   (cond
     (satisfies? IEncodeClojure x)
     (-js->clj x (apply array-map opts))
     (seq opts)
     (let [{:keys [keywordize-keys]} opts
           keyfn (if keywordize-keys keyword str)
           f (fn thisfn [x]
               (cond
                 (seq? x)
                 (doall (map thisfn x))
                 (coll? x)
                 (into (empty x) (map thisfn) x)
                 (array? x)
                 (persistent!
                  (reduce #(conj! %1 (thisfn %2))
                          (transient []) x))
                 (identical? (type x) js/Object)
                 (persistent!
                  (reduce (fn [r k] (assoc! r (keyfn k) (thisfn (aget x k))))
                          (transient {}) (js-keys x)))
                 :else x))]
       (f x)))))

Use ClojureScript's min and max

Use ClojureScript's min and max


(require 'cljs.repl)
(require 'cljs.repl.node)

(cljs.repl/repl (cljs.repl.node/repl-env)
  :output-dir "out"
  :foreign-libs [{:file "libs/greeting.js"
                  :provides ["greeting"]
                  :module-type :commonjs}
                 {:file "libs/german.js"
                  :provides ["german"]
                  :module-type :commonjs}])

(require 'cljs.repl)
(require 'cljs.build.api)
(require 'cljs.repl.node)

(def foreign-libs [{:file "libs/greeting.js"
       :provides ["greeting"]
       :module-type :commonjs}
      {:file "libs/german.js"
       :provides ["german"]
       :module-type :commonjs}])

(cljs.build.api/build "src"
  {:main 'foo.bar
   :output-to "out/main.js"
   :verbose true
   :foreign-libs foreign-libs})

(cljs.repl/repl (cljs.repl.node/repl-env)
  :watch "src"
  :output-dir "out"
  :foreign-libs foreign-libs)

Revert "Update for CLJS-1313 testing"

Revert "Update for CLJS-1313 testing"

This reverts commit 784d7d52293a876a2a326dec18549293378edfc0.


(defproject onyx-app/lein-template "0.8.11.8"
  :description "Onyx Leiningen application template"
  :url "https://github.com/onyx-platform/onyx-template"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :repositories {"snapshots" {:url "https://clojars.org/repo"
                              :username :env
                              :password :env
                              :sign-releases false}
                 "releases" {:url "https://clojars.org/repo"
                             :username :env
                             :password :env
                             :sign-releases false}}
  :plugins [[lein-set-version "0.4.1"]]
  :profiles {:dev {:plugins [[lein-set-version "0.4.1"]
                             [lein-update-dependency "0.1.2"]
                             [lein-pprint "1.1.1"]]}}
  :eval-in-leiningen true)

(defproject onyx-app/lein-template "0.8.11.9-SNAPSHOT"
  :description "Onyx Leiningen application template"
  :url "https://github.com/onyx-platform/onyx-template"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :repositories {"snapshots" {:url "https://clojars.org/repo"
                              :username :env
                              :password :env
                              :sign-releases false}
                 "releases" {:url "https://clojars.org/repo"
                             :username :env
                             :password :env
                             :sign-releases false}}
  :plugins [[lein-set-version "0.4.1"]]
  :profiles {:dev {:plugins [[lein-set-version "0.4.1"]
                             [lein-update-dependency "0.1.2"]
                             [lein-pprint "1.1.1"]]}}
  :eval-in-leiningen true)

Prepare for next release cycle.

Prepare for next release cycle.


(defproject sqls "0.1.0-SNAPSHOT"
  :description "SQLS"
  :url "https://bitbucket.org/mpietrzak/sqls"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [
                 [org.clojure/clojure "1.6.0-beta2"]
                 [org.clojure/data.json "0.2.4"]
                 [org.clojure/java.jdbc "0.3.3"]
                 [org.clojure/tools.logging "0.2.6"]
                 [org.xerial/sqlite-jdbc "3.7.2"]
                 [seesaw "1.4.4"]
                 ]
  ; :main ^:skip-aot sqls.core
  :main sqls.core
  :java-source-paths ["src"]
  :target-path "target/%s"
  :plugins [[codox "0.6.6"]]
  :profiles {:uberjar {:aot :all}})

(defproject sqls "0.1.0-SNAPSHOT"
  :description "SQLS"
  :url "https://bitbucket.org/mpietrzak/sqls"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [
                 [org.clojure/clojure "1.6.0-beta2"]
                 [org.clojure/data.json "0.2.4"]
                 [org.clojure/java.jdbc "0.3.3"]
                 [org.clojure/tools.logging "0.2.6"]
                 [org.xerial/sqlite-jdbc "3.7.2"]
                 [seesaw "1.4.4"]
                 ]
  ; :main ^:skip-aot sqls.core
  :main sqls.core
  :java-source-paths ["src"]
  :target-path "target/%s"
  :plugins [[codox "0.6.7"]
            [lein-ancient "0.5.4"]]
  :profiles {:uberjar {:aot :all}}
  :jvm-opts ["-Xms4M" "-Xmx1G" "-XX:+PrintGC"])

Add lein-andient plugin and jvm-opts

Add lein-andient plugin and jvm-opts


;(defproject cli4clj "1.3.2"
(defproject cli4clj "1.3.3-SNAPSHOT"
  :description "Create simple interactive CLIs for Clojure applications."
  :url "https://github.com/ruedigergad/cli4clj"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [clj-assorted-utils "1.18.2"]
                 [org.clojure/core.async "0.3.443"]
                 [jline/jline "2.14.2"]]
  :global-vars {*warn-on-reflection* true}
  :html5-docs-docs-dir "ghpages/doc"
  :html5-docs-ns-includes #"^cli4clj.*"
  :html5-docs-repository-url "https://github.com/ruedigergad/cli4clj/blob/master"
  :test2junit-output-dir "ghpages/test-results"
  :test2junit-run-ant true
  :main cli4clj.example
  :plugins [[lein-cloverage "1.0.2"] [test2junit "1.3.3"] [lein-html5-docs "3.0.3"]]
  :profiles  {:repl  {:dependencies  [[jonase/eastwood "0.2.4" :exclusions  [org.clojure/clojure]]]}}
)

;(defproject cli4clj "1.3.2"
(defproject cli4clj "1.3.3-SNAPSHOT"
  :description "Create simple interactive CLIs for Clojure applications."
  :url "https://github.com/ruedigergad/cli4clj"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.9.0"]
                 [clj-assorted-utils "1.18.2"]
                 [org.clojure/core.async "0.3.443"]
                 [jline/jline "2.14.2"]]
  :global-vars {*warn-on-reflection* true}
  :html5-docs-docs-dir "ghpages/doc"
  :html5-docs-ns-includes #"^cli4clj.*"
  :html5-docs-repository-url "https://github.com/ruedigergad/cli4clj/blob/master"
  :test2junit-output-dir "ghpages/test-results"
  :test2junit-run-ant true
  :main cli4clj.example
  :plugins [[lein-cloverage "1.0.2"] [test2junit "1.3.3"] [lein-html5-docs "3.0.3"]]
  :profiles  {:repl  {:dependencies  [[jonase/eastwood "0.2.4" :exclusions  [org.clojure/clojure]]]}}
)

Update Clojure dependency to 1.9.0.

Update Clojure dependency to 1.9.0.


(ns refactor-nrepl.plugin
  (:require
   [refactor-nrepl.core :as core]
   [leiningen.core.main :as lein]))

(def ^:private external-dependencies
  ;; For whatever reason it didn't work to look for cider-nrepl here.
  {'org.clojure/clojure "1.7.0"})

(defn- version-ok?
  [dependencies artifact version-string]
  (or (->> dependencies
           (some (fn [[id v]]
                   (and (= id artifact)
                        (lein/version-satisfies? v version-string)))))
      (lein/warn (str "Warning: refactor-nrepl requires " artifact " "
                      version-string " or greater."))))

(defn- external-dependencies-ok? [dependencies]
  (reduce (fn [acc [artifact version-string]]
            (and (version-ok? dependencies artifact version-string) acc))
          true
          external-dependencies))

(defn middleware
  [{:keys [dependencies] :as project}]
  (if (external-dependencies-ok? dependencies)
    (-> project
        (update-in [:dependencies]
                   (fnil into [])
                   [['refactor-nrepl (core/version)]])
        (update-in [:repl-options :nrepl-middleware]
                   (fnil into [])
                   '[refactor-nrepl.middleware/wrap-refactor]))
    (do
      (lein/warn (str "Warning: refactor-nrepl middleware won't be "
                      "activated due to missing dependencies."))
      project)))

(ns refactor-nrepl.plugin
  (:require
   [refactor-nrepl.core :as core]
   [leiningen.core.main :as lein]))

(def ^:private external-dependencies
  ;; For whatever reason it didn't work to look for cider-nrepl here.
  {'org.clojure/clojure "1.7.0"})

(defn- version-ok?
  [dependencies artifact version-string]
  (or (->> dependencies
           (some (fn [[id v]]
                   (and (= id artifact)
                        (lein/version-satisfies? v version-string)))))
      (lein/warn (str "Warning: refactor-nrepl requires " artifact " "
                      version-string " or greater."))))

(defn- external-dependencies-ok? [dependencies exclusions]
  (let [exclusions (set exclusions)]
    (reduce (fn [acc [artifact version-string]]
              (or (exclusions artifact)
                  (and (version-ok? dependencies artifact version-string) acc)))
            true
            external-dependencies)))

(defn middleware
  [{:keys [dependencies exclusions] :as project}]
  (if (external-dependencies-ok? dependencies exclusions)
    (-> project
        (update-in [:dependencies]
                   (fnil into [])
                   [['refactor-nrepl (core/version)]])
        (update-in [:repl-options :nrepl-middleware]
                   (fnil into [])
                   '[refactor-nrepl.middleware/wrap-refactor]))
    (do
      (lein/warn (str "Warning: refactor-nrepl middleware won't be "
                      "activated due to missing dependencies."))
      project)))

Add support for skipping excluded dependencies

This patch tweaks the dependency checker, so that refactor-nrepl will
activate itself normally if one of its dependencies is listed in a
project's :exclusions. This enables a user to for instance exclude
org.clojure/clojure and provide a fork, thus taking on all
responsibility for providing an adequate version.


(defproject planck "0.1.0"
  :profiles {:dev
             {:dependencies [[org.clojure/clojurescript "1.9.660"]
                             [org.clojure/test.check "0.10.0-alpha1"]
                             [tubular "1.0.0"]]
              :source-paths ["dev"]}
             :build-release
             {}
             :build-commit
             {}}
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/clojurescript "1.9.660"]
                 [org.clojure/test.check "0.10.0-alpha1"]
                 [org.clojure/tools.reader "1.0.0"]
                 [com.cognitect/transit-clj "0.8.300"]
                 [com.cognitect/transit-cljs "0.8.239"]
                 [fipp "0.6.8"]
                 [malabarba/lazy-map "1.3"]
                 [cljsjs/parinfer "1.8.1-0"]]
  :clean-targets ["out" "target"])

(defproject planck "0.1.0"
  :profiles {:dev
             {:dependencies [[org.clojure/clojurescript ~(or (System/getenv "CLOJURESCRIPT_VERSION") "1.9.660")]
                             [org.clojure/test.check "0.10.0-alpha1"]
                             [tubular "1.0.0"]]
              :source-paths ["dev"]}
             :build-release
             {}
             :build-commit
             {}}
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/clojurescript ~(or (System/getenv "CLOJURESCRIPT_VERSION") "1.9.660")]
                 [org.clojure/test.check "0.10.0-alpha1"]
                 [org.clojure/tools.reader "1.0.0"]
                 [com.cognitect/transit-clj "0.8.300"]
                 [com.cognitect/transit-cljs "0.8.239"]
                 [fipp "0.6.8"]
                 [malabarba/lazy-map "1.3"]
                 [cljsjs/parinfer "1.8.1-0"]]
  :clean-targets ["out" "target"])

Allow parameterizing the ClojureScript version


(ns berry.converter.to-primitives-test
  (:require [berry.converter.to-primitives :refer :all]
            [clojure.test :refer :all]))

(deftest primitive-types-conversion
  (let [options {}]

    (testing "to-boolean"

             (is (and
                   (= "true" (to-boolean true options)))
                 (= "false" (to-boolean false options))))

    (testing "to-null"

             (is (= "null" (to-null nil options))))

    (testing "to-number"

             (testing "Floating-point numbers"

                      (is (= "15.3" (to-number 15.3 options))))

             (testing "Integers."

                      (is (= "21" (to-number 21 options)))))

    (testing "to-string"

             (is (= "\"hello\"" (to-string "hello" options))))))

Add test for to-primitives namespace.

Add test for to-primitives namespace.


(ns com.nomistech.clojure-the-language.core-async-1024-pending-ops
  (:require
   ;; [com.nomistech.clojure-the-language.core-async-1024-pending-ops :refer :all]
   [clojure.core.async :as a
    :exclude [map into reduce merge partition partition-by take]]
   [midje.sweet :refer :all]))

(fact "About pending operations"

  (fact "No more than 1024 pending puts"
    (let [c (a/chan)] (dotimes [i 1025] (a/put! c i)))
    => (throws AssertionError #"No more than 1024 pending puts"))

  (fact "No more than 1024 pending takes"
    (let [c (a/chan)] (dotimes [i 1025] (a/take! c #(do 42))))
    => (throws AssertionError #"No more than 1024 pending takes")))

core.async: Add stuff about no more than 1024 operations.


(ns buddy.auth.backends.stateless-token
  (:require [buddy.auth.protocols :as proto]
            [buddy.crypto.core :refer [base64->str]]
            [buddy.crypto.keys :refer [make-secret-key]]
            [buddy.crypto.signing :refer [loads]]
            [buddy.util :refer [m-maybe]]
            [clojure.string :refer [split]]
            [ring.util.response :refer [response? header status]]))

(defn parse-authorization-header
  "Given a request, try extract and parse
  authorization header."
  [request]
  (m-maybe [headers-map (:headers request)
            auth-header (get headers-map "authorization")
            pattern     (re-pattern "^Bearer (.+)$")
            matches     (re-find pattern auth-header)]
    (get matches 1)))

(defrecord StatelessTokenAuthBackend [pkey not-authorized-handler maxage]
  proto/IAuthentication
  (parse [_ request]
    (parse-authorization-header request))
  (authenticate [_ request data]
    (assoc request :identity (loads data pkey {:maxage maxage})))

  proto/IAuthorization
  (handle-unauthorized [_ request metadata]
    (let [rsp (when not-authorized-handler
                (not-authorized-handler request metadata))
          rsp (if (response? rsp) rsp
                (if (nil? rsp) {:body ""} {:body rsp}))]
      (-> rsp (status 401)))))

(defn stateless-token-backend
  "Given some options, create a new instance
  of HttpBasicBackend and return it."
  [pkey & {:keys [authorization-handler maxage]}]
  (->StatelessTokenAuthBackend
    (make-secret-key pkey)
    authorization-handler
    maxage))

Add stateless token auth backend.

Add stateless token auth backend.

(simplified oauth-like token authentication completely stateless)


(ns gtfve.data-check
  (:require [clojure.string :as string :refer [split join trim]]
            [clojure.pprint :as pp :refer [pprint]]
            [clj-time.format :as tf]
            [clj-time.coerce :refer [to-date]]
            [clojure.instant :as instant :refer [read-instant-date]]
            [datomic.api :as d]
            [clojure.set :as set :refer [union]]
            [gtfve.datomic :refer [conn uri feed]]))

(defn- collect-consecutive-stops
  "Return stops from a trip that are consecutively reused."
  [trip]
  (let [stops (->> (:trip/stops trip)
                   (sort-by :stop-time/stop-sequence))]
    (->> (reduce (fn [{:keys [last] :as acc} stop-time]
                   (let [{last-stop :stop-time/stop} last
                         {curr-stop :stop-time/stop} stop-time]
                     (if (= curr-stop last-stop)
                       (-> acc
                           (update-in [:coll] union #{last stop-time})
                           (assoc :last stop-time))
                       (assoc acc :last stop-time))))
                 {:coll #{}
                  :last nil}
                 stops)
         :coll)))

(defn find-consecutive-stops
  "Return all trip stops that are consecutively reused."
  [db]
  (->> (d/q '[:find [?t ...]
              :where [?t :trip/id]]
            db)
       (map (partial d/entity db))
       (reduce (fn [acc c]
                 (->> (collect-consecutive-stops c)
                      (sort-by :stop-time/stop-sequence)
                      (into acc)))
               [])))

Add namespace for data checking

Add namespace for data checking


(ns videotest.hex.core
  (:require
   [quil.applet :as qa :refer [applet-close]]
   [quil.core :as q]
   [quil.middleware :as m]))

;; Optoma Projector
;; (def DISPLAY-WIDTH 1280.0)
;; (def DISPLAY-HEIGHT 800.0)

;; Lenovo
(def DISPLAY-WIDTH 1366.0)
(def DISPLAY-HEIGHT 768.0)

;; 32 works
(def NUM-COL-BINS 64.0)
(def DISPLAY-BIN-SIZE (/ DISPLAY-WIDTH NUM-COL-BINS))
(def NUM-ROW-BINS (/ DISPLAY-HEIGHT DISPLAY-BIN-SIZE))

(def DISPLAY-BIN-SIZE-X2  (* DISPLAY-BIN-SIZE 2.0))
(def DISPLAY-BIN-SIZE-2   (/ DISPLAY-BIN-SIZE 2.0))

(defn grid-coords [col-bins row-bins]
  (doall
   (vec
    (for [row (range 0 row-bins)
          col (range 0 col-bins)]
      [col row]))))

(defn draw-cell [col row w half-w]
  (q/push-matrix)
  (q/rect (+ (* col w) half-w)
          (+ (* row w) half-w)
          w w)
  (q/pop-matrix))

(defn draw-hex-grid [{:keys [grid-coords]}]
  (q/rect-mode :center)
  (q/no-fill)
  (q/stroke-weight 1)
  (q/stroke 0 255 255 255)
  (dorun
   (map (fn [[col row]]
          (draw-cell col row DISPLAY-BIN-SIZE DISPLAY-BIN-SIZE-2))
        grid-coords)))

(defn setup []
  {:grid-coords (grid-coords NUM-COL-BINS NUM-ROW-BINS)
   :hex-cells {}})

(defn update [state]
  state)

(defn draw [state]
  (let [x 1]
    (q/background 255)
    (q/push-matrix)
    (q/translate DISPLAY-WIDTH 0)
    (q/scale -1 1)
    (draw-hex-grid state)
    (q/pop-matrix)))

(defn on-close [state]
  )

(q/defsketch videotest
  :title "hex"
  :size [DISPLAY-WIDTH DISPLAY-HEIGHT]
  :setup setup
  :update update
  :draw draw
  :on-close on-close
  :middleware [m/fun-mode])

(.setResizable (.frame videotest) true)

Add grid, in preparation of creating hex grid.


(ns main)

(defn main []
  (let [a (Double/parseDouble (read-line))
        b (Double/parseDouble (read-line))
        c (Double/parseDouble (read-line))]
    (format "%.1f" (/ (+ (* a 2.0) (* b 3.0) (* c 5.0)) 10.0))))

(println "MEDIA =" (main))

Solve Average 2 in clojure

Solve Average 2 in clojure


(ns main)

(def seconds-per-hour (* 60 60))
(def seconds-per-minutes 60)

(defn main []
  (loop [line (read-line)]
    (when line
      (let [value (Integer/parseInt line)
            hours (quot value seconds-per-hour)
            value (mod value seconds-per-hour)
            minutes (quot value seconds-per-minutes)
            seconds (mod value seconds-per-minutes)]
        (printf "%d:%d:%d%n" hours minutes seconds))
      (recur (read-line)))))

(main)

Solve Time Conversion in clojure

Solve Time Conversion in clojure


(ns caesium.sodium-test
  (:require [caesium.sodium :as s]
            [clojure.test :refer [deftest is]]))

(deftest init-test
  (is (#{0 1} (s/init)))
  (is (= 1 (s/init))))

Add a test for sodium init

Add a test for sodium init


;; gorilla-repl.fileformat = 1

;; **
;;; # Testing JLink
;;;
;;; You can use this worksheet to test whether JLink is set up correctly on your computer.
;; **

;; @@
(ns warm-swamp
  (:require [gorilla-plot.core :as plot])
  (:import [com.wolfram.jlink]))
;; @@
;; =>
;;; {"type":"html","content":"nil","value":"nil"}
;; <=

;; @@
(def kernel (com.wolfram.jlink.MathLinkFactory/createKernelLink "-linkmode launch -linkname \"/Applications/Mathematica.app/Contents/MacOS/MathKernel\""))
;; @@
;; =>
;;; {"type":"html","content":"#'warm-swamp/kernel","value":"#'warm-swamp/kernel"}
;; <=

;; @@
(.waitForAnswer kernel)
;; @@
;; =>
;;; {"type":"html","content":"8","value":"8"}
;; <=

;; @@
(.getString kernel)
;; @@
;; =>
;;; {"type":"html","content":""In[1]:= "","value":"\"In[1]:= \""}
;; <=

;; @@
(.evaluate kernel "1 + 1")
;; @@
;; =>
;;; {"type":"html","content":"nil","value":"nil"}
;; <=

;; @@
(.waitForAnswer kernel)
;; @@
;; =>
;;; {"type":"html","content":"3","value":"3"}
;; <=

;; @@
(.getString kernel)
;; @@
;; =>
;;; {"type":"html","content":""2"","value":"\"2\""}
;; <=

;; @@
(.close kernel)
;; @@
;; =>
;;; {"type":"html","content":"nil","value":"nil"}
;; <=

;; @@

;; @@

Add a worksheet to test JLink is operational.


(ns merkle-db.key-test
  (:require
    [clojure.test :refer :all]
    [merkle-db.key :as key])
  (:import
    blocks.data.PersistentBytes))

(defn ->key
  "Construct a new `PersistentBytes` value containing the given byte data."
  [& data]
  (PersistentBytes/wrap (byte-array data)))

(deftest lexicographic-ordering
  (testing "equal arrays"
    (is (zero? (key/compare (byte-array 0) (byte-array 0))))
    (is (zero? (key/compare (byte-array [1 2 3]) (byte-array [1 2 3])))))
  (testing "equal prefixes"
    (is (neg? (key/compare (byte-array [1 2 3])
                           (byte-array [1 2 3 4]))))
    (is (pos? (key/compare (byte-array [1 2 3 4])
                           (byte-array [1 2 3])))))
  (testing "order-before"
    (is (neg? (key/compare (byte-array [1 2 3])
                           (byte-array [1 2 4]))))
    (is (neg? (key/compare (byte-array [1 2 3])
                           (byte-array [1 3 2]))))
    (is (neg? (key/compare (byte-array [0 2 3 4])
                           (byte-array [1 3 2 1]))))
  (testing "order-after"
    (is (pos? (key/compare (byte-array [1 2 4])
                           (byte-array [1 2 3]))))
    (is (pos? (key/compare (byte-array [1 3 2])
                           (byte-array [1 2 3]))))
    (is (pos? (key/compare (byte-array [1 3 2 1])
                           (byte-array [0 2 3 4])))))))

Add unit tests for key functions.

Add unit tests for key functions.


(ns sidequarter-frontend.styles
  (:require [garden.def :refer [defstylesheet defstyles defrule]]
            [garden.units :refer [px]]))

(defrule horizontal-list :ul.h-list)

(defstyles screen
  (horizontal-list
   {:list-style-type "none"
    :margin 0
    :padding 0}
   [:li
    {:display "inline"
     :margin-right (px 10)}])
  [[:body
    {:background-color "#00bcd4"}]
   [:.sidekiq-list
    [:.sidekiq
     {:background-color "#fff"}]]])

Add garden style generation with few background colors


(defn solution
  []
  (->> (range 1 100)
       (reduce *')
       (str)
       (seq)
       (pmap #(Character/getNumericValue %))
       (reduce +)
       (str)))

Solve 20 in Clojure (alterantive solution)


(ns ^:figwheel-always sidequarter-frontend.api
    (:require-macros [sidequarter-frontend.env :refer [cljs-env]]
                     [cljs.core.async.macros :refer [go]])
    (:require [cljs-http.client :as http]
              [cljs.core.async :refer [<! >! put! chan]]))

(def api-url (cljs-env :api-url))

(defn get-sidekiqs []
  (http/jsonp api-url {:callback-name "callback"}))

Add namespace for performing API calls

Add namespace for performing API calls


(ns clojure-pf.data-link-type
  "Supported data link type level codes."
  (:require [clojure.set :refer [map-invert]]))

(def ^:private ^:const dlt-map
  {:null      0     ; no link-layer encapsulation
   :en10mb    1     ; ethernet (10Mb)
   :ieee80211 105}) ; IEEE 802.11 wireless

(def ^:private ^:const code-map
  (map-invert dlt-map))

(defn to-code [dlt]
  (get dlt-map dlt))

(defn from-code [code]
  (get code-map code))

Add data link type utility

Add data link type utility


(ns rotating-seq.core)

(defn create-r-seq [bucket-lifetime expire-interval]
  (assert (zero? (mod bucket-lifetime expire-interval)) "Bucket lifetime must divide evenly over expiration interval")
  (let [n-buckets (int (Math/ceil (/ bucket-lifetime expire-interval)))]
    (vec (repeat n-buckets (list)))))

(defn add-to-head [r-seq elements]
  (assoc r-seq 0 (into (r-seq 0) elements)))

(defn update-head [r-seq f & args]
  (update-in r-seq [0] (fn [x]
                         (let [result (f (concat x args))]
                           (if-not (coll? result)
                             [result] result)))))

(defn expire-bucket [r-seq]
  (vec (conj (butlast r-seq) (list))))

Add rotating seq to onyx for experimentation.


(ns lazytest.describe-asserts
  (:use lazytest.describe
	[lazytest.expect :only (expect)]
	[lazytest.testable :only (get-tests)]
	[lazytest.runnable-test :only (run-tests)]
	[lazytest.test-result :only (success?)]))

(remove-ns 'one)
(create-ns 'one)
(intern 'one 'a (describe "Addition"
		  (it "adds"
		    (expect (= 4 (+ 2 2))))))
(let [result (first (map run-tests (get-tests (the-ns 'one))))]
  (assert (success? result)))
(remove-ns 'one)

(remove-ns 'two)
(create-ns 'two)
(intern 'two 'b (describe "Addition"
		  (it "adds"
		    (expect (= 999 (+ 2 2))))))
(let [result (first (map run-tests (get-tests (the-ns 'two))))]
  (assert (not (success? result))))
(remove-ns 'two)

Add assertions for simple describe/is tests


(ns circle.backend.test-pallet
  (:use midje.sweet)
  (:require [circle.backend.pallet]))

(fact "flags->rvmrc works"
  (circle.backend.pallet/flags->rvmrc {:a 4 :b 6 :f "some string"})
  => "export a=4\nexport b=6\nexport f=\"some string\"\n")

Add tests for the flags->rvmrc function

Add tests for the flags->rvmrc function


(ns metabase.models.card-test
  (:require [expectations :refer :all]
            (metabase.api [card-test :refer [post-card]]
                          [dash-test :refer [create-dash]])
            [metabase.db :refer [ins]]
            (metabase.models [card :refer [Card]]
                             [dashboard-card :refer [DashboardCard]])
            [metabase.test.util :refer [random-name]]))

;; Check that the :dashboard_count delay returns the correct count of Dashboards a Card is in
(expect [0 1 2]
  (let [{card-id :id}       (post-card (random-name))
        get-dashboard-count (fn [] @(:dashboard_count (Card card-id)))]

    [(get-dashboard-count)
     (do (ins DashboardCard :card_id card-id, :dashboard_id (:id (create-dash (random-name))))
         (get-dashboard-count))
     (do (ins DashboardCard :card_id card-id, :dashboard_id (:id (create-dash (random-name))))
         (get-dashboard-count))]))

Add unit test for Card dashboard_count :sweat:


(ns onyx.log.commands.assign-bookkeeper-log-id
  (:require [clojure.core.async :refer [>!!]]
            [clojure.data :refer [diff]]
            [onyx.log.commands.common :as common]
            [onyx.log.entry :refer [create-log-entry]]
            [schema.core :as s]
            [onyx.schema :refer [Replica LogEntry Reactions ReplicaDiff State]]
            [onyx.extensions :as extensions]))

(s/defmethod extensions/apply-log-entry :signal-ready :- Replica
  [{:keys [args]} :- LogEntry replica]
  (update-in replica
             [:state-logs (:job-id args) (:task-id args) (:slot-id args)]
             (fn [logs]
               (conj (vec logs) (:ledger-id args)))))

(s/defmethod extensions/replica-diff :signal-ready :- ReplicaDiff
  [{:keys [args]} :- LogEntry old new]
  (second (diff (:state-logs old) (:state-logs new))))

(s/defmethod extensions/reactions :signal-ready :- Reactions
  [{:keys [args]} :- LogEntry old new diff peer-args]
  [])

(s/defmethod extensions/fire-side-effects! :signal-ready :- State
  [{:keys [args message-id]} :- LogEntry old new diff state]
  state)

Add log command to assign bookkeeper log ids


(ns main)

(defn main []
  (loop [line (read-line)]
    (when line
      (let [value (-> line
                      (Integer/parseInt))
            years (quot value 365)
            months (-> (mod value 365)
                       (quot 30))
            days (-> (mod value 365)
                     (mod 30))]
        (printf "%d ano(s)%n%d mes(es)%n%d dia(s)%n" years months days))
      (recur (read-line)))))

(main)

Solve Age in Days in clojure

Solve Age in Days in clojure


(ns
  ^{:author "Brian Craft"
    :doc "c3p0 connection pool utilities."}
  cavm.conn-pool
  (:import (com.mchange.v2.c3p0 ComboPooledDataSource)))

(defn pool
  "Create a connection pool."
  [{:keys [classname subprotocol subname
           user password
           excess-timeout idle-timeout
           minimum-pool-size maximum-pool-size
           test-connection-query idle-connection-test-period
           test-connection-on-checkin test-connection-on-checkout
           conn-customizer]
    :or {excess-timeout (* 30 60)
         idle-timeout (* 3 60 60)
         minimum-pool-size 3
         maximum-pool-size 15
         test-connection-query nil
         idle-connection-test-period 0
         test-connection-on-checkin false
         test-connection-on-checkout false
         conn-customizer nil}}]
  {:datasource (doto (ComboPooledDataSource.)
                 (.setDriverClass classname)
                 (.setJdbcUrl (str "jdbc:" subprotocol ":" subname))
                 (.setUser user)
                 (.setPassword password)
                 (.setMaxIdleTimeExcessConnections excess-timeout)
                 (.setMaxIdleTime idle-timeout)
                 (.setMinPoolSize minimum-pool-size)
                 (.setMaxPoolSize maximum-pool-size)
                 (.setIdleConnectionTestPeriod idle-connection-test-period)
                 (.setTestConnectionOnCheckin test-connection-on-checkin)
                 (.setTestConnectionOnCheckout test-connection-on-checkout)
                 (.setPreferredTestQuery test-connection-query)
                 (.setConnectionCustomizerClassName conn-customizer))})

Add utility for connection pools.

Add utility for connection pools.


(ns clojure-walkthrough.jocj.ch03-04
  (use clojure.pprint)
  (:gen-class))

(def MAX-CONNECTION 10)

(def RABBITMQ-CONNECTION)

(def ^:dynamic RABBITMQ-CONNECTION)

(binding [RABBITMQ-CONNECTION (new-connection)]
  (
   ;; do something here with RABBITMQ-CONNECTION
   ))

;; Special variables

(def ^:dynamic *db-host* "localhost")

(defn expense-report [start-date end-date]
  (println *db-host*))  ;; cand do real work

;; rebind once we are ready
(binding [*db-host* "production"]
  (expense-report "2010-01-01" "2010-01-07")) ;; Will print "production" to the console

;; Dynamic Scope

(def ^:dynamic *eval-me* 10)

(defn print-the-var [label]
  (println label *eval-me*))

(print-the-var "A:") ;; will print "A: 10" in the REPL

(binding [*eval-me* 20] ;; the first binding
  (print-the-var "B:")
  (binding [*eval-me* 30] ;; the 2nd binding
    (print-the-var "C:"))
  (print-the-var "D:"))

;; Result:
;; A: 10
;; B: 20
;; C: 30
;; D: 20

(print-the-var "E:")

;; Result:
;; E: 10

Add example from 3.4 - scope

Add example from 3.4 - scope


(ns workflo.macros.specs.conforming-query
  (:require #?(:cljs [cljs.spec :as s]
               :clj  [clojure.spec :as s])
            #?(:cljs [cljs.spec.impl.gen :as gen]
               :clj  [clojure.spec.gen :as gen])
            [workflo.macros.props.util :as util]
            [workflo.macros.specs.query]))

;;;; Simple properties

(s/def ::simple-property
  (s/tuple #{:simple}
           :workflo.macros.specs.query/property-name))

;;;; Links

(s/def ::link
  (s/tuple #{:link}
           :workflo.macros.specs.query/link))

;;;; Joins

(s/def ::model-join
  (s/tuple #{:model-join}
           :workflo.macros.specs.query/model-join))

(s/def ::recursive-join
  (s/tuple #{:recursive-join}
           :workflo.macros.specs.query/recursive-join))

(s/def ::properties-join
  (s/tuple #{:properties-join}
           :workflo.macros.specs.query/properties-join))

(s/def ::join
  (s/tuple #{:join}
           (s/or :model-join ::model-join
                 :recursive-join ::recursive-join
                 :properties-join ::properties-join)))

;;;; Individual properties

(s/def ::property-value
  (s/or :simple ::simple-property
        :link   ::link
        :join   ::join))

(s/def ::property
  (s/tuple #{:property} ::property-value))

;;;; Nested properties

(s/def ::base
  :workflo.macros.specs.query/property-name)

(s/def ::children
  (s/with-gen
    (s/and vector? (s/+ ::property-value))
    #(gen/vector (s/gen ::property-value)
                 1 10)))

(s/def ::nested-properties-value
  (s/keys :req-un [::base ::children]))

(s/def ::nested-properties
  (s/tuple #{:nested-properties} ::nested-properties-value))

;;;; Queries

(s/def ::regular-query-value
  (s/or :property ::property
        :nested-properties ::nested-properties))

(s/def ::regular-query
  (s/tuple #{:regular-query} ::regular-query-value))

(s/def ::parameters
  :workflo.macros.specs.query/parameters)

(s/def ::parameterized-query-value
  (s/keys :req-un [::regular-query-value ::parameters]))

(s/def ::parameterized-query
  (s/tuple #{:parameterized-query} ::parameterized-query-value))

(s/def ::query
  (s/with-gen
    (s/and vector?
           (s/+ (s/alt :regular-query ::regular-query
                       :parameterized-query ::parameterized-query)))
    #(gen/vector (gen/one-of [(s/gen ::regular-query)
                              (s/gen ::parameterized-query)])
                 1 10)))

Add specs for the results of parsing queries with clojure.spec/conform


(ns yada.dev.examples
  (:require
   [yada.yada :as yada]
   [manifold.stream :as ms]))

(defn routes []
  ["/examples"
   [
    ["/sse-body" (yada/resource
             {:methods
              {:get {:produces "text/event-stream"
                     :response (fn [ctx] (ms/periodically 400 (fn [] "foo")))}}})]
    ["/sse-resource" (yada/handler (ms/periodically 400 (fn [] "foo")))]]])

(ns yada.dev.examples
  (:require
   [yada.yada :as yada]
   [manifold.stream :as ms]
   [manifold.deferred :as d]))

(defn routes []
  ["/examples"
   [
    ["/sse-resource" (yada/handler (ms/periodically 400 (fn [] "foo")))]
    ["/sse-body"
     (yada/resource
      {:methods
       {:get {:produces "text/event-stream"
              :response (fn [ctx]
                          (let [source (ms/periodically 400 (fn [] "foo"))
                                sink (ms/stream 10)]
                            (ms/on-closed
                             sink
                             (fn [] (println "closed")))
                            (ms/connect source sink)
                            sink
                            ))}}})]
    ["/sse-body-with-close"
     (yada/resource {:methods {:get
                               {:produces "text/event-stream"
                                :response (fn [ctx]
                                            (let [source (ms/periodically 400 (fn [] "foo"))
                                                  sink (ms/stream 10)]
                                              (ms/on-closed sink (fn [] (println "closed")))
                                              (ms/connect source sink)
                                              sink))}}})]]])

Add example of SSE channel close notification


(ns mdr2.pipeline2.utils
  "Utilities for dealing with the [Pipeline2 Web Service
  API](https://code.google.com/p/daisy-pipeline/wiki/WebServiceAPI)"
  (:require [clojure.zip :refer [xml-zip]]
            [clojure.data.zip.xml :refer [xml1-> attr]]
            [mdr2.pipeline2.core :as dp2]))

(def ^:private poll-interval 1000)

(defn- get-id [job]
  (-> job xml-zip (xml1-> (attr :id))))

(defn- get-status [job]
  (-> job xml-zip (xml1-> (attr :status))))

(defn create-job-and-wait [script inputs options]
  (let [id (get-id (dp2/job-create script inputs options))]
    (Thread/sleep poll-interval) ; wait a bit before polling the first time
    (loop [result (dp2/job id)]
      (let [status (get-status result)]
        (if (= "RUNNING" status)
          (do
            (Thread/sleep poll-interval)
            (recur (dp2/job id)))
          result)))))

Add utilities to deal with the pipeline2 web service api


(ns main)

(defn main []
  (let [n (Double/parseDouble (read-line))]
   (format "%.4f" (* (* n n) 3.14159))))

(printf "A=%s%n" (main))

Solve Area of a Circle in clojure

Solve Area of a Circle in clojure


(ns circle.db.migration-lib
  "Library for performing DB migrations in mongo"
  (:require [somnium.congomongo :as mongo])
  (:use [clojure.tools.logging :only (infof)])
  (:use [arohner.utils :only (inspect)]))

(defonce migrations (ref []))

(defn clear-migrations []
  (dosync
   (alter migrations (constantly []))))

(defn add-migration [m]
  (dosync
   (alter migrations conj m)))

(defn def-migration
  "Returns a new migration object. Query is the :where clause of a
  congomongo query. transform is a fn of one argument, the old
  row. transform should return the updated row."
  [name & {:keys [coll query transform] :as args}]
  (add-migration (merge args {:name name})))

(defn run-migration [m]
  (infof "starting migration %s" (-> m :name))
  (doseq [row (mongo/fetch (-> m :coll) :where (-> m :query))
          :let [coll (-> m :coll)
                t (-> m :transform)]]
    (mongo/update! coll row (t row)))
  (infof "finished migration %s" (-> m :name)))

(defn run-all-migrations []
  (infof "starting migrations")
  (doseq [m @migrations]
    (run-migration m))
  (infof "migrations finished"))

Add a migration library, call it on startup


(ns com.nomistech.clojure-the-language.c-200-clojure-basics.s-600-clojure-spec
  (:require [clojure.spec.alpha :as s]
            [midje.sweet :refer :all]))

;;;; ___________________________________________________________________________
;;;; Stuff from https://clojure.org/guides/spec

(fact
  (s/conform even? 1000)
  => 1000)

(fact
  (s/conform even? 999)
  => :clojure.spec.alpha/invalid)

Add beginnings of clojure.spec examples

Add beginnings of clojure.spec examples


(ns cavm.h2-unpack-rows)

; The following a mechanism to avoid a direct dependency on other cavm code
; that should not be aot compiled.
; This file has to be aot compiled so h2 can find it (or so I'm lead to believe).
; However a dependency on other files causes them to be affected by the aot. This
; messes up dynamic reloading of those files, meaning we can't develop from
; the repl reliably. The workaround is to provide a method for injecting the
; dependency, by setting a var root.

(def lookup-row nil)
(defn set-lookup-row! [f]
  (alter-var-root (var lookup-row) (fn [_] f)))

(def lookup-value nil)
(defn set-lookup-value! [f]
  (alter-var-root (var lookup-value) (fn [_] f)))

;
; Blob unpack functions for h2.
;

(defn- -unpack [conn field-id row]
  (lookup-row conn field-id row))

; Somehow the return value will be cast automatically.
(def ^:private -unpackCode -unpack)

(defn- -unpackValue [conn field-id row]
  (lookup-value conn field-id row))

(gen-class :name unpack_rows
           :methods [^:static [unpackCode [java.sql.Connection int int] int]
                     ^:static [unpack [java.sql.Connection int int] float]
                     ^:static [unpackValue [java.sql.Connection int int] String]])

Add blob unpack hooks for h2.

Add blob unpack hooks for h2.


(ns cmr.transmit.test.echo.rest
  "Tests for cmr.transmit.echo.rest namespace"
  (:require [clojure.test :refer :all]
            [cmr.transmit.echo.rest :as rest]))

(deftest test-error-masked
  (let [error-message "Unexpected error message: Token 123 does not exist."
       status 500]
    (is (= (format "Unexpected status %d from response. body: %s" status "Token does not exist")
           (rest/unexpected-status-error! status error-message)))))

Add transmit lib error test

Add transmit lib error test


(ns re-frame.subs-test
  (:require [clojure.test  :refer :all]
            [re-frame.subs :as subs]
            [re-frame.db   :as db]))

(defn fixture-re-frame
  [f]
  (let [restore-re-frame (re-frame.core/make-restore-fn)]
    (f)
    (restore-re-frame)))

(use-fixtures :each fixture-re-frame)

(deftest test-reg-sub-clj-repl
  (subs/reg-sub
   :a-sub
   (fn [db _] (:a db)))

  (subs/reg-sub
   :b-sub
   (fn [db _] (:b db)))

  (subs/reg-sub
   :a-b-sub
   (fn [_ _]
     [(subs/subscribe [:a-sub])
      (subs/subscribe [:b-sub])])
   (fn [[a b] _]
     {:a a :b b}))

  (let [test-sub (subs/subscribe [:a-b-sub])]
    (reset! db/app-db {:a 1 :b 2})
    (is (= {:a 1 :b 2} @test-sub))
    (swap! db/app-db assoc :b 3)
    (is (= {:a 1 :b 3} @test-sub))))

Add tests for subs in clj

Add tests for subs in clj


(ns com.nomistech.clojure-the-language.c-800-libraries.s-300-core-async.ss-010-core-async-functions-on-channels
  (:require [clojure.core.async :as a]
            [midje.sweet :refer :all]))

;;;; You can put functions on channels.
;;;; - That's cool.
;;;; - But should you?
;;;;   - Maybe it makes debugging harder.
;;;;     - You read something about this.
;;;; - You could use an agent instead.

(defn put-and-take-n-funs [n]
  (let [c (a/chan 10)]
    (dotimes [i n]
      (a/>!! c (fn [] i)))
    (for [i (range n)]
      (let [f (a/<!! c)]
        (f)))))

(fact
  (put-and-take-n-funs 10)
  => (range 10))

Add example of putting functions on channels


(ns workflo.macros.specs.parsed-query
  (:require #?(:cljs [cljs.spec :as s]
               :clj  [clojure.spec :as s])
            #?(:cljs [cljs.spec.impl.gen :as gen]
               :clj  [clojure.spec.gen :as gen])
            [workflo.macros.props.util :as util]
            [workflo.macros.specs.query]))

(s/def ::type
  #{:property :link :join})

(s/def ::name
  :workflo.macros.specs.query/property-name)

(s/def ::link-id
  :workflo.macros.specs.query/link-id)

(s/def ::join-target
  (s/with-gen
    (s/or :model :workflo.macros.specs.query/model-name
          :recursion :workflo.macros.specs.query/recursion
          :properties ::query)
    #(gen/one-of [(s/gen :workflo.macros.specs.query/model-name)
                  (s/gen :workflo.macros.specs.query/recursion)
                  (s/gen '#{[{:type :property :name name}]
                            [{:type :property :name name}
                             {:type :property :name email}]
                            [{:type :property :name name}
                             {:type :link :name current-user :link-id '_}
                             {:type :join :name friends
                              :join-target 'User}]})])))

(s/def ::parameters
  :workflo.macros.specs.query/parameters)

(defmulti  typed-property :type)

(defmethod typed-property :property [_]
  (s/keys :req-un [::type ::name]
          :opt-un [::parameters]))

(defmethod typed-property :link [_]
  (s/keys :req-un [::type ::name ::link-id]
          :opt-un [::parameters]))

(defmethod typed-property :join [_]
  (s/keys :req-un [::type ::name ::join-target]
          :opt-un [::parameters]))

(s/def ::property
  (s/multi-spec typed-property :type))

(s/def ::query
  (s/with-gen
    (s/and vector? (s/+ ::property))
    #(gen/vector (s/gen ::property)
                 1 10)))

Add specs for the data format resulting from parsing queries


(ns forecast.repository.ip-locator
  (:require [clj-http.client :as client]
            [cheshire.core :refer [parse-string]]
            [clojure.string :refer [split]]
            ))

(defn ip->location
  [ip]
  (try
    (let [url (str "http://ipinfo.io/" ip)
          response (client/get url {:accept :json :socket-timeout 1000 :conn-timeout 1000})]
      (if (= (:status response) 200)
        (->
         ((parse-string (:body response)) "loc")
         (split #",")
         ((fn [v] {:latitude (read-string (first v)) :longitude (read-string (second v))}))
         )
        response
        ))
    (catch Exception e {:error (str e)})))

;; (prn (ip->location "8.8.8.8"))

Add ip resolver to get lat/long.

Add ip resolver to get lat/long.


(ns riemann.hipchat-test
  (:use riemann.hipchat
        clojure.test)
  (:require [riemann.logging :as logging]))

(def api-key (System/getenv "HIPCHAT_API_KEY"))
(def room (System/getenv "HIPCHAT_ALERT_ROOM"))
(def alert_user "Riemann_HC_Test")

(when-not api-key
  (println "export HIPCHAT_API_KEY=\"...\" to run these tests."))

(when-not room
  (println "export HIPCHAT_ALERT_ROOM=\"...\" to run these tests."))

(logging/init)

(deftest good_event
  (let [hc (hipchat {:token api-key :room room :from alert_user :notify 0})]
    (hc {:host "localhost"
         :service "hipchat test good"
         :metric 42
         :state "ok"})))

(deftest error_event
  (let [hc (hipchat {:token api-key :room room :from alert_user :notify 0})]
    (hc {:host "localhost"
         :service "hipchat test error"
         :metric 43
         :state "error"})))

(deftest critical_event
  (let [hc (hipchat {:token api-key :room room :from alert_user :notify 0})]
    (hc {:host "localhost"
         :service "hipchat test critical"
         :metric 44
         :state "critical"})))

(deftest yellow
  (let [hc (hipchat {:token api-key :room room :from alert_user :notify 0})]
    (hc {:host "localhost"
         :service "hipchat test yellow"
         :metric 45
         :state "unknown"})))

(deftest multiple_events
  (let [hc (hipchat {:token api-key :room room :from alert_user :notify 0})]
    (hc [{:host "localhost"
          :service "hipchat multi 1"
          :metric 46
          :state "ok"}
         {:host "localhost"
          :service "hipchat multi 2"
          :metric 47
          :state "ok"}])))

Add some basic hipchat tests

Add some basic hipchat tests


(ns com.stuartsierra.lazytest-spec
  (:use [com.stuartsierra.lazytest
         :only (describe spec spec?
                         is given defcontext
                         context? ok? success?
                         pending? error? container?)]))

(defcontext dummy-context-1 [] 1)

(defcontext is-without-givens []
  (is (= 1 1) "hello" (= 1 2)))

(defcontext is-with-givens []
  (given [x dummy-context-1]
         (is (= x 1) "hello" (= x 2))))

(spec is-spec "The 'is' macro"
      (given [it is-without-givens]
             (spec "without any givens"
                   (is "should create a spec"
                       (spec? it)

                       "should create an invokable fn"
                       (instance? clojure.lang.IFn it)

                       "should attach :doc string metadata to assertions"
                       (= "hello" (:doc (meta (second (:children it)))))

                       "should attach :form metadata to assertions"
                       (= '(= 1 1) (:form (meta (first (:children it))))))

                   (spec "should have children"
                         (is (seq (:children it))

                             "that are specs"
                             (every? spec? (:children it))

                             "that are invokable IFns"
                             (every? #(instance? clojure.lang.IFn %) (:children it))

                             "as many as there are expressions"
                             (= 2 (count (:children it)))))))

      (given [it is-with-givens]
             (spec "with givens"
                   (is "should create a spec"
                       (spec? it)

                       "should create an invokable IFns"
                       (instance? clojure.lang.IFn it)

                       "should attach :doc string metadata to assertions"
                       (= "hello" (:doc (meta (second (:children it)))))

                       "should attach :form metadata to assertions"
                       (= '(= x 1) (:form (meta (first (:children it))))))

                   (spec "should have children"
                         (is (seq (:children it))

                             "that are specs"
                             (every? spec? (:children it))

                             "that are invokable IFns"
                             (every? #(instance? clojure.lang.IFn %) (:children it))

                             "as many as there are expressions"
                             (= 2 (count (:children it)))

                             (spec "with contexts"
                                   (is (seq (:contexts (first (:children it))))
                                       "that are Context objects"
                                       (every? context? (:contexts (first (:children it)))))))))))

(comment
  (spec assertions-spec "Assertions, when invoked"
        (given [it is-without-givens]
               (spec "should return an object"
                     (is (not (nil? ((:first (:children it)))))
                         "that supports success?"
                         (ok? (success? ((:first (:children it)))))
                         "that supports pending?"
                         (ok? (pending? ((:first (:children it)))))
                         "that supports error?"
                         (ok? (error? ((:first (:children it)))))
                         "that supports container?"
                         (ok? (container? ((:first (:children it))))))))))

Add first round of self-tests

Add first round of self-tests


;
;  (C) Copyright 2017  Pavel Tisnovsky
;
;  All rights reserved. This program and the accompanying materials
;  are made available under the terms of the Eclipse Public License v1.0
;  which accompanies this distribution, and is available at
;  http://www.eclipse.org/legal/epl-v10.html
;
;  Contributors:
;      Pavel Tisnovsky
;

(ns clj-mrazik.db-interface-test
  (:require [clojure.test :refer :all]
            [clj-mrazik.db-interface :refer :all]))

;
; Common functions used by tests.
;

(defn callable?
    "Test if given function-name is bound to the real function."
    [function-name]
    (clojure.test/function? function-name))

;
; Tests for various functions
;

(deftest test-select-word-class-id-existence
    "Check that the clj-mrazik.db-interface/select-word-class-id definition exists."
    (testing "if the clj-mrazik.db-interface/select-word-class-id definition exists."
        (is (callable? 'clj-mrazik.db-interface/select-word-class-id))))

(deftest test-select-source-id-existence
    "Check that the clj-mrazik.db-interface/select-source-id definition exists."
    (testing "if the clj-mrazik.db-interface/select-source-id definition exists."
        (is (callable? 'clj-mrazik.db-interface/select-source-id))))

(deftest test-insert-word-into-dictionary-existence
    "Check that the clj-mrazik.db-interface/insert-word-into-dictionary definition exists."
    (testing "if the clj-mrazik.db-interface/insert-word-into-dictionary definition exists."
        (is (callable? 'clj-mrazik.db-interface/insert-word-into-dictionary))))

(deftest test-select-words-existence
    "Check that the clj-mrazik.db-interface/select-words definition exists."
    (testing "if the clj-mrazik.db-interface/select-words definition exists."
        (is (callable? 'clj-mrazik.db-interface/select-words))))

(deftest test-select-word-count-existence
    "Check that the clj-mrazik.db-interface/select-word-count definition exists."
    (testing "if the clj-mrazik.db-interface/select-word-count definition exists."
        (is (callable? 'clj-mrazik.db-interface/select-word-count))))

(deftest test-all-words-count-existence
    "Check that the clj-mrazik.db-interface/all-words-count definition exists."
    (testing "if the clj-mrazik.db-interface/all-words-count definition exists."
        (is (callable? 'clj-mrazik.db-interface/all-words-count))))

Test for the module db-interface + basic checks


(ns cmr.metadata-db.migrations.087-update-generic-document-name-length
  (:require
   [config.mdb-migrate-helper :as h]))

(defn up
  "Migrates the database up to version 87."
  []
  (println "cmr.metadata-db.migrations.087-update-generic-document-name-length up...")
  (h/sql "alter table METADATA_DB.CMR_GENERIC_DOCUMENTS modify document_name VARCHAR(1020)"))

(defn down
  "Migrates the database down from version 87."
  []
  ;; do nothing as we don't want to truncate the document name
  (println "cmr.metadata-db.migrations.087-update-generic-document-name-length down..."))

CMR-8766: Change CMR_GENERIC_DOCUMENTS DOCUMENT_NAME column size from 20 to 1020.


;   Copyright (c) Rich Hickey. All rights reserved.
;   The use and distribution terms for this software are covered by the
;   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
;   which can be found in the file epl-v10.html at the root of this distribution.
;   By using this software in any fashion, you are agreeing to be bound by
;   the terms of this license.
;   You must not remove this notice, or any other, from this software.

(ns ^{:doc "Tests for reading [:tag {:attr 'value} body*] as XML."
      :author "Alan Malloy"}
  clojure.data.xml.test-sexp
  (:use [clojure.test :only [deftest is are]]
        [clojure.data.xml :as xml :only [sexp-as-element
                                         sexps-as-fragment element]]))

(deftest as-element
  (let [xml-input "<tag attr=\"value\"><body /></tag>"
        sexp-input [:tag {:attr "value"} :body]]
    (is (= (with-in-str xml-input (xml/parse *in*))
           (sexp-as-element sexp-input)))))

(deftest as-fragment
  (let [input (list [:tag1 "stuff"]
                    [:tag2 "other"])]
    (is (= (sexps-as-fragment input)
           (map sexp-as-element input)))
    (is (thrown? Exception (sexp-as-element input)))))

Add a test for new hiccup/prxml/sexp-based xml style


(ns integration.braid.system-start-stop-test
  (:require [braid.core :refer :all]
            [clojure.test :refer :all]))

(deftest start-stop
  (is (start! 0))
  (is (stop!)))

Add simple integration test for system startup/shutdown


{:nodes
 {:comp
  {:name "gen-feature-counts",
   :type "tool",
   :args []}
  :prn1 {:type "func",
         :name "prn"}},
 :edges
 {:comp [:prn1]}}

Add job flow for general rnaseq comparisons


(ns main)

(defn sum-all-divibles-by
  [n limit]
  (let [p (quot limit n)]
    (quot (* n (* p (+ p 1))) 2)))

(defn main []
  (- (+ (sum-all-divibles-by 3 999)
        (sum-all-divibles-by 5 999))
     (sum-all-divibles-by 15 999)))

(println (main))

Solve Multiples of 3 and 5 in clojure

Solve Multiples of 3 and 5 in clojure


(ns subman.t-views
  (:require [midje.sweet :refer [fact truthy]]
            [subman.views :as views]))

(fact "index page should be ok"
      (views/index-page) => truthy)

Add tests for server side views

Add tests for server side views


(ns clojure.clojure-walkthrough.cjia.ch08-object)

;; The complete simple object system for Clojure

(declare ^:dynamic this)

(declare find-method)

(defn new-object [klass]
  (let [state (ref {})]
    (fn thiz [command & args]
      (case command
        :class klass
        :class-name (klass name)
        :set! (let [[k v] args]
                (dosync (alter state assoc k v))
                nil)
        :get (let [[key] args]
               (@state key))
        (let [method (klass :method command)]
          (if-not method
            (throw (RuntimeException.
                    (str "Unable to respond to " command))))
          (binding [this thiz]
            (apply method args)))))))

(defn new-class [class-name parent methods]
  (fn klass [command & args]
    (case command
      :name (name class-name)
      :parent parent
      :new (new-object klass)
      :methods methods
      :method (let [[method-name] args]
                (find-method method-name methods)))))

(def OBJECT (new-class :OBJECT nil {}))

(defn find-method [method-name klass]
  (or ((klass :methods) method-name)
      (if-not (= #'OBJECT klass)
        (find-method method-name (klass :parent)))))

(defn method-spec [sexpr]
  (let [name (keyword (second sexpr))
        body (next sexpr)]
    [name (conj body 'fn)]))

(defn method-specs [sexprs]
  (->> sexprs
       (filter #(= 'method (first %)))
       (mapcat method-spec)
       (apply hash-map)))

(defn parent-class-spec [sexprs]
  (let [extends-spec (filter #(= 'extends (first %)) sexprs)
        extends (first extends-spec)]
    (if (empty? extends)
      'OBJECT
      (last extends))))

(defmacro defclass [class-name & specs]
  (let [parent-class (parent-class-spec specs)
        fns (or (method-specs specs) {})]
    `(def ~class-name (new-class '~class-name #'~parent-class ~fns))))

Add the complete example for simple object system!


(ns bakyeono.litedocx.unit-test
  (:require [clojure.test :refer :all]
            [bakyeono.litedocx.unit :refer :all]))

(deftest convert-test
  (is (== (convert "1m" "m") 1))
  (is (== (convert "1 cm" "cm") 1))
  (is (== (convert "1.0mm" "mm") 1))
  (is (== (convert "1inch" "inch") 1))
  (is (== (convert "1 in." "inch") 1))
  (is (== (convert "1 inch" "cm") 2.54))
  (is (== (convert "72 pt" "inch") 1))
  (is (== (convert "1 yd" "inch") 1/36)))

Add unit tests for litedocx.unit package