diff --git a/spec/integration/default_namespace.rb b/spec/integration/default_namespace.rb deleted file mode 100644 index b2d64e1..0000000 --- a/spec/integration/default_namespace.rb +++ /dev/null @@ -1,77 +0,0 @@ -require 'spec_helper' - -describe ActiveAdmin::Application do - - include Rails.application.routes.url_helpers - - [false, nil].each do |value| - - describe "with a #{value} default namespace" do - - before(:all) do - @__original_application = ActiveAdmin.application - application = ActiveAdmin::Application.new - application.default_namespace = value - ActiveAdmin.application = application - load_defaults! - reload_routes! - end - - after(:all) do - ActiveAdmin.application = @__original_application - end - - it "should generate a dashboard controller" do - defined?(::DashboardController).should be_true - end - - it "should generate a dashboard route" do - dashboard_path.should == "/" - end - - it "should generate a log out path" do - destroy_admin_user_session_path.should == "/admin_users/logout" - end - - it "should generate a log in path" do - new_admin_user_session_path.should == "/admin_users/login" - end - - end - - end - - describe "with a test default namespace" do - - before(:all) do - @__original_application = ActiveAdmin.application - application = ActiveAdmin::Application.new - application.default_namespace = :test - ActiveAdmin.application = application - load_defaults! - reload_routes! - end - - after(:all) do - ActiveAdmin.application = @__original_application - end - - it "should generate a dashboard controller" do - defined?(::Test::DashboardController).should be_true - end - - it "should generate a dashboard route" do - test_dashboard_path.should == "/test" - end - - it "should generate a log out path" do - destroy_admin_user_session_path.should == "/test/logout" - end - - it "should generate a log in path" do - new_admin_user_session_path.should == "/test/login" - end - - end - -end diff --git a/spec/integration/javascript_spec.rb b/spec/integration/javascript_spec.rb deleted file mode 100644 index 92f66fe..0000000 --- a/spec/integration/javascript_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'spec_helper' -require 'jslint' - -%x[which java] -if $? == 0 # Only run the JS Lint test if Java is installed - describe "Javascript" do - before do - @lint = JSLint::Lint.new( - :paths => ['public/javascripts/**/*.js'], - :exclude_paths => ['public/javascripts/vendor/**/*.js'], - :config_path => 'spec/support/jslint.yml' - ) - end - - it "should not have any syntax errors" do - @lint.run - end - end -end - diff --git a/spec/integration/memory_spec.rb b/spec/integration/memory_spec.rb deleted file mode 100644 index ead2e7d..0000000 --- a/spec/integration/memory_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'spec_helper' - -# These tests show the memory leak that is currently in Active Admin. They -# are all marked as pending until they pass. To work on them, comment out the -# pending method call in #it_should_not_leak -describe "Memory Leak" do - - def count_instances_of(klass) - ObjectSpace.each_object(klass) { } - end - - def self.it_should_not_leak(klass) - it "should not leak #{klass}" do - GC.start - - count = count_instances_of(klass) - - load_defaults! - GC.start - - count_instances_of(klass).should == count - end - end - - it_should_not_leak ActiveAdmin::Namespace - it_should_not_leak ActiveAdmin::Resource - -end diff --git a/spec/integration/stylesheets_spec.rb b/spec/integration/stylesheets_spec.rb deleted file mode 100644 index 760a5cb..0000000 --- a/spec/integration/stylesheets_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'spec_helper' - -describe "Stylesheets" do - if Rails.version[0..2] == '3.1' - require "sprockets" - context "when Rails 3.1.x" do - let(:css) do - assets = Rails.application.assets - assets.find_asset("active_admin.css") - end - it "should successfully render the scss stylesheets using sprockets" do - css.should_not be_nil - end - it "should not have any syntax errors" do - css.to_s.should_not include("Syntax error:") - end - end - end - - if Rails.version[0..2] == '3.0' - context "when Rails 3.0.x" do - let(:stylesheet_path) do - Rails.root + 'public/stylesheets/active_admin.css' - end - - before do - "rm #{stylesheet_path}" if File.exists?(stylesheet_path) - Sass::Plugin.force_update_stylesheets - end - - it "should render the scss stylesheets using SASS" do - File.exists?(stylesheet_path).should be_true - end - - it "should not have any syntax errors" do - css = File.read(stylesheet_path) - css.should_not include("Syntax error:") - end - end - end -end diff --git a/spec/javascripts/coffeescripts/jquery.aa.checkbox-toggler-spec.js.coffee b/spec/javascripts/coffeescripts/jquery.aa.checkbox-toggler-spec.js.coffee deleted file mode 100644 index 755761c..0000000 --- a/spec/javascripts/coffeescripts/jquery.aa.checkbox-toggler-spec.js.coffee +++ /dev/null @@ -1,50 +0,0 @@ -describe "AA.CheckboxToggler", -> - - beforeEach -> - loadFixtures('checkboxes.html') - - @collection = $("#collection") - @toggle_all = @collection.find(".toggle_all") - - @checkboxes = @collection.find(":checkbox").not(@toggle_all) - - - new AA.CheckboxToggler({}, @collection) - - describe "on init", -> - it "should raise an error if container not found", -> - expect( => new AA.CheckboxToggler({}) ).toThrow("Container element not found") - - it "should raise an error if 'toggle all' checkbox not found", -> - @toggle_all.remove() - expect( => new AA.CheckboxToggler({}, @collection); ).toThrow("'toggle all' checkbox not found") - - describe "'toggle all' checkbox", -> - it "should check all checkboxes when checked", -> - @toggle_all.trigger("click") - expect(@checkboxes).toHaveAttr("checked") - - it "should uncheck all checkboxes when unchecked", -> - @toggle_all.trigger("click") - @toggle_all.trigger("click") - expect(@checkboxes).not.toHaveAttr("checked") - - describe "individual checkboxes", -> - - describe "when all checkboxes are selected and one is unchecked", -> - beforeEach -> - @collection.find(":checkbox").attr("checked", "checked") - @collection.find("#item_1").trigger("click") - - it "should uncheck the 'toggle all' checkbox", -> - expect(@toggle_all).not.toHaveAttr("checked") - - describe "when the last checkbox is checked", -> - beforeEach -> - @checkboxes.attr("checked", "checked") - @collection.find("#item_1").removeAttr("checked") - @collection.find("#item_1").trigger("click") - - it "should check the 'toggle all' checkbox", -> - expect(@toggle_all).toHaveAttr("checked") - diff --git a/spec/javascripts/coffeescripts/jquery.aa.popover-spec.js.coffee b/spec/javascripts/coffeescripts/jquery.aa.popover-spec.js.coffee deleted file mode 100644 index 8e672f4..0000000 --- a/spec/javascripts/coffeescripts/jquery.aa.popover-spec.js.coffee +++ /dev/null @@ -1,82 +0,0 @@ -describe "AA.Popover", -> - $wrapper = undefined - $button = undefined - $popover = undefined - popover = undefined - beforeEach -> - $wrapper = $(inject(id: "wrapper")) - $button = $(inject( - el: "a" - id: "my_popover_button" - attrs: - href: "#my_popover" - )) - $popover = $(inject(id: "my_popover")) - $button.popover - fadeInDuration: 0 - fadeOutDuration: 0 - - popover = $button.data("popover") - - describe "opening button / link is pressed", -> - it "should open the popover", -> - $button.trigger "click" - expect($("#my_popover")).toBeVisible() - - describe "when initiated", -> - it "should be hidden", -> - expect($popover).toBeHidden() - - it "should be have class popover", -> - expect($popover).toHaveClass "popover" - - describe "nipple", -> - it "should exist", -> - expect($popover).toContain ".popover_nipple" - - describe "when open is called", -> - beforeEach -> - expect($popover).toBeHidden() - $button.popover "open" - - it "should be open", -> - expect($popover).toBeVisible() - - describe "when destroy is called", -> - beforeEach -> - $button.popover "destroy" - - it "should not have popover stored as a data attr", -> - expect($button.data("popover")).toEqual `undefined` - - it "should not be bound to any event listeners", -> - expect($button.data("events")).toEqual `undefined` - - describe "when it's already open", -> - beforeEach -> - $button.popover "open" - - describe "when close is called", -> - beforeEach -> - $button.popover "close" - - it "should close", -> - expect($popover).toBeHidden() - - describe "when user clicks outside", -> - beforeEach -> - $button.popover "open" - $("#wrapper").trigger "click" - - it "should close", -> - expect($popover).toBeHidden() - - describe "options", -> - describe "autoOpen set to false", -> - beforeEach -> - $button.popover "destroy" - $button.popover autoOpen: false - - it "should not open when the link is clicked", -> - $button.trigger "click" - expect($("#my_popover")).toBeHidden() diff --git a/spec/javascripts/coffeescripts/jquery.aa.table-checkbox-toggler-spec.js.coffee b/spec/javascripts/coffeescripts/jquery.aa.table-checkbox-toggler-spec.js.coffee deleted file mode 100644 index 9ba8d1d..0000000 --- a/spec/javascripts/coffeescripts/jquery.aa.table-checkbox-toggler-spec.js.coffee +++ /dev/null @@ -1,34 +0,0 @@ -describe "AA.TableCheckboxToggler", -> - - beforeEach -> - loadFixtures('table_checkboxes.html'); - - @collection = $("#collection") - @toggle_all = @collection.find(".toggle_all") - - @checkboxes = @collection.find(":checkbox").not(@toggle_all) - - new AA.TableCheckboxToggler({}, @collection) - - describe "'selected' class for table row", -> - it "should add the class 'selected' to rows when their checkbox is checked ", -> - checkbox = $("#item_1") - checkbox.attr("checked", "checked") - checkbox.trigger("change") - - expect(checkbox.parents("tr")).toHaveAttr("class", "selected") - - it "should remove the class 'selected' from rows when their checkbox is unchecked ", -> - checkbox = $("#item_1") - checkbox.trigger("change") - - expect(checkbox.parents("tr")).not.toHaveAttr("class", "selected") - - describe "clicking a cell", -> - it "should toggle the checkbox when a cell is clicked", -> - checkbox = $("#item_1") - row = checkbox.parents("td") - $(row).trigger("click") - - expect(checkbox).toHaveAttr("checked", "checked") - diff --git a/spec/javascripts/compiled/jquery.aa.checkbox-toggler-spec.js b/spec/javascripts/compiled/jquery.aa.checkbox-toggler-spec.js deleted file mode 100644 index ee2dcb7..0000000 --- a/spec/javascripts/compiled/jquery.aa.checkbox-toggler-spec.js +++ /dev/null @@ -1,60 +0,0 @@ -(function() { - - describe("AA.CheckboxToggler", function() { - beforeEach(function() { - loadFixtures('checkboxes.html'); - this.collection = $("#collection"); - this.toggle_all = this.collection.find(".toggle_all"); - this.checkboxes = this.collection.find(":checkbox").not(this.toggle_all); - return new AA.CheckboxToggler({}, this.collection); - }); - describe("on init", function() { - it("should raise an error if container not found", function() { - var _this = this; - return expect(function() { - return new AA.CheckboxToggler({}); - }).toThrow("Container element not found"); - }); - return it("should raise an error if 'toggle all' checkbox not found", function() { - var _this = this; - this.toggle_all.remove(); - return expect(function() { - return new AA.CheckboxToggler({}, _this.collection); - }).toThrow("'toggle all' checkbox not found"); - }); - }); - describe("'toggle all' checkbox", function() { - it("should check all checkboxes when checked", function() { - this.toggle_all.trigger("click"); - return expect(this.checkboxes).toHaveAttr("checked"); - }); - return it("should uncheck all checkboxes when unchecked", function() { - this.toggle_all.trigger("click"); - this.toggle_all.trigger("click"); - return expect(this.checkboxes).not.toHaveAttr("checked"); - }); - }); - return describe("individual checkboxes", function() { - describe("when all checkboxes are selected and one is unchecked", function() { - beforeEach(function() { - this.collection.find(":checkbox").attr("checked", "checked"); - return this.collection.find("#item_1").trigger("click"); - }); - return it("should uncheck the 'toggle all' checkbox", function() { - return expect(this.toggle_all).not.toHaveAttr("checked"); - }); - }); - return describe("when the last checkbox is checked", function() { - beforeEach(function() { - this.checkboxes.attr("checked", "checked"); - this.collection.find("#item_1").removeAttr("checked"); - return this.collection.find("#item_1").trigger("click"); - }); - return it("should check the 'toggle all' checkbox", function() { - return expect(this.toggle_all).toHaveAttr("checked"); - }); - }); - }); - }); - -}).call(this); diff --git a/spec/javascripts/compiled/jquery.aa.popover-spec.js b/spec/javascripts/compiled/jquery.aa.popover-spec.js deleted file mode 100644 index d4b82b0..0000000 --- a/spec/javascripts/compiled/jquery.aa.popover-spec.js +++ /dev/null @@ -1,106 +0,0 @@ -(function() { - - describe("AA.Popover", function() { - var $button, $popover, $wrapper, popover; - $wrapper = void 0; - $button = void 0; - $popover = void 0; - popover = void 0; - beforeEach(function() { - $wrapper = $(inject({ - id: "wrapper" - })); - $button = $(inject({ - el: "a", - id: "my_popover_button", - attrs: { - href: "#my_popover" - } - })); - $popover = $(inject({ - id: "my_popover" - })); - $button.popover({ - fadeInDuration: 0, - fadeOutDuration: 0 - }); - return popover = $button.data("popover"); - }); - describe("opening button / link is pressed", function() { - return it("should open the popover", function() { - $button.trigger("click"); - return expect($("#my_popover")).toBeVisible(); - }); - }); - describe("when initiated", function() { - it("should be hidden", function() { - return expect($popover).toBeHidden(); - }); - it("should be have class popover", function() { - return expect($popover).toHaveClass("popover"); - }); - return describe("nipple", function() { - return it("should exist", function() { - return expect($popover).toContain(".popover_nipple"); - }); - }); - }); - describe("when open is called", function() { - beforeEach(function() { - expect($popover).toBeHidden(); - return $button.popover("open"); - }); - return it("should be open", function() { - return expect($popover).toBeVisible(); - }); - }); - describe("when destroy is called", function() { - beforeEach(function() { - return $button.popover("destroy"); - }); - it("should not have popover stored as a data attr", function() { - return expect($button.data("popover")).toEqual(undefined); - }); - return it("should not be bound to any event listeners", function() { - return expect($button.data("events")).toEqual(undefined); - }); - }); - describe("when it's already open", function() { - beforeEach(function() { - return $button.popover("open"); - }); - describe("when close is called", function() { - beforeEach(function() { - return $button.popover("close"); - }); - return it("should close", function() { - return expect($popover).toBeHidden(); - }); - }); - return describe("when user clicks outside", function() { - beforeEach(function() { - $button.popover("open"); - return $("#wrapper").trigger("click"); - }); - return it("should close", function() { - return expect($popover).toBeHidden(); - }); - }); - }); - return describe("options", function() { - return describe("autoOpen set to false", function() { - beforeEach(function() { - $button.popover("destroy"); - return $button.popover({ - autoOpen: false - }); - }); - return it("should not open when the link is clicked", function() { - $button.trigger("click"); - return expect($("#my_popover")).toBeHidden(); - }); - }); - }); - }); - -}).call(this); diff --git a/spec/javascripts/compiled/jquery.aa.table-checkbox-toggler-spec.js b/spec/javascripts/compiled/jquery.aa.table-checkbox-toggler-spec.js deleted file mode 100644 index f412a5a..0000000 --- a/spec/javascripts/compiled/jquery.aa.table-checkbox-toggler-spec.js +++ /dev/null @@ -1,37 +0,0 @@ -(function() { - - describe("AA.TableCheckboxToggler", function() { - beforeEach(function() { - loadFixtures('table_checkboxes.html'); - this.collection = $("#collection"); - this.toggle_all = this.collection.find(".toggle_all"); - this.checkboxes = this.collection.find(":checkbox").not(this.toggle_all); - return new AA.TableCheckboxToggler({}, this.collection); - }); - describe("'selected' class for table row", function() { - it("should add the class 'selected' to rows when their checkbox is checked ", function() { - var checkbox; - checkbox = $("#item_1"); - checkbox.attr("checked", "checked"); - checkbox.trigger("change"); - return expect(checkbox.parents("tr")).toHaveAttr("class", "selected"); - }); - return it("should remove the class 'selected' from rows when their checkbox is unchecked ", function() { - var checkbox; - checkbox = $("#item_1"); - checkbox.trigger("change"); - return expect(checkbox.parents("tr")).not.toHaveAttr("class", "selected"); - }); - }); - return describe("clicking a cell", function() { - return it("should toggle the checkbox when a cell is clicked", function() { - var checkbox, row; - checkbox = $("#item_1"); - row = checkbox.parents("td"); - $(row).trigger("click"); - return expect(checkbox).toHaveAttr("checked", "checked"); - }); - }); - }); - -}).call(this); diff --git a/spec/javascripts/fixtures/checkboxes.html b/spec/javascripts/fixtures/checkboxes.html deleted file mode 100644 index 245b3d0..0000000 --- a/spec/javascripts/fixtures/checkboxes.html +++ /dev/null @@ -1,9 +0,0 @@ -
- - - - - - -
- diff --git a/spec/javascripts/fixtures/table_checkboxes.html b/spec/javascripts/fixtures/table_checkboxes.html deleted file mode 100644 index 1c438e5..0000000 --- a/spec/javascripts/fixtures/table_checkboxes.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - -
- -
- - diff --git a/spec/javascripts/helpers/SpecHelper.js b/spec/javascripts/helpers/SpecHelper.js deleted file mode 100644 index e759ff0..0000000 --- a/spec/javascripts/helpers/SpecHelper.js +++ /dev/null @@ -1,3 +0,0 @@ -beforeEach(function() { - window.inject = $.jasmine.inject; -}); diff --git a/spec/javascripts/helpers/vendor/jasmine-fixture-0.0.5.js b/spec/javascripts/helpers/vendor/jasmine-fixture-0.0.5.js deleted file mode 100644 index c5d9a62..0000000 --- a/spec/javascripts/helpers/vendor/jasmine-fixture-0.0.5.js +++ /dev/null @@ -1,108 +0,0 @@ -/* jasmine-fixture Makes injecting HTML snippets into the DOM easy & clean! - * site: https://github.com/searls/jasmine-fixture */ -(function($){ - var originalJasmineFixture = window.jasmineFixture, - defaultConfiguration = { - el:'div', - cssClass:'', - id:'', - text: '', - html: '', - defaultAttribute: 'class', - attrs: {} - }; - - window.jasmineFixture = function($) { - var isReady = false, - rootId = 'specContainer', - defaults = $.extend({},defaultConfiguration); - - $.jasmine = { - inject: function(arg,context) { - if(isReady !== true) init(); - var parent = context ? context : $('#'+rootId), - $toInject; - if(itLooksLikeHtml(arg)) { - $toInject = $(arg); - } else { - var config = $.extend({},defaults,arg,{ userString: arg }); - $toInject = $('<'+config.el+'>'); - applyAttributes($toInject,config); - injectContents($toInject,config); - } - return $toInject.appendTo(parent); - }, - configure: function(config) { - $.extend(defaults,config); - }, - restoreDefaults: function(){ - defaults = $.extend({},defaultConfiguration); - }, - noConflict: function() { - window.jasmineFixture = originalJasmineFixture; - return this; - } - }; - - $.fn.inject = function(html){ - return $.jasmine.inject(html,$(this)); - }; - - var applyAttributes = function($html,config) { - var attrs = $.extend({},{ - id: config.id, - 'class': config['class'] || config.cssClass - }, config.attrs); - if(isString(config.userString)) { - attrs[config.defaultAttribute] = config.userString; - } - for(var key in attrs) { - if(attrs[key]) { - $html.attr(key,attrs[key]); - } - } - }; - - var injectContents = function($el,config){ - if(config.text && config.html) { - throw "Error: because they conflict, you may only configure inject() to set `html` or `text`, not both! \n\nHTML was: "+config.html+" \n\n Text was: "+config.text - } else if(config.text) { - $el.text(config.text); - } else if(config.html) { - $el.html(config.html); - } - } - - var itLooksLikeHtml = function(arg) { - return isString(arg) && arg.indexOf('<') !== -1 - }; - - var isString = function(arg) { - return arg && arg.constructor === String; - }; - - var init = function() { - $('body').append('
'); - isReady = true; - }; - - var tidyUp = function() { - $('#'+rootId).remove(); - isReady = false; - }; - - $(function(jQuery){ - init(); - }); - afterEach(function(){ - tidyUp(); - }); - - return $.jasmine; - }; - - if(jQuery) { - var jasmineFixture = window.jasmineFixture(jQuery); - window.inject = window.inject || jasmineFixture.inject; - } -})(jQuery); \ No newline at end of file diff --git a/spec/javascripts/helpers/vendor/jasmine-jquery.js b/spec/javascripts/helpers/vendor/jasmine-jquery.js deleted file mode 100644 index e41001b..0000000 --- a/spec/javascripts/helpers/vendor/jasmine-jquery.js +++ /dev/null @@ -1,288 +0,0 @@ -var readFixtures = function() { - return jasmine.getFixtures().proxyCallTo_('read', arguments); -}; - -var preloadFixtures = function() { - jasmine.getFixtures().proxyCallTo_('preload', arguments); -}; - -var loadFixtures = function() { - jasmine.getFixtures().proxyCallTo_('load', arguments); -}; - -var setFixtures = function(html) { - jasmine.getFixtures().set(html); -}; - -var sandbox = function(attributes) { - return jasmine.getFixtures().sandbox(attributes); -}; - -var spyOnEvent = function(selector, eventName) { - jasmine.JQuery.events.spyOn(selector, eventName); -} - -jasmine.getFixtures = function() { - return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures(); -}; - -jasmine.Fixtures = function() { - this.containerId = 'jasmine-fixtures'; - this.fixturesCache_ = {}; - this.fixturesPath = 'spec/javascripts/fixtures'; -}; - -jasmine.Fixtures.prototype.set = function(html) { - this.cleanUp(); - this.createContainer_(html); -}; - -jasmine.Fixtures.prototype.preload = function() { - this.read.apply(this, arguments); -}; - -jasmine.Fixtures.prototype.load = function() { - this.cleanUp(); - this.createContainer_(this.read.apply(this, arguments)); -}; - -jasmine.Fixtures.prototype.read = function() { - var htmlChunks = []; - - var fixtureUrls = arguments; - for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) { - htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex])); - } - - return htmlChunks.join(''); -}; - -jasmine.Fixtures.prototype.clearCache = function() { - this.fixturesCache_ = {}; -}; - -jasmine.Fixtures.prototype.cleanUp = function() { - jQuery('#' + this.containerId).remove(); -}; - -jasmine.Fixtures.prototype.sandbox = function(attributes) { - var attributesToSet = attributes || {}; - return jQuery('
').attr(attributesToSet); -}; - -jasmine.Fixtures.prototype.createContainer_ = function(html) { - var container; - if(html instanceof jQuery) { - container = jQuery('
'); - container.html(html); - } else { - container = '
' + html + '
' - } - jQuery('body').append(container); -}; - -jasmine.Fixtures.prototype.getFixtureHtml_ = function(url) { - if (typeof this.fixturesCache_[url] == 'undefined') { - this.loadFixtureIntoCache_(url); - } - return this.fixturesCache_[url]; -}; - -jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function(relativeUrl) { - var self = this; - var url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl; - jQuery.ajax({ - async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded - cache: false, - dataType: 'html', - url: url, - success: function(data) { - self.fixturesCache_[relativeUrl] = data; - }, - error: function(jqXHR, status, errorThrown) { - throw Error('Fixture could not be loaded: ' + url + ' (status: ' + status + ', message: ' + errorThrown.message + ')'); - } - }); -}; - -jasmine.Fixtures.prototype.proxyCallTo_ = function(methodName, passedArguments) { - return this[methodName].apply(this, passedArguments); -}; - - -jasmine.JQuery = function() {}; - -jasmine.JQuery.browserTagCaseIndependentHtml = function(html) { - return jQuery('
').append(html).html(); -}; - -jasmine.JQuery.elementToString = function(element) { - return jQuery('
').append(element.clone()).html(); -}; - -jasmine.JQuery.matchersClass = {}; - -(function(namespace) { - var data = { - spiedEvents: {}, - handlers: [] - }; - - namespace.events = { - spyOn: function(selector, eventName) { - var handler = function(e) { - data.spiedEvents[[selector, eventName]] = e; - }; - jQuery(selector).bind(eventName, handler); - data.handlers.push(handler); - }, - - wasTriggered: function(selector, eventName) { - return !!(data.spiedEvents[[selector, eventName]]); - }, - - cleanUp: function() { - data.spiedEvents = {}; - data.handlers = []; - } - } -})(jasmine.JQuery); - -(function(){ - var jQueryMatchers = { - toHaveClass: function(className) { - return this.actual.hasClass(className); - }, - - toBeVisible: function() { - return this.actual.is(':visible'); - }, - - toBeHidden: function() { - return this.actual.is(':hidden'); - }, - - toBeSelected: function() { - return this.actual.is(':selected'); - }, - - toBeChecked: function() { - return this.actual.is(':checked'); - }, - - toBeEmpty: function() { - return this.actual.is(':empty'); - }, - - toExist: function() { - return this.actual.size() > 0; - }, - - toHaveAttr: function(attributeName, expectedAttributeValue) { - return hasProperty(this.actual.attr(attributeName), expectedAttributeValue); - }, - - toHaveId: function(id) { - return this.actual.attr('id') == id; - }, - - toHaveHtml: function(html) { - return this.actual.html() == jasmine.JQuery.browserTagCaseIndependentHtml(html); - }, - - toHaveText: function(text) { - if (text && jQuery.isFunction(text.test)) { - return text.test(this.actual.text()); - } else { - return this.actual.text() == text; - } - }, - - toHaveValue: function(value) { - return this.actual.val() == value; - }, - - toHaveData: function(key, expectedValue) { - return hasProperty(this.actual.data(key), expectedValue); - }, - - toBe: function(selector) { - return this.actual.is(selector); - }, - - toContain: function(selector) { - return this.actual.find(selector).size() > 0; - }, - - toBeDisabled: function(selector){ - return this.actual.is(':disabled'); - }, - - // tests the existence of a specific event binding - toHandle: function(eventName) { - var events = this.actual.data("events"); - return events && events[eventName].length > 0; - }, - - // tests the existence of a specific event binding + handler - toHandleWith: function(eventName, eventHandler) { - var stack = this.actual.data("events")[eventName]; - var i; - for (i = 0; i < stack.length; i++) { - if (stack[i].handler == eventHandler) { - return true; - } - } - return false; - } - }; - - var hasProperty = function(actualValue, expectedValue) { - if (expectedValue === undefined) { - return actualValue !== undefined; - } - return actualValue == expectedValue; - }; - - var bindMatcher = function(methodName) { - var builtInMatcher = jasmine.Matchers.prototype[methodName]; - - jasmine.JQuery.matchersClass[methodName] = function() { - if (this.actual instanceof jQuery) { - var result = jQueryMatchers[methodName].apply(this, arguments); - this.actual = jasmine.JQuery.elementToString(this.actual); - return result; - } - - if (builtInMatcher) { - return builtInMatcher.apply(this, arguments); - } - - return false; - }; - }; - - for(var methodName in jQueryMatchers) { - bindMatcher(methodName); - } -})(); - -beforeEach(function() { - this.addMatchers(jasmine.JQuery.matchersClass); - this.addMatchers({ - toHaveBeenTriggeredOn: function(selector) { - this.message = function() { - return [ - "Expected event " + this.actual + " to have been triggered on" + selector, - "Expected event " + this.actual + " not to have been triggered on" + selector - ]; - }; - return jasmine.JQuery.events.wasTriggered(selector, this.actual); - } - }) -}); - -afterEach(function() { - jasmine.getFixtures().cleanUp(); - jasmine.JQuery.events.cleanUp(); -}); \ No newline at end of file diff --git a/spec/javascripts/helpers/vendor/sinon-1.2.0.js b/spec/javascripts/helpers/vendor/sinon-1.2.0.js deleted file mode 100644 index 3f61880..0000000 --- a/spec/javascripts/helpers/vendor/sinon-1.2.0.js +++ /dev/null @@ -1,2915 +0,0 @@ -/** - * Sinon.JS 1.2.0, 2011/09/27 - * - * @author Christian Johansen (christian@cjohansen.no) - * - * (The BSD License) - * - * Copyright (c) 2010-2011, Christian Johansen, christian@cjohansen.no - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of Christian Johansen nor the names of his contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -"use strict"; -/*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/ -/*global module, require, __dirname, document*/ -/** - * Sinon core utilities. For internal use only. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ - -var sinon = (function () { - var div = typeof document != "undefined" && document.createElement("div"); - - function isNode(obj) { - var success = false; - - try { - obj.appendChild(div); - success = div.parentNode == obj; - } catch (e) { - return false; - } finally { - try { - obj.removeChild(div); - } catch (e) {} - } - - return success; - } - - function isElement(obj) { - return div && obj && obj.nodeType === 1 && isNode(obj); - } - - return { - wrapMethod: function wrapMethod(object, property, method) { - if (!object) { - throw new TypeError("Should wrap property of object"); - } - - if (typeof method != "function") { - throw new TypeError("Method wrapper should be function"); - } - - var wrappedMethod = object[property]; - var type = typeof wrappedMethod; - - if (type != "function") { - throw new TypeError("Attempted to wrap " + type + " property " + property + - " as function"); - } - - if (wrappedMethod.restore && wrappedMethod.restore.sinon) { - throw new TypeError("Attempted to wrap " + property + " which is already wrapped"); - } - - if (wrappedMethod.calledBefore) { - var verb = !!wrappedMethod.returns ? "stubbed" : "spied on"; - throw new TypeError("Attempted to wrap " + property + " which is already " + verb); - } - - var owned = object.hasOwnProperty(property); - object[property] = method; - method.displayName = property; - - method.restore = function () { - if(owned) { - object[property] = wrappedMethod; - } else { - delete object[property]; - } - }; - - method.restore.sinon = true; - - return method; - }, - - extend: function extend(target) { - for (var i = 1, l = arguments.length; i < l; i += 1) { - for (var prop in arguments[i]) { - if (arguments[i].hasOwnProperty(prop)) { - target[prop] = arguments[i][prop]; - } - - // DONT ENUM bug, only care about toString - if (arguments[i].hasOwnProperty("toString") && - arguments[i].toString != target.toString) { - target.toString = arguments[i].toString; - } - } - } - - return target; - }, - - create: function create(proto) { - var F = function () {}; - F.prototype = proto; - return new F(); - }, - - deepEqual: function deepEqual(a, b) { - if (typeof a != "object" || typeof b != "object") { - return a === b; - } - - if (isElement(a) || isElement(b)) { - return a === b; - } - - if (a === b) { - return true; - } - - if (Object.prototype.toString.call(a) == "[object Array]") { - if (a.length !== b.length) { - return false; - } - - for (var i = 0, l = a.length; i < l; i += 1) { - if (!deepEqual(a[i], b[i])) { - return false; - } - } - - return true; - } - - var prop, aLength = 0, bLength = 0; - - for (prop in a) { - aLength += 1; - - if (!deepEqual(a[prop], b[prop])) { - return false; - } - } - - for (prop in b) { - bLength += 1; - } - - if (aLength != bLength) { - return false; - } - - return true; - }, - - functionName: function functionName(func) { - var name = func.displayName || func.name; - - // Use function decomposition as a last resort to get function - // name. Does not rely on function decomposition to work - if it - // doesn't debugging will be slightly less informative - // (i.e. toString will say 'spy' rather than 'myFunc'). - if (!name) { - var matches = func.toString().match(/function ([^\s\(]+)/); - name = matches && matches[1]; - } - - return name; - }, - - functionToString: function toString() { - if (this.getCall && this.callCount) { - var thisValue, prop, i = this.callCount; - - while (i--) { - thisValue = this.getCall(i).thisValue; - - for (prop in thisValue) { - if (thisValue[prop] === this) { - return prop; - } - } - } - } - - return this.displayName || "sinon fake"; - }, - - getConfig: function (custom) { - var config = {}; - custom = custom || {}; - var defaults = sinon.defaultConfig; - - for (var prop in defaults) { - if (defaults.hasOwnProperty(prop)) { - config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop]; - } - } - - return config; - }, - - format: function (val) { - return "" + val; - }, - - defaultConfig: { - injectIntoThis: true, - injectInto: null, - properties: ["spy", "stub", "mock", "clock", "server", "requests"], - useFakeTimers: true, - useFakeServer: true - }, - - timesInWords: function timesInWords(count) { - return count == 1 && "once" || - count == 2 && "twice" || - count == 3 && "thrice" || - (count || 0) + " times"; - }, - - calledInOrder: function (spies) { - for (var i = 1, l = spies.length; i < l; i++) { - if (!spies[i - 1].calledBefore(spies[i])) { - return false; - } - } - - return true; - }, - - orderByFirstCall: function (spies) { - return spies.sort(function (a, b) { - // uuid, won't ever be equal - return a.getCall(0).callId < b.getCall(0).callId ? -1 : 1; - }); - } - }; -}()); - -if (typeof module == "object" && typeof require == "function") { - module.exports = sinon; - module.exports.spy = require("./sinon/spy"); - module.exports.stub = require("./sinon/stub"); - module.exports.mock = require("./sinon/mock"); - module.exports.collection = require("./sinon/collection"); - module.exports.assert = require("./sinon/assert"); - module.exports.sandbox = require("./sinon/sandbox"); - module.exports.test = require("./sinon/test"); - module.exports.testCase = require("./sinon/test_case"); - module.exports.assert = require("./sinon/assert"); -} - -/* @depend ../sinon.js */ -/*jslint eqeqeq: false, onevar: false, plusplus: false*/ -/*global module, require, sinon*/ -/** - * Spy functions - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - var spyCall; - var callId = 0; - var push = [].push; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - function spy(object, property) { - if (!property && typeof object == "function") { - return spy.create(object); - } - - if (!object || !property) { - return spy.create(function () {}); - } - - var method = object[property]; - return sinon.wrapMethod(object, property, spy.create(method)); - } - - sinon.extend(spy, (function () { - var slice = Array.prototype.slice; - - function delegateToCalls(api, method, matchAny, actual, notCalled) { - api[method] = function () { - if (!this.called) { - return !!notCalled; - } - - var currentCall; - var matches = 0; - - for (var i = 0, l = this.callCount; i < l; i += 1) { - currentCall = this.getCall(i); - - if (currentCall[actual || method].apply(currentCall, arguments)) { - matches += 1; - - if (matchAny) { - return true; - } - } - } - - return matches === this.callCount; - }; - } - - function matchingFake(fakes, args, strict) { - if (!fakes) { - return; - } - - var alen = args.length; - - for (var i = 0, l = fakes.length; i < l; i++) { - if (fakes[i].matches(args, strict)) { - return fakes[i]; - } - } - } - - var uuid = 0; - - // Public API - var spyApi = { - reset: function () { - this.called = false; - this.calledOnce = false; - this.calledTwice = false; - this.calledThrice = false; - this.callCount = 0; - this.args = []; - this.returnValues = []; - this.thisValues = []; - this.exceptions = []; - this.callIds = []; - }, - - create: function create(func) { - var name; - - if (typeof func != "function") { - func = function () {}; - } else { - name = sinon.functionName(func); - } - - function proxy() { - return proxy.invoke(func, this, slice.call(arguments)); - } - - sinon.extend(proxy, spy); - delete proxy.create; - sinon.extend(proxy, func); - - proxy.reset(); - proxy.prototype = func.prototype; - proxy.displayName = name || "spy"; - proxy.toString = sinon.functionToString; - proxy._create = sinon.spy.create; - proxy.id = "spy#" + uuid++; - - return proxy; - }, - - invoke: function invoke(func, thisValue, args) { - var matching = matchingFake(this.fakes, args); - var exception, returnValue; - this.called = true; - this.callCount += 1; - this.calledOnce = this.callCount == 1; - this.calledTwice = this.callCount == 2; - this.calledThrice = this.callCount == 3; - push.call(this.thisValues, thisValue); - push.call(this.args, args); - push.call(this.callIds, callId++); - - try { - if (matching) { - returnValue = matching.invoke(func, thisValue, args); - } else { - returnValue = (this.func || func).apply(thisValue, args); - } - } catch (e) { - push.call(this.returnValues, undefined); - exception = e; - throw e; - } finally { - push.call(this.exceptions, exception); - } - - push.call(this.returnValues, returnValue); - - return returnValue; - }, - - getCall: function getCall(i) { - if (i < 0 || i >= this.callCount) { - return null; - } - - return spyCall.create(this, this.thisValues[i], this.args[i], - this.returnValues[i], this.exceptions[i], - this.callIds[i]); - }, - - calledBefore: function calledBefore(spyFn) { - if (!this.called) { - return false; - } - - if (!spyFn.called) { - return true; - } - - return this.callIds[0] < spyFn.callIds[0]; - }, - - calledAfter: function calledAfter(spyFn) { - if (!this.called || !spyFn.called) { - return false; - } - - return this.callIds[this.callCount - 1] > spyFn.callIds[spyFn.callCount - 1]; - }, - - withArgs: function () { - var args = slice.call(arguments); - - if (this.fakes) { - var match = matchingFake(this.fakes, args, true); - - if (match) { - return match; - } - } else { - this.fakes = []; - } - - var original = this; - var fake = this._create(); - fake.matchingAguments = args; - push.call(this.fakes, fake); - - fake.withArgs = function () { - return original.withArgs.apply(original, arguments); - }; - - return fake; - }, - - matches: function (args, strict) { - var margs = this.matchingAguments; - - if (margs.length <= args.length && - sinon.deepEqual(margs, args.slice(0, margs.length))) { - return !strict || margs.length == args.length; - } - }, - - printf: function (format) { - var spy = this; - var args = [].slice.call(arguments, 1); - var formatter; - - return (format || "").replace(/%(.)/g, function (match, specifyer) { - formatter = spyApi.formatters[specifyer]; - - if (typeof formatter == "function") { - return formatter.call(null, spy, args); - } else if (!isNaN(parseInt(specifyer), 10)) { - return sinon.format(args[specifyer - 1]); - } - - return "%" + specifyer; - }); - } - }; - - delegateToCalls(spyApi, "calledOn", true); - delegateToCalls(spyApi, "alwaysCalledOn", false, "calledOn"); - delegateToCalls(spyApi, "calledWith", true); - delegateToCalls(spyApi, "alwaysCalledWith", false, "calledWith"); - delegateToCalls(spyApi, "calledWithExactly", true); - delegateToCalls(spyApi, "alwaysCalledWithExactly", false, "calledWithExactly"); - delegateToCalls(spyApi, "neverCalledWith", false, "notCalledWith", true); - delegateToCalls(spyApi, "threw", true); - delegateToCalls(spyApi, "alwaysThrew", false, "threw"); - delegateToCalls(spyApi, "returned", true); - delegateToCalls(spyApi, "alwaysReturned", false, "returned"); - delegateToCalls(spyApi, "calledWithNew", true); - delegateToCalls(spyApi, "alwaysCalledWithNew", false, "calledWithNew"); - - spyApi.formatters = { - "c": function (spy) { - return sinon.timesInWords(spy.callCount); - }, - - "n": function (spy) { - return spy.toString(); - }, - - "C": function (spy) { - var calls = []; - - for (var i = 0, l = spy.callCount; i < l; ++i) { - push.call(calls, " " + spy.getCall(i).toString()); - } - - return calls.length > 0 ? "\n" + calls.join("\n") : ""; - }, - - "t": function (spy) { - var objects = []; - - for (var i = 0, l = spy.callCount; i < l; ++i) { - push.call(objects, sinon.format(spy.thisValues[i])); - } - - return objects.join(", "); - }, - - "*": function (spy, args) { - return args.join(", "); - } - }; - - return spyApi; - }())); - - spyCall = (function () { - return { - create: function create(spy, thisValue, args, returnValue, exception, id) { - var proxyCall = sinon.create(spyCall); - delete proxyCall.create; - proxyCall.proxy = spy; - proxyCall.thisValue = thisValue; - proxyCall.args = args; - proxyCall.returnValue = returnValue; - proxyCall.exception = exception; - proxyCall.callId = typeof id == "number" && id || callId++; - - return proxyCall; - }, - - calledOn: function calledOn(thisValue) { - return this.thisValue === thisValue; - }, - - calledWith: function calledWith() { - for (var i = 0, l = arguments.length; i < l; i += 1) { - if (!sinon.deepEqual(arguments[i], this.args[i])) { - return false; - } - } - - return true; - }, - - calledWithExactly: function calledWithExactly() { - return arguments.length == this.args.length && - this.calledWith.apply(this, arguments); - }, - - notCalledWith: function notCalledWith() { - for (var i = 0, l = arguments.length; i < l; i += 1) { - if (!sinon.deepEqual(arguments[i], this.args[i])) { - return true; - } - } - return false; - }, - - returned: function returned(value) { - return this.returnValue === value; - }, - - threw: function threw(error) { - if (typeof error == "undefined" || !this.exception) { - return !!this.exception; - } - - if (typeof error == "string") { - return this.exception.name == error; - } - - return this.exception === error; - }, - - calledWithNew: function calledWithNew(thisValue) { - return this.thisValue instanceof this.proxy; - }, - - calledBefore: function (other) { - return this.callId < other.callId; - }, - - calledAfter: function (other) { - return this.callId > other.callId; - }, - - toString: function () { - var callStr = this.proxy.toString() + "("; - var args = []; - - for (var i = 0, l = this.args.length; i < l; ++i) { - push.call(args, sinon.format(this.args[i])); - } - - callStr = callStr + args.join(", ") + ")"; - - if (typeof this.returnValue != "undefined") { - callStr += " => " + sinon.format(this.returnValue); - } - - if (this.exception) { - callStr += " !" + this.exception.name; - - if (this.exception.message) { - callStr += "(" + this.exception.message + ")"; - } - } - - return callStr; - } - }; - }()); - - spy.spyCall = spyCall; - - // This steps outside the module sandbox and will be removed - sinon.spyCall = spyCall; - - if (commonJSModule) { - module.exports = spy; - } else { - sinon.spy = spy; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend spy.js - */ -/*jslint eqeqeq: false, onevar: false*/ -/*global module, require, sinon*/ -/** - * Stub functions - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - function stub(object, property, func) { - if (!!func && typeof func != "function") { - throw new TypeError("Custom stub should be function"); - } - - var wrapper; - - if (func) { - wrapper = sinon.spy && sinon.spy.create ? sinon.spy.create(func) : func; - } else { - wrapper = stub.create(); - } - - if (!object && !property) { - return sinon.stub.create(); - } - - if (!property && !!object && typeof object == "object") { - for (var prop in object) { - if (object.hasOwnProperty(prop) && typeof object[prop] == "function") { - stub(object, prop); - } - } - - return object; - } - - return sinon.wrapMethod(object, property, wrapper); - } - - function getCallback(stub, args) { - if (stub.callArgAt < 0) { - for (var i = 0, l = args.length; i < l; ++i) { - if (!stub.callArgProp && typeof args[i] == "function") { - return args[i]; - } - - if (stub.callArgProp && args[i] && - typeof args[i][stub.callArgProp] == "function") { - return args[i][stub.callArgProp]; - } - } - - return null; - } - - return args[stub.callArgAt]; - } - - var join = Array.prototype.join; - - function getCallbackError(stub, func, args) { - if (stub.callArgAt < 0) { - var msg; - - if (stub.callArgProp) { - msg = sinon.functionName(stub) + - " expected to yield to '" + stub.callArgProp + - "', but no object with such a property was passed." - } else { - msg = sinon.functionName(stub) + - " expected to yield, but no callback was passed." - } - - if (args.length > 0) { - msg += " Received [" + join.call(args, ", ") + "]"; - } - - return msg; - } - - return "argument at index " + stub.callArgAt + " is not a function: " + func; - } - - function callCallback(stub, args) { - if (typeof stub.callArgAt == "number") { - var func = getCallback(stub, args); - - if (typeof func != "function") { - throw new TypeError(getCallbackError(stub, func, args)); - } - - func.apply(null, stub.callbackArguments); - } - } - - var uuid = 0; - - sinon.extend(stub, (function () { - var slice = Array.prototype.slice; - - function throwsException(error, message) { - if (typeof error == "string") { - this.exception = new Error(message || ""); - this.exception.name = error; - } else if (!error) { - this.exception = new Error("Error"); - } else { - this.exception = error; - } - - return this; - } - - return { - create: function create() { - var functionStub = function () { - if (functionStub.exception) { - throw functionStub.exception; - } - - callCallback(functionStub, arguments); - - return functionStub.returnValue; - }; - - functionStub.id = "stub#" + uuid++; - var orig = functionStub; - functionStub = sinon.spy.create(functionStub); - functionStub.func = orig; - - sinon.extend(functionStub, stub); - functionStub._create = sinon.stub.create; - functionStub.displayName = "stub"; - functionStub.toString = sinon.functionToString; - - return functionStub; - }, - - returns: function returns(value) { - this.returnValue = value; - - return this; - }, - - "throws": throwsException, - throwsException: throwsException, - - callsArg: function callsArg(pos) { - if (typeof pos != "number") { - throw new TypeError("argument index is not number"); - } - - this.callArgAt = pos; - this.callbackArguments = []; - - return this; - }, - - callsArgWith: function callsArgWith(pos) { - if (typeof pos != "number") { - throw new TypeError("argument index is not number"); - } - - this.callArgAt = pos; - this.callbackArguments = slice.call(arguments, 1); - - return this; - }, - - yields: function () { - this.callArgAt = -1; - this.callbackArguments = slice.call(arguments, 0); - - return this; - }, - - yieldsTo: function (prop) { - this.callArgAt = -1; - this.callArgProp = prop; - this.callbackArguments = slice.call(arguments, 1); - - return this; - } - }; - }())); - - if (commonJSModule) { - module.exports = stub; - } else { - sinon.stub = stub; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend stub.js - */ -/*jslint eqeqeq: false, onevar: false, nomen: false*/ -/*global module, require, sinon*/ -/** - * Mock functions. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - var push = [].push; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - function mock(object) { - if (!object) { - return sinon.expectation.create("Anonymous mock"); - } - - return mock.create(object); - } - - sinon.mock = mock; - - sinon.extend(mock, (function () { - function each(collection, callback) { - if (!collection) { - return; - } - - for (var i = 0, l = collection.length; i < l; i += 1) { - callback(collection[i]); - } - } - - return { - create: function create(object) { - if (!object) { - throw new TypeError("object is null"); - } - - var mockObject = sinon.extend({}, mock); - mockObject.object = object; - delete mockObject.create; - - return mockObject; - }, - - expects: function expects(method) { - if (!method) { - throw new TypeError("method is falsy"); - } - - if (!this.expectations) { - this.expectations = {}; - this.proxies = []; - } - - if (!this.expectations[method]) { - this.expectations[method] = []; - var mockObject = this; - - sinon.wrapMethod(this.object, method, function () { - return mockObject.invokeMethod(method, this, arguments); - }); - - push.call(this.proxies, method); - } - - var expectation = sinon.expectation.create(method); - push.call(this.expectations[method], expectation); - - return expectation; - }, - - restore: function restore() { - var object = this.object; - - each(this.proxies, function (proxy) { - if (typeof object[proxy].restore == "function") { - object[proxy].restore(); - } - }); - }, - - verify: function verify() { - var expectations = this.expectations || {}; - var messages = [], met = []; - - each(this.proxies, function (proxy) { - each(expectations[proxy], function (expectation) { - if (!expectation.met()) { - push.call(messages, expectation.toString()); - } else { - push.call(met, expectation.toString()); - } - }); - }); - - this.restore(); - - if (messages.length > 0) { - sinon.expectation.fail(messages.concat(met).join("\n")); - } - - return true; - }, - - invokeMethod: function invokeMethod(method, thisValue, args) { - var expectations = this.expectations && this.expectations[method]; - var length = expectations && expectations.length || 0; - - for (var i = 0; i < length; i += 1) { - if (!expectations[i].met() && - expectations[i].allowsCall(thisValue, args)) { - return expectations[i].apply(thisValue, args); - } - } - - var messages = []; - - for (i = 0; i < length; i += 1) { - push.call(messages, " " + expectations[i].toString()); - } - - messages.unshift("Unexpected call: " + sinon.spyCall.toString.call({ - proxy: method, - args: args - })); - - sinon.expectation.fail(messages.join("\n")); - } - }; - }())); - - var times = sinon.timesInWords; - - sinon.expectation = (function () { - var slice = Array.prototype.slice; - var _invoke = sinon.spy.invoke; - - function callCountInWords(callCount) { - if (callCount == 0) { - return "never called"; - } else { - return "called " + times(callCount); - } - } - - function expectedCallCountInWords(expectation) { - var min = expectation.minCalls; - var max = expectation.maxCalls; - - if (typeof min == "number" && typeof max == "number") { - var str = times(min); - - if (min != max) { - str = "at least " + str + " and at most " + times(max); - } - - return str; - } - - if (typeof min == "number") { - return "at least " + times(min); - } - - return "at most " + times(max); - } - - function receivedMinCalls(expectation) { - var hasMinLimit = typeof expectation.minCalls == "number"; - return !hasMinLimit || expectation.callCount >= expectation.minCalls; - } - - function receivedMaxCalls(expectation) { - if (typeof expectation.maxCalls != "number") { - return false; - } - - return expectation.callCount == expectation.maxCalls; - } - - return { - minCalls: 1, - maxCalls: 1, - - create: function create(methodName) { - var expectation = sinon.extend(sinon.stub.create(), sinon.expectation); - delete expectation.create; - expectation.method = methodName; - - return expectation; - }, - - invoke: function invoke(func, thisValue, args) { - this.verifyCallAllowed(thisValue, args); - - return _invoke.apply(this, arguments); - }, - - atLeast: function atLeast(num) { - if (typeof num != "number") { - throw new TypeError("'" + num + "' is not number"); - } - - if (!this.limitsSet) { - this.maxCalls = null; - this.limitsSet = true; - } - - this.minCalls = num; - - return this; - }, - - atMost: function atMost(num) { - if (typeof num != "number") { - throw new TypeError("'" + num + "' is not number"); - } - - if (!this.limitsSet) { - this.minCalls = null; - this.limitsSet = true; - } - - this.maxCalls = num; - - return this; - }, - - never: function never() { - return this.exactly(0); - }, - - once: function once() { - return this.exactly(1); - }, - - twice: function twice() { - return this.exactly(2); - }, - - thrice: function thrice() { - return this.exactly(3); - }, - - exactly: function exactly(num) { - if (typeof num != "number") { - throw new TypeError("'" + num + "' is not a number"); - } - - this.atLeast(num); - return this.atMost(num); - }, - - met: function met() { - return !this.failed && receivedMinCalls(this); - }, - - verifyCallAllowed: function verifyCallAllowed(thisValue, args) { - if (receivedMaxCalls(this)) { - this.failed = true; - sinon.expectation.fail(this.method + " already called " + times(this.maxCalls)); - } - - if ("expectedThis" in this && this.expectedThis !== thisValue) { - sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " + - this.expectedThis); - } - - if (!("expectedArguments" in this)) { - return; - } - - if (!args || args.length === 0) { - sinon.expectation.fail(this.method + " received no arguments, expected " + - this.expectedArguments.join()); - } - - if (args.length < this.expectedArguments.length) { - sinon.expectation.fail(this.method + " received too few arguments (" + args.join() + - "), expected " + this.expectedArguments.join()); - } - - if (this.expectsExactArgCount && - args.length != this.expectedArguments.length) { - sinon.expectation.fail(this.method + " received too many arguments (" + args.join() + - "), expected " + this.expectedArguments.join()); - } - - for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) { - if (!sinon.deepEqual(this.expectedArguments[i], args[i])) { - sinon.expectation.fail(this.method + " received wrong arguments (" + args.join() + - "), expected " + this.expectedArguments.join()); - } - } - }, - - allowsCall: function allowsCall(thisValue, args) { - if (this.met()) { - return false; - } - - if ("expectedThis" in this && this.expectedThis !== thisValue) { - return false; - } - - if (!("expectedArguments" in this)) { - return true; - } - - args = args || []; - - if (args.length < this.expectedArguments.length) { - return false; - } - - if (this.expectsExactArgCount && - args.length != this.expectedArguments.length) { - return false; - } - - for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) { - if (!sinon.deepEqual(this.expectedArguments[i], args[i])) { - return false; - } - } - - return true; - }, - - withArgs: function withArgs() { - this.expectedArguments = slice.call(arguments); - return this; - }, - - withExactArgs: function withExactArgs() { - this.withArgs.apply(this, arguments); - this.expectsExactArgCount = true; - return this; - }, - - on: function on(thisValue) { - this.expectedThis = thisValue; - return this; - }, - - toString: function () { - var args = (this.expectedArguments || []).slice(); - - if (!this.expectsExactArgCount) { - push.call(args, "[...]"); - } - - var callStr = sinon.spyCall.toString.call({ - proxy: this.method, args: args - }); - - var message = callStr.replace(", [...", "[, ...") + " " + - expectedCallCountInWords(this); - - if (this.met()) { - return "Expectation met: " + message; - } - - return "Expected " + message + " (" + - callCountInWords(this.callCount) + ")"; - }, - - verify: function verify() { - if (!this.met()) { - sinon.expectation.fail(this.toString()); - } - - return true; - }, - - fail: function (message) { - var exception = new Error(message); - exception.name = "ExpectationError"; - - throw exception; - } - }; - }()); - - if (commonJSModule) { - module.exports = mock; - } else { - sinon.mock = mock; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend stub.js - * @depend mock.js - */ -/*jslint eqeqeq: false, onevar: false, forin: true*/ -/*global module, require, sinon*/ -/** - * Collections of stubs, spies and mocks. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - var push = [].push; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - function getFakes(fakeCollection) { - if (!fakeCollection.fakes) { - fakeCollection.fakes = []; - } - - return fakeCollection.fakes; - } - - function each(fakeCollection, method) { - var fakes = getFakes(fakeCollection); - - for (var i = 0, l = fakes.length; i < l; i += 1) { - if (typeof fakes[i][method] == "function") { - fakes[i][method](); - } - } - } - - function compact(fakeCollection) { - var fakes = getFakes(fakeCollection); - var i = 0; - while (i < fakes.length) { - fakes.splice(i, 1); - } - } - - var collection = { - verify: function resolve() { - each(this, "verify"); - }, - - restore: function restore() { - each(this, "restore"); - compact(this); - }, - - verifyAndRestore: function verifyAndRestore() { - var exception; - - try { - this.verify(); - } catch (e) { - exception = e; - } - - this.restore(); - - if (exception) { - throw exception; - } - }, - - add: function add(fake) { - push.call(getFakes(this), fake); - return fake; - }, - - spy: function spy() { - return this.add(sinon.spy.apply(sinon, arguments)); - }, - - stub: function stub(object, property, value) { - if (property) { - var original = object[property]; - - if (typeof original != "function") { - if (!object.hasOwnProperty(property)) { - throw new TypeError("Cannot stub non-existent own property " + property); - } - - object[property] = value; - - return this.add({ - restore: function () { - object[property] = original; - } - }); - } - } - - return this.add(sinon.stub.apply(sinon, arguments)); - }, - - mock: function mock() { - return this.add(sinon.mock.apply(sinon, arguments)); - }, - - inject: function inject(obj) { - var col = this; - - obj.spy = function () { - return col.spy.apply(col, arguments); - }; - - obj.stub = function () { - return col.stub.apply(col, arguments); - }; - - obj.mock = function () { - return col.mock.apply(col, arguments); - }; - - return obj; - } - }; - - if (commonJSModule) { - module.exports = collection; - } else { - sinon.collection = collection; - } -}(typeof sinon == "object" && sinon || null)); - -/*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/ -/*global module, require, window*/ -/** - * Fake timer API - * setTimeout - * setInterval - * clearTimeout - * clearInterval - * tick - * reset - * Date - * - * Inspired by jsUnitMockTimeOut from JsUnit - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ - -if (typeof sinon == "undefined") { - var sinon = {}; -} - -sinon.clock = (function () { - var id = 0; - - function addTimer(args, recurring) { - if (args.length === 0) { - throw new Error("Function requires at least 1 parameter"); - } - - var toId = id++; - var delay = args[1] || 0; - - if (!this.timeouts) { - this.timeouts = {}; - } - - this.timeouts[toId] = { - id: toId, - func: args[0], - callAt: this.now + delay - }; - - if (recurring === true) { - this.timeouts[toId].interval = delay; - } - - return toId; - } - - function parseTime(str) { - if (!str) { - return 0; - } - - var strings = str.split(":"); - var l = strings.length, i = l; - var ms = 0, parsed; - - if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) { - throw new Error("tick only understands numbers and 'h:m:s'"); - } - - while (i--) { - parsed = parseInt(strings[i], 10); - - if (parsed >= 60) { - throw new Error("Invalid time " + str); - } - - ms += parsed * Math.pow(60, (l - i - 1)); - } - - return ms * 1000; - } - - function createObject(object) { - var newObject; - - if (Object.create) { - newObject = Object.create(object); - } else { - var F = function () {}; - F.prototype = object; - newObject = new F(); - } - - newObject.Date.clock = newObject; - return newObject; - } - - return { - now: 0, - - create: function create(now) { - var clock = createObject(this); - - if (typeof now == "number") { - this.now = now; - } - - return clock; - }, - - setTimeout: function setTimeout(callback, timeout) { - return addTimer.call(this, arguments, false); - }, - - clearTimeout: function clearTimeout(timerId) { - if (!this.timeouts) { - this.timeouts = []; - } - - delete this.timeouts[timerId]; - }, - - setInterval: function setInterval(callback, timeout) { - return addTimer.call(this, arguments, true); - }, - - clearInterval: function clearInterval(timerId) { - this.clearTimeout(timerId); - }, - - tick: function tick(ms) { - ms = typeof ms == "number" ? ms : parseTime(ms); - var tickFrom = this.now, tickTo = this.now + ms, previous = this.now; - var timer = this.firstTimerInRange(tickFrom, tickTo); - - while (timer && tickFrom <= tickTo) { - if (this.timeouts[timer.id]) { - tickFrom = this.now = timer.callAt; - this.callTimer(timer); - } - - timer = this.firstTimerInRange(previous, tickTo); - previous = tickFrom; - } - - this.now = tickTo; - }, - - firstTimerInRange: function (from, to) { - var timer, smallest, originalTimer; - - for (var id in this.timeouts) { - if (this.timeouts.hasOwnProperty(id)) { - if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) { - continue; - } - - if (!smallest || this.timeouts[id].callAt < smallest) { - originalTimer = this.timeouts[id]; - smallest = this.timeouts[id].callAt; - - timer = { - func: this.timeouts[id].func, - callAt: this.timeouts[id].callAt, - interval: this.timeouts[id].interval, - id: this.timeouts[id].id - }; - } - } - } - - return timer || null; - }, - - callTimer: function (timer) { - try { - if (typeof timer.func == "function") { - timer.func.call(null); - } else { - eval(timer.func); - } - } catch (e) {} - - if (!this.timeouts[timer.id]) { - return; - } - - if (typeof timer.interval == "number") { - this.timeouts[timer.id].callAt += timer.interval; - } else { - delete this.timeouts[timer.id]; - } - }, - - reset: function reset() { - this.timeouts = {}; - }, - - Date: (function () { - var NativeDate = Date; - - function ClockDate(year, month, date, hour, minute, second, ms) { - // Defensive and verbose to avoid potential harm in passing - // explicit undefined when user does not pass argument - switch (arguments.length) { - case 0: - return new NativeDate(ClockDate.clock.now); - case 1: - return new NativeDate(year); - case 2: - return new NativeDate(year, month); - case 3: - return new NativeDate(year, month, date); - case 4: - return new NativeDate(year, month, date, hour); - case 5: - return new NativeDate(year, month, date, hour, minute); - case 6: - return new NativeDate(year, month, date, hour, minute, second); - default: - return new NativeDate(year, month, date, hour, minute, second, ms); - } - } - - if (NativeDate.now) { - ClockDate.now = function now() { - return ClockDate.clock.now; - }; - } - - if (NativeDate.toSource) { - ClockDate.toSource = function toSource() { - return NativeDate.toSource(); - }; - } - - ClockDate.toString = function toString() { - return NativeDate.toString(); - }; - - ClockDate.prototype = NativeDate.prototype; - ClockDate.parse = NativeDate.parse; - ClockDate.UTC = NativeDate.UTC; - - return ClockDate; - }()) - }; -}()); - -sinon.timers = { - setTimeout: setTimeout, - clearTimeout: clearTimeout, - setInterval: setInterval, - clearInterval: clearInterval, - Date: Date -}; - -sinon.useFakeTimers = (function (global) { - var methods = ["Date", "setTimeout", "setInterval", "clearTimeout", "clearInterval"]; - - function restore() { - var method; - - for (var i = 0, l = this.methods.length; i < l; i++) { - method = this.methods[i]; - global[method] = this["_" + method]; - } - } - - function stubGlobal(method, clock) { - clock["_" + method] = global[method]; - - global[method] = function () { - return clock[method].apply(clock, arguments); - }; - - for (var prop in clock[method]) { - if (clock[method].hasOwnProperty(prop)) { - global[method][prop] = clock[method][prop]; - } - } - - global[method].clock = clock; - } - - return function useFakeTimers(now) { - var clock = sinon.clock.create(now); - clock.restore = restore; - clock.methods = Array.prototype.slice.call(arguments, - typeof now == "number" ? 1 : 0); - - if (clock.methods.length === 0) { - clock.methods = methods; - } - - for (var i = 0, l = clock.methods.length; i < l; i++) { - stubGlobal(clock.methods[i], clock); - } - - return clock; - }; -}(typeof global != "undefined" ? global : this)); - -if (typeof module == "object" && typeof require == "function") { - module.exports = sinon; -} - -/*jslint eqeqeq: false, onevar: false*/ -/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/ -/** - * Minimal Event interface implementation - * - * Original implementation by Sven Fuchs: https://gist.github.com/995028 - * Modifications and tests by Christian Johansen. - * - * @author Sven Fuchs (svenfuchs@artweb-design.de) - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2011 Sven Fuchs, Christian Johansen - */ - -if (typeof sinon == "undefined") { - this.sinon = {}; -} - -(function () { - var push = [].push; - - sinon.Event = function Event(type, bubbles, cancelable) { - this.initEvent(type, bubbles, cancelable); - }; - - sinon.Event.prototype = { - initEvent: function(type, bubbles, cancelable) { - this.type = type; - this.bubbles = bubbles; - this.cancelable = cancelable; - }, - - stopPropagation: function () {}, - - preventDefault: function () { - this.defaultPrevented = true; - } - }; - - sinon.EventTarget = { - addEventListener: function addEventListener(event, listener, useCapture) { - this.eventListeners = this.eventListeners || {}; - this.eventListeners[event] = this.eventListeners[event] || []; - push.call(this.eventListeners[event], listener); - }, - - removeEventListener: function removeEventListener(event, listener, useCapture) { - var listeners = this.eventListeners && this.eventListeners[event] || []; - - for (var i = 0, l = listeners.length; i < l; ++i) { - if (listeners[i] == listener) { - return listeners.splice(i, 1); - } - } - }, - - dispatchEvent: function dispatchEvent(event) { - var type = event.type; - var listeners = this.eventListeners && this.eventListeners[type] || []; - - for (var i = 0; i < listeners.length; i++) { - if (typeof listeners[i] == "function") { - listeners[i].call(this, event); - } else { - listeners[i].handleEvent(event); - } - } - - return !!event.defaultPrevented; - } - }; -}()); - -/** - * @depend event.js - */ -/*jslint eqeqeq: false, onevar: false*/ -/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/ -/** - * Fake XMLHttpRequest object - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ - -if (typeof sinon == "undefined") { - this.sinon = {}; -} - -sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest }; - -sinon.FakeXMLHttpRequest = (function () { - /*jsl:ignore*/ - var unsafeHeaders = { - "Accept-Charset": true, - "Accept-Encoding": true, - "Connection": true, - "Content-Length": true, - "Cookie": true, - "Cookie2": true, - "Content-Transfer-Encoding": true, - "Date": true, - "Expect": true, - "Host": true, - "Keep-Alive": true, - "Referer": true, - "TE": true, - "Trailer": true, - "Transfer-Encoding": true, - "Upgrade": true, - "User-Agent": true, - "Via": true - }; - /*jsl:end*/ - - function FakeXMLHttpRequest() { - this.readyState = FakeXMLHttpRequest.UNSENT; - this.requestHeaders = {}; - this.requestBody = null; - this.status = 0; - this.statusText = ""; - - if (typeof FakeXMLHttpRequest.onCreate == "function") { - FakeXMLHttpRequest.onCreate(this); - } - } - - function verifyState(xhr) { - if (xhr.readyState !== FakeXMLHttpRequest.OPENED) { - throw new Error("INVALID_STATE_ERR"); - } - - if (xhr.sendFlag) { - throw new Error("INVALID_STATE_ERR"); - } - } - - sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, { - async: true, - - open: function open(method, url, async, username, password) { - this.method = method; - this.url = url; - this.async = typeof async == "boolean" ? async : true; - this.username = username; - this.password = password; - this.responseText = null; - this.responseXML = null; - this.requestHeaders = {}; - this.sendFlag = false; - this.readyStateChange(FakeXMLHttpRequest.OPENED); - }, - - readyStateChange: function readyStateChange(state) { - this.readyState = state; - - if (typeof this.onreadystatechange == "function") { - this.onreadystatechange(); - } - - this.dispatchEvent(new sinon.Event("readystatechange")); - }, - - setRequestHeader: function setRequestHeader(header, value) { - verifyState(this); - - if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) { - throw new Error("Refused to set unsafe header \"" + header + "\""); - } - - if (this.requestHeaders[header]) { - this.requestHeaders[header] += "," + value; - } else { - this.requestHeaders[header] = value; - } - }, - - // Helps testing - setResponseHeaders: function setResponseHeaders(headers) { - this.responseHeaders = {}; - - for (var header in headers) { - if (headers.hasOwnProperty(header)) { - this.responseHeaders[header] = headers[header]; - } - } - - if (this.async) { - this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED); - } - }, - - // Currently treats ALL data as a DOMString (i.e. no Document) - send: function send(data) { - verifyState(this); - - if (!/^(get|head)$/i.test(this.method)) { - if (this.requestHeaders["Content-Type"]) { - var value = this.requestHeaders["Content-Type"].split(";"); - this.requestHeaders["Content-Type"] = value[0] + ";charset=utf-8"; - } else { - this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8"; - } - - this.requestBody = data; - } - - this.errorFlag = false; - this.sendFlag = this.async; - this.readyStateChange(FakeXMLHttpRequest.OPENED); - - if (typeof this.onSend == "function") { - this.onSend(this); - } - }, - - abort: function abort() { - this.aborted = true; - this.responseText = null; - this.errorFlag = true; - this.requestHeaders = {}; - - if (this.readyState > sinon.FakeXMLHttpRequest.UNSENT && this.sendFlag) { - this.readyStateChange(sinon.FakeXMLHttpRequest.DONE); - this.sendFlag = false; - } - - this.readyState = sinon.FakeXMLHttpRequest.UNSENT; - }, - - getResponseHeader: function getResponseHeader(header) { - if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) { - return null; - } - - if (/^Set-Cookie2?$/i.test(header)) { - return null; - } - - header = header.toLowerCase(); - - for (var h in this.responseHeaders) { - if (h.toLowerCase() == header) { - return this.responseHeaders[h]; - } - } - - return null; - }, - - getAllResponseHeaders: function getAllResponseHeaders() { - if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) { - return ""; - } - - var headers = ""; - - for (var header in this.responseHeaders) { - if (this.responseHeaders.hasOwnProperty(header) && - !/^Set-Cookie2?$/i.test(header)) { - headers += header + ": " + this.responseHeaders[header] + "\r\n"; - } - } - - return headers; - }, - - setResponseBody: function setResponseBody(body) { - if (this.readyState == FakeXMLHttpRequest.DONE) { - throw new Error("Request done"); - } - - if (this.async && this.readyState != FakeXMLHttpRequest.HEADERS_RECEIVED) { - throw new Error("No headers received"); - } - - var chunkSize = this.chunkSize || 10; - var index = 0; - this.responseText = ""; - - do { - if (this.async) { - this.readyStateChange(FakeXMLHttpRequest.LOADING); - } - - this.responseText += body.substring(index, index + chunkSize); - index += chunkSize; - } while (index < body.length); - - var type = this.getResponseHeader("Content-Type"); - - if (this.responseText && - (!type || /(text\/xml)|(application\/xml)|(\+xml)/.test(type))) { - try { - this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText); - } catch (e) {} - } - - if (this.async) { - this.readyStateChange(FakeXMLHttpRequest.DONE); - } else { - this.readyState = FakeXMLHttpRequest.DONE; - } - }, - - respond: function respond(status, headers, body) { - this.setResponseHeaders(headers || {}); - this.status = typeof status == "number" ? status : 200; - this.statusText = FakeXMLHttpRequest.statusCodes[this.status]; - this.setResponseBody(body || ""); - } - }); - - sinon.extend(FakeXMLHttpRequest, { - UNSENT: 0, - OPENED: 1, - HEADERS_RECEIVED: 2, - LOADING: 3, - DONE: 4 - }); - - // Borrowed from JSpec - FakeXMLHttpRequest.parseXML = function parseXML(text) { - var xmlDoc; - - if (typeof DOMParser != "undefined") { - var parser = new DOMParser(); - xmlDoc = parser.parseFromString(text, "text/xml"); - } else { - xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); - xmlDoc.async = "false"; - xmlDoc.loadXML(text); - } - - return xmlDoc; - }; - - FakeXMLHttpRequest.statusCodes = { - 100: "Continue", - 101: "Switching Protocols", - 200: "OK", - 201: "Created", - 202: "Accepted", - 203: "Non-Authoritative Information", - 204: "No Content", - 205: "Reset Content", - 206: "Partial Content", - 300: "Multiple Choice", - 301: "Moved Permanently", - 302: "Found", - 303: "See Other", - 304: "Not Modified", - 305: "Use Proxy", - 307: "Temporary Redirect", - 400: "Bad Request", - 401: "Unauthorized", - 402: "Payment Required", - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 406: "Not Acceptable", - 407: "Proxy Authentication Required", - 408: "Request Timeout", - 409: "Conflict", - 410: "Gone", - 411: "Length Required", - 412: "Precondition Failed", - 413: "Request Entity Too Large", - 414: "Request-URI Too Long", - 415: "Unsupported Media Type", - 416: "Requested Range Not Satisfiable", - 417: "Expectation Failed", - 422: "Unprocessable Entity", - 500: "Internal Server Error", - 501: "Not Implemented", - 502: "Bad Gateway", - 503: "Service Unavailable", - 504: "Gateway Timeout", - 505: "HTTP Version Not Supported" - }; - - return FakeXMLHttpRequest; -}()); - -(function (global) { - var GlobalXMLHttpRequest = global.XMLHttpRequest; - var GlobalActiveXObject = global.ActiveXObject; - var supportsActiveX = typeof ActiveXObject != "undefined"; - var supportsXHR = typeof XMLHttpRequest != "undefined"; - - sinon.useFakeXMLHttpRequest = function () { - sinon.FakeXMLHttpRequest.restore = function restore(keepOnCreate) { - if (supportsXHR) { - global.XMLHttpRequest = GlobalXMLHttpRequest; - } - - if (supportsActiveX) { - global.ActiveXObject = GlobalActiveXObject; - } - - delete sinon.FakeXMLHttpRequest.restore; - - if (keepOnCreate !== true) { - delete sinon.FakeXMLHttpRequest.onCreate; - } - }; - - if (supportsXHR) { - global.XMLHttpRequest = sinon.FakeXMLHttpRequest; - } - - if (supportsActiveX) { - global.ActiveXObject = function ActiveXObject(objId) { - if (objId == "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) { - return new sinon.FakeXMLHttpRequest(); - } - - return new GlobalActiveXObject(objId); - }; - } - - return sinon.FakeXMLHttpRequest; - }; -}(this)); - -if (typeof module == "object" && typeof require == "function") { - module.exports = sinon; -} - -/** - * @depend fake_xml_http_request.js - */ -/*jslint eqeqeq: false, onevar: false, regexp: false, plusplus: false*/ -/*global module, require, window*/ -/** - * The Sinon "server" mimics a web server that receives requests from - * sinon.FakeXMLHttpRequest and provides an API to respond to those requests, - * both synchronously and asynchronously. To respond synchronuously, canned - * answers have to be provided upfront. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ - -if (typeof sinon == "undefined") { - var sinon = {}; -} - -sinon.fakeServer = (function () { - var push = [].push; - function F() {} - - function create(proto) { - F.prototype = proto; - return new F(); - } - - function responseArray(handler) { - var response = handler; - - if (Object.prototype.toString.call(handler) != "[object Array]") { - response = [200, {}, handler]; - } - - if (typeof response[2] != "string") { - throw new TypeError("Fake server response body should be string, but was " + - typeof response[2]); - } - - return response; - } - - var wloc = window.location; - var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host); - - function matchOne(response, reqMethod, reqUrl) { - var rmeth = response.method; - var matchMethod = !rmeth || rmeth.toLowerCase() == reqMethod.toLowerCase(); - var url = response.url; - var matchUrl = !url || url == reqUrl || (typeof url.test == "function" && url.test(reqUrl)); - - return matchMethod && matchUrl; - } - - function match(response, request) { - var requestMethod = this.getHTTPMethod(request); - var requestUrl = request.url; - - if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) { - requestUrl = requestUrl.replace(rCurrLoc, ""); - } - - if (matchOne(response, this.getHTTPMethod(request), requestUrl)) { - if (typeof response.response == "function") { - var args = [request].concat(requestUrl.match(response.url).slice(1)); - return response.response.apply(response, args); - } - - return true; - } - - return false; - } - - return { - create: function () { - var server = create(this); - this.xhr = sinon.useFakeXMLHttpRequest(); - server.requests = []; - - this.xhr.onCreate = function (xhrObj) { - server.addRequest(xhrObj); - }; - - return server; - }, - - addRequest: function addRequest(xhrObj) { - var server = this; - push.call(this.requests, xhrObj); - - xhrObj.onSend = function () { - server.handleRequest(this); - }; - - if (this.autoRespond && !this.responding) { - setTimeout(function () { - server.responding = false; - server.respond(); - }, this.autoRespondAfter || 10); - - this.responding = true; - } - }, - - getHTTPMethod: function getHTTPMethod(request) { - if (this.fakeHTTPMethods && /post/i.test(request.method)) { - var matches = (request.requestBody || "").match(/_method=([^\b;]+)/); - return !!matches ? matches[1] : request.method; - } - - return request.method; - }, - - handleRequest: function handleRequest(xhr) { - if (xhr.async) { - if (!this.queue) { - this.queue = []; - } - - push.call(this.queue, xhr); - } else { - this.processRequest(xhr); - } - }, - - respondWith: function respondWith(method, url, body) { - if (arguments.length == 1) { - this.response = responseArray(method); - } else { - if (!this.responses) { - this.responses = []; - } - - if (arguments.length == 2) { - body = url; - url = method; - method = null; - } - - push.call(this.responses, { - method: method, - url: url, - response: typeof body == "function" ? body : responseArray(body) - }); - } - }, - - respond: function respond() { - var queue = this.queue || []; - var request; - - while(request = queue.shift()) { - this.processRequest(request); - } - }, - - processRequest: function processRequest(request) { - try { - if (request.aborted) { - return; - } - - var response = this.response || [404, {}, ""]; - - if (this.responses) { - for (var i = 0, l = this.responses.length; i < l; i++) { - if (match.call(this, this.responses[i], request)) { - response = this.responses[i].response; - break; - } - } - } - - if (request.readyState != 4) { - request.respond(response[0], response[1], response[2]); - } - } catch (e) {} - }, - - restore: function restore() { - return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments); - } - }; -}()); - -if (typeof module == "object" && typeof require == "function") { - module.exports = sinon; -} - -/** - * @depend fake_server.js - * @depend fake_timers.js - */ -/*jslint browser: true, eqeqeq: false, onevar: false*/ -/*global sinon*/ -/** - * Add-on for sinon.fakeServer that automatically handles a fake timer along with - * the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery - * 1.3.x, which does not use xhr object's onreadystatehandler at all - instead, - * it polls the object for completion with setInterval. Dispite the direct - * motivation, there is nothing jQuery-specific in this file, so it can be used - * in any environment where the ajax implementation depends on setInterval or - * setTimeout. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ - -(function () { - function Server() {} - Server.prototype = sinon.fakeServer; - - sinon.fakeServerWithClock = new Server(); - - sinon.fakeServerWithClock.addRequest = function addRequest(xhr) { - if (xhr.async) { - if (typeof setTimeout.clock == "object") { - this.clock = setTimeout.clock; - } else { - this.clock = sinon.useFakeTimers(); - this.resetClock = true; - } - - if (!this.longestTimeout) { - var clockSetTimeout = this.clock.setTimeout; - var clockSetInterval = this.clock.setInterval; - var server = this; - - this.clock.setTimeout = function (fn, timeout) { - server.longestTimeout = Math.max(timeout, server.longestTimeout || 0); - - return clockSetTimeout.apply(this, arguments); - }; - - this.clock.setInterval = function (fn, timeout) { - server.longestTimeout = Math.max(timeout, server.longestTimeout || 0); - - return clockSetInterval.apply(this, arguments); - }; - } - } - - return sinon.fakeServer.addRequest.call(this, xhr); - }; - - sinon.fakeServerWithClock.respond = function respond() { - var returnVal = sinon.fakeServer.respond.apply(this, arguments); - - if (this.clock) { - this.clock.tick(this.longestTimeout || 0); - this.longestTimeout = 0; - - if (this.resetClock) { - this.clock.restore(); - this.resetClock = false; - } - } - - return returnVal; - }; - - sinon.fakeServerWithClock.restore = function restore() { - if (this.clock) { - this.clock.restore(); - } - - return sinon.fakeServer.restore.apply(this, arguments); - }; -}()); - -/** - * @depend ../sinon.js - * @depend collection.js - * @depend util/fake_timers.js - * @depend util/fake_server_with_clock.js - */ -/*jslint eqeqeq: false, onevar: false, plusplus: false*/ -/*global require, module*/ -/** - * Manages fake collections as well as fake utilities such as Sinon's - * timers and fake XHR implementation in one convenient object. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ - -if (typeof module == "object" && typeof require == "function") { - var sinon = require("../sinon"); - sinon.extend(sinon, require("./util/fake_timers")); -} - -(function () { - var push = [].push; - - function exposeValue(sandbox, config, key, value) { - if (!value) { - return; - } - - if (config.injectInto) { - config.injectInto[key] = value; - } else { - push.call(sandbox.args, value); - } - } - - function prepareSandboxFromConfig(config) { - var sandbox = sinon.create(sinon.sandbox); - - if (config.useFakeServer) { - if (typeof config.useFakeServer == "object") { - sandbox.serverPrototype = config.useFakeServer; - } - - sandbox.useFakeServer(); - } - - if (config.useFakeTimers) { - if (typeof config.useFakeTimers == "object") { - sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers); - } else { - sandbox.useFakeTimers(); - } - } - - return sandbox; - } - - sinon.sandbox = sinon.extend(sinon.create(sinon.collection), { - useFakeTimers: function useFakeTimers() { - this.clock = sinon.useFakeTimers.apply(sinon, arguments); - - return this.add(this.clock); - }, - - serverPrototype: sinon.fakeServer, - - useFakeServer: function useFakeServer() { - var proto = this.serverPrototype || sinon.fakeServer; - - if (!proto || !proto.create) { - return null; - } - - this.server = proto.create(); - return this.add(this.server); - }, - - inject: function (obj) { - sinon.collection.inject.call(this, obj); - - if (this.clock) { - obj.clock = this.clock; - } - - if (this.server) { - obj.server = this.server; - obj.requests = this.server.requests; - } - - return obj; - }, - - create: function (config) { - if (!config) { - return sinon.create(sinon.sandbox); - } - - var sandbox = prepareSandboxFromConfig(config); - sandbox.args = sandbox.args || []; - var prop, value, exposed = sandbox.inject({}); - - if (config.properties) { - for (var i = 0, l = config.properties.length; i < l; i++) { - prop = config.properties[i]; - value = exposed[prop] || prop == "sandbox" && sandbox; - exposeValue(sandbox, config, prop, value); - } - } else { - exposeValue(sandbox, config, "sandbox", value); - } - - return sandbox; - } - }); - - sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer; - - if (typeof module != "undefined") { - module.exports = sinon.sandbox; - } -}()); - -/** - * @depend ../sinon.js - * @depend stub.js - * @depend mock.js - * @depend sandbox.js - */ -/*jslint eqeqeq: false, onevar: false, forin: true, plusplus: false*/ -/*global module, require, sinon*/ -/** - * Test function, sandboxes fakes - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - function test(callback) { - var type = typeof callback; - - if (type != "function") { - throw new TypeError("sinon.test needs to wrap a test function, got " + type); - } - - return function () { - var config = sinon.getConfig(sinon.config); - config.injectInto = config.injectIntoThis && this || config.injectInto; - var sandbox = sinon.sandbox.create(config); - var exception, result; - var args = Array.prototype.slice.call(arguments).concat(sandbox.args); - - try { - result = callback.apply(this, args); - } catch (e) { - exception = e; - } - - sandbox.verifyAndRestore(); - - if (exception) { - throw exception; - } - - return result; - }; - } - - test.config = { - injectIntoThis: true, - injectInto: null, - properties: ["spy", "stub", "mock", "clock", "server", "requests"], - useFakeTimers: true, - useFakeServer: true - }; - - if (commonJSModule) { - module.exports = test; - } else { - sinon.test = test; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend test.js - */ -/*jslint eqeqeq: false, onevar: false, eqeqeq: false*/ -/*global module, require, sinon*/ -/** - * Test case, sandboxes all test functions - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon || !Object.prototype.hasOwnProperty) { - return; - } - - function createTest(property, setUp, tearDown) { - return function () { - if (setUp) { - setUp.apply(this, arguments); - } - - var exception, result; - - try { - result = property.apply(this, arguments); - } catch (e) { - exception = e; - } - - if (tearDown) { - tearDown.apply(this, arguments); - } - - if (exception) { - throw exception; - } - - return result; - }; - } - - function testCase(tests, prefix) { - /*jsl:ignore*/ - if (!tests || typeof tests != "object") { - throw new TypeError("sinon.testCase needs an object with test functions"); - } - /*jsl:end*/ - - prefix = prefix || "test"; - var rPrefix = new RegExp("^" + prefix); - var methods = {}, testName, property, method; - var setUp = tests.setUp; - var tearDown = tests.tearDown; - - for (testName in tests) { - if (tests.hasOwnProperty(testName)) { - property = tests[testName]; - - if (/^(setUp|tearDown)$/.test(testName)) { - continue; - } - - if (typeof property == "function" && rPrefix.test(testName)) { - method = property; - - if (setUp || tearDown) { - method = createTest(property, setUp, tearDown); - } - - methods[testName] = sinon.test(method); - } else { - methods[testName] = tests[testName]; - } - } - } - - return methods; - } - - if (commonJSModule) { - module.exports = testCase; - } else { - sinon.testCase = testCase; - } -}(typeof sinon == "object" && sinon || null)); - -/** - * @depend ../sinon.js - * @depend stub.js - */ -/*jslint eqeqeq: false, onevar: false, nomen: false, plusplus: false*/ -/*global module, require, sinon*/ -/** - * Assertions matching the test spy retrieval interface. - * - * @author Christian Johansen (christian@cjohansen.no) - * @license BSD - * - * Copyright (c) 2010-2011 Christian Johansen - */ - -(function (sinon) { - var commonJSModule = typeof module == "object" && typeof require == "function"; - var slice = Array.prototype.slice; - var assert; - - if (!sinon && commonJSModule) { - sinon = require("../sinon"); - } - - if (!sinon) { - return; - } - - function verifyIsStub() { - var method; - - for (var i = 0, l = arguments.length; i < l; ++i) { - method = arguments[i]; - - if (!method) { - assert.fail("fake is not a spy"); - } - - if (typeof method != "function") { - assert.fail(method + " is not a function"); - } - - if (typeof method.getCall != "function") { - assert.fail(method + " is not stubbed"); - } - } - } - - function failAssertion(object, msg) { - var failMethod = object.fail || assert.fail; - failMethod.call(object, msg); - } - - function mirrorPropAsAssertion(name, method, message) { - if (arguments.length == 2) { - message = method; - method = name; - } - - assert[name] = function (fake) { - verifyIsStub(fake); - - var args = slice.call(arguments, 1); - var failed = false; - - if (typeof method == "function") { - failed = !method(fake); - } else { - failed = typeof fake[method] == "function" ? - !fake[method].apply(fake, args) : !fake[method]; - } - - if (failed) { - failAssertion(this, fake.printf.apply(fake, [message].concat(args))); - } else { - assert.pass(name); - } - }; - } - - function exposedName(prefix, prop) { - return !prefix || /^fail/.test(prop) ? prop : - prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1); - }; - - assert = { - failException: "AssertError", - - fail: function fail(message) { - var error = new Error(message); - error.name = this.failException || assert.failException; - - throw error; - }, - - pass: function pass(assertion) {}, - - callOrder: function assertCallOrder() { - verifyIsStub.apply(null, arguments); - var expected = "", actual = ""; - - if (!sinon.calledInOrder(arguments)) { - try { - expected = [].join.call(arguments, ", "); - actual = sinon.orderByFirstCall(slice.call(arguments)).join(", "); - } catch (e) {} - - failAssertion(this, "expected " + expected + " to be " + - "called in order but were called as " + actual); - } else { - assert.pass("callOrder"); - } - }, - - callCount: function assertCallCount(method, count) { - verifyIsStub(method); - - if (method.callCount != count) { - var msg = "expected %n to be called " + sinon.timesInWords(count) + - " but was called %c%C"; - failAssertion(this, method.printf(msg)); - } else { - assert.pass("callCount"); - } - }, - - expose: function expose(target, options) { - if (!target) { - throw new TypeError("target is null or undefined"); - } - - var o = options || {}; - var prefix = typeof o.prefix == "undefined" && "assert" || o.prefix; - var includeFail = typeof o.includeFail == "undefined" || !!o.includeFail; - - for (var method in this) { - if (method != "export" && (includeFail || !/^(fail)/.test(method))) { - target[exposedName(prefix, method)] = this[method]; - } - } - - return target; - } - }; - - mirrorPropAsAssertion("called", "expected %n to have been called at least once but was never called"); - mirrorPropAsAssertion("notCalled", function (spy) { return !spy.called; }, - "expected %n to not have been called but was called %c%C"); - mirrorPropAsAssertion("calledOnce", "expected %n to be called once but was called %c%C"); - mirrorPropAsAssertion("calledTwice", "expected %n to be called twice but was called %c%C"); - mirrorPropAsAssertion("calledThrice", "expected %n to be called thrice but was called %c%C"); - mirrorPropAsAssertion("calledOn", "expected %n to be called with %1 as this but was called with %t"); - mirrorPropAsAssertion("alwaysCalledOn", "expected %n to always be called with %1 as this but was called with %t"); - mirrorPropAsAssertion("calledWith", "expected %n to be called with arguments %*%C"); - mirrorPropAsAssertion("alwaysCalledWith", "expected %n to always be called with arguments %*%C"); - mirrorPropAsAssertion("calledWithExactly", "expected %n to be called with exact arguments %*%C"); - mirrorPropAsAssertion("alwaysCalledWithExactly", "expected %n to always be called with exact arguments %*%C"); - mirrorPropAsAssertion("neverCalledWith", "expected %n to never be called with arguments %*%C"); - mirrorPropAsAssertion("threw", "%n did not throw exception%C"); - mirrorPropAsAssertion("alwaysThrew", "%n did not always throw exception%C"); - - if (commonJSModule) { - module.exports = assert; - } else { - sinon.assert = assert; - } -}(typeof sinon == "object" && sinon || null)); diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml deleted file mode 100644 index ab759a7..0000000 --- a/spec/javascripts/support/jasmine.yml +++ /dev/null @@ -1,74 +0,0 @@ -# src_files -# -# Return an array of filepaths relative to src_dir to include before jasmine specs. -# Default: [] -# -# EXAMPLE: -# -# src_files: -# - lib/source1.js -# - lib/source2.js -# - dist/**/*.js -# -src_files: - - spec/javascripts/support/jquery.min.js - - spec/javascripts/support/jquery-ui-1.8.16.custom.min.js - - app/assets/javascripts/active_admin/compiled/lib/**/*.js - - app/assets/javascripts/active_admin/compiled/components/**/*.js - -# stylesheets -# -# Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs. -# Default: [] -# -# EXAMPLE: -# -# stylesheets: -# - css/style.css -# - stylesheets/*.css -# -stylesheets: - -# helpers -# -# Return an array of filepaths relative to spec_dir to include before jasmine specs. -# Default: ["helpers/**/*.js"] -# -# EXAMPLE: -# -helpers: - - helpers/**/*.js - - -# spec_files -# -# Return an array of filepaths relative to spec_dir to include. -# Default: ["**/*[sS]pec.js"] -# -# EXAMPLE: -# -spec_files: - - **/*[sS]pec.js - - -# src_dir -# -# Source directory path. Your src_files must be returned relative to this path. Will use root if left blank. -# Default: project root -# -# EXAMPLE: -# -# src_dir: public -# -src_dir: - -# spec_dir -# -# Spec directory path. Your spec_files must be returned relative to this path. -# Default: spec/javascripts -# -# EXAMPLE: -# -# spec_dir: spec/javascripts -# -spec_dir: spec/javascripts/ diff --git a/spec/javascripts/support/jasmine_config.rb b/spec/javascripts/support/jasmine_config.rb deleted file mode 100644 index 47286f2..0000000 --- a/spec/javascripts/support/jasmine_config.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Jasmine - class Config - - # Add your overrides or custom config code here - - end -end - - -# Note - this is necessary for rspec2, which has removed the backtrace -module Jasmine - class SpecBuilder - def declare_spec(parent, spec) - me = self - example_name = spec["name"] - @spec_ids << spec["id"] - backtrace = @example_locations[parent.description + " " + example_name] - parent.it example_name, {} do - me.report_spec(spec["id"]) - end - end - end -end diff --git a/spec/javascripts/support/jasmine_runner.rb b/spec/javascripts/support/jasmine_runner.rb deleted file mode 100644 index 13ebce0..0000000 --- a/spec/javascripts/support/jasmine_runner.rb +++ /dev/null @@ -1,32 +0,0 @@ -$:.unshift(ENV['JASMINE_GEM_PATH']) if ENV['JASMINE_GEM_PATH'] # for gem testing purposes - -require 'rubygems' -require 'jasmine' -jasmine_config_overrides = File.expand_path(File.join(File.dirname(__FILE__), 'jasmine_config.rb')) -require jasmine_config_overrides if File.exist?(jasmine_config_overrides) -if Jasmine::rspec2? - require 'rspec' -else - require 'spec' -end - -jasmine_config = Jasmine::Config.new -spec_builder = Jasmine::SpecBuilder.new(jasmine_config) - -should_stop = false - -if Jasmine::rspec2? - RSpec.configuration.after(:suite) do - spec_builder.stop if should_stop - end -else - Spec::Runner.configure do |config| - config.after(:suite) do - spec_builder.stop if should_stop - end - end -end - -spec_builder.start -should_stop = true -spec_builder.declare_suites \ No newline at end of file diff --git a/spec/javascripts/support/jquery-ui-1.8.16.custom.min.js b/spec/javascripts/support/jquery-ui-1.8.16.custom.min.js deleted file mode 100755 index 350b024..0000000 --- a/spec/javascripts/support/jquery-ui-1.8.16.custom.min.js +++ /dev/null @@ -1,34 +0,0 @@ -/*! - * jQuery UI 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI - */ -(function(c,j){function k(a,b){var d=a.nodeName.toLowerCase();if("area"===d){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&l(a)}return(/input|select|textarea|button|object/.test(d)?!a.disabled:"a"==d?a.href||b:b)&&l(a)}function l(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.16", -keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({propAttr:c.fn.prop||c.fn.attr,_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d= -this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this, -"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart": -"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,m,n){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(m)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(n)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight, -outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){return k(a,!isNaN(c.attr(a,"tabindex")))},tabbable:function(a){var b=c.attr(a, -"tabindex"),d=isNaN(b);return(d||b>=0)&&k(a,!d)}});c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&& -a.element[0].parentNode)for(var e=0;e0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; -f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() -{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/spec/spec_helper_without_rails.rb b/spec/spec_helper_without_rails.rb deleted file mode 100644 index f2a1078..0000000 --- a/spec/spec_helper_without_rails.rb +++ /dev/null @@ -1,9 +0,0 @@ -$LOAD_PATH.unshift(File.dirname(__FILE__)) -$LOAD_PATH << File.expand_path('../support', __FILE__) - -ENV['BUNDLE_GEMFILE'] = File.expand_path('../../Gemfile', __FILE__) -require "bundler" -Bundler.setup - -require 'detect_rails_version' -ENV['RAILS'] = detect_rails_version diff --git a/spec/support/detect_rails_version.rb b/spec/support/detect_rails_version.rb deleted file mode 100644 index 84d6e9c..0000000 --- a/spec/support/detect_rails_version.rb +++ /dev/null @@ -1,37 +0,0 @@ -# Detects the current version of Rails that is being used -# -# -unless defined?(RAILS_VERSION_FILE) - RAILS_VERSION_FILE = File.expand_path("../../../.rails-version", __FILE__) -end - -unless defined?(DEFAULT_RAILS_VERSION) - # DEFAULT_RAILS_VERSION = "3.2.0" - require 'rails/version' - DEFAULT_RAILS_VERSION = Rails::VERSION::STRING -end - -def detect_rails_version - version = version_from_file || version_from_env || DEFAULT_RAILS_VERSION - - puts "Detected Rails: #{version}" if ENV['DEBUG'] - - version -end - -def version_from_file - if File.exists?(RAILS_VERSION_FILE) - version = File.read(RAILS_VERSION_FILE).chomp.strip - version = nil if version == "" - - version - end -end - -def version_from_env - ENV['RAILS'] -end - -def write_rails_version(version) - File.open(RAILS_VERSION_FILE, "w+"){|f| f << version } -end diff --git a/spec/support/integration_example_group.rb b/spec/support/integration_example_group.rb deleted file mode 100644 index 3096ebd..0000000 --- a/spec/support/integration_example_group.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'action_dispatch' -require 'capybara/rails' -require 'capybara/dsl' - -module RSpec - module Rails - module IntegrationExampleGroup - extend ActiveSupport::Concern - - include ActionDispatch::Integration::Runner - include RSpec::Rails::TestUnitAssertionAdapter - include ActionDispatch::Assertions - include Capybara::DSL - include RSpec::Matchers - - def app - ::Rails.application - end - - def last_response - page - end - - included do - before do - @router = ::Rails.application.routes - end - end - end - end -end diff --git a/spec/support/jslint.yml b/spec/support/jslint.yml deleted file mode 100644 index 44c426d..0000000 --- a/spec/support/jslint.yml +++ /dev/null @@ -1,80 +0,0 @@ -# ------------ rake task options ------------ - -# JS files to check by default, if no parameters are passed to rake jslint -# (you may want to limit this only to your own scripts and exclude any external scripts and frameworks) - -# this can be overridden by adding 'paths' and 'exclude_paths' parameter to rake command: -# rake jslint paths=path1,path2,... exclude_paths=library1,library2,... - -paths: - - app/assets/javascripts/active_admin/**/*.js - -exclude_paths: - - app/assets/javascripts/active_admin/vendor.js - -# ------------ jslint options ------------ -# see http://www.jslint.com/lint.html#options for more detailed explanations - -# "enforce" type options (true means potentially more warnings) - -adsafe: false # true if ADsafe rules should be enforced. See http://www.ADsafe.org/ -bitwise: true # true if bitwise operators should not be allowed -newcap: true # true if Initial Caps must be used with constructor functions -eqeqeq: false # true if === should be required (for ALL equality comparisons) -immed: false # true if immediate function invocations must be wrapped in parens -nomen: false # true if initial or trailing underscore in identifiers should be forbidden -onevar: false # true if only one var statement per function should be allowed -plusplus: false # true if ++ and -- should not be allowed -regexp: false # true if . and [^...] should not be allowed in RegExp literals -safe: false # true if the safe subset rules are enforced (used by ADsafe) -strict: false # true if the ES5 "use strict"; pragma is required -undef: false # true if variables must be declared before used -white: false # true if strict whitespace rules apply (see also 'indent' option) - -# "allow" type options (false means potentially more warnings) - -cap: false # true if upper case HTML should be allowed -css: true # true if CSS workarounds should be tolerated -debug: false # true if debugger statements should be allowed (set to false before going into production) -es5: false # true if ECMAScript 5 syntax should be allowed -evil: false # true if eval should be allowed -forin: true # true if unfiltered 'for in' statements should be allowed -fragment: true # true if HTML fragments should be allowed -laxbreak: false # true if statement breaks should not be checked -on: false # true if HTML event handlers (e.g. onclick="...") should be allowed -sub: false # true if subscript notation may be used for expressions better expressed in dot notation - -# other options - -maxlen: 300 # Maximum line length -indent: 2 # Number of spaces that should be used for indentation - used only if 'white' option is set -maxerr: 50 # The maximum number of warnings reported (per file) -passfail: false # true if the scan should stop on first error (per file) -# following are relevant only if undef = true -predef: '' # Names of predefined global variables - comma-separated string or a YAML array -browser: true # true if the standard browser globals should be predefined -rhino: false # true if the Rhino environment globals should be predefined -windows: false # true if Windows-specific globals should be predefined -widget: false # true if the Yahoo Widgets globals should be predefined -devel: true # true if functions like alert, confirm, console, prompt etc. are predefined - - -# ------------ jslint_on_rails custom lint options (switch to true to disable some annoying warnings) ------------ - -# ignores "missing semicolon" warning at the end of a function; this lets you write one-liners -# like: x.map(function(i) { return i + 1 }); without having to put a second semicolon inside the function -lastsemic: false - -# allows you to use the 'new' expression as a statement (without assignment) -# so you can call e.g. new Ajax.Request(...), new Effect.Highlight(...) without assigning to a dummy variable -newstat: false - -# ignores the "Expected an assignment or function call and instead saw an expression" warning, -# if the expression contains a proper statement and makes sense; this lets you write things like: -# element && element.show(); -# valid || other || lastChance || alert('OMG!'); -# selected ? show() : hide(); -# although these will still cause a warning: -# element && link; -# selected ? 5 : 10; -statinexp: false \ No newline at end of file diff --git a/spec/support/rails_template.rb b/spec/support/rails_template.rb deleted file mode 100644 index f8e0c32..0000000 --- a/spec/support/rails_template.rb +++ /dev/null @@ -1,73 +0,0 @@ -# Rails template to build the sample app for specs - -# Create a cucumber database and environment -# copy_file File.expand_path('../templates/cucumber.rb', __FILE__), "config/environments/cucumber.rb" -# copy_file File.expand_path('../templates/cucumber_with_reloading.rb', __FILE__), "config/environments/cucumber_with_reloading.rb" - -# gsub_file 'config/database.yml', /^test:.*\n/, "test: &test\n" -# gsub_file 'config/database.yml', /\z/, "\ncucumber:\n <<: *test\n database: db/cucumber.sqlite3" -# gsub_file 'config/database.yml', /\z/, "\ncucumber_with_reloading:\n <<: *test\n database: db/cucumber.sqlite3" - -# Generate some test models -generate :model, "post title:string body:text published_at:datetime author_id:integer category_id:integer" -inject_into_file 'app/models/post.rb', " belongs_to :author, :class_name => 'User'\n belongs_to :category\n accepts_nested_attributes_for :author\n", :after => "class Post < ActiveRecord::Base\n" -# Rails 3.2.3 model generator declare attr_accessible -inject_into_file 'app/models/post.rb', " attr_accessible :author\n", :before => "end" if Rails::VERSION::STRING >= '3.2.3' -generate :model, "user type:string first_name:string last_name:string username:string age:integer" -inject_into_file 'app/models/user.rb', " has_many :posts, :foreign_key => 'author_id'\n", :after => "class User < ActiveRecord::Base\n" -generate :model, "publisher --migration=false --parent=User" -generate :model, 'category name:string description:text' -inject_into_file 'app/models/category.rb', " has_many :posts\n accepts_nested_attributes_for :posts\n", :after => "class Category < ActiveRecord::Base\n" -generate :model, 'store name:string' - -# Generate a model with string ids -generate :model, "tag name:string" -# gsub_file(Dir['db/migrate/*_create_tags.rb'][0], /\:tags\sdo\s.*/, ":tags, :id => false, :primary_key => :id do |t|\n\t\t\tt.string :id\n" ) -id_model_setup = <<-EOF - self.primary_key = :id - before_create :set_id - - private - def set_id - self.id = 8.times.inject("") { |s,e| s << (i = Kernel.rand(62); i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61 ))).chr } - end -EOF -inject_into_file 'app/models/tag.rb', id_model_setup, :after => "class Tag < ActiveRecord::Base\n" - -if Rails::VERSION::MAJOR == 3 && Rails::VERSION::MINOR == 1 #Rails 3.1 Gotcha - gsub_file 'app/models/tag.rb', /self\.primary_key.*$/, "define_attr_method :primary_key, :id" -end - -# Configure default_url_options in test environment -inject_into_file "config/environments/test.rb", " config.action_mailer.default_url_options = { :host => 'example.com' }\n", :after => "config.cache_classes = true\n" - -# # Add our local Active Admin to the load path -# inject_into_file "config/environment.rb", "\n$LOAD_PATH.unshift('#{File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib'))}')\nrequire \"active_admin\"\n", :after => "require File.expand_path('../application', __FILE__)" - -# Add some translations -append_file "config/locales/en.yml", File.read(File.expand_path('../templates/en.yml', __FILE__)) - -# Add predefined admin resources -directory File.expand_path('../templates/admin', __FILE__), "app/admin" - -run "rm Gemfile" -run "rm -r test" -run "rm -r spec" - -$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) - -# we need this routing path, named "logout_path", for testing -route <<-EOS - devise_scope :user do - match '/admin/logout' => 'active_admin/devise/sessions#destroy', :as => :logout - end -EOS - -generate :'active_admin:install' - -# Setup a root path for devise -route "root :to => 'admin/dashboard#index'" - -# rake "db:migrate" -# rake "db:test:prepare" -# run "/usr/bin/env RAILS_ENV=cucumber rake db:migrate" diff --git a/spec/support/rails_template_with_data.rb b/spec/support/rails_template_with_data.rb deleted file mode 100644 index 1be8d73..0000000 --- a/spec/support/rails_template_with_data.rb +++ /dev/null @@ -1,58 +0,0 @@ -# Use the default -apply File.expand_path("../rails_template.rb", __FILE__) - -# Register Active Admin controllers -%w{ Post User Category }.each do |type| - generate :'active_admin:resource', type -end - -scopes = <<-EOF - scope :all, :default => true - - scope :drafts do |posts| - posts.where(["published_at IS NULL"]) - end - - scope :scheduled do |posts| - posts.where(["posts.published_at IS NOT NULL AND posts.published_at > ?", Time.now.utc]) - end - - scope :published do |posts| - posts.where(["posts.published_at IS NOT NULL AND posts.published_at < ?", Time.now.utc]) - end - - scope :my_posts do |posts| - posts.where(:author_id => current_admin_user.id) - end -EOF -inject_into_file 'app/admin/posts.rb', scopes , :after => "ActiveAdmin.register Post do\n" - -# Setup some default data -append_file "db/seeds.rb", <<-EOF - users = ["Jimi Hendrix", "Jimmy Page", "Yngwie Malmsteen", "Eric Clapton", "Kirk Hammett"].collect do |name| - first, last = name.split(" ") - User.create! :first_name => first, - :last_name => last, - :username => [first,last].join('-').downcase, - :age => rand(80) - end - - categories = ["Rock", "Pop Rock", "Alt-Country", "Blues", "Dub-Step"].collect do |name| - Category.create! :name => name - end - - published_at_values = [Time.now.utc - 5.days, Time.now.utc - 1.day, nil, Time.now.utc + 3.days] - - 1_000.times do |i| - user = users[i % users.size] - cat = categories[i % categories.size] - published_at = published_at_values[i % published_at_values.size] - Post.create :title => "Blog Post \#{i}", - :body => "Blog post \#{i} is written by \#{user.username} about \#{cat.name}", - :category => cat, - :published_at => published_at, - :author => user - end -EOF - -rake 'db:seed' diff --git a/spec/support/templates/admin/stores.rb b/spec/support/templates/admin/stores.rb deleted file mode 100644 index 2078d00..0000000 --- a/spec/support/templates/admin/stores.rb +++ /dev/null @@ -1 +0,0 @@ -ActiveAdmin.register Store diff --git a/spec/support/templates/cucumber.rb b/spec/support/templates/cucumber.rb deleted file mode 100644 index 183fa0f..0000000 --- a/spec/support/templates/cucumber.rb +++ /dev/null @@ -1,24 +0,0 @@ -require File.expand_path('config/environments/test', Rails.root) - -# rails/railties/lib/rails/test_help.rb aborts if the environment is not 'test'. (Rails 3.0.0.beta3) -# We can't run Cucumber/RSpec/Test_Unit tests in different environments then. -# -# For now, I patch StringInquirer so that Rails.env.test? returns true when Rails.env is 'test' or 'cucumber' -# -# https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/4458-rails-should-allow-test-to-run-in-cucumber-environment -module ActiveSupport - class StringInquirer < String - def method_missing(method_name, *arguments) - if method_name.to_s[-1,1] == "?" - test_string = method_name.to_s[0..-2] - if test_string == 'test' - self == 'test' or self == 'cucumber' - else - self == test_string - end - else - super - end - end - end -end diff --git a/spec/support/templates/cucumber_with_reloading.rb b/spec/support/templates/cucumber_with_reloading.rb deleted file mode 100644 index e9b2592..0000000 --- a/spec/support/templates/cucumber_with_reloading.rb +++ /dev/null @@ -1,5 +0,0 @@ -require File.expand_path('config/environments/cucumber', Rails.root) - -Rails.application.class.configure do - config.cache_classes = false -end diff --git a/spec/support/templates/en.yml b/spec/support/templates/en.yml deleted file mode 100644 index d1d2b61..0000000 --- a/spec/support/templates/en.yml +++ /dev/null @@ -1,6 +0,0 @@ -# Sample translations used to test ActiveAdmin's I18n integration. - activerecord: - models: - store: - one: Bookstore - other: Bookstores diff --git a/spec/unit/abstract_view_factory_spec.rb b/spec/unit/abstract_view_factory_spec.rb deleted file mode 100644 index 4d1c772..0000000 --- a/spec/unit/abstract_view_factory_spec.rb +++ /dev/null @@ -1,79 +0,0 @@ -require 'spec_helper' - -require 'active_admin/abstract_view_factory' - -describe ActiveAdmin::AbstractViewFactory do - - let(:view_factory){ ActiveAdmin::AbstractViewFactory.new } - let(:mock_view){ Class.new } - - describe "registering a new view key" do - before do - view_factory.register :my_new_view_class => mock_view - end - - it "should respond to :my_new_view_class" do - view_factory.respond_to?(:my_new_view_class) - end - - it "should respond to :my_new_view_class=" do - view_factory.respond_to?(:my_new_view_class=) - end - - it "should generate a getter method" do - view_factory.my_new_view_class.should == mock_view - end - - it "should be settable view a setter method" do - view_factory.my_new_view_class = "Some Obj" - view_factory.my_new_view_class.should == "Some Obj" - end - end - - describe "array syntax access" do - before do - view_factory.register :my_new_view_class => mock_view - end - - it "should be available through array syntax" do - view_factory[:my_new_view_class].should == mock_view - end - - it "should be settable through array syntax" do - view_factory[:my_new_view_class] = "My New View Class" - view_factory[:my_new_view_class].should == "My New View Class" - end - end - - describe "registering default views" do - before do - ActiveAdmin::AbstractViewFactory.register :my_default_view_class => mock_view - end - it "should generate a getter method" do - view_factory.my_default_view_class.should == mock_view - end - it "should be settable view a setter method and not change default" do - view_factory.my_default_view_class = "Some Obj" - view_factory.my_default_view_class.should == "Some Obj" - view_factory.default_for(:my_default_view_class).should == mock_view - end - end - - describe "subclassing the ViewFactory" do - let(:subclass) do - ActiveAdmin::AbstractViewFactory.register :my_subclassed_view => "From Parent" - Class.new(ActiveAdmin::AbstractViewFactory) do - def my_subclassed_view - "From Subclass" - end - end - end - - it "should use the subclass implementation" do - factory = subclass.new - factory.my_subclassed_view.should == "From Subclass" - end - end - - -end diff --git a/spec/unit/action_builder_spec.rb b/spec/unit/action_builder_spec.rb deleted file mode 100644 index 25fcaec..0000000 --- a/spec/unit/action_builder_spec.rb +++ /dev/null @@ -1,126 +0,0 @@ -require 'spec_helper' - -describe 'defining new actions from registration blocks' do - - let(:controller){ Admin::PostsController } - - describe "generating a new member action" do - before do - action! - reload_routes! - end - - after(:each) do - controller.clear_member_actions! - end - - context "with a block" do - let(:action!) do - ActiveAdmin.register Post do - member_action :comment do - # Do nothing - end - end - end - - it "should create a new public instance method" do - controller.public_instance_methods.collect(&:to_s).should include("comment") - end - it "should add itself to the member actions config" do - controller.active_admin_config.member_actions.size.should == 1 - end - it "should create a new named route" do - Rails.application.routes.url_helpers.methods.collect(&:to_s).should include("comment_admin_post_path") - end - end - - context "without a block" do - let(:action!) do - ActiveAdmin.register Post do - member_action :comment - end - end - it "should still generate a new empty action" do - controller.public_instance_methods.collect(&:to_s).should include("comment") - end - end - - context "with :title" do - let(:action!) do - ActiveAdmin.register Post do - member_action :comment, :title => "My Awesome Comment" - end - end - - subject { find_before_filter controller, :comment } - - it { should set_page_title_to "My Awesome Comment" } - end - end - - describe "generate a new collection action" do - before do - action! - reload_routes! - end - after(:each) do - controller.clear_collection_actions! - end - - context "with a block" do - let(:action!) do - ActiveAdmin.register Post do - collection_action :comments do - # Do nothing - end - end - end - it "should create a new public instance method" do - controller.public_instance_methods.collect(&:to_s).should include("comments") - end - it "should add itself to the member actions config" do - controller.active_admin_config.collection_actions.size.should == 1 - end - it "should create a new named route" do - Rails.application.routes.url_helpers.methods.collect(&:to_s).should include("comments_admin_posts_path") - end - end - context "without a block" do - let(:action!) do - ActiveAdmin.register Post do - collection_action :comments - end - end - it "should still generate a new empty action" do - controller.public_instance_methods.collect(&:to_s).should include("comments") - end - end - context "with :title" do - let(:action!) do - ActiveAdmin.register Post do - collection_action :comments, :title => "My Awesome Comments" - end - end - - subject { find_before_filter controller, :comments } - - it { should set_page_title_to "My Awesome Comments" } - end - end - - def find_before_filter(controller, action) - controller._process_action_callbacks.detect { |f| f.kind == :before && f.options[:only] == [action] } - end - - RSpec::Matchers.define :set_page_title_to do |expected| - match do |filter| - filter.raw_filter.call - @actual = filter.klass.instance_variable_get(:@page_title) - @actual == expected - end - - failure_message_for_should do |filter| - message = "expected before_filter to set the @page_title to '#{expected}', but was '#{@actual}'" - end - end -end diff --git a/spec/unit/active_admin_spec.rb b/spec/unit/active_admin_spec.rb deleted file mode 100644 index a7a397e..0000000 --- a/spec/unit/active_admin_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'spec_helper' - -describe ActiveAdmin do - describe "#default_namespace" do - it "should delegate to ActiveAdmin.application" do - ActiveAdmin.application.should_receive(:default_namespace) - - ActiveAdmin.default_namespace - end - - it "should be deprecated" do - ActiveAdmin::Deprecation.should_receive(:warn) - - ActiveAdmin.default_namespace - end - end - - %w(register register_page unload! load! routes).each do |method| - it "delegates ##{method} to application" do - ActiveAdmin.application.should_receive(method) - - ActiveAdmin.send(method) - end - end -end diff --git a/spec/unit/application_spec.rb b/spec/unit/application_spec.rb deleted file mode 100644 index 37280f4..0000000 --- a/spec/unit/application_spec.rb +++ /dev/null @@ -1,129 +0,0 @@ -require 'spec_helper' -require 'fileutils' - -describe ActiveAdmin::Application do - - let(:application) do - ActiveAdmin::Application.new.tap do |app| - # Manually override the load paths becuase RSpec messes these up - app.load_paths = [File.expand_path('app/admin', Rails.root)] - end - end - - it "should have a default load path of ['app/admin']" do - application.load_paths.should == [File.expand_path('app/admin', Rails.root)] - end - - it "should remove app/admin from the autoload path to remove the possibility of conflicts" do - ActiveSupport::Dependencies.autoload_paths.should_not include(File.join(Rails.root, "app/admin")) - end - - it "should remove app/admin from the eager load paths (Active Admin deals with loading)" do - Rails.application.config.eager_load_paths.should_not include(File.join(Rails.root, "app/admin")) - end - - it "should store the site's title" do - application.site_title.should == "" - end - - it "should set the site title" do - application.site_title = "New Title" - application.site_title.should == "New Title" - end - - it "should store the site's title link" do - application.site_title_link.should == "" - end - - it "should set the site's title link" do - application.site_title_link = "http://www.mygreatsite.com" - application.site_title_link.should == "http://www.mygreatsite.com" - end - - it "should store the site's title image" do - application.site_title_image.should == "" - end - - it "should set the site's title image" do - application.site_title_image = "http://railscasts.com/assets/episodes/stills/284-active-admin.png?1316476106" - application.site_title_image.should == "http://railscasts.com/assets/episodes/stills/284-active-admin.png?1316476106" - end - - it "should have a view factory" do - application.view_factory.should be_an_instance_of(ActiveAdmin::ViewFactory) - end - - it "should have deprecated admin notes by default" do - application.admin_notes.should be_nil - end - - it "should allow comments by default" do - application.allow_comments.should == true - end - - describe "authentication settings" do - - it "should have no default current_user_method" do - application.current_user_method.should == false - end - - it "should have no default authentication method" do - application.authentication_method.should == false - end - - it "should have a logout link path (Devise's default)" do - application.logout_link_path.should == :destroy_admin_user_session_path - end - - it "should have a logout link method (Devise's default)" do - application.logout_link_method.should == :get - end - end - - describe "files in load path" do - it "should load files in the first level directory" do - application.files_in_load_path.should include(File.expand_path("app/admin/dashboard.rb", Rails.root)) - end - - it "should load files from subdirectories" do - FileUtils.mkdir_p(File.expand_path("app/admin/public", Rails.root)) - test_file = File.expand_path("app/admin/public/posts.rb", Rails.root) - FileUtils.touch(test_file) - application.files_in_load_path.should include(test_file) - end - end - - describe "#namespace (or #find_or_create_namespace)" do - - it "should yield a new namespace" do - application.namespace :new_namespace do |ns| - ns.name.should == :new_namespace - end - end - - it "should return an instantiated namespace" do - admin = application.find_or_create_namespace :admin - admin.should == application.namespaces[:admin] - end - - it "should yield an existing namespace" do - expect { - application.namespace :admin do |ns| - ns.should == application.namespaces[:admin] - raise "found" - end - }.to raise_error("found") - end - end - - describe "#register_page" do - it "finds or create the namespace and register the page to it" do - namespace = mock - application.should_receive(:find_or_create_namespace).with("public").and_return namespace - namespace.should_receive(:register_page).with("My Page", {:namespace => "public"}) - - application.register_page("My Page", :namespace => "public") - end - end - -end diff --git a/spec/unit/asset_registration_spec.rb b/spec/unit/asset_registration_spec.rb deleted file mode 100644 index 62a767f..0000000 --- a/spec/unit/asset_registration_spec.rb +++ /dev/null @@ -1,43 +0,0 @@ -require 'spec_helper' - -module MockRegistration - extend ActiveAdmin::AssetRegistration -end - -describe ActiveAdmin::AssetRegistration do - - before do - MockRegistration.clear_stylesheets! - MockRegistration.clear_javascripts! - end - - it "should register a stylesheet file" do - MockRegistration.register_stylesheet "active_admin.css" - MockRegistration.stylesheets.length.should == 1 - MockRegistration.stylesheets.first.path.should == "active_admin.css" - end - - it "should clear all existing stylesheets" do - MockRegistration.register_stylesheet "active_admin.css" - MockRegistration.stylesheets.length.should == 1 - MockRegistration.clear_stylesheets! - MockRegistration.stylesheets.length.should == 0 - end - - it "should allow media option when registering stylesheet" do - MockRegistration.register_stylesheet "active_admin.css", :media => :print - MockRegistration.stylesheets.first.options[:media].should == :print - end - - it "should register a javascript file" do - MockRegistration.register_javascript "active_admin.js" - MockRegistration.javascripts.should == ["active_admin.js"] - end - - it "should clear all existing javascripts" do - MockRegistration.register_javascript "active_admin.js" - MockRegistration.javascripts.should == ["active_admin.js"] - MockRegistration.clear_javascripts! - MockRegistration.javascripts.should == [] - end -end diff --git a/spec/unit/auto_link_spec.rb b/spec/unit/auto_link_spec.rb deleted file mode 100644 index 1d511d6..0000000 --- a/spec/unit/auto_link_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -require 'spec_helper' - -class AutoLinkMockResource - attr_accessor :namespace - def initialize(namespace) - @namespace = namespace - end -end - -describe "auto linking resources" do - include ActiveAdmin::ViewHelpers::ActiveAdminApplicationHelper - include ActiveAdmin::ViewHelpers::AutoLinkHelper - include ActiveAdmin::ViewHelpers::DisplayHelper - - let(:active_admin_config) { AutoLinkMockResource.new(namespace) } - let(:active_admin_namespace){ ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin) } - let(:post){ Post.create! :title => "Hello World" } - - def admin_post_path(post) - "/admin/posts/#{post.id}" - end - - context "when the resource is not registered" do - it "should return the display name of the object" do - auto_link(post).should == "Hello World" - end - end - - context "when the resource is registered" do - before do - active_admin_namespace.register Post - end - it "should return a link with the display name of the object" do - self.should_receive(:link_to).with("Hello World", admin_post_path(post)) - auto_link(post) - end - end - -end diff --git a/spec/unit/base_controller_shared_examples.rb b/spec/unit/base_controller_shared_examples.rb deleted file mode 100644 index 15ddd76..0000000 --- a/spec/unit/base_controller_shared_examples.rb +++ /dev/null @@ -1,25 +0,0 @@ -# Required methods: -# * controller_class -# * controller -# -shared_examples_for "BaseController" do - let(:controller_class) { described_class } - - describe "Menu" do - describe "setting the current tab" do - before do - controller.stub!(:active_admin_config => resource, :parent? => true) - controller.send :set_current_tab # Run the before filter - end - subject{ controller.instance_variable_get(:@current_tab) } - - context "when menu item name is 'Resources' without a parent menu item" do - let(:menu_item){ stub } - let(:resource){ mock(:menu_item => menu_item, :parent_menu_item_name => nil, :belongs_to? => false) } - it { should == menu_item } - end - - end - end - -end diff --git a/spec/unit/base_controller_spec.rb b/spec/unit/base_controller_spec.rb deleted file mode 100644 index 1743fb9..0000000 --- a/spec/unit/base_controller_spec.rb +++ /dev/null @@ -1,8 +0,0 @@ -require 'spec_helper' -require File.expand_path('base_controller_shared_examples', File.dirname(__FILE__)) - -describe ActiveAdmin::BaseController do - let(:controller) { ActiveAdmin::BaseController.new } - - it_should_behave_like "BaseController" -end diff --git a/spec/unit/batch_actions/resource_spec.rb b/spec/unit/batch_actions/resource_spec.rb deleted file mode 100644 index a4db0e8..0000000 --- a/spec/unit/batch_actions/resource_spec.rb +++ /dev/null @@ -1,91 +0,0 @@ -require 'spec_helper' - -describe ActiveAdmin::BatchActions::ResourceExtension do - - let(:resource) do - namespace = ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin) - namespace.batch_actions = true - namespace.register(Post) - end - - describe "default action" do - - it "should have the default action by default" do - resource.batch_actions.size.should == 1 and resource.batch_actions.first.sym == :destroy - end - - end - - describe "adding a new batch action" do - - before do - resource.clear_batch_actions! - resource.add_batch_action :flag, "Flag" do - # Empty - end - end - - it "should add an batch action" do - resource.batch_actions.size.should == 1 - end - - it "should store an instance of BatchAction" do - resource.batch_actions.first.should be_an_instance_of(ActiveAdmin::BatchAction) - end - - it "should store the block in the batch action" do - resource.batch_actions.first.block.should_not be_nil - end - - end - - describe "removing batch action" do - - before do - resource.remove_batch_action :destroy - end - - it "should allow for batch action removal" do - resource.batch_actions.size.should == 0 - end - - end - - describe "#batch_action_path" do - - it "returns the path as a symbol" do - resource.batch_action_path.should == :batch_action_admin_posts_path - end - - end - - describe "#display_if_block" do - - it "should return true by default" do - action = ActiveAdmin::BatchAction.new :default, "Default" - action.display_if_block.call.should == true - end - - it "should return the :if block if set" do - action = ActiveAdmin::BatchAction.new :with_block, "With Block", :if => proc { false } - action.display_if_block.call.should == false - end - - end - - describe "batch action priority" do - - it "should have a default priority" do - action = ActiveAdmin::BatchAction.new :default, "Default" - action.priority.should == 10 - end - - it "should correctly order two actions" do - priority_one = ActiveAdmin::BatchAction.new :one, "One", :priority => 1 - priority_ten = ActiveAdmin::BatchAction.new :ten, "Ten", :priority => 10 - priority_one.should be < priority_ten - end - - end - -end diff --git a/spec/unit/batch_actions/settings_spec.rb b/spec/unit/batch_actions/settings_spec.rb deleted file mode 100644 index d013a52..0000000 --- a/spec/unit/batch_actions/settings_spec.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'spec_helper' - -describe "Batch Actions Settings" do - let(:app) { ActiveAdmin::Application.new } - let(:ns) { ActiveAdmin::Namespace.new(app, "Admin") } - let(:post_resource) { ns.register Post } - - it "should be disabled globally by default" do - # Note: the default initializer would set it to true - - app.batch_actions.should be_false - ns.batch_actions.should be_false - post_resource.batch_actions_enabled?.should be_false - end - - it "should be settable to true" do - app.batch_actions = true - app.batch_actions.should == true - end - - it "should be an inheritable_setting" do - app.batch_actions = true - ns.batch_actions.should == true - end - - it "should be settable at the namespace level" do - app.batch_actions = true - ns.batch_actions = false - - app.batch_actions.should == true - ns.batch_actions.should == false - end - - it "should be settable at the resource level" do - post_resource.batch_actions_enabled?.should == false - post_resource.batch_actions = true - post_resource.batch_actions_enabled?.should == true - end - - it "should inherit the setting on the resource from the namespace" do - ns.batch_actions = false - post_resource.batch_actions_enabled?.should == false - post_resource.batch_actions.should be_empty - - post_resource.batch_actions = true - post_resource.batch_actions_enabled?.should == true - post_resource.batch_actions.should_not be_empty - end - - it "should inherit the setting from the namespace when set to nil" do - ns.batch_actions = true - - post_resource.batch_actions = true - post_resource.batch_actions_enabled?.should == true - post_resource.batch_actions.should_not be_empty - - post_resource.batch_actions = nil - post_resource.batch_actions_enabled?.should == true # inherited from namespace - post_resource.batch_actions.should_not be_empty - end -end diff --git a/spec/unit/belongs_to_spec.rb b/spec/unit/belongs_to_spec.rb deleted file mode 100644 index 9d70574..0000000 --- a/spec/unit/belongs_to_spec.rb +++ /dev/null @@ -1,42 +0,0 @@ -require 'spec_helper' - -describe ActiveAdmin::Resource::BelongsTo do - - - let(:application){ ActiveAdmin::Application.new } - let(:namespace){ Namespace.new(application, :admin) } - let(:post){ namespace.register(Post) } - let(:belongs_to){ ActiveAdmin::Resource::BelongsTo.new(post, :user) } - - it "should have an owner" do - belongs_to.owner.should == post - end - - it "should have a namespace" do - belongs_to.namespace.should == namespace - end - - describe "finding the target" do - context "when the resource has been registered" do - let(:user){ namespace.register(User) } - before { user } # Ensure user is registered - - it "should return the target resource" do - belongs_to.target.should == user - end - end - - context "when the resource has not been registered" do - it "should raise a ActiveAdmin::BelongsTo::TargetNotFound" do - lambda { - belongs_to.target - }.should raise_error(ActiveAdmin::Resource::BelongsTo::TargetNotFound) - end - end - end - - it "should be optional" do - belongs_to = ActiveAdmin::Resource::BelongsTo.new post, :user, :optional => true - belongs_to.should be_optional - end -end diff --git a/spec/unit/breadcrumbs_spec.rb b/spec/unit/breadcrumbs_spec.rb deleted file mode 100644 index 3c35a72..0000000 --- a/spec/unit/breadcrumbs_spec.rb +++ /dev/null @@ -1,143 +0,0 @@ -require 'spec_helper' - -describe "Breadcrumbs" do - - include ActiveAdmin::ViewHelpers - - describe "generating a trail from paths" do - - # Mock our params - def params; {}; end - # Mock link to and return a hash - def link_to(name, url); {:name => name, :path => url}; end - - let(:trail) { breadcrumb_links(path) } - - context "when request '/admin'" do - let(:path){ "/admin" } - - it "should not have any items" do - trail.size.should == 0 - end - end - - context "when path '/admin/posts'" do - let(:path) { "/admin/posts" } - - it "should have one item" do - trail.size.should == 1 - end - it "should have a link to /admin" do - trail[0][:name].should == "Admin" - trail[0][:path].should == "/admin" - end - end - - context "when path '/admin/posts/1'" do - let(:path) { "/admin/posts/1" } - - it "should have 2 items" do - trail.size.should == 2 - end - it "should have a link to /admin" do - trail[0][:name].should == "Admin" - trail[0][:path].should == "/admin" - end - it "should have a link to /admin/posts" do - trail[1][:name].should == "Posts" - trail[1][:path].should == "/admin/posts" - end - end - - context "when path '/admin/posts/1/comments'" do - let(:path) { "/admin/posts/1/comments" } - - it "should have 3 items" do - trail.size.should == 3 - end - it "should have a link to /admin" do - trail[0][:name].should == "Admin" - trail[0][:path].should == "/admin" - end - it "should have a link to /admin/posts" do - trail[1][:name].should == "Posts" - trail[1][:path].should == "/admin/posts" - end - - context "when Post.find(1) doesn't exist" do - it "should have a link to /admin/posts/1" do - trail[2][:name].should == "1" - trail[2][:path].should == "/admin/posts/1" - end - end - - context "when Post.find(1) does exist" do - before do - Post.stub!(:find).and_return{ mock(:display_name => "Hello World") } - end - it "should have a link to /admin/posts/1 using display name" do - trail[2][:name].should == "Hello World" - trail[2][:path].should == "/admin/posts/1" - end - end - end - - context "when path '/admin/posts/4e24d6249ccf967313000000/comments'" do - let(:path) { "/admin/posts/4e24d6249ccf967313000000/comments" } - - it "should have 3 items" do - trail.size.should == 3 - end - it "should have a link to /admin" do - trail[0][:name].should == "Admin" - trail[0][:path].should == "/admin" - end - it "should have a link to /admin/posts" do - trail[1][:name].should == "Posts" - trail[1][:path].should == "/admin/posts" - end - - context "when Post.find(4e24d6249ccf967313000000) doesn't exist" do - it "should have a link to /admin/posts/4e24d6249ccf967313000000" do - trail[2][:name].should == "4e24d6249ccf967313000000" - trail[2][:path].should == "/admin/posts/4e24d6249ccf967313000000" - end - end - - context "when Post.find(4e24d6249ccf967313000000) does exist" do - before do - Post.stub!(:find).with('4e24d6249ccf967313000000').and_return{ mock(:display_name => "Hello World") } - end - it "should have a link to /admin/posts/4e24d6249ccf967313000000 using display name" do - trail[2][:name].should == "Hello World" - trail[2][:path].should == "/admin/posts/4e24d6249ccf967313000000" - end - end - end - - context "when path '/admin/posts/1/coments/1'" do - let(:path) { "/admin/posts/1/comments/1" } - - it "should have 4 items" do - trail.size.should == 4 - end - it "should have a link to /admin" do - trail[0][:name].should == "Admin" - trail[0][:path].should == "/admin" - end - it "should have a link to /admin/posts" do - trail[1][:name].should == "Posts" - trail[1][:path].should == "/admin/posts" - end - it "should have a link to /admin/posts/1" do - trail[2][:name].should == "1" - trail[2][:path].should == "/admin/posts/1" - end - it "should have a link to /admin/posts/1/comments" do - trail[3][:name].should == "Comments" - trail[3][:path].should == "/admin/posts/1/comments" - end - end - - end -end diff --git a/spec/unit/comments_spec.rb b/spec/unit/comments_spec.rb deleted file mode 100644 index babdc9d..0000000 --- a/spec/unit/comments_spec.rb +++ /dev/null @@ -1,124 +0,0 @@ -require 'spec_helper' - -describe "Comments" do - let(:application){ ActiveAdmin::Application.new } - - describe ActiveAdmin::Comment do - subject { ActiveAdmin::Comment } - - describe "Associations and Validations" do - before do - pending "This is not passing on Travis-CI. See Issue #1273." - end - - it { should belong_to :resource } - it { should belong_to :author } - - it { should validate_presence_of :resource } - it { should validate_presence_of :body } - it { should validate_presence_of :namespace } - end - - describe ".find_for_resource_in_namespace" do - let(:post){ Post.create!(:title => "Hello World") } - let(:namespace_name){ "admin" } - - before do - @comment = ActiveAdmin::Comment.create! :resource => post, - :body => "A Comment", - :namespace => namespace_name - end - - it "should return a comment for the resource in the same namespace" do - ActiveAdmin::Comment.find_for_resource_in_namespace(post, namespace_name).should == [@comment] - end - - it "should not return a comment for the same resource in a different namespace" do - ActiveAdmin::Comment.find_for_resource_in_namespace(post, 'public').should == [] - end - - it "should not return a comment for a different resource" do - another_post = Post.create! :title => "Another Hello World" - ActiveAdmin::Comment.find_for_resource_in_namespace(another_post, namespace_name).should == [] - end - end - - describe ".resource_id_cast" do - let(:post) { Post.create!(:title => "Testing.") } - let(:namespace_name) { "admin" } - - it "should cast resource_id as string" do - comment = ActiveAdmin::Comment.create! :resource => post, - :body => "Another Comment", - :namespace => namespace_name - ActiveAdmin::Comment.resource_id_cast(comment).class.should eql String - end - end - - describe ".resource_id_type" do - it "should be :string" do - ActiveAdmin::Comment.resource_id_type.should eql :string - end - end - - describe "Commenting on resource with string id" do - let(:tag){ Tag.create!(:name => "cooltags") } - let(:namespace_name){ "admin" } - - it "should allow commenting" do - comment = ActiveAdmin::Comment.create! :resource => tag, - :body => "Another Comment", - :namespace => namespace_name - - ActiveAdmin::Comment.find_for_resource_in_namespace(tag, namespace_name).should == [comment] - end - end - end - - describe ActiveAdmin::Comments::NamespaceHelper do - describe "#comments?" do - - it "should have comments when the namespace allows comments" do - ns = ActiveAdmin::Namespace.new(application, :admin) - ns.allow_comments = true - ns.comments?.should be_true - end - - it "should not have comments when the namespace does not allow comments" do - ns = ActiveAdmin::Namespace.new(application, :admin) - ns.allow_comments = false - ns.comments?.should be_false - end - - it "should have comments when the application allows comments and no local namespace config" do - application.allow_comments = true - ns = ActiveAdmin::Namespace.new(application, :admin) - ns.comments?.should be_true - end - - it "should not have comments when the application does not allow commands and no local namespace config" do - application.allow_comments = false - ns = ActiveAdmin::Namespace.new(application, :admin) - ns.comments?.should be_false - end - - end - end - - describe ActiveAdmin::Comments::ResourceHelper do - it "should add an attr_accessor :comments to ActiveAdmin::Resource" do - ns = ActiveAdmin::Namespace.new(application, :admin) - resource = ActiveAdmin::Resource.new(ns, Post) - resource.comments.should be_nil - resource.comments = true - resource.comments.should be_true - end - - it "should not have comment if set to false by in allow_comments_in" do - ns = ActiveAdmin::Namespace.new(application, application.default_namespace) - resource = ActiveAdmin::Resource.new(ns, Post) - resource.comments = false - resource.comments?.should be_false - end - end -end diff --git a/spec/unit/component_spec.rb b/spec/unit/component_spec.rb deleted file mode 100644 index 7ab697d..0000000 --- a/spec/unit/component_spec.rb +++ /dev/null @@ -1,18 +0,0 @@ -require 'spec_helper' - -class MockComponentClass < ActiveAdmin::Component; end - -describe ActiveAdmin::Component do - - let(:component_class){ MockComponentClass } - let(:component){ component_class.new } - - it "should be a subclass of an html div" do - ActiveAdmin::Component.ancestors.should include(Arbre::HTML::Div) - end - - it "should render to a div, even as a subclass" do - component.tag_name.should == 'div' - end - -end diff --git a/spec/unit/config_shared_examples.rb b/spec/unit/config_shared_examples.rb deleted file mode 100644 index a4e8682..0000000 --- a/spec/unit/config_shared_examples.rb +++ /dev/null @@ -1,72 +0,0 @@ -shared_examples_for "ActiveAdmin::Config" do - describe "namespace" do - it "should return the namespace" do - config.namespace.should == namespace - end - end - - describe "page_presenters" do - it "should return an empty hash by default" do - config.page_presenters.should == {} - end - end - - it { respond_to :controller_name } - it { respond_to :controller } - it { respond_to :route_prefix } - it { respond_to :route_collection_path } - it { respond_to :comments? } - it { respond_to :belongs_to? } - it { respond_to :action_items? } - it { respond_to :sidebar_sections? } - - describe "Naming" do - it "implements #resource_label" do - expect { config.resource_label }.should_not raise_error - end - - it "implements #plural_resource_label" do - expect { config.plural_resource_label }.should_not raise_error - end - end - - describe "Menu" do - describe "menu item" do - - it "initializes a new menu item with defaults" do - config.menu_item.label.should == config.plural_resource_label - end - - it "initialize a new menu item with custom options" do - config.menu :label => "Hello" - config.menu_item.label.should == "Hello" - end - - end - - describe "#include_in_menu?" do - it "should be included in menu by default" do - config.include_in_menu?.should == true - end - - it "should not be included in menu when menu set to false" do - config.menu false - config.include_in_menu?.should == false - end - end - - describe "parent menu item name" do - - it "should be nil when not set" do - config.parent_menu_item_name.should == nil - end - - it "should return the name if set" do - config.menu :parent => "Blog" - config.parent_menu_item_name.should == "Blog" - end - - end - - end -end diff --git a/spec/unit/controller_filters_spec.rb b/spec/unit/controller_filters_spec.rb deleted file mode 100644 index 5807f33..0000000 --- a/spec/unit/controller_filters_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'spec_helper' - -describe ActiveAdmin, "filters" do - let(:application){ ActiveAdmin::Application.new } - - describe "before filters" do - it "should add a new before filter to ActiveAdmin::ResourceController" do - ActiveAdmin::ResourceController.should_receive(:before_filter).and_return(true) - application.before_filter :my_filter, :only => :show - end - end - - describe "skip before filters" do - it "should add a new skip before filter to ActiveAdmin::ResourceController" do - ActiveAdmin::ResourceController.should_receive(:skip_before_filter).and_return(true) - application.skip_before_filter :my_filter, :only => :show - end - end - - describe "after filters" do - it "should add a new after filter to ActiveAdmin::ResourceController" do - ActiveAdmin::ResourceController.should_receive(:after_filter).and_return(true) - application.after_filter :my_filter, :only => :show - end - end - - describe "around filters" do - it "should add a new around filter to ActiveAdmin::ResourceController" do - ActiveAdmin::ResourceController.should_receive(:around_filter).and_return(true) - application.around_filter :my_filter, :only => :show - end - end - -end diff --git a/spec/unit/csv_builder_spec.rb b/spec/unit/csv_builder_spec.rb deleted file mode 100644 index 5a96478..0000000 --- a/spec/unit/csv_builder_spec.rb +++ /dev/null @@ -1,93 +0,0 @@ -require 'spec_helper' - -describe ActiveAdmin::CSVBuilder do - - describe '.default_for_resource using Post' do - let(:csv_builder) { ActiveAdmin::CSVBuilder.default_for_resource(Post) } - - it "should return a default csv_builder for Post" do - csv_builder.should be_a(ActiveAdmin::CSVBuilder) - end - - specify "the first column should be Id" do - csv_builder.columns.first.name.should == 'Id' - csv_builder.columns.first.data.should == :id - end - - specify "the following columns should be content_column" do - csv_builder.columns[1..-1].each_with_index do |column, index| - column.name.should == Post.content_columns[index].name.titleize - column.data.should == Post.content_columns[index].name.to_sym - end - end - end - - context 'when empty' do - let(:builder){ ActiveAdmin::CSVBuilder.new } - - it "should have no columns" do - builder.columns.should == [] - end - end - - context "with a symbol column (:title)" do - let(:builder) do - ActiveAdmin::CSVBuilder.new do - column :title - end - end - - it "should have one column" do - builder.columns.size.should == 1 - end - - describe "the column" do - let(:column){ builder.columns.first } - - it "should have a name of 'Title'" do - column.name.should == "Title" - end - - it "should have the data :title" do - column.data.should == :title - end - end - end - - context "with a block and title" do - let(:builder) do - ActiveAdmin::CSVBuilder.new do - column "My title" do - # nothing - end - end - end - - it "should have one column" do - builder.columns.size.should == 1 - end - - describe "the column" do - let(:column){ builder.columns.first } - - it "should have a name of 'My title'" do - column.name.should == "My title" - end - - it "should have the data :title" do - column.data.should be_an_instance_of(Proc) - end - end - end - - context "with a separator" do - let(:builder) do - ActiveAdmin::CSVBuilder.new :separator => ";" - end - - it "should have proper separator" do - builder.column_separator.should == ";" - end - end - -end diff --git a/spec/unit/dashboard_controller_spec.rb b/spec/unit/dashboard_controller_spec.rb deleted file mode 100644 index f413121..0000000 --- a/spec/unit/dashboard_controller_spec.rb +++ /dev/null @@ -1,76 +0,0 @@ -require 'spec_helper' - -require 'active_admin/dashboards/dashboard_controller' -require 'active_admin/dashboards/section' - -module Admin - class TestDashboardController < ActiveAdmin::PageController - include ActiveAdmin::Dashboards::DashboardController - end -end - -class TestDashboardController < ActiveAdmin::PageController - include ActiveAdmin::Dashboards::DashboardController -end - -describe ActiveAdmin::Dashboards::DashboardController do - - describe "getting the namespace name" do - subject{ controller.send :namespace } - - context "when admin namespace" do - let(:controller){ Admin::TestDashboardController.new } - it { should == :admin } - end - - context "when root namespace" do - let(:controller){ TestDashboardController.new } - it { should == :root } - end - end - - describe "conditionally displaying sections" do - before { ActiveAdmin::Dashboards.clear_all_sections! } - let(:controller){ Admin::TestDashboardController.new } - - context "when :if not specified" do - before do - @section = ActiveAdmin::Dashboards.add_section('Stats').last - end - - it "should include section" do - controller.send(:find_sections).should include(@section) - end - end - - context "when :if option specified as a method" do - before do - @section = ActiveAdmin::Dashboards.add_section('Secret Codes', :if => :i_am_awesome?).last - end - - it "should call the method of the same name" do - controller.should_receive(:i_am_awesome?).and_return(true) - controller.send(:find_sections).should include(@section) - - controller.should_receive(:i_am_awesome?).and_return(false) - controller.send(:find_sections).should_not include(@section) - end - end - - context "when :if option specified as block" do - before do - @proc = Proc.new { true } - @section = ActiveAdmin::Dashboards.add_section('Secret Codes', :if => proc {}).last - end - - it "should evaluate the block" do - controller.should_receive(:instance_exec).with(&@proc).and_return(true) - controller.send(:find_sections).should include(@section) - - controller.should_receive(:instance_exec).with(&@proc).and_return(false) - controller.send(:find_sections).should_not include(@section) - end - end - end - -end diff --git a/spec/unit/dashboard_section_spec.rb b/spec/unit/dashboard_section_spec.rb deleted file mode 100644 index d47e3e7..0000000 --- a/spec/unit/dashboard_section_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -require 'spec_helper' - -describe ActiveAdmin::Dashboards::Section do - - def section(options = {}) - name = options.delete(:name) || "Recent Posts" - ActiveAdmin::Dashboards::Section.new(:admin, name, options){ } - end - - describe "accessors" do - it "should have a namespace" do - section.namespace.should == :admin - end - - it "should have a block" do - section.block.class.should == Proc - end - - it "should have a name" do - section.name.should == 'Recent Posts' - end - end - - describe "priority" do - context "when not set" do - subject{ section.priority } - it { should == ActiveAdmin::Dashboards::Section::DEFAULT_PRIORITY } - end - - context "when set" do - subject{ section(:priority => 1).priority } - it { should == 1 } - end - end - - describe "icon" do - it "should set the icon" do - s = section(:icon => :my_icon) - s.icon.should == :my_icon - end - it "should be nil by default" do - section.icon.should be_nil - end - end - - describe "sorting sections" do - it "should sort by priority then alpha" do - s1 = section :name => "Woot" - s2 = section :name => :Alpha - s3 = section :name => "Zulu", :priority => 1 - s4 = section :name => "Beta", :priority => 100 - [s1,s2,s3,s4].sort.should == [s3, s2, s1, s4] - end - end - -end diff --git a/spec/unit/dashboards_spec.rb b/spec/unit/dashboards_spec.rb deleted file mode 100644 index cab693c..0000000 --- a/spec/unit/dashboards_spec.rb +++ /dev/null @@ -1,59 +0,0 @@ -require 'spec_helper' - -describe ActiveAdmin::Dashboards do - - after(:each) do - ActiveAdmin::Dashboards.clear_all_sections! - end - - describe "adding sections" do - before do - ActiveAdmin::Dashboards.clear_all_sections! - ActiveAdmin::Dashboards.add_section('Recent Posts') - end - it "should add a new section namespaced" do - ActiveAdmin::Dashboards.sections[:admin].first.should be_an_instance_of(ActiveAdmin::Dashboards::Section) - end - end - - describe "adding sections using the build syntax" do - before do - ActiveAdmin::Dashboards.clear_all_sections! - ActiveAdmin::Dashboards.build do - section "Recent Posts" do - end - end - end - - it "should add a new section" do - ActiveAdmin::Dashboards.sections[:admin].first.should be_an_instance_of(ActiveAdmin::Dashboards::Section) - end - end - - describe "clearing all sections" do - before do - ActiveAdmin::Dashboards.add_section('Recent Posts') - end - it "should clear all sections" do - ActiveAdmin::Dashboards.clear_all_sections! - ActiveAdmin::Dashboards.sections.keys.should be_empty - end - end - - describe "finding namespaced sections" do - context "when the namespace exists" do - before do - ActiveAdmin::Dashboards.add_section('Recent Posts') - end - it "should return an array of sections" do - ActiveAdmin::Dashboards.sections_for_namespace(:admin).should_not be_empty - end - end - - context "when the namespace does not exists" do - it "should return an empty array" do - ActiveAdmin::Dashboards.sections_for_namespace(:not_a_namespace).should be_empty - end - end - end -end diff --git a/spec/unit/devise_spec.rb b/spec/unit/devise_spec.rb deleted file mode 100644 index 3126469..0000000 --- a/spec/unit/devise_spec.rb +++ /dev/null @@ -1,66 +0,0 @@ -require 'spec_helper' - -describe ActiveAdmin::Devise::Controller do - - let(:controller_class) do - klass = Class.new do - def self.layout(*); end - def self.helper(*); end - end - klass.send(:include, ActiveAdmin::Devise::Controller) - klass - end - - let(:controller) { controller_class.new } - - it "should set the root path to the default namespace" do - controller.root_path.should == "/admin" - end - - it "should set the root path to '/' when no default namespace" do - ActiveAdmin.application.stub!(:default_namespace => false) - controller.root_path.should == "/" - end - - describe "#config" do - let(:config) { ActiveAdmin::Devise.config } - - describe ":sign_out_via option" do - - subject { config[:sign_out_via] } - - context "when Devise does not implement sign_out_via (version < 1.2)" do - before do - ::Devise.should_receive(:respond_to?).with(:sign_out_via).and_return(false) - end - - it "should not contain any customization for sign_out_via" do - config.should_not have_key(:sign_out_via) - end - end - - context "when Devise implements sign_out_via (version >= 1.2)" do - before do - ::Devise.should_receive(:respond_to?).with(:sign_out_via).and_return(true) - ::Devise.stub!(:sign_out_via) { :delete } - end - - it "should contain the application.logout_link_method" do - ::Devise.should_receive(:sign_out_via).and_return(:delete) - ActiveAdmin.application.should_receive(:logout_link_method).and_return(:get) - - config[:sign_out_via].should include(:get) - end - - it "should contain Devise's logout_via_method(s)" do - ::Devise.should_receive(:sign_out_via).and_return([:delete, :post]) - ActiveAdmin.application.should_receive(:logout_link_method).and_return(:get) - - config[:sign_out_via].should == [:delete, :post, :get] - end - end - - end # describe ":sign_out_via option" - end # describe "#config" - -end diff --git a/spec/unit/display_name_spec.rb b/spec/unit/display_name_spec.rb deleted file mode 100644 index 3a45518..0000000 --- a/spec/unit/display_name_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'spec_helper' - -describe "display names" do - - include ActiveAdmin::ViewHelpers - - [:display_name, :full_name, :name, :username, :login, :title, :email, :to_s].each do |m| - it "should return #{m} if defined" do - r = Class.new do - define_method m do - m.to_s - end - end.new - display_name(r).should == m.to_s - end - end - - it "should memeoize the result for the class" do - c = Class.new do - def name - "My Name" - end - end - display_name(c.new).should == "My Name" - ActiveAdmin.application.should_not_receive(:display_name_methods) - display_name(c.new).should == "My Name" - end - -end diff --git a/spec/unit/dsl_include_spec.rb b/spec/unit/dsl_include_spec.rb deleted file mode 100644 index bab3cca..0000000 --- a/spec/unit/dsl_include_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'spec_helper' - -module MockModuleToInclude - def self.included(dsl) - end -end - - -describe ActiveAdmin::DSL, "#include" do - - let(:dsl){ ActiveAdmin::DSL.new(mock) } - - it "should call the included class method on the module that is included" do - MockModuleToInclude.should_receive(:included).with(dsl) - dsl.run_registration_block do - include MockModuleToInclude - end - end - -end diff --git a/spec/unit/event_spec.rb b/spec/unit/event_spec.rb deleted file mode 100644 index 19339a1..0000000 --- a/spec/unit/event_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'spec_helper' -require 'active_admin/event' - -describe ActiveAdmin::EventDispatcher do - - let(:test_event){ 'active_admin.test_event' } - let(:dispatcher){ ActiveAdmin::EventDispatcher.new } - - it "should add a subscriber for an event" do - dispatcher.subscribers(test_event).size.should == 0 - dispatcher.subscribe(test_event){ true } - dispatcher.subscribers(test_event).size.should == 1 - end - - it "should add a subscriber for multiple events" do - dispatcher.subscribe(test_event, test_event + "1"){ true } - dispatcher.subscribers(test_event).size.should == 1 - dispatcher.subscribers(test_event + "1").size.should == 1 - end - - it "should call the dispatch block with no arguments" do - dispatcher.subscribe(test_event){ raise StandardError, "From Event Handler" } - lambda { - dispatcher.dispatch(test_event) - }.should raise_error(StandardError, "From Event Handler") - end - - it "should call the dispatch block with one argument" do - arg = nil - dispatcher.subscribe(test_event){|passed_in| arg = passed_in } - dispatcher.dispatch(test_event, "My Arg") - arg.should == "My Arg" - end - - it "should clear all subscribers" do - dispatcher.subscribe(test_event){ false } - dispatcher.subscribe(test_event + "_2"){ false } - dispatcher.clear_all_subscribers! - dispatcher.subscribers(test_event).size.should == 0 - dispatcher.subscribers(test_event + "_2").size.should == 0 - end - - it "should have a dispatcher available from ActiveAdmin::Event" do - ActiveAdmin::Event.should be_an_instance_of(ActiveAdmin::EventDispatcher) - end - -end diff --git a/spec/unit/filters/filter_form_builder_spec.rb b/spec/unit/filters/filter_form_builder_spec.rb deleted file mode 100644 index 9a984c5..0000000 --- a/spec/unit/filters/filter_form_builder_spec.rb +++ /dev/null @@ -1,203 +0,0 @@ -require 'spec_helper' - - -describe ActiveAdmin::Filters::ViewHelper do - - # Setup an ActionView::Base object which can be used for - # generating the form for. - let(:helpers) do - view = action_view - def view.collection_path - "/posts" - end - - def view.protect_against_forgery? - false - end - - def view.a_helper_method - "A Helper Method" - end - - view - end - - def render_filter(search, name, options = {}) - render_arbre_component({:filter_args => [search, [options.merge(:attribute => name)]]}, helpers) do - text_node active_admin_filters_form_for(*assigns[:filter_args]) - end - end - - def filter(name, options = {}) - render_filter Post.search, name, options - end - - describe "the form in general" do - let(:body) { filter :title } - - it "should generate a form which submits via get" do - body.should have_tag("form", :attributes => { :method => 'get', :class => 'filter_form' }) - end - - it "should generate a filter button" do - body.should have_tag("input", :attributes => { :type => "submit", - :value => "Filter" }) - end - - it "should only generate the form once" do - body.to_s.scan(/q\[title_contains\]/).size.should == 1 - end - - it "should generate a clear filters link" do - body.should have_tag("a", "Clear Filters", :attributes => { :class => "clear_filters_btn" }) - end - end - - describe "string attribute" do - let(:body) { filter :title } - - it "should generate a search field for a string attribute" do - body.should have_tag("input", :attributes => { :name => "q[title_contains]"}) - end - - it "should label a text field with search" do - body.should have_tag('label', 'Search Title') - end - - it "should translate the label for text field" do - begin - I18n.backend.store_translations(:en, :activerecord => { :attributes => { :post => { :title => "Name" } } }) - body.should have_tag('label', 'Search Name') - ensure - I18n.backend.reload! - end - end - end - - describe "text attribute" do - let(:body) { filter :body } - - it "should generate a search field for a text attribute" do - body.should have_tag("input", :attributes => { :name => "q[body_contains]"}) - end - - it "should label a text field with search" do - body.should have_tag('label', 'Search Body') - end - end - - describe "datetime attribute" do - let(:body) { filter :created_at } - - it "should generate a date greater than" do - body.should have_tag("input", :attributes => { :name => "q[created_at_gte]", :class => "datepicker"}) - end - it "should generate a seperator" do - body.should have_tag("span", :attributes => { :class => "seperator"}) - end - it "should generate a date less than" do - body.should have_tag("input", :attributes => { :name => "q[created_at_lte]", :class => "datepicker"}) - end - end - - describe "integer attribute" do - let(:body) { filter :id } - - it "should generate a select option for equal to" do - body.should have_tag("option", "Equal To", :attributes => { :value => 'id_eq' }) - end - it "should generate a select option for greater than" do - body.should have_tag("option", "Greater Than") - end - it "should generate a select option for less than" do - body.should have_tag("option", "Less Than") - end - it "should generate a text field for input" do - body.should have_tag("input", :attributes => { - :name => /q\[(id_eq|id_equals)\]/ }) - end - it "should select the option which is currently being filtered" - end - - describe "belong to" do - before do - @john = User.create :first_name => "John", :last_name => "Doe", :username => "john_doe" - @jane = User.create :first_name => "Jane", :last_name => "Doe", :username => "jane_doe" - end - - context "when given as the _id attribute name" do - let(:body) { filter :author_id } - - it "should not render as an integer" do - body.should_not have_tag("input", :attributes => { - :name => "q[author_id_eq]"}) - end - it "should render as belongs to select" do - body.should have_tag("select", :attributes => { - :name => "q[author_id_eq]"}) - body.should have_tag("option", "jane_doe", :attributes => { - :value => @jane.id }) - end - end - - context "when given as the name of the relationship" do - let(:body) { filter :author } - - it "should generate a select" do - body.should have_tag("select", :attributes => { - :name => "q[author_id_eq]"}) - end - it "should set the default text to 'Any'" do - body.should have_tag("option", "Any", :attributes => { - :value => "" }) - end - it "should create an option for each related object" do - body.should have_tag("option", "john_doe", :attributes => { - :value => @john.id }) - body.should have_tag("option", "jane_doe", :attributes => { - :value => @jane.id }) - end - - context "with a proc" do - let :body do - filter :title, :as => :select, :collection => proc{ ['Title One', 'Title Two'] } - end - - it "should use call the proc as the collection" do - body.should have_tag("option", "Title One") - body.should have_tag("option", "Title Two") - end - - it "should render the collection in the context of the view" do - body = filter(:title, :as => :select, :collection => proc{[a_helper_method]}) - body.should have_tag("option", "A Helper Method") - end - end - end - - context "as check boxes" do - let(:body) { filter :author, :as => :check_boxes } - - it "should create a check box for each related object" do - body.should have_tag("input", :attributes => { - :name => "q[author_id_in][]", - :type => "checkbox", - :value => @john.id }) - body.should have_tag("input", :attributes => { - :name => "q[author_id_in][]", - :type => "checkbox", - :value => @jane.id }) - end - end - - context "when polymorphic relationship" do - let(:body) do - search = ActiveAdmin::Comment.search - render_filter(search, :resource) - end - it "should not generate any field" do - body.should have_tag("form", :attributes => { :method => 'get' }) - end - end - end # belongs to -end diff --git a/spec/unit/filters/resource_spec.rb b/spec/unit/filters/resource_spec.rb deleted file mode 100644 index 032f2af..0000000 --- a/spec/unit/filters/resource_spec.rb +++ /dev/null @@ -1,60 +0,0 @@ -require 'spec_helper' - -describe ActiveAdmin::Filters::ResourceExtension do - - let(:resource) do - namespace = ActiveAdmin::Namespace.new(ActiveAdmin::Application.new, :admin) - namespace.register(Post) - end - - it "should return the defaults if no filters are set" do - resource.filters.map{|f| f[:attribute].to_s }.sort.should == %w{ - author body category created_at published_at title updated_at - } - end - - it "should not have defaults when filters are disabled on the resource" do - resource.filters = false - resource.filters.should be_empty - end - - it "should not have defaults when the filters are disabled on the namespace" do - resource.namespace.filters = false - resource.filters.should be_empty - end - - it "should not have defaults when the filters are disabled on the application" do - resource.namespace.application.filters = false - resource.filters.should be_empty - end - - it "should add a filter" do - resource.add_filter :title - resource.filters.should == [{:attribute => :title}] - end - - it "should add a filter with options" do - resource.add_filter :title, :as => :string - resource.filters.should == [{:attribute => :title, :as => :string}] - end - - it "should raise an exception if trying to add a filter when they are disabled" do - resource.filters = false - expect { - resource.add_filter :title - }.should raise_error(RuntimeError) - end - - it "should reset filters" do - resource.add_filter :title - resource.filters.size.should == 1 - resource.reset_filters! - resource.filters.size.should > 1 - end - - it "should add a sidebar section for the filters" do - resource.sidebar_sections.first.name.should == :filters - end - - -end diff --git a/spec/unit/form_builder_spec.rb b/spec/unit/form_builder_spec.rb deleted file mode 100644 index 08f4592..0000000 --- a/spec/unit/form_builder_spec.rb +++ /dev/null @@ -1,407 +0,0 @@ -require 'spec_helper' - -describe ActiveAdmin::FormBuilder do - - # Setup an ActionView::Base object which can be used for - # generating the form for. - let(:helpers) do - view = action_view - def view.posts_path - "/posts" - end - - def view.protect_against_forgery? - false - end - - def view.url_for(*args) - if args.first == {:action => "index"} - posts_path - else - super - end - end - - def view.a_helper_method - "A Helper Method" - end - - view - end - - def build_form(options = {}, form_object = Post.new, &block) - options = {:url => helpers.posts_path}.merge(options) - - render_arbre_component({:form_object => form_object, :form_options => options, :form_block => block}, helpers)do - text_node active_admin_form_for(assigns[:form_object], assigns[:form_options], &assigns[:form_block]) - end.to_s - end - - context "in general with actions" do - let :body do - build_form do |f| - f.inputs do - f.input :title - f.input :body - end - f.actions do - f.action :submit, :label => "Submit Me" - f.action :submit, :label => "Another Button" - end - end - end - - it "should generate a text input" do - body.should have_tag("input", :attributes => { :type => "text", - :name => "post[title]" }) - end - it "should generate a textarea" do - body.should have_tag("textarea", :attributes => { :name => "post[body]" }) - end - it "should only generate the form once" do - body.scan(/Title/).size.should == 1 - end - it "should generate actions" do - body.should have_tag("input", :attributes => { :type => "submit", - :value => "Submit Me" }) - body.should have_tag("input", :attributes => { :type => "submit", - :value => "Another Button" }) - end - end - - context "in general with actions" do - let :body do - build_form do |f| - f.inputs do - f.input :title - f.input :body - end - f.actions do - f.action :submit, :button_html => { :value => "Submit Me" } - f.action :submit, :button_html => { :value => "Another Button" } - end - end - end - - it "should generate a text input" do - body.should have_tag("input", :attributes => { :type => "text", - :name => "post[title]" }) - end - it "should generate a textarea" do - body.should have_tag("textarea", :attributes => { :name => "post[body]" }) - end - it "should only generate the form once" do - body.scan(/Title/).size.should == 1 - end - it "should generate actions" do - body.should have_tag("input", :attributes => { :type => "submit", - :value => "Submit Me" }) - body.should have_tag("input", :attributes => { :type => "submit", - :value => "Another Button" }) - end - end - - context "when polymorphic relationship" do - it "should raise error" do - lambda { - comment = ActiveAdmin::Comment.new - build_form({:url => "admins/comments"}, comment) do |f| - f.inputs :resource - end - }.should raise_error(Formtastic::PolymorphicInputWithoutCollectionError) - end - end - - describe "passing in options with actions" do - let :body do - build_form :html => { :multipart => true } do |f| - f.inputs :title - f.actions - end - end - it "should pass the options on to the form" do - body.should have_tag("form", :attributes => { :enctype => "multipart/form-data" }) - end - end - - describe "passing in options with actions" do - let :body do - build_form :html => { :multipart => true } do |f| - f.inputs :title - f.actions - end - end - it "should pass the options on to the form" do - body.should have_tag("form", :attributes => { :enctype => "multipart/form-data" }) - end - end - - - context "with actions" do - it "should generate the form once" do - body = build_form do |f| - f.inputs do - f.input :title - end - f.actions - end - body.scan(/id=\"post_title\"/).size.should == 1 - end - it "should generate one button and a cancel link" do - body = build_form do |f| - f.actions - end - body.scan(/type=\"submit\"/).size.should == 1 - body.scan(/class=\"cancel\"/).size.should == 1 - end - it "should generate multiple actions" do - body = build_form do |f| - f.actions do - f.action :submit, :label => "Create & Continue" - f.action :submit, :label => "Create & Edit" - end - end - body.scan(/type=\"submit\"/).size.should == 2 - body.scan(/class=\"cancel\"/).size.should == 0 - end - - end - - context "with actons" do - it "should generate the form once" do - body = build_form do |f| - f.inputs do - f.input :title - end - f.actions - end - body.scan(/id=\"post_title\"/).size.should == 1 - end - it "should generate one button and a cancel link" do - body = build_form do |f| - f.actions - end - body.scan(/type=\"submit\"/).size.should == 1 - body.scan(/class=\"cancel\"/).size.should == 1 - end - it "should generate multiple actions" do - body = build_form do |f| - f.actions do - f.action :submit, :label => "Create & Continue" - f.action :submit, :label => "Create & Edit" - end - end - body.scan(/type=\"submit\"/).size.should == 2 - body.scan(/class=\"cancel\"/).size.should == 0 - end - end - - context "without passing a block to inputs" do - let :body do - build_form do |f| - f.inputs :title, :body - end - end - it "should have a title input" do - body.should have_tag("input", :attributes => { :type => "text", - :name => "post[title]" }) - end - it "should have a body textarea" do - body.should have_tag("textarea", :attributes => { :name => "post[body]" }) - end - end - - context "with semantic fields for" do - let :body do - build_form do |f| - f.inputs do - f.input :title - f.input :body - end - f.instance_eval do - @object.author = User.new - end - f.semantic_fields_for :author do |author| - author.inputs :first_name, :last_name - end - end - end - it "should generate a nested text input once" do - body.scan("post_author_attributes_first_name_input").size.should == 1 - end - end - - context "with collection inputs" do - before do - User.create :first_name => "John", :last_name => "Doe" - User.create :first_name => "Jane", :last_name => "Doe" - end - - describe "as select" do - let :body do - build_form do |f| - f.input :author - end - end - it "should create 2 options" do - body.scan(/\