diff options
author | Max <post@wickenrode.com> | 2017-02-12 20:49:31 +0100 |
---|---|---|
committer | Max <post@wickenrode.com> | 2017-02-12 20:49:31 +0100 |
commit | d2b1a5b84cb295eba8617f7e80681e0eeca46f0d (patch) | |
tree | 82dd73fb5c23849be2aa8c5df3695293410229e7 | |
parent | aee6a009a5355aa3c7c91f885685868e5294e71c (diff) | |
download | sequelpro-d2b1a5b84cb295eba8617f7e80681e0eeca46f0d.tar.gz sequelpro-d2b1a5b84cb295eba8617f7e80681e0eeca46f0d.tar.bz2 sequelpro-d2b1a5b84cb295eba8617f7e80681e0eeca46f0d.zip |
Add unit tests and fix a bug in JSON formatter
-rw-r--r-- | Source/SPJSONFormatter.m | 8 | ||||
-rw-r--r-- | UnitTests/SPJSONFormatterTests.m | 141 | ||||
-rw-r--r-- | sequel-pro.xcodeproj/project.pbxproj | 6 |
3 files changed, 151 insertions, 4 deletions
diff --git a/Source/SPJSONFormatter.m b/Source/SPJSONFormatter.m index 05cc2992..258845c9 100644 --- a/Source/SPJSONFormatter.m +++ b/Source/SPJSONFormatter.m @@ -62,11 +62,11 @@ static char GetNextANSIChar(SPJSONTokenizerState *stateInfo); return nil; } - if(curToken.tok == JSON_TOK_SQUARE_BRACE_CLOSE || curToken.tok == JSON_TOK_CURLY_BRACE_CLOSE) + if(idLevel > 0 && (curToken.tok == JSON_TOK_SQUARE_BRACE_CLOSE || curToken.tok == JSON_TOK_CURLY_BRACE_CLOSE)) idLevel--; - //if this token is a "]" or "}" and there was no "[" or "{" directly before it, add a linebreak before - if(prevTokenType != JSON_TOK_CURLY_BRACE_OPEN && prevTokenType != JSON_TOK_SQUARE_BRACE_OPEN && (curToken.tok == JSON_TOK_SQUARE_BRACE_CLOSE || curToken.tok == JSON_TOK_CURLY_BRACE_CLOSE)) { + //if this token is a "]" or "}" and there was no ",", "[" or "{" directly before it, add a linebreak before + if(prevTokenType != JSON_TOK_CURLY_BRACE_OPEN && prevTokenType != JSON_TOK_SQUARE_BRACE_OPEN && prevTokenType != JSON_TOK_COMMA && (curToken.tok == JSON_TOK_SQUARE_BRACE_CLOSE || curToken.tok == JSON_TOK_CURLY_BRACE_CLOSE)) { [formatted appendString:@"\n"]; needIndent = YES; } @@ -255,7 +255,7 @@ int SPJSONTokenizerInit(NSString *input, SPJSONTokenizerState *stateInfo) { stateInfo->ctxt = JSON_ROOT_CONTEXT; stateInfo->pos = 0; stateInfo->str = [input UTF8String]; - stateInfo->len = strlen(stateInfo->str); //we deem -[NSString UTF8String] to be a safe source + stateInfo->len = [input lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; return 0; } diff --git a/UnitTests/SPJSONFormatterTests.m b/UnitTests/SPJSONFormatterTests.m new file mode 100644 index 00000000..658169a4 --- /dev/null +++ b/UnitTests/SPJSONFormatterTests.m @@ -0,0 +1,141 @@ +// +// SPJSONFormatterTests.m +// sequel-pro +// +// Created by Max Lohrmann on 12.02.17. +// Copyright (c) 2017 Max Lohrmann. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// More info at <https://github.com/sequelpro/sequelpro> + +#import "SPJSONFormatter.h" +#import <Cocoa/Cocoa.h> +#import <XCTest/XCTest.h> + +@interface SPJSONFormatterTests : XCTestCase + +- (void)testFormatting; +- (void)testUnformatting; + +@end + +@implementation SPJSONFormatterTests + +- (void)testFormatting +{ + + //invalid input + XCTAssertNil([SPJSONFormatter stringByFormattingString:nil],@"nil output on nil input"); + + //empty string + XCTAssertEqualObjects([SPJSONFormatter stringByFormattingString:@""], @"", @"empty string stays empty"); + + //scalars on their own should not get changed + { + NSArray *scalars = @[@"true",@"false",@"null",@"123.45",@"1.4e-5",@"\"string\""]; + for (NSString *scalar in scalars) { + XCTAssertEqualObjects([SPJSONFormatter stringByFormattingString:scalar], scalar, @"scalar only input stays as is"); + } + } + + //simple test involving all types + { + NSString *unf = @"{\"key\": null, \"foo\": [true, false], \"ba\\\"r\": [{},{\"key2\": -1.98}]}"; + NSString *fmt = @"{\n\t\"key\": null,\n\t\"foo\": [\n\t\ttrue,\n\t\tfalse\n\t],\n\t\"ba\\\"r\": [\n\t\t{},\n\t\t{\n\t\t\t\"key2\": -1.98\n\t\t}\n\t]\n}"; + + XCTAssertEqualObjects([SPJSONFormatter stringByFormattingString:unf], fmt, @"simple formatting test"); + } + + //other tests + { + NSArray *tests = @[ + @[@"{\"key\": \"v\0al\"}",@"{\n\t\"key\": \"v\0al\"\n}", @"NUL in input (invalid JSON)"], + @[@"[\"\",\"\"\",\"", @"[\n\t\"\",\n\t\"\"\",\"", @"series of dquotes (invalid JSON)"], + @[@"{[{\"ab\\u0090c\",",@"{\n\t[\n\t\t{\n\t\t\t\"ab\\u0090c\",\n",@"unterminated elements (invalid JSON)"], + @[@"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[null]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]",@"[\n\t[\n\t\t[\n\t\t\t[\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t]\n\t\t\t\t\t]\n\t\t\t\t]\n\t\t\t]\n\t\t]\n\t]\n]",@"34 levels of indent"], + @[@"{\"a\":\"bcd}",@"{\n\t\"a\": \"bcd}",@"unterminated string (invalid JSON)"], + @[@"[1,\"ab\ncd\",3]",@"[\n\t1,\n\t\"ab\ncd\",\n\t3\n]",@"multiline string (invalid JSON)"], + @[@"{}}},false]",@"{}\n}\n},\nfalse\n]",@"closing something that is not open (invalid JSON)"], + @[@"[[123e4}}",@"[\n\t[\n\t\t123e4\n\t}\n}",@"unmatched braces (invalid JSON)"], + @[@"[{]}",@"[\n\t{\n\t]\n}",@"unmatched braces 2 (invalid JSON)"], + @[@"[ true , \n false \t ] \t \n",@"[\n\ttrue,\n\tfalse\n]",@"whitespace reformatting"], + @[@"[1,2,]",@"[\n\t1,\n\t2,\n]",@"trailing comma (valid for some parsers)"], + @[@"{}/{|}],-\"}[|[{}\\\"]:{~]\",,}{]\{|::[\\|\"],};]*}]",@"{}/{\n\t|\n}\n],\n-\"}[|[{}\\\"]:{~]\",\n,\n}{\n]{\n\t|: : [\n\t\t\\|\"],};]*}]",@"random garbage"], + ]; + + for (NSArray *pair in tests) { + XCTAssertEqualObjects([SPJSONFormatter stringByFormattingString:[pair objectAtIndex:0]], [pair objectAtIndex:1], @"%@", [pair objectAtIndex:2]); + } + } +} + +- (void)testUnformatting +{ + //invalid input + XCTAssertNil([SPJSONFormatter stringByUnformattingString:nil],@"nil output on nil input"); + + //empty string + XCTAssertEqualObjects([SPJSONFormatter stringByUnformattingString:@""], @"", @"empty string stays empty"); + + //scalars on their own should not get changed + { + NSArray *scalars = @[@"true",@"false",@"null",@"123.45",@"1.4e-5",@"\"string\""]; + for (NSString *scalar in scalars) { + XCTAssertEqualObjects([SPJSONFormatter stringByUnformattingString:scalar], scalar, @"scalar only input stays as is"); + } + } + + //simple test involving all types + { + NSString *unf = @"{\"key\": null, \"foo\": [true, false], \"ba\\\"r\": [{}, {\"key2\": -1.98}]}"; + NSString *fmt = @"{\n\t\"key\": null,\n\t\"foo\": [\n\t\ttrue,\n\t\tfalse\n\t],\n\t\"ba\\\"r\": [\n\t\t{},\n\t\t{\n\t\t\t\"key2\": -1.98\n\t\t}\n\t]\n}"; + + XCTAssertEqualObjects([SPJSONFormatter stringByUnformattingString:fmt], unf, @"simple unformatting test"); + } + + //other tests + { + NSArray *tests = @[ + @[@"{\n\t\"key\": \"v\0al\"\n}", @"{\"key\": \"v\0al\"}", @"NUL in input (invalid JSON)"], + @[@"[\n\t\"\",\n\t\"\"\",\"", @"[\"\", \"\"\",\"", @"series of dquotes (invalid JSON)"], + @[@"{\n\t[\n\t\t{\n\t\t\t\"ab\\u0090c\",\n",@"{[{\"ab\\u0090c\", ",@"unterminated elements (invalid JSON)"], + @[@"[\n\t[\n\t\t[\n\t\t\t[\n\t\t\t\t[\n\t\t\t\t\t[\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t]\n\t\t\t\t\t]\n\t\t\t\t]\n\t\t\t]\n\t\t]\n\t]\n]", @"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[null]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]",@"34 levels of indent"], + @[@"{\n\t\"a\": \"bcd}", @"{\"a\": \"bcd}",@"unterminated string (invalid JSON)"], + @[@"[\n\t1,\n\t\"ab\ncd\",\n\t3\n]",@"[1, \"ab\ncd\", 3]",@"multiline string (invalid JSON)"], + @[@"{}\n}\n},\nfalse\n]", @"{}}}, false]",@"closing something that is not open (invalid JSON)"], + @[@"[\n\t[\n\t\t123e4\n\t}\n}", @"[[123e4}}",@"unmatched braces (invalid JSON)"], + @[@"[\n\t{\n\t]\n}", @"[{]}",@"unmatched braces 2 (invalid JSON)"], + @[@"[ true , \n false \t ] \t \n",@"[true, false]",@"whitespace reformatting"], + @[@"[\n\t1,\n\t2,\n]", @"[1, 2, ]",@"trailing comma (valid for some parsers)"], + @[@"{}/{\n\t|\n}\n],\n-\"}[|[{}\\\"]:{~]\",\n,\n}{\n]{\n\t|: : [\n\t\t\\|\"],};]*}]", @"{}/{|}], -\"}[|[{}\\\"]:{~]\", , }{]\{|: : [\\|\"],};]*}]",@"random garbage"], + ]; + + for (NSArray *pair in tests) { + XCTAssertEqualObjects([SPJSONFormatter stringByUnformattingString:[pair objectAtIndex:0]], [pair objectAtIndex:1], @"%@", [pair objectAtIndex:2]); + } + } + + +} + +@end diff --git a/sequel-pro.xcodeproj/project.pbxproj b/sequel-pro.xcodeproj/project.pbxproj index 52e52d20..b84b20e4 100644 --- a/sequel-pro.xcodeproj/project.pbxproj +++ b/sequel-pro.xcodeproj/project.pbxproj @@ -224,6 +224,8 @@ 5080229C1BF7C0FE0052A9B2 /* MGTemplateStandardMarkers.m in Sources */ = {isa = PBXBuildFile; fileRef = 296DC8AD0F909194002A3258 /* MGTemplateStandardMarkers.m */; }; 5080229D1BF7C0FE0052A9B2 /* MGTemplateStandardFilters.m in Sources */ = {isa = PBXBuildFile; fileRef = 296DC8B40F909194002A3258 /* MGTemplateStandardFilters.m */; }; 50805B0D1BF2A068005F7A99 /* SPPopUpButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 50805B0C1BF2A068005F7A99 /* SPPopUpButtonCell.m */; }; + 50837F741E50DCD4004FAE8A /* SPJSONFormatterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 50837F731E50DCD4004FAE8A /* SPJSONFormatterTests.m */; }; + 50837F771E50E007004FAE8A /* SPJSONFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 73F70A951E4E547500636550 /* SPJSONFormatter.m */; }; 5089B0271BE714E300E226CD /* SPIdMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 5089B0261BE714E300E226CD /* SPIdMenu.m */; }; 50A9F8B119EAD4B90053E571 /* SPGotoDatabaseController.m in Sources */ = {isa = PBXBuildFile; fileRef = 50A9F8B019EAD4B90053E571 /* SPGotoDatabaseController.m */; }; 50D3C3491A75B8A800B5429C /* GotoDatabaseDialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = 50D3C34B1A75B8A800B5429C /* GotoDatabaseDialog.xib */; }; @@ -967,6 +969,7 @@ 508022941BF7BA470052A9B2 /* English */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = English; path = English.lproj/SPQLPluginExportSettingsTemplate.html; sourceTree = "<group>"; }; 50805B0B1BF2A068005F7A99 /* SPPopUpButtonCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPPopUpButtonCell.h; sourceTree = "<group>"; }; 50805B0C1BF2A068005F7A99 /* SPPopUpButtonCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPPopUpButtonCell.m; sourceTree = "<group>"; }; + 50837F731E50DCD4004FAE8A /* SPJSONFormatterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPJSONFormatterTests.m; sourceTree = "<group>"; }; 5089B0251BE714E300E226CD /* SPIdMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPIdMenu.h; sourceTree = "<group>"; }; 5089B0261BE714E300E226CD /* SPIdMenu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPIdMenu.m; sourceTree = "<group>"; }; 50A9F8AF19EAD4B90053E571 /* SPGotoDatabaseController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPGotoDatabaseController.h; sourceTree = "<group>"; }; @@ -2472,6 +2475,7 @@ children = ( 50D3C35B1A771C4C00B5429C /* SPParserUtilsTest.m */, 503B02CE1AE95C2C0060CAB1 /* SPTableFilterParserTest.m */, + 50837F731E50DCD4004FAE8A /* SPJSONFormatterTests.m */, ); name = Other; sourceTree = "<group>"; @@ -3180,6 +3184,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 50837F771E50E007004FAE8A /* SPJSONFormatter.m in Sources */, 505F56901BCEE491007467DD /* SPOSInfo.m in Sources */, 505F568F1BCEE485007467DD /* SPFunctions.m in Sources */, 502D21F81BA50966000D4CE7 /* SPDataAdditions.m in Sources */, @@ -3189,6 +3194,7 @@ 503B02CF1AE95C2C0060CAB1 /* SPTableFilterParserTest.m in Sources */, 50EA92681AB23EFC008D3C4F /* SPTableCopy.m in Sources */, 507FF1621BBF0D5000104523 /* SPTableCopyTest.m in Sources */, + 50837F741E50DCD4004FAE8A /* SPJSONFormatterTests.m in Sources */, 50EA926A1AB246B8008D3C4F /* SPDatabaseActionTest.m in Sources */, 50EA92651AB23EC8008D3C4F /* SPDatabaseAction.m in Sources */, 50EA92641AB23EAD008D3C4F /* SPDatabaseCopy.m in Sources */, |