1*082815dcSEvan Baconimport { 2*082815dcSEvan Bacon findObjcFunctionCodeBlock, 3*082815dcSEvan Bacon findObjcInterfaceCodeBlock, 4*082815dcSEvan Bacon findSwiftFunctionCodeBlock, 5*082815dcSEvan Bacon insertContentsInsideObjcFunctionBlock, 6*082815dcSEvan Bacon insertContentsInsideObjcInterfaceBlock, 7*082815dcSEvan Bacon insertContentsInsideSwiftClassBlock, 8*082815dcSEvan Bacon insertContentsInsideSwiftFunctionBlock, 9*082815dcSEvan Bacon} from '../codeMod'; 10*082815dcSEvan Bacon 11*082815dcSEvan Bacondescribe(findObjcInterfaceCodeBlock, () => { 12*082815dcSEvan Bacon it('should find class interface', () => { 13*082815dcSEvan Bacon const contents = `\ 14*082815dcSEvan Bacon#import <Foundation/Foundation.h> 15*082815dcSEvan Bacon 16*082815dcSEvan Bacon@interface Foo : NSObject 17*082815dcSEvan Bacon{ 18*082815dcSEvan Bacon int value; 19*082815dcSEvan Bacon} 20*082815dcSEvan Bacon 21*082815dcSEvan Bacon- (void)doSomething; 22*082815dcSEvan Bacon@end 23*082815dcSEvan Bacon 24*082815dcSEvan Bacon// some comments`; 25*082815dcSEvan Bacon 26*082815dcSEvan Bacon const expectContents = `\ 27*082815dcSEvan Bacon@interface Foo : NSObject 28*082815dcSEvan Bacon{ 29*082815dcSEvan Bacon int value; 30*082815dcSEvan Bacon} 31*082815dcSEvan Bacon 32*082815dcSEvan Bacon- (void)doSomething; 33*082815dcSEvan Bacon@end`; 34*082815dcSEvan Bacon 35*082815dcSEvan Bacon expect(findObjcInterfaceCodeBlock(contents, '@interface Foo')).toEqual({ 36*082815dcSEvan Bacon start: 35, 37*082815dcSEvan Bacon end: 104, 38*082815dcSEvan Bacon code: expectContents, 39*082815dcSEvan Bacon }); 40*082815dcSEvan Bacon }); 41*082815dcSEvan Bacon 42*082815dcSEvan Bacon it('should find class category', () => { 43*082815dcSEvan Bacon const contents = `\ 44*082815dcSEvan Bacon@interface Foo() <SomeProtocol> { 45*082815dcSEvan Bacon int value; 46*082815dcSEvan Bacon} 47*082815dcSEvan Bacon 48*082815dcSEvan Bacon- (void)doSomething; 49*082815dcSEvan Bacon@end 50*082815dcSEvan Bacon 51*082815dcSEvan Bacon// some comments`; 52*082815dcSEvan Bacon 53*082815dcSEvan Bacon const expectContents = `\ 54*082815dcSEvan Bacon@interface Foo() <SomeProtocol> { 55*082815dcSEvan Bacon int value; 56*082815dcSEvan Bacon} 57*082815dcSEvan Bacon 58*082815dcSEvan Bacon- (void)doSomething; 59*082815dcSEvan Bacon@end`; 60*082815dcSEvan Bacon 61*082815dcSEvan Bacon expect(findObjcInterfaceCodeBlock(contents, '@interface Foo')).toEqual({ 62*082815dcSEvan Bacon start: 0, 63*082815dcSEvan Bacon end: 75, 64*082815dcSEvan Bacon code: expectContents, 65*082815dcSEvan Bacon }); 66*082815dcSEvan Bacon }); 67*082815dcSEvan Bacon 68*082815dcSEvan Bacon it('should find class implementation', () => { 69*082815dcSEvan Bacon const contents = `\ 70*082815dcSEvan Bacon#import <Foundation/Foundation.h> 71*082815dcSEvan Bacon 72*082815dcSEvan Bacon@interface Foo() <SomeProtocol> { 73*082815dcSEvan Bacon int value; 74*082815dcSEvan Bacon} 75*082815dcSEvan Bacon 76*082815dcSEvan Bacon@implementation Foo 77*082815dcSEvan Bacon 78*082815dcSEvan Bacon- (void)doSomething 79*082815dcSEvan Bacon{ 80*082815dcSEvan Bacon // ... 81*082815dcSEvan Bacon} 82*082815dcSEvan Bacon 83*082815dcSEvan Bacon@end 84*082815dcSEvan Bacon 85*082815dcSEvan Bacon// some comments`; 86*082815dcSEvan Bacon 87*082815dcSEvan Bacon const expectContents = `\ 88*082815dcSEvan Bacon@implementation Foo 89*082815dcSEvan Bacon 90*082815dcSEvan Bacon- (void)doSomething 91*082815dcSEvan Bacon{ 92*082815dcSEvan Bacon // ... 93*082815dcSEvan Bacon} 94*082815dcSEvan Bacon 95*082815dcSEvan Bacon@end`; 96*082815dcSEvan Bacon 97*082815dcSEvan Bacon expect(findObjcInterfaceCodeBlock(contents, '@implementation Foo')).toEqual({ 98*082815dcSEvan Bacon start: 85, 99*082815dcSEvan Bacon end: 144, 100*082815dcSEvan Bacon code: expectContents, 101*082815dcSEvan Bacon }); 102*082815dcSEvan Bacon }); 103*082815dcSEvan Bacon 104*082815dcSEvan Bacon it('should returns null if not found', () => { 105*082815dcSEvan Bacon expect(findObjcInterfaceCodeBlock('', '@interface NotFound')).toBe(null); 106*082815dcSEvan Bacon }); 107*082815dcSEvan Bacon}); 108*082815dcSEvan Bacon 109*082815dcSEvan Bacondescribe(findObjcFunctionCodeBlock, () => { 110*082815dcSEvan Bacon it('should find function selector without arguments', () => { 111*082815dcSEvan Bacon const contents = `\ 112*082815dcSEvan Bacon// comments 113*082815dcSEvan Bacon- (void)foo 114*082815dcSEvan Bacon{ 115*082815dcSEvan Bacon [self doSomething]; 116*082815dcSEvan Bacon} 117*082815dcSEvan Bacon// comments`; 118*082815dcSEvan Bacon 119*082815dcSEvan Bacon const expectContents = `\ 120*082815dcSEvan Bacon{ 121*082815dcSEvan Bacon [self doSomething]; 122*082815dcSEvan Bacon}`; 123*082815dcSEvan Bacon expect(findObjcFunctionCodeBlock(contents, 'foo')).toEqual({ 124*082815dcSEvan Bacon start: 24, 125*082815dcSEvan Bacon end: 48, 126*082815dcSEvan Bacon code: expectContents, 127*082815dcSEvan Bacon }); 128*082815dcSEvan Bacon }); 129*082815dcSEvan Bacon 130*082815dcSEvan Bacon it('should find function selector with one argument', () => { 131*082815dcSEvan Bacon const contents = `\ 132*082815dcSEvan Bacon// comments 133*082815dcSEvan Bacon- (void)foo:(NSString *)value 134*082815dcSEvan Bacon{ 135*082815dcSEvan Bacon [self doSomething]; 136*082815dcSEvan Bacon} 137*082815dcSEvan Bacon// comments`; 138*082815dcSEvan Bacon 139*082815dcSEvan Bacon const expectContents = `\ 140*082815dcSEvan Bacon{ 141*082815dcSEvan Bacon [self doSomething]; 142*082815dcSEvan Bacon}`; 143*082815dcSEvan Bacon expect(findObjcFunctionCodeBlock(contents, 'foo:')).toEqual({ 144*082815dcSEvan Bacon start: 42, 145*082815dcSEvan Bacon end: 66, 146*082815dcSEvan Bacon code: expectContents, 147*082815dcSEvan Bacon }); 148*082815dcSEvan Bacon }); 149*082815dcSEvan Bacon 150*082815dcSEvan Bacon it('should find function selector with two arguments', () => { 151*082815dcSEvan Bacon const contents = `\ 152*082815dcSEvan Bacon// comments 153*082815dcSEvan Bacon- (void)foo:(NSString *)value withBar:(NSString *)barValue 154*082815dcSEvan Bacon{ 155*082815dcSEvan Bacon [self doSomething]; 156*082815dcSEvan Bacon} 157*082815dcSEvan Bacon// comments`; 158*082815dcSEvan Bacon 159*082815dcSEvan Bacon const expectContents = `\ 160*082815dcSEvan Bacon{ 161*082815dcSEvan Bacon [self doSomething]; 162*082815dcSEvan Bacon}`; 163*082815dcSEvan Bacon expect(findObjcFunctionCodeBlock(contents, 'foo:withBar:')).toEqual({ 164*082815dcSEvan Bacon start: 71, 165*082815dcSEvan Bacon end: 95, 166*082815dcSEvan Bacon code: expectContents, 167*082815dcSEvan Bacon }); 168*082815dcSEvan Bacon }); 169*082815dcSEvan Bacon 170*082815dcSEvan Bacon it('should return null if selector function not found', () => { 171*082815dcSEvan Bacon const contents = ` 172*082815dcSEvan Bacon// comments 173*082815dcSEvan Bacon- (void)foo:(NSString *)value 174*082815dcSEvan Bacon{ 175*082815dcSEvan Bacon [self doSomething]; 176*082815dcSEvan Bacon} 177*082815dcSEvan Bacon// comments`; 178*082815dcSEvan Bacon 179*082815dcSEvan Bacon expect(findObjcFunctionCodeBlock(contents, 'foo')).toBe(null); 180*082815dcSEvan Bacon }); 181*082815dcSEvan Bacon}); 182*082815dcSEvan Bacon 183*082815dcSEvan Bacondescribe(insertContentsInsideObjcFunctionBlock, () => { 184*082815dcSEvan Bacon it('should support prepend code to the head', () => { 185*082815dcSEvan Bacon const rawContents = ` 186*082815dcSEvan Bacon- (void)doSomething:(NSString *)value 187*082815dcSEvan Bacon{ 188*082815dcSEvan Bacon [self doAnotherThing]; 189*082815dcSEvan Bacon}`; 190*082815dcSEvan Bacon 191*082815dcSEvan Bacon const expectContents = ` 192*082815dcSEvan Bacon- (void)doSomething:(NSString *)value 193*082815dcSEvan Bacon{ 194*082815dcSEvan Bacon NSLog(@"value=%@", value); 195*082815dcSEvan Bacon [self doAnotherThing]; 196*082815dcSEvan Bacon}`; 197*082815dcSEvan Bacon 198*082815dcSEvan Bacon expect( 199*082815dcSEvan Bacon insertContentsInsideObjcFunctionBlock( 200*082815dcSEvan Bacon rawContents, 201*082815dcSEvan Bacon 'doSomething:', 202*082815dcSEvan Bacon 'NSLog(@"value=%@", value);', 203*082815dcSEvan Bacon { 204*082815dcSEvan Bacon position: 'head', 205*082815dcSEvan Bacon } 206*082815dcSEvan Bacon ) 207*082815dcSEvan Bacon ).toEqual(expectContents); 208*082815dcSEvan Bacon }); 209*082815dcSEvan Bacon 210*082815dcSEvan Bacon it('should support append code to the tail', () => { 211*082815dcSEvan Bacon const rawContents = ` 212*082815dcSEvan Bacon- (void)doSomething:(NSString *)value 213*082815dcSEvan Bacon{ 214*082815dcSEvan Bacon [self doAnotherThing]; 215*082815dcSEvan Bacon}`; 216*082815dcSEvan Bacon 217*082815dcSEvan Bacon const expectContents = ` 218*082815dcSEvan Bacon- (void)doSomething:(NSString *)value 219*082815dcSEvan Bacon{ 220*082815dcSEvan Bacon [self doAnotherThing]; 221*082815dcSEvan Bacon NSLog(@"value=%@", value); 222*082815dcSEvan Bacon}`; 223*082815dcSEvan Bacon 224*082815dcSEvan Bacon expect( 225*082815dcSEvan Bacon insertContentsInsideObjcFunctionBlock( 226*082815dcSEvan Bacon rawContents, 227*082815dcSEvan Bacon 'doSomething:', 228*082815dcSEvan Bacon 'NSLog(@"value=%@", value);', 229*082815dcSEvan Bacon { 230*082815dcSEvan Bacon position: 'tail', 231*082815dcSEvan Bacon } 232*082815dcSEvan Bacon ) 233*082815dcSEvan Bacon ).toEqual(expectContents); 234*082815dcSEvan Bacon }); 235*082815dcSEvan Bacon 236*082815dcSEvan Bacon it('should support append code to the tail but before the last return', () => { 237*082815dcSEvan Bacon const rawContents = ` 238*082815dcSEvan Bacon- (BOOL)doSomething:(NSString *)value 239*082815dcSEvan Bacon{ 240*082815dcSEvan Bacon [self doAnotherThing]; 241*082815dcSEvan Bacon return YES; 242*082815dcSEvan Bacon}`; 243*082815dcSEvan Bacon 244*082815dcSEvan Bacon const expectContents = ` 245*082815dcSEvan Bacon- (BOOL)doSomething:(NSString *)value 246*082815dcSEvan Bacon{ 247*082815dcSEvan Bacon [self doAnotherThing]; 248*082815dcSEvan Bacon NSLog(@"value=%@", value); 249*082815dcSEvan Bacon return YES; 250*082815dcSEvan Bacon}`; 251*082815dcSEvan Bacon 252*082815dcSEvan Bacon expect( 253*082815dcSEvan Bacon insertContentsInsideObjcFunctionBlock( 254*082815dcSEvan Bacon rawContents, 255*082815dcSEvan Bacon 'doSomething:', 256*082815dcSEvan Bacon 'NSLog(@"value=%@", value);', 257*082815dcSEvan Bacon { 258*082815dcSEvan Bacon position: 'tailBeforeLastReturn', 259*082815dcSEvan Bacon } 260*082815dcSEvan Bacon ) 261*082815dcSEvan Bacon ).toEqual(expectContents); 262*082815dcSEvan Bacon }); 263*082815dcSEvan Bacon}); 264*082815dcSEvan Bacon 265*082815dcSEvan Bacondescribe(insertContentsInsideObjcInterfaceBlock, () => { 266*082815dcSEvan Bacon it('should support append new function into class implementation', () => { 267*082815dcSEvan Bacon const contents = `\ 268*082815dcSEvan Bacon@interface Foo() <SomeProtocol> { 269*082815dcSEvan Bacon int value; 270*082815dcSEvan Bacon} 271*082815dcSEvan Bacon 272*082815dcSEvan Bacon@implementation Foo 273*082815dcSEvan Bacon 274*082815dcSEvan Bacon- (void)doSomething 275*082815dcSEvan Bacon{ 276*082815dcSEvan Bacon // ... 277*082815dcSEvan Bacon} 278*082815dcSEvan Bacon 279*082815dcSEvan Bacon@end`; 280*082815dcSEvan Bacon 281*082815dcSEvan Bacon const expectContents = `\ 282*082815dcSEvan Bacon@interface Foo() <SomeProtocol> { 283*082815dcSEvan Bacon int value; 284*082815dcSEvan Bacon} 285*082815dcSEvan Bacon 286*082815dcSEvan Bacon@implementation Foo 287*082815dcSEvan Bacon 288*082815dcSEvan Bacon- (void)doSomething 289*082815dcSEvan Bacon{ 290*082815dcSEvan Bacon // ... 291*082815dcSEvan Bacon} 292*082815dcSEvan Bacon 293*082815dcSEvan Bacon- (BOOL)isFoo 294*082815dcSEvan Bacon{ 295*082815dcSEvan Bacon return YES; 296*082815dcSEvan Bacon} 297*082815dcSEvan Bacon 298*082815dcSEvan Bacon@end`; 299*082815dcSEvan Bacon 300*082815dcSEvan Bacon expect( 301*082815dcSEvan Bacon insertContentsInsideObjcInterfaceBlock( 302*082815dcSEvan Bacon contents, 303*082815dcSEvan Bacon '@interface Foo', 304*082815dcSEvan Bacon `\ 305*082815dcSEvan Bacon- (BOOL)isFoo 306*082815dcSEvan Bacon{ 307*082815dcSEvan Bacon return YES; 308*082815dcSEvan Bacon}\n 309*082815dcSEvan Bacon`, 310*082815dcSEvan Bacon { position: 'tail' } 311*082815dcSEvan Bacon ) 312*082815dcSEvan Bacon ).toEqual(expectContents); 313*082815dcSEvan Bacon }); 314*082815dcSEvan Bacon}); 315*082815dcSEvan Bacon 316*082815dcSEvan Bacondescribe(findSwiftFunctionCodeBlock, () => { 317*082815dcSEvan Bacon it('should find function with match selector', () => { 318*082815dcSEvan Bacon const contents = ` 319*082815dcSEvan Baconclass Foo: NSObject { 320*082815dcSEvan Bacon func doSomething() { 321*082815dcSEvan Bacon print("Hello!") 322*082815dcSEvan Bacon } 323*082815dcSEvan Bacon 324*082815dcSEvan Bacon func doSomething(forName name: String) -> Bool { 325*082815dcSEvan Bacon return true 326*082815dcSEvan Bacon } 327*082815dcSEvan Bacon 328*082815dcSEvan Bacon func doSomething(_ name: String, withValue value: String) { 329*082815dcSEvan Bacon print("Hello \\(name) - value[\\(value)]!") 330*082815dcSEvan Bacon } 331*082815dcSEvan Bacon} 332*082815dcSEvan Bacon`; 333*082815dcSEvan Bacon expect(findSwiftFunctionCodeBlock(contents, 'doSomething(_:withValue:)')).toEqual({ 334*082815dcSEvan Bacon start: 203, 335*082815dcSEvan Bacon end: 253, 336*082815dcSEvan Bacon code: ['{', ' print("Hello \\(name) - value[\\(value)]!")', ' }'].join('\n'), 337*082815dcSEvan Bacon }); 338*082815dcSEvan Bacon }); 339*082815dcSEvan Bacon}); 340*082815dcSEvan Bacon 341*082815dcSEvan Bacondescribe(insertContentsInsideSwiftClassBlock, () => { 342*082815dcSEvan Bacon it('should support adding new property inside class code block', () => { 343*082815dcSEvan Bacon const contents = ` 344*082815dcSEvan Bacon// comments 345*082815dcSEvan Baconclass Foo: NSObject { 346*082815dcSEvan Bacon func doSomething() { 347*082815dcSEvan Bacon // ... 348*082815dcSEvan Bacon } 349*082815dcSEvan Bacon}`; 350*082815dcSEvan Bacon 351*082815dcSEvan Bacon const expectContents = ` 352*082815dcSEvan Bacon// comments 353*082815dcSEvan Baconclass Foo: NSObject { 354*082815dcSEvan Bacon var Value: String? 355*082815dcSEvan Bacon 356*082815dcSEvan Bacon func doSomething() { 357*082815dcSEvan Bacon // ... 358*082815dcSEvan Bacon } 359*082815dcSEvan Bacon}`; 360*082815dcSEvan Bacon 361*082815dcSEvan Bacon expect( 362*082815dcSEvan Bacon insertContentsInsideSwiftClassBlock(contents, 'class Foo', '\n var Value: String?\n', { 363*082815dcSEvan Bacon position: 'head', 364*082815dcSEvan Bacon }) 365*082815dcSEvan Bacon ).toEqual(expectContents); 366*082815dcSEvan Bacon }); 367*082815dcSEvan Bacon}); 368*082815dcSEvan Bacon 369*082815dcSEvan Bacondescribe(insertContentsInsideSwiftFunctionBlock, () => { 370*082815dcSEvan Bacon it('should support prepend code to the head', () => { 371*082815dcSEvan Bacon const rawContents = ` 372*082815dcSEvan Baconfunc doSomething(_ value: String!) { 373*082815dcSEvan Bacon self.doAnotherThing() 374*082815dcSEvan Bacon}`; 375*082815dcSEvan Bacon 376*082815dcSEvan Bacon const expectContents = ` 377*082815dcSEvan Baconfunc doSomething(_ value: String!) { 378*082815dcSEvan Bacon print("value=\\(value)") 379*082815dcSEvan Bacon self.doAnotherThing() 380*082815dcSEvan Bacon}`; 381*082815dcSEvan Bacon 382*082815dcSEvan Bacon expect( 383*082815dcSEvan Bacon insertContentsInsideSwiftFunctionBlock( 384*082815dcSEvan Bacon rawContents, 385*082815dcSEvan Bacon 'doSomething(_:)', 386*082815dcSEvan Bacon 'print("value=\\(value)")', 387*082815dcSEvan Bacon { 388*082815dcSEvan Bacon position: 'head', 389*082815dcSEvan Bacon } 390*082815dcSEvan Bacon ) 391*082815dcSEvan Bacon ).toEqual(expectContents); 392*082815dcSEvan Bacon }); 393*082815dcSEvan Bacon 394*082815dcSEvan Bacon it('should support append code to the tail', () => { 395*082815dcSEvan Bacon const rawContents = ` 396*082815dcSEvan Baconfunc doSomething(_ value: String!) { 397*082815dcSEvan Bacon self.doAnotherThing() 398*082815dcSEvan Bacon}`; 399*082815dcSEvan Bacon 400*082815dcSEvan Bacon const expectContents = ` 401*082815dcSEvan Baconfunc doSomething(_ value: String!) { 402*082815dcSEvan Bacon self.doAnotherThing() 403*082815dcSEvan Bacon print("value=\\(value)") 404*082815dcSEvan Bacon}`; 405*082815dcSEvan Bacon 406*082815dcSEvan Bacon expect( 407*082815dcSEvan Bacon insertContentsInsideSwiftFunctionBlock( 408*082815dcSEvan Bacon rawContents, 409*082815dcSEvan Bacon 'doSomething(_:)', 410*082815dcSEvan Bacon 'print("value=\\(value)")', 411*082815dcSEvan Bacon { 412*082815dcSEvan Bacon position: 'tail', 413*082815dcSEvan Bacon } 414*082815dcSEvan Bacon ) 415*082815dcSEvan Bacon ).toEqual(expectContents); 416*082815dcSEvan Bacon }); 417*082815dcSEvan Bacon 418*082815dcSEvan Bacon it('should support append code to the tail but before the last return', () => { 419*082815dcSEvan Bacon const rawContents = ` 420*082815dcSEvan Baconfunc doSomething(_ value: String!) -> Bool { 421*082815dcSEvan Bacon self.doAnotherThing() 422*082815dcSEvan Bacon return true 423*082815dcSEvan Bacon}`; 424*082815dcSEvan Bacon 425*082815dcSEvan Bacon const expectContents = ` 426*082815dcSEvan Baconfunc doSomething(_ value: String!) -> Bool { 427*082815dcSEvan Bacon self.doAnotherThing() 428*082815dcSEvan Bacon print("value=\\(value)") 429*082815dcSEvan Bacon return true 430*082815dcSEvan Bacon}`; 431*082815dcSEvan Bacon 432*082815dcSEvan Bacon expect( 433*082815dcSEvan Bacon insertContentsInsideSwiftFunctionBlock( 434*082815dcSEvan Bacon rawContents, 435*082815dcSEvan Bacon 'doSomething(_:)', 436*082815dcSEvan Bacon 'print("value=\\(value)")', 437*082815dcSEvan Bacon { 438*082815dcSEvan Bacon position: 'tailBeforeLastReturn', 439*082815dcSEvan Bacon } 440*082815dcSEvan Bacon ) 441*082815dcSEvan Bacon ).toEqual(expectContents); 442*082815dcSEvan Bacon }); 443*082815dcSEvan Bacon}); 444