Permalink
Browse files

Changed to match only against request maps

  • Loading branch information...
1 parent 7567c31 commit 66a730e6af7de3a252bd014bad55438cec48ba54 @weavejester weavejester committed Nov 30, 2010
Showing with 69 additions and 74 deletions.
  1. +42 −54 src/clout/core.clj
  2. +27 −20 test/clout/test/core.clj
View
@@ -23,48 +23,13 @@
(for [i (range (.groupCount matcher))]
(.group matcher (inc i))))
-;; Lexer functions
-
-(defn- lex-1
- "Lex one symbol from a string, and return the symbol and trailing source."
- [src clauses]
- (some
- (fn [[re action]]
- (let [matcher (re-matcher re src)]
- (if (.lookingAt matcher)
- [(if (fn? action) (action matcher) action)
- (.substring src (.end matcher))])))
- (partition 2 clauses)))
-
-(defn- lex
- "Lex a string into tokens by matching against regexs and evaluating
- the matching associated function."
- [src & clauses]
- (loop [results []
- src src
- clauses clauses]
- (if-let [[result src] (lex-1 src clauses)]
- (let [results (conj results result)]
- (if (= src "")
- results
- (recur results src clauses))))))
-
;; Route matching
(defn- urldecode
"Encode a urlencoded string using the default encoding."
[string]
(URLDecoder/decode string))
-(defn request-url
- "Return the complete URL for the request."
- [request]
- (str
- (name (:scheme request))
- "://"
- (get-in request [:headers "host"])
- (:uri request)))
-
(defn- assoc-vec
"Associate a key with a value. If the key already exists in the map, create a
vector of values."
@@ -85,28 +50,24 @@
{}
(map vector keys groups)))
-(defprotocol Request
- (uri [request absolute?]
- "Return the URI of the request. If absolute? is true, the URI returned
- will be an absolte URL."))
-
-(extend-protocol Request
- nil
- (uri [_ _] (uri "/" false))
- String
- (uri [path _] path)
- Map
- (uri [request absolute?]
- (if absolute?
- (request-url request)
- (:uri request))))
+(defn- request-url
+ "Return the complete URL for the request."
+ [request]
+ (str (name (:scheme request))
+ "://"
+ (get-in request [:headers "host"])
+ (:uri request)))
+
+(defn- path-info
+ "Return the path info for the request."
+ [request]
+ (or (:path-info request)
+ (:uri request)))
(defprotocol Route
(route-matches [route request]
"If the route matches the supplied request, the matched keywords are
- returned as a map. Otherwise, nil is returned.
- e.g. (route-matches \"/product/:id\" \"/product/10\")
- -> {:id 10}"))
+ returned as a map. Otherwise, nil is returned."))
(declare route-compile)
@@ -118,14 +79,41 @@
(defrecord CompiledRoute [re keys absolute?]
Route
(route-matches [route request]
- (let [matcher (re-matcher re (uri request absolute?))]
+ (let [path-info (if absolute?
+ (request-url request)
+ (path-info request))
+ matcher (re-matcher re path-info)]
(if (.matches matcher)
(assoc-keys-with-groups
(map urldecode (re-groups* matcher))
keys)))))
;; Compile routes
+(defn- lex-1
+ "Lex one symbol from a string, and return the symbol and trailing source."
+ [src clauses]
+ (some
+ (fn [[re action]]
+ (let [matcher (re-matcher re src)]
+ (if (.lookingAt matcher)
+ [(if (fn? action) (action matcher) action)
+ (.substring src (.end matcher))])))
+ (partition 2 clauses)))
+
+(defn- lex
+ "Lex a string into tokens by matching against regexs and evaluating
+ the matching associated function."
+ [src & clauses]
+ (loop [results []
+ src src
+ clauses clauses]
+ (if-let [[result src] (lex-1 src clauses)]
+ (let [results (conj results result)]
+ (if (= src "")
+ results
+ (recur results src clauses))))))
+
(defn- absolute-url?
"True if the path contains an absolute URL."
[path]
View
@@ -3,49 +3,46 @@
clout.core))
(deftest fixed-path
- (are [path] (route-matches path path)
+ (are [path] (route-matches path {:uri path})
"/"
"/foo"
"/foo/bar"
"/foo/bar.html"))
-(deftest nil-paths
- (is (route-matches "/" nil)))
-
(deftest keyword-paths
- (are [path uri params] (= (route-matches path uri) params)
+ (are [path uri params] (= (route-matches path {:uri uri}) params)
"/:x" "/foo" {:x "foo"}
"/foo/:x" "/foo/bar" {:x "bar"}
"/a/b/:c" "/a/b/c" {:c "c"}
"/:a/b/:c" "/a/b/c" {:a "a", :c "c"}))
(deftest keywords-match-extensions
- (are [path uri params] (= (route-matches path uri) params)
+ (are [path uri params] (= (route-matches path {:uri uri}) params)
"/foo.:ext" "/foo.txt" {:ext "txt"}
"/:x.:y" "/foo.txt" {:x "foo", :y "txt"}))
(deftest hyphen-keywords
- (are [path uri params] (= (route-matches path uri) params)
+ (are [path uri params] (= (route-matches path {:uri uri}) params)
"/:foo-bar" "/baz" {:foo-bar "baz"}
"/:foo-" "/baz" {:foo- "baz"}))
(deftest underscore-keywords
- (are [path uri params] (= (route-matches path uri) params)
+ (are [path uri params] (= (route-matches path {:uri uri}) params)
"/:foo_bar" "/baz" {:foo_bar "baz"}
"/:_foo" "/baz" {:_foo "baz"}))
(deftest urlencoded-keywords
- (are [path uri params] (= (route-matches path uri) params)
+ (are [path uri params] (= (route-matches path {:uri uri}) params)
"/:x" "/foo%20bar" {:x "foo bar"}
"/:x" "/foo+bar" {:x "foo bar"}))
(deftest same-keyword-many-times
- (are [path uri params] (= (route-matches path uri) params)
+ (are [path uri params] (= (route-matches path {:uri uri}) params)
"/:x/:x/:x" "/a/b/c" {:x ["a" "b" "c"]}
"/:x/b/:x" "/a/b/c" {:x ["a" "c"]}))
(deftest non-ascii-keywords
- (are [path uri params] (= (route-matches path uri) params)
+ (are [path uri params] (= (route-matches path {:uri uri}) params)
"/:äñßOÔ" "/abc" {:äñßOÔ "abc"}
"/:ÁäñßOÔ" "/abc" {:ÁäñßOÔ "abc"}
"/:ä/:ش" "/foo/bar" {:ä "foo""bar"}
@@ -54,29 +51,39 @@
"/:Ä_ü" "/baz" {:Ä_ü "baz"}))
(deftest wildcard-paths
- (are [path uri params] (= (route-matches path uri) params)
+ (are [path uri params] (= (route-matches path {:uri uri}) params)
"/*" "/foo" {:* "foo"}
"/*" "/foo.txt" {:* "foo.txt"}
"/*" "/foo/bar" {:* "foo/bar"}
"/foo/*" "/foo/bar/baz" {:* "bar/baz"}
"/a/*/d" "/a/b/c/d" {:* "b/c"}))
(deftest compiled-routes
- (is (= (route-matches (route-compile "/foo/:id") "/foo/bar")
+ (is (= (route-matches (route-compile "/foo/:id") {:uri "/foo/bar"})
{:id "bar"})))
(deftest url-paths
- (is (route-matches "http://localhost" "http://localhost")))
+ (is (route-matches
+ "http://localhost/"
+ {:scheme :http
+ :headers {"host" "localhost"}
+ :uri "/"})))
(deftest url-port-paths
- (is (route-matches "localhost:8080" "localhost:8080"))
- (is (not (route-matches "localhost:8080" "localhost:7070"))))
+ (let [request {:scheme :http
+ :headers {"host" "localhost:8080"}
+ :uri "/"}]
+ (is (route-matches "http://localhost:8080/" request))
+ (is (not (route-matches "http://localhost:7070/" request)))))
(deftest unmatched-paths
- (is (nil? (route-matches "/foo" "/bar"))))
+ (is (nil? (route-matches "/foo" {:uri "/bar"}))))
+
+(deftest path-info-matches
+ (is (route-matches "/bar" {:uri "/foo", :path-info "/bar"})))
(deftest custom-matches
(let [route (route-compile "/foo/:bar" {:bar #"\d+"})]
- (is (not (route-matches route "/foo/bar")))
- (is (not (route-matches route "/foo/1x")))
- (is (route-matches route "/foo/10"))))
+ (is (not (route-matches route {:uri "/foo/bar"})))
+ (is (not (route-matches route {:uri "/foo/1x"})))
+ (is (route-matches route {:uri "/foo/10"}))))

0 comments on commit 66a730e

Please sign in to comment.