Methods to generate jasmine fixtures in controller specs, and methods to load those fixtures in jasmine specs.
This commit is contained in:
parent
9c50f900ed
commit
a1ea193fb9
2 changed files with 119 additions and 0 deletions
|
|
@ -8,3 +8,79 @@
|
|||
// }
|
||||
// })
|
||||
//});
|
||||
|
||||
beforeEach(function() {
|
||||
$('#jasmine_content').empty();
|
||||
spec.clearLiveEventBindings();
|
||||
jasmine.Clock.useMock();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
spec.clearLiveEventBindings();
|
||||
expect(spec.loadFixtureCount).toBeLessThan(2);
|
||||
spec.loadFixtureCount = 0;
|
||||
});
|
||||
|
||||
var context = describe;
|
||||
var spec = {};
|
||||
|
||||
spec.clearLiveEventBindings = function() {
|
||||
var events = jQuery.data(document, "events");
|
||||
for (prop in events) {
|
||||
delete events[prop];
|
||||
}
|
||||
};
|
||||
|
||||
spec.content = function() {
|
||||
return $('#jasmine_content');
|
||||
};
|
||||
|
||||
// Loads fixure markup into the DOM as a child of the jasmine_content div
|
||||
spec.loadFixture = function(fixtureName) {
|
||||
var $destination = $('#jasmine_content');
|
||||
|
||||
// get the markup, inject it into the dom
|
||||
$destination.html(spec.fixtureHtml(fixtureName));
|
||||
|
||||
// keep track of fixture count to fail specs that
|
||||
// call loadFixture() more than once
|
||||
spec.loadFixtureCount++;
|
||||
};
|
||||
|
||||
// Returns fixture markup as a string. Useful for fixtures that
|
||||
// represent the response text of ajax requests.
|
||||
spec.readFixture = function(fixtureName) {
|
||||
return spec.fixtureHtml(fixtureName);
|
||||
};
|
||||
|
||||
spec.fixtureHtml = function(fixtureName) {
|
||||
if (!spec.cachedFixtures[fixtureName]) {
|
||||
spec.cachedFixtures[fixtureName] = spec.retrieveFixture(fixtureName);
|
||||
}
|
||||
return spec.cachedFixtures[fixtureName];
|
||||
};
|
||||
|
||||
spec.retrieveFixture = function(fixtureName) {
|
||||
|
||||
// construct a path to the fixture, including a cache-busting timestamp
|
||||
var path = '/tmp/js_dom_fixtures/' + fixtureName + ".fixture.html?" + new Date().getTime();
|
||||
var xhr;
|
||||
|
||||
// retrieve the fixture markup via xhr request to jasmine server
|
||||
try {
|
||||
xhr = new jasmine.XmlHttpRequest();
|
||||
xhr.open("GET", path, false);
|
||||
xhr.send(null);
|
||||
} catch(e) {
|
||||
throw new Error("couldn't fetch " + path + ": " + e);
|
||||
}
|
||||
var regExp = new RegExp(/Couldn\\\'t load \/fixture/);
|
||||
if (regExp.test(xhr.responseText)) {
|
||||
throw new Error("Couldn't load fixture with key: '" + fixtureName + "'. No such file: '" + path + "'.");
|
||||
}
|
||||
|
||||
return xhr.responseText;
|
||||
};
|
||||
|
||||
spec.loadFixtureCount = 0;
|
||||
spec.cachedFixtures = {};
|
||||
43
spec/support/fixture_generation.rb
Normal file
43
spec/support/fixture_generation.rb
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
Rspec::Rails::ControllerExampleGroup.class_eval do
|
||||
|
||||
# Saves the markup to a fixture file using the given name
|
||||
def save_fixture(markup, name)
|
||||
fixture_path = File.join(Rails.root, 'tmp', 'js_dom_fixtures')
|
||||
Dir.mkdir(fixture_path) unless File.exists?(fixture_path)
|
||||
|
||||
fixture_file = File.join(fixture_path, "#{name}.fixture.html")
|
||||
File.open(fixture_file, 'w') do |file|
|
||||
file.puts(markup)
|
||||
end
|
||||
end
|
||||
|
||||
# From the controller spec response body, extracts html identified
|
||||
# by the css selector.
|
||||
def html_for(selector)
|
||||
doc = Nokogiri::HTML(response.body)
|
||||
|
||||
remove_third_party_scripts(doc)
|
||||
content = doc.css(selector).first.to_s
|
||||
|
||||
return convert_body_tag_to_div(content)
|
||||
end
|
||||
|
||||
# Remove scripts such as Google Analytics to avoid running them
|
||||
# when we load into the dom during js specs.
|
||||
def remove_third_party_scripts(doc)
|
||||
scripts = doc.at('#third-party-scripts')
|
||||
scripts.remove if scripts
|
||||
end
|
||||
|
||||
# Many of our css and jQuery selectors rely on a class attribute we
|
||||
# normally embed in the <body>. For example:
|
||||
#
|
||||
# <body class="workspaces show">
|
||||
#
|
||||
# Here we convert the body tag to a div so that we can load it into
|
||||
# the document running js specs without embedding a <body> within a <body>.
|
||||
def convert_body_tag_to_div(markup)
|
||||
return markup.gsub("<body", '<div').gsub("</body>", "</div>")
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
Reference in a new issue