Skip to content

Commit

Permalink
Merge branch 'feature/Swift' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
drekka committed Oct 24, 2016
2 parents c684c6e + 498945c commit c85442e
Show file tree
Hide file tree
Showing 17 changed files with 234 additions and 62 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ Story Teller is an advanced logging framework that takes an entirely different a

See how it works on the main [Story Teller site](http://drekka.github.io/StoryTeller).

# v1.7.6
# v1.8.0

* First cut of adding support for Swift. STLog(...), STStarScope(...) and STStartLogging(...) all working.
* Fixed issues where missing Foundation import in PEGKit generated code was causing compilation failues.

# V1.7.5
Expand All @@ -24,7 +25,7 @@ See how it works on the main [Story Teller site](http://drekka.github.io/StoryTe

* Fixing bug where a weakly referenced key would crash the app if logging was done in a dealloc.

# V1.7.2 #
# V1.7.2

* Added option to log the thread number.
* Added option to draw a picture of the thread similar to a git branch view as the logging occurs. The ASCII based character image illustrates which messages are on the main thread and which are on background threads.
Expand Down
66 changes: 56 additions & 10 deletions StoryTeller.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions StoryTeller/STAbstractLogger.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
#import "STAbstractLogger.h"
#import <pthread/pthread.h>

#define NBR_KEYS 8 // details + message.

NSString * const STLoggerTemplateKeyThreadPicture = @"{{threadPicture}}";
NSString * const STLoggerTemplateKeyThreadNumber = @"{{threadNumber}}";
NSString * const STLoggerTemplateKeyThreadId = @"{{threadId}}";
Expand Down
4 changes: 2 additions & 2 deletions StoryTeller/STConsoleLogger.m
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,6 @@ -(void) writeText:(char *) text {
printf("%s\n", text);
}

NS_ASSUME_NONNULL_END

@end

NS_ASSUME_NONNULL_END
23 changes: 4 additions & 19 deletions StoryTeller/STMacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,23 @@
// Copyright © 2015 Derek Clarkson. All rights reserved.
//

@import Foundation;
#import "STSToryTeller.h"

#ifdef DISABLE_STORY_TELLER

// Remove all logging code.
#define STStartLogging(expression)
#define STStartScope(key)
#define STEndScope(key)
#define STLog(key, messageTemplate, ...)
#define STExecuteBlock(key, codeBlock)

#else

// Internal macro - don't use publically.
#define _ST_CONCAT(prefix, suffix) prefix ## suffix

// Concantiates the two values using another macro to do the work. This allows a level of indirection which
// means that macros such as __LINE__ can be concatinated.
#define ST_CONCATINATE(prefix, suffix) _ST_CONCAT(prefix, suffix)

#define STStartLogging(expression) \
[[STStoryTeller storyTeller] startLogging:expression]

// Note the NS_VALID_UNTIL_END_OF_SCOPE macro. This ensures that the variable does not immediately dealloc.
#define STStartScope(key) \
NS_VALID_UNTIL_END_OF_SCOPE __unused id ST_CONCATINATE(_stHook_, __LINE__) = [[STStoryTeller storyTeller] startScope:key] \

NS_VALID_UNTIL_END_OF_SCOPE __unused id ST_CONCATINATE(_stHook_, __LINE__) = [[STStoryTeller instance] startScope:key]

#define STLog(key, messageTemplate, ...) \
[[STStoryTeller storyTeller] record:key file:__FILE__ method: __func__ lineNumber: __LINE__ message:messageTemplate, ## __VA_ARGS__]
[[STStoryTeller instance] record:key file:__FILE__ method: __func__ lineNumber: __LINE__ message:messageTemplate, ## __VA_ARGS__]

#define STExecuteBlock(key, codeBlock) \
[[STStoryTeller storyTeller] execute:key block:codeBlock]
[[STStoryTeller instance] execute:key block:codeBlock]

#endif
27 changes: 24 additions & 3 deletions StoryTeller/STStoryTeller.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

NS_ASSUME_NONNULL_BEGIN

void STStartLogging(NSString *expression);

/**
The main StoryTeller class.
@discussion This class brings together all the configuration and processing for Story Teller. At the moment it's all in one class because it's not very big. Most of the functionality commonly needed is wrapped up in macros defined above.
Expand All @@ -28,14 +30,14 @@ NS_ASSUME_NONNULL_BEGIN
@discussion All interactions with Story Teller should go through this method.
@return The main STStoryTeller instance.
*/
+(nullable STStoryTeller *) storyTeller;
+(instancetype) instance;

/// @name Configuration

/**
The current active logger.
@discussion By defaul this is an instance of STConsoleLogger. However, you can create and set a different class as long as it conforms to the STLogger protocol.
@discussion By default this is an instance of STConsoleLogger. However, you can create and set a different class as long as it conforms to the STLogger protocol.
@see STLogger
*/
@property (nonatomic, strong) id<STLogger> logger;
Expand Down Expand Up @@ -111,7 +113,26 @@ NS_ASSUME_NONNULL_BEGIN
file:(const char *) fileName
method:(const char *) methodName
lineNumber:(int) lineNumber
message:(NSString *) messageTemplate, ...;
message:(NSString *) messageTemplate, ... NS_FORMAT_FUNCTION(5, 6);

/**
The main method to be called to log a message in the current logger.
@discussion This method also handled the descision making around whether to pass the message onto the current logger or not. If going ahead, it assembles the final message and passes it to the logger. The key is weak to avoid issues around using this method in blocks and circular references to objects.
@param key the key to log the message under.
@param fileName the name of the file where the `STLog(...)` statement occurs.
@param methodName the name of the method where the `STLog(...)` statement occurs.
@param lineNumber the line number in the method where the `STLog(...)` statement occurs.
@param messageTemplate a standard NSString format message.
@param args a list of values for the message template.
*/
-(void) record:(id) key
file:(const char *) fileName
method:(const char *) methodName
lineNumber:(int) lineNumber
message:(NSString *) messageTemplate
args:(va_list) args;

/**
Useful helper method which executes a block of code if the key is active.
Expand Down
30 changes: 24 additions & 6 deletions StoryTeller/STStoryTeller.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@

NS_ASSUME_NONNULL_BEGIN

void STStartLogging(NSString *expression) {
[[STStoryTeller instance] startLogging:expression];
}

@implementation STStoryTeller {
NSMutableSet *_activeKeys;
NSMutableSet<id<STMatcher>> *_logMatchers;
Expand All @@ -26,7 +30,7 @@ @implementation STStoryTeller {

static __strong STStoryTeller *__storyTeller;

+(nullable STStoryTeller *) storyTeller {
+(instancetype) instance {
@synchronized (self) {
if (!__storyTeller) {
__storyTeller = [[STStoryTeller alloc] init];
Expand Down Expand Up @@ -89,7 +93,7 @@ -(int) numberActiveScopes {
-(id) startScope:(__weak id) key {
[_activeKeys addObject:key];
return [[STDeallocHook alloc] initWithBlock:^{
[[STStoryTeller storyTeller] endScope:key];
[[STStoryTeller instance] endScope:key];
}];
}

Expand All @@ -108,18 +112,32 @@ -(void) record:(id) key
method:(const char *) methodName
lineNumber:(int) lineNumber
message:(NSString *) messageTemplate, ... {
va_list args;
va_start(args, messageTemplate);
[self record:key
file:fileName
method:methodName
lineNumber:lineNumber
message:messageTemplate
args:args];
va_end(args);
}

-(void) record:(id) key
file:(const char *) fileName
method:(const char *) methodName
lineNumber:(int) lineNumber
message:(NSString *) messageTemplate
args:(va_list) args {

// Only continue if the key is being logged.
if (![self shouldLogKey:key]) {
return;
}

// Assemble the main message.
va_list args;
va_start(args, messageTemplate);
NSString *msg = [[NSString alloc] initWithFormat:messageTemplate arguments:args];
va_end(args);


// And give it to the scribe.
[self.logger writeMessage:msg
fromFile:fileName
Expand Down
2 changes: 1 addition & 1 deletion StoryTeller/StoryTeller.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ FOUNDATION_EXPORT const unsigned char StoryTellerVersionString[];
#import <StoryTeller/STConsoleLogger.h>
#import <StoryTeller/STLogger.h>
#import <StoryTeller/STMacros.h>
#import <StoryTeller/STStoryTeller.h>
#import <StoryTeller/STStoryTeller.h>
22 changes: 22 additions & 0 deletions StoryTeller/StoryTellerSwift.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// StoryTellerWrapper.swift
// StoryTeller
//
// Created by Derek Clarkson on 17/10/16.
// Copyright © 2016 Derek Clarkson. All rights reserved.
//

import Foundation

public func STLog(_ key:AnyObject, file:String = #file, method:String = #function, line:Int32 = #line, _ messageTemplate:String, _ args:CVarArg...) {
withVaList(args) {
STStoryTeller.instance().record(key, file: file, method: method, lineNumber:line, message: messageTemplate, args: $0)
}
}

public func STStartScope(_ key:AnyObject, _ block:() -> Void) {
let x = STStoryTeller.instance().startScope(key)
block()
let _ = x
// STStoryTeller.instance().endScope(key)
}
10 changes: 10 additions & 0 deletions StoryTellerTests/Bridging-Header.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// Bridging-Header.h
// StoryTeller
//
// Created by Derek Clarkson on 23/10/16.
// Copyright © 2016 Derek Clarkson. All rights reserved.
//

#import "InMemoryLogger.h"
#import "STStoryTeller+Internal.h"
1 change: 0 additions & 1 deletion StoryTellerTests/InMemoryLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//

@import Foundation;

@import StoryTeller;

@interface InMemoryLogger : STAbstractLogger
Expand Down
1 change: 0 additions & 1 deletion StoryTellerTests/InMemoryLogger.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//
// InMemoryScribe.m
// StoryTeller
//
// Created by Derek Clarkson on 18/06/2015.
Expand Down
2 changes: 1 addition & 1 deletion StoryTellerTests/OptionsTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ -(void) setUp {

// Mock out story teller.
_mockStoryTeller = OCMClassMock([STStoryTeller class]);
OCMStub([_mockStoryTeller storyTeller]).andReturn(_mockStoryTeller);
OCMStub([_mockStoryTeller instance]).andReturn(_mockStoryTeller);
}

-(void) tearDown {
Expand Down
13 changes: 13 additions & 0 deletions StoryTellerTests/STStoryTeller+Internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// STStoryTeller+Internal.h
// StoryTeller
//
// Created by Derek Clarkson on 23/10/16.
// Copyright © 2016 Derek Clarkson. All rights reserved.
//

// Accessing internal methods for testing purposes.
@interface STStoryTeller (Testing)
+(void) reset;
+(void) clearMatchers;
@end
64 changes: 64 additions & 0 deletions StoryTellerTests/STSwiftTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// STSwiftTests.swift
// StoryTeller
//
// Created by Derek Clarkson on 21/10/16.
// Copyright © 2016 Derek Clarkson. All rights reserved.
//

import XCTest
@testable import StoryTeller

class STSwiftTests: XCTestCase {

let _inMemoryLogger = InMemoryLogger()

override func setUp() {
STStoryTeller.instance().logger = _inMemoryLogger
}

override func tearDown() {
STStoryTeller.reset()
}

func testBaseLogging() {
STStartLogging("[StoryTellerTests.STSwiftTests]")
STLog(self, "Hello")
validateLogLine(0, methodName: "testBaseLogging", lineNumber: #line - 1, message: "Hello")
}

func testScopeActive() {
STStartLogging("[StoryTellerTests.STSwiftTests]")
STStartScope(self) {
STLog("xyz" as NSString, "Hello")
}
validateLogLine(0, methodName: "testBaseLogging", lineNumber: #line - 2, message: "Hello")
}

func testScopeNestedActive() {
STStartLogging("[StoryTellerTests.STSwiftTests]")
STStartScope(self) {
STLog("xyz" as NSString, "Hello")
}
STLog("xyz" as NSString, "Hello 2")
validateLogLine(0, methodName: "testBaseLogging", lineNumber: #line - 3, message: "Hello")
XCTAssertEqual(1, _inMemoryLogger.log.count)
}

// MARK:- Internal

func validateLogLine(_ atIndex:Int, methodName:String, lineNumber:Int, message:String) {

if _inMemoryLogger.log.count < atIndex + 1 {
XCTFail("Not enough log lines")
return
}

let fullFilename:NSString = #file
let filename = fullFilename.lastPathComponent
let expected = "\(filename):\(lineNumber) \(message)"
let loggedMsg = _inMemoryLogger.log[atIndex]
let idx = loggedMsg.index(loggedMsg.startIndex, offsetBy: 13)
XCTAssertEqual(expected, loggedMsg.substring(from:idx))
}
}
Loading

0 comments on commit c85442e

Please sign in to comment.