Skip to content

Commit

Permalink
Merge pull request #180 from brandoncorrea/master
Browse files Browse the repository at this point in the history
Passes Speclj using Advanced ClojureScript Optimizations
  • Loading branch information
slagyr authored May 28, 2024
2 parents c05c694 + 08b77c8 commit 4e615ab
Show file tree
Hide file tree
Showing 33 changed files with 758 additions and 628 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ jobs:
run: clojure -M:test:spec

- name: Run ClojureScript Tests
run: clojure -M:test:cljs once
run: clojure -M:test:cljs ci
12 changes: 12 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# 3.4.8

* can now be built and executed under `:advanced` ClojureScript optimizations
* exports functions needed by JavaScript
* refactors functions that would otherwise fail with `:advanced` optimizations
* extends `run-specs` to accepts string keys in addition to keyword keys
* exports `speclj.run.standard.arm()` function to JavaScript (synonym for `speclj.run.standard.armed = true`)
* exports `speclj.run.standard.disarm()` function to JavaScript (synonym for `speclj.run.standard.armed = false`)
* `Runner` can now `get-descriptions`
* `Runner` can now `filter-descriptions` based on a hash-map of string/boolean namespace pairs
* `{"speclj.core" true "speclj.reporting" false"}`

# 3.4.7

* fixes bug where `should-throw` would expand string predicates improperly under cljs whitespace optimizations.
Expand Down
16 changes: 7 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ Include speclj in your `:dev` profile `:dependencies` and`:plugins`. Then change

```clojure
; - snip
:dependencies [[org.clojure/clojure "1.11.2"]]
:profiles {:dev {:dependencies [[speclj "3.4.6"]]}}
:plugins [[speclj "3.4.6"]]
:dependencies [[org.clojure/clojure "1.11.3"]]
:profiles {:dev {:dependencies [[speclj "3.4.8"]]}}
:plugins [[speclj "3.4.8"]]
:test-paths ["spec"]
```

Expand Down Expand Up @@ -140,7 +140,7 @@ Add a `spec` alias to your `deps.edn`.
```clojure
{
:aliases {:spec {:main-opts ["-m" "speclj.main" "-c"]
:extra-deps {speclj/speclj {:mvn/version "3.4.6"}}
:extra-deps {speclj/speclj {:mvn/version "3.4.8"}}
:extra-paths ["spec"]}}
}
```
Expand Down Expand Up @@ -245,10 +245,8 @@ p.onConsoleMessage = function (x) {
p.injectJs(phantom.args[0]);

var result = p.evaluate(function () {
speclj.run.standard.armed = true;
return speclj.run.standard.run_specs(
cljs.core.keyword("color"), true
);
speclj.run.standard.arm();
return speclj.run.standard.run_specs("color", true);
});

phantom.exit(result);
Expand Down Expand Up @@ -314,7 +312,7 @@ Here's an example alias for your `deps.edn`.
```clojure
{:aliases {:cov {:main-opts ["-m" "cloverage.coverage" "--runner" ":speclj" "-p" "src" "-s" "spec" ]
:extra-deps {cloverage/cloverage {:mvn/version "1.2.4"}
speclj/speclj {:mvn/version "3.4.6"}}}}}
speclj/speclj {:mvn/version "3.4.8"}}}}}
```

Sadly, Cloverage doesn't offer a way to pass arguments to the runner (Speclj in this case). Speclj will use the
Expand Down
96 changes: 44 additions & 52 deletions bin/specs.html
Original file line number Diff line number Diff line change
@@ -1,69 +1,61 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="iso-8859-1" content="text/html" http-equiv="Content-Type"/>
<title>Speclj Specs</title>
<!--<script src="../js/es5-shim.js" type="text/javascript"></script>-->
<script src="../target/cljs/goog/base.js" type="text/javascript"></script>
<script src="../target/specs.js" type="text/javascript"></script>
<script type="text/javascript">
String.prototype.endsWith = function (suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
<meta charset="iso-8859-1" content="text/html" http-equiv="Content-Type"/>
<title>Speclj Specs</title>
<!--<script src="../js/es5-shim.js" type="text/javascript"></script>-->
<script src="../target/cljs/goog/base.js" type="text/javascript"></script>
<script src="../target/specs.js" type="text/javascript"></script>
<script type="text/javascript">
String.prototype.endsWith = function (suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1
}

// Load all the specs
for(var k in goog.debugLoader_.dependencies_) {
var dep = goog.debugLoader_.dependencies_[k];
for (var i = 0; i < dep.provides.length; i++) {
var ns = dep.provides[i];
// console.log(ns);
if (ns.endsWith("_spec")) {
goog.require(ns)
}
}
}
// Load all the specs
for (let k in goog.debugLoader_.dependencies_) {
let dep = goog.debugLoader_.dependencies_[k]
dep.provides
.filter(ns => ns.endsWith("_spec"))
.forEach(goog.require)
}

runSpecsConfigured = function (color, reporter) {
speclj.run.standard.armed = true;
return speclj.run.standard.run_specs(
cljs.core.keyword("color"), color
, cljs.core.keyword("reporters"), [reporter]
);
};
runSpecsConfigured = function (color, reporter) {
speclj.run.standard.arm()
return speclj.run.standard.run_specs(
"color", color,
"reporters", [reporter]
)
}

runSpecs = function () {
return runSpecsConfigured(false, "documentation");
}
runSpecs = function () {
return runSpecsConfigured(false, "documentation")
}

runSpecsFiltered = function (affectedSpecs) {
if(affectedSpecs != null) {
console.log("Only running affected specs:");
var descriptionAtom = speclj.config.active_runner().descriptions;
cljs.core.swap_BANG_(descriptionAtom, function (descriptions) {
return cljs.core.filter(function (description) {
return description.ns in affectedSpecs;
}, descriptions);
});
cljs.core.doall(cljs.core.map(function (description) {
console.log(" ", description.ns);
}, cljs.core.deref(descriptionAtom)));
}
return runSpecsConfigured(true, "documentation");
}
</script>
runSpecsFiltered = function (affectedSpecs) {
if (affectedSpecs != null) {
console.log("Only running affected specs:")
var runner = speclj.config.active_runner()
speclj.running.filter_descriptions(runner, affectedSpecs)
speclj.running.get_descriptions(runner)
.forEach((description) =>
console.log(" ", description.ns))
}
return runSpecsConfigured(true, "documentation")
}
</script>
</head>
<body>
<h3 style="margin: 1em">Speclj CLJS Specs</h3>

<p style="margin: 1em; width: 400px;">
Typically these specs are run using a headless browser driven by a script.
But you can run them here if you like.
That is, assuming all the cljs has been compiled in development.
<br/>
Open up the browser console:
Typically these specs are run using a headless browser driven by a script.
But you can run them here if you like.
That is, assuming all the cljs has been compiled in development.
<br/>
Open up the browser console:
</p>
<pre style="margin: 1em; padding: 1em; width: 400px; border: 1px dotted slategray; background-color: lightgray;">
runSpecs()
</pre>
</body>
</html>
</html>
38 changes: 27 additions & 11 deletions dev/speclj/dev/cljs.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,29 @@


(def build-options
{:optimizations :none
:output-to "target/specs.js"
:output-dir "target/cljs"
:cache-analysis true
:source-map true
:pretty-print true
:verbose true
:watch-fn (fn [] (println "Success!"))
})
{:development {:optimizations :none
:output-to "target/specs.js"
:output-dir "target/cljs"
:cache-analysis true
:source-map true
:pretty-print true
:verbose true
:watch-fn (fn [] (println "Success!"))
}
:ci {
:cache-analysis false
:optimizations :advanced
:output-to "target/specs.js"
:output-dir "target/cljs"
:pretty-print false
:verbose false
:watch-fn (fn [] (println "Success!"))
}})

(defn ->build-key [build-key]
(case build-key
"ci" :ci
:development))

(defn run-specs []
(let [process (.exec (Runtime/getRuntime) "node bin/speclj.js")
Expand All @@ -23,5 +37,7 @@
(System/exit (.waitFor process))))

(defn -main [& args]
(api/build "spec" build-options)
(run-specs))
(let [build-key (->build-key (first args))
build (get build-options build-key)]
(api/build "spec" build)
(run-specs)))
8 changes: 2 additions & 6 deletions examples/basics/basic_spec.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(ns basics-spec
(:require [speclj.core :refer :all]
[speclj.run.standard :refer [run-specs]]))
[speclj.run.standard :as standard]))

;(describe "Truth"
;
Expand All @@ -10,7 +10,6 @@
; (it "is not false"
; (should-not false)))


(declare *the-answer*)
(describe "Calculator"

Expand All @@ -34,7 +33,4 @@
(should= 42 *the-answer*))
)


(run-specs)


(standard/run-specs)
7 changes: 2 additions & 5 deletions examples/basics/calulator_spec.clj
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
(ns basics-spec.calulator_spec
(:require [speclj.core :refer :all]
[speclj.run.standard :refer [run-specs]]))


[speclj.run.standard :as standard]))

(describe "Calculator"

Expand All @@ -28,5 +26,4 @@
(should= 42 *the-answer*))
)


(run-specs)
(standard/run-specs)
54 changes: 27 additions & 27 deletions spec/speclj/config_spec.cljc
Original file line number Diff line number Diff line change
@@ -1,70 +1,70 @@
(ns speclj.config-spec
(#?(:cljs :require-macros :clj :require)
[speclj.core :refer [describe it should-not= should= should-throw should-not-contain should-be-same]])
(:require [speclj.config :refer [load-runner load-reporter default-config
parse-tags config-mappings *tag-filter* config-bindings]]
(:require [speclj.core #?(:clj :refer :cljs :refer-macros) [describe context it should-not= should= should-throw should-not-contain should-not-be-nil should-be-same]]
[speclj.spec-helper #?(:clj :refer :cljs :refer-macros) [test-exported-meta]]
[speclj.config :as sut]
[speclj.platform :as platform]
[speclj.report.progress]
[speclj.report.silent]
[speclj.run.standard :refer [run-specs]]))

[speclj.run.standard :as standard]))

(describe "Config"
(it "dynamically loads StandardRunner"
(let [runner (load-runner "standard")]
(let [runner (sut/load-runner "standard")]
(should-not= nil runner)
(should= speclj.run.standard.StandardRunner (type runner))))

#?(:clj
(it "dynamically loads VigilantRunner"
(let [runner (load-runner "vigilant")]
(let [runner (sut/load-runner "vigilant")]
(should-not= nil runner)
(should= "speclj.run.vigilant.VigilantRunner" (.getName (type runner))))))

(it "throws exception with unrecognized runner"
(should-throw platform/exception "Failed to load runner: blah" (load-runner "blah")))
(should-throw platform/exception "Failed to load runner: blah" (sut/load-runner "blah")))

(it "dynamically loads ProgressReporter"
(let [reporter (load-reporter "progress")]
(let [reporter (sut/load-reporter "progress")]
(should-not= nil reporter)
(should= speclj.report.progress.ProgressReporter (type reporter))))

(it "dynamically loads SilentReporter"
(let [reporter (load-reporter "silent")]
(should-not= nil reporter)
(let [reporter (sut/load-reporter "silent")]
(should-not-be-nil reporter)
(should= speclj.report.silent.SilentReporter (type reporter))))

(it "throws exception with unrecognized reporter"
(should-throw platform/exception "Failed to load reporter: blah" (load-reporter "blah")))
(should-throw platform/exception "Failed to load reporter: blah" (sut/load-reporter "blah")))

(it "can be given a pre-fabricated reporter"
(let [pre-fabricated-reporter (speclj.report.silent/new-silent-reporter)
reporter (load-reporter pre-fabricated-reporter)]
reporter (sut/load-reporter pre-fabricated-reporter)]
(should-not= nil reporter)
(should-be-same reporter pre-fabricated-reporter)))

(it "converts tag input to includes/excludes"
(should= {:includes #{} :excludes #{}} (parse-tags []))
(should= {:includes #{:one} :excludes #{}} (parse-tags [:one]))
(should= {:includes #{:one} :excludes #{}} (parse-tags ["one"]))
(should= {:includes #{:one :two} :excludes #{}} (parse-tags ["one" 'two]))
(should= {:includes #{} :excludes #{:one}} (parse-tags ["~one"]))
(should= {:includes #{} :excludes #{:one :two}} (parse-tags ["~one" "~two"]))
(should= {:includes #{:two} :excludes #{:one}} (parse-tags ["~one" "two"])))
(should= {:includes #{} :excludes #{}} (sut/parse-tags []))
(should= {:includes #{:one} :excludes #{}} (sut/parse-tags [:one]))
(should= {:includes #{:one} :excludes #{}} (sut/parse-tags ["one"]))
(should= {:includes #{:one :two} :excludes #{}} (sut/parse-tags ["one" 'two]))
(should= {:includes #{} :excludes #{:one}} (sut/parse-tags ["~one"]))
(should= {:includes #{} :excludes #{:one :two}} (sut/parse-tags ["~one" "~two"]))
(should= {:includes #{:two} :excludes #{:one}} (sut/parse-tags ["~one" "two"])))

#?(:clj
(it "should translate tags in config-bindings"
(let [mappings (config-mappings (assoc default-config :tags ["one" "~two"]))]
(let [mappings (sut/config-mappings (assoc sut/default-config :tags ["one" "~two"]))]
(should=
{:includes #{:one} :excludes #{:two}}
(get mappings #'*tag-filter*)))))
(get mappings #'sut/*tag-filter*)))))
#?(:clj
(it "doesn't include *parent-description* in config-bindings"
(let [cb (config-bindings)]
(let [cb (sut/config-bindings)]
(should-not-contain #'speclj.config/*parent-description* cb))))

(context "exporting"
(test-exported-meta sut/active-runner)
(test-exported-meta speclj.report.silent/new-silent-reporter)
)
)

(run-specs)


(standard/run-specs)
Loading

0 comments on commit 4e615ab

Please sign in to comment.