Skip to content

Commit

Permalink
Simplify GRMustacheExpression API
Browse files Browse the repository at this point in the history
  • Loading branch information
groue committed Dec 11, 2012
1 parent baf9a76 commit 23e15ea
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 69 deletions.
10 changes: 5 additions & 5 deletions src/classes/GRMustacheContext.m
Expand Up @@ -254,14 +254,14 @@ - (id)currentContextValue
return [[_contextObject retain] autorelease];
}

- (id)contextValueForKey:(NSString *)key isProtected:(BOOL *)isProtected
- (id)contextValueForKey:(NSString *)key protected:(BOOL *)protected
{
if (_protectedContextObject) {
for (GRMustacheContext *context = self; context; context = context.protectedContextParent) {
id value = [GRMustacheContext valueForKey:key inObject:context.protectedContextObject];
if (value != nil) {
if (isProtected) {
*isProtected = YES;
if (protected != NULL) {
*protected = YES;
}
return value;
}
Expand All @@ -283,8 +283,8 @@ - (id)contextValueForKey:(NSString *)key isProtected:(BOOL *)isProtected
if (hidden) { continue; }
id value = [GRMustacheContext valueForKey:key inObject:contextObject];
if (value != nil) {
if (isProtected) {
*isProtected = NO;
if (protected != NULL) {
*protected = NO;
}
return value;
}
Expand Down
12 changes: 6 additions & 6 deletions src/classes/GRMustacheContext_private.h
Expand Up @@ -130,22 +130,22 @@ extern BOOL GRMustacheContextDidCatchNSUndefinedKeyException;
* Performs a key lookup in the receiver's context stack, and returns the found
* value.
*
* @param key The searched key.
* @param isProtected Upon return, is YES if the value comes from the protected
* context stack.
* @param key The searched key.
* @param protected Upon return, is YES if the value comes from the protected
* context stack.
*
* @return The value found in the context stack.
*
* @see -[GRMustacheIdentifierExpression evaluateInContext:]
* @see -[GRMustacheIdentifierExpression valueWithContext:]
*/
- (id)contextValueForKey:(NSString *)key isProtected:(BOOL *)isProtected GRMUSTACHE_API_INTERNAL;
- (id)contextValueForKey:(NSString *)key protected:(BOOL *)protected GRMUSTACHE_API_INTERNAL;

/**
* Returns the top object of the receiver's context stack.
*
* @return The top object of the receiver's context stack.
*
* @see -[GRMustacheImplicitIteratorExpression evaluateInContext:]
* @see -[GRMustacheImplicitIteratorExpression valueWithContext:]
*/
- (id)currentContextValue GRMUSTACHE_API_INTERNAL;

Expand Down
4 changes: 2 additions & 2 deletions src/classes/GRMustacheExpression.m
Expand Up @@ -35,10 +35,10 @@ - (void)dealloc
[super dealloc];
}

- (BOOL)evaluateInContext:(GRMustacheContext *)context value:(id *)value isProtected:(BOOL *)isProtected error:(NSError **)error
- (id)valueWithContext:(GRMustacheContext *)context protected:(BOOL *)protected
{
NSAssert(NO, @"Subclasses must override");
return NO;
return nil;
}

- (BOOL)isEqual:(id)anObject
Expand Down
6 changes: 2 additions & 4 deletions src/classes/GRMustacheExpression_private.h
Expand Up @@ -54,19 +54,17 @@
* Evaluates an expression against a rendering context, and return the value.
*
* @param context A Mustache rendering context
* @param value TODO
* @param protected TODO
* @param error TODO
*
* @return TODO
*/
- (BOOL)evaluateInContext:(GRMustacheContext *)context value:(id *)value isProtected:(BOOL *)isProtected error:(NSError **)error GRMUSTACHE_API_INTERNAL;
- (id)valueWithContext:(GRMustacheContext *)context protected:(BOOL *)protected GRMUSTACHE_API_INTERNAL;

/**
* Returns a Boolean value that indicates whether the receiver and a given
* object are equal.
*
* Expressions are equal if and only if the result of their `evaluateInContext:`
* Expressions are equal if and only if the result of their `valueWithContext:`
* implementation would return the same value in a given rendering context.
*
* Default implementation is NSObject's one: subclasses must override.
Expand Down
26 changes: 9 additions & 17 deletions src/classes/GRMustacheFilteredExpression.m
Expand Up @@ -86,17 +86,10 @@ - (BOOL)isEqual:(id)expression

#pragma mark GRMustacheExpression

- (BOOL)evaluateInContext:(GRMustacheContext *)context value:(id *)value isProtected:(BOOL *)isProtected error:(NSError **)error
- (id)valueWithContext:(GRMustacheContext *)context protected:(BOOL *)protected
{
id argument;
id filter;

if (![_argumentExpression evaluateInContext:context value:&argument isProtected:NULL error:error]) {
return NO;
}
if (![_filterExpression evaluateInContext:context value:&filter isProtected:NULL error:error]) {
return NO;
}
id argument = [_argumentExpression valueWithContext:context protected:NULL];
id filter = [_filterExpression valueWithContext:context protected:NULL];

if (filter == nil) {
GRMustacheToken *token = self.token;
Expand All @@ -116,16 +109,15 @@ - (BOOL)evaluateInContext:(GRMustacheContext *)context value:(id *)value isProte
}
}

if (_curry && [filter respondsToSelector:@selector(curryArgument:)]) {
*value = [(id<GRMustacheFilter>)filter curryArgument:argument];
} else {
*value = [(id<GRMustacheFilter>)filter transformedValue:argument];
if (protected != NULL) {
*protected = NO;
}

if (isProtected) {
*isProtected = NO;
if (_curry && [filter respondsToSelector:@selector(curryArgument:)]) {
return [(id<GRMustacheFilter>)filter curryArgument:argument];
} else {
return [(id<GRMustacheFilter>)filter transformedValue:argument];
}
return YES;
}

@end
5 changes: 2 additions & 3 deletions src/classes/GRMustacheIdentifierExpression.m
Expand Up @@ -63,10 +63,9 @@ - (BOOL)isEqual:(id)expression

#pragma mark - GRMustacheExpression

- (BOOL)evaluateInContext:(GRMustacheContext *)context value:(id *)value isProtected:(BOOL *)isProtected error:(NSError **)error
- (id)valueWithContext:(GRMustacheContext *)context protected:(BOOL *)protected
{
*value = [context contextValueForKey:_identifier isProtected:isProtected];
return YES;
return [context contextValueForKey:_identifier protected:protected];
}

@end
9 changes: 4 additions & 5 deletions src/classes/GRMustacheImplicitIteratorExpression.m
Expand Up @@ -38,13 +38,12 @@ - (BOOL)isEqual:(id)expression

#pragma mark - GRMustacheExpression

- (BOOL)evaluateInContext:(GRMustacheContext *)context value:(id *)value isProtected:(BOOL *)isProtected error:(NSError **)error
- (id)valueWithContext:(GRMustacheContext *)context protected:(BOOL *)protected
{
*value = [context currentContextValue];
if (isProtected) {
*isProtected = NO;
if (protected != NULL) {
*protected = NO;
}
return YES;
return [context currentContextValue];
}

@end
11 changes: 5 additions & 6 deletions src/classes/GRMustacheScopedExpression.m
Expand Up @@ -77,14 +77,13 @@ - (BOOL)isEqual:(id)expression

#pragma mark - GRMustacheExpression

- (BOOL)evaluateInContext:(GRMustacheContext *)context value:(id *)value isProtected:(BOOL *)isProtected error:(NSError **)error
- (id)valueWithContext:(GRMustacheContext *)context protected:(BOOL *)protected
{
id scopedValue;
if (![_baseExpression evaluateInContext:context value:&scopedValue isProtected:isProtected error:error]) {
return NO;
id scopedValue = [_baseExpression valueWithContext:context protected:protected];
if (protected != NULL) {
*protected = NO;
}
*value = [GRMustacheContext valueForKey:_scopeIdentifier inObject:scopedValue];
return YES;
return [GRMustacheContext valueForKey:_scopeIdentifier inObject:scopedValue];
}

@end
9 changes: 3 additions & 6 deletions src/classes/GRMustacheTag.m
Expand Up @@ -100,16 +100,13 @@ - (BOOL)renderInBuffer:(NSMutableString *)buffer withContext:(GRMustacheContext

// Evaluate expression

__block id object;
BOOL isProtected;
if (![_expression evaluateInContext:context value:&object isProtected:&isProtected error:error]) {
return NO;
}
BOOL protected;
__block id object = [_expression valueWithContext:context protected:&protected];


// Hide object if it is protected

if (isProtected) {
if (protected) {
// Object is protected: it may enter the context stack, and provide
// value for `.` and `.name`. However, it must not expose its keys.
//
Expand Down
30 changes: 15 additions & 15 deletions src/tests/Private/GRMustacheContextTest.m
Expand Up @@ -125,7 +125,7 @@ - (void)testOneDepthRuntimeForwardsValueForKeyToItsObject
GRKVCRecorder *recorder = [GRKVCRecorder recorderWithRecognizedKey:@"foo"];
GRMustacheContext *context = [GRMustacheContext context];
context = [context contextByAddingObject:recorder];
[context contextValueForKey:@"foo" isProtected:NULL];
[context contextValueForKey:@"foo" protected:NULL];
STAssertEqualObjects(recorder.lastAccessedKey, @"foo", nil);
}

Expand All @@ -136,7 +136,7 @@ - (void)testTwoDepthRuntimeForwardsValueForKeyToTopObjectOnlyIfTopObjectHasKey
GRMustacheContext *context = [GRMustacheContext context];
context = [context contextByAddingObject:rootRecorder];
context = [context contextByAddingObject:topRecorder];
STAssertEqualObjects([context contextValueForKey:@"top" isProtected:NULL], @"top", nil);
STAssertEqualObjects([context contextValueForKey:@"top" protected:NULL], @"top", nil);
STAssertEqualObjects(topRecorder.lastAccessedKey, @"top", nil);
STAssertNil(rootRecorder.lastAccessedKey, nil);
}
Expand All @@ -148,7 +148,7 @@ - (void)testTwoDepthRuntimeForwardsValueForKeyToBothObjectIfTopObjectMisses
GRMustacheContext *context = [GRMustacheContext context];
context = [context contextByAddingObject:rootRecorder];
context = [context contextByAddingObject:topRecorder];
STAssertEqualObjects([context contextValueForKey:@"root" isProtected:NULL], @"root", nil);
STAssertEqualObjects([context contextValueForKey:@"root" protected:NULL], @"root", nil);
STAssertEqualObjects(topRecorder.lastAccessedKey, @"root", nil);
STAssertEqualObjects(rootRecorder.lastAccessedKey, @"root", nil);
}
Expand All @@ -160,7 +160,7 @@ - (void)testTwoDepthRuntimeMissesIfBothObjectMisses
GRMustacheContext *context = [GRMustacheContext context];
context = [context contextByAddingObject:rootRecorder];
context = [context contextByAddingObject:topRecorder];
STAssertNil([context contextValueForKey:@"foo" isProtected:NULL], nil);
STAssertNil([context contextValueForKey:@"foo" protected:NULL], nil);
STAssertEqualObjects(topRecorder.lastAccessedKey, @"foo", nil);
STAssertEqualObjects(rootRecorder.lastAccessedKey, @"foo", nil);
}
Expand All @@ -172,7 +172,7 @@ - (void)testNilDoesNotStopsExploration
context = [context contextByAddingObject:dictionary];
dictionary = [NSDictionary dictionary];
context = [context contextByAddingObject:dictionary];
STAssertEqualObjects([context contextValueForKey:@"key" isProtected:NULL], @"foo", nil);
STAssertEqualObjects([context contextValueForKey:@"key" protected:NULL], @"foo", nil);
}

- (void)testNSNullDoesStopExploration
Expand All @@ -182,7 +182,7 @@ - (void)testNSNullDoesStopExploration
context = [context contextByAddingObject:dictionary];
dictionary = [NSDictionary dictionaryWithObject:[NSNull null] forKey:@"key"];
context = [context contextByAddingObject:dictionary];
STAssertEqualObjects([context contextValueForKey:@"key" isProtected:NULL], [NSNull null], nil);
STAssertEqualObjects([context contextValueForKey:@"key" protected:NULL], [NSNull null], nil);
}

- (void)testNSNumberWithBoolNODoesStopExploration
Expand All @@ -192,7 +192,7 @@ - (void)testNSNumberWithBoolNODoesStopExploration
context = [context contextByAddingObject:dictionary];
dictionary = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:@"key"];
context = [context contextByAddingObject:dictionary];
STAssertEqualObjects([context contextValueForKey:@"key" isProtected:NULL], [NSNumber numberWithBool:NO], nil);
STAssertEqualObjects([context contextValueForKey:@"key" protected:NULL], [NSNumber numberWithBool:NO], nil);
}

- (void)testOneDepthRuntimeTemplate
Expand Down Expand Up @@ -222,7 +222,7 @@ - (void)testRuntimeRethrowsNonNSUndefinedKeyException
ThrowingObject *throwingObject = [[[ThrowingObject alloc] init] autorelease];
GRMustacheContext *context = [GRMustacheContext context];
context = [context contextByAddingObject:throwingObject];
STAssertThrows([context contextValueForKey:@"NonNSUndefinedKeyException" isProtected:NULL], nil);
STAssertThrows([context contextValueForKey:@"NonNSUndefinedKeyException" protected:NULL], nil);
}

- (void)testRuntimeSwallowsNonSelfNSUndefinedKeyException
Expand All @@ -231,28 +231,28 @@ - (void)testRuntimeSwallowsNonSelfNSUndefinedKeyException
ThrowingObject *throwingObject = [[[ThrowingObject alloc] init] autorelease];
GRMustacheContext *context = [GRMustacheContext context];
context = [context contextByAddingObject:throwingObject];
STAssertNoThrow([context contextValueForKey:@"NonSelfNSUndefinedKeyException" isProtected:NULL], nil);
STAssertNoThrow([context contextValueForKey:@"NonSelfNSUndefinedKeyException" protected:NULL], nil);
}

- (void)testRuntimeSwallowsSelfNSUndefinedKeyException
{
ThrowingObject *throwingObject = [[[ThrowingObject alloc] init] autorelease];
GRMustacheContext *context = [GRMustacheContext context];
context = [context contextByAddingObject:throwingObject];
STAssertNoThrow([context contextValueForKey:@"SelfNSUndefinedKeyException" isProtected:NULL], nil);
STAssertNoThrow([context contextValueForKey:@"SelfNSUndefinedKeyException" protected:NULL], nil);
}

- (void)testContextByAddingProtectedObject
{
GRMustacheContext *context = [GRMustacheContext context];
context = [context contextByAddingProtectedObject:@{ @"safe": @"important" }];
STAssertEqualObjects([context contextValueForKey:@"safe" isProtected:NULL], @"important", @"");
STAssertEqualObjects([context contextValueForKey:@"safe" protected:NULL], @"important", @"");
context = [context contextByAddingObject:@{ @"safe": @"hack", @"fragile": @"A" }];
STAssertEqualObjects([context contextValueForKey:@"safe" isProtected:NULL], @"important", @"");
STAssertEqualObjects([context contextValueForKey:@"fragile" isProtected:NULL], @"A", @"");
STAssertEqualObjects([context contextValueForKey:@"safe" protected:NULL], @"important", @"");
STAssertEqualObjects([context contextValueForKey:@"fragile" protected:NULL], @"A", @"");
context = [context contextByAddingObject:@{ @"safe": @"hack", @"fragile": @"B" }];
STAssertEqualObjects([context contextValueForKey:@"safe" isProtected:NULL], @"important", @"");
STAssertEqualObjects([context contextValueForKey:@"fragile" isProtected:NULL], @"B", @"");
STAssertEqualObjects([context contextValueForKey:@"safe" protected:NULL], @"important", @"");
STAssertEqualObjects([context contextValueForKey:@"fragile" protected:NULL], @"B", @"");
}

@end

0 comments on commit 23e15ea

Please sign in to comment.