├── .gitignore ├── .travis.yml ├── LICENSE ├── README.rst ├── hytest ├── hytest.hy ├── requirements.txt ├── setup.py ├── test_hytest.hy └── travis.sh /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | dist 3 | HyTest.egg-info 4 | venv 5 | # It's a little personal script I use for testing 6 | test.hy 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: python 3 | python: 4 | - "2.7" 5 | - "3.2" 6 | - "3.3" 7 | - "3.4" 8 | - "pypy" 9 | script: "./travis.sh" 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Ryan Gonzalez 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | HyTest 2 | ====== 3 | 4 | .. image:: https://travis-ci.org/kirbyfan64/hytest.png 5 | :target: https://travis-ci.org/kirbyfan64/hytest 6 | 7 | HyTest is a really cool unit testing framework for `Hy `_ (think Python+Lisp). Actually, as far as I know, it's the *only* unit testing framework for Hy. Here's an example: 8 | 9 | .. code:: clojure 10 | 11 | (require hytest [*]) ; load HyTest 12 | 13 | (test-set abc ; define a test set, similar to a unittest test case 14 | (test-setup ; test setup 15 | (def x 0) 16 | (def y 1) 17 | (def z nil)) 18 | (test-teardown ; test teardown; executed regardless of whether or not test failed 19 | ; nothing to see here! 20 | ) 21 | (test = 1 1) ; test for equality 22 | (test == 1 1) ; same as = 23 | (test eq 1 1) ; again, same as = 24 | (test != 1 0) ; test for inequality 25 | (test ne 1 0) ; same as != 26 | (test < 0 1) ; test for less-than 27 | (test lt 0 1) ; same as < 28 | (test > 1 0) ; test for greater-than 29 | (test gt 1 0) ; same as > 30 | (test >= 1 1) ; greater-than-or-equal-to 31 | (test gte 1 1) ; same as >= 32 | (test <= 1 1) ; less-than-or-equal-to 33 | (test lte 1 1) ; same as <= 34 | (test is x x) ; test for identity; sort of like assert x is x 35 | (test is-not x y) ; test for identity inequality; sort of like assert x is not y 36 | (test is-nil z) ; test to see if equal-to None/nil 37 | (test is-not-nil x) ; opposite of is-nil 38 | (test is-none z) ; same as is-nil 39 | (test is-not-none x) ; same as is-not-nil 40 | (test ~ 0 0.00000001) ; test for almost equal(like unittest's assertAlmostEqual) 41 | (test aeq 0 0.00000001) ; same as ~ 42 | (test !~ 0 1) ; test for not almost equal(like unittest's assertNotAlmostEqual) 43 | (test ane 0 1); same as !~ 44 | (test =~ "abc" "b") ; test to see if "abc" matches regex "b" 45 | (test re "abc" "b") ; same as =~ 46 | (test !=~ "abc" "d") ; opposite of =~ 47 | (test not-re "abc" "d") ; same as !=~ 48 | (test =: [1 2 3] [3 1 2]) ; test to see if both items are equal when sorted 49 | (test ieq [1 2 3] [3 1 2]) ; same as =: 50 | (test !=: [1 2 3] [3 1]) ; opposite of =: 51 | (test ine [1 2 3] [3 1]) ; same as !=: 52 | (test true 1) ; test to see if 1 is truthy(so that (bool 1) is true) 53 | (test True 1) ; same as true 54 | (test false 0) ; test to see if 0 is falsy(so that (bool 0) is false) 55 | (test False 0) ; same as false 56 | (test not 0) ; same as false 57 | (test in 1 [1 2 3]) ; test for membership 58 | (test not-in 1 [2 3]) ; opposite of in 59 | (test raises (assert false)) ; test that the code that follows raises an exception 60 | (test not-raises (assert true)) ; opposite of raises 61 | (test raises-exc [AssertionError] (assert false)) ; test that the code that follows raises one of the exceptions in the list 62 | (test not-raises-exc [AssertionError] (assert true)) ; test that one of the given exceptions is NOT raised by the code that follows 63 | (test raises-msg "abc" (raise (ValueError "abc"))) ; test that the code that follows raises an exception whose message matches the regex "abc" 64 | (test not-raises-msg "abc" (raise (ValueError "ab")))) ; opposite of raises-msg 65 | 66 | (test-set xyz 67 | (if true 68 | (skip-test "Reason for skipping here"))) ; skip-test skips the current test 69 | 70 | (test-set-fails fls ; test-set-fails defines a test set that *should* fail 71 | (test not 1)) 72 | 73 | To run the tests, just run:: 74 | 75 | $ hytest 76 | -------------------------------------------------------------------------------- /hytest: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # A little wrapper over HyTest 3 | 4 | import sys 5 | from hy.core.language import is_integer 6 | from hytest import main, load_tests 7 | 8 | if __name__ == '__main__': 9 | res = main(*sys.argv) 10 | if is_integer(res): 11 | sys.exit(res) 12 | -------------------------------------------------------------------------------- /hytest.hy: -------------------------------------------------------------------------------- 1 | (import [hy.importer [import-file-to-module]] 2 | [collections [OrderedDict]] 3 | [os [walk getcwd path]] 4 | traceback 5 | warnings 6 | sys) 7 | 8 | (if-python2 9 | (try 10 | (import [cStringIO [StringIO]]) 11 | (except [] 12 | (import [StringIO [StringIO]]))) 13 | (import [io [StringIO]])) 14 | 15 | (def __version__ "0.2") 16 | 17 | (try 18 | (import colorama) 19 | (except []) 20 | (else (colorama.init))) 21 | 22 | (try 23 | (import [hy.models [HyExpression HyInteger HyString HySymbol]]) 24 | (except [] 25 | (import [hy.models.expression [HyExpression] 26 | hy.models.integer [HyInteger] 27 | hy.models.string [HyString] 28 | hy.models.symbol [HySymbol]]))) 29 | 30 | (defclass SkipException [Exception] []) 31 | (defclass FailException [Exception] []) 32 | 33 | (defmacro skip-test [reason] 34 | `(raise (.SkipException (__import__ "hytest") ~reason))) 35 | 36 | (defmacro skip-test-if [cond reason] 37 | `(if ~cond (raise (.SkipException (__import__ "hytest") ~reason)))) 38 | 39 | (defmacro skip-test-unless [cond reason] 40 | `(if-not ~cond (raise (.SkipException (__import__ "hytest") ~reason)))) 41 | 42 | (defmacro fail-test [&optional [msg ""]] 43 | `(raise (.FailException (__import__ "hytest") ~msg))) 44 | 45 | (defn fm [s &rest args] 46 | `(% ~(HyString s) (cut (, ~@args) 0 ~(HyInteger (s.count "%"))))) 47 | 48 | (defmacro --hytest-fm [s &rest args] 49 | `(% ~s (, ~@args))) 50 | 51 | (defn tst [exp msg] 52 | `(if-not ~exp (fail-test ~msg))) 53 | 54 | (defn cmp-base [op lhs rhs fms] 55 | (setv ln (gensym) rn (gensym) astr (gensym)) 56 | `(do 57 | (setv ~ln ~lhs ~rn ~rhs ~astr ~(if-python2 `basestring `(, str bytes))) 58 | ~(tst `(~op ~ln ~rn) 59 | `(+ 60 | ~(fm fms `(repr ~ln) `(repr ~rn)) 61 | (if (and (isinstance ~ln ~astr) (isinstance ~rn ~astr) 62 | (in "\n" ~ln) (in "\n" ~rn)) 63 | (+ "\n" (.join "\n" 64 | (.ndiff (__import__ "difflib") 65 | (.splitlines ~ln) 66 | (.splitlines ~rn)))) 67 | ""))) 68 | (del ~ln ~rn ~astr))) 69 | 70 | (defn test-eq [lhs rhs] (cmp-base `= lhs rhs "%s != %s")) 71 | (defn test-ne [lhs rhs] (cmp-base `!= lhs rhs "%s == %s")) 72 | (defn test-lt [lhs rhs] (cmp-base `< lhs rhs "%s >= %s")) 73 | (defn test-gt [lhs rhs] (cmp-base `> lhs rhs "%s <= %s")) 74 | (defn test-lte [lhs rhs] (cmp-base `<= lhs rhs "%s > %s")) 75 | (defn test-gte [lhs rhs] (cmp-base `>= lhs rhs "%s < %s")) 76 | 77 | (defn test-is [lhs rhs] (cmp-base `is lhs rhs "%s is not %s")) 78 | (defn test-is-not [lhs rhs] (cmp-base `is-not lhs rhs "%s is %s")) 79 | 80 | (defn test-is-nil [x] (test-is x `None)) 81 | (defn test-is-not-nil [x] (test-is-not x `None)) 82 | 83 | (defn almost-base [op] `(fn [lhs rhs] (~op (round (- lhs rhs) 7) 0))) 84 | (defn test-almost-eq [lhs rhs] (cmp-base (almost-base `=) lhs rhs 85 | "%s is not almost equal to %s")) 86 | (defn test-almost-ne [lhs rhs] (cmp-base (almost-base `!=) lhs rhs 87 | "%s is almost equal to %s")) 88 | 89 | (defn test-regex [s r] (cmp-base `(fn [s r] (.search (__import__ "re") r s)) s r 90 | "%s does not match regex %s")) 91 | (defn test-not-regex [s r] (cmp-base `(fn [s r] 92 | (not (.search (__import__ "re") r s))) s r 93 | "%s matches regex %s")) 94 | 95 | (defn items-base [op] `(fn [lhs rhs] (~op (sorted lhs) (sorted rhs)))) 96 | (defn test-items-eq [lhs rhs] (cmp-base (items-base `=) lhs rhs 97 | "items in %s are not equal to items in %s")) 98 | (defn test-items-ne [lhs rhs] (cmp-base (items-base `!=) lhs rhs 99 | "items in %s are equal to items in %s")) 100 | 101 | (defn test-true [x] (cmp-base `(fn [x _] x) x `None "%s is not true")) 102 | (defn test-not [x] (cmp-base `(fn [x _] (not x)) x `None "%s is not true")) 103 | 104 | (defn test-in [x sq] (cmp-base `in x sq "item %s not in sequence %s")) 105 | (defn test-not-in [x sq] (cmp-base `not-in x sq "item %s is in sequence %s")) 106 | 107 | (def raise-var (gensym)) 108 | 109 | (defn test-raises-any [&rest body] 110 | `(try 111 | ~@body 112 | (except []) 113 | (else (fail-test "code did not raise exception")))) 114 | 115 | (defn test-raises [exceptions &rest body] 116 | (setv strexc (HyString (.join ", " (map str exceptions)))) 117 | `(try 118 | ~@body 119 | (except [[~@exceptions]]) 120 | (else (fail-test (+ "code did not raise one of: " ~strexc))))) 121 | 122 | (defn test-raises-msg [m &rest body] 123 | `(try 124 | ~@body 125 | (except [~raise-var Exception] 126 | (if-not (.search (__import__ "re") ~m (str ~raise-var)) 127 | (fail-test 128 | ~(fm "exception message '%s' did not match %s" `(str ~raise-var) m)))) 129 | (else (fail-test "code did not raise exception")))) 130 | 131 | (defn test-not-raises-any [&rest body] 132 | `(try 133 | ~@body 134 | (except [~raise-var Exception] 135 | (fail-test (+ "code raised exception " (repr ~raise-var)))))) 136 | 137 | (defn test-not-raises [exceptions &rest body] 138 | `(try 139 | ~@body 140 | (except [~raise-var [~@exceptions]] 141 | (fail-test (+ "code raised exception " (repr ~raise-var)))))) 142 | 143 | (defn test-not-raises-msg [m &rest body] 144 | `(try 145 | ~@body 146 | (except [~raise-var Exception] 147 | (if (.search (__import__ "re") ~m (str ~raise-var)) 148 | (fail-test ~(fm "raised exception message '%s' matched %s" 149 | `(str ~raise-var) m)))))) 150 | 151 | (def opmap {"=" test-eq 152 | "!=" test-ne 153 | "<" test-lt 154 | ">" test-gt 155 | "<=" test-lte 156 | ">=" test-gte 157 | "eq" test-eq 158 | "ne" test-ne 159 | "lt" test-lt 160 | "gt" test-gt 161 | "lte" test-lte 162 | "gte" test-gte 163 | "is" test-is 164 | "is-not" test-is-not 165 | "is-nil" test-is-nil 166 | "is-not-nil" test-is-not-nil 167 | "is-none" test-is-nil 168 | "~" test-almost-eq 169 | "!~" test-almost-ne 170 | "aeq" test-almost-eq 171 | "ane" test-almost-ne 172 | "=~" test-regex 173 | "!=~" test-not-regex 174 | "re" test-regex 175 | "not-re" test-not-regex 176 | "=:" test-items-eq 177 | "!=:" test-items-ne 178 | "ieq" test-items-eq 179 | "ine" test-items-ne 180 | "True" test-true 181 | "False" test-not 182 | "not" test-not 183 | "in" test-in 184 | "not-in" test-not-in 185 | "raises" test-raises-any 186 | "raises-exc" test-raises 187 | "raises-msg" test-raises-msg 188 | "not-raises" test-not-raises-any 189 | "not-raises-exc" test-not-raises 190 | "not-raises-msg" test-not-raises-msg}) 191 | 192 | (defmacro test [name &rest args] 193 | (setv sname (.replace (str name) "_" "-")) 194 | (if-not (in sname opmap) 195 | (macro-error name (% "unknown comparator: %s" sname))) 196 | (apply (get opmap sname) args)) 197 | 198 | (def mods []) 199 | (def tests (OrderedDict)) 200 | 201 | (defn add-test [func file] 202 | (if-not (in file tests) 203 | (assoc tests file (.OrderedDict (__import__ "collections")))) 204 | (setv mytests (get tests file)) 205 | (if (in func.__name__ mytests) 206 | (warnings.warn (+ "duplicate test: " file ":" func.__name__))) 207 | (assoc mytests func.__name__ func)) 208 | 209 | (defn get-setup-and-teardown [body] 210 | (setv body (list body)) 211 | (defmacro get-f2 [x] `(if (and body (get body 0)) (get (get body 0) 0) None)) 212 | (if (= (get-f2 body) (HySymbol "test_setup")) 213 | (setv setup (cut (.pop body 0) 1)) 214 | (setv setup (HyExpression []))) 215 | (if (= (get-f2 body) (HySymbol "test_teardown")) 216 | (setv teardown (cut (.pop body 0) 1)) 217 | (setv teardown (HyExpression []))) 218 | (, (tuple body) setup teardown)) 219 | 220 | (defmacro test-set [name &rest body] 221 | (setv [body setup teardown] (get-setup-and-teardown body)) 222 | `(do 223 | (defn ~name [] ~@setup (try (do ~@body) (finally ~@teardown))) 224 | (.add-test (__import__ "hytest") ~name __file__))) 225 | 226 | (defmacro test-set-fails [name &rest body] 227 | (setv [body setup teardown] (get-setup-and-teardown body)) 228 | (setv skipexc (gensym)) 229 | `(do 230 | (defn ~name [] 231 | ~@setup 232 | (setv ~skipexc (getattr (__import__ "hytest") "SkipException")) 233 | (try 234 | (do ~@body) 235 | (except [~skipexc] (raise)) 236 | (except []) 237 | (finally ~@teardown))) 238 | (.add-test (__import__ "hytest") ~name __file__))) 239 | 240 | (defn main [this &rest args] 241 | (if (or (in "-h" args) (in "--help" args)) 242 | (sys.exit (% "usage: %s [--version] " this))) 243 | (when (in "--version" args) 244 | (print (+ "hytest v" __version__)) 245 | (-> 0 int sys.exit)) 246 | (setv wanted-names args) 247 | (defn starstr [s] 248 | (setv stars (* "*" (len s))) 249 | (print stars) 250 | (print s) 251 | (print stars)) 252 | (load-tests) 253 | (setv wanted (OrderedDict)) 254 | (when wanted-names 255 | (for [n wanted-names] 256 | (if-not (in ":" n) 257 | (sys.exit (% "test name %s must have module specifier" n)) 258 | (setv [mod test] (n.split ":"))) 259 | (if-not (in mod tests) 260 | (sys.exit (+ "unknown module: " mod))) 261 | (if-not (in test (get tests mod)) 262 | (sys.exit (+ "unknown test: " n))) 263 | (if-not (in mod wanted) 264 | (assoc wanted mod (OrderedDict))) 265 | (assoc (get wanted mod) test (get (get tests mod) test)))) 266 | (unless wanted 267 | (setv wanted tests)) 268 | (setv run 0) 269 | (setv skipped []) 270 | (setv traces []) 271 | (setv outputs (, [] [] [])) 272 | (setv stdout sys.stdout) 273 | (setv stderr sys.stderr) 274 | (for [[mod mtests] (wanted.items)] 275 | (sys.stdout.write (% "\033[34m%s\033[0m " mod)) 276 | (for [[name tst] (mtests.items)] 277 | (setv fullname (--hytest-fm "%s:%s" mod name)) 278 | (setv out (StringIO)) 279 | (setv err (StringIO)) 280 | (setv sys.stdout out) 281 | (setv sys.stderr err) 282 | (try 283 | (try 284 | (tst) 285 | (except [] (raise)) 286 | (finally 287 | (setv sys.stdout stdout) 288 | (setv sys.stderr stderr))) 289 | (except [e SkipException] 290 | (skipped.append (, fullname (str e))) 291 | (.append (get outputs 1) (, fullname (out.getvalue) (err.getvalue))) 292 | (sys.stdout.write "\033[35mS\033[0m")) 293 | (except [e Exception] 294 | (sys.stdout.write "\033[31mF\033[0m") 295 | (traces.append (, fullname (traceback.format-exc))) 296 | (.append (get outputs 0) (, fullname (out.getvalue) (err.getvalue)))) 297 | (else 298 | (sys.stdout.write "\033[32m.\033[0m") 299 | (.append (get outputs 2) (, fullname (out.getvalue) (err.getvalue)))) 300 | (finally 301 | (+= run 1)))) 302 | (print)) 303 | (defn print-bufs [n] 304 | (setv st (get outputs n)) 305 | (if-not st 306 | (raise (ValueError ""))) 307 | (setv (, tst out err) (get st 0)) 308 | (when out 309 | (starstr (% "CAPTURED STDOUT: %s: " tst)) 310 | (print out)) 311 | (when err 312 | (starstr (% "CAPTURED STDERR: %s: " tst)) 313 | (print err)) 314 | (st.pop 0)) 315 | (while True 316 | (try 317 | (print-bufs 2) 318 | (except [ValueError] (break)))) 319 | (for [[tst trace] traces] 320 | (print_bufs 0) 321 | (print "\033[31m") 322 | (starstr (% "ERROR: %s:" tst)) 323 | (print trace) 324 | (print "\033[0m")) 325 | (for [[tst reason] skipped] 326 | (print_bufs 1) 327 | (print "\033[35m") 328 | (starstr (--hytest-fm "SKIPPED %s: %s" tst reason)) 329 | (print "\033[0m")) 330 | (print (% "\033[34mTests run: %d" run)) 331 | (print (% "\033[32mTests succeeded: %d" (- run (len traces) (len skipped)))) 332 | (print (% "\033[31mTests failed: %d\033[0m" (len traces))) 333 | (print (% "\033[35mTests skipped: %d\033[0m" (len skipped))) 334 | (-> traces bool int)) 335 | 336 | (defn find-tests [dir] 337 | (setv test-paths []) 338 | (for [[root dirs files] (walk dir)] 339 | (for [f files] 340 | (if (and (f.startswith "test") (= (get (path.splitext f) 1) ".hy")) 341 | (test-paths.append (path.join root f))))) 342 | test-paths) 343 | 344 | (defn load-tests [] 345 | (for [p (find-tests (getcwd))] 346 | (mods.append 347 | (import-file-to-module (get (path.splitext (path.basename p)) 0) p)))) 348 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | hy >= 0.12.0 2 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | try: 2 | from setuptools import setup 3 | from setuptools.command.build_py import build_py 4 | setuptools = True 5 | except: 6 | from distutils.core import setup 7 | from distutils.command.build_py import build_py 8 | setuptools = False 9 | 10 | import os, re 11 | 12 | # XXX: This is a hack 13 | 14 | def patch(func): 15 | setattr(build_py, func.__name__, func) 16 | 17 | @patch 18 | def find_modules(self): 19 | return [('', 'hytest', 'hytest.hy')] 20 | 21 | @patch 22 | def get_module_outfile(self, build_dir, *_): 23 | return os.path.join(build_dir, 'hytest.hy') 24 | 25 | this_dir = os.path.dirname(__file__) 26 | 27 | with open(os.path.join(this_dir, 'README.rst')) as f: 28 | readme = f.read() 29 | 30 | with open(os.path.join(this_dir, 'hytest.hy')) as f: 31 | version = re.search(r'\(def __version__ "([^"]+)"\)', f.read()).group(1) 32 | 33 | with open(os.path.join(this_dir, 'requirements.txt')) as f: 34 | hy_ver = f.read().strip() 35 | 36 | kw = {} 37 | if setuptools: 38 | kw['install_requires'] = hy_ver 39 | 40 | setup( 41 | name='HyTest', 42 | version=version, 43 | description='A testing framework for Hy', 44 | long_description=readme, 45 | author='Ryan Gonzalez', 46 | author_email='rymg19@gmail.com', 47 | classifiers=[ 48 | 'License :: OSI Approved :: MIT License', 49 | 'Operating System :: OS Independent', 50 | 'Topic :: Software Development :: Testing' 51 | ], 52 | requires=[hy_ver.replace('>= ', '(>=')+')'], 53 | scripts=['hytest'], 54 | py_modules=['hytest'], 55 | url='https://github.com/kirbyfan64/hytest', 56 | **kw) 57 | -------------------------------------------------------------------------------- /test_hytest.hy: -------------------------------------------------------------------------------- 1 | (require [hytest [*]]) 2 | (import [hytest [find-tests FailException]] 3 | [os [getcwd makedirs path]] 4 | [shutil [rmtree]] 5 | [tempfile [mkdtemp]]) 6 | 7 | (test-set test-setup-and-teardown 8 | (test-setup 9 | (def x 0) 10 | (def y 1)) 11 | (test-teardown 12 | (def x 1) 13 | (def y 2)) 14 | (test = x 0) 15 | (test = y 1)) 16 | 17 | (test-set test-skip 18 | (test raises-msg "skipthis" (skip-test "skipthis"))) 19 | 20 | (test-set test-fails 21 | (test raises-msg "failthis" (fail-test "failthis"))) 22 | 23 | (test-set-fails test-fails2 24 | (assert False)) 25 | 26 | (test-set test-cmp 27 | (test = 1 1) 28 | (test raises-exc [FailException] (test = 1 2)) 29 | (test != 1 2) 30 | (test raises-exc [FailException] (test != 1 1)) 31 | (test < 0 1) 32 | (test raises-exc [FailException] (test < 1 0)) 33 | (test > 1 0) 34 | (test raises-exc [FailException] (test > 0 1))) 35 | 36 | (test-set test-is 37 | (def obj (object)) 38 | (test is obj obj) 39 | (test is-not obj (object)) 40 | (test raises-exc [FailException] (test is obj (object))) 41 | (test raises-exc [FailException] (test is-not obj obj))) 42 | 43 | (test-set test-nil 44 | (test is-nil None) 45 | (test is-not-nil 0) 46 | (test raises-exc [FailException] (test is-nil 0)) 47 | (test raises-exc [FailException] (test is-not-nil None))) 48 | 49 | (test-set test-almost 50 | (test aeq 1.00000001 1) 51 | (test ane 1 2) 52 | (test raises-exc [FailException] (test aeq 1 2)) 53 | (test raises-exc [FailException] (test ane 1.00000001 1))) 54 | 55 | (test-set test-regex 56 | (test =~ "abc" "c") 57 | (test !=~ "abc" "d") 58 | (test raises-exc [FailException] (test =~ "abc" "d")) 59 | (test raises-exc [FailException] (test !=~ "abc" "c"))) 60 | 61 | (test-set test-items 62 | (test =: [1 2 3] [3 2 1]) 63 | (test !=: [1 2 3] [3 2]) 64 | (test raises-exc [FailException] (test =: [1 2 3] [3 2])) 65 | (test raises-exc [FailException] (test !=: [1 2 3] [3 2 1]))) 66 | 67 | (test-set test-membership 68 | (test in 1 [1 2 3]) 69 | (test not-in 0 [1 2 3]) 70 | (test raises-exc [FailException] (test in 0 [1 2 3])) 71 | (test raises-exc [FailException] (test not-in 1 [1 2 3]))) 72 | 73 | (test-set test-raises 74 | (test raises (assert False)) 75 | (test raises-exc [AssertionError] (assert False)) 76 | (test raises-msg "abc" (raise (ValueError "1abc2"))) 77 | (test not-raises (assert True)) 78 | (test not-raises-exc [AssertionError] (assert True)) 79 | (test not-raises-msg "abc" (raise (ValueError "1ab2c")))) 80 | 81 | (test-set test-boolcmp 82 | (test True 1) 83 | (test False 0) 84 | (test not 0) 85 | (test raises-exc [FailException] (test True 0)) 86 | (test raises-exc [FailException] (test False 1)) 87 | (test raises-exc [FailException] (test not 1))) 88 | 89 | (def x 1) 90 | 91 | (test-set test-globals 92 | (test = x 1)) 93 | 94 | (defn touch [&rest parts] 95 | "Join the path `parts` and touch the resulting filename." 96 | (.close (open (apply path.join parts) "a"))) 97 | 98 | (test-set test-find-tests 99 | (setv root (mkdtemp)) 100 | (try 101 | (do (makedirs (path.join root "a" "b" "c")) 102 | (touch root "test_root.hy") 103 | (touch root "a" "test_a.hy") 104 | (touch root "a" "b" "test_b.hy") 105 | (touch root "a" "b" "c" "test_c.hy") 106 | (test = (find-tests root) 107 | [(path.join root "test_root.hy") 108 | (path.join root "a" "test_a.hy") 109 | (path.join root "a" "b" "test_b.hy") 110 | (path.join root "a" "b" "c" "test_c.hy")])) 111 | (finally (rmtree root)))) 112 | -------------------------------------------------------------------------------- /travis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo "Installing dependencies..." 6 | pip install -r requirements.txt 7 | 8 | echo "Running tests..." 9 | python ./hytest 10 | --------------------------------------------------------------------------------