Ensure PathWatcher isn't watching anything at the end of each spec

This replaces the old functionality of ensuring no files or directories have subscriptions in javascript. We allow this now, but we just don't allow leaked watches at the native layer.
This commit is contained in:
Corey Johnson & Nathan Sobo
2012-11-28 17:16:15 -07:00
parent ac84a8ab0a
commit db78d6a7e5
5 changed files with 28 additions and 19 deletions

View File

@@ -19,5 +19,6 @@ typedef void (^WatchCallback)(NSString *, NSString *);
- (id)initWithContext:(CefRefPtr<CefV8Context>)context;
- (NSString *)watchPath:(NSString *)path callback:(WatchCallback)callback;
- (void)unwatchPath:(NSString *)path callbackId:(NSString *)callbackId error:(NSError **)error;
- (NSArray *)watchedPaths;
@end

View File

@@ -144,6 +144,10 @@ static NSMutableArray *gPathWatchers;
}
}
- (NSArray *)watchedPaths {
return [_callbacksByPath allKeys];
}
- (bool)createKeventForPath:(NSString *)path {
path = [path stringByStandardizingPath];

View File

@@ -43,6 +43,9 @@ var $native = {};
native function unwatchPath(path, callbackId);
$native.unwatchPath = unwatchPath;
native function getWatchedPaths();
$native.getWatchedPaths = getWatchedPaths;
native function makeDirectory(path);
$native.makeDirectory = makeDirectory;

View File

@@ -237,6 +237,21 @@ bool Native::Execute(const CefString& name,
return true;
}
else if (name == "getWatchedPaths") {
PathWatcher *pathWatcher = [PathWatcher pathWatcherForContext:CefV8Context::GetCurrentContext()];
NSArray *paths = [pathWatcher watchedPaths];
CefRefPtr<CefV8Value> pathsArray = CefV8Value::CreateArray([paths count]);
for (int i = 0; i < [paths count]; i++) {
CefRefPtr<CefV8Value> path = CefV8Value::CreateString([[paths objectAtIndex:i] UTF8String]);
pathsArray->SetValue(i, path);
}
retval = pathsArray;
return true;
}
else if (name == "makeDirectory") {
NSString *path = stringFromCefV8Value(arguments[0]);
NSFileManager *fm = [NSFileManager defaultManager];

View File

@@ -16,13 +16,11 @@ require 'window'
requireStylesheet "jasmine.css"
pathsWithSubscriptions = null
jasmine.DEFAULT_TIMEOUT_INTERVAL = 200
beforeEach ->
window.fixturesProject = new Project(require.resolve('fixtures'))
window.resetTimeouts()
pathsWithSubscriptions = []
# make editor display updates synchronous
spyOn(Editor.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
@@ -39,10 +37,8 @@ afterEach ->
delete window.rootView if window.rootView
$('#jasmine-content').empty()
window.fixturesProject.destroy()
waits(0)
runs ->
# ensureNoPathSubscriptions()
ensureNoPathSubscriptions()
waits(0) # yield to ui thread to make screen update more frequently
window.keymap.bindKeys '*', 'meta-w': 'close'
$(document).on 'close', -> window.close()
@@ -51,20 +47,10 @@ $('html,body').css('overflow', 'auto')
# Don't load user configuration in specs, because it's variable
RootView.prototype.loadUserConfiguration = ->
for klass in [Directory, File]
klass.prototype.originalOn = klass.prototype.on
klass.prototype.on = (args...) ->
pathsWithSubscriptions.push(this) if @subscriptionCount() == 0
@originalOn(args...)
ensureNoPathSubscriptions = ->
totalSubscriptionCount = 0
for path in pathsWithSubscriptions
totalSubscriptionCount += path.subscriptionCount()
console.log "Non-zero subscription count on", path if path.subscriptionCount() > 0
if totalSubscriptionCount > 0
throw new Error("Total path subscription count was #{totalSubscriptionCount}, when it should have been 0.\nSee console for details.")
watchedPaths = $native.getWatchedPaths()
if watchedPaths.length > 0
throw new Error("Leaking subscriptions for paths: " + watchedPaths.join(", "))
# Use underscore's definition of equality for toEqual assertions
jasmine.Env.prototype.equals_ = _.isEqual