diff --git a/.rspec b/.rspec new file mode 100644 index 00000000..35f4d744 --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--format Fuubar diff --git a/Rakefile b/Rakefile index 48e55902..6f19dcc1 100644 --- a/Rakefile +++ b/Rakefile @@ -10,22 +10,20 @@ end task :default => :spec +desc "Run all developement tests" +task :spec do + system "rspec" +end + +# Keeping this around for the Doc task, remove when doc is refactored task :require_pages_submodule do raise "Submodule for Github Pages isn't present. Run git submodule update --init" unless pages_submodule_present end -task :require_node do - raise "\nNode.js is required to develop code for Jasmine. Please visit http://nodejs.org to install.\n\n" unless node_installed? -end - def pages_submodule_present File.exist?('pages/download.html') end -def node_installed? - `which node` =~ /node/ -end - class String include Term::ANSIColor end diff --git a/jasmine-core.gemspec b/jasmine-core.gemspec index f73d5444..049710fe 100644 --- a/jasmine-core.gemspec +++ b/jasmine-core.gemspec @@ -22,4 +22,9 @@ Gem::Specification.new do |s| s.add_development_dependency "sass" s.add_development_dependency "compass" s.add_development_dependency "ragaskar-jsdoc_helper" + s.add_development_dependency "rspec" + s.add_development_dependency "fuubar" + s.add_development_dependency "awesome_print" + s.add_development_dependency "thor" + s.add_development_dependency "nokogiri" end diff --git a/jasmine_dev.thor b/jasmine_dev.thor new file mode 100644 index 00000000..7fe0ca71 --- /dev/null +++ b/jasmine_dev.thor @@ -0,0 +1 @@ +require "#{File.expand_path(File.dirname(__FILE__))}/tasks/jasmine_dev" \ No newline at end of file diff --git a/jshint/run.js b/jshint/run.js index 7fc856c2..c4282f4f 100644 --- a/jshint/run.js +++ b/jshint/run.js @@ -1,5 +1,5 @@ var fs = require("fs"); -var sys = require("sys"); +var util = require("util"); var path = require("path"); var JSHINT = require("./jshint").JSHINT; diff --git a/lib/jasmine-core/jasmine-html.js b/lib/jasmine-core/jasmine-html.js index 3de4e8a5..a0b06394 100644 --- a/lib/jasmine-core/jasmine-html.js +++ b/lib/jasmine-core/jasmine-html.js @@ -84,7 +84,7 @@ jasmine.HtmlReporter = function(_doc) { }; self.reportRunnerResults = function(runner) { - reporterView.complete(); + reporterView && reporterView.complete(); }; self.reportSuiteResults = function(suite) { @@ -158,67 +158,7 @@ jasmine.HtmlReporter = function(_doc) { ); } }; -jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);jasmine.HtmlReporterHelpers = {}; - -jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) { - var el = document.createElement(type); - - for (var i = 2; i < arguments.length; i++) { - var child = arguments[i]; - - if (typeof child === 'string') { - el.appendChild(document.createTextNode(child)); - } else { - if (child) { - el.appendChild(child); - } - } - } - - for (var attr in attrs) { - if (attr == "className") { - el[attr] = attrs[attr]; - } else { - el.setAttribute(attr, attrs[attr]); - } - } - - return el; -}; - -jasmine.HtmlReporterHelpers.getSpecStatus = function(child) { - var results = child.results(); - var status = results.passed() ? 'passed' : 'failed'; - if (results.skipped) { - status = 'skipped'; - } - - return status; -}; - -jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) { - var parentDiv = this.dom.summary; - var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite'; - var parent = child[parentSuite]; - - if (parent) { - if (typeof this.views.suites[parent.id] == 'undefined') { - this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views); - } - parentDiv = this.views.suites[parent.id].element; - } - - parentDiv.appendChild(childElement); -}; - - -jasmine.HtmlReporterHelpers.addHelpers = function(ctor) { - for(var fn in jasmine.HtmlReporterHelpers) { - ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn]; - } -}; - -jasmine.HtmlReporter.ReporterView = function(dom) { +jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);jasmine.HtmlReporter.ReporterView = function(dom) { this.startedAt = new Date(); this.runningSpecCount = 0; this.completeSpecCount = 0; diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 2e562a80..f22c7633 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -197,12 +197,12 @@ jasmine.any = function(clazz) { }; /** - * Returns a matchable subset of a hash/JSON object. For use in expectations when you don't care about all of the + * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the * attributes on the object. * * @example * // don't care about any other attributes than foo. - * expect(mySpy).toHaveBeenCalledWith(jasmine.hashContaining({foo: "bar"}); + * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"}); * * @param sample {Object} sample * @returns matchable object for the sample @@ -293,7 +293,7 @@ jasmine.Spy = function(name) { }; /** - * Tells a spy to call through to the actual implementation. + * Tells a spy to call through to the actual implemenatation. * * @example * var foo = { @@ -929,12 +929,12 @@ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { return a.getTime() == b.getTime(); } - if (a instanceof jasmine.Matchers.Any) { - return a.matches(b); + if (a.jasmineMatches) { + return a.jasmineMatches(b); } - if (b instanceof jasmine.Matchers.Any) { - return b.matches(a); + if (b.jasmineMatches) { + return b.jasmineMatches(a); } if (a instanceof jasmine.Matchers.ObjectContaining) { @@ -1235,7 +1235,7 @@ jasmine.Matchers.prototype.toEqual = function(expected) { /** * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual * @param expected - * @deprecated as of 1.0. Use not.toNotEqual() instead. + * @deprecated as of 1.0. Use not.toEqual() instead. */ jasmine.Matchers.prototype.toNotEqual = function(expected) { return !this.env.equals_(this.actual, expected); @@ -1408,7 +1408,7 @@ jasmine.Matchers.prototype.toContain = function(expected) { * Matcher that checks that the expected item is NOT an element in the actual Array. * * @param {Object} expected - * @deprecated as of 1.0. Use not.toNotContain() instead. + * @deprecated as of 1.0. Use not.toContain() instead. */ jasmine.Matchers.prototype.toNotContain = function(expected) { return !this.env.contains_(this.actual, expected); @@ -1476,7 +1476,7 @@ jasmine.Matchers.Any = function(expectedClass) { this.expectedClass = expectedClass; }; -jasmine.Matchers.Any.prototype.matches = function(other) { +jasmine.Matchers.Any.prototype.jasmineMatches = function(other) { if (this.expectedClass == String) { return typeof other == 'string' || other instanceof String; } @@ -1496,7 +1496,7 @@ jasmine.Matchers.Any.prototype.matches = function(other) { return other instanceof this.expectedClass; }; -jasmine.Matchers.Any.prototype.toString = function() { +jasmine.Matchers.Any.prototype.jasmineToString = function() { return ''; }; @@ -1504,7 +1504,7 @@ jasmine.Matchers.ObjectContaining = function (sample) { this.sample = sample; }; -jasmine.Matchers.ObjectContaining.prototype.matches = function(other, mismatchKeys, mismatchValues) { +jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) { mismatchKeys = mismatchKeys || []; mismatchValues = mismatchValues || []; @@ -1526,9 +1526,192 @@ jasmine.Matchers.ObjectContaining.prototype.matches = function(other, mismatchKe return (mismatchKeys.length === 0 && mismatchValues.length === 0); }; -jasmine.Matchers.ObjectContaining.prototype.toString = function () { - return ""; +jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () { + return ""; }; +// Mock setTimeout, clearTimeout +// Contributed by Pivotal Computer Systems, www.pivotalsf.com + +jasmine.FakeTimer = function() { + this.reset(); + + var self = this; + self.setTimeout = function(funcToCall, millis) { + self.timeoutsMade++; + self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); + return self.timeoutsMade; + }; + + self.setInterval = function(funcToCall, millis) { + self.timeoutsMade++; + self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); + return self.timeoutsMade; + }; + + self.clearTimeout = function(timeoutKey) { + self.scheduledFunctions[timeoutKey] = jasmine.undefined; + }; + + self.clearInterval = function(timeoutKey) { + self.scheduledFunctions[timeoutKey] = jasmine.undefined; + }; + +}; + +jasmine.FakeTimer.prototype.reset = function() { + this.timeoutsMade = 0; + this.scheduledFunctions = {}; + this.nowMillis = 0; +}; + +jasmine.FakeTimer.prototype.tick = function(millis) { + var oldMillis = this.nowMillis; + var newMillis = oldMillis + millis; + this.runFunctionsWithinRange(oldMillis, newMillis); + this.nowMillis = newMillis; +}; + +jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { + var scheduledFunc; + var funcsToRun = []; + for (var timeoutKey in this.scheduledFunctions) { + scheduledFunc = this.scheduledFunctions[timeoutKey]; + if (scheduledFunc != jasmine.undefined && + scheduledFunc.runAtMillis >= oldMillis && + scheduledFunc.runAtMillis <= nowMillis) { + funcsToRun.push(scheduledFunc); + this.scheduledFunctions[timeoutKey] = jasmine.undefined; + } + } + + if (funcsToRun.length > 0) { + funcsToRun.sort(function(a, b) { + return a.runAtMillis - b.runAtMillis; + }); + for (var i = 0; i < funcsToRun.length; ++i) { + try { + var funcToRun = funcsToRun[i]; + this.nowMillis = funcToRun.runAtMillis; + funcToRun.funcToCall(); + if (funcToRun.recurring) { + this.scheduleFunction(funcToRun.timeoutKey, + funcToRun.funcToCall, + funcToRun.millis, + true); + } + } catch(e) { + } + } + this.runFunctionsWithinRange(oldMillis, nowMillis); + } +}; + +jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { + this.scheduledFunctions[timeoutKey] = { + runAtMillis: this.nowMillis + millis, + funcToCall: funcToCall, + recurring: recurring, + timeoutKey: timeoutKey, + millis: millis + }; +}; + +/** + * @namespace + */ +jasmine.Clock = { + defaultFakeTimer: new jasmine.FakeTimer(), + + reset: function() { + jasmine.Clock.assertInstalled(); + jasmine.Clock.defaultFakeTimer.reset(); + }, + + tick: function(millis) { + jasmine.Clock.assertInstalled(); + jasmine.Clock.defaultFakeTimer.tick(millis); + }, + + runFunctionsWithinRange: function(oldMillis, nowMillis) { + jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); + }, + + scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { + jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); + }, + + useMock: function() { + if (!jasmine.Clock.isInstalled()) { + var spec = jasmine.getEnv().currentSpec; + spec.after(jasmine.Clock.uninstallMock); + + jasmine.Clock.installMock(); + } + }, + + installMock: function() { + jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; + }, + + uninstallMock: function() { + jasmine.Clock.assertInstalled(); + jasmine.Clock.installed = jasmine.Clock.real; + }, + + real: { + setTimeout: jasmine.getGlobal().setTimeout, + clearTimeout: jasmine.getGlobal().clearTimeout, + setInterval: jasmine.getGlobal().setInterval, + clearInterval: jasmine.getGlobal().clearInterval + }, + + assertInstalled: function() { + if (!jasmine.Clock.isInstalled()) { + throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); + } + }, + + isInstalled: function() { + return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; + }, + + installed: null +}; +jasmine.Clock.installed = jasmine.Clock.real; + +//else for IE support +jasmine.getGlobal().setTimeout = function(funcToCall, millis) { + if (jasmine.Clock.installed.setTimeout.apply) { + return jasmine.Clock.installed.setTimeout.apply(this, arguments); + } else { + return jasmine.Clock.installed.setTimeout(funcToCall, millis); + } +}; + +jasmine.getGlobal().setInterval = function(funcToCall, millis) { + if (jasmine.Clock.installed.setInterval.apply) { + return jasmine.Clock.installed.setInterval.apply(this, arguments); + } else { + return jasmine.Clock.installed.setInterval(funcToCall, millis); + } +}; + +jasmine.getGlobal().clearTimeout = function(timeoutKey) { + if (jasmine.Clock.installed.clearTimeout.apply) { + return jasmine.Clock.installed.clearTimeout.apply(this, arguments); + } else { + return jasmine.Clock.installed.clearTimeout(timeoutKey); + } +}; + +jasmine.getGlobal().clearInterval = function(timeoutKey) { + if (jasmine.Clock.installed.clearTimeout.apply) { + return jasmine.Clock.installed.clearInterval.apply(this, arguments); + } else { + return jasmine.Clock.installed.clearInterval(timeoutKey); + } +}; + /** * @constructor */ @@ -1669,8 +1852,8 @@ jasmine.PrettyPrinter.prototype.format = function(value) { this.emitScalar('null'); } else if (value === jasmine.getGlobal()) { this.emitScalar(''); - } else if (value instanceof jasmine.Matchers.Any) { - this.emitScalar(value.toString()); + } else if (value.jasmineToString) { + this.emitScalar(value.jasmineToString()); } else if (typeof value === 'string') { this.emitString(value); } else if (jasmine.isSpy(value)) { @@ -2337,192 +2520,9 @@ jasmine.WaitsForBlock.prototype.execute = function(onComplete) { }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); } }; -// Mock setTimeout, clearTimeout -// Contributed by Pivotal Computer Systems, www.pivotalsf.com - -jasmine.FakeTimer = function() { - this.reset(); - - var self = this; - self.setTimeout = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); - return self.timeoutsMade; - }; - - self.setInterval = function(funcToCall, millis) { - self.timeoutsMade++; - self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); - return self.timeoutsMade; - }; - - self.clearTimeout = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - - self.clearInterval = function(timeoutKey) { - self.scheduledFunctions[timeoutKey] = jasmine.undefined; - }; - -}; - -jasmine.FakeTimer.prototype.reset = function() { - this.timeoutsMade = 0; - this.scheduledFunctions = {}; - this.nowMillis = 0; -}; - -jasmine.FakeTimer.prototype.tick = function(millis) { - var oldMillis = this.nowMillis; - var newMillis = oldMillis + millis; - this.runFunctionsWithinRange(oldMillis, newMillis); - this.nowMillis = newMillis; -}; - -jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { - var scheduledFunc; - var funcsToRun = []; - for (var timeoutKey in this.scheduledFunctions) { - scheduledFunc = this.scheduledFunctions[timeoutKey]; - if (scheduledFunc != jasmine.undefined && - scheduledFunc.runAtMillis >= oldMillis && - scheduledFunc.runAtMillis <= nowMillis) { - funcsToRun.push(scheduledFunc); - this.scheduledFunctions[timeoutKey] = jasmine.undefined; - } - } - - if (funcsToRun.length > 0) { - funcsToRun.sort(function(a, b) { - return a.runAtMillis - b.runAtMillis; - }); - for (var i = 0; i < funcsToRun.length; ++i) { - try { - var funcToRun = funcsToRun[i]; - this.nowMillis = funcToRun.runAtMillis; - funcToRun.funcToCall(); - if (funcToRun.recurring) { - this.scheduleFunction(funcToRun.timeoutKey, - funcToRun.funcToCall, - funcToRun.millis, - true); - } - } catch(e) { - } - } - this.runFunctionsWithinRange(oldMillis, nowMillis); - } -}; - -jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { - this.scheduledFunctions[timeoutKey] = { - runAtMillis: this.nowMillis + millis, - funcToCall: funcToCall, - recurring: recurring, - timeoutKey: timeoutKey, - millis: millis - }; -}; - -/** - * @namespace - */ -jasmine.Clock = { - defaultFakeTimer: new jasmine.FakeTimer(), - - reset: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.reset(); - }, - - tick: function(millis) { - jasmine.Clock.assertInstalled(); - jasmine.Clock.defaultFakeTimer.tick(millis); - }, - - runFunctionsWithinRange: function(oldMillis, nowMillis) { - jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); - }, - - scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { - jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); - }, - - useMock: function() { - if (!jasmine.Clock.isInstalled()) { - var spec = jasmine.getEnv().currentSpec; - spec.after(jasmine.Clock.uninstallMock); - - jasmine.Clock.installMock(); - } - }, - - installMock: function() { - jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; - }, - - uninstallMock: function() { - jasmine.Clock.assertInstalled(); - jasmine.Clock.installed = jasmine.Clock.real; - }, - - real: { - setTimeout: jasmine.getGlobal().setTimeout, - clearTimeout: jasmine.getGlobal().clearTimeout, - setInterval: jasmine.getGlobal().setInterval, - clearInterval: jasmine.getGlobal().clearInterval - }, - - assertInstalled: function() { - if (!jasmine.Clock.isInstalled()) { - throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); - } - }, - - isInstalled: function() { - return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; - }, - - installed: null -}; -jasmine.Clock.installed = jasmine.Clock.real; - -//else for IE support -jasmine.getGlobal().setTimeout = function(funcToCall, millis) { - if (jasmine.Clock.installed.setTimeout.apply) { - return jasmine.Clock.installed.setTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.setTimeout(funcToCall, millis); - } -}; - -jasmine.getGlobal().setInterval = function(funcToCall, millis) { - if (jasmine.Clock.installed.setInterval.apply) { - return jasmine.Clock.installed.setInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.setInterval(funcToCall, millis); - } -}; - -jasmine.getGlobal().clearTimeout = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearTimeout.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearTimeout(timeoutKey); - } -}; - -jasmine.getGlobal().clearInterval = function(timeoutKey) { - if (jasmine.Clock.installed.clearTimeout.apply) { - return jasmine.Clock.installed.clearInterval.apply(this, arguments); - } else { - return jasmine.Clock.installed.clearInterval(timeoutKey); - } -}; - jasmine.version_= { "major": 1, "minor": 1, "build": 0, - "revision": 1299963843 + "revision": 1332515016 }; diff --git a/pages b/pages index d08ce2de..a9d577eb 160000 --- a/pages +++ b/pages @@ -1 +1 @@ -Subproject commit d08ce2de245d6782c09c652045a12e93af0dc7ec +Subproject commit a9d577eb45346c088c857af5bb301540c2a121f4 diff --git a/spec/node_suite.js b/spec/node_suite.js index da7a5b09..bd2867b3 100644 --- a/spec/node_suite.js +++ b/spec/node_suite.js @@ -1,5 +1,5 @@ var fs = require('fs'); -var sys = require('sys'); +var util = require('util'); var path = require('path'); // yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw] @@ -37,7 +37,7 @@ jasmine.executeSpecs = function(specs, done, isVerbose, showColors) { } var jasmineEnv = jasmine.getEnv(); - var consoleReporter = new jasmine.ConsoleReporter(sys.print, done, showColors); + var consoleReporter = new jasmine.ConsoleReporter(util.print, done, showColors); jasmineEnv.addReporter(consoleReporter); jasmineEnv.execute(); diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 00000000..a2e43eb4 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,51 @@ +# This file was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# Require this file using `require "spec_helper.rb"` to ensure that it is only +# loaded once. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + config.treat_symbols_as_metadata_keys_with_true_values = true + config.run_all_when_everything_filtered = true + config.filter_run :focus +end + +require 'awesome_print' +require 'tmpdir' +require 'nokogiri' + +def project_root + File.join(File.expand_path(File.dirname(__FILE__)), '..') +end + +require "#{project_root}/tasks/jasmine_dev" + +def capture_output(capture = true) + if capture + output = StringIO.new + $stdout = output + end + yield + if capture + output.string + end +ensure + $stdout = STDOUT +end + +def reset_dir(dir) + FileUtils.rm_r dir if File.exists?(dir) + FileUtils.mkdir_p dir +end + +def jasmine_version + version = jasmine_version_object + + version_string = "#{version['major']}.#{version['minor']}.#{version['build']}" + version_string += ".rc#{version['release_candidate']}" if version['release_candidate'] + version_string +end + +def jasmine_version_object + @version_object ||= JSON.parse(File.read(File.join(JasmineDev.project_root, 'src', 'version.json'))) +end \ No newline at end of file diff --git a/spec/tasks/build_distribution_spec.rb b/spec/tasks/build_distribution_spec.rb new file mode 100644 index 00000000..e105be91 --- /dev/null +++ b/spec/tasks/build_distribution_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper.rb' + +describe "Build Jasmine task" do + + let(:jasmine_core_dir) { "#{Dir.tmpdir}/jasmine-core" } + let(:jasmine_dev) { JasmineDev.new } + + before do + reset_dir jasmine_core_dir + @output = capture_output { jasmine_dev.build_distribution jasmine_core_dir } + end + + it "should say that JSHint is running" do + @output.should match(/Running JSHint/) + @output.should match(/Jasmine JSHint PASSED/) + end + + it "should tell the developer it is building the distribution" do + @output.should match(/Building Jasmine distribution/) + end + + it "should build jasmine.js in the destination directory" do + File.exist?("#{jasmine_core_dir}/jasmine.js").should be_true + end + + it "should build jasmine-html.js in the destination directory" do + File.exist?("#{jasmine_core_dir}/jasmine-html.js").should be_true + end + + it "should build jasmine.css" do + File.exist?("#{jasmine_core_dir}/jasmine.css").should be_true + end +end \ No newline at end of file diff --git a/spec/tasks/build_github_pages_spec.rb b/spec/tasks/build_github_pages_spec.rb new file mode 100644 index 00000000..8e0cedcb --- /dev/null +++ b/spec/tasks/build_github_pages_spec.rb @@ -0,0 +1,56 @@ +require 'spec_helper.rb' + +describe "Build Github Pages task" do + + let(:pages_dir) { File.join(Dir.tmpdir, 'pages') } + let(:jasmine_dev) { JasmineDev.new } + + before do + reset_dir pages_dir + end + + describe "when the Github pages submodule is not present" do + before do + jasmine_dev.should_receive(:has_pages_submodule?).and_return(false) + + @output = capture_output { jasmine_dev.build_github_pages pages_dir } + end + + it "should tell the user the task is running" do + @output.should match(/Building Github Pages/) + end + + it "should prompt the user to install the submodule" do + @output.should match(/Submodule for Github Pages isn't present/) + end + end + + describe "when the Github pages submodule is present" do + before do + jasmine_dev.should_receive(:has_pages_submodule?).and_return(true) + + @output = capture_output { jasmine_dev.build_github_pages pages_dir } + end + + it "should tell the user the task is running" do + @output.should match(/Building Github Pages/) + end + + it "should tell the user the pages are built" do + @output.should match(/Congratulations, project dumped to/) + end + + it "should copy the pages output to the requested diretory" do + Dir.chdir File.join(pages_dir, 'pages_output') do + pages = Dir.glob(File.join('**', '*')) + + pages.should include('download.html') + pages.should include('index.html') + pages.should include(File.join('images', 'jasmine_logo.png')) + pages.should include(File.join('images', 'pivotal_logo.gif')) + pages.should include(File.join('css', 'pygments.css')) + pages.should include(File.join('css', 'screen.css')) + end + end + end +end \ No newline at end of file diff --git a/spec/tasks/build_standalone_distribution_spec.rb b/spec/tasks/build_standalone_distribution_spec.rb new file mode 100644 index 00000000..8588268f --- /dev/null +++ b/spec/tasks/build_standalone_distribution_spec.rb @@ -0,0 +1,109 @@ +require 'spec_helper.rb' + +describe "Standalone Distribution tasks" do + + let(:jasmine_dev) { JasmineDev.new } + let(:standalone_temp_dir) { File.join(Dir.tmpdir, 'jasmine_test') } + let(:download_dir) { File.join(standalone_temp_dir, 'download')} + + describe "build_standalone_distribution" do + before do + reset_dir standalone_temp_dir + reset_dir download_dir + + Dir.should_receive(:tmpdir).any_number_of_times.and_return(standalone_temp_dir) + + @standalone_staging_dir = File.join(standalone_temp_dir, 'jasmine_standalone') + + @version_dir = File.join(@standalone_staging_dir, "jasmine-standalone-#{jasmine_version}") + @lib_dir = File.join(@version_dir, 'lib') + @source_dir = File.join(@version_dir, 'src') + @spec_dir = File.join(@version_dir, 'spec') + + @output = capture_output { jasmine_dev.build_standalone_distribution download_dir } + end + + it "should build the distribution" do + @output.should match(/Building Jasmine distribution/) + end + + it "should tell the developer the task has started" do + @output.should match(/Building standalone distribution/) + end + + it "should copy the lib directory to the staging directory, under a versioned directory" do + lib_dir_files = Dir.glob(File.join(standalone_temp_dir, 'jasmine_standalone', '**', '*')) + + staged_lib_files = %w{ jasmine.js jasmine-html.js jasmine.css MIT.LICENSE } + staged_lib_files.each do |filename| + lib_dir_files.should include(File.join(@lib_dir, "jasmine-#{jasmine_version}", filename)) + end + end + + it "should copy the sample project source to the staging directory" do + File.exist?(File.join(@source_dir, 'Player.js')).should be_true + File.exist?(File.join(@source_dir, 'Song.js')).should be_true + end + + it "should copy the sample project specs to the staging directory" do + File.exist?(File.join(@spec_dir, 'PlayerSpec.js')).should be_true + File.exist?(File.join(@spec_dir, 'SpecHelper.js')).should be_true + end + + it "should copy a build SpecRunner.html to the staging directory" do + File.exist?(File.join(@version_dir, 'SpecRunner.html')).should be_true + end + + it "should zip up the contents of the staging directory" do + File.exist?(File.join(@standalone_staging_dir, "jasmine-standalone-#{jasmine_version}.zip")).should be_true + end + + it "should copy the zip file to the pages sub directory" do + File.exist?(File.join(download_dir, "jasmine-standalone-#{jasmine_version}.zip")).should be_true + end + + describe "when the zip file is unzipped" do + before do + @out_directory = File.join(standalone_temp_dir, 'unzip') + reset_dir @out_directory + + FileUtils.cp File.join(@standalone_staging_dir, "jasmine-standalone-#{jasmine_version}.zip"), + @out_directory + + Dir.chdir @out_directory do + system("unzip -qq jasmine-standalone-#{jasmine_version}.zip") + end + end + + describe "the distirbution" do + before do + Dir.chdir @out_directory do + @files = Dir.glob(File.join('**', '*')) + end + end + + it "should include the correct root files" do + @files.should include('SpecRunner.html') + end + + it "should include the correct lib files" do + %w{ jasmine.js jasmine-html.js jasmine.css MIT.LICENSE }.each do |file| + @files.should include(File.join('lib', "jasmine-#{jasmine_version}", file)) + end + end + + it "should include the correct src files" do + %w{Player.js Song.js}.each do |file| + @files.should include(File.join('src', file)) + end + end + + it "should include the correct spec files" do + %w{PlayerSpec.js SpecHelper.js}.each do |file| + @files.should include(File.join('spec', file)) + end + end + end + end + end +end \ No newline at end of file diff --git a/spec/tasks/build_standalone_runner_spec.rb b/spec/tasks/build_standalone_runner_spec.rb new file mode 100644 index 00000000..70728327 --- /dev/null +++ b/spec/tasks/build_standalone_runner_spec.rb @@ -0,0 +1,63 @@ +require 'spec_helper.rb' + +describe "Build Standalone runner HTML task" do + + let(:jasmine_dev) { JasmineDev.new } + let(:standalone_temp_dir) { "#{Dir.tmpdir}/jasmine_test" } + + describe "build_standalone_runner" do + before do + reset_dir standalone_temp_dir + Dir.should_receive(:tmpdir).any_number_of_times.and_return(standalone_temp_dir) + + @standalone_staging_dir = File.join(standalone_temp_dir, 'jasmine_standalone') + + @version_dir = File.join(@standalone_staging_dir, "jasmine-standalone-#{jasmine_version}") + + @output = capture_output { jasmine_dev.build_standalone_runner } + end + + it "should tell the developer the task has started" do + @output.should match(/Building standalone runner HTML/) + end + + it "should copy a build SpecRunner.html to the staging directory" do + File.exist?(File.join(@version_dir, 'SpecRunner.html')).should be_true + end + + describe "should build the file that has HTML that" do + before do + html = File.read(File.join(@version_dir, 'SpecRunner.html')) + @runner = Nokogiri(html) + end + + it "should have the favicon tag" do + favicon_tag = @runner.css('link')[0] + favicon_tag['href'].should match("lib/jasmine-#{jasmine_version}/jasmine_favicon.png") + end + + it "should have the stylesheet" do + css_tag = @runner.css('link')[1] + css_tag['href'].should match("lib/jasmine-#{jasmine_version}/jasmine.css") + end + + it "should have the jasmine script tags" do + script_sources = @runner.css('script').collect {|tag| tag['src']} + script_sources.should include("lib/jasmine-#{jasmine_version}/jasmine.js") + script_sources.should include("lib/jasmine-#{jasmine_version}/jasmine-html.js") + end + + it "should have the example source files" do + script_sources = @runner.css('script').collect {|tag| tag['src']} + script_sources.should include('src/Player.js') + script_sources.should include('src/Song.js') + end + + it "should have the example source files" do + script_sources = @runner.css('script').collect {|tag| tag['src']} + script_sources.should include('spec/SpecHelper.js') + script_sources.should include('spec/PlayerSpec.js') + end + end + end +end diff --git a/spec/tasks/count_specs_spec.rb b/spec/tasks/count_specs_spec.rb new file mode 100644 index 00000000..3f4afd09 --- /dev/null +++ b/spec/tasks/count_specs_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper.rb' + +describe "Spec counting task" do + + let(:jasmine_dev) { JasmineDev.new } + + before do + @output = capture_output { jasmine_dev.count_specs } + end + + it "should tell the developer that the specs are being counted" do + @output.should match(/Counting specs/) + end + + it "should report the number of specs that will run in node" do + @output.should match(/\d+ \e\[0mspecs for Node.js/) + end + + it "should report the number of specs that will run in the browser" do + @output.should match(/\d+ \e\[0mspecs for Browser/) + end + + it "should remind the developer to check the count" do + @output.should match(/Please verify/) + end +end \ No newline at end of file diff --git a/spec/tasks/execute_specs_spec.rb b/spec/tasks/execute_specs_spec.rb new file mode 100644 index 00000000..040378ef --- /dev/null +++ b/spec/tasks/execute_specs_spec.rb @@ -0,0 +1,81 @@ +require 'spec_helper.rb' + +describe "Spec tasks" do + + let(:jasmine_dev) { JasmineDev.new } + + describe "execute_specs_in_node" do + describe "when Node.js is not present" do + before do + jasmine_dev.should_receive(:has_node?).and_return(false) + @output = capture_output { jasmine_dev.execute_specs_in_node } + end + + it "should prompt the user to install Node" do + @output.should match(/Node\.js is required/) + end + end + + describe "when Node.js is present" do + before do + jasmine_dev.should_receive(:has_node?).and_return(true) + @output = capture_output { jasmine_dev.execute_specs_in_node } + end + + it "should build the distribution" do + @output.should match(/Building Jasmine distribution/) + end + + it "should tell the developer that the specs are being counted" do + @output.should match(/Counting specs/) + end + + it "should tell the user that the specs are running in Node.js" do + @output.should match(/specs via Node/) + @output.should match(/Started/) + @output.should match(/\d+ specs, 0 failures/) + end + end + end + + describe "execute_specs_in_browser" do + before do + jasmine_dev.should_receive(:run) + @output = capture_output { jasmine_dev.execute_specs_in_browser } + end + + it "should build the distribution" do + @output.should match(/Building Jasmine distribution/) + end + + it "should tell the developer that the specs are being counted" do + @output.should match(/Counting specs/) + end + + it "should tell the user that the specs are running in the broswer" do + @output.should match(/specs via the default web browser/) + end + end + + describe "execute_specs" do + before do + @output = capture_output { jasmine_dev.execute_specs } + end + + it "should build the distribution" do + @output.should match(/Building Jasmine distribution/) + end + + it "should tell the developer that the specs are being counted" do + @output.should match(/Counting specs/) + end + + it "should tell the user that the specs are running in Node.js" do + @output.should match(/specs via Node/) + end + + it "should tell the user that the specs are running in the broswer" do + @output.should match(/specs via the default web browser/) + end + end +end \ No newline at end of file diff --git a/spec/tasks/jshint_spec.rb b/spec/tasks/jshint_spec.rb new file mode 100644 index 00000000..850c12f1 --- /dev/null +++ b/spec/tasks/jshint_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper.rb' + +describe "JSHint task" do + + let(:tmp_dir) { "#{Dir.tmpdir}/jasmine_tasks_test" } + let(:jasmine_dev) { JasmineDev.new } + + before do + reset_dir tmp_dir + end + + describe "when Node is not present" do + before do + jasmine_dev.should_receive(:has_node?).and_return(false) + @output = capture_output { jasmine_dev.js_hint } + end + + it "should not tell the user that lint is running" do + @output.should_not match(/Running JSHint/) + end + + it "should prompt the user to install Node" do + @output.should match(/Node\.js is required/) + end + end + + describe "when Node is present" do + before do + jasmine_dev.should_receive(:has_node?).and_return(true) + + @output = capture_output { jasmine_dev.js_hint } + end + + it "should tell the user that lint is running" do + @output.should match(/Running JSHint/) + @output.should match(/Jasmine JSHint PASSED/) + end + end +end \ No newline at end of file diff --git a/spec/tasks/release_spec.rb b/spec/tasks/release_spec.rb new file mode 100644 index 00000000..b7eff4b5 --- /dev/null +++ b/spec/tasks/release_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper.rb' + +describe "Release task" do + + let(:jasmine_dev) { JasmineDev.new } + + describe "when the pages submodule is not present" do + before do + jasmine_dev.should_receive(:has_pages_submodule?).and_return(false) + + @output = capture_output { jasmine_dev.release_prep } + end + + it "should tell the user the task is running" do + @output.should match(/Building Release/) + end + + it "should prompt the user to install the submodule" do + @output.should match(/Submodule for Github Pages isn't present/) + end + end + + describe "when the pages submodule is present" do + before do + JasmineDev.any_instance.should_receive(:write_version_files) + JasmineDev.any_instance.should_receive(:build_distribution) + JasmineDev.any_instance.should_receive(:build_standalone_distribution) + JasmineDev.any_instance.should_receive(:build_github_pages) + + jasmine_dev.should_receive(:has_pages_submodule?).and_return(true) + + @output = capture_output { jasmine_dev.release_prep } + end + + it "should tell the user the task is running" do + @output.should match(/Building Release/) + end + end +end \ No newline at end of file diff --git a/spec/tasks/version_spec.rb b/spec/tasks/version_spec.rb new file mode 100644 index 00000000..5018252a --- /dev/null +++ b/spec/tasks/version_spec.rb @@ -0,0 +1,55 @@ +require 'spec_helper.rb' + +describe "Version tasks" do + + let(:jasmine_dev) { JasmineDev.new } + + describe "write_version_files" do + + before do + @output = capture_output { jasmine_dev.write_version_files } + end + + it "should tell the user that the task has started" do + @output.should match(/Building version files/) + end + + it "should build the version.js file" do + js_version = File.read(File.join(project_root, 'src', 'version.js')) + js_version.should match(%Q{"build": #{jasmine_version_object["build"]}}) + js_version.should match(%Q{"minor": #{jasmine_version_object["minor"]}}) + js_version.should match(%Q{"build": #{jasmine_version_object["build"]}}) + + if jasmine_version_object["release_candidate"] + js_version.should match(%Q{"rc:" #{jasmine_version_object["release_candidate"]}}) + end + + js_version.should match(/"revision": \d+/) + end + + it "should build the jasmine-core ruby gem version" do + ruby_version = File.read(File.join(project_root, 'lib', 'jasmine-core', 'version.rb')) + ruby_version.should match(%Q{VERSION = "#{jasmine_version}"}) + end + end + + describe "display_version" do + describe "when Node.js is not present" do + before do + @output = capture_output { jasmine_dev.display_version } + end + + it "should display a version header" do + @output.should match(/Current version/) + end + + it "should display the current version Object" do + @output.should match(/Display version: \e\[33m\d+\.\d+\.\d+/) + end + + it "should display the current version string" do + @output.should match(/\{ "major": \d+, "minor": \d+, "build": \d+/) + end + end + end +end \ No newline at end of file diff --git a/src/version.js b/src/version.js index 34491afa..d0a28fea 100644 --- a/src/version.js +++ b/src/version.js @@ -2,5 +2,5 @@ jasmine.version_= { "major": 1, "minor": 1, "build": 0, - "revision": 1320442951 + "revision": 1333301588 }; diff --git a/tasks/build_dist.rb b/tasks/build_dist.rb deleted file mode 100644 index 6b6126a9..00000000 --- a/tasks/build_dist.rb +++ /dev/null @@ -1,51 +0,0 @@ -desc "Build core jasmine.js" -task :build_dist => [:lint, :write_version_files] do - puts 'Building Jasmine distribution from source'.cyan - - puts 'Building JavaScript'.yellow - concat_into('./lib/jasmine-core/jasmine.js') { core_sources + version_source_file } - concat_into('./lib/jasmine-core/jasmine-html.js') { html_sources } - - puts 'Buliding CSS'.yellow - system("compass compile") - FileUtils.cp('./src/html/jasmine.css', './lib/jasmine-core/jasmine.css') -end - -def concat_into(output_file, &block) - files = yield - File.open(output_file, 'w') do |out| - files.each do |f| - out << File.read(f) - end - end -end - -desc 'Check jasmine sources for coding problems' -task :lint => :require_node do - puts "Running JSHint via Node.js".cyan - system("node jshint/run.js") || exit(1) -end - -task :hint => :lint - -task :write_version_files do - scope = OpenStruct.new(:major => version_hash["major"], - :minor => version_hash["minor"], - :build => version_hash["build"], - :release_candidate => version_hash["release_candidate"], - :revision => Time.now.to_i) - - js_template = Tilt.new('./src/templates/version.js.erb') - File.open('./src/version.js', 'w+') do |f| - f << js_template.render(scope) - end - - rb_template = Tilt.new('./src/templates/version.rb.erb') - File.open('./lib/jasmine-core/version.rb', 'w+') do |f| - f << rb_template.render(scope) - end -end - -def version_source_file - Dir.glob('src/version.js') -end diff --git a/tasks/build_specs.rb b/tasks/build_specs.rb deleted file mode 100644 index 7d7e6da7..00000000 --- a/tasks/build_specs.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'ostruct' - -#build the browser spec for Jasmine core based on current tree -task :build_runner_html do - template = Tilt.new('spec/templates/runner.html.erb') - - File.open('spec/runner.html', 'w+') do |f| - scope = OpenStruct.new(:title => "Jasmine Spec Runner: Jasmine Core", - :favicon => favicon, - :jasmine_tags => jasmine_tags, - :source_tags => source_tags, - :spec_file_tags => spec_file_tags) - f << template.render(scope) - end -end - -def favicon - < -HTML -end - -def jasmine_tags - tags = %Q{} - tags << "\n " - tags << script_tags_for("../lib/jasmine-core/jasmine.js") - tags << "\n " - tags << undefined_catch - tags -end - -def undefined_catch - < - // yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw] - undefined = "diz be undefined yo"; - -HTML -end - -def source_tags - other_files = html_sources + console_sources - script_tags_for other_files.collect { |f| "../#{f}" } -end - -def spec_file_tags - spec_files = core_specfiles + html_specfiles + console_specfiles - script_tags_for spec_files.collect { |f| "../#{f}" } -end - diff --git a/tasks/helpers.rb b/tasks/helpers.rb deleted file mode 100644 index 66c9f683..00000000 --- a/tasks/helpers.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'json' - -def core_sources - first_sources = JSON.parse(File.read('./src/SourcesList.json')).collect { |f| "./src/core/#{f}" } - - remaining_sources = Dir.glob('./src/core/*.js').reject { |f| first_sources.include?(f) }.sort - - first_sources + remaining_sources -end - -def html_sources - ['./src/html/HtmlReporterHelpers.js'] + Dir.glob('./src/html/*.js') -end - -def console_sources - Dir.glob('./src/console/*.js') -end - -def core_specfiles - Dir.glob('./spec/core/*.js') -end - -def html_specfiles - Dir.glob('./spec/html/*.js') -end - -def console_specfiles - Dir.glob('./spec/console/*.js') -end - -def version_string - version = "#{version_hash['major']}.#{version_hash['minor']}.#{version_hash['build']}" - version += ".rc#{version_hash['release_candidate']}" if version_hash['release_candidate'] - version -end - -def version_hash - @version ||= JSON.parse(File.new("./src/version.json").read); -end - -def script_tags_for(files) - script_tag = Tilt::new('./spec/templates/script_tag.html.erb') - - srcs = (files.is_a?(String) ? [files] : files) - srcs.inject([]) do |tags, f| - scope = OpenStruct.new :file => f - tags << script_tag.render(scope) - tags - end.join("\n ") -end diff --git a/tasks/jasmine_dev.rb b/tasks/jasmine_dev.rb new file mode 100644 index 00000000..af4a7154 --- /dev/null +++ b/tasks/jasmine_dev.rb @@ -0,0 +1,18 @@ +require 'thor' +require 'json' +require 'term/ansicolor' +require 'tilt' +require 'ostruct' + +$:.unshift(File.join(File.dirname(__FILE__), "jasmine_dev")) + +require "base" +require "js_hint" +require "build_distribution" +require "build_github_pages" +require "build_standalone_distribution" +require "build_standalone_runner" +require "count_specs" +require "execute_specs" +require "release" +require "version" \ No newline at end of file diff --git a/tasks/jasmine_dev/base.rb b/tasks/jasmine_dev/base.rb new file mode 100644 index 00000000..ea140199 --- /dev/null +++ b/tasks/jasmine_dev/base.rb @@ -0,0 +1,56 @@ +class JasmineDev < Thor + include Thor::Actions + + def self.source_root + File.dirname(__FILE__) + end + + def self.source_paths + [ + File.join(JasmineDev.project_root, 'lib', 'jasmine-core'), + JasmineDev.project_root + ] + end + + def self.project_root + File.join(JasmineDev.source_root, '..', '..') + end + + def self.spacer + "\n--------------------" + end + + no_tasks do + # allows merged stdout in test with low-harassment + def run_with_output(*run_args) + say run *run_args + end + + def node_installed? + return true if has_node? + + say "Node.js is required to develop Jasmine. Please visit http://nodejs.org to install. ", + :red + false + end + + def has_node? + run "which node", :verbose => false, :capture => true + last_exit_code = $?.to_s[-1] + + last_exit_code == '0' + end + + def pages_submodule_installed? + return true if has_pages_submodule? + + say "Submodule for Github Pages isn't present. Run git submodule update --init", + :red + false + end + + def has_pages_submodule? + File.exist?(File.join(JasmineDev.project_root, 'pages', 'download.html')) + end + end +end diff --git a/tasks/jasmine_dev/build_distribution.rb b/tasks/jasmine_dev/build_distribution.rb new file mode 100644 index 00000000..6986e937 --- /dev/null +++ b/tasks/jasmine_dev/build_distribution.rb @@ -0,0 +1,66 @@ +class JasmineDev < Thor + + desc "build_distribution", "Build Jasmine js & css files" + def build_distribution(directory = "./lib/jasmine-core") + invoke :js_hint + + say JasmineDev.spacer + + say "Building Jasmine distribution from source into #{directory}", :cyan + + say 'Building JavaScript...', :yellow + + inside directory do + create_file "jasmine.js", + concat_contents_of(jasmine_js_paths), + :force => true + create_file "jasmine-html.js", + concat_contents_of(jasmine_html_js_paths), + :force => true + end + + say 'Building CSS...', :yellow + + run "compass compile", :capture => true + + copy_file File.join("#{JasmineDev.project_root}", 'src', 'html', 'jasmine.css'), + File.join(directory, 'jasmine.css') + end + + no_tasks do + def jasmine_js_paths + sources_list = File.read(File.join(JasmineDev.project_root, 'src', 'SourcesList.json')) + first_paths = JSON.parse(sources_list).collect do |f| + File.join(JasmineDev.project_root, 'src', 'core', f) + end + + remaining_paths = Dir.glob(File.join(JasmineDev.project_root, 'src', 'core', '*.js')) + remaining_paths << File.join(JasmineDev.project_root, 'src', 'version.js') + + add_only_new_elements(first_paths, remaining_paths) + end + + def jasmine_html_js_paths + first_paths = [] + first_paths << File.join(JasmineDev.project_root, 'src', 'html', 'HtmlReporterHelpers.js') + first_paths += Dir.glob(File.join('.', 'src', 'html', '*.js')) + + remaining_paths = Dir.glob(File.join(JasmineDev.project_root, 'src', 'html', '*.js')) + add_only_new_elements(first_paths, remaining_paths) + end + + def add_only_new_elements(first, remaining) + remaining.inject(first) do |result, element| + result << element unless result.include?(element) + result + end + end + + def concat_contents_of(paths) + paths.inject("") do |string, path| + string << File.read(path) + string + end + end + end +end \ No newline at end of file diff --git a/tasks/jasmine_dev/build_github_pages.rb b/tasks/jasmine_dev/build_github_pages.rb new file mode 100644 index 00000000..63300605 --- /dev/null +++ b/tasks/jasmine_dev/build_github_pages.rb @@ -0,0 +1,18 @@ +class JasmineDev < Thor + + desc "build_github_pages", "Build static pages for pivotal.github.com/jasmine" + def build_github_pages(pages_dir = File.expand_path(File.join('.', 'pages'))) + say JasmineDev.spacer + + say "Building Github Pages...", :cyan + + return unless pages_submodule_installed? + + pages_output = File.join(pages_dir, 'pages_output') + FileUtils.rm_r(pages_output) if File.exist?(pages_output) + + inside File.join('pages', 'pages_source') do + run_with_output "frank export #{pages_output}", :capture => true + end + end +end \ No newline at end of file diff --git a/tasks/jasmine_dev/build_standalone_distribution.rb b/tasks/jasmine_dev/build_standalone_distribution.rb new file mode 100644 index 00000000..473e01d9 --- /dev/null +++ b/tasks/jasmine_dev/build_standalone_distribution.rb @@ -0,0 +1,49 @@ +class JasmineDev < Thor + include Thor::Actions + + desc "build_standalone_distribution", "Build Jasmine standalone distribution" + def build_standalone_distribution(download_dir = File.expand_path(File.join('.', 'pages', 'downloads'))) + invoke :build_distribution + + say JasmineDev.spacer + + say "Building standalone distribution...", :cyan + + say "Staging files...", :yellow + + lib_files.each do |f| + copy_file f, File.join(standalone_temp_dir, 'lib', "jasmine-#{version_string}", f) + end + + ['src', 'spec'].each do |dir| + directory File.join('lib', 'jasmine-core', 'example', dir), + File.join(standalone_temp_dir, dir) + end + + invoke :build_standalone_runner + + say "Zipping distribution...", :yellow + + inside standalone_temp_dir do + run_with_output "zip -rq ../jasmine-standalone-#{jasmine_version}.zip ." + + say "Copying Zip file to downloads directory", :yellow + run "cp ../jasmine-standalone-#{jasmine_version}.zip #{download_dir}" + end + + end + + no_tasks do + def standalone_temp_dir + @standalone_temp_dir ||= File.join(Dir.tmpdir, 'jasmine_standalone', "jasmine-standalone-#{version_string}") + end + + def lib_files + %w{ jasmine.js jasmine-html.js jasmine.css MIT.LICENSE } + end + + def example_path + File.join('lib', "jasmine-#{version_string}") + end + end +end \ No newline at end of file diff --git a/tasks/jasmine_dev/build_standalone_runner.rb b/tasks/jasmine_dev/build_standalone_runner.rb new file mode 100644 index 00000000..0f440657 --- /dev/null +++ b/tasks/jasmine_dev/build_standalone_runner.rb @@ -0,0 +1,59 @@ +class JasmineDev < Thor + include Thor::Actions + + desc "build_standalone_runner", "Build HTML spec runner for Jasmine standalone distribution" + + def build_standalone_runner + say JasmineDev.spacer + + say "Building standalone runner HTML...", :cyan + + create_file File.join(standalone_temp_dir, 'SpecRunner.html') do + template = Tilt.new(File.join('spec', 'templates','runner.html.erb')) + + scope = OpenStruct.new(:title => "Jasmine Spec Runner", + :favicon => example_favicon, + :jasmine_tags => example_jasmine_tags, + :source_tags => example_source_tags, + :spec_file_tags => example_spec_tags) + template.render(scope) + end + end + + no_tasks do + def standalone_temp_dir + @standalone_temp_dir ||= File.join(Dir.tmpdir, 'jasmine_standalone', "jasmine-standalone-#{version_string}") + end + + def example_path + File.join('lib', "jasmine-#{version_string}") + end + + def example_favicon + %Q{} + end + + def script_tags_for(files) + srcs = (files.is_a?(String) ? [files] : files) + srcs.inject([]) do |tags, file| + tags << %Q{} + tags + end.join("\n ") + end + + def example_jasmine_tags + tags = %Q{} + tags << "\n " + tags << script_tags_for(["#{example_path}/jasmine.js", "#{example_path}/jasmine-html.js"]) + tags + end + + def example_source_tags + script_tags_for ['spec/SpecHelper.js', 'spec/PlayerSpec.js'] + end + + def example_spec_tags + script_tags_for ['src/Player.js', 'src/Song.js'] + end + end +end \ No newline at end of file diff --git a/tasks/jasmine_dev/count_specs.rb b/tasks/jasmine_dev/count_specs.rb new file mode 100644 index 00000000..b6839393 --- /dev/null +++ b/tasks/jasmine_dev/count_specs.rb @@ -0,0 +1,29 @@ +class JasmineDev < Thor + + desc "count_specs", "Count the number of specs for each test runner" + def count_specs + say JasmineDev.spacer + say "Counting specs...", :cyan + + core_spec_count = count_specs_in(File.join('spec', 'core')) + console_spec_count = count_specs_in(File.join('spec', 'console')) + html_spec_count = count_specs_in(File.join('spec', 'html')) + + say "#{(core_spec_count + console_spec_count).to_s} ", :yellow + say "specs for Node.js runner (exclude DOM-related specs)" + say "#{(core_spec_count + console_spec_count + html_spec_count).to_s} ", :yellow + say "specs for Browser runner (all specs)" + say "\n" + say "Please verify that these numbers match the runner output." + end + + no_tasks do + def count_specs_in(relative_path) + files = Dir.glob(File.join(JasmineDev.project_root, relative_path, '*.js')) + files.inject(0) do |count, file| + File.read(file).scan(/\sit\s*\(/) { |s| count += 1 } + count + end + end + end +end \ No newline at end of file diff --git a/tasks/jasmine_dev/execute_specs.rb b/tasks/jasmine_dev/execute_specs.rb new file mode 100644 index 00000000..fa954135 --- /dev/null +++ b/tasks/jasmine_dev/execute_specs.rb @@ -0,0 +1,52 @@ +class JasmineDev < Thor + + desc "execute_specs_in_node", "Run all relevant specs in Node.js" + + def execute_specs_in_node + return unless node_installed? + + invoke :build_distribution + invoke :count_specs + + say JasmineDev.spacer + + say "Running all appropriate specs via Node.js...", :cyan + + with_color_option = Term::ANSIColor.coloring? ? "--color" : "--noColor" + + run_with_output "node spec/node_suite.js #{with_color_option}", :capture => true + end + + desc "execute_specs_in_browser", "Run all relevent specs in your default browser" + + def execute_specs_in_browser + invoke :build_distribution + invoke :count_specs + + say JasmineDev.spacer + + say "Running all appropriate specs via the default web browser...", :cyan + + open_specs_in_browser + end + + desc "execute_specs", "Run all of Jasmine's specs" + + def execute_specs + invoke :execute_specs_in_node + invoke :execute_specs_in_browser + end + + no_tasks do + def open_specs_in_browser + require 'rbconfig' + + case Object.const_get(defined?(RbConfig) ? :RbConfig : :Config)::CONFIG['host_os'] + when /linux/ + run "xdg-open spec/runner.html" + else + run "open spec/runner.html" + end + end + end +end diff --git a/tasks/jasmine_dev/js_hint.rb b/tasks/jasmine_dev/js_hint.rb new file mode 100644 index 00000000..d97a93a6 --- /dev/null +++ b/tasks/jasmine_dev/js_hint.rb @@ -0,0 +1,13 @@ +class JasmineDev < Thor + + desc "js_hint", "Run Jasmine source through JSHint" + def js_hint + say JasmineDev.spacer + + return unless node_installed? + + say "Running JSHint on Jasmine source and specs...", :cyan + + run_with_output "node jshint/run.js", :capture => true + end +end \ No newline at end of file diff --git a/tasks/jasmine_dev/release.rb b/tasks/jasmine_dev/release.rb new file mode 100644 index 00000000..5458b25d --- /dev/null +++ b/tasks/jasmine_dev/release.rb @@ -0,0 +1,16 @@ +class JasmineDev < Thor + + desc 'release_prep', "Update version and build distributions" + def release_prep + say JasmineDev.spacer + + say "Building Release...", :cyan + + return unless pages_submodule_installed? + + invoke :write_version_files + invoke :build_distribution + invoke :build_standalone_distribution + invoke :build_github_pages + end +end \ No newline at end of file diff --git a/tasks/jasmine_dev/version.rb b/tasks/jasmine_dev/version.rb new file mode 100644 index 00000000..18f42a03 --- /dev/null +++ b/tasks/jasmine_dev/version.rb @@ -0,0 +1,54 @@ +class JasmineDev < Thor + + desc "write_version_files", "Write out version files" + def write_version_files + say JasmineDev.spacer + + say "Building version files", :cyan + + scope = OpenStruct.new(:major => version_object["major"], + :minor => version_object["minor"], + :build => version_object["build"], + :release_candidate => version_object["release_candidate"], + :revision => Time.now.to_i) + + js_template = Tilt.new(File.join(JasmineDev.project_root, 'src', 'templates', 'version.js.erb')) + create_file File.join(JasmineDev.project_root, 'src', 'version.js'), :force => true do + js_template.render(scope) + end + end + + desc "display_version", "Display version currently stored in source" + def display_version + + say "Current version information from src/version.json", :cyan + + say "Display version: " + say "#{version_string}", :yellow + + say "Version object: " + say "#{version_object_old}", :yellow + end + + no_tasks do + def version + @version ||= File.read(File.join(JasmineDev.project_root, 'src', 'version.json')) + end + + def version_string + display = "#{version_object['major']}.#{version_object['minor']}.#{version_object['build']}" + display += ".rc#{version_object['release_candidate']}" if version_object['release_candidate'] + display + end + + def version_object + @version_object ||= JSON.parse(version) + end + + def version_object_old + version.gsub("\n", " "). + gsub(/\s+/, " "). + gsub(/\}\s+$/, "}") + end + end +end \ No newline at end of file diff --git a/tasks/pages.rb b/tasks/pages.rb deleted file mode 100644 index 434f4543..00000000 --- a/tasks/pages.rb +++ /dev/null @@ -1,13 +0,0 @@ -desc "Build the Github pages HTML" -task :build_pages => :require_pages_submodule do - Dir.chdir("pages") do - FileUtils.rm_r('pages_output') if File.exist?('pages_output') - Dir.chdir('pages_source') do - system("frank export ../pages_output") - end - puts "\n" - puts "Copying built website to the root of the gh-pages branch".cyan - puts "\n\n" - system("cp -r pages_output/* .") - end -end \ No newline at end of file diff --git a/tasks/spec.rb b/tasks/spec.rb deleted file mode 100644 index ac496d6f..00000000 --- a/tasks/spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -desc "Run spec suite: Browser, Node, JSHint" -task :spec => ["build_dist", "count_specs", "spec:node", "spec:browser"] - -desc 'Run specs in Node.js' -task "spec:node" => [:count_specs, :require_node] do - puts "Running all appropriate specs via Node.js".cyan - - color = Term::ANSIColor.coloring? ? "--color" : "--noColor" - system("node spec/node_suite.js #{color}") -end - -desc "Run specs in the default browser (MacOS, Linux)" -task "spec:browser" => [:count_specs, :build_runner_html] do - puts "Running all appropriate specs via the default web browser".cyan - - require 'rbconfig' - case Object.const_get(defined?(RbConfig) ? :RbConfig : :Config)::CONFIG['host_os'] - when /linux/ - system("xdg-open spec/runner.html") - else - system("open spec/runner.html") - end -end - -#Count number of specs in Jasmine core -task :count_specs do - core_specs_count = count_specs_in(Dir.glob('spec/core/*.js')) - console_spec_count = count_specs_in(Dir.glob('spec/console/*.js')) - html_spec_count = count_specs_in(Dir.glob('spec/html/*.js')) - - puts "\n" - puts "#{(core_specs_count + console_spec_count).to_s.yellow.bold} specs for Node.js runner (exclude DOM-related specs)" - puts "#{(core_specs_count + console_spec_count + html_spec_count).to_s.yellow.bold} specs for Browser runner (all specs)" - puts "\n" - puts "Please verify that these numbers match the runner output." - puts "\n" -end - -def count_specs_in(files) - files.inject(0) do |count, file| - File.read(file).scan(/\sit\s*\(/) {|s| count += 1} - count - end -end diff --git a/tasks/standalone.rb b/tasks/standalone.rb deleted file mode 100644 index b29007d3..00000000 --- a/tasks/standalone.rb +++ /dev/null @@ -1,91 +0,0 @@ -require 'ostruct' - -desc "Build standalone distribution" -task :standalone => [:require_pages_submodule, :protect_current_dist_zip, :build_spec_runner_html] do - require 'tmpdir' - - zip_root = File.join(Dir.tmpdir, "zip_root") - temp_dir = File.join(zip_root, "jasmine-standalone-#{version_string}") - puts "Building Example Project in #{temp_dir}" - FileUtils.rm_r temp_dir if File.exist?(temp_dir) - FileUtils.mkdir_p(temp_dir) - - root = File.expand_path(File.join(File.dirname(__FILE__), '..')) - FileUtils.mkdir_p(File.join(root, "example")) - FileUtils.cp_r(File.join(root, 'example/.'), File.join(temp_dir)) - - lib_dir = File.join(temp_dir, "lib/jasmine-#{version_string}") - FileUtils.mkdir_p(lib_dir) - { - "images/jasmine_favicon.png" => "jasmine_favicon.png", - "lib/jasmine-core/jasmine.js" => "jasmine.js", - "lib/jasmine-core/jasmine-html.js" => "jasmine-html.js", - "lib/jasmine-core/jasmine.css" => "jasmine.css", - "MIT.LICENSE" => "MIT.LICENSE" - }.each_pair do |src, dest| - FileUtils.cp(File.join(root, src), File.join(lib_dir, dest)) - end - - dist_dir = File.join(root, 'pages/downloads') - zip_file_name = File.join(dist_dir, "jasmine-standalone-#{version_string}.zip") - - puts "Zipping Example Project and moving to #{zip_file_name}" - exec "cd #{zip_root} && zip #{zip_file_name} -r . -x .[a-zA-Z0-9]*" -end - -#Build SpecRunner.html for standalone dist example project -task :build_spec_runner_html do - template = Tilt.new('spec/templates/runner.html.erb') - - File.open('lib/jasmine-core/example/SpecRunner.html', 'w+') do |f| - scope = OpenStruct.new(:title => "Jasmine Spec Runner", - :favicon => example_favicon, - :jasmine_tags => example_jasmine_tags, - :source_tags => example_source_tags, - :spec_file_tags => example_spec_tags) - f << template.render(scope) - end -end - -def example_path - "lib/jasmine-#{version_string}" -end - -def example_favicon - < -HTML -end - -def example_jasmine_tags - tags = %Q{} - tags << "\n " - tags << script_tags_for(["#{example_path}/jasmine.js", "#{example_path}/jasmine-html.js"]) - tags -end - -def example_source_tags - script_tags_for ['spec/SpecHelper.js', 'spec/PlayerSpec.js'] -end - -def example_spec_tags - script_tags_for ['src/Player.js', 'src/Song.js'] -end - - -task :protect_current_dist_zip do - root = File.expand_path(File.join(File.dirname(__FILE__), '..')) - dist_dir = File.join(root, 'pages/downloads') - zip_file_name = File.join(dist_dir, "jasmine-standalone-#{version_string}.zip") - - zip_present_message = "\n\n" - zip_present_message << "==> STOPPED <==".red - zip_present_message << "\n\n" - zip_present_message << "The file ".red + "#{zip_file_name}" + " already exists.".red + "\n" - zip_present_message << "If you should be building the next version, update src/version.json" - zip_present_message << "\n" - zip_present_message << "If the version is correct, you must be trying to re-build the standalone ZIP. Delete the ZIP and rebuild." - zip_present_message << "\n" - - raise zip_present_message if File.exist?(zip_file_name) -end diff --git a/tasks/version.rb b/tasks/version.rb deleted file mode 100644 index c98ce9b3..00000000 --- a/tasks/version.rb +++ /dev/null @@ -1,5 +0,0 @@ -task :version do - require 'pp' - pp version_hash - pp version_string -end \ No newline at end of file