Skip to content

Commit

Permalink
base infrastructure for the joxa-reimplementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ericbmerritt committed Nov 23, 2012
1 parent 9470f37 commit 45b9a55
Show file tree
Hide file tree
Showing 26 changed files with 2,948 additions and 22 deletions.
95 changes: 95 additions & 0 deletions build-support/joxa1-build.mkf
Original file line number Original file line Diff line number Diff line change
@@ -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
8 changes: 8 additions & 0 deletions rebar.config
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -16,4 +16,12 @@


{escript_emu_args, "%%!\n"}. {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"}]}. {post_hooks, [{compile, "make jxa"}]}.
161 changes: 161 additions & 0 deletions src/joxa-assert.jxa
Original file line number Original file line Diff line number Diff line change
@@ -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)))))))
30 changes: 10 additions & 20 deletions src/joxa-build-support.jxa → src/joxa-build-utils.jxa
Original file line number Original file line Diff line number Diff line change
@@ -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 ;; Test Support
;; ============ ;; ============
;; ;;
;; This module provides some functionality that helps in applying ;; This module provides some functionality that helps in applying
;; tests from a makefile. Given a path to an OTP application it will ;; 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 ;; extract all of the module names from the app and attempt to run the
;; proper and eunit tests on said modules. ;; proper and eunit tests on said modules.
(ns joxa-build-support (ns joxa-build-utils
(require joxa-eunit (require joxa-eunit
joxa-assert joxa-assert
joxa-lists joxa-lists
Expand All @@ -20,9 +25,7 @@
file file
io_lib io_lib
code code
filename filename)
cucumberl
joxa-assert)
(use (joxa-core :only (try/1 if/3 +/1 when/2 unless/2 !=/2)) (use (joxa-core :only (try/1 if/3 +/1 when/2 unless/2 !=/2))
(erlang :only (==/2)))) (erlang :only (==/2))))


Expand Down Expand Up @@ -79,26 +82,13 @@
(name . names)) (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) (defn+ main (args)
;; Path comes in as an atom from the command line ;; Path comes in as an atom from the command line
(case args (case args
([:eunit path] ([:eunit path]
(eunit-test-app (erlang/atom_to_list path))) (eunit-test-app (erlang/atom_to_list path)))
([:proper path] ([:proper path]
(proper-test-app (erlang/atom_to_list path))) (proper-test-app (erlang/atom_to_list path)))
([:cucumberl path]
(cucumberl-test-app (erlang/atom_to_list path)))
([:print path] ([:print path]
(io/format "~p~n" (io/format "~p~n"
[(gather-modules-from-app [(gather-modules-from-app
Expand All @@ -112,7 +102,7 @@
(case (file/consult input-path) (case (file/consult input-path)
({:ok [{:application name mod-info}]} ({:ok [{:application name mod-info}]}
(io/format "writing ~s~n" [app-file-path]) (io/format "writing ~s~n" [app-file-path])
(joxa-assert/assert-equal (joxa-assert/is-equal
:ok :ok
(file/write_file (file/write_file
app-file-path app-file-path
Expand Down Expand Up @@ -140,9 +130,9 @@
(let* (ebin-path "/foo/bar/baz" (let* (ebin-path "/foo/bar/baz"
uber-path "/foo/bar/baz/namespace/module-name.beam" uber-path "/foo/bar/baz/namespace/module-name.beam"
uber-path2 "/foo/bar/baz/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)) (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)))) (file-name-to-module-name ebin-path uber-path2))))


(joxa-eunit/testable) (joxa-eunit/testable)
Loading

0 comments on commit 45b9a55

Please sign in to comment.