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. |