Skip to content

Commit

Permalink
midje.clojure.core for things I wish were in clojure.core
Browse files Browse the repository at this point in the history
  • Loading branch information
marick committed Jan 26, 2013
1 parent b80eafd commit 1def023
Show file tree
Hide file tree
Showing 34 changed files with 316 additions and 285 deletions.
2 changes: 1 addition & 1 deletion src/midje/checkers.clj
@@ -1,7 +1,7 @@
(ns ^{:doc "Checkers are for checking results of expectations, or checking
that appropriate arguments are passed to prerequisites"}
midje.checkers
(:use [midje.util.thread-safe-var-nesting :only [var-root]]))
(:use midje.clojure.core))

(letfn [(republish [namespace symbols]
(require namespace)
Expand Down
5 changes: 3 additions & 2 deletions src/midje/checking/checkers/collection.clj
Expand Up @@ -2,10 +2,11 @@

(ns ^{:doc "Checkers for collections and strings."}
midje.checking.checkers.collection
(:use [clojure.set :only [union]]
(:use midje.clojure.core
[clojure.set :only [union]]
[clojure.pprint :only [cl-format]]
[midje.util.backwards-compatible-utils :only [every-pred-m]]
[midje.util.form-utils :only [regex? record? classic-map? pred-cond macro-for]]
[midje.util.form-utils :only [pred-cond macro-for]]
[midje.checking.checkers collection-util util chatty defining collection-comparison]
midje.checking.extended-equality
[midje.checking.extended-falsehood :only [extended-true?]]
Expand Down
5 changes: 3 additions & 2 deletions src/midje/checking/checkers/collection_comparison.clj
Expand Up @@ -2,8 +2,9 @@

(ns ^{:doc "Code to use to compare collections."}
midje.checking.checkers.collection-comparison
(:use [clojure.math.combinatorics :only [permutations]]
[midje.util.form-utils :only [tack-on-to rotations sort-map]]
(:use midje.clojure.core
[clojure.math.combinatorics :only [permutations]]
[midje.util.form-utils :only [tack-on-to sort-map]]
[midje.util.object-utils :only [function-name named-function?]]
[midje.checking.checkers collection-util util chatty defining]
midje.checking.extended-equality
Expand Down
2 changes: 1 addition & 1 deletion src/midje/checking/checkers/collection_util.clj
@@ -1,5 +1,5 @@
(ns midje.checking.checkers.collection-util
(:use [midje.util.form-utils :only [extended-fn? regex?]]
(:use midje.clojure.core
[midje.checking.extended-falsehood :only [as-data-laden-falsehood]]))

(defn same-lengths? [actual expected]
Expand Down
5 changes: 3 additions & 2 deletions src/midje/checking/checkers/simple.clj
Expand Up @@ -2,13 +2,14 @@

(ns ^{:doc "Prepackaged functions that perform common checks."}
midje.checking.checkers.simple
(:use [midje.checking.checkers.defining :only [as-checker checker defchecker]]
(:use midje.clojure.core
[midje.checking.checkers.defining :only [as-checker checker defchecker]]
[midje.checking.extended-falsehood :only [extended-false?]]
[midje.checking.extended-equality :only [extended-=]]
[midje.checking.checkers.util :only [named-as-call]]
[midje.error-handling.exceptions :only [captured-throwable?]]
[midje.util.ecosystem :only [clojure-1-3? +M -M *M]]
[midje.util.form-utils :only [defalias def-many-methods pred-cond regex?]]
[midje.util.form-utils :only [def-many-methods pred-cond]]
[midje.util.backwards-compatible-utils :only [every-pred-m some-fn-m]]
[clojure.algo.monads :only [domonad set-m]])
(:import [midje.error_handling.exceptions ICapturedThrowable]))
Expand Down
2 changes: 1 addition & 1 deletion src/midje/checking/checkers/util.clj
@@ -1,5 +1,5 @@
(ns midje.checking.checkers.util
(:use [midje.util.form-utils :only [classic-map?]]
(:use midje.clojure.core
[midje.util.object-utils :only [name-object]]))

(defn named-as-call
Expand Down
5 changes: 2 additions & 3 deletions src/midje/checking/examples.clj
@@ -1,12 +1,11 @@
(ns ^{:doc "Core Midje functions that process expects and report on their results."}
midje.checking.examples
(:use clojure.test
(:use midje.clojure.core
[midje.checking.extended-equality :only [extended-= evaluate-checking-function]]
[midje.error-handling.exceptions :only [captured-throwable]]
midje.data.prerequisite-state
midje.util.form-utils
midje.util.laziness
[midje.util.namespace :only [immigrate]])
midje.util.laziness)
(:require [midje.config :as config]
[midje.emission.boundaries :as emission-boundary]
[midje.parsing.1-to-explicit-form.background :as background]
Expand Down
5 changes: 3 additions & 2 deletions src/midje/checking/extended_equality.clj
@@ -1,7 +1,8 @@
(ns ^{:doc "`=` extended for regular expressions, functions, etc."}
midje.checking.extended-equality
(:use [midje.checking.extended-falsehood :only [as-data-laden-falsehood data-laden-falsehood?]]
[midje.util.form-utils :only [classic-map? extended-fn? pairs record? regex?]]))
(:use midje.clojure.core
[midje.checking.extended-falsehood :only [as-data-laden-falsehood data-laden-falsehood?]]
[midje.util.form-utils :only [pairs]]))


(defn evaluate-checking-function
Expand Down
142 changes: 142 additions & 0 deletions src/midje/clojure/core.clj
@@ -0,0 +1,142 @@
(ns ^{:doc "Functions I wouldn't mind to see in clojure.core"}
midje.clojure.core)

;;; Types and pseudo types

(defn regex? [x]
(= (class x) java.util.regex.Pattern))

(defn stringlike?
"String or regex"
[x]
(or (string? x)
(regex? x)))

(defn classic-map? [x]
(.isInstance clojure.lang.APersistentMap x))

(defn record? [x]
(and (map? x) (not (classic-map? x))))

(defn extended-fn? [x]
(or (fn? x)
(= (class x) clojure.lang.MultiFn)))

(defn named? [x]
(instance? clojure.lang.Named x))


;;; Annoyances

(defn strictly [loose-predicate]
(comp boolean loose-predicate))

(def any? (strictly some))

(def not-empty? (strictly seq))


;;; Vars

(defn var-root [var]
(alter-var-root var identity))



(defn var-name
"Get the namespace-qualified name of a var."
[v]
(apply symbol (map str ((juxt (comp ns-name :ns)
:name)
(meta v)))))


;;; Namespaces

(defn alias-var
"Create a var with the supplied name in the current namespace, having the same
metadata and root-binding as the supplied var."
[name ^clojure.lang.Var var]
(apply intern *ns*
(with-meta name (merge {:dont-test (str "Alias of " (var-name var))}
(meta var)
(meta name)))
(when (.hasRoot var) [@var])))


(defmacro defalias
"Defines an alias for a var: a new var with the same root binding (if
any) and similar metadata. The metadata of the alias is its initial
metadata (as provided by def) merged into the metadata of the original."
[dst src]
`(alias-var (quote ~dst) (var ~src)))

(letfn [(move-var [var sym]
(let [sym (with-meta sym (assoc (meta var) :ns *ns*))]
(if (.hasRoot var)
(intern *ns* sym (var-root var))
(intern *ns* sym))))]

(defn immigrate
"Create a public var in this namespace for each public var in the
namespaces named by ns-names. The created vars have the same name, root
binding, and metadata as the original except that their :ns metadata
value is this namespace."
[& ns-names]
(doseq [ns ns-names]
(require ns)
(doseq [[sym ^clojure.lang.Var var] (ns-publics ns)]
(move-var var sym))))

(defn immigrate-from
"Like `immigrate`, except wth a list of named symbols."
[ns symbols]
(doseq [sym symbols]
(move-var (ns-resolve ns sym) sym))))

;;; Maps

(defn hash-map-duplicates-ok
"Like hash-map, except duplicate keys are OK. Last one takes precedence."
[& keys-and-vals]
(if (empty? keys-and-vals)
{}
(apply assoc {} keys-and-vals)))

(defn invert
"Produce a map with values as keys.
Values are assumed unique."
[map]
(reduce (fn [so-far [key val]]
(assoc so-far val key))
{}
map))

(defn dissoc-keypath
"Like `dissoc`, but takes a sequence of keys.
There must be at least two keys."
[map keys]
(let [[path-to-end-key end-key] [(butlast keys) (last keys)]
ending-container (get-in map path-to-end-key)
without-key (dissoc ending-container end-key)]
(assoc-in map path-to-end-key without-key)))


;;; Sequences

(defn separate-by
"Like clojure.core/separate, but not lazy, returns nil for empty list."
[predicate forms]
(let [group (group-by (strictly predicate) forms)]
[ (group true) (group false) ]))

(defn rotations
"Returns a lazy seq of all rotations of a seq"
[coll]
(for [i (range 0 (count coll))]
(lazy-cat (drop i coll) (take i coll))))

(defn map-first
"Like map, but applies f to only the first element of the seq"
[f x]
(cons (f (first x)) (rest x)))
4 changes: 2 additions & 2 deletions src/midje/data/compendium.clj
Expand Up @@ -2,8 +2,8 @@
about a particular subject'. The Midje compendium contains
the currently relevant facts."}
midje.data.compendium
(:use [midje.error-handling.exceptions :only [user-error]]
[midje.util.form-utils :only [dissoc-keypath]])
(:use midje.clojure.core
[midje.error-handling.exceptions :only [user-error]])
(:require [midje.data.fact :as fact]
[midje.config :as config]))

Expand Down
3 changes: 2 additions & 1 deletion src/midje/data/prerequisite_state.clj
@@ -1,6 +1,7 @@
(ns ^{:doc "The semi-sweet representation of provided forms."}
midje.data.prerequisite-state
(:use [utilize.seq :only (separate find-first)]
(:use midje.clojure.core
[utilize.seq :only (separate find-first)]
[midje.util.object-utils :only [object-name]]
midje.util.form-utils
[midje.checking.extended-equality :only [extended-= extended-list-=]]
Expand Down
2 changes: 1 addition & 1 deletion src/midje/data/project_state.clj
@@ -1,6 +1,6 @@
(ns ^{:doc "What we know about the changing project file/namespace tree."}
midje.data.project-state
(:use [midje.util.form-utils :only [invert separate-by]]
(:use midje.clojure.core
[swiss-arrows.core :only [-<>]]
[bultitude.core :only [namespaces-in-dir namespaces-on-classpath]])
(:require [midje.emission.boundaries :as emission-boundary]
Expand Down
5 changes: 3 additions & 2 deletions src/midje/error_handling/background_validations.clj
@@ -1,12 +1,13 @@
(ns ^{:doc "Validation methods confirming the proper syntax of (against-)background macros."}
midje.error-handling.background-validations
(:use [clojure.pprint :only [cl-format]]
(:use midje.clojure.core
[clojure.pprint :only [cl-format]]
[midje.error-handling.validation-errors :only [simple-validation-error-report-form
validation-error-report-form validate when-valid]]
[midje.parsing.util.arrows :only [start-of-checking-arrow-sequence? take-arrow-sequence]]
[midje.parsing.1-to-explicit-form.background :only [seq-headed-by-setup-teardown-form?]]
[midje.parsing.1-to-explicit-form.prerequisites :only [metaconstant-prerequisite?]]
[midje.util.form-utils :only [def-many-methods named? pred-cond]]
[midje.util.form-utils :only [def-many-methods pred-cond]]
[midje.util.backwards-compatible-utils :only [some-fn-m]]))

(def #^:private possible-wrapping-targets #{:facts, :contents, :checks })
Expand Down
6 changes: 3 additions & 3 deletions src/midje/error_handling/validation_errors.clj
@@ -1,9 +1,9 @@
(ns ^{:doc "Code for identifying invalid Midje syntax. Includes control
flow macros, validation error creation, etc."}
midje.error-handling.validation-errors
(:use [clojure.algo.monads :only [defmonad domonad]]
[midje.parsing.util.file-position :only [form-position]]
[midje.util.form-utils :only [named?]])
(:use midje.clojure.core
[clojure.algo.monads :only [defmonad domonad]]
[midje.parsing.util.file-position :only [form-position]])
(:require [midje.emission.api :as emit]))


Expand Down
3 changes: 2 additions & 1 deletion src/midje/parsing/0_to_fact_form/formulas.clj
@@ -1,6 +1,7 @@
(ns ^{:doc "Midje's special blend of generative-style testing."}
midje.parsing.0-to-fact-form.formulas
(:use [midje.util.form-utils :only [first-named? named? pop-docstring pop-opts-map]]
(:use midje.clojure.core
[midje.util.form-utils :only [first-named? pop-docstring pop-opts-map]]
[midje.error-handling.validation-errors :only [simple-validation-error-report-form validate-m validate]]
[midje.parsing.1-to-explicit-form.prerequisites :only [head-of-form-providing-prerequisites?]]
[midje.parsing.util.arrows :only [leaf-expect-arrows leaves-contain-arrow?]]
Expand Down
5 changes: 3 additions & 2 deletions src/midje/parsing/1_to_explicit_form/background.clj
@@ -1,12 +1,13 @@
(ns ^{:doc "Code to be run before, after or around facts. Also,
prerequisites that pertain to a group of facts."}
midje.parsing.1-to-explicit-form.background
(:use [midje.parsing.util.arrows :only [start-of-checking-arrow-sequence? take-arrow-sequence]]
(:use midje.clojure.core
[midje.parsing.util.arrows :only [start-of-checking-arrow-sequence? take-arrow-sequence]]
[midje.parsing.1-to-explicit-form.metaconstants :only [predefine-metaconstants-from-form]]
[midje.parsing.1-to-explicit-form.prerequisites :only [metaconstant-prerequisite? prerequisite-to-fake]]
[midje.data.prerequisite-state :only [with-installed-fakes]]
[midje.parsing.util.wrapping :only [for-wrapping-target? with-wrapping-target]]
[midje.util.form-utils :only [first-named? map-first pred-cond separate-by
[midje.util.form-utils :only [first-named? pred-cond
symbol-named? translate-zipper]]
[midje.util.laziness :only [eagerly]]
[midje.util.thread-safe-var-nesting :only [namespace-values-inside-out
Expand Down
5 changes: 3 additions & 2 deletions src/midje/parsing/1_to_explicit_form/facts.clj
@@ -1,6 +1,7 @@
(ns ^{:doc "Parsing facts."}
midje.parsing.1-to-explicit-form.facts
(:use [midje.error-handling.validation-errors :only [validate when-valid]]
(:use midje.clojure.core
[midje.error-handling.validation-errors :only [validate when-valid]]
[midje.util.namespace :only [semi-sweet-keyword?]]

[midje.parsing.1-to-explicit-form.expects :only [expect?
Expand All @@ -21,7 +22,7 @@
against-background?]]
[midje.parsing.1-to-explicit-form.metaconstants :only [predefine-metaconstants-from-form]]
[midje.util.form-utils :only [def-many-methods first-named? translate-zipper
preserve-type quoted? pred-cond reader-line-number named?]]
preserve-type quoted? pred-cond reader-line-number]]
[midje.util.laziness :only [eagerly]]
[midje.parsing.util.zip :only [skip-to-rightmost-leaf]]
[swiss-arrows.core :only [-<>]])
Expand Down
29 changes: 3 additions & 26 deletions src/midje/parsing/2_to_lexical_maps/data_fakes.clj
@@ -1,32 +1,9 @@
(ns ^{:doc "=contains=> prereqisites"}
midje.parsing.2-to-lexical-maps.data-fakes
(:use [utilize.seq :only (separate find-first)]
[midje.util.object-utils :only [object-name]]
[midje.checkers :only [exactly]]
[midje.checking.checkers.defining :only [checker? checker-makers]]
[midje.parsing.1-to-explicit-form.expects :only [expect? up-to-full-expect-form]]
[midje.util.form-utils :only [first-named? translate-zipper map-difference
hash-map-duplicates-ok pred-cond
quoted-list-form? extended-fn?]]
[midje.checking.extended-equality :only [extended-= extended-list-=]]
[midje.parsing.util.file-position :only [user-file-position]]
[midje.util.thread-safe-var-nesting :only [namespace-values-inside-out
with-pushed-namespace-values
with-altered-roots]]
[midje.parsing.util.wrapping :only [with-wrapping-target]]
[midje.util.deprecation :only [deprecate]]
(:use midje.clojure.core
midje.error-handling.validation-errors
midje.error-handling.semi-sweet-validations
[midje.parsing.arrow-symbols]
[clojure.tools.macro :only [macrolet]])
(:require [midje.data.metaconstant :as metaconstant]
[clojure.zip :as zip]
[midje.config :as config]
[midje.parsing.util.fnref :as fnref]
[midje.error-handling.exceptions :as exceptions]
[midje.parsing.lexical-maps :as lexical-maps]
[midje.emission.api :as emit])
(:import midje.data.metaconstant.Metaconstant))
midje.error-handling.semi-sweet-validations)
(:require [midje.parsing.lexical-maps :as lexical-maps]))


(defn to-lexical-map-form [a-list]
Expand Down
9 changes: 5 additions & 4 deletions src/midje/parsing/2_to_lexical_maps/examples.clj
@@ -1,14 +1,15 @@
(ns ^{:doc "generate a map for a particular example"}
midje.parsing.2-to-lexical-maps.examples
(:use [utilize.seq :only (separate find-first)]
(:use midje.clojure.core
[utilize.seq :only (separate find-first)]
[midje.util.object-utils :only [object-name]]
[midje.checkers :only [exactly]]
[midje.checking.checkers.defining :only [checker? checker-makers]]
[midje.parsing.1-to-explicit-form.expects :only [expect? up-to-full-expect-form]]
[midje.util.form-utils :only [first-named? translate-zipper map-difference
hash-map-duplicates-ok pred-cond
quoted-list-form? extended-fn?
def-many-methods separate-by]]
pred-cond
quoted-list-form?
def-many-methods ]]
[midje.checking.extended-equality :only [extended-= extended-list-=]]
[midje.parsing.util.file-position :only [user-file-position]]
[midje.util.namespace :only [semi-sweet-keyword?]]
Expand Down

0 comments on commit 1def023

Please sign in to comment.