I've talked in the past about testing with JSTalk, and in that post I had a little snippet of code that looked like this:
PXWithUndo(doc, function() { [[win canvas] placeBezierRectOnMask:NSMakeRect(0, 50, 30, 30)]; }); PXWithUndo(doc, function() { // do something else that's undoable });
The idea being that I call multiple operations in quick succession (from JSTalk) and then test each of those undos and make sure the state is exactly what it should be. I recently came across an instance where I needed to do the same thing in Objective-C code, so I thought I'd share with my fair readers the solution I came up with (experienced Obj-C coders will probably know right away what the solution is).
This is what I want my test code to look like:
[[self document] withUndo:^{ [self placeBezierRectOnMask:NSMakeRect(0, 50, 30, 30)]; }]; [[self document] withUndo:^{ // do something else that's undoable, etc. }];
So to make this method a reality, I'm going to open up my document's header file and add a typedef at the top above my @interface:
typedef void (^TSWithUndoBlock)();
Next up, add the prototype to our document interface:
- (void)withUndo:(TSWithUndoBlock)block;
And then finally, in our document implementation:
- (void)withUndo:(TSWithUndoBlock)block { [[self undoManager] setGroupsByEvent:NO]; [[self undoManager] beginUndoGrouping]; block(); [[self undoManager] endUndoGrouping]; [[self undoManager] setGroupsByEvent:YES]; }
Tada. Simple, easy, and great for testing multiple undo operations.
Postscript: TS stands for "TinySketch". Post postscript: TinySketch was the original name for FlySketch. Moar postscript: FlySketch 2.0 turned into Acorn 1.0 because the FS upgrade got a bit out of hand. And to make a long postscript short, that's why Acorn's classes use the prefix TS.