/dev/trouble
Eric Roller's blog

Saturday, January 31, 2015

XCTest: Place Error Markers in Another File

I have a XCTestCase scenario using the following methodology:

- (void)testScript {
    NSError* error = nil;
    for (NSURL *scriptURL in [self findScriptFiles]) {

        // Read the entire file.
        NSString *text = [NSString stringWithContentsOfURL:scriptURL
                encoding:NSUTF8StringEncoding error:&error];

        // Test each line.
        [text enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {

            XCTAssertTrue([self runInstruction:line]);
        }];
    }
}

This works, but I don’t like it that all error messages are placed in the testScript source code, whereas they should really be placed inline in the parsed script.

I did a bit of digging in the XCTestCase framework headers and found the solution, using recordFailureWithDescription:inFile:atLine:expected:

- (void)testScript {
    NSError* error = nil;
    for (NSURL *scriptURL in [self findScriptFiles]) {

        // Read the entire file.
        NSString *text = [NSString stringWithContentsOfURL:scriptURL
                encoding:NSUTF8StringEncoding error:&error];
        __block NSUInteger lineNum = 0;

        // Test each line.
        [text enumerateLinesUsingBlock:^(NSString *line, BOOL *stop) {

            lineNum++;

            if ([self runInstruction:line] == NO) {
                // Place the error marker in the parsed file!
                [self recordFailureWithDescription:@"Instruction failed"
                        inFile:[self sourcePathForURL:scriptURL]
                        atLine:lineNum
                        expected:YES];
            }
        }];
    }
}

NB. The scriptURL points to a file within the resources folder of the test target, i.e. not to the original script file in my Xcode project. I therefore need to locate the original script file, for instance relative to the current source file (whose name can be obtained through the __FILE__ preprocessor macro).

Sunday, January 25, 2015

Automator Workflow to Scale iOS App Icons

For iOS development, it is necessary to provide a set of app icons of different sizes, all the way from a high-resolution icon for the AppStore to a tiny icon that will be used in Spotlight search results. The trouble is, how to create the icons, again, and again,…

Well, here’s how… [Read More…]

Thursday, December 25, 2014

Blog Reboot: First Post

I have decided to switch my blog to a different backend; one that is easier to maintain and doesn’t rely on MySQL (which I always found overkill and difficult to backup). Now I only need to extract my old blog posts from that last database dump file…

Update: Having worked through the dump file in a text editor, I found hundreds of duplicate entries marked as ‘inherit’ and ‘nnn-revision-m‘. These entries may be the result of multiple edits of a post. This is exactly the kind of data bloat that I strive to avoid. The current solution stores all entries in simple text files. Easy to back up. Easy to index. No duplication.

Friday, January 17, 2014

Weekly / Monthly Subversion Dump Backups

Just added a new section to /etc/periodic/monthly/mine.monthly in the attempt to create monthly backups of my subversion repositories, using compressed dump files:

[Read More…]

Tuesday, September 3, 2013

UIScrollView vs. AutoLayout

Setting up a scroll view with multiple subviews (one for each page), I found myself unable to scroll. Everything looked fine. I even had the AutoLayout constraints defined for each of the subviews: pinned width, pinned height, top 0 pt, left x pt (depending on which page).

It took several debugging sessions to work out that the contentSize of the scroll view had been set (through AutoLayout) (after viewDidAppear:) to the size of a single page. Despite my constraints.

The fix is not obvious: there must be constraints for both the top-left corner as well as the bottom-right corner. Once I added an additional constraint for the last view to the right side, the contentSize was correctly calculated to contain all pages.

This tip came from a comment on StackOverflow.