Permalink
Browse files

base infrastructure for the joxa-reimplementation

  • Loading branch information...
ericbmerritt committed Nov 23, 2012
1 parent 9470f37 commit 45b9a5599c2ce722e48a13e3c34d63b5349e4bbe
@@ -0,0 +1,95 @@
+## -*- mode: Makefile; fill-column: 75; comment-column: 50; -*-
+TEST_EBIN=$(APPDIR)/.eunit
+TEST_FLAGS=--pa $(TEST_EBIN)
+
+DEPS_DIR=$(CURDIR)/deps
+
+EBIN_DIRS=$(wildcard $(DEPS_DIR)/*/ebin)
+BASE_ERLCFLAGS=$(EBIN_DIRS:%= --pa %)
+ERLCFLAGS=$(BASE_ERLCFLAGS) --pa $(BEAMDIR)
+ERLFLAGS=$(ERLCFLAGS)
+ASTDIR=$(SRCDIR)/ast
+
+BOOTSTRAP_ERLFLAGS=-noshell -pa $(BEAMDIR) $(BASE_ERLCFLAGS)
+
+COMP= joxa $(ERLFLAGS) $(TEST_FLAGS)
+
+SRCBEAMS = $(BEAMDIR)/joxa-cc-peg.beam \
+ $(BEAMDIR)/joxa-cc-util.beam \
+ $(BEAMDIR)/joxa-cc-lexer.beam \
+ $(BEAMDIR)/joxa-cc-error.beam \
+ $(BEAMDIR)/joxa-cc-path.beam \
+ $(BEAMDIR)/joxa-cc-ns.beam \
+ $(BEAMDIR)/joxa-cc-ctx.beam \
+ $(BEAMDIR)/joxa-cc-parser.beam \
+ $(BEAMDIR)/joxa-cc-parser.beam \
+ $(BEAMDIR)/joxa-lib.beam \
+ $(BEAMDIR)/joxa-assert.beam \
+ $(BEAMDIR)/joxa-test.beam
+
+TESTBEAMS=$(TEST_EBIN)/joxa-cc-ctx_tests.beam \
+ $(TEST_EBIN)/joxa-cc-error_tests.beam \
+ $(TEST_EBIN)/joxa-cc-path_tests.beam \
+ $(TEST_EBIN)/joxa-cc-peg_tests.beam \
+ $(TEST_EBIN)/joxa-cc-lexer_tests.beam \
+ $(TEST_EBIN)/joxa-assert_tests.beam \
+ $(TEST_EBIN)/joxa-test_tests.beam
+
+.PHONY: all bootstrap clean update-versions \
+ jxa test build get-deps proper eunit \
+ cucumber shell bare-escript
+
+.PRECIOUS: %/.d
+
+all: build test
+
+## Build all the directories as task dependencies
+%/.d:
+ @mkdir -p $(@D)
+ @touch $@
+
+$(BEAMDIR)/%.beam: $(SRCDIR)/joxa-cc-%.jxa $(BEAMDIR)/.d
+ $(COMP) --bootstrap -o $(BEAMDIR) -c $<
+
+$(BEAMDIR)/%.beam: $(SRCDIR)/%.jxa $(BEAMDIR)/.d
+ $(COMP) -o $(BEAMDIR) -c $<
+
+$(TEST_EBIN)/%.beam: $(TESTDIR)/%.jxa $(TEST_EBIN)/.d
+ $(COMP) -o $(TEST_EBIN) -c $<
+
+jxa: $(SRCBEAMS)
+
+update-versions:
+ $(CURDIR)/build-support/update-versions.sh
+
+build: update-versions
+ $(REBAR) compile
+
+get-deps:
+ $(REBAR) get-deps
+
+shell: build $(TESTBEAMS)
+ $(ERL) $(ERLFLAGS) -s joxa main -s init stop
+
+jxa-clean:
+ $(REBAR) skip_deps=true clean
+ rm -rf $(APPDIR)/joxa
+ rm -rf $(APPDIR)/.bootstrap
+ rm -rf $(APPDIR)/_build
+ rm -rf $(APPDIR)/erl_crash.dump
+
+jxa-distclean: jxa-clean
+ rm -rf $(APPDIR)/deps
+
+test: build $(TESTBEAMS) proper eunit
+
+eunit: build
+ $(REBAR) skip_deps=true eunit
+
+bare-escript:
+ $(REBAR) skip_deps=true escriptize
+
+escript: build bare-escript
+
+bootstrap:
+ make -f $(CURDIR)/build-support/bootstrap.mkf
View
@@ -16,4 +16,12 @@
{escript_emu_args, "%%!\n"}.
+%%% -*- mode: erlang -*-
+{erl_opts, [warnings_as_errors, debug_info]}.
+
+{cover_enabled, true}.
+{cover_print_enabled, true}.
+{eunit_opts, [{report, {eunit_surefire, [{dir, "."}]}}]}.
+
+
{post_hooks, [{compile, "make jxa"}]}.
View
@@ -0,0 +1,161 @@
+;;; @Copyright: Erlware, LLC
+;;;
+;;; Licensed under the Apache License, Version 2.0 you may not use
+;;; this file except in compliance with the License. You may obtain a
+;;; copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+;; Assertions for Joxa
+;; ===================
+;;
+;; Assertions form part of the design process, and in others they are
+;; used only to check assumptions at runtime. In both cases, they can
+;; be checked for validity at runtime
+;;
+;; These assertions are based directly on the assertions provided by
+;; Eunit with just a bit of Joxification
+(ns joxa-assert
+ (require erlang
+ joxa-core))
+
+;; This macro yields 'true' if the value of E matches the guarded
+;; pattern G, otherwise 'false'.
+(defmacro+ matches? (g e)
+ `(case ~e
+ (~g :true)
+ (_ :false)))
+
+;; The is macro is written the way it is so as not to cause warnings
+;; for clauses that cannot match, even if the expression is a constant.
+(defmacro+ is (bool-expr)
+ (let* (__v (joxa-core/gensym))
+ `(case ~bool-expr
+ (:true
+ :ok)
+ (~__v
+ (erlang/error {:assertion_failed
+ [{:namespace ($namespace)}
+ {:line ($line-number)}
+ {:expression (quote ~bool-expr)}
+ {:expected (quote :true)}
+ {:value (case ~__v
+ (:false ~__v)
+ (_ {:not_a_boolean ~__v}))}]})))))
+
+(defmacro+ is (guard expr)
+ (let* (__v (joxa-core/gensym))
+ `(case ~expr
+ (~guard :ok)
+ (~__v (erlang/error {:assertMatch_failed
+ [{:namespace ($namespace)}
+ {:line ($line-number)}
+ {:expression (quote ~expr)}
+ {:pattern (quote ~guard)}
+ {:value ~__v}]})))))
+
+(defmacro+ is-not (guard expr)
+ (let* (__v (joxa-core/gensym))
+ `(let* (~__v ~expr)
+ (case ~__v
+ (~guard
+ (erlang/error {:assertNotMatch_failed
+ [{:namespace ($namespace)}
+ {:line ($line-number)}
+ {:expression (quote ~expr)}
+ {:pattern (quote ~guard)}
+ {:value ~__v}]}))
+ (_ :ok)))))
+
+;; This is a convenience macro which gives more detailed reports when
+;; the expected LHS value is not a pattern, but a computed value
+(defmacro+ is-equal (expect expr)
+ (let* (__x (joxa-core/gensym)
+ __v (joxa-core/gensym))
+ `(let* (~__x ~expect)
+ (case ~expr
+ (~__x :ok)
+ (~__v
+ (erlang/error {:assertEqual_failed
+ [{:namespace ($namespace)}
+ {:line ($line-number)}
+ {:expression (quote ~expr)}
+ {:expected ~__x}
+ {:value ~__v}]}))))))
+
+;; This is the inverse case of assertEqual, for convenience.
+(defmacro+ is-not-equal (unexpect expr)
+ (let* (__x (joxa-core/gensym))
+ `(let* (~__x ~unexpect)
+ (case ~expr
+ (~__x
+ (erlang/error {:assertNotEqual_failed
+ [{:namespace ($namespace)}
+ {:line ($line-number)}
+ {:expression (quote ~expr)}
+ {:value ~__x}]}))
+ (_ :ok)))))
+
+
+;; Note: Class and Term are patterns, and can not be used for value.
+;; Term can be a guarded pattern, but Class cannot.
+(defmacro+ throws-exception (class term expr)
+ (let* (__v (joxa-core/gensym)
+ __c (joxa-core/gensym)
+ __t (joxa-core/gensym))
+ `(joxa-core/try
+ (let* (~__v ~expr)
+ (erlang/error
+ {:assertException_failed
+ [{:namespace ($namespace)}
+ {:line ($line-number)}
+ {:expression (quote ~expr)}
+ {:pattern
+ {(quote ~class) (quote ~term)}}
+ {:unexpected_success ~__v}]}))
+ (catch
+ ({~class ~term} :ok)
+ ({~__c ~__t}
+ (erlang/error
+ {:assertException_failed
+ [{:namespace ($namespace)}
+ {:line ($line-number)}
+ {:expression (quote ~expr)}
+ {:pattern {(quote ~class) (quote ~term)}}
+ {:unexpected_exception
+ {~__c ~__t
+ (erlang/get_stacktrace)}}]}))))))
+
+(defmacro+ throws-error (term expr)
+ `(joxa-assert/throws-exception :error ~term ~expr))
+
+(defmacro+ throws-exit (term expr)
+ `(joxa-assert/throws-exception :exit ~term ~expr))
+
+(defmacro+ throws-throw (term expr)
+ `(joxa-assert/throws-exception :throw ~term ~expr))
+
+;; This is the inverse case of assertException, for convenience.
+;; Note: Class and Term are patterns, and can not be used for value.
+;; Both Class and Term can be guarded patterns. Because they can be
+;; guarded expressions both class and term must be enclosed in
+;; parens. That is it shoud be (:exit) not :exit etc
+(defmacro+ does-not-throw-exception (class term expr)
+ (let* (__c (joxa-core/gensym)
+ __t (joxa-core/gensym))
+ `(joxa-core/try
+ ~expr
+ (catch
+ ({~__c ~__t}
+ (case ~__c
+ (~class
+ (case ~__t
+ (~term
+ (erlang/error {:assertNotException_failed
+ [{:namespace ($namespace)}
+ {:line ($line-number)}
+ {:expression (quote ~expr)}
+ {:pattern
+ {(quote ~class) (quote ~term)}}
+ {:unexpected_exception,
+ {~__c ~__t,
+ (erlang/get_stacktrace)}}]}))
+ (_ :ok)))
+ (_ :ok)))))))
@@ -1,11 +1,16 @@
+;;; @Copyright: Erlware, LLC
+;;;
+;;; Licensed under the Apache License, Version 2.0 you may not use
+;;; this file except in compliance with the License. You may obtain a
+;;; copy of the License at http://www.apache.org/licenses/LICENSE-2.0
;; Test Support
;; ============
;;
;; This module provides some functionality that helps in applying
;; tests from a makefile. Given a path to an OTP application it will
;; extract all of the module names from the app and attempt to run the
;; proper and eunit tests on said modules.
-(ns joxa-build-support
+(ns joxa-build-utils
(require joxa-eunit
joxa-assert
joxa-lists
@@ -20,9 +25,7 @@
file
io_lib
code
- filename
- cucumberl
- joxa-assert)
+ filename)
(use (joxa-core :only (try/1 if/3 +/1 when/2 unless/2 !=/2))
(erlang :only (==/2))))
@@ -79,26 +82,13 @@
(name . names))
[])))
-(defn+ cucumberl-test-app (path)
- (joxa-lists/dolist (feature (gather-features-from-app path))
- (io/format "Running feature ~s~n" [feature])
- (try
- (case (cucumberl/run feature)
- ({:ok, _} :ok)
- (_
- (init/stop 1)))
- (catch ({_ _}
- (init/stop 1))))))
-
(defn+ main (args)
;; Path comes in as an atom from the command line
(case args
([:eunit path]
(eunit-test-app (erlang/atom_to_list path)))
([:proper path]
(proper-test-app (erlang/atom_to_list path)))
- ([:cucumberl path]
- (cucumberl-test-app (erlang/atom_to_list path)))
([:print path]
(io/format "~p~n"
[(gather-modules-from-app
@@ -112,7 +102,7 @@
(case (file/consult input-path)
({:ok [{:application name mod-info}]}
(io/format "writing ~s~n" [app-file-path])
- (joxa-assert/assert-equal
+ (joxa-assert/is-equal
:ok
(file/write_file
app-file-path
@@ -140,9 +130,9 @@
(let* (ebin-path "/foo/bar/baz"
uber-path "/foo/bar/baz/namespace/module-name.beam"
uber-path2 "/foo/bar/baz/module-name.beam")
- (joxa-assert/assert-equal :namespace.module-name
+ (joxa-assert/is-equal :namespace.module-name
(file-name-to-module-name ebin-path uber-path))
- (joxa-assert/assert-equal :module-name
+ (joxa-assert/is-equal :module-name
(file-name-to-module-name ebin-path uber-path2))))
(joxa-eunit/testable)
Oops, something went wrong.

0 comments on commit 45b9a55

Please sign in to comment.