Add cljs-test to test-runner via browser/html
- standardised test namespaces: renamed to use -test suffix and moved to eliminate redundant /test folder - added cljs-test based tests via browser/html. These mimic original karma tests. NOTE: previous lein aliases `once` and `auto` have been replaced by `test-once` , `test-auto` & `karma-once` - update karma.conf & circle.yml - updated CHANGES.md & CONTRIBUTING.md
This commit is contained in:
parent
b75ec509bb
commit
a1314eb6c3
119
CHANGES.md
119
CHANGES.md
|
@ -1,87 +1,87 @@
|
|||
## 0.8.0 (2016.07.XX)
|
||||
|
||||
Staying on the leading edge of new buzzwords is obviously critical for any framework. Angular's terrifying faceplant
|
||||
is a sobering reminder to us all. With this release, re-frame's already impressive buzzword muscles
|
||||
bulge further with new walnuts like "effects", "coeffects", and "de-duplicated signal graph". Yeah, I know, right?
|
||||
Staying on the leading edge of new buzzwords is obviously critical for any framework. Angular's terrifying faceplant
|
||||
is a sobering reminder to us all. With this release, re-frame's already impressive buzzword muscles
|
||||
bulge further with new walnuts like "effects", "coeffects", and "de-duplicated signal graph". Yeah, I know, right?
|
||||
|
||||
Some may even find these new features useful.
|
||||
|
||||
Headline:
|
||||
- re-frame subscriptions are now de-duplicated. As a result,
|
||||
- re-frame subscriptions are now de-duplicated. As a result,
|
||||
many Signal graphs will be more
|
||||
efficient. The new behaviour better matches programmer intuitions about what "should" happen.
|
||||
|
||||
efficient. The new behaviour better matches programmer intuitions about what "should" happen.
|
||||
|
||||
*Explanation*
|
||||
|
||||
|
||||
Each subscription causes a handler to execute, producing
|
||||
a reactive stream of updates. Two calls to `(subscribe [:some :query])` results in two copies of the same
|
||||
subscription handler running, each delivering a stream of updates. Now, if these two subscriptions
|
||||
were running at the same time, this would be inefficient. Both handlers would be
|
||||
doing the same computations and delivering the same stream of updates. Unnecessary, duplicate work.
|
||||
|
||||
Starting with this version, this sort of duplication has been eliminated. Two, or more, concurrent
|
||||
subscriptions for the same query will now source reactive updates from the one executing handler.
|
||||
|
||||
|
||||
Starting with this version, this sort of duplication has been eliminated. Two, or more, concurrent
|
||||
subscriptions for the same query will now source reactive updates from the one executing handler.
|
||||
|
||||
So, how do we know if two subscriptions are "the same"? Answer: two subscriptions
|
||||
are the same if their query vectors test `=` to each other.
|
||||
|
||||
So, these two subscriptions are *not* "the same": `[:some-event 42]` `[:some-event "blah"]`. Even
|
||||
though they involve the same event id, `:some-event`, the query vectors do not test `=`.
|
||||
|
||||
- added a new subscription handler registration function called `re-frame.core/def-sub`. It is an
|
||||
|
||||
So, these two subscriptions are *not* "the same": `[:some-event 42]` `[:some-event "blah"]`. Even
|
||||
though they involve the same event id, `:some-event`, the query vectors do not test `=`.
|
||||
|
||||
- added a new subscription handler registration function called `re-frame.core/def-sub`. It is an
|
||||
alternative to `re-frame.core/register-sub` (now renamed to `re-frame.core/def-sub-raw`).
|
||||
`def-sub` is significantly easier to use and understand,
|
||||
while often also being more performant. The design has really fallen out nicely and we're
|
||||
while often also being more performant. The design has really fallen out nicely and we're
|
||||
delighted with it.
|
||||
|
||||
|
||||
With `def-sub`, you no longer need to use `reaction` explicitly. Subscription handlers are now pure
|
||||
which makes them easier to understand and test etc. Plus, as you'll see in the docs, there is some
|
||||
gratuitous syntactic sugar.
|
||||
|
||||
The todomvc example is a tutorial on the subject:
|
||||
|
||||
The todomvc example is a tutorial on the subject:
|
||||
https://github.com/Day8/re-frame/blob/master/examples/todomvc/src/todomvc/subs.cljs
|
||||
|
||||
- The API for the undo/redo features has been put into `re-frame.core`.
|
||||
Detailed documentation is now available: https://github.com/Day8/re-frame/wiki/Undo-&-Redo
|
||||
While undo and redo has been a part of re-frame from the beginning, the feature has been hidden
|
||||
and not documented, so it is nice to see it given proper API status.
|
||||
|
||||
- The API for the undo/redo features has been put into `re-frame.core`.
|
||||
Detailed documentation is now available: https://github.com/Day8/re-frame/wiki/Undo-&-Redo
|
||||
While undo and redo has been a part of re-frame from the beginning, the feature has been hidden
|
||||
and not documented, so it is nice to see it given proper API status.
|
||||
Plus, this release has [a couple of enhancements](https://github.com/Day8/re-frame/wiki/Undo-&-Redo#harvesting-and-re-instating)
|
||||
over that which previously existed previously.
|
||||
|
||||
- there's now two kinds of event handlers: pure and effectful. XXX
|
||||
over that which previously existed previously.
|
||||
|
||||
- there's now two kinds of event handlers: pure and effectful. XXX
|
||||
For description see: https://github.com/Day8/re-frame/wiki/Effectful-Event-Handlers
|
||||
|
||||
|
||||
- taking advantage of the new effectful event handlers, there's now a new library
|
||||
which makes it easy to XXXX
|
||||
|
||||
|
||||
|
||||
|
||||
Breaking:
|
||||
- requires Reagent >= v0.6.0
|
||||
|
||||
- `re-frame.core/register-handler` has been renamed `re-frame.core/def-event`. (There's now
|
||||
two kinds of event-handlers, pure and effectful. Event handlers of the 2nd, new kind
|
||||
should be registered via the new function `re-frame.core/def-event-fx`)
|
||||
|
||||
- `re-frame.core/register-sub` has been renamed `re-frame.core/def-sub-raw`. This is to indicate that
|
||||
this kind of registration is now considered the low level, close to the metal way to
|
||||
- requires Reagent >= v0.6.0
|
||||
|
||||
- `re-frame.core/register-handler` has been renamed `re-frame.core/def-event`. (There's now
|
||||
two kinds of event-handlers, pure and effectful. Event handlers of the 2nd, new kind
|
||||
should be registered via the new function `re-frame.core/def-event-fx`)
|
||||
|
||||
- `re-frame.core/register-sub` has been renamed `re-frame.core/def-sub-raw`. This is to indicate that
|
||||
this kind of registration is now considered the low level, close to the metal way to
|
||||
create subscriptions handlers. This release introduced `def-sub` which becomes the preferred way
|
||||
to register subscription handlers.
|
||||
|
||||
- By default, re-frame uses `js/console` functions like `error` and `warn` when logging, but you can
|
||||
supply alternative functions using `re-frame.core/set-loggers!`.
|
||||
|
||||
With this release, any alternatives you supply will be called with different parameters.
|
||||
Previously loggers were called with a single `str` parameter but now they are expected to act
|
||||
|
||||
- By default, re-frame uses `js/console` functions like `error` and `warn` when logging, but you can
|
||||
supply alternative functions using `re-frame.core/set-loggers!`.
|
||||
|
||||
With this release, any alternatives you supply will be called with different parameters.
|
||||
Previously loggers were called with a single `str` parameter but now they are expected to act
|
||||
like `console.log` itself and take variadic, non string params. Sorry to break things, but
|
||||
we are trying to maximise use of cljs-devtools and information is lost when strings are
|
||||
we are trying to maximise use of cljs-devtools and information is lost when strings are
|
||||
output, instead of actual data.
|
||||
|
||||
Of course, you need only worry about this if you are using `re-frame.core/set-loggers!` to
|
||||
hook in your own loggers. If you are, then, to transition, you'll need to tweak like this:
|
||||
|
||||
Of course, you need only worry about this if you are using `re-frame.core/set-loggers!` to
|
||||
hook in your own loggers. If you are, then, to transition, you'll need to tweak like this:
|
||||
```
|
||||
;; your old log function might have looked like this. Single string parameter.
|
||||
(defn my-logger [s] (do-something-with s))
|
||||
|
||||
(defn my-logger [s] (do-something-with s))
|
||||
|
||||
;; your new version will have variadic params, and turn them into a string
|
||||
(defn my-logger [& args] (do-something-with (apply str args))
|
||||
```
|
||||
|
@ -92,10 +92,21 @@ Improvements
|
|||
- XXX todomvc changed to use spec, instead of Schema
|
||||
|
||||
- Bug fix: `post-event-callbacks` were not called when `dispatch-sync` was called.
|
||||
- added new API `re-frame.core/remove-post-event-callback`. See doc string.
|
||||
- when an event-handler makes no change to `app-db`, the `debug` middleware now logs a
|
||||
single line saying so, rather than a "group". Makes it slightly easier to grok
|
||||
- added new API `re-frame.core/remove-post-event-callback`. See doc string.
|
||||
- when an event-handler makes no change to `app-db`, the `debug` middleware now logs a
|
||||
single line saying so, rather than a "group". Makes it slightly easier to grok
|
||||
the absence of change.
|
||||
- Standardised test namespaces: renamed to use -test suffix and moved to eliminate redundant /test folder
|
||||
- Added cljs.test based tests via browser/html. These mimic original karma tests. NOTE: previous lein aliases `once` and `auto` have been replaced by `test-once` , `test-auto` & `karma-once` see [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
|
||||
####Other:####
|
||||
- changed dev deps/plugins
|
||||
<pre>
|
||||
binaryage/devtools "0.7.2"
|
||||
lein-npm "0.6.2"
|
||||
lein-figwheel "0.5.4-7"
|
||||
lein-shell "0.5.0" (added)
|
||||
</pre>
|
||||
|
||||
## 0.7.0 (2016-03-14)
|
||||
|
||||
|
|
|
@ -26,12 +26,21 @@ Use your best judgement on what is needed here.
|
|||
|
||||
## Running the tests
|
||||
|
||||
#### Via Browser/HTML
|
||||
```sh
|
||||
lein test-once # builds re-frame tests & opens browser on test/test.html
|
||||
# or lein test-auto # then open a browser on test/test.html
|
||||
# and refresh browser to rerun tests after each auto compile.
|
||||
```
|
||||
|
||||
#### Via Karma
|
||||
|
||||
To run the tests, you must have recent versions of node, npm, Leiningen, and a C++ compiler toolchain installed. If you're on Linux or Mac OS X then you will be fine, if you're on Windows then you need to install Visual Studio Community Edition, and the C++ compiler dependencies.
|
||||
|
||||
```
|
||||
lein deps # will run lein-npm and install Karma and other node dependencies. Only needed the first time.
|
||||
lein once # or lein auto # to build re-frame
|
||||
karma start # to run the tests with an auto watcher
|
||||
```sh
|
||||
lein deps # runs lein-npm, installs Karma & other node dependencies. Only needed the first time.
|
||||
lein karma-once # to build re-frame tests
|
||||
karma start # to run the tests with an auto watcher
|
||||
```
|
||||
|
||||
## Pull requests for bugs
|
||||
|
|
|
@ -10,5 +10,5 @@ dependencies:
|
|||
- node_modules
|
||||
test:
|
||||
override:
|
||||
- lein once
|
||||
- lein karma-once
|
||||
- karma start --single-run --reporters junit,dots
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module.exports = function (config) {
|
||||
var root = 'run/compiled/test'; // same as :output-dir
|
||||
var junitOutputDir = process.env.CIRCLE_TEST_REPORTS || "run/compiled/test/junit";
|
||||
var root = 'run/compiled/karma/test'; // same as :output-dir
|
||||
var junitOutputDir = process.env.CIRCLE_TEST_REPORTS || "run/compiled/karma/test/junit";
|
||||
|
||||
config.set({
|
||||
frameworks: ['cljs-test'],
|
||||
|
@ -11,7 +11,7 @@ module.exports = function (config) {
|
|||
],
|
||||
|
||||
client: {
|
||||
args: ['re_frame.test.runner.run']
|
||||
args: ['re_frame.test_runner.run_karma']
|
||||
},
|
||||
|
||||
// the default configuration
|
||||
|
|
51
project.clj
51
project.clj
|
@ -4,37 +4,52 @@
|
|||
:license {:name "MIT"}
|
||||
:dependencies [[org.clojure/clojure "1.8.0"]
|
||||
[org.clojure/clojurescript "1.9.89"]
|
||||
[reagent "0.6.0-rc"]]
|
||||
[reagent "0.6.0-rc"]]
|
||||
|
||||
:profiles {:debug {:debug true}
|
||||
:dev {:dependencies [[karma-reporter "0.3.0"]
|
||||
[binaryage/devtools "0.7.0"]]
|
||||
:plugins [[lein-cljsbuild "1.1.3"]
|
||||
[lein-npm "0.6.1"]
|
||||
[lein-figwheel "0.5.4-2"]]}}
|
||||
:dev {:dependencies [[karma-reporter "0.3.0"]
|
||||
[binaryage/devtools "0.7.2"]]
|
||||
:plugins [[lein-cljsbuild "1.1.3"]
|
||||
[lein-npm "0.6.2"]
|
||||
[lein-figwheel "0.5.4-7"]
|
||||
[lein-shell "0.5.0"]]}}
|
||||
|
||||
:clean-targets [:target-path
|
||||
"run/compiled"]
|
||||
:clean-targets [:target-path "run/compiled"]
|
||||
|
||||
:resource-paths ["run/resources"]
|
||||
:jvm-opts ["-Xmx1g" "-XX:+UseConcMarkSweepGC"]
|
||||
:source-paths ["src"]
|
||||
:test-paths ["test"]
|
||||
:source-paths ["src"]
|
||||
:test-paths ["test"]
|
||||
|
||||
:shell {:commands {"open" {:windows ["cmd" "/c" "start"]
|
||||
:macosx "open"
|
||||
:linux "xdg-open"}}}
|
||||
|
||||
:deploy-repositories [["releases" :clojars {:sign-releases false}]
|
||||
["snapshots" :clojars {:sign-releases false}]]
|
||||
|
||||
:npm {:dependencies [[karma "1.0.0"]
|
||||
[karma-cljs-test "0.1.0"]
|
||||
:npm {:dependencies [[karma "1.0.0"]
|
||||
[karma-cljs-test "0.1.0"]
|
||||
[karma-chrome-launcher "0.2.0"]
|
||||
[karma-junit-reporter "0.3.8"]]}
|
||||
[karma-junit-reporter "0.3.8"]]}
|
||||
|
||||
:cljsbuild {:builds [{:id "test"
|
||||
:source-paths ["test" "src"]
|
||||
:compiler {:output-to "run/compiled/test.js"
|
||||
:source-map "run/compiled/test.js.map"
|
||||
:output-dir "run/compiled/test"
|
||||
:compiler {:output-to "run/compiled/browser/test.js"
|
||||
:source-map true
|
||||
:output-dir "run/compiled/browser/test"
|
||||
:optimizations :none
|
||||
:source-map-timestamp true
|
||||
:pretty-print true}}
|
||||
{:id "karma"
|
||||
:source-paths ["test" "src"]
|
||||
:compiler {:output-to "run/compiled/karma/test.js"
|
||||
:source-map "run/compiled/karma/test.js.map"
|
||||
:output-dir "run/compiled/karma/test"
|
||||
:optimizations :whitespace
|
||||
:main "re_frame.test_runner"
|
||||
:pretty-print true}}]}
|
||||
|
||||
:aliases {"auto" ["do" "clean," "cljsbuild" "auto" "test,"]
|
||||
"once" ["do" "clean," "cljsbuild" "once" "test,"] })
|
||||
:aliases {"test-once" ["do" "clean," "cljsbuild" "once" "test," "shell" "open" "test/test.html"]
|
||||
"test-auto" ["do" "clean," "cljsbuild" "auto" "test,"]
|
||||
"karma-once" ["do" "clean," "cljsbuild" "once" "karma,"]})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(ns re-frame.test.middleware
|
||||
(ns re-frame.middleware-test
|
||||
(:require [cljs.test :refer-macros [is deftest]]
|
||||
[reagent.ratom :refer [atom]]
|
||||
[re-frame.middleware :as middleware]))
|
|
@ -1,4 +1,4 @@
|
|||
(ns re-frame.test.subs
|
||||
(ns re-frame.subs-test
|
||||
(:require [cljs.test :refer-macros [is deftest]]
|
||||
[reagent.ratom :refer-macros [reaction]]
|
||||
[re-frame.subs :as subs]
|
|
@ -1,15 +0,0 @@
|
|||
(ns re-frame.test.runner
|
||||
(:require [jx.reporter.karma :as karma :include-macros true]
|
||||
[re-frame.test.middleware]
|
||||
[re-frame.test.undo]
|
||||
[re-frame.test.subs]
|
||||
[devtools.core :as devtools]))
|
||||
|
||||
(devtools/install!) ;; we love https://github.com/binaryage/cljs-devtools
|
||||
|
||||
(defn ^:export run [karma]
|
||||
(karma/run-tests
|
||||
karma
|
||||
're-frame.test.middleware
|
||||
're-frame.test.undo
|
||||
're-frame.test.subs))
|
|
@ -0,0 +1,33 @@
|
|||
(ns re-frame.test-runner
|
||||
(:refer-clojure :exclude (set-print-fn!))
|
||||
(:require
|
||||
[cljs.test :as cljs-test :include-macros true]
|
||||
[jx.reporter.karma :as karma :include-macros true]
|
||||
[devtools.core :as devtools]
|
||||
;; Test Namespaces -------------------------------
|
||||
[re-frame.middleware-test]
|
||||
[re-frame.undo-test]
|
||||
[re-frame.subs-test]))
|
||||
|
||||
(enable-console-print!)
|
||||
(devtools/install! [:custom-formatters :sanity-hints]) ;; we love https://github.com/binaryage/cljs-devtools
|
||||
|
||||
;; ---- BROWSER based tests ----------------------------------------------------
|
||||
(defn ^:export set-print-fn! [f]
|
||||
(set! cljs.core.*print-fn* f))
|
||||
|
||||
|
||||
(defn ^:export run-html-tests []
|
||||
(cljs-test/run-tests
|
||||
're-frame.middleware-test
|
||||
're-frame.undo-test
|
||||
're-frame.subs-test))
|
||||
|
||||
;; ---- KARMA -----------------------------------------------------------------
|
||||
|
||||
(defn ^:export run-karma [karma]
|
||||
(karma/run-tests
|
||||
karma
|
||||
're-frame.middleware-test
|
||||
're-frame.undo-test
|
||||
're-frame.subs-test))
|
|
@ -1,4 +1,4 @@
|
|||
(ns re-frame.test.undo
|
||||
(ns re-frame.undo-test
|
||||
(:require [cljs.test :refer-macros [is deftest]]
|
||||
[re-frame.undo :as undo]
|
||||
[re-frame.db :as db]
|
|
@ -0,0 +1,129 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<title>re-frame Unit Tests</title>
|
||||
<meta charset='utf-8'>
|
||||
<meta name="google" content="notranslate"/>
|
||||
|
||||
<!-- Use a monospaced font and a dark theme -->
|
||||
<!-- some colour from Palette from http://clrs.cc/ -->
|
||||
<style>
|
||||
body {
|
||||
font-family: Courier, "Courier New", monospace;
|
||||
font-size: 11;
|
||||
background-color: #111;
|
||||
color: #AAA;
|
||||
margin: 0.25in 0.25in 0.25in 0.25in;
|
||||
}
|
||||
h2 {
|
||||
font-size: 24;
|
||||
}
|
||||
.red {
|
||||
color: #FF4136;
|
||||
}
|
||||
.green {
|
||||
color: #2ECC40;
|
||||
}
|
||||
.orange {
|
||||
color: #FF851B;
|
||||
}
|
||||
.blue {
|
||||
color: #0074D9;
|
||||
}
|
||||
.test-header {
|
||||
color: #EEE;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>re-frame Unit Tests</h2>
|
||||
<div id="output-goes-here"></div>
|
||||
|
||||
<script src="../run/compiled/browser/test/goog/base.js" type="text/javascript"></script>
|
||||
<script src="../run/compiled/browser/test.js" type="text/javascript"></script>
|
||||
|
||||
<script>
|
||||
// This loop is where a lot of important work happens
|
||||
// It will inject both the unit tests and code-to-be-tested into the page
|
||||
//find out what requires cljs.core
|
||||
// reverse nameToPath
|
||||
var pathToName = {};
|
||||
for (var key in goog.dependencies_.nameToPath) {
|
||||
var value = goog.dependencies_.nameToPath[key];
|
||||
pathToName[value] = key;
|
||||
}
|
||||
for (var key in goog.dependencies_.requires) {
|
||||
if (goog.dependencies_.requires.hasOwnProperty(key)) {
|
||||
if (goog.dependencies_.requires[key]["cljs.core"]) {
|
||||
//as key is a path find its namespace
|
||||
goog.require(pathToName[key]); // will trigger CLOSURE_IMPORT_SCRIPT calls which injectJs into page
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Output
|
||||
var outputDiv = document.getElementById("output-goes-here")
|
||||
|
||||
function testPrintLn(line) {
|
||||
line = line.replace(/\n/g, "");
|
||||
if (line == "")
|
||||
return;
|
||||
line = line.replace(/</g, "<");
|
||||
line = line.replace(/>/g, ">");
|
||||
|
||||
// First, to the console
|
||||
console.log(line);
|
||||
|
||||
// Second, into the HTML
|
||||
var span = document.createElement("pre");
|
||||
outputDiv.appendChild(span);
|
||||
|
||||
// look for colour markers
|
||||
if (-1 != line.indexOf('ERRORS:')) {
|
||||
span.className = "blue"
|
||||
}
|
||||
if (-1 != line.indexOf('WARNINGS:')) {
|
||||
span.className = "blue"
|
||||
}
|
||||
if (-1 != line.indexOf('ERROR ')) {
|
||||
span.className = "orange"
|
||||
}
|
||||
if (-1 != line.indexOf('FAIL')) {
|
||||
span.className = "red"
|
||||
}
|
||||
if (-1 != line.indexOf('Testing test.')) {
|
||||
span.className = "test-header"
|
||||
}
|
||||
if (-1 != line.indexOf('failures,')) {
|
||||
if (-1 != line.indexOf('0 failures, 0 errors')) {
|
||||
document.body.style.backgroundColor = "#00430D";
|
||||
span.className = "green";
|
||||
}
|
||||
else {
|
||||
document.body.style.backgroundColor = "771419";
|
||||
span.className = "red";
|
||||
}
|
||||
}
|
||||
|
||||
// replace leading blanks with so text lines up
|
||||
var numLeadingBlanks = line.match(/^\s*/)[0].length;
|
||||
var leadingNBSP = Array(numLeadingBlanks).join(" ")
|
||||
|
||||
span.innerHTML = leadingNBSP + line + "<br>";
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Run Tests
|
||||
//
|
||||
function run_tests() {
|
||||
re_frame.test_runner.set_print_fn_BANG_(testPrintLn);
|
||||
re_frame.test_runner.run_html_tests();
|
||||
}
|
||||
|
||||
// Don't run any tests till this page is fully loaded.
|
||||
// Remember there'll be lots of async <script> added by the loop above.
|
||||
window.addEventListener('load', run_tests);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue