Skip to content

Commit

Permalink
hide unnecessary output when running CDRJUnitXMLReporter specs
Browse files Browse the repository at this point in the history
  • Loading branch information
cppforlife committed Oct 6, 2012
1 parent f753aa3 commit a498073
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 61 deletions.
57 changes: 25 additions & 32 deletions Source/CDRJUnitXMLReporter.m
Expand Up @@ -3,7 +3,6 @@

@implementation CDRJUnitXMLReporter

#pragma mark - Memory
- (id)init {
if (self = [super init]) {
successMessages_ = [[NSMutableArray alloc] init];
Expand All @@ -16,41 +15,16 @@ - (void)dealloc {
[super dealloc];
}

#pragma mark - Private

- (NSString *)escape:(NSString *)s {
NSMutableString *escaped = [NSMutableString stringWithString:s];

[escaped setString:[escaped stringByReplacingOccurrencesOfString:@"&" withString:@"&"]];
[escaped setString:[escaped stringByReplacingOccurrencesOfString:@">" withString:@">"]];
[escaped setString:[escaped stringByReplacingOccurrencesOfString:@"<" withString:@"&lt;"]];
[escaped setString:[escaped stringByReplacingOccurrencesOfString:@"\"" withString:@"&quot;"]];
[escaped setString:[escaped stringByReplacingOccurrencesOfString:@"'" withString:@"&apos;"]];

return escaped;
}

- (void)writeXmlToFile:(NSString *)xml {
char *xmlFile = getenv("CEDAR_JUNIT_XML_FILE");
if (!xmlFile) {
xmlFile = "build/TEST-Cedar.xml";
}

NSError *error;
[xml writeToFile:[NSString stringWithUTF8String:xmlFile] atomically:YES encoding:NSUTF8StringEncoding error:&error];
}

#pragma mark - Overriden Methods

- (NSString *)failureMessageForExample:(CDRExample *)example {
return [NSString stringWithFormat:@"%@\n%@\n",[example fullText], example.failure];
return [NSString stringWithFormat:@"%@\n%@\n", example.fullText, example.failure];
}

- (void)reportOnExample:(CDRExample *)example {
NSMutableArray *messages = nil;
switch (example.state) {
case CDRExampleStatePassed:
[successMessages_ addObject:[example fullText]];
[successMessages_ addObject:example.fullText];
break;
case CDRExampleStateFailed:
case CDRExampleStateError:
Expand All @@ -63,27 +37,46 @@ - (void)reportOnExample:(CDRExample *)example {

- (void)runDidComplete {
[super runDidComplete];

NSMutableString *xml = [NSMutableString string];
[xml appendString:@"<?xml version=\"1.0\"?>\n"];
[xml appendString:@"<testsuite>\n"];

for (NSString *spec in successMessages_) {
[xml appendFormat:@"\t<testcase classname=\"Cedar\" name=\"%@\" />\n", [self escape:spec]];
[xml appendFormat:@"\t<testcase classname=\"Cedar\" name=\"%@\" />\n", [self escapeString:spec]];
}

for (NSString *spec in failureMessages_) {
NSArray *parts = [spec componentsSeparatedByString:@"\n"];
NSString *name = [parts objectAtIndex:0];
NSString *message = [parts objectAtIndex:1];

[xml appendFormat:@"\t<testcase classname=\"Cedar\" name=\"%@\">\n", [self escape:name]];
[xml appendFormat:@"\t\t<failure type=\"Failure\">%@</failure>\n", [self escape:message]];
[xml appendFormat:@"\t<testcase classname=\"Cedar\" name=\"%@\">\n", [self escapeString:name]];
[xml appendFormat:@"\t\t<failure type=\"Failure\">%@</failure>\n", [self escapeString:message]];
[xml appendString:@"\t</testcase>\n"];
}

[xml appendString:@"</testsuite>\n"];

[self writeXmlToFile:xml];
}

#pragma mark - Private

- (NSString *)escapeString:(NSString *)unescaped {
NSString *escaped = [unescaped stringByReplacingOccurrencesOfString:@"&" withString:@"&amp;"];
escaped = [escaped stringByReplacingOccurrencesOfString:@">" withString:@"&gt;"];
escaped = [escaped stringByReplacingOccurrencesOfString:@"<" withString:@"&lt;"];
escaped = [escaped stringByReplacingOccurrencesOfString:@"\"" withString:@"&quot;"];
return [escaped stringByReplacingOccurrencesOfString:@"'" withString:@"&apos;"];
}

- (void)writeXmlToFile:(NSString *)xml {
char *xmlFile = getenv("CEDAR_JUNIT_XML_FILE");
if (!xmlFile) xmlFile = "build/TEST-Cedar.xml";

[xml writeToFile:[NSString stringWithUTF8String:xmlFile]
atomically:YES
encoding:NSUTF8StringEncoding
error:NULL];
}
@end
1 change: 0 additions & 1 deletion Source/Headers/CDRJUnitXMLReporter.h
Expand Up @@ -4,5 +4,4 @@
@interface CDRJUnitXMLReporter : CDRDefaultReporter {
NSMutableArray *successMessages_;
}

@end
53 changes: 25 additions & 28 deletions Spec/CDRJUnitXMLReporterSpec.mm
Expand Up @@ -35,6 +35,19 @@ - (void)writeXmlToFile:(NSString *)xmlString {
self.xml = xmlString;
}

// Temporarily redirect stdout to avoid unnecessary output when running tests
- (void)runDidComplete {
FILE *realStdout = stdout;
stdout = fopen("/dev/null", "w");

@try {
[super runDidComplete];
}
@finally {
fclose(stdout);
stdout = realStdout;
}
}
@end

// Allow setting state for testing purposes
Expand All @@ -44,12 +57,11 @@ - (void)setState:(CDRExampleState)state {
state_ = state;
}

+ (id) exampleWithText:(NSString *)text andState:(CDRExampleState)state {
+ (id)exampleWithText:(NSString *)text andState:(CDRExampleState)state {
CDRExample *example = [CDRExample exampleWithText:text andBlock:^{}];
[example setState:state];
return example;
}

@end


Expand All @@ -59,91 +71,76 @@ + (id) exampleWithText:(NSString *)text andState:(CDRExampleState)state {
__block TestCDRJUnitXMLReporter *reporter;

beforeEach(^{
reporter = [[TestCDRJUnitXMLReporter alloc] init];
});

afterEach(^{
[reporter release];
reporter = [[[TestCDRJUnitXMLReporter alloc] init] autorelease];
});

context(@"When no specs are run", ^{
context(@"when no specs are run", ^{
it(@"should output a blank test suite report", ^{
[reporter runDidComplete];

expect(reporter.xml).to(equal(@"<?xml version=\"1.0\"?>\n<testsuite>\n</testsuite>\n"));
});
});

describe(@"Each passing spec", ^{
describe(@"each passing spec", ^{
it(@"should be written to the XML file", ^{
CDRExample *example1 = [CDRExample exampleWithText:@"Passing spec 1" andState:CDRExampleStatePassed];
CDRExample *example2 = [CDRExample exampleWithText:@"Passing spec 2" andState:CDRExampleStatePassed];

[reporter reportOnExample:example1];

CDRExample *example2 = [CDRExample exampleWithText:@"Passing spec 2" andState:CDRExampleStatePassed];
[reporter reportOnExample:example2];

[reporter runDidComplete];

expect([reporter.xml rangeOfString:@"<testcase classname=\"Cedar\" name=\"Passing spec 1\" />"].location).to_not(equal((NSUInteger)NSNotFound));
expect([reporter.xml rangeOfString:@"<testcase classname=\"Cedar\" name=\"Passing spec 2\" />"].location).to_not(equal((NSUInteger)NSNotFound));
});

it(@"should have its name escaped", ^{
CDRExample *example = [CDRExample exampleWithText:@"Special ' characters \" should < be & escaped > " andState:CDRExampleStatePassed];

[reporter reportOnExample:example];

[reporter runDidComplete];

expect([reporter.xml rangeOfString:@"name=\"Special &apos; characters &quot; should &lt; be &amp; escaped &gt; \""].location).to_not(equal((NSUInteger)NSNotFound));
});
});

describe(@"Each failing spec", ^{
describe(@"each failing spec", ^{
it(@"should be written to the XML file", ^{
CDRExample *example1 = [CDRExample exampleWithText:@"Failing spec 1" andState:CDRExampleStateFailed];
example1.failure = [CDRSpecFailure specFailureWithReason:@"Failure reason 1"];
[reporter reportOnExample:example1];

CDRExample *example2 = [CDRExample exampleWithText:@"Failing spec 2" andState:CDRExampleStateFailed];
example2.failure = [CDRSpecFailure specFailureWithReason:@"Failure reason 2"];

[reporter reportOnExample:example1];
[reporter reportOnExample:example2];

[reporter runDidComplete];

expect([reporter.xml rangeOfString:@"<testcase classname=\"Cedar\" name=\"Failing spec 1\">\n\t\t<failure type=\"Failure\">Failure reason 1</failure>\n\t</testcase>"].location).to_not(equal((NSUInteger)NSNotFound));
expect([reporter.xml rangeOfString:@"<testcase classname=\"Cedar\" name=\"Failing spec 2\">\n\t\t<failure type=\"Failure\">Failure reason 2</failure>\n\t</testcase>"].location).to_not(equal((NSUInteger)NSNotFound));
});

it(@"should have its name escaped", ^{
CDRExample *example = [CDRExample exampleWithText:@"Special ' characters \" should < be & escaped > " andState:CDRExampleStateFailed];

[reporter reportOnExample:example];

[reporter runDidComplete];

expect([reporter.xml rangeOfString:@"name=\"Special &apos; characters &quot; should &lt; be &amp; escaped &gt; \""].location).to_not(equal((NSUInteger)NSNotFound));
});

it(@"should escape the failure reason", ^{
CDRExample *example1 = [CDRExample exampleWithText:@"Failing spec 1\n Special ' characters \" should < be & escaped > " andState:CDRExampleStateFailed];

[reporter reportOnExample:example1];
CDRExample *example = [CDRExample exampleWithText:@"Failing spec 1\n Special ' characters \" should < be & escaped > " andState:CDRExampleStateFailed];
[reporter reportOnExample:example];

[reporter runDidComplete];

expect([reporter.xml rangeOfString:@"<failure type=\"Failure\"> Special &apos; characters &quot; should &lt; be &amp; escaped &gt; </failure>"].location).to_not(equal((NSUInteger)NSNotFound));
});
});

describe(@"Each spec that causes an error", ^{
describe(@"each spec that causes an error", ^{
it(@"should be handled the same as a failing spec", ^{
CDRExample *example = [CDRExample exampleWithText:@"Failing spec\nFailure reason" andState:CDRExampleStateError];

[reporter reportOnExample:example];

[reporter runDidComplete];

expect([reporter.xml rangeOfString:@"<testcase classname=\"Cedar\" name=\"Failing spec\">\n\t\t<failure type=\"Failure\">Failure reason</failure>\n\t</testcase>"].location).to_not(equal((NSUInteger)NSNotFound));
});
});
Expand Down

0 comments on commit a498073

Please sign in to comment.