Personally, I can't imagine any development setup on UNIX without Emacs. Probably, VI would do but it's internal language far inferior to emacs-lisp.
So, here we go again - my desktop, that did not change for 3+ month...
It Emacs on the left and something what missing from Emacs functionality on the right (otherwise it wouldn't be there:)).
While developing significant piece of software we often feel insecure. It's especially true for dynamic languages which gives no guaranty of any kind about runtime (they are too rock-n-roll IMO, some type inference wouldn't harm).
To leverage this feeling we adding amount of bravado into SW life-circle with Maven, Hudson, Agile and Continuous Integration/Deployment. It helps, but seems like overkill for me and while this Zen can be practical in corporate aquarium (because they have office plankton there) it is not for individual projects (when no Zen/Lean master around).
Here is my receipt for better sleep while still have fun with big amount of code.
REM We would need nothing but linux-base to organize relevant TDD/CI environment for development with JavaScript.
For Integration Test I would recommend JsTestDriver from Google. It is quite sane piece of software with sound integration test-strategy.
We need to start server, register target browser's as test slave and trigger tests on repository when ready.
Those bits of manual labor can be automated with Bash script.
We need to start server, register target browser's as test slave and trigger tests on repository when ready.
Those bits of manual labor can be automated with Bash script.
run_jsTestDrive.sh
# test-runner Continuous Integration style java -jar $JSTESTDRIVER_HOME/JsTestDriver-1.2.2.jar --port 4224 --captureConsole & PID=$! trap "{ echo 'Exiting'; echo $PID; kill $PID ; exit 0; }" SIGINT SIGTERM sleep 3 while true; do sleep 2 java -jar $JSTESTDRIVER_HOME/JsTestDriver-1.2.2.jar --tests all | \ tee >({ \ grep -q -s 'Total.*Fails: 0; Errors: 0'; \ if [ $? -eq 0 ]; then \ echo -e "\e[1;32m Tests successful - Fails: 0; Errors: 0 \e[0m"; \ else \ echo -e "\e[1;31m Tests failed. \e[0m"; \ fi \ }) inotifywait -e modify *.js done
It will start (and kill) server for us. It will look on disk for changing files and fire tests if any.
NB. It's very important that all your test have colored diagnostic. It doesn't meter what it says but it must be GREEN or RED for your peripheral vision to pick up it easily.
Tests failed. vs. Tests successful - Fails: 0; Errors: 0
Also colors are big importance because TDD process based on REFACTOR-GREEN-COMMIT cycle, and 'green means tested.
There is some mambo-jumbo in the script which does coloring with terminal control sequences.
File changes picked up by kernel inode supervisor using user land utility $ inotifywait -e modify *.js
For Unitary Test I had to write small piece.
There about dozen well written xTest frameworks but I wanted to keep same test database for `unitary and for `integration. While we already fixed CI framework to js-test-driver, its TestCase format have to be reused with new unitary TestRunner.
TestCase("js-test-unit", { setUp: function() { jstestunit.testCaseManager = new jstestunit.TestCaseManager(); jstestunit.testCaseBuilder = new jstestunit.TestCaseBuilder(jstestunit.testCaseManager); jstestunit.testRunner = new jstestunit.TestRunner(); }, tearDown: function(){ delete jstestunit.testCaseManager; delete jstestunit.testCaseBuilder; delete jstestunit.testRunner; }, "test configuration exist": function(){ assertEquals('object', typeof jstestunit.config); assertEquals('object', typeof jstestunit.testCaseManager); assertEquals('object', typeof jstestunit.testCaseBuilder); assertEquals('object', typeof jstestunit.testRunner); }, });
Sources is in the repo on BitBucket: $ hg clone https://lib.aca55a@bitbucket.org/lib.aca55a/js-test-unit
This TestRunner is HTML infected and have to run directly inside Browser. To integrate it with Emacs we would need another module - MozRepl. This one is hooked directly in Gecko engine of FF and shows on localhost:4242. On Emacs side it is just sock to REPL. From the MozRepl you can `BrowserReload() effectively re-executing all your tests.
Again we can automate stuff in emacs-lisp this time.
;; M-x moz-reload-mode (define-minor-mode moz-reload-mode "Moz Reload Minor Mode" nil " Reload" nil (if moz-reload-mode ;; Edit hook buffer-locally. (add-hook 'after-save-hook 'moz-reload nil t) (remove-hook 'after-save-hook 'moz-reload t))) (defun moz-reload () (moz-firefox-reload)) (defun moz-firefox-reload () (comint-send-string (inferior-moz-process) "BrowserReload();"))
This setup did not add functionality. You REPL code normal way, occasionally saving files. But general feeling is like you hawing angel on right shoulder singing `Don't worry, be happy... .
Demon on left knows real state of affairs, and this what happens when you connection human to machine - you have to leverage fear.
1 Fr - define fear between zero and 1.0 software, when constant being-in-the-flow of 1 challenge applied to coding, produces a function of 1 hack, the programmer not being a seat of any interruptive force.
Few tips in the end.
- It is true that Emacs is best in the business but it is also true that it is hard to get on this 50+ year marked. I'm there today thanks to unknown-somebody who's config I `borrowed some years ago. Still use it - $ hg clone https://lib.aca55a@bitbucket.org/lib.aca55a/env . It is easy to discover key-binding in emacs-keys.el and module settings in emacs-packages.el for starter.
- It is important to get right setup for you language. Examples of `right are:
- SLIME mode for CLOS
- Tuareg mode for OCAML
- js2 + espresso-mode for JavaScript. (how to do it correctly)
- There are integrated solution which easier to work with, but keep keep in mind that they raise fear to totally new level.
P.S. My testing harness runs outside of Emacs and when some error are in the report I have to communicate manually to editor. Still some automation goes in:
while read f; do emacsclient -n `echo $f|sed 's/\([^:]*\):\(.*\):.*/+\2 \1/'`; done
No comments:
Post a Comment