Compare commits

...

318 Commits

Author SHA1 Message Date
John Bintz
f7384d684c It's been fun. Use Karma instead. 2014-05-14 15:34:21 -04:00
John Bintz
1055dc1016 Merge pull request #177 from jeremy-brenner/master
Qt 4.8 fix
2013-03-15 10:59:23 -07:00
Jeremy Brenner
c1e786f3c5 Added compiler directive to include getopt.h on qt versions >= 4.8 2013-03-15 11:23:50 -05:00
John Bintz
aa1d989a90 message about looking for new maintainer 2012-07-30 11:15:32 -04:00
John Bintz
30e1ff8e51 bump version 2012-04-23 11:08:17 -04:00
John Bintz
9b41a36841 fix a bad commit and fix multijson deprecation warnings 2012-04-23 09:30:56 -04:00
John Bintz
65137186c8 Merge pull request #142 from pungoyal/master
fixing multi_json 1.3.2 issue #140
2012-04-18 08:05:08 -07:00
Puneet Goyal
a89682f771 Update vendor/assets/javascripts/intense.coffee 2012-04-18 20:24:20 +05:30
Puneet Goyal
3815a47d07 fixing multi_json 1.3.2 issue 2012-04-18 20:22:14 +05:30
John Bintz
724541a2cb Merge pull request #135 from tddium/master
Sort order in directory globs
2012-04-03 06:50:51 -07:00
William Josephson
1c81ea7286 Most filesystems don't guarantee directory listing order, so sort glob results. 2012-04-02 22:12:45 -04:00
John Bintz
8c6a792960 Merge pull request #132 from doitian/master
Do not populate the global Sprockets environment
2012-03-23 11:48:33 -07:00
Ian Yang
1aac97ea1f do not populate the global Sprockets environment 2012-03-23 22:52:54 +08:00
John Bintz
21590a9a19 Merge pull request #111 from rossta/register_custom_template_hook
Ability to register custom template engines...
2012-03-22 04:17:13 -07:00
John Bintz
68683e4b6c Merge pull request #131 from pmcelhaney/patch-1
Great price and record fast shipping time!!! Would request again. :)
2012-03-20 11:12:14 -07:00
Patrick McElhaney
181f4e286a Removed log messages from spec runner. 2012-03-19 17:05:51 -03:00
John Bintz
d572b0d6fe Merge pull request #130 from pmcelhaney/patch-1
Fixed getLastModified callback firing three times
2012-03-19 12:11:28 -07:00
Patrick McElhaney
af20af8524 Fixed getLastModified callback firing three times (once for every readyState change). 2012-03-19 15:28:41 -03:00
John Bintz
0064595dea remove the specification of the qmakespec, maybe help fix #59 2012-02-21 09:19:33 -05:00
John Bintz
2e2651d11a may fix #119, file paths on windows 2012-02-21 09:04:00 -05:00
John Bintz
c96cbd4aac move sprockets gem finding to separate gem that enforces rubygems version, implements #116 in a different way 2012-02-08 09:07:54 -05:00
John Bintz
4f11cba073 some fixes for bad things. i'm sad 2012-02-03 15:12:28 -05:00
John Bintz
bad6839760 rc version bump 2012-01-27 09:19:44 -05:00
John Bintz
453f439271 forgot a change 2012-01-24 14:47:31 -05:00
John Bintz
142a0c974b make sure src_files can also be loaded from other asset paths, should fix problem found by @christiannelson 2012-01-24 14:38:10 -05:00
Ross Kaffenberger
75dce5b66b Ability to register custom template engines via Jasmine::Headless.register_engine hook 2012-01-22 18:40:13 -05:00
John Bintz
0d4550524f crazy crazy changes for server running and outside browser usage and other *magic* 2012-01-18 18:04:36 -05:00
John Bintz
47b8d10d56 server runner updated 2012-01-17 13:32:57 -05:00
John Bintz
d3c3e7bd7d don't reinvent the wheel 2012-01-13 07:45:27 -05:00
John Bintz
f51f041b85 webrick seems to need log write locations or things get weird 2012-01-12 18:40:25 -05:00
John Bintz
8de1bd8cf0 clean up some fixes 2012-01-12 18:07:08 -05:00
John Bintz
09842c0539 fix a few verbose reporter bugs 2012-01-12 16:47:36 -05:00
John Bintz
5d43eb2193 let's run with a server, like all the cool kids do nowadays\! 2012-01-12 15:02:32 -05:00
John Bintz
ed4590ee44 ensure assets with same logical_path but different pathnames are included, fixes #110 2012-01-12 14:16:16 -05:00
John Bintz
b7553062bd rearrange js 2012-01-11 15:41:27 -05:00
John Bintz
ed76916205 more cleanup 2012-01-11 14:24:09 -05:00
John Bintz
b9b4648a24 update reporter 2012-01-11 11:37:25 -05:00
John Bintz
282ed40264 merge 2012-01-11 09:58:47 -05:00
John Bintz
1f56031d8b -q to silence some noisy things, fixes #97 2012-01-11 08:44:28 -05:00
John Bintz
da59a48025 add verbose reporter 2012-01-10 17:14:37 -05:00
John Bintz
81f561282a make sure window.promot doesn't get called, fixes #106 2012-01-09 13:20:58 -05:00
John Bintz
dfe1bece2c make sure window.promot doesn't get called, fixes #106 2012-01-09 11:09:34 -05:00
John Bintz
7587381e1e qt 4.8 webkit doesn't use working dir to resolve local file urls anymore, fixes #101 2012-01-03 10:47:18 -05:00
John Bintz
df83a61cb5 add help options 2011-12-30 15:33:06 -05:00
John Bintz
d5b2239d0f more clean up work, break things apart for manageability/testing 2011-12-30 11:34:30 -05:00
John Bintz
d31f628d91 clean up how reporting is done somoe more 2011-12-30 10:47:08 -05:00
John Bintz
0adf3a41b6 a whole ton of reporters work 2011-12-29 18:37:23 -05:00
John Bintz
09f4df94de merge 2011-12-29 09:38:24 -05:00
John Bintz
9dafb83892 things in a weird state... 2011-12-29 09:32:27 -05:00
John Bintz
9ff0dca191 Merge branch 'master' of github.com:johnbintz/jasmine-headless-webkit 2011-12-24 10:12:44 -05:00
John Bintz
dd86eb404e remove debugging 2011-12-24 09:55:21 -05:00
John Bintz
ac9a9cf23b try loading bundler too 2011-12-24 09:54:04 -05:00
John Bintz
e38963ed42 try loading bundler too 2011-12-24 09:53:52 -05:00
John Bintz
8465590930 Merge pull request #98 from lautis/erb-in-config-file
Parse and run ERB tags inside YAML config
2011-12-16 06:31:00 -08:00
Ville Lautanala
4c7a1f860d Parse and run ERB tags inside YAML config 2011-12-16 14:21:06 +02:00
John Bintz
5743227de6 have runner define report files as a queue 2011-12-12 14:54:53 -05:00
John Bintz
e03389e938 start splitting the reporters out 2011-12-12 12:22:32 -05:00
John Bintz
4e64480c69 bump version 2011-12-12 09:44:45 -05:00
John Bintz
7dde9328df add lib/ and app/ to vendored assets search, fixes #93 2011-12-08 09:13:45 -05:00
John Bintz
84e369d30a bump version 2011-12-06 09:37:26 -05:00
John Bintz
352ee417c5 fix extension search issue and expand bad extension searches to jasmine-style includes 2011-12-06 09:31:23 -05:00
John Bintz
00468fc1b3 Merge pull request #90 from scottdavis/master
Patch for unsupported formats in sprockets
2011-12-05 15:52:15 -08:00
Scott Davis
297f822da1 register non supported formats to there own handler and return there contents as empty so sprokets requres do not have to be changed for work. This will report to STDOUT if the file has been skipped 2011-12-05 18:49:52 -05:00
John Bintz
1099773484 bump version 2011-12-05 17:30:23 -05:00
John Bintz
d038a748ed remove debugging 2011-12-02 18:47:17 -05:00
John Bintz
3b0a11edea fix spec filtering 2011-12-02 18:37:14 -05:00
John Bintz
f3dd4f2bf8 bump version 2011-12-01 18:24:15 -05:00
John Bintz
6ad4bdaec0 also provide asset_paths in jasmine.yml for adding paths 2011-12-01 16:52:01 -05:00
John Bintz
e25d89962c fix issues for when not running under bundler 2011-12-01 10:37:35 -05:00
John Bintz
b6d94a5d0d make sure a parent module is defined first 2011-12-01 10:26:23 -05:00
John Bintz
ab1994696d bump version and add basic developer instructions 2011-12-01 10:01:06 -05:00
John Bintz
5d504570fd small refactoring 2011-12-01 08:59:05 -05:00
John Bintz
a291fd5de3 clean up the printing of headless reporter results 2011-11-29 15:36:17 -05:00
John Bintz
af14f69a07 performance boost in finding matchign spec lines 2011-11-29 15:11:40 -05:00
John Bintz
3c993001de use kernel.rand/srand 2011-11-29 14:48:55 -05:00
John Bintz
602eb634d7 bump version for upcoming release 2011-11-29 11:25:20 -05:00
John Bintz
9affa65df4 fix writing of paths and stuff, fixes #77 2011-11-29 10:56:02 -05:00
John Bintz
0d4562119f small speed optimization 2011-11-29 09:45:23 -05:00
John Bintz
ee3b6e598c cacheable actions write out better filenames, and get rid of local jquery and use jquery-rails gem for testing 2011-11-28 16:53:42 -05:00
John Bintz
4ae9815471 better randomization 2011-11-28 11:52:33 -05:00
John Bintz
3fe66c66c5 specify the random order seed with --seed 2011-11-28 11:47:05 -05:00
John Bintz
f8db052281 randomize spec load order because why not 2011-11-25 18:11:21 -05:00
John Bintz
16f867af09 a little cleanup work 2011-11-25 16:18:06 -05:00
John Bintz
03a381d3cc prevent crazy onload loop, perhaps? 2011-11-25 11:20:14 -05:00
John Bintz
bd6a1afb92 bump version 2011-11-23 10:53:26 -05:00
John Bintz
3911041866 merge sprockets code into mainline, please report bugs 2011-11-23 09:50:14 -05:00
John Bintz
edf5a49f27 test coverage and cleanup in anticipation of merge 2011-11-23 09:35:44 -05:00
John Bintz
634f60ffe6 fix tests 2011-11-22 14:01:05 -05:00
John Bintz
38327e6a95 more cleanups for things i found that are broken 2011-11-22 12:14:00 -05:00
John Bintz
2316041580 ok i actually want a bundled asset 2011-11-22 10:51:46 -05:00
John Bintz
7d75b5466f whoa actually just plug in sprockets, need to backfill tests later since i have real work to do 2011-11-22 10:36:42 -05:00
John Bintz
130a65ecdd Merge branch 'sprockets-integration' of github.com:johnbintz/jasmine-headless-webkit into sprockets-integration 2011-11-21 20:19:05 -05:00
John Bintz
7206341768 require_self 2011-11-21 20:18:11 -05:00
John Bintz
a9cc872cc8 some cleanup 2011-11-21 17:03:44 -05:00
John Bintz
7ba77ea1f9 dont show the running message if there are compile errors 2011-11-21 16:10:15 -05:00
John Bintz
a18100bb71 move the jquery console test to the right spot 2011-11-21 14:13:15 -05:00
John Bintz
08798ff88d Merge pull request #82 from rocketpack/master
console.log to clone jQuery objects before appending them.
2011-11-21 10:56:49 -08:00
John Bintz
a9b879722b reset version for a release, other branch will be 0.8 2011-11-21 13:52:01 -05:00
John Bintz
4727ad5b7b show an indicator when wait tests are running, so it doesn't look like the program crashed 2011-11-21 11:33:51 -05:00
John Bintz
9b5729b808 yet more changes, getting really close 2011-11-21 10:55:37 -05:00
John Bintz
fde8bc3b7b a ton of changes 2011-11-21 10:32:49 -05:00
Leo Lännenmäki
115e2eff8b Clone elements before appending them to the temporary div that is used for logging. 2011-11-21 08:18:16 +02:00
John Bintz
d214674620 fixing things up and cleaning more things 2011-11-20 13:35:30 -05:00
John Bintz
ca8c655f00 more sprockets improvements 2011-11-20 11:56:25 -05:00
John Bintz
61c8ed8828 more sprockets improvements 2011-11-19 19:15:38 -05:00
John Bintz
e04d692d26 reowrk a bunch of the tilt stuff, only use extensions we know 2011-11-19 12:45:40 -05:00
John Bintz
8867d00ac8 support sprockets-style jst templates 2011-11-18 16:00:24 -05:00
John Bintz
537b2e437d more work on making sprockets support better, oh yeah 2011-11-18 11:50:48 -05:00
Leo Lännenmäki
f57a59d767 console.log to clone jQuery objects before appending them.
If the appended element was a child of another element it was removed from that element.
This caused console.logging a child element to remove it from the parent.
2011-11-18 15:09:36 +02:00
John Bintz
4f8e732fa4 run the spec file analyzer through the gauntlet 2011-11-18 06:29:36 -05:00
John Bintz
a2e3ea90c9 require works, whoa 2011-11-17 22:16:04 -05:00
John Bintz
1583807c14 still reworking things, broken 2011-11-17 16:18:25 -05:00
John Bintz
9b103807ee explicitly include coffeescript, might fix #79 2011-11-16 15:39:45 -05:00
John Bintz
4150dd1828 working on stuff, broken 2011-11-16 15:28:02 -05:00
John Bintz
91d9773933 do the ping better 2011-11-10 14:18:25 -05:00
John Bintz
26762f0586 have the built-in reporter ping the runner when tests complete, to keep it alive 2011-11-10 13:52:42 -05:00
John Bintz
c7ce823409 merge in the new file handle approach, try it and let me know where it breaks 2011-11-10 11:32:54 -05:00
John Bintz
495fd1900e nuke the cpu detection 2011-11-10 11:18:55 -05:00
John Bintz
2d73baabb3 bump version 2011-11-06 09:32:09 -05:00
John Bintz
ce7b0f1368 remove cpu detection, who cares when the runner's about to be totally slimmed down 2011-11-06 09:26:37 -05:00
John Bintz
5ca065728d finalize the runner, time to merge? 2011-11-05 14:19:41 -04:00
John Bintz
3a559fb0d5 more cleaning 2011-10-26 22:20:51 -04:00
John Bintz
7b91fc5a76 more furniture rearranging 2011-10-26 20:05:05 -04:00
John Bintz
befd0b4a2d streamline more things 2011-10-26 08:55:44 -04:00
John Bintz
69d865c050 rearrange the furniture some more 2011-10-26 08:45:23 -04:00
John Bintz
298e8c2d3d last set of changes 2011-10-25 22:22:29 -04:00
John Bintz
d9ade573c9 clean out the old cruft, getting really close 2011-10-25 16:15:52 -04:00
John Bintz
9289f97f16 more gutting and cleaning, just like a fish 2011-10-25 15:41:22 -04:00
John Bintz
7db116fb45 more breakage 2011-10-25 11:25:28 -04:00
John Bintz
54e5d5c9d5 more breakage 2011-10-25 11:25:02 -04:00
John Bintz
dda84fdcb9 first big switch to javascript doing all the work 2011-10-24 16:40:08 -04:00
John Bintz
894b979674 merge jasmine.yml keys the same way as the gem 2011-10-24 11:48:41 -04:00
John Bintz
cba18bfd22 bump version 2011-10-24 11:22:50 -04:00
John Bintz
7b3e9eaa3d changelog 2011-10-24 11:03:06 -04:00
John Bintz
eede055dfe console.peek seems like a good idea, let's try it 2011-10-17 19:47:42 -04:00
John Bintz
82052d7803 warning for older versions of rubygems, someone else can fix it if it becomes a problem 2011-10-17 14:36:40 -04:00
John Bintz
f7e220bb18 fix output file writing 2011-10-17 11:10:00 -04:00
John Bintz
065cb6a985 better support for pulling in vendored helpers 2011-10-17 10:34:11 -04:00
John Bintz
2aabba2cd7 vendored helpers support, take a look at jasmine-spec-extras 2011-10-17 10:07:24 -04:00
John Bintz
8503d86aba Merge branch 'master' of github.com:johnbintz/jasmine-headless-webkit 2011-10-17 09:25:42 -04:00
John Bintz
42ed3e6013 ensure all paths are expanded before working with them, should fix johnbintz/guard-jasmine-headless-webkit #10 2011-10-17 09:25:11 -04:00
John Bintz
919ce4f79c Merge pull request #72 from ordinaryzelig/master
Fix global defaults file path
2011-10-16 14:29:41 -07:00
Jared Ning
1244d780c1 Fix global defaults file path. 2011-10-16 10:05:35 -05:00
John Bintz
951cf80f09 also allow runner output to be defined in yaml, implements #66 2011-10-11 08:55:43 -04:00
John Bintz
0be7b9e20c start work on writing out report files usable by other things 2011-10-10 14:11:13 -04:00
John Bintz
b04bb49879 add 1.9.3-rc1 test support and fix #70 2011-10-10 09:32:27 -04:00
John Bintz
c1dc86a329 check that e.sourceURL is available before using it 2011-09-26 18:42:38 -04:00
John Bintz
04e2bc5f22 Merge branch 'super-traces' 2011-09-20 16:10:30 -04:00
John Bintz
4f8a49e47c better printing of matching matcher lines 2011-09-20 16:09:32 -04:00
John Bintz
870b8e2a51 Merge branch 'master' of github.com:johnbintz/jasmine-headless-webkit 2011-09-19 16:16:21 -04:00
John Bintz
719ecf7f3c bump version 2011-09-17 12:06:56 -04:00
John Bintz
62d00cdd4c Merge branch 'super-traces' 2011-09-16 11:11:53 -04:00
John Bintz
15e9e90a7b require digest/sha1 2011-09-16 10:44:06 -04:00
John Bintz
262b7a8223 much better accuracy 2011-09-12 15:38:40 -04:00
John Bintz
84a87d423c performance tweak 2011-09-12 15:18:13 -04:00
John Bintz
243fe526ac rip out the big js parser and put in a tiny one to guess spec line numbers on failures 2011-09-12 15:12:58 -04:00
John Bintz
d8d04b8638 bump version 2011-09-12 09:15:56 -04:00
John Bintz
9c78766ded fix jsDump parsing 2011-09-09 15:35:51 -04:00
John Bintz
dc134dcf24 fix the determination of spec files for line number analysis 2011-09-09 11:49:17 -04:00
John Bintz
7bd6894397 also add beautify-html.js 2011-09-08 13:59:28 -04:00
John Bintz
a8b066ee50 make sure reports don't blow up with multi-line console messages 2011-09-08 12:17:50 -04:00
John Bintz
d8023afaee hack up a copy of jsDump and improve console reporting 2011-09-08 11:48:33 -04:00
John Bintz
363ee91b6b better support for when we don't know spec line location 2011-09-06 16:48:19 -04:00
John Bintz
6bf64edb32 better support for re-running specific specs and getting information on which specs failed 2011-09-06 16:01:10 -04:00
John Bintz
183bd93d31 timer updates, should fix #56 2011-09-06 11:37:29 -04:00
John Bintz
7f197c3719 modify reporter for use with guard 2011-09-03 07:54:52 -04:00
John Bintz
cae6f16623 finish new-style reporting, time to use it 2011-09-02 17:00:21 -04:00
John Bintz
f1318a5223 Merge branch 'master' into qt-cleanup 2011-09-02 15:52:24 -04:00
John Bintz
e5510f13d0 halfway in the middle of the reporting change 2011-09-02 15:52:19 -04:00
John Bintz
b21573b1dc fix a bug and give a message when the cache is building 2011-09-02 11:31:58 -04:00
John Bintz
8b8fc32f80 change how includes work and shuffle things around 2011-09-02 10:49:15 -04:00
John Bintz
68a2888d35 failed test 2011-09-02 10:24:24 -04:00
John Bintz
23bd56ee21 remove a bunch of specrunners 2011-09-01 10:41:06 -04:00
John Bintz
c523a1e310 second part - cache spec file analysis 2011-09-01 10:39:29 -04:00
John Bintz
fa27ee715a enable coffeescript cache, step 1 of a big speedup 2011-09-01 09:38:53 -04:00
John Bintz
bd8fa3e536 appease rubygems 2011-09-01 08:36:11 -04:00
John Bintz
3fdc69cfdd starting work on report file output 2011-08-30 15:59:09 -04:00
John Bintz
0c368ec9f2 factor out the console reporting from the runner 2011-08-30 11:56:35 -04:00
John Bintz
904be27e42 some more c++ cleanup 2011-08-29 13:35:36 -04:00
John Bintz
aeb6d57505 stupid cpp fixes 2011-08-27 10:53:29 -04:00
John Bintz
e3923335b8 clean up cpp some more 2011-08-26 11:18:04 -04:00
John Bintz
a46e72c1e2 fix colors options, fixes #55 2011-08-23 20:07:05 -04:00
John Bintz
64037b205f big merge 2011-08-23 19:55:48 -04:00
John Bintz
b54f163d3e make cleanups and color fixes 2011-08-23 19:49:47 -04:00
John Bintz
a206df590f ensure bad utf-8 is handled, fixes #48 2011-08-23 19:24:28 -04:00
John Bintz
d039aba84b start of file listing 2011-08-23 19:23:56 -04:00
John Bintz
ac5b8a4c98 add penchant 2011-08-23 18:54:23 -04:00
John Bintz
01b1fcce16 fix qmake bug 2011-08-23 18:47:15 -04:00
John Bintz
ebe5b03e36 start of file listing 2011-08-22 13:26:48 -04:00
John Bintz
47f6fead79 Merge pull request #57 from marcpeabody/master
Mac install issue fixed
2011-08-22 06:11:40 -07:00
Marc Peabody
9146041ce6 Inconsistent darwin/mac_os_x symbol bug
It was causing:
lib/qt/qmake.rb:114:in `check_qmake!': undefined method `strip' for nil:NilClass (NoMethodError)
2011-08-21 21:55:32 -04:00
John Bintz
350db80eed bump version 2011-08-12 10:22:21 -04:00
John Bintz
2a1d986f19 ensure rubygems is loaded, should fix #49 2011-08-11 14:15:42 -04:00
John Bintz
6a06d87a4c special case for when logging jquery nodes -- print the html 2011-08-11 13:07:48 -04:00
John Bintz
dc5b8c026d better errors and flatten jasmine.yml keys, allowing for merged yaml sequences in config 2011-08-10 13:11:05 -04:00
John Bintz
88d1b7f1d2 bump version and fix rake task 2011-08-10 09:02:11 -04:00
John Bintz
f094aeabc6 remove a flaky test 2011-08-10 08:55:38 -04:00
John Bintz
77a14311aa don't process any more specs when there's an error, makes the output make more sense on super-fast computers when errors occur 2011-08-07 14:45:57 -04:00
John Bintz
96c69f3def nuke the hydra stuff 2011-08-07 00:49:12 -04:00
John Bintz
30ce01c017 this caching is too dangerous 2011-08-07 00:17:45 -04:00
John Bintz
bb92628716 set up hydra for testing 2011-08-04 10:38:52 -04:00
John Bintz
680f66db6e Merge branch 'master' of github.com:johnbintz/jasmine-headless-webkit 2011-08-04 10:19:51 -04:00
John Bintz
572d2a8b5a ensure bad utf-8 is handled, fixes #48 2011-08-04 10:18:05 -04:00
John Bintz
4fb82c2e7c more qt testing work 2011-08-03 12:26:39 -04:00
John Bintz
1de9307c5d Merge pull request #47 from rapportive-oss/master
Patch to allow running specs containing UTF-8
2011-08-03 05:23:03 -07:00
Sam Stokes
7af9e353af Set test harness to UTF-8 to allow running UTF-8 spec source files 2011-08-02 20:28:39 -07:00
John Bintz
370eb182d8 trying stuff 2011-08-02 15:47:14 -04:00
John Bintz
22577e0fdc qt cleanup 2011-08-02 10:20:18 -04:00
John Bintz
60713fc88f start c++ cleanup 2011-08-01 13:09:08 -04:00
John Bintz
316383671a Merge pull request #44 from dcuddeback/master
Fix for issue #43: unitialized constant during `rake` for Rails 2.3 applications
2011-07-29 18:35:08 -07:00
John Bintz
37c4e2e52b better qt finding 2011-07-29 21:33:19 -04:00
David Cuddeback
14c3c13699 Fix compatibility for Rails 2.3 2011-07-29 12:01:40 -07:00
John Bintz
11c2cbc950 um, what was i thinking? 2011-07-29 09:58:59 -04:00
John Bintz
93e189545c bump version 2011-07-26 16:40:01 -04:00
John Bintz
32d2c59f4c changelog 2011-07-26 16:34:43 -04:00
John Bintz
477fc437ce Merge pull request #41 from Absolight/6a4d426109696cd0ffa5f79707e3132e7674ea89
have it compile on FreeBSD
2011-07-25 08:07:36 -07:00
Mathieu Arnold
6a4d426109 Make it compile on FreeBSD. 2011-07-25 15:29:07 +02:00
John Bintz
2c27d6b6b3 handle when forms try to leave, too 2011-07-22 12:48:51 -04:00
John Bintz
8a5121bd90 small clenaup and ensure form submits don't trigger loops, either 2011-07-22 09:40:40 -04:00
John Bintz
d08fb1d445 changelog 2011-07-22 07:48:19 -04:00
John Bintz
f96a0e3d76 Merge branch 'master' of github.com:johnbintz/jasmine-headless-webkit 2011-07-22 07:47:54 -04:00
John Bintz
13bcd5226e ensure a spec can't leave the page, causing a craaaazy loop 2011-07-22 07:42:25 -04:00
John Bintz
b97c8f8954 Merge pull request #39 from olivoil/master
require yaml in runner.rb
2011-07-20 15:54:54 -07:00
Olivier Melcher
8f98da4767 require yaml in runner.rb
fixes bad YAML module look-up that would give the following error:

[jasmine-headless-webkit] uninitialized constant Jasmine::Headless::Runner::YAML (NameError)
/gems/jasmine-headless-webkit-0.6.0/lib/jasmine/headless/runner.rb:47:in `jasmine_config'
2011-07-20 15:27:20 -07:00
John Bintz
fe18d2a3fd bump version 2011-07-20 09:30:30 -04:00
John Bintz
f9e3bdfbce merge in changes 2011-07-20 09:28:45 -04:00
John Bintz
f77bfb1705 changelog and minor version bump 2011-07-20 09:26:01 -04:00
John Bintz
132d9355bd changes and hooks and junk 2011-07-19 10:47:24 -04:00
John Bintz
4c7e03dc57 we don't need all of jasmine, just jasmine-core 2011-07-19 10:41:23 -04:00
John Bintz
75f4d26344 better handling of rails version checks 2011-07-19 10:29:25 -04:00
John Bintz
21d93e7c9f set application name to silence phonon warnings 2011-07-19 09:54:39 -04:00
John Bintz
b03e6d8298 Merge branch 'master' of github.com:johnbintz/jasmine-headless-webkit 2011-07-18 10:54:48 -04:00
John Bintz
879975a8ca better qt building? 2011-07-18 10:52:57 -04:00
John Bintz
4b154128ed Merge pull request #37 from ConradIrwin/master
-c/--no-colors are broken.
2011-07-15 19:54:33 -07:00
Conrad Irwin
f4a8458246 Respect the showColors option... 2011-07-15 18:07:43 -07:00
John Bintz
da08c96af6 changelog 2011-07-15 17:45:26 -04:00
John Bintz
b723d015bc Merge branch 'master' of github.com:johnbintz/jasmine-headless-webkit 2011-07-15 17:44:34 -04:00
John Bintz
154372e130 add in JHW self-tests to default task 2011-07-15 17:44:03 -04:00
John Bintz
efd8150a55 have runner tried to build qtwebkit widget if it's missing 2011-07-14 16:23:29 -04:00
John Bintz
e72eaef7a1 better finding of spec lines 2011-07-14 10:54:44 -04:00
John Bintz
3c4e557517 show line numbers for spec failures, whoa nelly 2011-07-13 14:42:47 -04:00
John Bintz
05e7d07d40 bump version 2011-07-12 08:52:31 -04:00
John Bintz
7af4657238 changelog for, like, the last one million versions 2011-07-12 08:48:51 -04:00
John Bintz
1a22a52096 big version bump 2011-07-11 21:42:42 -04:00
John Bintz
6454c329fa Merge pull request #31 from rcarver/jasmine-1-1
Jasmine 1.1 compatibility
2011-06-30 14:42:54 -07:00
Ryan Carver
d5e44fe9a5 change Jasmine.root to Jasmine::Core.path to work with jasmine 1.1 2011-06-30 12:27:57 -07:00
John Bintz
1d3991f52e support globs in file filters, fixes #29 2011-06-30 06:41:32 -04:00
John Bintz
edd503f262 passing in no files doesn't mean run a focused test with zero files, doi 2011-06-29 10:38:15 -04:00
John Bintz
99c939e6d0 raise exceptions on rake task failures, hopefully addresses #26 2011-06-28 11:24:11 -04:00
John Bintz
7316f77367 use mocha mocking instead of punching ducks 2011-06-28 11:06:36 -04:00
John Bintz
343fd6f84b rearrange the furniture on the Rake task test a little bit 2011-06-28 10:30:41 -04:00
John Bintz
96e071aa37 Merge pull request #28 from zspencer/master
Fixed defect with using the Rake Task without having Rails installed
2011-06-28 07:21:22 -07:00
Zachary Spencer
3b214f913f made the tests a bit more robust, but they may now be more DANGEROUS! 2011-06-28 16:49:31 +08:00
Zachary Spencer
953e4ec5b9 Merge branch 'master' of github.com:zspencer/jasmine-headless-webkit 2011-06-28 16:32:53 +08:00
Zachary Spencer
ccaab1c8f3 Made it so the rake task doesn't explode if you're too cool to use Rails 2011-06-28 16:31:37 +08:00
Zachary Spencer
4e5ba7945c Made it so the rake task doesn't explode if you're too cool to use Rails 2011-06-28 16:25:32 +08:00
John Bintz
c67f8dbadf run all tests after focused run if console.log was used 2011-06-24 15:57:00 -04:00
John Bintz
f82e3c0c2d bump version 2011-06-23 19:47:53 -04:00
John Bintz
de8a7c3b4c bye bye autotest 2011-06-23 19:45:59 -04:00
John Bintz
cc370aac0b remove unneeded method 2011-06-23 09:34:41 -04:00
John Bintz
c359e8b28b targeted runs w/ files outside scope work 2011-06-23 09:29:07 -04:00
John Bintz
e9a9a79142 Merge pull request #24 from ramonmaruko/linux-compile-error
Fix: g++: error: unrecognized option '-h'
2011-06-22 05:48:38 -07:00
Ramon Marco L. Navarro
675e958b66 Fix: g++: error: unrecognized option '-h' 2011-06-21 23:36:54 +08:00
John Bintz
00c4a30481 fix railtie for rails 3.1, fixes #22 2011-06-21 06:49:00 -04:00
John Bintz
e7dcffe004 bump version 2011-06-19 16:12:14 -04:00
John Bintz
a62a069166 update rakefile for rake >= 0.9.0 2011-06-19 16:11:22 -04:00
John Bintz
d4b886099c fix other half of #19, better error reporting and exceptions 2011-06-19 15:08:18 -04:00
John Bintz
3b71a0355b half-fix for #19, ensure coffeescript files have newlines separating them 2011-06-19 14:51:47 -04:00
John Bintz
ff792b81f6 bump version 2011-06-18 13:00:09 -04:00
John Bintz
2baed03356 better fix rake task for new rake dsl 2011-06-18 12:43:22 -04:00
John Bintz
7c37c80a9a fix coffeescript compile error exceptions 2011-06-17 10:27:00 -04:00
John Bintz
cff6891a8d Merge branch 'duck-punch-sprockets' 2011-06-17 09:40:59 -04:00
John Bintz
58d8f95588 report other errors better 2011-06-17 09:34:18 -04:00
John Bintz
293763cc1e make the rake task use the shiny new runner 2011-06-16 19:38:45 -04:00
John Bintz
96352d21a0 only load the rake dsl in if it's possible 2011-06-16 19:33:36 -04:00
John Bintz
6f85d3d1e8 fix #12, Rake::DSL 2011-06-16 17:34:00 -04:00
John Bintz
d3b3cb6c23 remove another debug thing 2011-06-16 10:52:13 -04:00
John Bintz
2c0d4d797b remove a debug thing 2011-06-16 10:50:45 -04:00
John Bintz
50bd14a82e fix running from non-cli 2011-06-16 10:11:37 -04:00
John Bintz
cdff35c0e2 break out running from bin 2011-06-16 09:51:49 -04:00
John Bintz
f3e63c3031 that object doesn't exist 2011-06-13 08:14:24 -04:00
John Bintz
ac7cf07d5d the duck doesn't need to be punched as hard as I thought... 2011-06-13 07:50:15 -04:00
John Bintz
cc619466df punch sprockets in the duck to make it compile files we can actually test 2011-06-12 10:40:18 -04:00
John Bintz
c29757ad9f ensure files are not required twice, fixes #10 (h/t @dnagir) 2011-06-11 09:54:15 -04:00
John Bintz
46d1027982 fix coffeescript compile error support 2011-06-10 17:14:50 -04:00
John Bintz
5f025c9b91 reset that isFinished flag, plz 2011-06-10 15:50:14 -04:00
John Bintz
2672550bbd ok, there's a little bit that can be cached 2011-06-10 14:29:16 -04:00
John Bintz
d0afb329f1 caching doesn't work as nicely w/ grouped coffeescript compile, turning it off for now 'cause the speed benefit of grouped compilation is already huge 2011-06-10 14:25:08 -04:00
John Bintz
67940c5066 only call the coffeescript compiler as much as needed. so much faster 2011-06-10 14:18:35 -04:00
John Bintz
26675216ad don't do things twice, it wastes time 2011-06-10 11:35:54 -04:00
John Bintz
5e1520a732 option to not run all tests if you don't want it to 2011-06-10 11:10:09 -04:00
John Bintz
7ff876a56f this is big enough for a new version 2011-06-10 11:04:48 -04:00
John Bintz
f7d899b0f7 write out two templates and execute one after the other if everything's cool 2011-06-10 11:02:26 -04:00
John Bintz
c32f13fbe1 factor out file list management 2011-06-10 10:04:21 -04:00
John Bintz
7c8f4c0e4e no wait, this makes more sense 2011-06-08 13:47:51 -04:00
John Bintz
57faed9d8f actually count right, total tests == total expects 2011-06-08 13:46:08 -04:00
John Bintz
860da38c99 bump version 2011-06-08 09:42:22 -04:00
John Bintz
2b5eaa7990 provide both console.log and console.pp 2011-06-08 09:27:54 -04:00
John Bintz
1d4d5f397a tweak a test for multi-platform run 2011-06-07 15:04:11 -04:00
John Bintz
c5956ee7d3 remove coffee watchr 2011-06-07 14:56:44 -04:00
John Bintz
0426fc57cc use the jasmine pretty printer if available 2011-06-07 14:55:31 -04:00
John Bintz
b06fb6f101 update gemspec so you must use coffee-script 2.2, avoids node.js console.log output issue 2011-06-01 14:54:44 -04:00
John Bintz
3f630c73e9 give better messages with javascript errors 2011-05-31 09:37:29 -04:00
John Bintz
ccafb37bbe bump version 2011-05-29 13:10:47 -04:00
John Bintz
c765e98047 new gemfile 2011-05-29 12:37:33 -04:00
John Bintz
029e12ad7b can write out a reporting file 2011-05-29 12:30:19 -04:00
John Bintz
1be31e800e bump version 2011-05-19 20:11:13 -04:00
John Bintz
f190b8c5e4 avoid that railtie 2011-05-19 20:08:19 -04:00
John Bintz
1ab01a7d25 bump version 2011-05-17 11:12:45 -04:00
John Bintz
ea0b00e4dc create a railtie to have tasks appear automatically 2011-05-17 10:41:51 -04:00
John Bintz
9ede8f2148 changelog 2011-05-17 07:55:22 -04:00
John Bintz
5833d57c8d it's a branch, not a fork 2011-05-17 07:48:02 -04:00
John Bintz
ed7d6a9378 switch to rake task and gh-pages hosting the readme 2011-05-17 07:47:42 -04:00
John Bintz
aa11f442bc add global options 2011-05-16 17:19:44 -04:00
John Bintz
9715eb3a2e small refactoring 2011-05-15 22:42:02 -04:00
John Bintz
fd3e8218d7 clean up the runner a little 2011-05-15 22:39:10 -04:00
John Bintz
690858e342 tiny bug fix for coffeescript compilation errors 2011-05-14 10:28:27 -04:00
John Bintz
cc943330f2 tiny cleanup 2011-05-13 10:01:46 -04:00
208 changed files with 6447 additions and 841 deletions

View File

@ -1,9 +0,0 @@
Autotest.add_hook(:initialize) do |at|
at.add_mapping(%r{bin/.*}, true) do |filename|
at.files_matching(%r{spec/bin/.*})
end
at.add_mapping(%r{spec/jasmine/.*}, true) do |filename|
at.files_matching(%r{spec/bin/.*})
end
end

11
.gitignore vendored
View File

@ -6,3 +6,14 @@ Makefile
specrunner.moc specrunner.moc
specrunner.o specrunner.o
ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner
*.o
moc_*.*
.DS_Store
hydra-runner.log
jhw-test
.jhw-cache/
_site/
jhw.*.html
coverage/
tmp/
cache dir/

89
CHANGELOG.md Normal file
View File

@ -0,0 +1,89 @@
## 0.7.2
* Improved finding of CoffeeScript spec line locations
* Improved Runner reporting of which expectations failed
* Initial vendored helper support, paving the way for Sprockets integratioon (maybe!)
* Add 1.9.3-rc1 test support and fixes
* Add console.peek()
## 0.7.1
* Bugfix for missing digest/sha1 import
## 0.7.0
* Major C++ cleanup, now much more modular
* Greatly improved object inspection and printing provided by jsDump and beautify-js
## 0.6.3
* Ensure Rubygems is available before doing version comparison
* Fix other build problems
* Better output for jQuery nodes
## 0.6.2
* Clean up C++ and test running
## 0.6.1
* Ensure YAML is loaded before use
* Make sure specs can't break out of the page they're running in
* Fix compilation on FreeBSD
## 0.6.0
* File and line number information for failing specs
* Try to build the runner if it's missing
* Kill warnings and streamline includes
## 0.5.0
* Run all tests after focused run if `console.log` was used
* Ensure Rake task works outside of Rails
* Ensure focused tests aren't run when CLI called with no files
* Support globs in focused test filters
* Raise exceptions on Rake task failures
* Update to use Jasmine 1.1
## 0.4.2
* Fix Rails 3.1 Railtie so it's included properly
* Fix compilation of runner on Linux
* Run files that are outside of the project's scope
## 0.4.1
* Fix CoffeeScript concatenation bug
* Report CoffeeScript errors better
## 0.4.0
* Change how tests are counted for totals
* Run targeted and full tests in the same runner instance for speed!
* Concatenate adjacent CoffeeScript files before compilation for more speed!
* Ensure files are not required twice
* Break out runner usage from CLI so that it can be resued in Rake tasks and elsewhere
* Add a Rails 3.1 task to precompile all assets with a specific "MD5 hash"
## 0.2.3
* Better messages for JavaScript errors
* `console.pp` added for more in-depth object inspection
## 0.2.2
* Write out a reporting file that can be used for Guard notification
## 0.2.1
* Avoid a Railtie so JHW works outside of Rails
## 0.2.0
* Add a Rake task and a default task for Rails
* Global runner configuration via ~/.jasmine-headless-webkit
* Custom Jasmine reporter for better user feedback
* Specify the specs to be run, instead of always running them all
* Move README to gh-pages site

26
Gemfile
View File

@ -1,8 +1,30 @@
source "http://rubygems.org" source :rubygems
# Specify your gem's dependencies in jasmine-headless-webkit.gemspec # Specify your gem's dependencies in jasmine-headless-webkit.gemspec
gemspec gemspec
gem 'rspec' gem 'rspec'
gem 'autotest'
gem 'fakefs', :require => nil gem 'fakefs', :require => nil
gem 'guard'
gem 'guard-rspec'
gem 'guard-shell'
gem 'guard-coffeescript'
gem 'guard-cucumber'
require 'rbconfig'
case RbConfig::CONFIG['host_os']
when /darwin/
when /linux/
gem 'libnotify'
end
gem 'mocha'
gem 'cucumber'
gem 'jquery-rails', '~> 1.0.0'
gem 'ejs'
gem 'guard-jasmine-headless-webkit', :git => 'git://github.com/johnbintz/guard-jasmine-headless-webkit.git'

41
Guardfile Normal file
View File

@ -0,0 +1,41 @@
# Add files and commands to this file, like the example:
# watch('file/path') { `command(s)` }
#
guard 'coffeescript', :input => 'vendor/assets/coffeescripts', :output => 'vendor/assets/javascripts'
guard 'shell' do
watch(%r{ext/jasmine-webkit-specrunner/.*\.(cpp|h|pro|pri)}) { |m|
if !m[0]['moc_']
compile
end
}
end
# A sample Guardfile
# More info at https://github.com/guard/guard#readme
guard 'rspec', :version => 2, :all_on_start => false do
watch(%r{^spec/.+_spec\.rb})
watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch(%r{^bin/(.+)}) { |m| "spec/bin/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { "spec" }
end
guard 'cucumber', :cli => '-r features --format pretty' do
watch(%r{^features/.+\.feature$})
watch(%r{^features/support/.+$}) { 'features' }
watch(%r{^features/steps/(.+)_steps\.rb$}) { 'features' }
end
guard 'jasmine-headless-webkit', :all_on_start => false do
watch(%r{^spec/javascripts/.+_spec\.coffee})
watch(%r{^jasmine/(.+)\.coffee$}) { |m| "spec/javascripts/#{m[1]}_spec.coffee" }
end
def compile
system %{cd ext/jasmine-webkit-specrunner && ruby extconf.rb}
end
compile

106
README.md
View File

@ -1,102 +1,24 @@
_This project is dead. You should use [Karma](http://karma-runner.github.io/) instead. I do._
# Jasmine Headless WebKit runner # Jasmine Headless WebKit runner
Run your specs at sonic boom speed! No pesky reload button or page rendering slowdowns! Run your specs at sonic boom speed! No pesky reload button or page rendering slowdowns!
## Introduction http://johnbintz.github.com/jasmine-headless-webkit/ has the most up-to-date information on using
this project. You can see the source of that site on the gh-pages branch.
This gem works with projects that have used the [Jasmine gem](https://github.com/pivotal/jasmine-gem) to ## For those who want to hack on the project...
create a `jasmine.yml` file that defines what to test. The runner loads that
`jasmine.yml` file and executes the tests defined within in a Qt WebKit widget, displaying the results
to the console and setting the exit code to one of the following:
* 0 for success The best way to get everything running that you need for development and testing is
* 1 for spec run failure to use Guard:
* 2 for spec run success, but `console.log` was called during the run
`console.log` works, too, so you can run your specs side-by-side in a browser if you're so inclined. It ``` bash
serializes whatever you're passing in as as JSON string, so objects that are cyclical in nature will not bundle install
serialize. If anyone has a good solution for this, please suggest and/or fork'n'fix. bundle exec guard
... build Qt runner ...
## Installation ... compile CoffeeScript to JS ...
... run RSpec and JHW ...
`gem install jasmine-headless-webkit` or use Bundler. ```
Installation requires Qt 4.7. See [senchalabs/examples](https://github.com/senchalabs/examples) and [my fork
of examples](https://github.com/johnbintz/examples) for more information on the QtWebKit runner.
Tested in the following environments:
* Mac OS X 10.6, with MacPorts Qt and Nokia Qt.mpkg
* Kubuntu 10.10
Let me know via a message or in the Issues section if it works on your setup and it's not listed!
## Usage
jasmine-headless-webkit [options] [list of spec files to run]
Current supported options:
* `-c`/`--colors` enables color output
* `--no-colors` disables color output
* `--keep` preserves the temporary HTML document if an error occurs in testing
* `-j`/`--jasmine-config` sets the `jasmine.yml` file to load *(defaults to `spec/javascripts/support/jasmine.yml`)*
If provided, only the requested spec files will be executed. Otherwise, all matching specs will be run.
These options can also be placed into a `.jasmine-headless-webkit` file in your project root.
### CoffeeScript Support
`jasmine-headless-webkit` brings in the `coffee-script` gem and compiles & injects all CoffeeScript into the
generated HTML page. All you need to do is configure your `jasmine.yml` file to look for .coffee files:
src_files:
- app/assets/javascripts/**/*.coffee
spec_files:
- **/*[sS]pec.coffee
*(This will probably make it difficult to test your code in an official Jasmine server for now. You can try
[a technique like this](https://github.com/jbaudanza/rack-asset-compiler/blob/master/examples/jasmine_config.rb) for compiling CoffeeScript when it's requested from the server
or use [this fork of jasmine-gem](https://github.com/johnbintz/jasmine-gem/tree/coffeescript-inline-support) which
is thoroughly untested.)*
You will get line numbers on compile errors, but not logic errors. This is a CoffeeScript thing, and they're working on it. :)
### JavaScript Dialogs
You can call `alert()` and `confirm()` in your code. `alert()` will print the message to the console, and
`confirm()` will always return true. There's no way right now to respond to `confirm()`, so it's best to
mock that call:
spyOn(window, 'confirm').andReturn(false);
### Autotest Integration
`jasmine-headless-webkit` can integrate with Autotest. Your `jasmine.yml` file needs to be in the default
path, and you have to be ready to use a very alpha implementation of the feature. If used with RSpec 2,
Jasmine tests run after RSpec tests.
You need to create a `.jasmine-headless-webkit` file in your project root for this integration
to work.
`jasmine-headless-webkit` provides two new hooks: `:run_jasmine` and `:ran_jasmine` for before and after the
Jasmine specs have run. This is a good place to do things like re-package all your assets using
[Jammit](http://documentcloud.github.com/jammit/):
Autotest.add_hook(:run_jasmine) do |at|
system %{jammit}
end
### Server Interaction
`jasmine-headless-webkit` works the same as if you create an HTML file, manually load the Jasmine library and
your code & tests into the page, and open that page in a browser. Because of this, there's no way to handle
server interaction with your application or with a Jasmine server. If you need to test server interaction,
do one of the following:
* Stub your server responses using [Sinon.JS](http://sinonjs.org/)
* Use [PhantomJS](http://www.phantomjs.org/) against a running copy of a Jasmine server, instead of this project
## License ## License

View File

@ -1,2 +1,65 @@
include Rake::DSL if defined?(Rake::DSL)
require 'bundler' require 'bundler'
Bundler::GemHelper.install_tasks Bundler::GemHelper.install_tasks
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
$: << File.expand_path('../lib', __FILE__)
require 'jasmine-headless-webkit'
require 'jasmine/headless/task'
Jasmine::Headless::Task.new
PLATFORMS = %w{1.9.2 1.9.3}
def rvm_bundle(command = '')
Bundler.with_clean_env do
system %{bash -c 'unset BUNDLE_BIN_PATH && unset BUNDLE_GEMFILE && rvm #{PLATFORMS.join(',')} do bundle #{command}'}
end
end
class SpecFailure < StandardError; end
class BundleFailure < StandardError; end
namespace :spec do
desc "Run on three Rubies"
task :platforms do
rvm_bundle
rvm_bundle "exec rspec spec"
rvm_bundle "exec cucumber"
raise SpecError.new if $?.exitstatus != 0
end
end
task :default => [ 'spec:platforms', 'jasmine:headless' ]
desc "Build the runner"
task :build_runner do
Dir.chdir 'ext/jasmine-webkit-specrunner' do
system %{ruby extconf.rb}
end
end
desc "Generate vendored JS"
task :generate_js do
require 'sprockets'
source = 'vendor/assets/coffeescripts'
target = 'vendor/assets/javascripts'
env = Sprockets::Environment.new { |s| s.append_path 'vendor/assets/coffeescripts' }
Dir[File.join(File.expand_path(source), '*.coffee')].each do |file|
file_target = file.gsub(source, target).gsub('.coffee', '.js')
puts "#{file} => #{file_target}"
File.open(file_target, 'wb') do |fh|
fh.print env.find_asset(File.expand_path(file)).to_s
end
end
end

View File

@ -2,110 +2,10 @@
require 'rubygems' require 'rubygems'
gem_dir = File.expand_path('../..', __FILE__) $: << File.expand_path('../../lib', __FILE__)
$:.unshift(File.join(gem_dir, 'lib'))
require 'yaml' require 'jasmine-headless-webkit'
require 'fileutils'
require 'getoptlong'
gem 'jasmine'
gem 'coffee-script'
gem 'rainbow'
require 'jasmine'
require 'coffee-script' require 'coffee-script'
require 'rainbow'
require 'jasmine/cli' Jasmine::Headless::CommandLine.run!
include Jasmine::CLI
opts = GetoptLong.new(
[ '--colors', '-c', GetoptLong::NO_ARGUMENT ],
[ '--no-colors', GetoptLong::NO_ARGUMENT ],
[ '--keep', GetoptLong::NO_ARGUMENT ],
[ '--jasmine-config', '-j', GetoptLong::REQUIRED_ARGUMENT ]
)
options = {
:colors => false,
:remove_html_file => true,
:jasmine_config => 'spec/javascripts/support/jasmine.yml'
}
@process_options = lambda { |*args|
opt, arg = args.flatten[0..1]
case opt
when '--colors', '-c'
options[:colors] = true
when '--no-colors', '-nc'
options[:colors] = false
when '--keep', '-k'
options[:remove_html_file] = false
when '--jasmine-config', '-j'
options[:jasmine_config] = arg
end
}
read_defaults_file if defaults_file?
opts.each(&@process_options)
@spec_filter = ARGV.dup
data = YAML.load_file(options[:jasmine_config])
if !File.file?(File.join(gem_dir, RUNNER))
puts "The Qt WebKit widget is not compiled! Try re-installing this gem."
exit 1
end
puts "Running Jasmine specs..."
files = %w{jasmine jasmine-html}.collect { |name| File.join(Jasmine.root, "lib/#{name}.js") }
files << File.join(gem_dir, 'jasmine/jasmine.headless-reporter.js')
files += [ [ 'src_files', 'src_dir' ], [ 'stylesheets', 'src_dir' ], [ 'helpers', 'spec_dir' ], [ 'spec_files', 'spec_dir' ] ].collect do |searches, root|
data[searches] ||= DEFAULTS[searches]
data[root] ||= DEFAULTS[root]
if data[searches]
data[searches].collect do |search|
path = search
path = File.join(data[root], path) if data[root]
files = Dir[path]
if searches == 'spec_files'
files = files.find_all { |file| use_spec?(file) }
end
files
end
end
end
files = files.flatten.compact.collect { |file|
case File.extname(file)
when '.js'
%{<script type="text/javascript" src="#{file}"></script>}
when '.coffee'
begin
%{<script type="text/javascript">#{CoffeeScript.compile(fh = File.open(file))}</script>}
rescue CoffeeScript::CompilationError => e
puts "[%s] %s: %s" % [ 'coffeescript'.color(:red), file.color(:yellow), e.message.color(:white) ]
exit 1
ensure
fh.close
end
when '.css'
%{<link rel="stylesheet" href="#{file}" type="text/css" />}
end
}
output = jasmine_html_template(files)
File.open(target = "specrunner.#{$$}.html", 'w') { |fh| fh.print output }
system %{#{File.join(gem_dir, RUNNER)} #{options[:colors] ? '-c' : ''} #{target}}
status = $?.exitstatus
FileUtils.rm_f target if options[:remove_html_file] || (status == 0)
exit status

View File

@ -1,18 +0,0 @@
require 'coffee-script'
FILE = 'jasmine/jasmine.headless-reporter.coffee' if !self.class.const_defined?(:FILE)
TARGET = FILE.gsub('.coffee', '.js') if !self.class.const_defined?(:TARGET)
watch(FILE) { coffee }
def coffee
begin
File.open(TARGET, 'w') { |fh| fh.print CoffeeScript.compile File.open(FILE) }
puts "Wrote #{TARGET}"
rescue Exception => e
puts e.message
end
end
coffee

2
config/cucumber.yml Normal file
View File

@ -0,0 +1,2 @@
default: -r features

View File

@ -0,0 +1,5 @@
build:
true
install:
true

View File

@ -0,0 +1,15 @@
#include <QtGui>
#include <QtWebKit>
#include <iostream>
#include "Page.h"
Page::Page() : QWebPage() {}
void Page::javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID) {
emit handleError(message, lineNumber, sourceID);
}
void Page::javaScriptAlert(QWebFrame *, const QString &) {}
bool Page::javaScriptConfirm(QWebFrame *, const QString &) { return false; }
bool Page::javaScriptPrompt(QWebFrame *, const QString &, const QString &, QString *) { return false; }

View File

@ -0,0 +1,20 @@
#ifndef JHW_PAGE
#define JHW_PAGE
#include <QtGui>
#include <QtWebKit>
class Page: public QWebPage {
Q_OBJECT
public:
Page();
protected:
void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID);
void javaScriptAlert(QWebFrame *, const QString &);
bool javaScriptConfirm(QWebFrame *, const QString &);
bool javaScriptPrompt(QWebFrame *, const QString &, const QString &, QString *);
signals:
void handleError(const QString & message, int lineNumber, const QString & sourceID);
};
#endif

View File

@ -0,0 +1,208 @@
#include <QtGui>
#include <QtWebKit>
#include <QFile>
#include <QTextStream>
#include <iostream>
#include <sstream>
#include <QQueue>
#include "Runner.h"
#include "Page.h"
using namespace std;
Runner::Runner() : QObject()
, runs(0)
, hasErrors(false)
, _hasSpecFailure(false)
, usedConsole(false)
, isFinished(false)
, useColors(false)
, quiet(false)
{
page.settings()->enablePersistentStorage();
ticker.setInterval(TIMER_TICK);
connect(&ticker, SIGNAL(timeout()), this, SLOT(timerEvent()));
connect(&page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool)));
connect(&page, SIGNAL(handleError(const QString &, int, const QString &)), this, SLOT(handleError(const QString &, int, const QString &)));
connect(page.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJHW()));
}
void Runner::addFile(const QString &spec) {
runnerFiles.enqueue(spec);
}
void Runner::go() {
ticker.stop();
page.setPreferredContentsSize(QSize(1024, 600));
addJHW();
loadSpec();
}
void Runner::addJHW() {
page.mainFrame()->addToJavaScriptWindowObject("JHW", this);
}
void Runner::handleError(const QString &message, int lineNumber, const QString &sourceID) {
QString messageEscaped = QString(message);
QString sourceIDEscaped = QString(sourceID);
messageEscaped.replace(QString("\""), QString("\\\""));
sourceIDEscaped.replace(QString("\""), QString("\\\""));
std::stringstream ss;
ss << lineNumber;
QString command("JHW._handleError(\"" + messageEscaped + "\", " + QString(ss.str().c_str()) + ", \"" + sourceIDEscaped + "\"); false;");
page.mainFrame()->evaluateJavaScript(command);
hasErrors = true;
}
void Runner::loadSpec()
{
QVectorIterator<QString> iterator(reportFiles);
while (iterator.hasNext()) {
QFile *outputFile = new QFile(iterator.next());
outputFile->open(QIODevice::WriteOnly);
outputFiles.enqueue(outputFile);
}
QString runnerFile = runnerFiles.dequeue();
page.mainFrame()->load(runnerFile);
ticker.start();
}
void Runner::watch(bool ok) {
if (!ok) {
std::cerr << "Can't load " << qPrintable(page.mainFrame()->url().toString()) << ", the file may be broken." << std::endl;
std::cerr << "Out of curiosity, did your tests try to submit a form and you haven't prevented that?" << std::endl;
std::cerr << "Try running your tests in your browser with the Jasmine server and see what happens." << std::endl;
QApplication::instance()->exit(1);
return;
}
page.mainFrame()->evaluateJavaScript(QString("JHW._setColors(") + (useColors ? QString("true") : QString("false")) + QString("); false;"));
}
void Runner::setColors(bool colors) {
useColors = colors;
}
void Runner::hasUsedConsole() {
usedConsole = true;
}
void Runner::hasError() {
hasErrors = true;
}
void Runner::hasSpecFailure() {
_hasSpecFailure = true;
}
void Runner::setReportFiles(QStack<QString> &files) {
reportFiles = files;
}
void Runner::timerPause() {
ticker.stop();
}
void Runner::timerDone() {
ticker.start();
}
void Runner::ping() {
runs = 0;
}
void Runner::setSeed(QString s) {
seed = s;
}
void Runner::setQuiet(bool q) {
quiet = q;
}
QString Runner::getSeed() {
return seed;
}
bool Runner::isQuiet() {
return quiet;
}
void Runner::print(const QString &fh, const QString &content) {
if (fh == "stdout") {
std::cout << qPrintable(content);
std::cout.flush();
}
if (fh == "stderr") {
std::cerr << qPrintable(content);
std::cerr.flush();
}
if (fh.contains("report")) {
int index = (int)fh.split(":").last().toUInt();
QTextStream ts(outputFiles.at(index));
ts << qPrintable(content);
ts.flush();
}
}
void Runner::finishSuite() {
isFinished = true;
runs = 0;
}
void Runner::timerEvent() {
++runs;
if (hasErrors && runs > 2)
QApplication::instance()->exit(1);
if (isFinished && runs > 2) {
while (!outputFiles.isEmpty()) {
outputFiles.dequeue()->close();
}
int exitCode = 0;
if (_hasSpecFailure || hasErrors) {
exitCode = 1;
} else {
if (usedConsole) {
exitCode = 2;
}
}
bool runAgain = true;
if (runnerFiles.count() == 0) {
runAgain = false;
} else {
if (exitCode == 1) {
runAgain = false;
}
}
if (runAgain) {
isFinished = false;
loadSpec();
} else {
QApplication::instance()->exit(exitCode);
}
}
if (runs > MAX_LOOPS) {
std::cerr << "WARNING: too many runs and the test is still not finished!" << std::endl;
QApplication::instance()->exit(1);
}
}

View File

@ -0,0 +1,73 @@
#ifndef JHW_RUNNER
#define JHW_RUNNER
#include <QtGui>
#include <QtWebKit>
#include <QFile>
#include <QTextStream>
#include <iostream>
#include <fstream>
#include <sstream>
#include <QQueue>
#include <QApplication>
#include "Page.h"
using namespace std;
class Runner: public QObject {
Q_OBJECT
public:
enum { TIMER_TICK = 200, MAX_LOOPS = 50 };
Runner();
void setColors(bool colors);
void setReportFiles(QStack<QString> &files);
void setSeed(QString s);
void setQuiet(bool q);
void addFile(const QString &spec);
void go();
public slots:
void timerPause();
void timerDone();
void hasUsedConsole();
void hasError();
void hasSpecFailure();
bool isQuiet();
QString getSeed();
void print(const QString &fh, const QString &content);
void finishSuite();
void ping();
private slots:
void watch(bool ok);
void addJHW();
void timerEvent();
void handleError(const QString & message, int lineNumber, const QString & sourceID);
private:
Page page;
QTimer ticker;
int runs;
bool hasErrors;
bool _hasSpecFailure;
bool usedConsole;
bool isFinished;
bool useColors;
bool quiet;
QString seed;
QQueue<QString> runnerFiles;
QStack<QString> reportFiles;
void loadSpec();
QQueue<QFile *> outputFiles;
};
#endif

View File

@ -0,0 +1,8 @@
TEMPLATE = app
CONFIG -= app_bundle
QMAKE_INFO_PLIST = Info.plist
QT += network webkit
SOURCES = Page.cpp Runner.cpp
HEADERS = Page.h Runner.h

View File

@ -1,2 +1,10 @@
system %{qmake -spec macx-g++} require 'fileutils'
system %{make}
$: << File.expand_path("../../../lib", __FILE__)
require 'qt/qmake'
system %{make clean}
Qt::Qmake.make!('jasmine-headless-webkit', 'specrunner.pro')
FileUtils.cp File.expand_path('../Makefile.dummy', __FILE__), File.expand_path('../Makefile', __FILE__)

View File

@ -1,320 +1,83 @@
/* /*
Copyright (c) 2010 Sencha Inc. Copyright (c) 2010 Sencha Inc.
Copyright (c) 2011 John Bintz Copyright (c) 2011 John Bintz
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
*/ */
#include <QtGui> #include "Runner.h"
#include <QtWebKit>
#include <iostream> #if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)
#include <getopt.h>
#endif
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) #if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
#error Use Qt 4.7 or later version #error Use Qt 4.7 or later version
#endif #endif
class HeadlessSpecRunnerPage: public QWebPage
{
Q_OBJECT
signals:
void consoleLog(const QString &msg, int lineNumber, const QString &sourceID);
void internalLog(const QString &note, const QString &msg);
protected:
void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID);
bool javaScriptConfirm(QWebFrame *frame, const QString &msg);
void javaScriptAlert(QWebFrame *frame, const QString &msg);
};
void HeadlessSpecRunnerPage::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID)
{
emit consoleLog(message, lineNumber, sourceID);
}
bool HeadlessSpecRunnerPage::javaScriptConfirm(QWebFrame *frame, const QString &msg)
{
emit internalLog("TODO", "jasmine-headless-webkit can't handle confirm() yet! You should mock window.confirm for now. Returning true.");
return true;
}
void HeadlessSpecRunnerPage::javaScriptAlert(QWebFrame *frame, const QString &msg)
{
emit internalLog("alert", msg);
}
class HeadlessSpecRunner: public QObject
{
Q_OBJECT
public:
HeadlessSpecRunner();
void load(const QString &spec);
void setColors(bool colors);
public slots:
void log(const QString &msg);
void specPassed();
void specFailed();
void printName(const QString &name);
void printResult(const QString &result);
void finishSuite(const QString &duration, const QString &total, const QString& failed);
private slots:
void watch(bool ok);
void errorLog(const QString &msg, int lineNumber, const QString &sourceID);
void internalLog(const QString &note, const QString &msg);
protected:
bool hasElement(const char *select);
void timerEvent(QTimerEvent *event);
private:
HeadlessSpecRunnerPage m_page;
QBasicTimer m_ticker;
int m_runs;
bool hasErrors;
bool usedConsole;
bool showColors;
bool isFinished;
bool didFail;
bool consoleNotUsedThisRun;
void red();
void green();
void yellow();
void clear();
};
HeadlessSpecRunner::HeadlessSpecRunner()
: QObject()
, m_runs(0)
, hasErrors(false)
, usedConsole(false)
, showColors(false)
, isFinished(false)
, didFail(false)
, consoleNotUsedThisRun(false)
{
m_page.settings()->enablePersistentStorage();
connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool)));
connect(&m_page, SIGNAL(consoleLog(QString, int, QString)), this, SLOT(errorLog(QString, int, QString)));
connect(&m_page, SIGNAL(internalLog(QString, QString)), this, SLOT(internalLog(QString, QString)));
}
void HeadlessSpecRunner::load(const QString &spec)
{
m_ticker.stop();
m_page.mainFrame()->addToJavaScriptWindowObject("JHW", this);
m_page.mainFrame()->load(spec);
m_page.setPreferredContentsSize(QSize(1024, 600));
}
void HeadlessSpecRunner::watch(bool ok)
{
if (!ok) {
std::cerr << "Can't load " << qPrintable(m_page.mainFrame()->url().toString()) << ", the file may be broken." << std::endl;
std::cerr << "Out of curiosity, did your tests try to submit a form and you haven't prevented that?" << std::endl;
std::cerr << "Try running your tests in your browser with the Jasmine server and see what happens." << std::endl;
QApplication::instance()->exit(1);
return;
}
m_ticker.start(200, this);
}
bool HeadlessSpecRunner::hasElement(const char *select)
{
return !m_page.mainFrame()->findFirstElement(select).isNull();
}
void HeadlessSpecRunner::setColors(bool colors)
{
showColors = colors;
}
void HeadlessSpecRunner::red()
{
if (showColors) std::cout << "\033[0;31m";
}
void HeadlessSpecRunner::green()
{
if (showColors) std::cout << "\033[0;32m";
}
void HeadlessSpecRunner::yellow()
{
if (showColors) std::cout << "\033[0;33m";
}
void HeadlessSpecRunner::clear()
{
if (showColors) std::cout << "\033[m";
}
void HeadlessSpecRunner::specPassed()
{
consoleNotUsedThisRun = true;
green();
std::cout << '.';
clear();
fflush(stdout);
}
void HeadlessSpecRunner::specFailed()
{
consoleNotUsedThisRun = true;
didFail = true;
red();
std::cout << 'F';
clear();
fflush(stdout);
}
void HeadlessSpecRunner::errorLog(const QString &msg, int lineNumber, const QString &sourceID)
{
red();
std::cout << "[error] ";
clear();
std::cout << qPrintable(sourceID) << ":" << lineNumber << " : " << qPrintable(msg);
std::cout << std::endl;
hasErrors = true;
m_runs = 0;
m_ticker.start(200, this);
}
void HeadlessSpecRunner::internalLog(const QString &note, const QString &msg) {
red();
std::cout << "[" << qPrintable(note) << "] ";
clear();
std::cout << qPrintable(msg);
std::cout << std::endl;
}
void HeadlessSpecRunner::log(const QString &msg)
{
usedConsole = true;
green();
if (consoleNotUsedThisRun) {
std::cout << std::endl;
consoleNotUsedThisRun = false;
}
std::cout << "[console] ";
clear();
std::cout << qPrintable(msg);
std::cout << std::endl;
}
void HeadlessSpecRunner::printName(const QString &name)
{
std::cout << std::endl << std::endl;
red();
std::cout << qPrintable(name) << std::endl;
clear();
}
void HeadlessSpecRunner::printResult(const QString &result)
{
red();
std::cout << " " << qPrintable(result) << std::endl;
clear();
}
void HeadlessSpecRunner::finishSuite(const QString &duration, const QString &total, const QString& failed)
{
std::cout << std::endl;
if (didFail) {
red();
std::cout << "FAIL: ";
} else {
green();
std::cout << "PASS: ";
}
std::cout << qPrintable(total) << " tests, " << qPrintable(failed) << " failures, " << qPrintable(duration) << " secs.";
clear();
std::cout << std::endl;
isFinished = true;
}
void HeadlessSpecRunner::timerEvent(QTimerEvent *event)
{
++m_runs;
if (event->timerId() != m_ticker.timerId())
return;
if (hasErrors && m_runs > 2)
QApplication::instance()->exit(1);
if (!hasErrors) {
if (isFinished) {
int exitCode = 0;
if (didFail) {
exitCode = 1;
} else {
if (usedConsole) {
exitCode = 2;
}
}
QApplication::instance()->exit(exitCode);
}
if (m_runs > 30) {
std::cout << "WARNING: too many runs and the test is still not finished!" << std::endl;
QApplication::instance()->exit(1);
}
}
}
#include "specrunner.moc"
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
bool showColors = false; bool showColors = false;
char *filename = NULL; bool isQuiet = false;
QString seed;
QStack<QString> reporterFiles;
int c, index; int c, index;
while ((c = getopt(argc, argv, "c")) != -1) { while ((c = getopt(argc, argv, "cr:s:q")) != -1) {
switch(c) { switch(c) {
case 'c': case 'c':
showColors = true; showColors = true;
break; break;
} case 'q':
isQuiet = true;
break;
case 'r':
reporterFiles.push(QString(optarg));
break;
case 's':
seed = QString(optarg);
break;
} }
}
bool filenameFound = false; if (optind == argc) {
std::cerr << "Run Jasmine's SpecRunner headlessly" << std::endl << std::endl;
std::cerr << " specrunner [-c] [-s seed] [-r report file ...] specrunner.html ..." << std::endl;
return 1;
}
for (index = optind; index < argc; index++) { QApplication app(argc, argv);
filename = argv[index]; app.setApplicationName("jasmine-headless-webkit");
filenameFound = true; Runner runner;
}
if (!filenameFound) { runner.setColors(showColors);
std::cerr << "Run Jasmine's SpecRunner headlessly" << std::endl << std::endl; runner.setQuiet(isQuiet);
std::cerr << " specrunner [-c] SpecRunner.html" << std::endl; runner.setReportFiles(reporterFiles);
return 1; runner.setSeed(seed);
}
QApplication app(argc, argv); for (index = optind; index < argc; index++) {
runner.addFile(QString::fromLocal8Bit(argv[index]));
}
HeadlessSpecRunner runner; runner.go();
runner.setColors(showColors);
runner.load(QString::fromLocal8Bit(filename)); return app.exec();
return app.exec();
} }

View File

@ -1,7 +1,5 @@
TEMPLATE = app include(common.pri)
CONFIG -= app_bundle
SOURCES += specrunner.cpp
TARGET = jasmine-webkit-specrunner TARGET = jasmine-webkit-specrunner
SOURCES = specrunner.cpp
QT += network webkit
QMAKE_INFO_PLIST = Info.plist
QMAKESPEC = macx-gcc

View File

@ -0,0 +1,7 @@
Feature: Bin - Failure
Scenario: Run a failing test
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/failure/failure.yml -f File:spec/report.txt`
Then the exit status should be 1
And the report file "spec/report.txt" should have 1 total, 1 failure, no console usage

View File

@ -0,0 +1,7 @@
Feature: Bin - Files
Scenario: List the files a test suite will use
Given I have a test suite
When I run `bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml -l`
Then the exit status should be 0
And the output should include "spec/jasmine/success/success.js"
And the output should include "spec/jasmine/success/success_spec.js"

View File

@ -0,0 +1,18 @@
Feature: Bin - Filtered Run - Both Runs
Background:
Given there is no existing "spec/report.txt" file
Scenario: Run one and fail
When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_failure/filtered_failure.yml -f File:spec/report.txt ./spec/jasmine/filtered_failure/failure_spec.js`
Then the exit status should be 1
And the report file "spec/report.txt" should have 1 total, 1 failure, no console usage
Scenario: Run both and succeed
When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml -f File:spec/report.txt ./spec/jasmine/filtered_success/success_one_spec.js`
Then the exit status should be 0
And the report file "spec/report.txt" should have 2 total, 0 failures, no console usage
Scenario: Run both with console.log
When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_success_with_console/filtered_success.yml -f File:spec/report.txt ./spec/jasmine/filtered_success_with_console/success_one_spec.js`
Then the exit status should be 2
And the report file "spec/report.txt" should have 2 total, 0 failures, yes console usage

View File

@ -0,0 +1,14 @@
Feature: Bin - No Full Run
Background:
Given there is no existing "spec/report.txt" file
Scenario: Only run the filtered run
When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml -f File:spec/report.txt --no-full-run ./spec/jasmine/filtered_success/success_one_spec.js`
Then the exit status should be 0
And the report file "spec/report.txt" should have 1 total, 0 failure, no console usage
Scenario: Use a file outside of the normal test run
When I run `bin/jasmine-headless-webkit -j spec/jasmine/filtered_success/filtered_success.yml -f File:spec/report.txt ./spec/jasmine/filtered_success/success_other_file.js`
Then the exit status should be 0
And the report file "spec/report.txt" should have 1 total, 0 failure, no console usage

View File

@ -0,0 +1,7 @@
Feature: Bin - Help
Scenario: Display the Help
Given I have a test suite
When I run `bin/jasmine-headless-webkit -h`
Then I should get help output
And the exit status should be 0

View File

@ -0,0 +1,8 @@
Feature: Bin - Quiet Messages
Scenario: Run a test that would cause a lot of messages to be displayed and silence them all
Given I have a test suite
When I run `bin/jasmine-headless-webkit -q -j spec/jasmine/noisy/noisy.yml`
Then the exit status should be 0
And the output should not include "[Skipping File]"
And the output should not include "You should mock"

View File

@ -0,0 +1,8 @@
Feature: Bin - Runner Out
Scenario: Write out the runner to a specified file
Given I have a test suite
When I run `bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml --runner-out spec/runner.html`
Then the exit status should be 0
And the file "spec/runner.html" should contain a JHW runner
When I delete the file "spec/runner.html"

View File

@ -0,0 +1,7 @@
Feature: Bin - Two spec files with same basename
Scenario: Run both files
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/two_spec_files_same_basename/jasmine.yml -f File:spec/report.txt`
Then the exit status should be 0
And the report file "spec/report.txt" should have 2 total, 0 failures, no console usage

View File

@ -0,0 +1,20 @@
Feature: Bin - Success
Scenario: Run a successful test with long format definition
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit --seed 1234 -j spec/jasmine/success/success.yml --format File --out spec/report.txt`
Then the exit status should be 0
And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage
And the report file "spec/report.txt" should have seed 1234
Scenario: Run a successful test with legacy file reporting
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml --report spec/report.txt`
Then the exit status should be 0
And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage
Scenario: Run a successful test with shortened format definition
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/success/success.yml -f File:spec/report.txt`
Then the exit status should be 0
And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage

View File

@ -0,0 +1,5 @@
Feature: Bin - Success with JS Error
Scenario: Succeed
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/success_with_error/success_with_error.yml -f File:spec/report.txt`
Then the exit status should be 1

View File

@ -0,0 +1,7 @@
Feature: Bin - Try to Leave Page
Scenario: Fail on trying to leave the page
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/leave_page/leave_page.yml -f File:spec/report.txt`
Then the exit status should be 1
And the report file "spec/report.txt" should exist

View File

@ -0,0 +1,7 @@
Feature: Bin - Try to Click A Button
Scenario: Don't leave page when clicking a button
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/click_button/click_button.yml -f File:spec/report.txt`
Then the exit status should be 0
And the report file "spec/report.txt" should have 0 total, 0 failures, no console usage

View File

@ -0,0 +1,11 @@
Feature: Two files from source files
Scenario: Files are ordered directly
Given I have a test suite
When I run `bin/jasmine-headless-webkit -j spec/jasmine/two_files_from_src_files/jasmine.yml -l`
Then the exit status should be 0
And the following files should be loaded in order:
| vendor/vendor-file.js |
| vendor/vendor.js |
| app/app-file.js |
| app/app.js |

View File

@ -0,0 +1,7 @@
Feature: Bin - With CoffeeScript error
Scenario: Fail on CoffeeScript error
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/coffeescript_error/coffeescript_error.yml -f File:spec/report.txt`
Then the exit status should be 1
And the report file "spec/report.txt" should not exist

View File

@ -0,0 +1,7 @@
Feature: Use console.log
Scenario: Run a successful test that uses console.log
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit -j spec/jasmine/console_log/console_log.yml -f File:spec/report.txt`
Then the exit status should be 2
And the report file "spec/report.txt" should have 1 total, 0 failures, yes console usage

View File

@ -0,0 +1,7 @@
Feature: Bin - With Server
Scenario: Run using an HTTP server
Given there is no existing "spec/report.txt" file
When I run `bin/jasmine-headless-webkit --use-server -j spec/jasmine/success/success.yml -f File:spec/report.txt`
Then the exit status should be 0
And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage

View File

@ -0,0 +1,7 @@
Feature: Bin - With window.prompt()
Scenario: Alert the user that window.prompt() needs to be stubbed
Given I have a test suite
When I run `bin/jasmine-headless-webkit -j spec/jasmine/window_prompt/window_prompt.yml`
Then the exit status should be 0
And the output should include "You should mock window.prompt"

View File

@ -0,0 +1,24 @@
Feature: Reporters
In order to allow for multiple types of output
I should be able to
Manage reporters and decide which ones to use
Scenario: Use default reporters
Given I have the default runner options
When I get a runner
And I get a template writer
Then the template should use the "Console" reporter to "stdout"
And the command to run the runner should not include a report file
Scenario: Use a file reporter
Given I have the default runner options
And I have the following reporters:
| Name | File |
| Console | |
| File | file |
When I get a runner
And I get a template writer
Then the template should use the "Console" reporter to "stdout"
And the template should use the "File" reporter to "report:0"
And the command to run the runner should include the report file "file"

34
features/runner.feature Normal file
View File

@ -0,0 +1,34 @@
Feature: Using the Runner directly
Scenario: Succeed
Given I have the following runner options:
"""
:jasmine_config: spec/jasmine/success/success.yml
:reporters:
- [ 'File', 'spec/report.txt' ]
"""
When I get a runner
And I run the runner
Then the runner should have an exit status of 0
And the report file "spec/report.txt" should have 1 total, 0 failures, no console usage
Scenario: JavaScript Error
Given I have the following runner options:
"""
:jasmine_config: spec/jasmine/success_with_error/success_with_error.yml
"""
When I get a runner
And I run the runner
Then the runner should have an exit status of 1
Scenario: Failure
Given I have the following runner options:
"""
:jasmine_config: spec/jasmine/failure/failure.yml
:reporters:
- [ 'File', 'spec/report.txt' ]
"""
When I get a runner
And I run the runner
Then the runner should have an exit status of 1
And the report file "spec/report.txt" should have 1 total, 1 failure, no console usage

View File

@ -0,0 +1,2 @@
Given /^I have a test suite$/ do
end

View File

@ -0,0 +1,4 @@
Given /^there is no existing "([^"]*)" file$/ do |file|
FileUtils.rm_rf file
end

View File

@ -0,0 +1,4 @@
Given /^I have the default runner options$/ do
@options = Jasmine::Headless::Options.new
end

View File

@ -0,0 +1,10 @@
Given /^I have the following reporters:$/ do |table|
@options[:reporters] = []
table.hashes.each do |hash|
reporter = [ hash['Name'] ]
reporter << hash['File'] if !hash['File'].empty?
@options[:reporters] << reporter
end
end

View File

@ -0,0 +1,3 @@
Given /^I have the following runner options:$/ do |string|
@options = YAML.load(string)
end

View File

@ -0,0 +1,3 @@
Then /^the exit status should be (\d+)$/ do |exitstatus|
$?.exitstatus.should == exitstatus.to_i
end

View File

@ -0,0 +1,4 @@
Then /^the file "([^"]*)" should contain a JHW runner$/ do |file|
File.read(file).should include('jasmine.HeadlessReporter')
end

View File

@ -0,0 +1,10 @@
Then /^the following files should be loaded in order:$/ do |table|
files = table.raw.flatten
@output.lines.collect(&:strip).each do |line|
files.shift if line[files.first]
end
files.should be_empty
end

View File

@ -0,0 +1,4 @@
Then /^I should get help output$/ do
@output.should include("Usage:")
end

View File

@ -0,0 +1,3 @@
Then /^the output should include "([^"]*)"$/ do |string|
@output.should include(string)
end

View File

@ -0,0 +1,4 @@
Then /^the output should not include "([^"]*)"$/ do |string|
@output.should_not include(string)
end

View File

@ -0,0 +1,4 @@
Then /^the report file "([^"]*)" should not exist$/ do |file|
File.file?(file).should be_false
end

View File

@ -0,0 +1,3 @@
Then /^the report file "([^"]*)" should exist$/ do |file|
File.file?(file).should be_true
end

View File

@ -0,0 +1,7 @@
Then /^the report file "(.*)" should have (\d+) total, (\d+) failures?, (no|yes) console usage$/ do |file, total, failures, console_usage|
report = Jasmine::Headless::Report.load(file)
report.total.should == total.to_i
report.failed.should == failures.to_i
report.has_used_console?.should == (console_usage == 'yes')
end

View File

@ -0,0 +1,4 @@
Then /^the report file "([^"]*)" should have seed (\d+)$/ do |file, seed|
report = Jasmine::Headless::Report.load(file)
report.seed.should == seed.to_i
end

View File

@ -0,0 +1,3 @@
Then /^the runner should have an exit status of (\d+)$/ do |exit_status|
@result.should == exit_status.to_i
end

View File

@ -0,0 +1,4 @@
Then /^the command to run the runner should include the report file "([^"]*)"$/ do |file|
@runner.jasmine_command.should include("-r #{file}")
end

View File

@ -0,0 +1,3 @@
Then /^the command to run the runner should not include a report file$/ do
@runner.jasmine_command.should_not include('-r')
end

View File

@ -0,0 +1,6 @@
Then /^the template should use the "([^"]*)" reporter to "([^"]*)"$/ do |reporter, target|
output = @template_writer.render
output.should include(%{jasmine.HeadlessReporter.#{reporter}("#{target}")})
end

View File

@ -0,0 +1,3 @@
When /^I delete the file "([^"]*)"$/ do |file|
FileUtils.rm_f(file)
end

View File

@ -0,0 +1,4 @@
When /^I get a runner$/ do
@runner = Jasmine::Headless::Runner.new(@options)
end

View File

@ -0,0 +1,4 @@
When /^I get a template writer$/ do
@template_writer = Jasmine::Headless::TemplateWriter.new(@runner)
end

View File

@ -0,0 +1,4 @@
When /^I run `(.*)`$/ do |command|
@output = `#{command}`
end

View File

@ -0,0 +1,4 @@
When /^I run the runner$/ do
@result = @runner.run
end

7
features/support/env.rb Normal file
View File

@ -0,0 +1,7 @@
require 'jasmine-headless-webkit'
After do
FileUtils.rm_f 'spec/report.txt'
FileUtils.rm_f 'spec/runner.html'
end

View File

@ -1,10 +1,10 @@
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__) $:.push File.expand_path("../lib", __FILE__)
require "jasmine-headless-webkit/version" require "jasmine/headless/version"
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = "jasmine-headless-webkit" s.name = "jasmine-headless-webkit"
s.version = Jasmine::Headless::Webkit::VERSION s.version = Jasmine::Headless::VERSION
s.platform = Gem::Platform::RUBY s.platform = Gem::Platform::RUBY
s.authors = ["John Bintz", "Sencha Inc.", "Pivotal Labs"] s.authors = ["John Bintz", "Sencha Inc.", "Pivotal Labs"]
s.email = ["john@coswellproductions.com"] s.email = ["john@coswellproductions.com"]
@ -20,7 +20,11 @@ Gem::Specification.new do |s|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"] s.require_paths = ["lib"]
s.add_dependency 'jasmine' s.add_runtime_dependency 'jasmine-core'
s.add_dependency 'coffee-script' s.add_runtime_dependency 'coffee-script'
s.add_dependency 'rainbow' s.add_runtime_dependency 'rainbow'
s.add_runtime_dependency 'multi_json', '>= 1.2.0'
s.add_runtime_dependency 'sprockets'
s.add_runtime_dependency 'sprockets-vendor_gems'
end end

View File

@ -1,43 +0,0 @@
if !jasmine?
throw new Exception("jasmine not laoded!")
class HeadlessReporterResult
constructor: (name) ->
@name = name
@results = []
addResult: (message) ->
@results.push(message)
print: ->
JHW.printName(@name)
for result in @results
do (result) =>
JHW.printResult(result)
class jasmine.HeadlessReporter
constructor: ->
@results = []
@failedCount = 0
@length = 0
reportRunnerResults: (runner) ->
for result in @results
do (result) =>
result.print()
JHW.finishSuite((new Date() - @startTime) / 1000.0, @length, @failedCount)
reportRunnerStarting: (runner) ->
@startTime = new Date()
reportSpecResults: (spec) ->
if spec.results().passed()
JHW.specPassed()
else
JHW.specFailed()
failureResult = new HeadlessReporterResult(spec.getFullName())
for result in spec.results().getItems()
do (result) =>
if result.type == 'expect' and !result.passed_
@failedCount += 1
failureResult.addResult(result.message)
@results.push(failureResult)
reportSpecStarting: (spec) ->
reportSuiteResults: (suite) ->
@length += suite.specs().length

View File

@ -1,78 +0,0 @@
(function() {
var HeadlessReporterResult;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
if (!(typeof jasmine !== "undefined" && jasmine !== null)) {
throw new Exception("jasmine not laoded!");
}
HeadlessReporterResult = (function() {
function HeadlessReporterResult(name) {
this.name = name;
this.results = [];
}
HeadlessReporterResult.prototype.addResult = function(message) {
return this.results.push(message);
};
HeadlessReporterResult.prototype.print = function() {
var result, _i, _len, _ref, _results;
JHW.printName(this.name);
_ref = this.results;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
result = _ref[_i];
_results.push(__bind(function(result) {
return JHW.printResult(result);
}, this)(result));
}
return _results;
};
return HeadlessReporterResult;
})();
jasmine.HeadlessReporter = (function() {
function HeadlessReporter() {
this.results = [];
this.failedCount = 0;
this.length = 0;
}
HeadlessReporter.prototype.reportRunnerResults = function(runner) {
var result, _fn, _i, _len, _ref;
_ref = this.results;
_fn = __bind(function(result) {
return result.print();
}, this);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
result = _ref[_i];
_fn(result);
}
return JHW.finishSuite((new Date() - this.startTime) / 1000.0, this.length, this.failedCount);
};
HeadlessReporter.prototype.reportRunnerStarting = function(runner) {
return this.startTime = new Date();
};
HeadlessReporter.prototype.reportSpecResults = function(spec) {
var failureResult, result, _fn, _i, _len, _ref;
if (spec.results().passed()) {
return JHW.specPassed();
} else {
JHW.specFailed();
failureResult = new HeadlessReporterResult(spec.getFullName());
_ref = spec.results().getItems();
_fn = __bind(function(result) {
if (result.type === 'expect' && !result.passed_) {
this.failedCount += 1;
return failureResult.addResult(result.message);
}
}, this);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
result = _ref[_i];
_fn(result);
}
return this.results.push(failureResult);
}
};
HeadlessReporter.prototype.reportSpecStarting = function(spec) {};
HeadlessReporter.prototype.reportSuiteResults = function(suite) {
return this.length += suite.specs().length;
};
return HeadlessReporter;
})();
}).call(this);

View File

@ -1,7 +1,3 @@
module Jasmine require 'jasmine/headless'
module Headless require 'jasmine/headless/railtie' if defined?(Rails) && Rails::VERSION::MAJOR >= 3
module Webkit
# Your code goes here...
end
end
end

View File

@ -1,7 +0,0 @@
module Jasmine
module Headless
module Webkit
VERSION = "0.2.0"
end
end
end

View File

@ -1,55 +0,0 @@
module Jasmine
module CLI
DEFAULTS = {
'spec_files' => [ '**/*[sS]pec.js' ],
'helpers' => [ 'helpers/**/*.js' ],
'spec_dir' => 'spec/javascripts',
'src_dir' => nil,
'stylesheets' => [],
'src_files' => []
}
RUNNER = 'ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner'
DEFAULTS_FILE = '.jasmine-headless-webkit'
def process_jasmine_config(overrides = {})
DEFAULTS.merge(overrides)
end
def read_defaults_file
File.readlines(DEFAULTS_FILE).collect { |line| line.strip.split(' ', 2) }.each(&@process_options)
end
def defaults_file?
File.file?(DEFAULTS_FILE)
end
def use_spec?(file)
@spec_filter.empty? || @spec_filter.include?(file)
end
def jasmine_html_template(files)
<<-HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jasmine Test Runner</title>
<script type="text/javascript">
window.console = { log: function(data) { JHW.log(JSON.stringify(data)); } };
</script>
#{files.join("\n")}
</head>
<body>
<script type="text/javascript">
jasmine.getEnv().addReporter(new jasmine.HeadlessReporter());
jasmine.getEnv().execute();
</script>
</body>
</html>
HTML
end
end
end

61
lib/jasmine/headless.rb Normal file
View File

@ -0,0 +1,61 @@
require 'pathname'
module Jasmine
module Headless
EXCLUDED_FORMATS = %w{less sass scss erb str}
autoload :CommandLine, 'jasmine/headless/command_line'
autoload :CoffeeScriptCache, 'jasmine/headless/coffee_script_cache'
autoload :SpecFileAnalyzer, 'jasmine/headless/spec_file_analyzer'
autoload :CacheableAction, 'jasmine/headless/cacheable_action'
autoload :VERSION, 'jasmine/headless/version'
autoload :Runner, 'jasmine/headless/runner'
autoload :Options, 'jasmine/headless/options'
autoload :Task, 'jasmine/headless/task'
autoload :FilesList, 'jasmine/headless/files_list'
autoload :UniqueAssetList, 'jasmine/headless/unique_asset_list'
autoload :TemplateWriter, 'jasmine/headless/template_writer'
autoload :FileChecker, 'jasmine/headless/file_checker'
autoload :CoffeeTemplate, 'jasmine/headless/coffee_template'
autoload :JSTemplate, 'jasmine/headless/js_template'
autoload :JSTTemplate, 'jasmine/headless/jst_template'
autoload :CSSTemplate, 'jasmine/headless/css_template'
autoload :NilTemplate, 'jasmine/headless/nil_template'
autoload :Report, 'jasmine/headless/report'
autoload :ReportMessage, 'jasmine/headless/report_message'
class << self
def root
@root ||= Pathname(File.expand_path('../../..', __FILE__))
end
def warn(message)
output.puts message if show_warnings?
end
def show_warnings=(show)
@show_warnings = show
end
def show_warnings?
@show_warnings = true if @show_warnings.nil?
@show_warnings
end
def output
$stdout
end
end
end
end
require 'jasmine/headless/errors'

View File

@ -0,0 +1,85 @@
module Jasmine::Headless
class CacheableAction
class << self
def enabled=(bool)
@enabled = bool
end
def enabled?
@enabled = true if @enabled == nil
@enabled
end
def cache_type
raise ArgumentError.new("No cache type defined for #{self.name}") if @cache_type == nil
@cache_type
end
def cache_type=(type)
@cache_type = type
end
def cache_dir=(dir)
@cache_dir = dir
end
def cache_dir
@cache_dir ||= '.jhw-cache'
end
def for(file)
new(file).handle
end
end
attr_reader :file
def initialize(file)
@file = file
end
def handle
if CacheableAction.enabled?
if fresh?
unserialize(File.read(cache_file))
else
result = action
FileUtils.mkdir_p File.split(cache_file).first
File.open(cache_file, 'wb') { |fh| fh.print serialize(result) }
result
end
else
action
end
end
def cache_file
@cache_file ||= File.expand_path(relative_cache_file) + '.js'
end
def relative_cache_file
File.join(self.class.cache_dir, self.class.cache_type, file.gsub(Dir.pwd + '/', ''))
end
def fresh?
cached? && (File.mtime(file) < File.mtime(cache_file))
end
def cached?
File.exist?(cache_file)
end
def action
raise StandardError.new("Override action")
end
def serialize(data)
data
end
def unserialize(data)
data
end
end
end

View File

@ -0,0 +1,20 @@
require 'coffee_script'
require 'digest/sha1'
require 'fileutils'
module Jasmine
module Headless
class CoffeeScriptCache < CacheableAction
class << self
def cache_type
"coffee_script"
end
end
def action
CoffeeScript.compile(File.read(file))
end
end
end
end

View File

@ -0,0 +1,36 @@
require 'tilt/template'
require 'rainbow'
module Jasmine::Headless
class CoffeeTemplate < Tilt::Template
include Jasmine::Headless::FileChecker
self.default_mime_type = 'application/javascript'
def prepare ; end
def evaluate(scope, locals, &block)
if bad_format?(file)
alert_bad_format(file)
return ''
end
begin
cache = Jasmine::Headless::CoffeeScriptCache.new(file)
source = cache.handle
if cache.cached?
%{<script type="text/javascript" src="#{cache.cache_file}"></script>
<script type="text/javascript">window.CSTF['#{File.split(cache.cache_file).last}'] = '#{file}';</script>}
else
%{<script type="text/javascript">#{source}</script>}
end
rescue CoffeeScript::CompilationError => ne
puts "[%s] %s: %s" % [ 'coffeescript'.color(:red), file.color(:yellow), "#{ne.message}".color(:white) ]
raise ne
rescue StandardError => e
puts "[%s] Error in compiling file: %s" % [ 'coffeescript'.color(:red), file.color(:yellow) ]
raise e
end
end
end
end

View File

@ -0,0 +1,31 @@
module Jasmine::Headless
class CommandLine
class << self
def run!
require 'coffee-script'
require 'rainbow'
begin
options = Options.from_command_line
runner = Runner.new(options)
if options[:do_list]
FilesList.reset!
files_list = FilesList.new(:config => runner.jasmine_config)
files_list.files.each { |file| puts file }
else
exit runner.run
end
rescue CoffeeScript::CompilationError
exit 1
rescue StandardError => e
$stderr.puts "[%s] %s (%s)" % [ "jasmine-headless-webkit".color(:red), e.message.color(:white), e.class.name.color(:yellow) ]
$stderr.puts e.backtrace.collect { |line| " #{line}" }.join("\n")
exit 1
end
end
end
end
end

View File

@ -0,0 +1,19 @@
require 'tilt/template'
module Jasmine::Headless
class CSSTemplate < Tilt::Template
include Jasmine::Headless::FileChecker
self.default_mime_type = 'text/css'
def prepare ; end
def evaluate(scope, locals, &block)
if bad_format?(file)
alert_bad_format(file)
return ''
end
file ? %{<link rel="stylesheet" href="#{file}" type="text/css" />} : data
end
end
end

View File

@ -0,0 +1,16 @@
module Jasmine
module Headless
class NoRunnerError < StandardError
def message
"The jasmine-headless-webkit specrunner (jasmine-webkit-specrunner) could not be found! Try reinstalling the gem."
end
end
class TestFailure < StandardError; end
class ConsoleLogUsage < StandardError ; end
class JasmineConfigNotFound < Errno::ENOENT ; end
class InvalidReport < StandardError ; end
end
end

View File

@ -0,0 +1,25 @@
module Jasmine::Headless::FileChecker
def excluded_formats
::Jasmine::Headless::EXCLUDED_FORMATS
end
def bad_format?(file)
return if file.nil?
excluded_formats.any? do |format|
file[%r{\.#{format}(\.|$)}]
end
end
def alert_bad_format(file)
Jasmine::Headless.warn("[%s] %s: %s" % [ 'Skipping File'.color(:red), file.color(:yellow), "unsupported format".color(:white) ])
end
def alert_if_bad_format?(file)
if result = bad_format?(file)
alert_bad_format(file)
end
result
end
end

View File

@ -0,0 +1,332 @@
require 'jasmine-core'
require 'time'
require 'multi_json'
require 'set'
require 'sprockets'
require 'sprockets/engines'
require 'sprockets-vendor_gems'
module Jasmine::Headless
class FilesList
include FileChecker
class << self
def asset_paths
@asset_paths ||= Sprockets.find_gem_vendor_paths(:for => 'javascripts')
end
def reset!
@asset_paths = nil
@registered_engines = {}
# register haml-sprockets and handlebars_assets if it's available...
%w{haml-sprockets handlebars_assets}.each do |library|
begin
require library
rescue LoadError
end
end
if ENV['JHW_ENV']
begin
require 'bundler'
Bundler.require(ENV['JHW_ENV'].to_sym)
rescue LoadError
end
end
@sprockets_environment = nil
end
def registered_engines
@registered_engines ||= {}
end
def register_engine(file_extension, template_class)
registered_engines[file_extension] = template_class
end
def register_engines!
registered_engines.each do |file_extension, template_class|
Sprockets.register_engine file_extension, template_class
end
end
def default_files
%w{jasmine.js jasmine-html jasmine.css jasmine-extensions
intense headless_reporter_result jasmine.HeadlessReporter
jasmine.HeadlessReporter.ConsoleBase
jsDump beautify-html}
end
def extension_filter
extensions = (%w{.js .css} + Sprockets.engine_extensions)
%r{(#{extensions.join('|')})$}
end
end
PLEASE_WAIT_IM_WORKING_TIME = 2
attr_reader :options, :required_files, :potential_files_to_filter
def initialize(options = {})
@options = options
Kernel.srand(options[:seed]) if options[:seed]
@required_files = UniqueAssetList.new
@potential_files_to_filter = []
register_engines!
load_initial_assets
use_config if config?
end
def register_engines!
begin
require spec_helper
rescue LoadError
end
self.class.register_engines!
end
def load_initial_assets
self.class.default_files.each do |file|
begin
add_path(file)
rescue InvalidUniqueAsset => e
raise StandardError.new("Not an asset: #{file}")
end
end
(options[:reporters] || []).each do |reporter, identifier, file|
add_path("jasmine.HeadlessReporter.#{reporter}")
end
end
def files
required_files.flatten.collect { |asset| asset.pathname.to_s }.uniq
end
def spec_files
filter_for_requested_specs(
files.find_all { |file| spec_dir.any? { |dir| file[dir] } }
)
end
def filtered_files
filter_for_requested_specs(files)
end
def search_paths
return @search_paths if @search_paths
@search_paths = [ Jasmine::Core.path, Jasmine::Headless.root.join('vendor/assets/javascripts').to_s ]
@search_paths += self.class.asset_paths
@search_paths += src_dir.collect { |dir| File.expand_path(dir) }
@search_paths += asset_paths.collect { |dir| File.expand_path(dir) }
@search_paths += spec_dir.collect { |dir| File.expand_path(dir) }
@search_paths.uniq!
@search_paths
end
def sprockets_environment
return @sprockets_environment if @sprockets_environment
@sprockets_environment = Sprockets::Environment.new
search_paths.each { |path| @sprockets_environment.append_path(path) }
@sprockets_environment.unregister_postprocessor('application/javascript', Sprockets::SafetyColons)
# ...and unregister ones we don't want/need
@sprockets_environment.instance_eval do
EXCLUDED_FORMATS.each do |extension|
register_engine ".#{extension}", Jasmine::Headless::NilTemplate
end
register_engine '.coffee', Jasmine::Headless::CoffeeTemplate
register_engine '.js', Jasmine::Headless::JSTemplate
register_engine '.css', Jasmine::Headless::CSSTemplate
register_engine '.jst', Jasmine::Headless::JSTTemplate
end
@sprockets_environment
end
def has_spec_outside_scope?
if is_outside_scope = !spec_filter.empty?
is_outside_scope = spec_dir.any? do |dir|
spec_file_searches.any? do |search|
!spec_files.any? do |file|
target = File.join(dir, search)
File.fnmatch?(target, file) || File.fnmatch?(target.gsub(%{^**/}, ''), file)
end
end
end
end
is_outside_scope
end
def filtered?
files != filtered_files
end
def files_to_html
to_html(files)
end
def filtered_files_to_html
to_html(filtered_files)
end
def spec_file_line_numbers
@spec_file_line_numbers ||= Hash[spec_files.collect { |file|
if File.exist?(file)
if !(lines = Jasmine::Headless::SpecFileAnalyzer.for(file)).empty?
[ file, lines ]
end
else
nil
end
}.compact]
end
private
def to_html(files)
alert_time = Time.now + PLEASE_WAIT_IM_WORKING_TIME
files.collect do |file|
if alert_time && alert_time < Time.now
puts "Rebuilding cache, please wait..."
alert_time = nil
end
sprockets_environment.find_asset(file, :bundle => false).body
end.compact.reject(&:empty?)
end
def spec_filter
@spec_filter ||= (@options[:only] && @options[:only].collect { |path| expanded_dir(path) }.flatten) || []
end
SEARCH_ROOTS = {
'src_files' => 'src_dir',
'stylesheets' => 'src_dir',
'helpers' => 'spec_dir',
'spec_files' => 'spec_dir'
}
def use_config
@config = @options[:config].dup
@searches = {}
@potential_files_to_filter = []
%w{src_files stylesheets helpers spec_files}.each do |type|
if data = @config[type]
add_files(@searches[type] = data.flatten, type, send(SEARCH_ROOTS[type]))
end
end
end
def add_files(patterns, type, dirs)
patterns.each do |pattern|
dirs.collect { |dir| expanded_dir(File.join(dir, pattern)) }.each do |files|
files.sort! { |a, b| Kernel.rand(3) - 1 } if type == 'spec_files'
files.each do |path|
add_path(path, type)
end
end
end
if type == 'spec_files'
spec_filter.each { |path| add_path(path, type) }
end
end
def config?
@options[:config]
end
def expanded_dir(path)
file_list = Dir.glob(path).sort
file_list.find_all { |file|
file[extension_filter] && !alert_if_bad_format?(file)
}.collect {
|file| File.expand_path(file)
}.find_all {
|path| File.file?(path)
}
end
def extension_filter
self.class.extension_filter
end
def add_path(path, type = nil)
asset = sprockets_environment.find_asset(path)
@required_files << asset
if type == 'spec_files'
@potential_files_to_filter << path
end
end
def src_dir
@src_dir ||= config_dir_or_pwd('src_dir') + asset_paths
end
def spec_dir
@spec_dir ||= config_dir_or_pwd('spec_dir')
end
def asset_paths
@asset_paths ||= config_dir('asset_paths')
end
def spec_file_searches
@searches['spec_files']
end
def config_dir_or_pwd(dir)
if (found = config_dir(dir)).empty?
found = [ Dir.pwd ]
end
found
end
def config_dir(dir)
[ @options[:config] && @options[:config][dir] ].flatten.compact.collect { |dir| File.expand_path(dir) }
end
def filter_for_requested_specs(files)
files.find_all do |file|
if potential_files_to_filter.include?(file)
spec_filter.empty? || spec_filter.any? { |pattern| File.fnmatch?(pattern, file) }
else
true
end
end
end
def spec_helper
File.join(spec_dir, "helpers", "spec_helper")
end
end
end
module Jasmine::Headless
extend self
def register_engine(file_extension, template_class)
Jasmine::Headless::FilesList.register_engine(file_extension, template_class)
end
end

View File

@ -0,0 +1,23 @@
require 'tilt/template'
module Jasmine::Headless
class JSTemplate < Tilt::Template
include Jasmine::Headless::FileChecker
self.default_mime_type = 'application/javascript'
def prepare ; end
def evaluate(scope, locals, &block)
if bad_format?(file)
alert_bad_format(file)
return ''
end
if data[%r{^<script type="text/javascript"}]
data
else
file ? %{<script type="text/javascript" src="#{file}"></script>} : data
end
end
end
end

View File

@ -0,0 +1,15 @@
require 'sprockets/jst_processor'
module Jasmine::Headless
class JSTTemplate < Sprockets::JstProcessor
include Jasmine::Headless::FileChecker
def evaluate(*args)
if bad_format?(file)
alert_bad_format(file)
return ''
end
%{<script type="text/javascript">#{super}</script>}
end
end
end

View File

@ -0,0 +1,14 @@
require 'tilt/template'
require 'rainbow'
module Jasmine::Headless
class NilTemplate < Tilt::Template
def prepare ; end
def evaluate(scope, locals, &block)
return ''
end
end
end

View File

@ -0,0 +1,206 @@
require 'forwardable'
require 'getoptlong'
module Jasmine
module Headless
class Options
extend Forwardable
def_delegators :@options, :[], :[]=
DEFAULT_OPTIONS = {
:colors => false,
:remove_html_file => true,
:runner_output_filename => false,
:jasmine_config => 'spec/javascripts/support/jasmine.yml',
:do_list => false,
:full_run => true,
:enable_cache => true,
:files => [],
:reporters => [ [ 'Console' ] ],
:quiet => false,
:use_server => false,
:server_port => nil
}
DEFAULTS_FILE = File.join(Dir.pwd, '.jasmine-headless-webkit')
GLOBAL_DEFAULTS_FILE = File.expand_path('~/.jasmine-headless-webkit')
REPORT_DEPRECATED_MESSAGE = "--report is deprecated. Use --format HeadlessFileReporter --out <filename>"
def self.from_command_line
options = new
options.process_command_line_args
options[:files] = ARGV
options
end
def initialize(opts = {})
@options = DEFAULT_OPTIONS.dup
srand
@options[:seed] = rand(10000)
read_defaults_files
opts.each { |k, v| @options[k] = v if v }
end
def process_option(*args)
opt, arg = args.flatten[0..1]
case opt
when '--colors', '-c'
@options[:colors] = true
when '--no-colors', '-nc'
@options[:colors] = false
when '--cache'
@options[:enable_cache] = true
when '--no-cache'
@options[:enable_cache] = false
when '--keep'
@options[:remove_html_file] = false
when '--report'
warn REPORT_DEPRECATED_MESSAGE
add_reporter('File', arg)
add_reporter('Console')
when '--runner-out'
@options[:runner_output_filename] = arg
when '--jasmine-config', '-j'
@options[:jasmine_config] = arg
when '--no-full-run'
@options[:full_run] = false
when '--list', '-l'
@options[:do_list] = true
when '--quiet', '-q'
@options[:quiet] = true
when '--seed'
@options[:seed] = arg.to_i
when '--format', '-f'
add_reporter(arg)
when '--use-server'
@options[:use_server] = true
when '--server-port'
@options[:server_port] = arg.to_i
when '--out'
add_reporter_file(arg)
when '-h', '--help'
print_help
exit
end
end
def read_defaults_files
[ GLOBAL_DEFAULTS_FILE, DEFAULTS_FILE ].each do |file|
if File.file?(file)
File.readlines(file).collect { |line| line.strip.split(' ', 2) }.each { |*args| process_option(*args) }
end
end
end
def process_command_line_args
command_line_args = GetoptLong.new(
[ '--colors', '-c', GetoptLong::NO_ARGUMENT ],
[ '--no-colors', GetoptLong::NO_ARGUMENT ],
[ '--cache', GetoptLong::NO_ARGUMENT ],
[ '--no-cache', GetoptLong::NO_ARGUMENT ],
[ '--keep', GetoptLong::NO_ARGUMENT ],
[ '--runner-out', GetoptLong::REQUIRED_ARGUMENT ],
[ '--report', GetoptLong::REQUIRED_ARGUMENT ],
[ '--jasmine-config', '-j', GetoptLong::REQUIRED_ARGUMENT ],
[ '--no-full-run', GetoptLong::NO_ARGUMENT ],
[ '--list', '-l', GetoptLong::NO_ARGUMENT ],
[ '--seed', GetoptLong::REQUIRED_ARGUMENT ],
[ '--format', '-f', GetoptLong::REQUIRED_ARGUMENT ],
[ '--out', GetoptLong::REQUIRED_ARGUMENT ],
[ '--use-server', GetoptLong::NO_ARGUMENT ],
[ '--server-port', GetoptLong::REQUIRED_ARGUMENT ],
[ '-h', '--help', GetoptLong::NO_ARGUMENT ],
[ '-q', '--quiet', GetoptLong::NO_ARGUMENT ]
)
command_line_args.each { |*args| process_option(*args) }
end
def reporters
file_index = 0
@options[:reporters].collect do |reporter, file|
output = [ reporter ]
if file
output << "report:#{file_index}"
output << file
file_index += 1
else
output << "stdout"
end
output
end
end
def file_reporters
reporters.find_all { |reporter| reporter[1]["report:"] }
end
private
def add_reporter(name, file = nil)
if !@added_reporter
@options[:reporters] = []
@added_reporter = true
end
if (parts = name.split(':')).length == 2
name, file = parts
end
@options[:reporters] << [ name ]
add_reporter_file(file) if file
end
def add_reporter_file(file)
@options[:reporters].last << file
end
def print_help
options = [
[ '-c, --colors', 'Enable colors (default: disabled)' ],
[ '-nc, --no-colors', 'Disable colors' ],
[ '--cache', 'Enable cache (default: enabled)' ],
[ '--no-cache', 'Disable cache' ],
[ '--keep', 'Keep runner files on failure' ],
[ '--runner-out <filename>', 'Write runner to specified filename' ],
[ '-j, --jasmine-config <config file>', 'Jasmine Yaml config to use' ],
[ '--no-full-run', 'Do not perform a full spec run after a successful targeted spec run' ],
[ '--use-server', 'Load tests from an HTTP server instead of from filesystem' ],
[ '-l, --list', 'List files in the order they will be required' ],
[ '--seed <seed>', 'Random order seed for spec file ordering' ],
[ '-f, --format <reporter<:filename>>', 'Specify an output reporter and possibly output filename' ],
[ '--out <filename>', 'Specify output filename for last defined reporter' ],
[ '-q, --quiet', "Silence most non-test related warnings" ],
[ '-h, --help', "You're looking at it" ]
]
longest_length = options.collect(&:first).collect(&:length).max
puts <<-HELP
Usage: #{$0} [ options ] [ spec files ]
Options:
#{options.collect { |option, description| " #{option.ljust(longest_length)} #{description}" }.join("\n")}
Available reporters:
Console Write out spec results to the console in a progress format (default)
Verbose Write out spec results to the console in a verbose format
File Write spec results in jasmine-headless-webkit ReportFile format
Tap Write spec results in TAP format
Add reporters to the jasmine.HeadlessReporter object to access them
(ex: jasmine.HeadlessReporter.Teamcity for the Teamcity reporter)
HELP
end
end
end
end

View File

@ -0,0 +1,12 @@
module Jasmine
module Headless
class Railtie < Rails::Railtie
rake_tasks do
Jasmine::Headless::Task.new do |t|
t.colors = true
end
end
end
end
end

View File

@ -0,0 +1,81 @@
require 'forwardable'
module Jasmine::Headless
class Report
extend Forwardable
def_delegators :report, :length, :[]
def_delegators :last_total, :total, :failed, :time
class << self
def load(file)
new(file).process
end
end
attr_reader :file, :report
def initialize(file)
@file = file
end
def process
last_message = nil
@report = File.readlines(file).collect do |line|
type, *parts = line.split('||', -1)
if !(report_klass = report_class_for(type))
if last_message.kind_of?(Jasmine::Headless::ReportMessage::Console)
last_message.message << "\n"
last_message.message << line.strip
end
else
parts.last.strip!
last_message = report_klass.new_from_parts(parts)
end
end
self
end
def has_used_console?
@report.any? { |entry| entry.kind_of?(Jasmine::Headless::ReportMessage::Console) }
end
def has_failed_on?(statement)
@report.any? { |entry|
if entry.kind_of?(Jasmine::Headless::ReportMessage::Fail)
entry.statement == statement
end
}
end
def valid?
last_total != nil
end
def failed_files
@report.find_all { |entry|
entry.kind_of?(Jasmine::Headless::ReportMessage::Fail)
}.collect(&:filename).uniq.compact
end
def seed
if seed = report.find { |entry| entry.respond_to?(:seed) }
seed.seed
end
end
private
def last_total
@report.reverse.find { |entry| entry.respond_to?(:total) }
end
def report_class_for(type)
if constant = ReportMessage.constants.find { |k| k.to_s.downcase == type.downcase }
ReportMessage.const_get(constant)
end
end
end
end

View File

@ -0,0 +1,12 @@
module Jasmine::Headless
module ReportMessage
autoload :Spec, 'jasmine/headless/report_message/spec'
autoload :Pass, 'jasmine/headless/report_message/pass'
autoload :Fail, 'jasmine/headless/report_message/fail'
autoload :Console, 'jasmine/headless/report_message/console'
autoload :Error, 'jasmine/headless/report_message/error'
autoload :Total, 'jasmine/headless/report_message/total'
autoload :Seed, 'jasmine/headless/report_message/seed'
end
end

View File

@ -0,0 +1,18 @@
module Jasmine::Headless::ReportMessage
class Console
def self.new_from_parts(parts)
new(parts.first)
end
attr_reader :message
def initialize(message)
@message = message
end
def ==(other)
self.message == other.message
end
end
end

View File

@ -0,0 +1,20 @@
module Jasmine::Headless::ReportMessage
class Error
class << self
def new_from_parts(parts)
new(*parts)
end
end
attr_reader :message, :file_info
def initialize(message, file_info)
@message, @file_info = message, file_info
end
def ==(other)
self.message == other.message && self.file_info == other.file_info
end
end
end

View File

@ -0,0 +1,5 @@
module Jasmine::Headless::ReportMessage
class Fail < Spec
end
end

View File

@ -0,0 +1,5 @@
module Jasmine::Headless::ReportMessage
class Pass < Spec
end
end

View File

@ -0,0 +1,14 @@
module Jasmine::Headless::ReportMessage
class Seed
def self.new_from_parts(parts)
new(parts.first)
end
attr_reader :seed
def initialize(seed)
@seed = seed.to_i
end
end
end

View File

@ -0,0 +1,28 @@
module Jasmine::Headless::ReportMessage
class Spec
def self.new_from_parts(parts)
file_info = parts.pop
new(parts.join(' '), file_info)
end
attr_reader :statement, :file_info
def initialize(statement, file_info)
@statement, @file_info = statement, file_info
end
def ==(other)
self.statement == other.statement && self.file_info == other.file_info
end
def filename
if name = file_info.split(":").first
name
else
nil
end
end
end
end

View File

@ -0,0 +1,31 @@
module Jasmine::Headless::ReportMessage
class Total
class << self
def new_from_parts(parts)
new(*parts)
end
end
attr_reader :total, :failed, :time, :has_js_error
def initialize(total, failed, time, has_js_error)
@total, @failed, @time = total.to_i, failed.to_i, time.to_f
@has_js_error = case has_js_error
when String
has_js_error == "T"
else
has_js_error
end
end
def ==(other)
other &&
self.total == other.total &&
self.failed == other.failed &&
self.time == other.time &&
self.has_js_error == other.has_js_error
end
end
end

View File

@ -0,0 +1,261 @@
require 'fileutils'
require 'coffee-script'
require 'rainbow'
require 'yaml'
require 'erb'
require 'sprockets'
module Jasmine
module Headless
class IndexHandler
class << self
attr_accessor :index
end
def initialize(app)
@app = app
end
def call(env)
if env['PATH_INFO'] == '/'
return [ 302, { 'Location' => self.class.index }, [ 'Redirecting...' ] ]
end
@app.call(env)
end
end
class Runner
JASMINE_DEFAULTS = {
'spec_files' => [ '**/*[sS]pec.js' ],
'helpers' => [ 'helpers/**/*.js' ],
'spec_dir' => 'spec/javascripts',
'src_dir' => nil,
'stylesheets' => [],
'src_files' => [],
'backtrace' => []
}
RUNNER_DIR = File.expand_path('../../../../ext/jasmine-webkit-specrunner', __FILE__)
RUNNER = File.join(RUNNER_DIR, 'jasmine-webkit-specrunner')
attr_reader :options
def self.run(options = {})
new(options).run
end
def self.server_port
return @server_port if @server_port
require 'socket'
count = 100
begin
port = select_server_port
socket = TCPSocket.new(server_interface, port)
socket.close
count -= 1
raise "Could not create server port after 100 attempts!" if count == 0
rescue Errno::ECONNREFUSED
@server_port = port
break
ensure
begin
socket.close if socket
rescue IOError
end
end while true
@server_port
end
def self.server_port=(port)
@server_port = port
end
def self.select_server_port
21000 + rand(10000)
end
def self.server_interface
'127.0.0.1'
end
def self.server_uri
"http://#{server_interface}:#{server_port}"
end
def self.server_spec_path
self.server_uri + '/__JHW__/'
end
def self.ensure_server(options)
return if @server
require 'webrick'
require 'thread'
require 'rack'
require 'net/http'
port = server_port
@server = Thread.new do
Jasmine::Headless.warn "Powering up!"
app = Rack::Builder.new do
use IndexHandler
map '/__JHW__' do
run Rack::File.new(Dir.pwd)
end
map '/' do
run Rack::File.new('/')
end
end
Rack::Handler::WEBrick.run(
app,
:Port => port,
:Logger => Logger.new(StringIO.new),
:AccessLog => [
[ StringIO.new, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
[ StringIO.new, WEBrick::AccessLog::REFERER_LOG_FORMAT ]
]
)
end
while true do
begin
Net::HTTP.get(URI(server_uri))
break
rescue Errno::ECONNREFUSED => e
end
sleep 0.1
end
end
def initialize(options)
options = Options.new(options) if !options.kind_of?(Options)
@options = options
end
def template_writer
@template_writer ||= TemplateWriter.new(self)
end
def jasmine_config
return @jasmine_config if @jasmine_config
@jasmine_config = JASMINE_DEFAULTS.dup
jasmine_config_data.each do |key, value|
@jasmine_config[key] = value if value
end
@jasmine_config
end
def jasmine_command(*targets)
command = [ RUNNER ]
command << "-s #{options[:seed]}"
command << '-c' if options[:colors]
command << '-q' if options[:quiet]
options.file_reporters.each do |reporter, identifier, file|
command << "-r #{file}"
end
command += targets
command.compact.join(' ')
end
def run
Jasmine::Headless::CacheableAction.enabled = @options[:enable_cache]
Jasmine::Headless.show_warnings = !@options[:quiet]
FilesList.reset!
self.class.server_port = options[:server_port]
@_targets = template_writer.write
run_targets = absolute_run_targets(@_targets.dup)
if run_targets.length == 2
if (!@options[:full_run] && files_list.filtered?) || files_list.has_spec_outside_scope?
run_targets.pop
end
end
runner = lambda { system jasmine_command(run_targets) }
if options[:use_server]
wrap_in_server(run_targets, &runner)
else
runner.call
end
@_status = $?.exitstatus
ensure
if @_targets && !runner_filename && (@options[:remove_html_file] || (@_status == 0))
@_targets.each { |target| FileUtils.rm_f target }
end
end
def absolute_run_targets(targets)
targets.flatten.collect do |target|
if options[:use_server]
target = self.class.server_spec_path + target
else
target = "file://" + File.expand_path(target)
end
target
end
end
def runner_filename
options[:runner_output_filename] || begin
if (runner_output = jasmine_config['runner_output']) && !runner_output.empty?
runner_output
else
false
end
end
end
def files_list
@files_list ||= Jasmine::Headless::FilesList.new(
:config => jasmine_config,
:only => options[:files],
:seed => options[:seed],
:reporters => options.reporters
)
end
def wrap_in_server(run_targets)
self.class.ensure_server(options)
IndexHandler.index = run_targets.last
Jasmine::Headless.warn "HTTP powered specs! Located at #{run_targets.join(' ')}"
yield
end
private
def jasmine_config_data
raise JasmineConfigNotFound.new("Jasmine config not found. I tried #{@options[:jasmine_config]}.") if !File.file?(@options[:jasmine_config])
YAML.load(ERB.new(File.read(@options[:jasmine_config])).result(binding))
end
end
end
end

View File

@ -0,0 +1,44 @@
require 'multi_json'
module Jasmine::Headless
class SpecFileAnalyzer < CacheableAction
class << self
def cache_type
"spec_file_analysis"
end
end
def action
line_numbers = {}
data = File.read(file)
if data.respond_to?(:encode)
data.encode!('US-ASCII', 'UTF-8', :invalid => :replace, :undef => :replace)
else
require 'iconv'
ic = Iconv.new('UTF-8//IGNORE', 'US-ASCII')
data = ic.iconv(File.read(file) + ' ')[0..-2]
end
data.force_encoding('US-ASCII') if data.respond_to?(:force_encoding)
data.lines.each_with_index.each { |line, index|
if description = line[%r{(describe|context|it)[( ]*(["'])(.*)\2}, 3]
(line_numbers[description] ||= []) << (index + 1)
end
}
line_numbers
end
def serialize(data)
MultiJson.dump(data)
end
def unserialize(data)
MultiJson.load(data)
end
end
end

View File

@ -0,0 +1,34 @@
module Jasmine
module Headless
class Task
include Rake::DSL if defined?(Rake::DSL)
attr_accessor :colors, :keep_on_error, :jasmine_config
def initialize(name = 'jasmine:headless')
@colors = false
@keep_on_error = false
@jasmine_config = nil
yield self if block_given?
desc 'Run Jasmine specs headlessly'
task(name) { run_rake_task }
end
private
def run_rake_task
case Jasmine::Headless::Runner.run(
:colors => colors,
:remove_html_file => !@keep_on_error,
:jasmine_config => @jasmine_config
)
when 1
raise Jasmine::Headless::TestFailure
when 2
raise Jasmine::Headless::ConsoleLogUsage
end
end
end
end
end

View File

@ -0,0 +1,65 @@
require 'multi_json'
require 'erb'
require 'tempfile'
require 'forwardable'
module Jasmine::Headless
class TemplateWriter
attr_reader :runner
extend Forwardable
def_delegators :runner, :files_list, :options
def_delegators :options, :reporters
def initialize(runner)
@runner = runner
end
def write
output = [
[ all_tests_filename, files_list.files_to_html ]
]
output.unshift([filtered_tests_filename, files_list.filtered_files_to_html ]) if files_list.filtered?
output.each do |name, files|
template = template_for(files)
File.open(name, 'wb') { |fh| fh.print template }
end
output.collect(&:first)
end
def all_tests_filename
runner.runner_filename || "jhw.#{$$}.html"
end
def filtered_tests_filename
all_tests_filename.gsub(%r{\.html$}, '.filter.html')
end
def render
template_for(all_files)
end
def all_files
files_list.files_to_html
end
def jhw_reporters
reporters.collect do |reporter, output|
%{jasmine.getEnv().addReporter(new jasmine.HeadlessReporter.#{reporter}("#{output}"));}
end.join("\n")
end
private
def template_for(files)
spec_lines = files_list.spec_file_line_numbers
ERB.new(Jasmine::Headless.root.join('skel/template.html.erb').read).result(binding)
end
end
end

View File

@ -0,0 +1,16 @@
module Jasmine::Headless
class UniqueAssetList < ::Array
def <<(asset)
raise InvalidUniqueAsset.new("Not an asset: #{asset.inspect}") if !asset.respond_to?(:logical_path)
super if !self.any? { |other| asset.pathname == other.pathname }
end
def flatten
self.collect(&:to_a).flatten
end
end
class InvalidUniqueAsset < StandardError ; end
end

View File

@ -0,0 +1,5 @@
module Jasmine
module Headless
VERSION = "0.9.0.rc.2"
end
end

155
lib/qt/qmake.rb Normal file
View File

@ -0,0 +1,155 @@
require 'rbconfig'
require 'rubygems'
require 'rubygems/version'
module Qt
class NotInstalledError < StandardError; end
class Qmake
class << self
QMAKES = %w{qmake-qt4 qmake}
def installed?
path != nil
end
def make_installed?
make_path != nil
end
def command(project_file = nil)
spec = (case platform
when :linux
"linux-g++"
when :freebsd
"freebsd-g++"
when :mac_os_x
"macx-g++"
end)
command = "#{path} #{envs} -spec #{spec}"
command << " #{project_file}" if project_file
command
end
def make!(name, project_file = nil)
@name = name
check_make!
check_qmake!
system command(project_file)
system %{make}
end
#
# We need integration tests for these!
#
def path
@path ||= best_qmake
end
def make_path
get_exe_path('gmake') || get_exe_path('make')
end
def platform
case RbConfig::CONFIG['host_os']
when /linux/
:linux
when /freebsd/i
:freebsd
when /darwin/
:mac_os_x
end
end
def qt_version_of(qmake_path)
Gem::Version.new(%x{#{qmake_path} -v}.lines.to_a[1][%r{Using Qt version ([^ ]+) },1])
end
def best_qmake
if qmake_path = QMAKES.collect do |path|
result = nil
if qmake_path = get_exe_path(path)
if (qt_version = qt_version_of(qmake_path)) >= Gem::Version.create('4.7')
result = [ qmake_path, qt_version ]
end
end
result
end.compact.sort { |a, b| b.last <=> a.last }.first
qmake_path.first
else
nil
end
end
private
def envs
%w{QMAKE_CC QMAKE_CXX}.collect do |env|
if ENV[env]
"#{env}=#{ENV[env]}"
end
end.compact.join(" ")
end
def get_exe_path(command)
path = %x{which #{command}}.strip
path = nil if path == ''
path
end
def check_make!
if !make_installed?
install_method = (
case platform
when :linux
%{sudo apt-get install make or sudo yum install make}
when :freebsd
%{install /usr/ports/devel/gmake}
when :mac_os_x
%{Install XCode, and/or sudo port install make}
end
)
$stderr.puts <<-MSG
make is not installed. You'll need to install it to build #{@name}.
#{install_method} should do it for you.
MSG
raise NotInstalledError
end
end
def check_qmake!
if !installed?
install_method = (
case platform
when :linux
<<-MSG
sudo apt-get install libqt4-dev qt4-qmake on Debian-based systems, or downloading
Nokia's prebuilt binary at http://qt.nokia.com/downloads/
MSG
when :freebsd
<<-MSG
Install /usr/ports/www/qt4-webkit and /usr/ports/devel/qmake4.
MSG
MSG
when :mac_os_x
<<-MSG
sudo port install qt4-mac (for the patient) or downloading Nokia's pre-built binary
at http://qt.nokia.com/downloads/
MSG
end
).strip
$stderr.puts <<-MSG
qmake is not installed or is not the right version (#{@name} needs Qt 4.7 or above).
You'll need to install it to build #{@name}.
#{install_method} should do it for you.
MSG
end
end
end
end
end

11
script/gemfile Executable file
View File

@ -0,0 +1,11 @@
#!/usr/bin/env ruby
require 'rubygems'
require 'penchant'
if Penchant::Gemfile.do_full_env_switch!(ARGV[0])
puts "Gemfile switched to #{ARGV[0]}"
else
exit 0
end

Some files were not shown because too many files have changed in this diff Show More