From c3ec22b326e64ebb1fb9b7a7b592a021bbb954d9 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Tue, 10 Apr 2012 16:40:53 -0400 Subject: [PATCH] first stab at docs --- Guardfile | 6 +- _config.yml | 2 + _layouts/default.html | 14 +++ _layouts/haml/default.haml | 0 _layouts/haml/default.html.haml | 11 ++ config/compass.rb | 3 + index.md | 209 ++++++++++++++++++++++++++++++-- sass/screen.scss | 76 ++++++++++++ stylesheets/screen.css | 82 +++++++++++++ stylesheets/syntax.css | 60 +++++++++ stylesheets/vim.css | 69 +++++++++++ 11 files changed, 522 insertions(+), 10 deletions(-) create mode 100644 _layouts/default.html delete mode 100644 _layouts/haml/default.haml create mode 100644 _layouts/haml/default.html.haml create mode 100644 config/compass.rb create mode 100644 stylesheets/syntax.css create mode 100644 stylesheets/vim.css diff --git a/Guardfile b/Guardfile index 185f83e..3cb3c20 100644 --- a/Guardfile +++ b/Guardfile @@ -2,10 +2,10 @@ # More info at https://github.com/guard/guard#readme -guard 'compass' do - watch('^sass/(.*)\.s[ac]ss') +guard 'compass', :configuration_file => 'config/compass.rb' do + watch(%r{^sass/(.*)\.s[ac]ss$}) end -guard 'haml' do +guard 'haml', :input => '_layouts/haml', :output => '_layouts' do watch(/^.+(\.html\.haml)/) end diff --git a/_config.yml b/_config.yml index 1385d61..3d2e540 100644 --- a/_config.yml +++ b/_config.yml @@ -1,2 +1,4 @@ markdown: redcarpet +auto: true +pygments: true diff --git a/_layouts/default.html b/_layouts/default.html new file mode 100644 index 0000000..e0ebbc6 --- /dev/null +++ b/_layouts/default.html @@ -0,0 +1,14 @@ + + + Flowerbox + + + + + + +
+ {{ content }} +
+ + diff --git a/_layouts/haml/default.haml b/_layouts/haml/default.haml deleted file mode 100644 index e69de29..0000000 diff --git a/_layouts/haml/default.html.haml b/_layouts/haml/default.html.haml new file mode 100644 index 0000000..ca0277b --- /dev/null +++ b/_layouts/haml/default.html.haml @@ -0,0 +1,11 @@ +%html + %head + %title Flowerbox + %link{:href => 'http://fonts.googleapis.com/css?family=Pontano+Sans', :rel => :stylesheet, :type => 'text/css'}/ + %link{:href => 'http://fonts.googleapis.com/css?family=Gorditas', :rel => :stylesheet, :type => 'text/css'}/ + %link{:rel => :stylesheet, :href => 'stylesheets/screen.css', :type => 'text/css'}/ + %link{:rel => :stylesheet, :href => 'stylesheets/syntax.css', :type => 'text/css'}/ + %body + #container + {{ content }} + diff --git a/config/compass.rb b/config/compass.rb new file mode 100644 index 0000000..9a90d90 --- /dev/null +++ b/config/compass.rb @@ -0,0 +1,3 @@ +css_dir = 'stylesheets' +sass_dir = 'sass' + diff --git a/index.md b/index.md index 3c2d01b..7f6c655 100644 --- a/index.md +++ b/index.md @@ -1,11 +1,12 @@ --- -title: Flowerbox -- a multi-environment, multi-runner JavaScript testing framework framework. +title: Flowerbox -- a multi-environment, multi-runner, super-easy JavaScript testing framework framework. layout: default --- # Flowerbox -## A multi-environment, multi-runner JavaScript testing framework framework. - -## Super-fast unit testing getting started +## A multi-environment, multi-runner, super-easy JavaScript testing framework framework. +--- +## Super-fast unit testing getting started super guide! +### (you need Firefox at the very least) {% highlight sh %} gem install flowerbox @@ -14,13 +15,207 @@ flowerbox spec/javascripts {% endhighlight %} ## ...and what about integration testing? +### (whoa nelly, pure JS Cucumber?) {% highlight sh %} flowerbox plant cucumber flowerbox js-features -{% end %} +{% endhighlight %} -## Flowerbox! ...wha? +## Hey, I'm already using `jasmine-gem` or `jasmine-headless-webkit` +### (you're smart!) + +{% highlight sh %} +flowerbox transplant spec/javascripts +flowerbox spec/javascripts +{% endhighlight %} + +## I use Sprockets and need to configure asset paths and templates and stuff! +### (...may the force be with you...) + +{% highlight ruby %} +# in spec/javascripts/spec_helper.rb + +require 'haml-sprockets' + +Flowerbox.configure do |c| + c.asset_paths << "app/assets/javascripts" + c.asset_paths << "vendor/assets/javascripts" + + c.additional_files << "applications.js.coffee" + + # ... other stuff ... +end +{% endhighlight %} + +## Firefox is so 2008. Can I run my tests on Chrome? +### (we like Selenium here!) + +{% highlight ruby %} +Flowerbox.configure do |c| + c.run_with :chrome +end +{% endhighlight %} + +## Chrome is so 2010. Can I run my tests on node.js? +### (evented hipness! jsdom will give you a fake DOM to work with.) + +{% highlight ruby %} +# make sure node and npm are in your path +# jsdom and ws get installed in your project under node_modules + +Flowerbox.configure do |c| + c.run_with :node +end +{% endhighlight %} + +{% highlight coffeescript %} +# make sure you bind your global things to this + +class @MyCoolClass extends @MyBaseClass + cool: -> "yeah man" +{% endhighlight %} + +## Where'd headless support go?! + +No, I knew you'd ask. Read the long bit of text below. _tl;dr_: Selenium with Chrome is +pretty much the same setup, just as fast, and gives you stack traces and other debugging assistance. + +--- + +# Plant some Jasmine + +--- + +# Plant a Cucumber or two + +## Make a feature like in big boy Cucumber +### (that's 'cause it *is* big boy Cucumber, just in JS form) + +{% highlight gherkin %} +# js-features/features/my_cool_thing.feature + +Feature: My Cool Thing + Scenario: Show a cool thing + Given I have a cool thing + And I have a cool thing viewer + When I render the viewer + Then I should see the cool thing in the viewer + + @wip # <= tags work, too! + Scenario: Maybe do something else + Given something + When yadda + Then BAM +{% endhighlight %} + +## Write some steps +### (Flowerbox gives you a donut-full of syntactic sugar that wraps around Cucumber.js. Be sure to drink lots of water!) + +{% highlight coffeescript %} +# js-features/steps/given/i_have_a_cool_thing.js.coffee + +Flowerbox.Given /^I have a cool thing$/, -> + @data = + one: 'two' + three: 'four' + + @coolThing = new CoolThing(@data) +{% endhighlight %} + +{% highlight coffeescript %} +# js-features/steps/given/i_have_a_cool_thing_viewer.js.coffee + +Flowerbox.Given /^I have a cool thing viewer$/, -> + @coolThingViewer = new CoolThingViewer(@coolThing) +{% endhighlight %} + +{% highlight coffeescript %} +# js-features/steps/when/i_render_the_viewer.js.coffee + +Flowerbox.When /^I render the viewer$/, -> + @coolThingViewer.render() +{% endhighlight %} + +{% highlight coffeescript %} +# js-features/steps/then/i_should_see_the_cool_thing.js.coffee + +Flowerbox.Then /^I should see the cool thing in the viewer$/, -> + @expect( + @coolThingViewer.$('input[name="one"]').val() + ).toEqual(@data.one) + + @expect( + @coolThingViewer.$('input[name="three"]').val() + ).toEqual(@data.three) +{% endhighlight %} + +## Get some hooks up in here! +### (and other fun environment stuff) + +{% highlight coffeescript %} +# js-features/support/env.js.coffee +# +#= require ../steps + +Flowerbox.World -> + @Before (callback) -> + @something = 'is available everywhere' + callback() + + @After (callback) -> + Put = 'some stuff back' + callback() +{% endhighlight %} +--- + +# Flowerbox! Yea...wha? So I (John) have been in this JavaScript testing game for a while, and, after about -three years of the stuff, decided to finally take all the knowledge I had o +three years of doing JS testing for Web apps, decided to finally take all the knowledge I had +and make something that was dead-simple to use. + +## You already did once... + +`jasmine-headless-webkit` was my first attempt, but it's a C++/Qt mess. Downloading all of +Qt is a total pain. Also, Qt4's JavaScript engine, JavaScriptCore, doesn't have stack trace +support, so it got pretty useless for me for bigger, messy projects (looking at you, Backbone). +Qt5 has V8, but whatever, I just decided to ditch the whole +compiling software thing and replace it with running tests in Selenium and/or node.js. + +## Selenium faster than headless? But CI servers-- + +Sure, spinning up that instance of Firefox or Chrome is slower than starting up a small +QtWebKit widget, but there's a lot less that can go wrong when using a full-blown +browser. This also means your CI server config stays leaner. You may already have Qt installed +for capybara-webkit, but one less thing depending on Qt just makes your life (and mine) easier. + +Also, when running Flowerbox with Guard, your browser stays open between test runs, so you only +pay the startup penalty once. + +And, if you write everything correctly, you can just run your tests on node.js and not even have +to worry about a browser. + +## But you said fake browsers are teh bad-- + +I changed my mind. As long as I'm not testing for browser-only things, like CSS interaction +or position elements, running tests on node.js with a browser-like DOM provided by jsdom +really is good enough. I use full-blown Ruby Cucumber if I need to test more complex browser +things. + +## Cucumber.js? Full-stack testing is the only way! + +Yeah, and it's slow. I'll carve out what I can in Cucumber.js while I work on Ruby Cucumber +features. Makes the process of getting those complex integration tests written a lot faster. + +Also, I've changed my views on unit testing as a process. Unit testing for me is now about +two things: + +* Code design through a liberal use of stubs and mocks. +* Really quickly running through blg blobs of inputs/outputs (parsers and such). + +Treating unit testing this way taught me how to better organize and design my code, and I +only use it for really testing code when I need to test those big blobs of things. +This is my opinion, YMMV, Flowerbox lets you do what you want. Never use Cucumber.js support +if you don't want to. Write your integration bits in Jasmine. I don't mind. + diff --git a/sass/screen.scss b/sass/screen.scss index 81de847..d43df66 100644 --- a/sass/screen.scss +++ b/sass/screen.scss @@ -4,3 +4,79 @@ * */ @import "compass/reset"; +@import "compass/css3"; + +$base_color: #d9b741; +$header_color: #000; +$header_blend_color: #3a60e5; + +$code_border_color: $header_blend_color; + +body { + background-color: $base_color; +} + +#container { + width: 550px; + margin: 0 auto; +} + +h1, h2 { + font-weight: bold; +} + +h1 { + font-size: 1.75em; + margin: 0.35em 0; + color: mix($header_color, $header_blend_color, 90); +} + +h2 { + font-size: 1.45em; + margin: 0.25em 0; + color: mix($header_color, $header_blend_color, 70); +} + +h3 { + font-size: 1.1em; + margin: 0.2em 0; + color: mix($header_color, $header_blend_color, 50); +} + +h1, h2, h3 { + text-align: center; + font-family: 'Gorditas', 'Helvetica Neue', 'Helvetica'; +} + +p, li { + font-family: 'Pontano Sans', 'Helvetica Neue', 'Helvetica'; + line-height: 120%; +} + +code, pre { + font-family: 'Courier New'; +} + +.highlight { + font-size: 0.9em; + padding: 1em; + border: solid $code_border_color 1px; + + margin: 1em 0; +} + +em { + font-style: italic; +} + +p { + margin: 0.7em 0; +} + +li { + list-style-type: disc; +} + +ul { + padding-left: 2em; +} diff --git a/stylesheets/screen.css b/stylesheets/screen.css index d362d69..e8ede12 100644 --- a/stylesheets/screen.css +++ b/stylesheets/screen.css @@ -66,3 +66,85 @@ a img { article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary { display: block; } + +/* line 15, ../sass/screen.scss */ +body { + background-color: #d9b741; +} + +/* line 19, ../sass/screen.scss */ +#container { + width: 550px; + margin: 0 auto; +} + +/* line 24, ../sass/screen.scss */ +h1, h2 { + font-weight: bold; +} + +/* line 28, ../sass/screen.scss */ +h1 { + font-size: 1.75em; + margin: 0.35em 0; + color: #050916; +} + +/* line 34, ../sass/screen.scss */ +h2 { + font-size: 1.45em; + margin: 0.25em 0; + color: #111c44; +} + +/* line 40, ../sass/screen.scss */ +h3 { + font-size: 1.1em; + margin: 0.2em 0; + color: #1d3072; +} + +/* line 46, ../sass/screen.scss */ +h1, h2, h3 { + text-align: center; + font-family: 'Gorditas', 'Helvetica Neue', 'Helvetica'; +} + +/* line 51, ../sass/screen.scss */ +p, li { + font-family: 'Pontano Sans', 'Helvetica Neue', 'Helvetica'; + line-height: 120%; +} + +/* line 56, ../sass/screen.scss */ +code, pre { + font-family: 'Courier New'; +} + +/* line 60, ../sass/screen.scss */ +.highlight { + font-size: 0.9em; + padding: 1em; + border: solid #3a60e5 1px; + margin: 1em 0; +} + +/* line 68, ../sass/screen.scss */ +em { + font-style: italic; +} + +/* line 72, ../sass/screen.scss */ +p { + margin: 0.7em 0; +} + +/* line 76, ../sass/screen.scss */ +li { + list-style-type: disc; +} + +/* line 80, ../sass/screen.scss */ +ul { + padding-left: 2em; +} diff --git a/stylesheets/syntax.css b/stylesheets/syntax.css new file mode 100644 index 0000000..2774b76 --- /dev/null +++ b/stylesheets/syntax.css @@ -0,0 +1,60 @@ +.highlight { background: #ffffff; } +.highlight .c { color: #999988; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { font-weight: bold } /* Keyword */ +.highlight .o { font-weight: bold } /* Operator */ +.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { font-weight: bold } /* Keyword.Constant */ +.highlight .kd { font-weight: bold } /* Keyword.Declaration */ +.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #d14 } /* Literal.String */ +.highlight .na { color: #008080 } /* Name.Attribute */ +.highlight .nb { color: #0086B3 } /* Name.Builtin */ +.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ +.highlight .no { color: #008080 } /* Name.Constant */ +.highlight .ni { color: #800080 } /* Name.Entity */ +.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ +.highlight .nn { color: #555555 } /* Name.Namespace */ +.highlight .nt { color: #000080 } /* Name.Tag */ +.highlight .nv { color: #008080 } /* Name.Variable */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #d14 } /* Literal.String.Backtick */ +.highlight .sc { color: #d14 } /* Literal.String.Char */ +.highlight .sd { color: #d14 } /* Literal.String.Doc */ +.highlight .s2 { color: #d14 } /* Literal.String.Double */ +.highlight .se { color: #d14 } /* Literal.String.Escape */ +.highlight .sh { color: #d14 } /* Literal.String.Heredoc */ +.highlight .si { color: #d14 } /* Literal.String.Interpol */ +.highlight .sx { color: #d14 } /* Literal.String.Other */ +.highlight .sr { color: #009926 } /* Literal.String.Regex */ +.highlight .s1 { color: #d14 } /* Literal.String.Single */ +.highlight .ss { color: #990073 } /* Literal.String.Symbol */ +.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #008080 } /* Name.Variable.Class */ +.highlight .vg { color: #008080 } /* Name.Variable.Global */ +.highlight .vi { color: #008080 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ diff --git a/stylesheets/vim.css b/stylesheets/vim.css new file mode 100644 index 0000000..740f437 --- /dev/null +++ b/stylesheets/vim.css @@ -0,0 +1,69 @@ +.codehilite .hll { background-color: #222222 } +.codehilite .c { color: #000080 } /* Comment */ +.codehilite .err { color: #cccccc; border: 1px solid #FF0000 } /* Error */ +.codehilite .g { color: #cccccc } /* Generic */ +.codehilite .k { color: #cdcd00 } /* Keyword */ +.codehilite .l { color: #cccccc } /* Literal */ +.codehilite .n { color: #cccccc } /* Name */ +.codehilite .o { color: #3399cc } /* Operator */ +.codehilite .x { color: #cccccc } /* Other */ +.codehilite .p { color: #cccccc } /* Punctuation */ +.codehilite .cm { color: #000080 } /* Comment.Multiline */ +.codehilite .cp { color: #000080 } /* Comment.Preproc */ +.codehilite .c1 { color: #000080 } /* Comment.Single */ +.codehilite .cs { color: #cd0000; font-weight: bold } /* Comment.Special */ +.codehilite .gd { color: #cd0000 } /* Generic.Deleted */ +.codehilite .ge { color: #cccccc; font-style: italic } /* Generic.Emph */ +.codehilite .gr { color: #FF0000 } /* Generic.Error */ +.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.codehilite .gi { color: #00cd00 } /* Generic.Inserted */ +.codehilite .go { color: #808080 } /* Generic.Output */ +.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.codehilite .gs { color: #cccccc; font-weight: bold } /* Generic.Strong */ +.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.codehilite .gt { color: #0040D0 } /* Generic.Traceback */ +.codehilite .kc { color: #cdcd00 } /* Keyword.Constant */ +.codehilite .kd { color: #00cd00 } /* Keyword.Declaration */ +.codehilite .kn { color: #cd00cd } /* Keyword.Namespace */ +.codehilite .kp { color: #cdcd00 } /* Keyword.Pseudo */ +.codehilite .kr { color: #cdcd00 } /* Keyword.Reserved */ +.codehilite .kt { color: #00cd00 } /* Keyword.Type */ +.codehilite .ld { color: #cccccc } /* Literal.Date */ +.codehilite .m { color: #cd00cd } /* Literal.Number */ +.codehilite .s { color: #cd0000 } /* Literal.String */ +.codehilite .na { color: #cccccc } /* Name.Attribute */ +.codehilite .nb { color: #cd00cd } /* Name.Builtin */ +.codehilite .nc { color: #00cdcd } /* Name.Class */ +.codehilite .no { color: #cccccc } /* Name.Constant */ +.codehilite .nd { color: #cccccc } /* Name.Decorator */ +.codehilite .ni { color: #cccccc } /* Name.Entity */ +.codehilite .ne { color: #666699; font-weight: bold } /* Name.Exception */ +.codehilite .nf { color: #cccccc } /* Name.Function */ +.codehilite .nl { color: #cccccc } /* Name.Label */ +.codehilite .nn { color: #cccccc } /* Name.Namespace */ +.codehilite .nx { color: #cccccc } /* Name.Other */ +.codehilite .py { color: #cccccc } /* Name.Property */ +.codehilite .nt { color: #cccccc } /* Name.Tag */ +.codehilite .nv { color: #00cdcd } /* Name.Variable */ +.codehilite .ow { color: #cdcd00 } /* Operator.Word */ +.codehilite .w { color: #cccccc } /* Text.Whitespace */ +.codehilite .mf { color: #cd00cd } /* Literal.Number.Float */ +.codehilite .mh { color: #cd00cd } /* Literal.Number.Hex */ +.codehilite .mi { color: #cd00cd } /* Literal.Number.Integer */ +.codehilite .mo { color: #cd00cd } /* Literal.Number.Oct */ +.codehilite .sb { color: #cd0000 } /* Literal.String.Backtick */ +.codehilite .sc { color: #cd0000 } /* Literal.String.Char */ +.codehilite .sd { color: #cd0000 } /* Literal.String.Doc */ +.codehilite .s2 { color: #cd0000 } /* Literal.String.Double */ +.codehilite .se { color: #cd0000 } /* Literal.String.Escape */ +.codehilite .sh { color: #cd0000 } /* Literal.String.Heredoc */ +.codehilite .si { color: #cd0000 } /* Literal.String.Interpol */ +.codehilite .sx { color: #cd0000 } /* Literal.String.Other */ +.codehilite .sr { color: #cd0000 } /* Literal.String.Regex */ +.codehilite .s1 { color: #cd0000 } /* Literal.String.Single */ +.codehilite .ss { color: #cd0000 } /* Literal.String.Symbol */ +.codehilite .bp { color: #cd00cd } /* Name.Builtin.Pseudo */ +.codehilite .vc { color: #00cdcd } /* Name.Variable.Class */ +.codehilite .vg { color: #00cdcd } /* Name.Variable.Global */ +.codehilite .vi { color: #00cdcd } /* Name.Variable.Instance */ +.codehilite .il { color: #cd00cd } /* Literal.Number.Integer.Long */