Generative Testing

It’s no secret that I’ve been interested in testing. Most of the work I’ve done are around example-based testing. While useful, it’s interesting to look at other communities for inspiration. I’m specifically fascinated in the functional programming community. Generative testing in particular. It was popularized in the early 2000s by a famous implementation in Haskell, QuickCheck. In short, generative testing is allows you specify properties your software should have. Then the testing library generates test cases. It’s an alternative path the functional community has taken when it comes to testing. This becomes evident since testing functional code becomes mostly boilerplate management: ...

January 31, 2015 · 3 min

Parsing JSON in Objective-C - Part 2

Note: This previously was on Pivotal Labs blog. In the previous article, we used TDD to parse JSON into our Person model and refactored the code under test. In part 2, we’re going to refactor the code further to be more reusable and extendable. All the code in this article will also be in the same repository. Redesign The refactorings in the previous article were fairly straightforward and mechanical. Ultimately, we’ll need to break apart different concerns of this code. One approach would be to start with some questions: ...

November 8, 2014 · 9 min

Parsing JSON in Objective-C - Part 1

This post was original written on the Pivotal Labs Blog. JSON parsing is a frequent task for clients interfacing with any recent web API. Those web services frequently vary in quality: Is the API following a RESTful design pattern? Is it providing an object graph or just a single/collection of objects in the JSON response? What are the data types of the fields being returned? Can they be relied upon? How much work are clients duplicating to work around the server (e.g. - Performance, Business Logic, etc.)? If you have full control of the resulting API endpoints, then it is easy to build or fix the API to your client’s specific needs. Controlling the incidental complexity can be challenging for APIs you do not control, or which have to support a variety of clients. ...

October 24, 2014 · 9 min

Reverse Engineering Objective-C

Languages that have dynamic introspection provide powerful meta-programming capabilities. This is generally done at runtime with additional memory used for storing metadata - such as types and method signatures. But they also provide the same power for people reverse engineering your code. Let’s look at Objective-C, a simple code snippet: @interface MyObject : NSObject @end @implementation MyObject { NSInteger _number; } - (void)doSomething { _number++; NSLog(@"The %@", [self _doSomethingSpecial:_number]); } - (NSString *)_doSomethingSpecial:(NSInteger)number { return [NSString stringWithFormat:@"Number: %d", number]; } @end Simple enough, but what if we don’t have the source? Let’s step back to how Objective-C works… ...

July 26, 2014 · 4 min

Adapting Binary Search

It’s great to use classic algorithms to solve problems at hand. Take this problem of ellipsis: For a given text. Fit the maximum number of words that fits in the given size, append “… More” if there was truncation. No, NSLineBreakModeTailTruncation will not work. We need different text. The näive solution would simply to cut a word one-by-one until it fits with a custom ellipsis text: @implementation NSString (CustomEllipsis) - (NSString *)textThatFitsSize:(CGSize)size ellipsisText:(NSString *)text { CGSize infiniteSize = CGSizeMake(size.width, INFINITY); CGSize fullSize = [text boundingRectWithSize:infiniteSize options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin context:nil].size; // if text fits if (fullSize.height <= size.height) { return text; } NSString *finalString = nil; // if text doesn't fit NSMutableArray *words = [[text componentsSeparatedByString:@" "] mutableCopy]; while (fullSize.height > size.height) { [words removeLastObject]; finalString = [words componentsJoinByString:@" "]; finalString = [finalString stringByAppendString:@"... MORE"]; fullSize = [modifiedString boundingRectWithSize:infiniteSize options:NSStringDrawingUsesFontLeading|NSStringDrawingUsesLineFragmentOrigin context:nil].size; } return finalString; } @end Run that in a table cell and you’ve got performance problems! ...

July 25, 2014 · 2 min

Objective-C: Lazy Sequences

Lazy data structures are a powerful abstraction can increase the readability of your program while encouraging separation of concerns. What are they? Simply put, they are data structures that “realize” what they contain when they’re needed (or right before they’re needed). What can you do with lazy data structures? How about a page-scraper that paginates as needed: # pseudocode seed_url = "http://example.com/page/" # generate a lazy list of urls: # - http://example.com/page/1 # - http://example.com/page/2 # - etc. urls = lazy { for (i = 0; i < 100; i++) { yield seed_url + string(i) } } # a lazy list of html pages pages = map(urls, fetchURLPageContents) # a lazy list of list of links links_per_page = map(pages, extractLinksFromHTML) # flatten to just a lazy list of links links = join(links_per_page) # do stuff with links for link in links { record(link) } This creates a powerful abstract that separate tasks your program needs to get done behind an implicit interface. The ending for loop doesn’t need to know that those links came from multiple page fetches or the file system. If the loop short-circuited, then it minimizes the number of unnecessary fetches. ...

July 7, 2014 · 4 min