diff --git a/public/javascripts/aspect-edit.js b/public/javascripts/aspect-edit.js index 8346bb7dd9fc9a0019384674798df43d30884447..17c0c673da083eb69c92dc990d1229ee36b986f8 100644 --- a/public/javascripts/aspect-edit.js +++ b/public/javascripts/aspect-edit.js @@ -27,11 +27,15 @@ var AspectEdit = { $(".aspect h3").live('focus', AspectEdit.changeName); }, - startDrag: function(event, ui) { - $(this).children("img").animate({'height':80, 'width':80, 'opacity':0.8}, 200) - .tipsy("hide"); + startDrag: function() { + AspectEdit.animateImage($(this).children("img").first()); $(".draggable_info").fadeIn(100); }, + + animateImage: function(image) { + image.animate({'height':80, 'width':80, 'opacity':0.8}, 200); + image.tipsy("hide"); + }, duringDrag: function(event, ui) { $(this).children("img").tipsy("hide"); //ensure this is hidden diff --git a/spec/javascripts/aspect-edit-spec.js b/spec/javascripts/aspect-edit-spec.js index 9c2da462166a9558158b92643e8d999b86fd6e1b..e71f2dbf24af4ce1b8c4ea68dde2109cfdb2b9da 100644 --- a/spec/javascripts/aspect-edit-spec.js +++ b/spec/javascripts/aspect-edit-spec.js @@ -1,8 +1,38 @@ describe("AspectEdit", function() { -// describe("initialize", function() { -// -// }); + describe("initialize", function() { + it("calls draggable on ul .person", function() { + spyOn($.fn, "draggable"); + AspectEdit.initialize(); + expect($.fn.draggable).toHaveBeenCalledWith( + {revert: true, start: AspectEdit.startDrag, + drag: AspectEdit.duringDrag, stop: AspectEdit.stopDrag}); + expect($.fn.draggable.mostRecentCall.object.selector).toEqual("ul .person"); + }); + it("calls droppable on .aspect ul.dropzone", function() { + spyOn($.fn, "droppable"); + AspectEdit.initialize(); + expect($.fn.droppable).toHaveBeenCalledWith({hoverClass: 'active', drop: AspectEdit.onDropMove}); + expect($.fn.droppable.calls[0].object.selector).toEqual(".aspect ul.dropzone"); +// This would be AWESOME: +// expect($.fn.droppable) +// .toHaveBeenCalled() +// .on(".aspect ul.dropzone") +// .with({}); + }); + }); + + describe("startDrag", function() { + it("animates the image", function() { + $('#jasmine_content').html('<ul><li class="person ui-draggable" data-aspect_id="4cae42e12367bca44e000005" data-guid="4cae42d32367bca44e000003" style="top: 0px; left: 0px; ">' + + '<img alt="Alexander Hamiltom" class="avatar" data-person_id="4cae42d32367bca44e000003" src="/images/user/default.png?1287542906" original-title="Alexander Hamiltom" style="height: 70px; width: 70px; opacity: 1; display: inline; ">' + + '</li></ul>'); + spyOn(AspectEdit, "animateImage"); + $.proxy(AspectEdit.startDrag, $('.person.ui-draggable'))(); + expect(AspectEdit.animateImage).toHaveBeenCalled(); + expect(AspectEdit.animateImage.mostRecentCall.args[0]).toHaveClass("avatar"); + }); + }); describe("decrementRequestsCounter", function() { describe("when there is one request", function() { diff --git a/spec/javascripts/helpers/jasmine-jquery.js b/spec/javascripts/helpers/jasmine-jquery.js new file mode 100644 index 0000000000000000000000000000000000000000..0096c4fc53690e497291ffdb65d6f9d84393c181 --- /dev/null +++ b/spec/javascripts/helpers/jasmine-jquery.js @@ -0,0 +1,203 @@ +var readFixtures = function() { + return jasmine.getFixtures().proxyCallTo_('read', 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); +}; + +jasmine.getFixtures = function() { + return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures(); +}; + +jasmine.Fixtures = function() { + this.containerId = 'jasmine-fixtures'; + this.fixturesCache_ = {}; +}; + +jasmine.Fixtures.prototype.set = function(html) { + this.cleanUp(); + this.createContainer_(html); +}; + +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() { + $('#' + this.containerId).remove(); +}; + +jasmine.Fixtures.prototype.sandbox = function(attributes) { + var attributesToSet = attributes || {}; + return $('<div id="sandbox" />').attr(attributesToSet); +}; + +jasmine.Fixtures.prototype.createContainer_ = function(html) { + var container = $('<div id="' + this.containerId + '" />'); + container.html(html); + $('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(url) { + var self = this; + $.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_[url] = data; + } + }); +}; + +jasmine.Fixtures.prototype.proxyCallTo_ = function(methodName, passedArguments) { + return this[methodName].apply(this, passedArguments); +}; + + +jasmine.JQuery = function() {}; + +jasmine.JQuery.browserTagCaseIndependentHtml = function(html) { + return $('<div/>').append(html).html(); +}; + +jasmine.JQuery.elementToString = function(element) { + return $('<div />').append(element.clone()).html(); +}; + +jasmine.JQuery.matchersClass = {}; + + +(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) { + 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; + } + }; + + 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); +}); + +afterEach(function() { + jasmine.getFixtures().cleanUp(); +}); \ No newline at end of file