sudo apt-get install nodejs npm -y
sudo npm install -g coffee-script
For other releases, take a look at this post
Ruby 1.9.3-p194 and RubyGems 1.8.23 are used in this project.
To install Ruby and RubyGems, take a look at rbenv or rvm.
Bundler 1.0.21 is used. The following command was used to install the required gems.
bundle install --path vendor/bundle
For testing, the project uses Jasmine. However, Jasmine is slow when it comes to continuous testing. Reloading the browser is annoying. jasmine-headless-webkit provides an automated way to run tests in a browser environment.
The following command will install the necessary prerequisites.
sudo apt-get install libqt4-dev qt4-qmake -y
sudo update-alternatives --config qmake
Obviously, this project uses markdown.
sudo apt-get install markdown
All SnapEditor code is written in the coffeescripts/
directory. These files are compiled into JavaScript and placed in the javascripts/
directory.
Guard is used for continuous compiling. It listens to the coffeescripts/
directory for any changes. If there is, it will compile the CoffeeScript file into a JavaScript file and place it in javascripts/
. Use the following command to run Guard.
bundle exec guard start
A rake task is provided for compiling.
rake compile
The Jasmine specs are written in CoffeeScript. Use the following command to compile and run them manually.
bundle exec jasmine-headless-webkit
Guard is used for continuous testing. It watches for any changes to JavaScript files in the javascripts/
directory, CoffeeScript files in the spec/
directories, and spec/javascripts/support/jasmine.yml
. Use the following command to run Guard.
bundle exec guard start
This runs the tests only in WebKit. It is a good idea to test in all browsers, including a non-headless WebKit. A rackup file has been provided.
rackup config.ru
You can now point your browser to locahost:9292
and the Jasmine specs will run.
If you would like to configure which specs to run, you can modify spec/javascripts/support/jasmine.yml
. Look for the spec_files
property.
Although automated tests are preferred, the editor requires a lot of actions that simply can't be automated.
The spec/acceptance/
contains two files: dev.html
and test.html
. These contain both the form and inline editor for testing purposes.
dev.html
sources build/snapeditor.js
which changes whenever any CoffeeScript files are modified. This is used during development.
test.html
sources spec/acceptance/assets/javascripts/snapeditor.js
which does not change unless it gets overwritten. This is meant to be used during testing.
A rake task has been provided to generate spec/acceptance/assets/javascripts/snapeditor.js
.
rake prepare:test
RequireJS loads files asynchronously. However, Jasmine runs its tests immediately. Therefore, the it()
function does not give RequireJS the chance to load any files.
Changes have been made to RequireJS in the tests in order to load files synchronously. These changes can be found in
spec/javascripts/support/cs.custom.js
spec/javascripts/support/require.custom.coffee
SnapEditor is written using a custom jQuery (javascripts/jquery.custom.coffee
). If the tests used the default jQuery (lib/jquery.js
), we would be mixing different jQuerys. In most cases, this mixing does not cause problems.
However, listening to and triggering events from different jQuerys causes problems. Triggering an event from one jQuery does not trigger the eventHandler in another jQuery.
# example.coffee
define ["jquery.custom"], ($) ->
# $ is the custom jQuery
return {
element: (el) -> $(el).on("click", -> console.log("CLICK"))
jQueryElement: ($el) -> $el.on("click", -> console.log("CLICK"))
}
# example_without_custom_jquery.spec.coffee
require ["example"], (Example) ->
describe "Example", ->
# The default jQuery is used in the test and the custom jQuery is used
# inside the function.
it "doesn't log CLICK when using different jQuerys", ->
# $ is the default jQuery
$el = $("<div/>")
Example.element($el[0])
# CLICK is not logged
$el.trigger("click")
# The default jQuery is used in the test and inside the function.
it "logs CLICK when using the same default jQuery", ->
# $ is the default jQuery
$el = $("<div/>")
Example.jQueryElement($el)
# CLICK is logged
$el.trigger("click")
# example_with_custom_jquery.spec.coffee
require ["jquery.custom", "example"], ($, Example) ->
# The custom jQuery is used in the test and inside the function.
it "logs CLICK when using the same custom jQuery", ->
# $ is the custom jQuery
$el = $("<div/>")
Example.element($el[0])
# CLICK is logged
$el.trigger("click")
In order to keep things consistent, always require jquery.custom
. This guarantees that the tests will be using the custom jQuery and so everything will be using the same jQuery.
The beginning of the build starts at javascripts/snapeditor.js
. It is the start of all the requires.
build/
contains all the necessary files for building SnapEditor. build.js
has been provided as a profile for building SnapEditor using r.js
. Use the following command to use r.js
.
node r.js -o build.js
Whenever there are changes to the javascripts/
directory, the build is invoked.
Two rake tasks have been created to aid in building.
rake build # builds snapeditor.js without compiling
rake compileAndBuild # compile and build snapeditor.js
A rake task is provided for bundling SnapEditor.
rake prepare:bundle