emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/dash ec27b47 025/426: Turn tests into examples that can


From: Phillip Lord
Subject: [elpa] externals/dash ec27b47 025/426: Turn tests into examples that can both be tested and turned into docs
Date: Tue, 04 Aug 2015 19:36:28 +0000

branch: externals/dash
commit ec27b4764845777ac7b18390e18a3fa3fbd0e2f5
Author: Magnar Sveen <address@hidden>
Commit: Magnar Sveen <address@hidden>

    Turn tests into examples that can both be tested and turned into docs
---
 bang.el              |   61 +++++++++++----------
 create-docs.sh       |    7 +++
 docs.md              |  144 ++++++++++++++++++++++++++++++++++++++++++++++++++
 examples-to-docs.el  |   31 +++++++++++
 examples-to-tests.el |   19 +++++++
 examples.el          |   69 ++++++++++++++++++++++++
 run-tests.sh         |    2 +-
 tests.el             |   94 --------------------------------
 8 files changed, 303 insertions(+), 124 deletions(-)

diff --git a/bang.el b/bang.el
index 1094f4e..91c9f87 100644
--- a/bang.el
+++ b/bang.el
@@ -27,7 +27,12 @@
 
 (defalias '!map 'mapcar)
 
+(defun !map (fn list)
+  "Returns a new list consisting of the result of applying FN to the items in 
list."
+  (mapcar fn list))
+
 (defmacro !!map (form list)
+  "Anaphoric form of `!map'."
   `(!map (lambda (it) ,form) ,list))
 
 (defun !reduce-from (fn initial-value list)
@@ -36,16 +41,13 @@ first item in LIST, then applying FN to that result and the 
2nd
 item, etc. If LIST contains no items, returns INITIAL-VALUE and
 FN is not called."
   (let ((acc initial-value))
-     (while list
-       (setq acc (funcall fn acc (car list)))
-       (setq list (cdr list)))
-     acc))
+    (while list
+      (setq acc (funcall fn acc (car list)))
+      (setq list (cdr list)))
+    acc))
 
 (defmacro !!reduce-from (form initial-value list)
-  "Anaphoric form of `!reduce'. Returns the result of applying
-FORM to INITIAL-VALUE and the first item in LIST, then applying
-FORM to that result and the 2nd item, etc. If INITIAL-VALUE
-contains no items, returns INITIAL-VALUE and FORM is not called."
+  "Anaphoric form of `!reduce-from'."
   `(let ((!--list ,list)
          (!--acc ,initial-value))
      (while !--list
@@ -66,12 +68,7 @@ LIST has only 1 item, it is returned and FN is not called."
     (funcall fn)))
 
 (defmacro !!reduce (form list)
-  "Returns the result of applying FORM to the first 2 items in LIST,
-then applying FORM to that result and the 3rd item, etc. If
-LIST contains no items, FORM must accept no arguments as
-well, and reduce returns the result of calling FORM with no
-arguments. If LIST has only 1 item, it is returned and FORM
-is not called."
+  "Anaphoric form of `!reduce'."
   (if (eval list)
       `(!!reduce-from ,form ,(car (eval list)) ',(cdr (eval list)))
     `(let (acc it) ,form)))
@@ -86,7 +83,7 @@ is not called."
     (nreverse result)))
 
 (defmacro !!filter (form list)
-  "Returns a new list of the items in LIST for which FORM returns a non-nil 
value."
+  "Anaphoric form of `!filter'."
   `(let ((!--list ,list)
          (!--result '()))
      (while !--list
@@ -101,7 +98,7 @@ is not called."
   (!!filter (not (funcall fn it)) list))
 
 (defmacro !!remove (form list)
-  "Returns a new list of the items in LIST for which FORM returns nil."
+  "Anaphoric form of `!remove'."
   `(!!filter (not ,form) ,list))
 
 (defun !concat (&rest lists)
@@ -115,11 +112,15 @@ Thus function FN should return a collection."
   (apply '!concat (!map fn list)))
 
 (defmacro !!mapcat (form list)
-  "Returns the result of applying concat to the result of applying map to FORM 
and LIST.
-Thus function FORM should return a collection."
+  "Anaphoric form of `!mapcat'."
   `(apply '!concat (!!map ,form ,list)))
 
-(defalias '!partial 'apply-partially)
+(defun !partial (fn &rest args)
+  "Takes a function FN and fewer than the normal arguments to FN,
+and returns a fn that takes a variable number of additional ARGS.
+When called, the returned function calls FN with args +
+additional args."
+  (apply 'apply-partially fn args))
 
 (defun !uniq (list)
   "Return a new list with all duplicates removed.
@@ -143,16 +144,18 @@ or with `!compare-fn' if that's non-nil."
   "Return whether LIST contains ELEMENT.
 The test for equality is done with `equal',
 or with `!compare-fn' if that's non-nil."
-  (cond
-   ((null !compare-fn)    (member element list))
-   ((eq !compare-fn 'eq)  (memq element list))
-   ((eq !compare-fn 'eql) (memql element list))
-   (t
-    (let ((lst list))
-      (while (and lst
-                  (not (funcall !compare-fn element (car lst))))
-        (setq lst (cdr lst)))
-      lst))))
+  (not
+   (null
+    (cond
+     ((null !compare-fn)    (member element list))
+     ((eq !compare-fn 'eq)  (memq element list))
+     ((eq !compare-fn 'eql) (memql element list))
+     (t
+      (let ((lst list))
+        (while (and lst
+                    (not (funcall !compare-fn element (car lst))))
+          (setq lst (cdr lst)))
+        lst))))))
 
 (defvar !compare-fn nil
   "Tests for equality use this function or `equal' if this is nil.
diff --git a/create-docs.sh b/create-docs.sh
new file mode 100755
index 0000000..462a312
--- /dev/null
+++ b/create-docs.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+
+if [ -z "$EMACS" ] ; then
+    EMACS="emacs"
+fi
+
+$EMACS -batch -l examples-to-docs.el -l bang.el -l examples.el -f 
create-docs-file
diff --git a/docs.md b/docs.md
new file mode 100644
index 0000000..47cd06a
--- /dev/null
+++ b/docs.md
@@ -0,0 +1,144 @@
+## !map `(fn list)`
+
+Returns a new list consisting of the result of applying FN to the items in 
list.
+
+```cl
+(!map (lambda (num) (* num num)) (quote (1 2 3 4))) ;; => (quote (1 4 9 16))
+(!map (quote square) (quote (1 2 3 4))) ;; => (quote (1 4 9 16))
+(!!map (* it it) (quote (1 2 3 4))) ;; => (quote (1 4 9 16))
+```
+
+## !reduce-from `(fn initial-value list)`
+
+Returns the result of applying FN to INITIAL-VALUE and the
+first item in LIST, then applying FN to that result and the 2nd
+item, etc. If LIST contains no items, returns INITIAL-VALUE and
+FN is not called.
+
+```cl
+(!reduce-from (quote +) 7 (quote nil)) ;; => 7
+(!reduce-from (quote +) 7 (quote (1))) ;; => 8
+(!reduce-from (quote +) 7 (quote (1 2))) ;; => 10
+(!!reduce-from (+ acc it) 7 (quote (1 2 3))) ;; => 13
+```
+
+## !reduce `(fn list)`
+
+Returns the result of applying FN to the first 2 items in LIST,
+then applying FN to that result and the 3rd item, etc. If LIST
+contains no items, FN must accept no arguments as well, and
+reduce returns the result of calling FN with no arguments. If
+LIST has only 1 item, it is returned and FN is not called.
+
+```cl
+(!reduce (quote +) (quote nil)) ;; => 0
+(!reduce (quote +) (quote (1))) ;; => 1
+(!reduce (quote +) (quote (1 2))) ;; => 3
+(!reduce (lambda (memo item) (format %s-%s memo item)) (quote (1 2 3))) ;; => 
1-2-3
+(!!reduce (format %s-%s acc it) (quote (1 2 3))) ;; => 1-2-3
+(!!reduce (format %s-%s acc it) (quote nil)) ;; => nil-nil
+```
+
+## !filter `(fn list)`
+
+Returns a new list of the items in LIST for which FN returns a non-nil value.
+
+```cl
+(!filter (lambda (num) (= 0 (% num 2))) (quote (1 2 3 4))) ;; => (quote (2 4))
+(!filter (quote even?) (quote (1 2 3 4))) ;; => (quote (2 4))
+(!!filter (= 0 (% it 2)) (quote (1 2 3 4))) ;; => (quote (2 4))
+```
+
+## !remove `(fn list)`
+
+Returns a new list of the items in LIST for which FN returns nil.
+
+```cl
+(!remove (lambda (num) (= 0 (% num 2))) (quote (1 2 3 4))) ;; => (quote (1 3))
+(!remove (quote even?) (quote (1 2 3 4))) ;; => (quote (1 3))
+(!!remove (= 0 (% it 2)) (quote (1 2 3 4))) ;; => (quote (1 3))
+```
+
+## !concat `(&rest lists)`
+
+Returns a new list with the concatenation of the elements in
+the supplied LISTS.
+
+```cl
+(!concat) ;; => nil
+(!concat (quote (1))) ;; => (quote (1))
+(!concat (quote (1)) (quote (2))) ;; => (quote (1 2))
+(!concat (quote (1)) (quote (2 3)) (quote (4))) ;; => (quote (1 2 3 4))
+```
+
+## !mapcat `(fn list)`
+
+Returns the result of applying concat to the result of applying map to FN and 
LIST.
+Thus function FN should return a collection.
+
+```cl
+(!mapcat (quote list) (quote (1 2 3))) ;; => (quote (1 2 3))
+(!mapcat (lambda (item) (list 0 item)) (quote (1 2 3))) ;; => (quote (0 1 0 2 
0 3))
+(!!mapcat (list 0 it) (quote (1 2 3))) ;; => (quote (0 1 0 2 0 3))
+```
+
+## !partial `(fn &rest args)`
+
+Takes a function FN and fewer than the normal arguments to FN,
+and returns a fn that takes a variable number of additional ARGS.
+When called, the returned function calls FN with args +
+additional args.
+
+```cl
+(funcall (!partial (quote +) 5) 3) ;; => 8
+(funcall (!partial (quote +) 5 2) 3) ;; => 10
+```
+
+## !difference `(list list2)`
+
+Return a new list with only the members of LIST that are not in LIST2.
+The test for equality is done with `equal',
+or with `!compare-fn' if that's non-nil.
+
+```cl
+(!difference (quote nil) (quote nil)) ;; => (quote nil)
+(!difference (quote (1 2 3)) (quote (4 5 6))) ;; => (quote (1 2 3))
+(!difference (quote (1 2 3 4)) (quote (3 4 5 6))) ;; => (quote (1 2))
+```
+
+## !intersection `(list list2)`
+
+Return a new list containing only the elements that are members of both LIST 
and LIST2.
+The test for equality is done with `equal',
+or with `!compare-fn' if that's non-nil.
+
+```cl
+(!intersection (quote nil) (quote nil)) ;; => (quote nil)
+(!intersection (quote (1 2 3)) (quote (4 5 6))) ;; => (quote nil)
+(!intersection (quote (1 2 3 4)) (quote (3 4 5 6))) ;; => (quote (3 4))
+```
+
+## !uniq `(list)`
+
+Return a new list with all duplicates removed.
+The test for equality is done with `equal',
+or with `!compare-fn' if that's non-nil.
+
+```cl
+(!uniq (quote nil)) ;; => (quote nil)
+(!uniq (quote (1 2 2 4))) ;; => (quote (1 2 4))
+```
+
+## !contains? `(list element)`
+
+Return whether LIST contains ELEMENT.
+The test for equality is done with `equal',
+or with `!compare-fn' if that's non-nil.
+
+```cl
+(!contains? (quote (1 2 3)) 1) ;; => t
+(!contains? (quote (1 2 3)) 2) ;; => t
+(!contains? (quote nil) (quote nil)) ;; => nil
+(!contains? (quote nil) 1) ;; => nil
+(!contains? (quote (1 2 4)) 3) ;; => nil
+```
diff --git a/examples-to-docs.el b/examples-to-docs.el
new file mode 100644
index 0000000..4aa2b65
--- /dev/null
+++ b/examples-to-docs.el
@@ -0,0 +1,31 @@
+(defvar functions '())
+
+(defun example-to-string (example)
+  (let ((actual (car example))
+        (expected (cadr (cdr example))))
+    (format "%s ;; => %s" actual expected)))
+
+(defun examples-to-strings (examples)
+  (let (result)
+    (while examples
+      (setq result (cons (example-to-string examples) result))
+      (setq examples (cddr (cdr examples))))
+    (nreverse result)))
+
+(defmacro defexamples (cmd &rest examples)
+  `(add-to-list 'functions (list
+    ',cmd ;; command name
+    (cadr (symbol-function ',cmd)) ;; signature
+    (car (cddr (symbol-function ',cmd))) ;; docstring
+    (examples-to-strings ',examples)))) ;; examples
+
+(defun function-to-md (function)
+  (let ((command-name (car function))
+        (signature (cadr function))
+        (docstring (cadr (cdr function)))
+        (examples (mapconcat 'identity (cadr (cddr function)) "\n")))
+    (format "## %s `%s`\n\n%s\n\n```cl\n%s\n```\n" command-name signature 
docstring examples)))
+
+(defun create-docs-file ()
+  (with-temp-file "./docs.md"
+    (insert (mapconcat 'function-to-md (nreverse functions) "\n"))))
diff --git a/examples-to-tests.el b/examples-to-tests.el
new file mode 100644
index 0000000..080a65f
--- /dev/null
+++ b/examples-to-tests.el
@@ -0,0 +1,19 @@
+(require 'ert)
+
+(defun examples-to-should-1 (examples)
+  (let ((actual (car examples))
+        (expected (cadr (cdr examples))))
+    `(should (equal ,actual ,expected))))
+
+(defun examples-to-should (examples)
+  (let (result)
+    (while examples
+      (setq result (cons (examples-to-should-1 examples) result))
+      (setq examples (cddr (cdr examples))))
+    (nreverse result)))
+
+(defmacro defexamples (cmd &rest examples)
+  `(ert-deftest ,cmd ()
+     ,@(examples-to-should examples)))
+
+(provide 'examples-to-tests)
diff --git a/examples.el b/examples.el
new file mode 100644
index 0000000..aba8781
--- /dev/null
+++ b/examples.el
@@ -0,0 +1,69 @@
+(require 'bang)
+
+(defun even? (num) (= 0 (% num 2)))
+(defun square (num) (* num num))
+
+(defexamples !map
+  (!map (lambda (num) (* num num)) '(1 2 3 4)) => '(1 4 9 16)
+  (!map 'square '(1 2 3 4)) => '(1 4 9 16)
+  (!!map (* it it) '(1 2 3 4)) => '(1 4 9 16))
+
+(defexamples !reduce-from
+  (!reduce-from '+ 7 '()) => 7
+  (!reduce-from '+ 7 '(1)) => 8
+  (!reduce-from '+ 7 '(1 2)) => 10
+  (!!reduce-from (+ acc it) 7 '(1 2 3)) => 13)
+
+(defexamples !reduce
+  (!reduce '+ '()) => 0
+  (!reduce '+ '(1)) => 1
+  (!reduce '+ '(1 2)) => 3
+  (!reduce (lambda (memo item) (format "%s-%s" memo item)) '(1 2 3)) => "1-2-3"
+  (!!reduce (format "%s-%s" acc it) '(1 2 3)) => "1-2-3"
+  (!!reduce (format "%s-%s" acc it) '()) => "nil-nil")
+
+(defexamples !filter
+  (!filter (lambda (num) (= 0 (% num 2))) '(1 2 3 4)) => '(2 4)
+  (!filter 'even? '(1 2 3 4)) => '(2 4)
+  (!!filter (= 0 (% it 2)) '(1 2 3 4)) => '(2 4))
+
+(defexamples !remove
+  (!remove (lambda (num) (= 0 (% num 2))) '(1 2 3 4)) => '(1 3)
+  (!remove 'even? '(1 2 3 4)) => '(1 3)
+  (!!remove (= 0 (% it 2)) '(1 2 3 4)) => '(1 3))
+
+(defexamples !concat
+  (!concat) => nil
+  (!concat '(1)) => '(1)
+  (!concat '(1) '(2)) => '(1 2)
+  (!concat '(1) '(2 3) '(4)) => '(1 2 3 4))
+
+(defexamples !mapcat
+  (!mapcat 'list '(1 2 3)) => '(1 2 3)
+  (!mapcat (lambda (item) (list 0 item)) '(1 2 3)) => '(0 1 0 2 0 3)
+  (!!mapcat (list 0 it) '(1 2 3)) => '(0 1 0 2 0 3))
+
+(defexamples !partial
+  (funcall (!partial '+ 5) 3) => 8
+  (funcall (!partial '+ 5 2) 3) => 10)
+
+(defexamples !difference
+  (!difference '() '()) => '()
+  (!difference '(1 2 3) '(4 5 6)) => '(1 2 3)
+  (!difference '(1 2 3 4) '(3 4 5 6)) => '(1 2))
+
+(defexamples !intersection
+  (!intersection '() '()) => '()
+  (!intersection '(1 2 3) '(4 5 6)) => '()
+  (!intersection '(1 2 3 4) '(3 4 5 6)) => '(3 4))
+
+(defexamples !uniq
+  (!uniq '()) => '()
+  (!uniq '(1 2 2 4)) => '(1 2 4))
+
+(defexamples !contains?
+  (!contains? '(1 2 3) 1) => t
+  (!contains? '(1 2 3) 2) => t
+  (!contains? '() '()) => nil
+  (!contains? '() 1) => nil
+  (!contains? '(1 2 4) 3) => nil)
diff --git a/run-tests.sh b/run-tests.sh
index 32cda47..5043480 100755
--- a/run-tests.sh
+++ b/run-tests.sh
@@ -4,4 +4,4 @@ if [ -z "$EMACS" ] ; then
     EMACS="emacs"
 fi
 
-$EMACS -batch -l ert.el -l bang.el -l tests.el -f ert-run-tests-batch-and-exit
+$EMACS -batch -l ert.el -l examples-to-tests.el -l bang.el -l examples.el -f 
ert-run-tests-batch-and-exit
diff --git a/tests.el b/tests.el
deleted file mode 100644
index a197849..0000000
--- a/tests.el
+++ /dev/null
@@ -1,94 +0,0 @@
-(require 'ert)
-(require 'bang)
-
-(defun even? (num) (= 0 (% num 2)))
-(defun square (num) (* num num))
-
-(ert-deftest map ()
-  "`!map' returns a new list with the results of calling the function on each 
element."
-  (should (equal (!map (lambda (num) (* num num)) '(1 2 3 4)) '(1 4 9 16)))
-  (should (equal (!map 'square '(1 2 3 4)) '(1 4 9 16)))
-  (should (equal (!!map (* it it) '(1 2 3 4)) '(1 4 9 16)))
-  )
-
-(ert-deftest reduce-from ()
-  "`!reduce-from' takes a list and an initial value, and applies the function 
over them to create one result"
-  (should (equal (!reduce '+ '()) 0))
-  (should (equal (!reduce '+ '(1)) 1))
-  (should (equal (!reduce '+ '(1 2)) 3))
-  (should (equal (!reduce-from '+ 7 '()) 7))
-  (should (equal (!reduce-from '+ 7 '(1)) 8))
-  (should (equal (!reduce-from '+ 7 '(1 2)) 10))
-  (should (equal (!!reduce-from (+ acc it) 7 '(1 2 3)) 13))
-  )
-
-(ert-deftest reduce ()
-  "`!reduce' takes a list and applies the function over the elements to create 
one result"
-  (should (equal (!reduce (lambda (memo item) (format "%s-%s" memo item)) '(1 
2 3)) "1-2-3"))
-  (should (equal (!!reduce (format "%s-%s" acc it) '(1 2 3)) "1-2-3"))
-  (should (equal (!!reduce (format "%s-%s" acc it) '()) "nil-nil"))
-  )
-
-(ert-deftest filter ()
-  "`!filter' returns a new list of only those elements where the predicate was 
non-nil."
-  (should (equal (!filter (lambda (num) (= 0 (% num 2))) '(1 2 3 4)) '(2 4)))
-  (should (equal (!filter 'even? '(1 2 3 4)) '(2 4)))
-  (should (equal (!!filter (= 0 (% it 2)) '(1 2 3 4)) '(2 4)))
-  )
-
-(ert-deftest remove ()
-  "`!remove' returns a new list of only those elements where the predicate was 
nil."
-  (should (equal (!remove (lambda (num) (= 0 (% num 2))) '(1 2 3 4)) '(1 3)))
-  (should (equal (!remove 'even? '(1 2 3 4)) '(1 3)))
-  (should (equal (!!remove (= 0 (% it 2)) '(1 2 3 4)) '(1 3)))
-  )
-
-(ert-deftest concat ()
-  "`!concat' returns the concatenation of the elements in the supplied lists"
-  (should (equal (!concat) nil))
-  (should (equal (!concat '(1)) '(1)))
-  (should (equal (!concat '(1) '(2)) '(1 2)))
-  (should (equal (!concat '(1) '(2 3) '(4)) '(1 2 3 4)))
-  )
-
-(ert-deftest mapcat ()
-  "`!mapcat' applies the function to all elements of the list and then 
concatenates the result"
-  (should (equal (!mapcat 'list '(1 2 3)) '(1 2 3)))
-  (should (equal (!mapcat (lambda (item) (list 0 item)) '(1 2 3)) '(0 1 0 2 0 
3)))
-  (should (equal (!!mapcat (list 0 it) '(1 2 3)) '(0 1 0 2 0 3)))
-  )
-
-(ert-deftest partial ()
-  "`!partial' returns a function like fn where the first arguments are filled 
in"
-  (should (equal (funcall (!partial '+ 5) 3) 8))
-  (should (equal (funcall (!partial '+ 5 2) 3) 10))
-  )
-
-(ert-deftest difference ()
-  "`!difference' returns a new list of only elements in list1 that are not in 
list2."
-  (should (equal (!difference '() '()) '()))
-  (should (equal (!difference '(1 2 3) '(4 5 6)) '(1 2 3)))
-  (should (equal (!difference '(1 2 3 4) '(3 4 5 6)) '(1 2)))
-  )
-
-(ert-deftest intersection ()
-  "`!intersection' returns a new list of only elements that are in both given 
lists."
-  (should (equal (!intersection '() '()) '()))
-  (should (equal (!intersection '(1 2 3) '(4 5 6)) '()))
-  (should (equal (!intersection '(1 2 3 4) '(3 4 5 6)) '(3 4)))
-  )
-
-(ert-deftest uniq ()
-  "`!uniq' returns a new list of only unique elements."
-  (should (equal (!uniq '()) '()))
-  (should (equal (!uniq '(1 2 2 4)) '(1 2 4)))
-  )
-
-(ert-deftest contains? ()
-  "`!contains?' returns t if the list contains the element."
-  (should (!contains? '(1 2 3) 1))
-  (should (!contains? '(1 2 3) 2))
-  (should (not (!contains? '() '())))
-  (should (not (!contains? '() 1)))
-  (should (not (!contains? '(1 2 4) 3)))
-  )



reply via email to

[Prev in Thread] Current Thread [Next in Thread]