From 8eb5089b76c907c0fa98674b4f936865d2958f41 Mon Sep 17 00:00:00 2001 From: Brian Vallelunga Date: Tue, 17 Jun 2014 17:57:26 -0700 Subject: [PATCH 01/11] added front facing camera --- .../xcschemes/UnitTests.xcscheme | 53 ++++++++++++++++ .../xcschemes/VLBCameraView.xcscheme | 59 ++++++++++++++++++ .../xcschemes/xcschememanagement.plist | 32 ++++++++++ .../UserInterfaceState.xcuserstate | Bin 0 -> 12120 bytes VLBCameraView/VLBCameraView.h | 1 + VLBCameraView/VLBCameraView.m | 24 ++++++- 6 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 VLBCameraView.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/UnitTests.xcscheme create mode 100644 VLBCameraView.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/VLBCameraView.xcscheme create mode 100644 VLBCameraView.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 VLBCameraView.xcworkspace/xcuserdata/Brian.xcuserdatad/UserInterfaceState.xcuserstate diff --git a/VLBCameraView.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/UnitTests.xcscheme b/VLBCameraView.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/UnitTests.xcscheme new file mode 100644 index 0000000..af5c4a8 --- /dev/null +++ b/VLBCameraView.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/UnitTests.xcscheme @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VLBCameraView.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/VLBCameraView.xcscheme b/VLBCameraView.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/VLBCameraView.xcscheme new file mode 100644 index 0000000..71428b3 --- /dev/null +++ b/VLBCameraView.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/VLBCameraView.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VLBCameraView.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/xcschememanagement.plist b/VLBCameraView.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..da9034f --- /dev/null +++ b/VLBCameraView.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,32 @@ + + + + + SchemeUserState + + UnitTests.xcscheme + + orderHint + 1 + + VLBCameraView.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + BDFD0A8E1789800700DF1A90 + + primary + + + BDFD0A9F1789800700DF1A90 + + primary + + + + + diff --git a/VLBCameraView.xcworkspace/xcuserdata/Brian.xcuserdatad/UserInterfaceState.xcuserstate b/VLBCameraView.xcworkspace/xcuserdata/Brian.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..fd9b03b128f20a38da67068046830a8bffd27278 GIT binary patch literal 12120 zcmcIq30PCtw%$WX2xMf)Kp+WZ00(9iwQ6Nl6c7PXoYDvZQz5}5SiNey(^)%@cCc2! zv9`8WYpq&qoo#EaRXYz}JKWZKz1BL^+Ui>;hXmra_x1bUyYNAB&R%=%wfA28U;kR? zOmAy(dVN`0M-fH@Q6xYSNGM1Vm?oNMJ3L;e+cnYbo_@2V!RM_v+dU04oN&9=>~pup zAbj_-mz6jZiBKepMR6z|^+A16Khz(kqYRXZvQRe4L8DL^8jZ%Fa#VpT(O6W4#-VCd zgKE(vG#TB5W*{fJ8O=m3$b$cibBoo=CT(OvXidWe2NkJ4lG@AL%yhJH)W(4Xm9`U|~8f1{TLQh`h$7bpZuL5v_) z5GRNis03<(Mvyq(>}qdmIfBF}3PmFclB1Xjl{FbN9do^t;IrE|>&y);cCWV+Ns){Z zMmv!LDVcyBVNRLMEd2;nfC^C& zd@DhvOaqIbz;rB)&4h10*3MFG3RQvE3*cvW`AQm{KDWnPZlCLJ_t_K*FtTQb`<6=k zY-h6_S|-B{u(#Yk-O*xGq;qo!I!f3|kM}uSoW8jQ9*4aKfYn#$blk$L3#sDTu37Ui z6~zv(v)OeW4V*!|ey79Bc@cCgb+$OF?7kUO;gX*N*HMAQHif*dys!uy%wy+_$Y>3& z<9IXyrFEb>me_$NvLtRDl*M(mA#=-oj#lr7fx|Wh**eiwG>z$*nOTDh?5GjNbfW2~ zff<;w6FE>5OJ*s|G!@kJb`%9%b7NQ7n_W&{d!wVuG~)J&i2L~vwIUaCqqa%>xpje| z6Zx+W@07}#VkbD5+hzC6?F6Y=6Dw=R24Yaq1}~a@jSX|a1`9KpM!1c=MwpKlOslM^ zX!qH{`3gK9``j)xAKi*(0fYoDc|#cT+Z3@O!Jg5(5aY%V4toc>2c>nPJJDU}Zq|qO zW&OI)y>PjR^@qy|+*&40Y=A?R0sAq=>B|W1dPbSo+wOpasH}0cKrnSQhMH^&w7$Y!Dj)pEt1a@V}0;mphLo9*^4tuHTLDSEHkmpCQ+c^Hgu)+}gQqaNy&)8)0(>?cH5N>NwGE zl!CzkYp%7%rikf1{78?xz0Dg5m_2VE07Vvu894(0J@WIj7cAhtcRhM_85_)R@J93+ zcvZI_)Hr-yXd~K$W{t0`feT)IbGJAbWws()2inGlGArNq7P57r9q4VelMQ2qtfc2K z>_PiEN8F3{vEl5-PILgh!$zo7O*)TV=l*6CQaM}NGmC-t`DLDA&=&P{7zedMdDXV3s zpujii2b8uPeT%+B-=lx9k!%zzW22X&AJIwl6FSAluyL%K)dZlUu{%zdyBqA>k@ePl z+owAN&R*+-U7g$n(Wb)T_1c>q{9^us&Uc`5tejPShAyIC(Ixa7x(ti{JNg4%L02)t z@Po!-f+-f@2>26D4vsRux*YZ#Alu^uPX+gBZ*^6+w@&BcQjEjZ_-{9r4KwT>JDfL9 zwcXY1D0jF3j$68IEpfqFg)VT5?_2J4Ie2yTK4+@~#%XN>#li7Nl^@puxP z=D*_#$9_Us9Hyht(d70xLOpnui5#32Rn++GzIJb@ts65T>T=E9XvcL3&MgP$p_mSw z%cgbU0nEl7bWXI+-U3mfAYg7#bTGaF0yG}NZtB28nVqGEgGf+p1TI2powxuUVAI(M z_<{@I%XF4n6_hB$V?tw=v&PW*#$$06N?W!puyEJn=iuBB<-)bNE~H=rYwl4n2~P=` zIF-#{slg#{!qYi&ae$5JzzxjV)6j%xa6OvY%^d+dVbA`Apx{>Q=5%lb1-G#lmdg8$ z7cdz6a66vOTA7>83Slswi|2=tfkF6IAcHQB47801kb$6ix8u9QB!}XAn3}b5lJ~JN z$@}nwy(RHO_+jQ@UT)twav0)a9Nh{HV^fU&|2ykJo1etXAm-!6_$mA}eg;2_m*D5{ zQv5ud&2C|H*j)BEHjm9`3)rm?^KmEe-Qj3BUWr%X)p!k@klTRoYT$P*+s@u%`?yV4 zZ~?m5F}=OH+2P^&s0t><6UabL0PgK-w0jykUdajbO>oZY_?iHJUDH0j70Aw{UL6&& z(4*MVWN&Zr1xDc28@q2+aoxQ>2=LVa9}X{k;iCosYS5q%6P?r&pyR!d(QEj1&W$!P z)`2%OKQ|c*KYBNH|FZ#ttGNwt=M=ojZtuWvu{&65ZH3+G3byXT`%p|5-i`O*z3fhQ z7rVO)?}ycVhus4!xQ5&PK4HUgFyN?xEWyq_;a?9En@ev``H8RLH5up{3ZShe~p{r z_XPfiJ1EsOWHnFMLB_KX_1t7A_;G z45X^sAdFt8O&4q{nFIUF6^?pxfyu$PK>XIWwNGzxHgu=%kVmFBq@LqvH{KEMaxSpe*IfJuu7u3(o&dtx|xactgbsZE< zC=rkdA|xUbiH5_e3z`^=(9?Prh|A#u60P8kJ-4}38mRT0u}#6gJ#DO$Jn85GGNnKnflEKt~v^sH9+ zaqA>moVvd(Z&O%9Th8T~{GkpyNk&cJG!+3hA0fHmiFqWI3?vq=ZZ_TSbxej&kD~>U zceaBewwiVEvmH!^Kt=>-w37_(=6+--;1L8A(QgH;rbmuub4Tn_23_az|63Fj8ObY@QMLHi<`Xz8n=u7=y)= zPz>pYXflq}al=%T8d6Kfv-Rv%wt;P24himXQje?v3mWzsggl50x;i_gOM3J)t?6|zm+32^TG%XxsBW&CRs%8gdKV_AlcTN`jC6cLY^H4ExMmP7_#Ug zwj*fKqnt&Lk;mEFY_Zu<2{Mv43)5`ko`0}T+VhcKQdR= zgj9)d(X{cA@EX}fUWY-}ku3o1ThX|Q@D!w_(c^H{wb|jn zZ*l{t*X85(AAF~=J0&VaR!MGjPwEfkR9k9Gu|ZI`Ix~Dv3Gcg=e=qd2iUvG z9O_2&)9SS;O#m(^D=_KEAsP|XJ`4Rp>ey}M_e_@19@*}7HuZZ$<`3dHN zG*G7x9o&DBOTfL!8S*nZOMW5e$a!*sTqM7;kJ!iT6ZR?ljD60&U|+JY)*vgn49oim zxk9c|1aM>m5c-;F{8;bD$$p&f#~A=l@BjdCv=Fj}nQd;T%jXSL(t$)a0wQ&jWZoeI z49yE=9>8OO8#R9lAj0w$`a;JHpq*~d6uuN+(=fxqJxqw>FRR;K09H^V39xI(wSu96 z?+p4hd|u3t6>RMus-Uf{6nxlQ=BjYIoS}h1d)Re1gmuFNl~E-mq*RViu;XlHCyk-8 z?C*Z8S#dosLSSeqSqCeZ&nqEJ(TEp7MK+C9yV?q?E3++!_xUT_`p zAT@2G~O2kRzVTyufWnU%wDO+d z?5EJ1ptw(`(rMJj&a(^bVi&ce1GItt3e@xxOReKKw2t2%n|C`Y_b4Jf( zzlA`Dx@bF;!Kjg0Hd|*}aevJKC27s;sZuK1J zf~HVS-5A(uDAWO?@%ZK%ivVSsxzGdtp$+;@xKNJjqW97J=>zmZ`j8(JKNk3L zgdYq2Smei%ek}ImC_j$&V~HP2xhj4%eUv^%AFl`I>kZ^7eoO(+aIvGU#XXmM&^v#A zaZPRY*s-;NFhifDivc!!o*4u>b;0eY0*|BkWGATi*?=}}n6|RYn%aW$a$8kF?WmyK z((B08j47+KbqfdOIs$U$FnwTLk6=l$t*Ux#@%SRJmY>@4Ko?V3m)e5rktMYt3x&qA zq7qwaK}A`4eXz%>Ko2#Bs`gC4g8B2u){ZKvwv`u`mKThy2}->XkV?Q+_J*1E=73yT zW$D z7+XzAL3Ponz^a98*bwNG4`B%k%H`#C6~=)XS;ll@Ih6F<;km;6`6G*pU_nZX##U5; zN!-`cvWd1)B?ZML)j&G#E9M?(r(*u62^5cZ?X!t%C4gEOw zzmXL8j=D$qapM0AbZbJ1;K>$~*(J2j+8So}kWi z^a96C&ik>UgI@GwBUJ1Id4H>eM~Q3e7lAif=k=2l$)zFlilig^~ z8PJ&1l$Dd;FlfN^{Dz#S{3b}JTW9A(s$Ru)o6Pridk1A?1pkQFJsdhZmu2)J_}VC8%b2 z0cs|^0_BDX&FI_oJJ`M~LAAgoSSaWatP{K~*d^E_*e5t3cvo;xa7b`ia76IE;0M7; z!70IM!5P6>!8ySN!LNefB4Q(~5jhdlBibXDN4y@fH{xi-M-d-K{1|Z|;!?!rh$})Q zBtn(YAT$fD!ZcxDVZLyvaJX=UutYdgSSB1JtQWQjTZOZQw+R;s9}_MUt`M#hZWZnj z?iB789uU4OJSaRQ{6zS7;ThpY;Z;$jNH4O8azukgH;9IbZWNV@Mu|p?%0-nTm*{rU z3el^gJ)(W01EP0D2StZOhebz3$3!2CPKr*6PK(Zn&Wg^7E{J{={U-WdbR|+7nHD)T zvMSORc}wJdk*gxNMZOt%H1f;HuOg2}{up^7@((c;OT<#KT&xl6#7Sa&KBp2 z2Z-~<#o{vY7;%NTT3jox6HgRR7Ecqmh+X1&VkW*_e5ZJ!_&)Ii;)ldPihmOSD*i)! zH3~-wqavfCq9jq;sFWyklr<_Xs&7{A;DSA`%ThX6JACLY`qL64M zdP%AzP108~TH=(vPrU8vPH5@vR$%6 zvQx5K^10-yG(%b;wMko~Zs{zkPdZyVN4iM5So(}~iS&7ChqOz&Ub$EDv$zmxtTJt;jUy(IljdRh91EKZgzGs~>9KC*tYblDKuFxic=LRqn_ zR8}LalTDOOmQ9t}WGyncY?jO?n=P9oTO?a7dq%cI_Pne^)+KvUwn6rq>~+~2vaPcH zvV*civcs~EWS_`BlYJrkPIgvyQFcjoS&rmHE|3f5a(SXWS#FYBlvHB&A2WNcouZN##?@XOydyo0OZCTa??B+m$<%JC(bYN0i5uA1gmqey;pd z`L*)z%5Risl)uNQWBSF6jB&)wig_UBnV7Da6)~$~*2Juh*%-4aW^>Gzm~AoJV?K>V zv9j2Ku{Xw+#n!~mh@BU^DE7J7H)6NOz8U*g?Ax)sV$a83iHnF6#fjsh?vo8rHYKNWvYg;Yc(PzhCXRlF)eWl~vHX{x@e0#&7If~sCMSv6HU#Ag z^%S*J-J*7>XQ{pFcJ)H_lj^6{&#ITIm#I6|Yt^r)UsZ2ZZ&L44?^nO0eouW^eMEgs z{jvJE`k(5v>T~J~>dWds)K@iF6QxmWG#af&r%BWF)1+&%G&!0)%`i=&rdU&|8KoJo znWUMbnWkybI5f=~r^c(9uUV*hQ1h_nQO#n_)0$^B&uL!PY}Opme5LtS8>@}is@^Ar3D zYZEpme3tOFEiE9(rCBBll zA@Q}u*AsUq?oHgE_)d~G$(odzl%15DG$1KIX+%2 z^lS8c^zZ8r>yPM<>A%;X(Vx|y(_heEG7y8@pfYF-35G<2$zU<08u}Re8FCDR4bu#N zGu&ag+i_ma;hUrxS~qDe_kF{c!yj83UYnUOLp#h0=qWkt&BloKgG zrJOb;nXIN%Qy)`~soGR;nrnKdfZn0A@=m_9TeHGO3I z)SPY}VjgN9ZZ0rCVeT}qHNRwj*}UGo!Mx4avc712*}C4k!Me@5 j%evQk!1}KBp!I9(x7L$^A~b^Me1RWx1RbR4>Jwy literal 0 HcmV?d00001 diff --git a/VLBCameraView/VLBCameraView.h b/VLBCameraView/VLBCameraView.h index 7b94775..ad1522c 100644 --- a/VLBCameraView/VLBCameraView.h +++ b/VLBCameraView/VLBCameraView.h @@ -174,5 +174,6 @@ extern VLBCameraViewMeta const VLBCameraViewMetaOriginalImage; @callback on the main thread at VLBCameraViewDelegate#cameraView:willRetakePicture: */ - (void) retakePicture; +-(AVCaptureDevice *)frontFacingCameraIfAvailable @end diff --git a/VLBCameraView/VLBCameraView.m b/VLBCameraView/VLBCameraView.m index c67518c..d8e7708 100644 --- a/VLBCameraView/VLBCameraView.m +++ b/VLBCameraView/VLBCameraView.m @@ -137,7 +137,7 @@ -(void)awakeFromNib { NSError *error = nil; - AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + AVCaptureDevice *device = [self frontFacingCameraIfAvailable]; if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) { NSError *error; @@ -247,4 +247,26 @@ - (void)retakePicture:(UITapGestureRecognizer*) tapToRetakeGesture [self retakePicture]; } +-(AVCaptureDevice *)frontFacingCameraIfAvailable +{ + NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; + AVCaptureDevice *captureDevice = nil; + for (AVCaptureDevice *device in videoDevices) + { + if (device.position == AVCaptureDevicePositionFront) + { + captureDevice = device; + break; + } + } + + // couldn't find one on the front, so just get the default video device. + if ( ! captureDevice) + { + captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + } + + return captureDevice; +} + @end From 95c191df1fd25b75d4e645097d42f542dfb33604 Mon Sep 17 00:00:00 2001 From: Brian Vallelunga Date: Tue, 17 Jun 2014 18:04:35 -0700 Subject: [PATCH 02/11] fixed minor error --- .../UserInterfaceState.xcuserstate | Bin 12120 -> 11327 bytes VLBCameraView/VLBCameraView.h | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/VLBCameraView.xcworkspace/xcuserdata/Brian.xcuserdatad/UserInterfaceState.xcuserstate b/VLBCameraView.xcworkspace/xcuserdata/Brian.xcuserdatad/UserInterfaceState.xcuserstate index fd9b03b128f20a38da67068046830a8bffd27278..2726c95e18a67c81358e99990151572bc080cf9a 100644 GIT binary patch delta 6834 zcmaJ_2Y6IPw4Smx+wbn(yS;-UM0yiM5~{Qygg`=sWRolq2}wwy!=9xh7GRN%kU|L& zY0{e_B3%STK@=1V7Emm7_04WbFuwOa^09a3+?iAVIp^H@Y}ldH`Mii;rk^h`H^SZp zUD^h7(MxC)%0r`3J}N+kXbdVs6VWU*A1y#j&?+<&y@}SMDzp*3jW(lgXgAt}4xsnY zQFH>GLFdqC=n}e$uAv{%Pv~cK6WzuXi?A3=uoTO%9LHb<7O)AMu?1VP4coB;JFy4H z;wHESZWF}qaR=N9C*bb5C+>q^!2R)1JPc>xOzg*_aXv1F^ z{0~6{6GA8v5itoWh>~zbPprg7?8HkNk*1_I=|DP>1Tu&WCaENi3?b>{MKY8OBN-%% z3@5oHj}(w1GM-E&v&d{Rhs-An$U?H5tRO4NDpE#vk=9zq zThKQ2S=y04N1vxXX)oHF_Mv@gf9j`MG@Ito03A+8(3j|VI++5UPG`}%^cDI#T}a=c zOX&*wCas|B=_dL%-Av!3hw1zD2-SZ;kJ1n6F?yVypeN}mdX`=cmyze_5l9JtO{S^d zhh!ii0W*7MZXZJ@l#0^O5R{HyL_@&}Hn4*OoZtdCc)(kQGEgRJh`O`C927vqkr#Z> zo@v;a{bj=xm>N-jNS=Q}L21drqCg-+YkaI%SfhQ#$MlXU-8GO^I$}g1s_6w(j7m@` z(_<_ehsL7`;p3*>t~P+60X%aNO+u5|t0`zI3bNN@(KIw2%|J85t;|V|HqcIsp`jLi zf@Y&RY}s7&GMa~8L9e3MQ1|di{Q!9jh=tbh6f_RMuWvgXEkuheP#7&jZ$Kk>8k$1$ z^Jpnr#UC^hqnp9UV{2VSf(0>WY!8M+A1LT31owrK*ojIKn;pF_to^aVTznFIU!bMtFAeTBY7Tm||XT}R(Q zCrE(A3iKWG-3{o>eCKE9s)^1&5Z#LC_6u~01iJ?Dzo7>xc0KwX{ek{OchFsQ58a2Z z&<(mn4|pDWLa+7cA$o-VVz5|_5ysFP`oJKDhBz1s!ex_liIZlKV#Ii!~^hP z6kCat@j#q{2SE-5U^tAZ#Hlz955eg$67pdpOoGhRK7rvSk#rcIZ!~ou(kGg?`WEB_ z(gx&?7#V$28`Ug4BEmBp=imSy4!Q6WjDoyMXk!@7GGS);l5uh_E<%gf z)Bz5c;&BYecq|l@;qg!inHgGL*Fgi53-fZLLVA`2Mi%Y@f182#=uyZP%Axz zXCST|Ps7up2#U+`Ogsxppp;>#x5OQ+GsBxO2~gx;?Y>v>{CfKq;Ds;_#zV>z1KFO! z=$@JYEWt~M)ww^KWGe8InluwVJa{=?8L?#rOfEy+nbDaUL9MP!L4I*TUZ8t!UP+)R z;=o!3%5XV~U9$!)x-cDsIgnWsl9LfVPT|uq z7hZXy$60*79?J{(6L=ZsLCOo>glVbuq+iBg{AcM^w)9m<@g@|w5NgU6*Q#(Ge~)4- z@HhBd{2jaw^I<^+zJY(hKf*#-2kRs5a)tX#h44zLJe)5zhF_36>h%8=-$k+O@NN7X z{vH2;|HOA742$3mSPV;G={kH5-^UMF4tm7u_A*!vYZz)P*?-2=5b@pkLO-i|IZ-r5 zs`oHP9F$v}%MRiIR=`*tWQ62E9vcU8YRbEtQNmv-^J;Y<5+Xxf8Ii*BG9rf+kW#a2 zkUy_9P@GsC+4a~~q9PjRZlZ>jWkd_BAoIWFFbX(gAOealCp=mQZ$c9`AUqqq37Iea z>+pwVYJHG6h^tPx8_FQ1R+Nu4tP}MVl-I$L#F2RRg0XH=MxKU>Coh_j7LgarA+9Vc zuNJ_h4QW>=;~7}{M8>lU(y<2XPhzAUKoUuB)?Sg$_&3s(bR*qK5Arpw9EqZoIHpyXy;&JLs4wO_dN&r=|B+DjIERzwBm$RZxUc$jOFrkJ%`d{?I=(yH( z#iW!uBAUC%SlIpeP>=~YSV1NR$s{rv_P~BPRCh8+kWBkG+{tt@1NOqc2oxf1YhBA4 zX;i%lg$e&YD`YNtrQYUO$!l-`4nj)(2G^S~57<6$-N_+gvbf&HC1feQ3-7Tb-b^zx zII_mfHzU1(iFMhvy#OgEZ$-jWK`O~wvW~1L8%Pz|NUGrjI0_%aF*pt<;3S-a(^aS; zc^h>nTgXYDyF%E_LR52}Iy2)&6&B>?mlP*vmxQNVk6Ork z#c~VPs7h}ljZgB8b{+MEg6DnEBFeZ;7_(gnvM4g?>v2XWOCpmJPrM?+dO4e9 zXxoNwdpzOO9&>cTs>p&{p61es)~o57aGKX8t)OMJoPErsd7txD(zW$^9lC*TWXPmd zAJZj5m!~xF_1QvqBW^w2O1IJN^c}i`?xedym=9rN2n!)>3Sn~yTSC~no_%b4 z={~xj9zYH0A(n2EL)aF=_7HXeTjON7{h-11AU%zPWk|*D4{Fjm{g`EEjL9i_fqkx= z3tS*p8ChQWW1#QJHQF^fJliuv= zq#wIHNoM#QOw;H{T18LOA4Dcmd(j}#7|~qOVo{Z-TC_>DS+rHOU9>~AOSDI{Pjp6f zR&-8uL3B~{ndq|Uis(zxHPP3iTVgEMh&zb~h(qE<;tKJ8@fq<)LGcywFXG$c-^G85 z?~3n>ABz7H|0BT?gTyE?Nh}hZ#36A>JQAOzp(Iw)Qqo5FLvmblMRHS0 zq&8_==`+#}(vH$j(p0HmI#OC9T_UZJu9dErR!OU+o1~kiN2H%hzmwjV@iIYXmRV(X znN!wZHbfTm%d%ww*$7##Y^*FKn=P9wn>s&I&dUY4S#Fg# zlDCn!led>YEAJ&wmZ!@z<)h^jF_U5z#Vn3l z8nZlRWz5=`4KW*I-ip}~b2a80g<2sfIx0FVMg|q7it&nxiYbbqBBZEN>{RSg>{A?6 zysJ2@_)u{{@wws)#Z|>uiW`a_6+bI(DSlPjl&zF~lqt$oSL1u28O0u2z;QE0k-M+mr{Dmy|bEa@A9+ma1;50jhM>P*sM?ugX>h z^Hlk&LRFEfL^W2mK($+SRCP;rS1nSD)f%-)-9R0u?xapscTsm!_fYp#4^XG6)73-O z8EU^eUtOp!QkSSh>gnp4>e=c=>c#4%>gDPU>K*D`>OJax>TlGy)%P`GjZ`DoC^QC* zMdQ@OYM#?{(XT7e`}GJXhm9&wv#qXJ4ri3J5xJbyGXl4yG*-M`=)k{_8sj3 z?P2W^?NRM9?I+sH+AG>Gwb!-ZYQNY1puMY$(dl(IT_ar+T{B$^U9he08C?fmM_muy z3%WGjNL_($vM#6#>1OC=>E`HG>Z)`bb=A5}y1lvsx3BbZOJH;w~tCO4a# z%gy7K2Dw$-YOai1$8F#?a&K{)xSibl+%fJ1cZ&O%JI{T>eacgrr{UEBf~#D=0&`Om+?Gr;w`+Lck*t&3E!M=$+zL#@$LB@d@sHa-;eLl zC-a%SpU>iR_}Tm-em!5sSM!_r&HPq=JHLb9#qZ%y@n`t6{J9{1fxpOq#$V>I@L%%R z_=iS~(Q9mB>}4EgoM?RAxX!rQxW%~5xX*aZ_>u7wEczpYZM!RoL!wl=Xg zv$nLhwzjo)wRX2YZ|!AWW?g69Y~5jZMJQ-9kjh~`@r_0?Ue0|?X2yb?V9a(yI^bCYwY^R)A<^Stw-^OEz5^Q!Y}=eN!q&YzsOoWDBnyQoXz zvb!3(+PONpo_F-u>uK)k?@9HH_q^s=;aTZf=k*XUZdCKwRr7bm)GlU;Enahd0TsvyaDe-@9W+T-fiAn-aoyM ze6r3yozLJi`b<8zFV+|5i}yA4HTON|OYn8}b@dJMrThHRZ!APe&69pv^Q`^#W&aPM C+8hD^ delta 7592 zcmaJ_2Yi%8)8F#s`aM^3Jy&uip@mKWDG5~|gph(~BMA{i!{v45qn z0qcI%Ha?IJdV@Y-02mCs-~%uO)Fa~@Mz5ri>$zUN^1QvrOU@7-hU|m=b)`#)1DQpE>!;bKMm<&^48q9=l=z&9E9`wQCkia0E04Kt! zFa*Db-@s+?d$=5~fIq;Ma25O!u7+#iMz{&?fIHzKco-gmN8t&06<&jX!N1{kcmv*q zx8OhUDSQT>!x!)+d<9=4fC3^UMhb|K78#KR*^vXqq8g|Us*f6=rszG?8YQ44)DzQp z$IwZ13Y|sg(Is>Z-9Wc7gCj5x^8;9bg;<2eSc0WE5^JytTd@t-!Ev}Qu7~U6c-#WF z!|ibgoQ%8S6r7HG<38Af2jN^i7<+L(9*sZ70ZecZkHKT{SNIz|1JB0ua2Z~Rm*8c1 z1zv^M;PrST-iCMKgZL;uhEL*C_)mNZ*Sd_a;5+y(zK8GQr}!Cu&PW-Skuh>c!6+FO zqh=x*4Wngrj43n$wZf-}J@hjgBRxr)5JY%HPk&=pXW~(?y^+L{A#|Xal#m#=T$AYc zd;P^(1;y=iyv2n+e^S1lhzwtYyFh1`!*HrYpEEw*^w{31fNz?(+-C2L+%I6!msw=Vkf* z1zGu?UKNiXf8XS^cHZn_Z(%`}Z$ug88rmy4t=qs4JlVxndi-G6f9M%b^*D*$o=|9g zOT#EIx_@$7*OKC_fq9RTL+aFJw zlIHaHJ<@~z&!B2AMjB=P=^kcy{a(7%RH{7mJo0NO2u;?Q0$>&RaXx8QvDP(UE%k7v zPtrWa|p^ z0sFa4*$eiOR-|QuUx~c6H$nQR=YT|F;{5umbfQzI9NhkIyhRfh@5W4_e0aw8_@E7Sw z-Y1<%=LO(8xB+g0Tciu=PEtu4haE*uVRlKrr=U2gFguHjJ%6UZWT4mYFY)-(i$@fB z`V1<`%j@b1`2AVAo(fmo2MCUyYLZ*7reO6Idkb>g7Uq@Y7bKVD5A^ula;2vr=f4IO*@LruS=oVNk1sW= zAlH-RDWJg4tF*R#L3SZGhYnRtPVyFbD&%Drd-FY1QGOAXT&3{MYr6Cb$<=}jvq@LE zKn_VaxtSy@BKo=I-3NK|Jk9IYt=l8CII3xAn~-f4mv2w}sk@n#Ye8YLbx>hRK~8sXg)r@#IEIGs zb7f?}DChuJ%Da%r^^=;=O>r%HGO*a#>~VMEft6gDPqE|59ajI2BwOo{%tS)0N4Xm*9o z$$(PWf@D$glhu*!VFGLmV#{D6I6wxH1o{9I>BB%0lTxLl6YNs0BZ=fx$2{x?Q$Xze z`Bc(2wRr$chZ)s;JxT5xzTU8JwdQ_gFo~&>JOB>l68-^_Pztk&_sxqza4`xEcYANFIr)aKE3X3RnzF;4qR;3dzvwQ~^i8QSapMrto8;A_ZLj zE=maJ?<#A?z)#=dYyrm;Eh*wSCy@$HYen&ali-(cv%<-63h@y?Ek1{|gF~YYf&iQb z=hMUsr^9dI3^)_cg0tZqI2X<%!^nqZI2l1cA|uHtGMao$6E7?SF3<|Jf{Wl{xCAbx z5fGroR!9Gqk*#DK*~cXgIagTQc?Oo`=6ZZw@uYRQx|nt?%<;I>XhqJ+^5ygkb>)q6 z^v(+x<+p=iEnLqzb{!$5a03a_tqY3lCcw>bD>uA_j46fN$XF7S-ZjfxQ016ia34^X z!`*NX+)F+opOSIqa6dKnXEL4|xRkE?jyNkF9-}!59w(oX>c}|>e+RLP;VF0;o`Ju@ zv+x}JjZ7dD$t3bQ`GR~&CNGA6!1M3|%%y*q;AJv}d_`uE59r?_vY1-8P%@>9zNlni zo;N$LFkF|t!#s7e>-Y;xeA(3~xDD?EmvNM;gU$RdbOKoan<97z$2WMnp(N9NNNBPCJ+G0a7gNYlGh4$bb~L0*rq zN2h`u&v3e&Ib?1)2O%BOhb{^%5oO2#hH_7xE9cT8)(UB88Pk!ul|#rH9xCOA-Ysb- zXcZ8Hm&l1+D29}i1q9I48JZiF$Yo4%Tz-YJny6L?iZoPNZK@24bbQ(jp*U1GWEItB zP(3I}Zl6*%} zXlWVA`Lf>V+SZXxo6@JI4V#P}T^Tzl5p|$-5w$^WQ9IP0d{35>737Bns3Urxx~el- zN!C%{Y#=ecl01WoxoVx6>dhTooY9j$_O9qE!=WvYGI@36K-pHOFQ33C=zq@PO8&(MU5yjx|`=jh97lO~hxRVGd4 zObVf|$qusnjY-qdOwBurW}(?+C)q{OAyXPUpi;Epo!1M|BC?0r;+sNC3wpJjI93?+jpe~%_(Jl^kyU`xBmmDOA$l?D$T?NSgA21ycgXze-U`ppg z?th@^U8B!Yvp0h7CK6-#2 zqDSa4dO}WAN5wB7X*&T^2Y#>)?*?yBeu!Xv33Ar4a71galWqjgj97Dm0?bv~x*hQ|AYveET_W~S? zYv7u=7P(IDkh?)BrwR@lcXVig8&!ofZcJ`ehBIzT!x=Zj&B;x2yE>e4OPug_xZ*_I zhTJ0m&}hDIY8>4WcYgaV@ZcnRdi$3H)wluS&<%Ann+Ap5j=NL0<5Y5wq@2V(Xk$%N zEY83^u?1&l`oql^ZPv*Ha-UodLRq*c?b3A7_^MU*#RKSx4fn(Sv70<3kI3V4oCOZx zZ1RL=^`~@kCUdv+3RNF)s)mqf)jNy}a0!TAgbQ&I9*TX~kBiB3@`Ai1ugL2l1dH%6 z{2|vO(5x95gfIwM8pt}DJLgcreJrt|2WD?*ti>EUY<59iwzbF>RjDyPHWhELFGVY*80tgtlwJJLEOr==$*CAm{V`BuJw z(>|ASg+^JeVWN~H7FcVAi3J>S##%E>EanKI%^W7a zPV{O@xaIMo7q;louQq*{VI9Zt)K*_b@rE~qPXZN7+k`iV>PJUMY{6S;b*vw44GoVr zx8II;ypwYAZoH4f$R4~m2$eyoF2norfgscbq2XOT9O3W~gsQj7vpz2WZN!|Y;D~&S zBM>*ZDymN7-zawetGB_w<3E5MUkE~N5b8*iAf&Y|9FpHX9BcVs-A$FitN6zM6nGQg zq5^LRp)m;CnmCE{1|}?##13xXcVwgZh7D?4>o;oDfVNCc>Nkn!YJQc_2lx?}5*`Mj zr4&C7LMsi*jnR&z7YqZGi}6eR3cqFm0~y5NAdC(|dk{K;&>4iTAdCsZ*u}H~wljQ2 zzzBhh5z~}K4X6=>HG{Ag(Fb8|Vh`1{Uk)&O?vg-Cucs=4oQa~HKer8-COB>*$R+Mf zM`N>#XM`sw(U(1#c8tE`jDvCZpzU$7hd>|zdJqk2fySUYXiW>=Vzh?d=IujA&?2R}XaXR8m#Px_r5ld^6w4Z@_QHe~;gi-Kfpi8Kg>VM zKh8hFKgB=8zrhdO;@{@q;osvw;6LI&;XmWQ;J*^+1+jt_f)s&U@S$LmV6kAcV2j|S z;19uh!9~G!!6U&-Ar?x6QlU(!6B>n4LW?j~SXWqI*ihJ57%yxm>?G_W>?%wZrVBHK zy@Y*){e^kL0^vv@5sndlBAg(cB>X}+S$JJ|Q}`qxd?|b_f+C(sAQFirBE2YD1S) z!=)3Y)1@<|v!(N-rP6ZgD(P0~F6kcWKItLp5$Q4MFVYjzi_*)|tJ1%vH>9_uPo>YK z&!sO}HEUxXtc$I|)?(|h%>!&pwl&*^ZO3+C)7T8Q7u$#J$GX`(wvZjl7PG_H;p{|q zIy;k{&CX*>*>d)Kb~U?}UC;i+ZesVdhuNd-arQL(D|?RpoxRH5V;{3m+2=AKLo!Cj zlgVTznN4PwIb}6vwPkU#da|~%B-sqvBH2%}O|mVrz&6 ze=2_=f29D52!&FiR~Qvh3X8&}h*i{7)KiRXM#W~u z)_`KWVy9xa;)LRq;*8>~;y1+~iVKQA6_*uv6fcxoWi4e#rAIkb`Gs<(vRt`PxmdYW zxlFl6xlXx3xly@Uxm9^q1yro6iK?}#lPXO$ST#~LQ8h>PlWLP{i)x!{hiaGVq3V@7 zLd{nT)nc_&ZBRSawbXUgb=CFN&DDWSb$|6}^+fgO>Mzw()N|DH)TQcj^(ysN^>+16 z_3lVrq%AT&vPEQSWS_`!k&`0VMP7)!75P8|G)Ti}cp8}|Qe)8AH7-r8rluxQldS2f z$<*}G^wYRCgEb#$@-zjSB8^WoQuC>1ie`yst!ArcyJn|mw`Q;AsOES;b3$`Ub4GJk z^H{6a#%oiwncCjkzFMy~Pg|fJs`YD2v=g+`v@^7`v~#udwPo66+LhWLwQIENw7azX zwLfbQX^(49XisU+XfJC2(caTO&_2>W*S^%g)#xh!d33otugt5-%g*R_v-`tpnk0WQ~h}TZ2esQe0`aIfqs$x2mLzz2K`3; zX8l(ELH%L7DXL4HjxxKpIIhardt+R7Fm{9zO#I9Sz%da*=pHg*=^Zt*>CyTa>#PT^1v#$ z##{SYM_bFR%d9)Cd#wAd2dzh}$E_!=XRPO}e^@VCFI%r#Z(E;OpWBqSfYDaR*2vb< z*1^`v=CKvnhT6WcO|#9gZMPk;9kSiCJ-5Az)@ItZy@tJkJ=LCRA7P(tpKYIGpKG6QUvB@=zSh3MzQw-XzRSMH{)_#j z{j~k8qmHAwqlKfDBhm3qz)|K{=2-6d!LiD*+OgTO&9T$5+p*7a!10UYcgHoyea8#O zD<^OwC*zblP;@P~0#{8s&U-TFVipZJ;p diff --git a/VLBCameraView/VLBCameraView.h b/VLBCameraView/VLBCameraView.h index ad1522c..160722f 100644 --- a/VLBCameraView/VLBCameraView.h +++ b/VLBCameraView/VLBCameraView.h @@ -174,6 +174,6 @@ extern VLBCameraViewMeta const VLBCameraViewMetaOriginalImage; @callback on the main thread at VLBCameraViewDelegate#cameraView:willRetakePicture: */ - (void) retakePicture; --(AVCaptureDevice *)frontFacingCameraIfAvailable +-(AVCaptureDevice *)frontFacingCameraIfAvailable; @end From 09da6e1c546bbe17f33247de363a2ae7b4da8f5a Mon Sep 17 00:00:00 2001 From: Brian Vallelunga Date: Wed, 18 Jun 2014 01:02:29 -0700 Subject: [PATCH 03/11] now works in simulator --- .../UserInterfaceState.xcuserstate | Bin 11327 -> 11600 bytes VLBCameraView/VLBCameraView.m | 120 +++++++++--------- 2 files changed, 62 insertions(+), 58 deletions(-) diff --git a/VLBCameraView.xcworkspace/xcuserdata/Brian.xcuserdatad/UserInterfaceState.xcuserstate b/VLBCameraView.xcworkspace/xcuserdata/Brian.xcuserdatad/UserInterfaceState.xcuserstate index 2726c95e18a67c81358e99990151572bc080cf9a..d26509f0d52ed437e154287f77bbac3ab54dcfc9 100644 GIT binary patch delta 6521 zcmZ`-2Xs@%(%#uszp}b?RjhhtW55)H>CL7ELdOP7HO3ZTVlcQ6ia{$Np@f7Y2oOlX zC6v%1KqZ0HzT8fsT zHE1o`jJBYyXdBv%enE%PNpuRGMiBj2w%c9m;;zl?Dx5jO7Tigz}$4R&=?uGl}ez-p# zjECSHJPZ%VqwrWf4o}3>@N^su?twb~zwk5sH-3&^6GB8pL$pLk^u$1{#7WAL7*d{8 zAQee<5>IN7nxrmCAc>?gX-(RYwxk_tPdboJ#7Fv)exyIiBm>ANWDqGJl#CYchw-BlAfSSwxnS)npA>OZJexWFOgYCI`qbW$)(^# zoB%@b7d(zjpqNUig(lE)YrB#HXlA1^G?`7L(%!UOs>YOmvWe17i8;PB4U(s7 z)WK}4NryV2E-0oDb*7PpD23W-x!?kgr7G%yQj1Ve)QdW(mqs5$a-={UN<$e)SA_bY zbn2w8BIHATshfJJ5WJ;v``Zf%V^UD)?*N~L9N$vU!@TKRK>B&Vy|4Yv>rYDLDLPECdJq-nDRIj#4ZSwQd z`egai6LWIXh8Lp(G#U-*(l#kfmY#&7K&nRnmh+wZVnjm+DAPL@jYl!XXdL!=p-q`{1lVOS*ts`>+sl?Teogq%U=LTYVcJI~X`@AO_mmr=}u1z`^h zUCa2dq5CLi3HlFn^bK?q-9op~9dsAnqs^GRo70bI3)+%?Ok2^`OPISKpoi!Ydp|)> z+4C85cpKW5wrB4Sv?F^aG3l3$2mL@mw1Bn?LjxorWq^DGp(I~kF`JR0A)VSLG2&HIB93vmG*d> zS>S=F_Yn`#P>yz?DJ-+P@Ipt3g(@E`SA{s*jdrKPhlwpDd_lwMQFf4;Q0Ievb)g>Z zNqaG|zw()7ZiYl?#oP>yp$RmFX3!iyf)>ycKBj534^5{T)JOZ$ezZT$Tmr434T?q$ zQA6ke9U+M!d;lHIYLuD%m(Y!LQyAwll64yB4QbGa`79kWzz2PU_av=cBPgPu&`~F$ zKV-6{0q_ZAvE_8gW*5m2)FGH6Z5ug)7HEKGoq$}(V@&xl6h4JvFdRmphQZy^j`E>& z5FJhjQghHLtCawwVN5ajfkJ?0(;S*h^N+ze_>2{-qc9#ObZeR686Y@9&rFuR7lnS$xzsl3qChgnrxW=6xT zqEPWU26Nc4zk#_h4>E!S<-F`uI*g)JO^4uj_Qc?Jxr(biuvGm5C=7za#MBot^`J0I zS>=Qh_&(@T#EM`cn{2O$t^a|$7Bh!sqYjXPI?$2Kp9Pc^+z>dI!H9{$ef^lpJag@=PG8Aou%?!@4iTVp+3#BZL z0$h~@*a5pj(>rOP5Pqg(Xu0GzX_}uZ4mvcVz(4vxolI+wk+o}7s~+pB zRz1G@sBR z{{vqo#9>Pqec%2s`aZxLWmpStRK+T>!1j0{14qN$;6oMfFQlJ_ae>R@3aq|$>e#vn zmq#oQ7MHKWnibp~ z_n@okk8evVPQ`uRuYEWjXV5itEfwA#Oh{nq6Z$K&EfZ&bu*E+R52EYndMb47nAxv? z*c!HJ@CTc6aXvc~&Z9pSqK54B>;lv_$sUxOo#ktunU&|uX_K8%20A1KHy7dn-4fp2v~zOO;H=EN&cS7xh^qLrka?fu@pLQQ@y@(S_{$H@`W2o+x6$nk zu4Y>eXu+m&!Ic%uCmUesjp9dzka@)P&+6j^w<%$s1ym`F(e=}>qPT|&CIo< z8sb%WHC}_)vJeR@Fo&o)0LB2Yr#ApmEMTF=rpSDsTxRdhs`9}tmKNpV2L6rZ;?W}f zJ3dU0)6=YBcn3&)f|ad8dhET5=&#(r%q6Gs1qPA-NlbhZUqS-DLQl|>Oy?+g5Gj!nIlV^zL$A{tC4?hN5kZV2 zjbVXA5<9(3|9p!D;vxbIHgOXVy+iL75ig0N_vn3w1=g1bA4k@(#F9`0@s6V^iK7qb zL&lM4kF8vbg`Cu;PiX#eQjc9+?D``0NdwZ5H0qk`W36?lTc^+HU-W4J^vtZ@?k40T z)+&>xq#0>W|EACBKgFa4X-Ph&FX&79idhlqNblG&Bshuw`!2z=a#4M}Kp@D>n{mn5oIM(S1c6Ubm!+<4O z?|L$ljZ&AA!DI-@A-N=vfQ(@c z@4F5%ysMZ^j}8B>Nea_tfg&~IL?zm8cL5fL9 zFwWx9YLvuD1!a|Ep4sIiBP9}gPbC#>4E@62Ox%l{ayVa7eWaZ09I<>wp5`4@*YRS za0)&R$EKBUxGy6yC%r#w19Fa#|B&mQlJe5>d=!ujS&#=+L^V)d)CkYSbMazU?>6II zcppB158}i4C_au);#cfbftyrgp9gA^+U)Z{eU=*u>;pj(`z+9fA-Oy8_avz#jij@$ z1bNIeXUJ2LSJYh8M>I+_Q&c2cC)yy|DB3LAD%vjEDf(HoN3>6LR&-u;QFK{!Rdh{s zU361)TXa`+Un~_{#nIx<;!N>u@lx?7@qY0y;)CJ~;@jeT;y=ZY#81S3NfZ*j#4NE& zA|(zKk(niu-k|r4-$(4+jjF-%i%#jpHR!V-9te5;G*(%vC z*(v#1@~h;8e9N>`qGBd1ZiWbPdZ#WN4ikDR=Q5Q zLAp`8S-MraUHYr^ko2(hsPwq>r1Z4(tn{G_$#k+fnZLJeoNStGhU{zE9NApix3ZP8 zEwb&howD7sy|VqXld?Z#H)XeFcV!P{k7Z9~&t!kgC33sGg1nNvioBXUUS3n)MBZH9 zLf%T=M&3@|L!K&6lV`~L%KOXn<-_D7N z+vHdL^7{%<5QSJFRmc^bB0`~7Xcc-zv?4}PK@qE{tf;D}rifS6RMb|~RdiBhDn=TvbArd%`bBd$HyflK0ga6P$HE{n_NhH!b@ zP;M9(;3jaBxXIjC+*Iyc&R@ipa0|Jm+;VOux0>6{{l=Z;E^$}5Ke(IRZSF32pL?kk zD|JdtxMDCa3xDpxDlD%UADC^srME4M1QD|af7D^DsuA6K7IUspd;zf}LLK^m;- ztVz}6Yy2ZLQ#ErmyEO+iPqYzQwN|UuYmHim)~yw^QQFGd6m3uKcQGZ!~Rew!?UH_;4q5iS{ss5S%xxrwlXJ}~{Vi;i3RAbOM(>Tkx!noPE+ql=b-}sC1SK|reDdQRAIpYQ6CF4yK zGI1uO$z!T$s${BSiZfL=)i*UXC72qUnwpxMGE4zeiD|28uW6s@fa#>^jOm=|qUo~f zs_BmDf$5RyiRmw%@G?KI;FY|V*Yif6=Usexz9wIfZ@@R=oAS;17W~J2GT)OQzz^iJ z`5ZovAIeYSXYsT7Is9CHF~5{w&adLv@IUhV`6K*E{xpAj+##$>|>scFE8(9;rGp$9|rPk%vmDbhPwbm`xZGP(x z>n`hV>t5^c*7MdI)+g3i*4H+$5u4bivT1BOo55zXnQhf=-E94BQ*Co>3vH`xTWvdR zyKH-G`)mhnCvB%~XKm*rD@N9iOpI(2*(~y-$d-{EBa7)J$1B}akdGskqt9LHS8w~qOag^tCJ z9~{dZD;(<_TO3y$ubiCI;N+bar_CATtl_NXtm|yxOmH@FHg_iZot>O1&Th^g&R)(m zXS#EOv&4DO`Ou|x)p8}c5?xJPtzGG^zOGDHmMhzpZg}nsD#0tn3Dtz^LJgs@&`f9{v=Z71?S)=KmM~nH zAbcTwB}@}$2(yH5gl~mq!U|!PuvS&Kh delta 6406 zcmaJ^2YggT(BIj;n(OcG-Mik!7y=S{5h0Y&LMR~+5+FIk0ntE05_;hF=!n##_Y_Kq zNE4)^h=_`cf~ZIp3xY(k(9v)2LO}e!-1Zw5fGW`z^d{PdcA~v#A3B8I zMaR)c=u`9s`Wk(ME}_flI=X>=K{wGYARq!UNI(iQkV6b8KmZe%!2(vWfgK#+1P{bQ zeP{?xgU}LMK^tfbNzet7p(pf$fiMWNARGKJ0!BhU6u>Abh6ykcD9nP{@EXj4*I_X% zfu(3Ftblc}9x7l9RKa%G3;SR{9EJDb7<>eu!B_A#d;?eDJNN}|LN)vf|6qgxV@$9J zi*a`aR$>n8u@&2}9eeQ$_(j|Vx5903Tih4-!|Av`&cK;?03L`3;Ve8D55>7S59i}T zJPuFBGw@723opP6@glr3{64e@KEVGFM3h8D)I>wH#7L~fOMK)xQinWGUL*}j0%=H^ zl9xzp@-pd6x{$7<8%ZYJNiX6jgGmkNmK^N-ITUEHTI5XjORA1f7pq+G8>MW`5!W_yl7W6?M?KD<@c&DE45`W$U> z7EMGYY-kdijDl=<44Q(bqG@P)*rZNzG^Ne8KfZ8(G?q4@&(pf$3+iS=(IT|89EH(hw1mDu>(Li!!fCV|tzb)6GWAzybQuyDS)4mG zH&B??W#o{+I2y-nh|kjg*H2%db!a^*MP(VjoIHO~(MaaQ^qS8=QFxrjDK10hs3P(e zOixMeG5D20PI2v48zWoM`Vq+kpYea~gsSL-2LF3P&9>Xoj(#briG_v!@nvW`syK~y zF$3O0yU`vrHgiaR&gc=$inQLz{fl!)1ms1<{t*SV5pBFkn-(*?M#O$}Ae^NYMCc$> zlEp(_!#<3TgjZkJt zpQeR#Ie#Bi9ntMq+CCEL8fgEH?xWaE=nwQK`U~AgchFsQk9MFPX%g*3JJT+->n8L7 zJw%TfCRPFhpxtOP?aQDLM+eeDOgo2uL87K$^x(YQoccNSh6nsZ0)>yIgA#Ozs{j?K zK?7Raou<$pv}XlyphsTdX)oHF9fv+ly?gqSpzZv*9oYjWHg49aVZ1A$apQ)QWc?>L zh<7zjXx4aA)S2J{_kfht4!JqSx%nggh2zV>g)069c<_R+2JmzM?Ne3M` zmt}{Oj3v2Hh?cH@f+QFXV;MkU49zcvakPMDXK8gE`u0gJ$jdE`eZf@z2=gDEhT7Sf_Jm<}^&F&)jo(MIA9rY8r6M&)?hPNXRESG#U5 zEO=(!LRdt{(s4AcfA8F3!)w(neij=4xLVCu;B!gHCU_0`|!b& zh@7CaXm*YFKaOm95FZCoJO!tp5qSo_q_5FAG_9w%?UeLq9DWWi{AcPVHgzsd z^R~@*Ar$|w*j$C5P;5DT4?n<0-KsE~U%p@{Mp8?!kSQH6F5(x`M8w>lqv?*nf8ToU~d_Uyx)xSj5xyV(0Jx|==s zFsHVR`8bHPv41_?89g*O2M=MX_i;K(4HTC%P5@P~#Knjxvhc9S(^(nBuRw4;9bdyA z@h^Ts^t;wqMR+u`JeoA{7`pc{MDchCmg5Qa@I+if_tAs&$P=96AfEDX@ZqU=8r@G1 zu;A`ccrAD~e*Kx@xp*EuL=Us!YK6ms!+7a4!^`k;`VM`U4cAfTYHPGz8!3_|)?_Ax z2bh{amxQylw-eMl*!zWpp{DKZD z!=K?(^bGx)Mfzzuz+XmEf4Ge$Eqq=q3*xWwg-Fut*|9|EE>aqS&xSgGQ4wA{jrSL8FFEC)IlNC;ZF*Defk&X5xOM-_UbR+_#U#oliQq zfPbdsKCQU55^v+XEJpYay-G4y*{O@9rsejqzM(DrVUj_7MKKn(PU#~2_2OH;%|%=AZk<4O35jW}5V ziJds;PxM+DaS=EDnOMV3S5H z*rYN2jV7ES%~;#Wnn%){v>+`>tNulSJl3ePMuYxAf2X%XpkZcayW5cVET@sSB$2eE zf6~9`?Q+tAbRy2r#SA+2I`Lg0SA@3*U0O0yUZse|o^ks}QUr zd1M3`N%Bbn8AS?75h*64$(Rt35Qsw{34t^OvJl8a5EBAL2$UgEg+LuSqY5&fOdu2c zv-YH@xG;C*un>sCt6k?KRx-;3FV9(L=~)?PmR*GGNwdUUU#_~LD`NlZ?zT{J7QsHMBEEV5`$gc#wDixTr9#5%Vl zN-T^J@4MYmVsV71b~~fQvIxO@;-kdM2+_s!a+FvTA?AA$q!CNjk@ewfk4sukN=X^( zx~n}e`zpwWXKFXuOtvsIlFATprKBnZdglC|USINdvKMii$PTiT>>_WG-DD4WI|O_P zj3E$0Uty*^&Ri`!A~Gqid5`2 zTazTo=Pc&|;FIJGYpcHqfro+qY1SYuqX+F)G!)$e;{!ty3v-6EKCuqL!k*qEVvRqNSorQI%+`Xq#w< zXqRZW=xxzH(E-t?qEn(TL}x^2MPG}~iO!2IiY|-36IF{rtP!^n_ZEl5i^b*QgW^xc zpNWI##lMPgiT@D)CB7rRCw?G)B>qPN5`)AjF-a^Eo5Ue;Njwstq>dz3(nyjl$&iea zlt>myc1u2#oR{2`VyR8qOxi-)O4?f5Mw%}5ONUE~rOTw{(hbs0(n@KSbgOim^qBN3 z>5tNTGF~Rg%rdLYE_2Fy$ueaApe#ogkPVaN%Erh-vYE2kvN^K3vURe}vR$%+vTtRV zW&g-!a$YXT&2p>!1$k3>b9qboOY*MrRC%U6TRuWQUOrVmT|QGjTYf?Qqx@kE#0W92 zm~JsWVX;2Nn`5@byb-fI=2Fb}3bjH|v{tlJ3|9n4E5<1%C?+X_ zijbmGu}85_aX@ic@s8rC;seDQ#kYzJic5+siffANieD7firU$coMyio(6dHrZqH$_sH7{#AYEm@4G^v_2O`aw=UNc2AO*2C?OY@p0tXZO2rdgp` zrCFods5z|pP;**yS@W~zhUTW`SIsTWea%D7-&&-_T9MYHZKEBmov59rovxj!U94TE zU7=mAU8`NMeM@^tdsKT&dt7@$`=$1r_Pq9@_Nw*=?N8dDwRdzeI=#-OdqG!U*Fe`$ z*DR=Op=+gUt?Q)gsq3#BuFKbz=z_YCZkld}ZkBGfu2Q!}SEbvk+pjyMJEA+PJEl9X zJEyyd?gaM{car;@JI#H`eZ^ho zZgPKex4FCAeLd)jUaXhu<@$JiTYa{Egnoj)L_b+i^;7iI^fUBf{Sy5${R;gm{Tlr` zeW`x0{sa9t`bUO%LpMXZA=5C>kZl-j7-AS>m};0|m}Qs~G|V;3H>@#iF>EvJFzhny zHS9MWG#oY@F`PAAHT-C}X1HOvY53Lf(C`lryoi_ZGM?v6yoI;(PTtMe=M(rwd{e$T z-;(ddcjc4$9(*r8mCxq={9t|vKa*d~Z{jQYDt;@!jo-oV;&=0J^ZWRd{HOdW{tG^M zhCj=H&7b4X^B4Kc`~#!L=ruMpb~O$%PB6|lZZvK)Za3~U9x$FTerEjAc+q&tc*S_# zc*A(pc-wf#cu&9r5yS!~@PZ&%1e@Rxo)_v14TOe5W1*?gUg#`z6_SNsLaLA^^b=kY ziUcZ57iJ2xg?YjPVNp<6ER+dV!d~H!a71`lI4+zJJ`zp}mxODkCZ?B7iKh0Zj;7wG zfN7X1*Yv7sgel)N%2Z?;Z5nHO&Gfoyo@s$8Y+7nsVOnikYg%tAGwm~-HT`CKWHy-V zm=n#J=0bDOJk31AJj*=SJm0*~95x>`-?k8o%o1Z!T7o)@-ojf1i_cQW5^IUGOt#Fi zEVeAQEVrz*thQ{hY_e2Zsw`VA+bnx6M=hUN&RMQnez5#x`Pp*A@~7pt<*wzv<)P(o ztJG?+I;?fA^{ox8jjTq zy={9gXzOE}W?N`mY+GtuVOwQeW7}w}vTe0(v+b}Qw!LS2-}Zs+r0rANDccve%eFu4 zg571WXK!e4Y;S6BWp8b7V^6fVvv;!(vlrNl?4#{t?X&EQ?2GM7?aS?}?APsoIFLi? zkUJC(mBZjLI!q3W!{+ch;v793uR6v%f>RvR9Wx!X9ZMbMjt!1Yj!H+BW2m^9ScO z=M87I^Ec-`7ja2kc2^x&b5|QzXIC#*A6J2EysN~u+*RtTaDD7L-9e8jrGQPn|M>a0q+Fw zeD7xOPH(mMFYiO2%$KP18GJ^c$>;XP`r>@?z88H7zL$M%eeHZ5e0_bHK7X`TMHtt- M$;Fy??bDa@Kkx2|v;Y7A diff --git a/VLBCameraView/VLBCameraView.m b/VLBCameraView/VLBCameraView.m index d8e7708..533ea89 100644 --- a/VLBCameraView/VLBCameraView.m +++ b/VLBCameraView/VLBCameraView.m @@ -52,8 +52,8 @@ - (void)retakePicture:(UITapGestureRecognizer*) tapToRetakeGesture; [cameraView.session setSessionPreset:AVCaptureSessionPresetPhoto]; cameraView.videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:cameraView.session]; - cameraView.videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; - cameraView.videoPreviewLayer.frame = cameraView.layer.bounds; + cameraView.videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; + cameraView.videoPreviewLayer.frame = cameraView.layer.bounds; cameraView.flashView = [[UIView alloc] initWithFrame:cameraView.preview.bounds]; cameraView.flashView.backgroundColor = [UIColor whiteColor]; @@ -67,31 +67,33 @@ - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; - VLB_IF_NOT_SELF_RETURN_NIL(); + VLB_IF_NOT_SELF_RETURN_NIL(); VLB_LOAD_VIEW() - + VLBCameraViewInitBlock(self); - -return self; + + return self; } -(id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; - VLB_IF_NOT_SELF_RETURN_NIL(); + VLB_IF_NOT_SELF_RETURN_NIL(); VLB_LOAD_VIEW() - - VLBCameraViewInitBlock(self); -return self; + if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { + VLBCameraViewInitBlock(self); + } + + return self; } -(VLBCaptureStillImageBlock) didFinishTakingPicture:(AVCaptureSession*) session preview:(UIImageView*) preview { __weak VLBCameraView *wself = self; -return ^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) + return ^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { [session stopRunning]; @@ -100,7 +102,7 @@ -(VLBCaptureStillImageBlock) didFinishTakingPicture:(AVCaptureSession*) session [wself cameraView:wself didErrorOnTakePicture:error]; }); - return; + return; } NSData* imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; @@ -109,7 +111,7 @@ -(VLBCaptureStillImageBlock) didFinishTakingPicture:(AVCaptureSession*) session imageDataSampleBuffer, kCMAttachmentMode_ShouldPropagate); NSDictionary *info = (__bridge NSDictionary*)attachments; - + if(wself.writeToCameraRoll) { [wself.delegate cameraView:wself willRriteToCameraRollWithMetadata:info]; @@ -121,57 +123,59 @@ -(VLBCaptureStillImageBlock) didFinishTakingPicture:(AVCaptureSession*) session DDLogError(@"%@", error); }]; } - + dispatch_async(dispatch_get_main_queue(), ^(void) - { - preview.image = image; - - [wself cameraView:wself didFinishTakingPicture:image withInfo:info meta:nil]; - - CFRelease(attachments); - }); + { + preview.image = image; + + [wself cameraView:wself didFinishTakingPicture:image withInfo:info meta:nil]; + + CFRelease(attachments); + }); }; } -(void)awakeFromNib { - NSError *error = nil; - - AVCaptureDevice *device = [self frontFacingCameraIfAvailable]; - - if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) { - NSError *error; - if ([device lockForConfiguration:&error]) { - device.focusMode = AVCaptureFocusModeContinuousAutoFocus; - [device unlockForConfiguration]; + if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { + NSError *error = nil; + + AVCaptureDevice *device = [self frontFacingCameraIfAvailable]; + + if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) { + NSError *error; + if ([device lockForConfiguration:&error]) { + device.focusMode = AVCaptureFocusModeContinuousAutoFocus; + [device unlockForConfiguration]; + } } - } - - if([device isFlashModeSupported:AVCaptureFlashModeAuto]){ - if ([device lockForConfiguration:&error]) { - device.flashMode = AVCaptureFlashModeAuto; - [device unlockForConfiguration]; + + if([device isFlashModeSupported:AVCaptureFlashModeAuto]){ + if ([device lockForConfiguration:&error]) { + device.flashMode = AVCaptureFlashModeAuto; + [device unlockForConfiguration]; + } } - } - - AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; - - if(error){ - [NSException raise:[NSString stringWithFormat:@"Failed with error %d", (int)[error code]] - format:[error localizedDescription], nil]; - } - - [self.session addInput:deviceInput]; - - self.stillImageOutput = [AVCaptureStillImageOutput new]; - [self.session addOutput:self.stillImageOutput]; - - [self.layer addSublayer:self.videoPreviewLayer]; - - [self.session startRunning]; - self.stillImageConnection = [self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo]; - [self cameraView:self didCreateCaptureConnection:self.stillImageConnection]; + AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; + + if(error){ + [NSException raise:[NSString stringWithFormat:@"Failed with error %d", (int)[error code]] + format:[error localizedDescription], nil]; + } + + [self.session addInput:deviceInput]; + + self.stillImageOutput = [AVCaptureStillImageOutput new]; + [self.session addOutput:self.stillImageOutput]; + + [self.layer addSublayer:self.videoPreviewLayer]; + + [self.session startRunning]; + + self.stillImageConnection = [self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo]; + [self cameraView:self didCreateCaptureConnection:self.stillImageConnection]; + } } -(void)cameraView:(VLBCameraView*)cameraView didCreateCaptureConnection:(AVCaptureConnection*)captureConnection @@ -197,7 +201,7 @@ -(void)cameraView:(VLBCameraView *)cameraView didFinishTakingPicture:(UIImage *) CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], crop); UIImage *newImage = [UIImage imageWithCGImage:imageRef scale:1.0f orientation:image.imageOrientation]; //preserve camera orientation CGImageRelease(imageRef); - + [self.delegate cameraView:cameraView didFinishTakingPicture:newImage @@ -223,8 +227,8 @@ - (void)takePicture // set the appropriate pixel format / image type output setting depending on if we'll need an uncompressed image for // the possiblity of drawing the red square over top or if we're just writing a jpeg to the camera roll which is the trival case [self.stillImageOutput setOutputSettings:@{AVVideoCodecKey:AVVideoCodecJPEG}]; - [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:self.stillImageConnection - completionHandler:didFinishTakingPicture]; + [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:self.stillImageConnection + completionHandler:didFinishTakingPicture]; //test if(self.allowPictureRetake){ From df8653c900cce27b16bc94b9c6875c1ac45b8919 Mon Sep 17 00:00:00 2001 From: Brian Vallelunga Date: Wed, 18 Jun 2014 01:10:51 -0700 Subject: [PATCH 04/11] small changes to project --- .gitignore | 2 ++ .../UserInterfaceState.xcuserstate | Bin 11600 -> 0 bytes 2 files changed, 2 insertions(+) create mode 100644 .gitignore delete mode 100644 VLBCameraView.xcworkspace/xcuserdata/Brian.xcuserdatad/UserInterfaceState.xcuserstate diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e3a38d5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +VLBCameraView.xcworkspace/xcuserdata diff --git a/VLBCameraView.xcworkspace/xcuserdata/Brian.xcuserdatad/UserInterfaceState.xcuserstate b/VLBCameraView.xcworkspace/xcuserdata/Brian.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index d26509f0d52ed437e154287f77bbac3ab54dcfc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11600 zcmc(F33OA{_V*du%x&hOY15`n3T5bAI)FfDsI*YpQc4+O+TNB(+ms|l%H#>6;5?%8 zK&68W0-_=yGApAvG6{&N$OA=15fOQc{?E-|MqZi zO-rN0?MX^H3LroLgCGzL1o&%wuF5)tak(AN<|?bR=5D6esu{13^4U0Er+8B!d(%5)^?u!6;A+O2B9^29$!apbV6Q z3Q!Fug1f*}-~e}nX`m6fz$`Eu+zaM|N5G@tG4MEe2`mTgpaXP*F7Pr~1J;5!zy`1t zYy;cD4zLHj2R;VJ!KdH^I0MdtufcWjAMiW)1Ka?Ag1;bu5F!{1#ZU(2PzALx97e-_ zus<9CQ(+n$1c$<5a5&6{m2f<)f)ijhoCqhu$#4p^!3OApbKqQfA8dgS!bjnga4~!q zJ`Z1nFTqZ@60U`>!8hSsa0lE8_riVfWB3U?43EH1;kWQ2{0@E(e}I?ZkMJjW8Qy?@ z!oLte5Fvz75RxDT(jWthKqeH8Vo)3!fD%y>x&sYG!_aV)jfznT8jZ%FQdEv6ped*x zHK3`e1x-gTG!wO)aV+}UqDBKsv;eNP3 z9)MGE8Xknx@nD>db8s#$#wB<(9)nBqSUe6hxE?p)sn~(<#?x>!o`VTqfEVJ2@T2$% z{4{D_zk=P@5TG@etZBQ#P8ul_+he7*w$bi(cYqKON)W*vKmn8_i0mO2o5Grv zmywxPkeeHynx2&rpO&7J7oVGvpA?^(l9id8pHrBWm6~o-Xo~U+#yefp+%5K6Cf`}x z+Qc+_c*Z&q1>#l#JurYUUJ~2_^y}BqAav5+WtCRlp3QK@6}^ISil=u#gZE zO5P>eR3-rlqn~}Juv{F?bKQjWu>x zk-O62cGNUdW(L0?RK(nXDedgpSp&^!a|fDdC#NMP4K!zFq|KenUqC7t3gT9SG%yIH zgA9-fvcO<41l&R7L_w59Mbtz?v_wbrtHCg;`fQK`azP&bRsaf#fhylf!bu#dpxzk_kJ zRz#N-IvSZ$yJzZT`ja~YyHEkdHif*hI5&?Pn9I%zkpv{Z9`+e`(m;=VHONu$g29n`>_&30E? z2c?=`HM)F^FYfR%xWSB@WSB{1h$R+Fw$t2;!yGVo%INZvR*#(;UyjRVZ|ekez&tRW zLWu7tCkO#vn?mg;?BU)C2+N;mdmmT`;yS?sa6fo}^dtSrfKIRoJO~~l14$mqXLV_= zs-;eqK<{Ie!;|2@^@MVdtF_kC>Y^^7EN2>N3}x#4vo?k4Hp`0K?pDUl^M3+72jW(M zC&5$TY48kK44x(NB!MK7B$7;0R)FWh67VkyKFcWZq>{m82nC!R7IZjpE1210Z?0qN zd{E5>ca}1H5!BflU#?j^ve;d+eT8H#Ij8<8m}N6g0C6t>f(2e~f_r zbD4Uli}A1Ec4MK6a-v|uC3Rh`wr25Elv)l2c z>%e-}qF*KH?cg<%LHbS(FnylvO|Tinb%2dv6Uii5?3a!7OD5@C8c0udHG4KipClHD zQU*~-%E(IX!J(aCw_mV#$Q{JO@4px9_lt3W3?+T}i9_H6c48CBY6l;ZVLcO{fFtb0 zVKThkCkwr%o4r=VZ*mfR=4X4Fqx8Nf9 z4tx)OAO+N#3dsmEk`$3U$tY61np)FO;4=7`e*OZk(!bZJJ(ZBrq?CS+C1vz)Im?^H z^#Yg6>ALwsslC&wJQ~pKEpDccPBSzfv15L7@!2?Qi!8*sbK5G~TBzk|*?|C0p(fY8 z)W01|+8y3FyZSqORd4nqT+Y@Oy5MhDoRK_tt`GGfhC$287#}b|0Tfa+>c)?9#?whh zL}2>3(dG09M=t3mr`ZV%0k-9&4>zvpHLmu3@76xlK?8g3ECRzYGLH1+7DNDBCp5uG z7)2_{1Tx8wxG)CB_C`C{2lgf7Nfql8Y^3u0AB+8#?3QdF0P@@h!o+~ZNidmIlZh0r z>C&EIN|?%@AP0`3)(UfB9?XXYun>-bBViG|lh{cOsU>xUA@!tzOeK!h zuo#xmh(8PrgJWSCET=elH5&tB%zU zYmS_TsKHcn6%hBkytSr@!hALNi%X-_bVWW>Z*Oh%6#2@S z78m2DU+ip%V-4Cz-oUv0F__*f%bOo(cRC91f_7L#jjR^dK?c^_6e^d~>ETiq_9&x$ z$(+7{X?C=_Ilxf14t+2q4qQ+~aU6bWjF&!)dUQGO2}5TJB5- zW2~;zMgw7wSIk%h#=Xb(;A%R}vBrf76tw-Pjct5R0 z4#S0TQFRZmaXu-?aMD7ibMWyHe3*-%J*uI*)A;G5EVVma9qdD2RF5}tye!PD?_cm{q!7Lf@zah2Jd8<@!>9d%4j zVP9|fr62M z3lii-vV_BQ-(4dqMQ9{LAt;pmi!3F}ZbE1dkZ%v7D9i_-u17MQ}$Ugok!WMX( z8Sq+5DEH|NKi6L2XS2}1*M`iG>E)RR*;osRTs)Y znQ$Q*OjeWiG$L&#eXEL@`tFW|FSq6!6#i_bn)7}(otaSPXqf6F?)D#)g9=$TxhN0i zqXO~@Swq&6bzQU~7>0^KA8JSj@+!@=D3*j*+G+O3X6tPE?@Q{-?Due`n@wR1ob7h! z@>(aG^qT`FeaoFLnorSwm7|4i(a^3<0EusR)+0HsjfL}<`+Xi&ph`Z|M&rqA-I+G3 zrhN@G5ltemlQ;cYHnO3b-U%cvc0ZW=tGucQs5lfHy z=$e**HEz^OWkMeERy!C*bw>52qRWej(EaQwA3zJqcCxGIln*=(Gs$o zyu;!KTa))rQ!Uw(cKOzF*YP4XVql=HPacL*2U<&$dDMxz(938AT8UPn)#w$phU_K# z$bNEw93=0NL*#w(!D`S4y-JPiHS{`q18ty&W})WwAu)KN)(h!hs~5&nv!e+;^^jbe zBTs8_I+{IhUvrWM6xyCJc4yzc(ArJw5b9~vko273H0W?m&s=6I4M9%VB(A$zUOSax z`?DJEXIX1AHA9c1*_V~llk-l`EvEY!xC%5761rLCw6qk`G}&F$T;gbU_!-mP1AccK z0)N}P(H`2eK<}V;$w%bl4zw5TBcG5j*#rMW7_uocIK1-xO)Ygf*~d5Ktt~Cot!_rI z02*F~L+C>)1H6Dfph56(2l@zoOpcNhw2RS$aOjv1&5ry(NFVts5S>7uQ~dc`Fhgh1 z7r=tPBFD&aY6_o{zTH7(_~6?G75-!w(Dy8&eS^M57twd*BsoPsBd5F259kuz@h9>* zIYW2+g4Oo_zwkJF$Et+YlV+!7q^1lsC#TWyIDu_Wr6<$gIDe4;pg&kp_?>*!j&6{z z1Fi;Bz@UNVtW8n;f1TMU%w&6;E!2h*yIJF4ETKBY0xZNLEGFm3zsY%Wp$ki~42R%Q z@(uZ!T=7B;tHihf`{LXrfy-EmX=$9`W&_d;U&nmlEl5jU4E4@dcZJ>6z;t))^Vo+z zvW)6c|&&*%^y{Z^?WeF2J&rpFu~yzW^n{I zk&EODN51dCRvb%yAea6@lbk-!>CuV5Bfu7_J&B+tyDk8s@j%Qr zd3x9-;big?xlAmy<^BLiN)yK09?=KZID>*U&LqE()}wd`trls`i0{Bd@i07mg4-9S zX*No(kzdJGFI4}R4T|+z*PP3cqA^ucaq=9ALIt< zTgh2aC1(#dMa*rF*X!zUuY;TGXPSfIGFBty$Z z;Dyi&kr!ew3|avfVw4QHm;Wx z##^u1XOQM@LSH##z3n*zwy^XfHhT3l3KVJj>uF5n5D z_YoR;6LyPe8=X_)CtK|Gnnc~kPrZXpif$&mbx(?ir&V}$KxU5D z;#X;S!0WtF*N)eFp`Jd6qRBDq+MN9b0t~;;n|K>gt;8GgCcGKHg}30h@m4Pk^FpH+ zhI?Uz7n-~<(hH+j(!RC@@5HSYKOa^(b2#?XxDjs zaWbC<&040&J>EeJPlgSan%)yUG}3M|H|*U1^1W*A7h`I zT)>~=6J)s;_VL0v8iac?Q~Wub{&*n;-v4@Mb82rs!+dGhRUZtEV%nHGt|i2{KEeOS z=g0XPMFi59qryN8eJyGbeR*LxT1;QoSw#z+tu)2oPhZVBgg&M(=NzT4=iHz#-bCXR z`m#+r&ZIBf+(DyoHhtZuoW5i;o`#-@crvzOJFca#+<2(QO76)|% zZ4BBRv?XY3(DtC6LA!(A4cZ&DKj>7@>7X+~Uk05GIu~?4=$oL6LEi^m3Kj+%gZl(m z20MbE4_*`ecJP7V_ks@ve;#}>_=n&hgMSYGCHPl?M4%QJ1V%xGAW|?ukR(VEqzSSF zLj*$w!v!URy99Q@-2%5@o?xNi8Nm`khhV+nO~EF?TY~L^or2whcLnbYjtR~Qz7t## z{2^2c!-Rc=@xnx5vM^ORSa^qUm@r$ID`bRi!X?5L!VSWW!p*`h!mYyX!kxnRg&zt( z79JKJ6&@F!5S|iV76Fk;lq|YSv_SNv=o!(oq9vlGq8CK#McYI>MY~0NMEgVsM8`#6 zi@p(E6n!tcEV?4PD!L~6O)LXFWn&Xjtki=+=pACW#L zeM0(zv_sk@T_If~T_;^HeO)m z#mKC(KC&!XuIzEyGTD0B>#_~9jk3+MEwZh$?XsP+-Lj*ytGqNvbXJzMP z=Vjl>u7t=!j3LP(cZ8IMw1zwwvMgj>$U7mYL#~Bf5BWXhM#x{GhS2EHxX`rF@u9V$ zOlU)>BXnA5Q|SEA#i3oHn?sL;9t-_6^knE~p`Xj;a)Ufd9xb=XW95D2Y4YLn0{IAe zk$jZALhhE&ls_l$lCO}jlD{I~EZ-vED&Hk*rPb8_(d6_lq;1=wNk5$R7NW;%2;KBvPwBwxls9pa+7ka@+;*fbr1s1j8vsx(!GDoZs)m8~jKRj4XeRjO*0T~(`MR1GSJYO!jaYOm@;)hDVWs$;6N zs>`Y?s;jDNs_UxXRX0?BsYBHYwMwl~>(mCdQ5~UiO#B>b2?v>SO9N z>Mzx2)#udb)jz5)tFNf9s;{Z9Yc!f6nj+0~%`DAA%~P6{n$?;$nsu7>n%6aNYj$hi z)$G;m*BsOw*PPIt(wx?OtNBjzgXTxgADTb4K#Q~rtw|fDjn-PU#o7s4yS7Q|)K1sB zwR5!dwF|XRXrIMEdeeE&rr`nU+&$ORwztDc813IZrtBcVM z(8cQ#b;-I^-5t7Nx@=vpE?-xutJ8UPUApbMeY*X+gSz9ole*7zXLMic&g#C?{iOR@ z_lxdVJ=Tl#61_~X)T{Mcyvf71V~zox&g|6PB> zAT%fpCPR$DYUpDaV2C#)8j=lphGN4wLzSW0Fv;LB%rVTPDfN8A0>cA_MTUnAj~E^^ zv>Q4NFB?`GUNNjQyk^*7*l5^n*kbtD@I#m|OcORBY-m_jm@DkTuxG=ThP@E>Qdn2m zim+8-uY?^jh8T^;C}XtIVvIBPHx4u=7>5{#8iyNmjEjvO#x=%u#`VV6jT?;Hj600G zjPDrt821@JGM+YGF#ck^Vf-r`hU4(y@X&BYxGG!|t_wGWr-oODPYr(}d`b9<@Ylk( zhwlo1Cwy=C{_un0$HPyAp9()6F(4u{A}1m*q99^KL{UUpL`6hpL{-GZh{+L)A~r{y zH|b0kQy){DX@Du-lxWH{4K)on<(TqJrKWMF@umr;DW&*^xquFV8nOn^>&9lw(%wF>X z^8@C`%}dP7%p1(x%paPMna`Lnm@h^PqUF)5=!EEu=)uwU=)0qvqMwdl7X4E6mgsk) z_eP(M{x14bj5tOWqm3CFQy5beb6?COF^|XWh}j==A?A`L)MB+HTT(2kmO++WOMzvi zWt3$!t$3$c8ZB*>MV5yxk6E6yJY#vz@-NE^mbI2wEw5QNST)&DZ*$p|Qhb cb7J#i$Hi91a& From db99f2c07abd408b7d2f572ed78bc463a61b540f Mon Sep 17 00:00:00 2001 From: Brian Vallelunga Date: Sat, 16 Aug 2014 03:06:30 -0700 Subject: [PATCH 05/11] scaleable camera view --- VLBCameraView.xcodeproj/project.pbxproj | 16 +-- .../contents.xcworkspacedata | 1 - .../xcshareddata/VLBCameraView.xccheckout | 41 ------- VLBCameraView/VLBCameraView.h | 5 +- VLBCameraView/VLBCameraView.m | 18 ++- VLBCameraView/VLBCameraView.xib | 105 ++++++++++++------ 6 files changed, 87 insertions(+), 99 deletions(-) delete mode 100644 VLBCameraView.xcworkspace/contents.xcworkspacedata delete mode 100644 VLBCameraView.xcworkspace/xcshareddata/VLBCameraView.xccheckout diff --git a/VLBCameraView.xcodeproj/project.pbxproj b/VLBCameraView.xcodeproj/project.pbxproj index caa7d31..2a7db58 100644 --- a/VLBCameraView.xcodeproj/project.pbxproj +++ b/VLBCameraView.xcodeproj/project.pbxproj @@ -45,15 +45,10 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 305442DF5A6A4C36A0B159CD /* Pods.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.xcconfig; path = Pods/Pods.xcconfig; sourceTree = SOURCE_ROOT; }; - 35021534EBF8467782866427 /* Pods-UnitTests.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.xcconfig"; path = "Pods/Pods-UnitTests.xcconfig"; sourceTree = SOURCE_ROOT; }; - 357AE1252B2140F3977F19BE /* Pods.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.xcconfig; path = Pods/Pods.xcconfig; sourceTree = SOURCE_ROOT; }; 3E8915A70C194608B46A5442 /* libPods-UnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-UnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 6BDFC5F2E1CE467286E2530F /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; - A2CDF7F1A105493ABD9C885E /* Pods-UnitTests.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.xcconfig"; path = "Pods/Pods-UnitTests.xcconfig"; sourceTree = SOURCE_ROOT; }; BDBD0B2C17899C49003A7B23 /* CoreImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = System/Library/Frameworks/CoreImage.framework; sourceTree = SDKROOT; }; BDBD0B2E17899C4E003A7B23 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; }; - BDBD0B4B1789A191003A7B23 /* UnitTests copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "UnitTests copy-Info.plist"; path = "/Users/qnoid/Developer/workspace/objective-c/VLBCameraView/libVLBCameraView/UnitTests copy-Info.plist"; sourceTree = ""; }; BDBD0B571789A265003A7B23 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; BDBD0B5A1789A28D003A7B23 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; BDBD0B5F1789A3CA003A7B23 /* 8mpximage.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = 8mpximage.png; path = "Supporting Files/8mpximage.png"; sourceTree = ""; }; @@ -122,11 +117,6 @@ BDFD0AA91789800800DF1A90 /* VLBCameraViewTests */, BDFD0A911789800700DF1A90 /* Frameworks */, BDFD0A901789800700DF1A90 /* Products */, - A2CDF7F1A105493ABD9C885E /* Pods-UnitTests.xcconfig */, - 357AE1252B2140F3977F19BE /* Pods.xcconfig */, - 305442DF5A6A4C36A0B159CD /* Pods.xcconfig */, - 35021534EBF8467782866427 /* Pods-UnitTests.xcconfig */, - BDBD0B4B1789A191003A7B23 /* UnitTests copy-Info.plist */, ); sourceTree = ""; }; @@ -238,7 +228,7 @@ name = UnitTests; productName = VLBCameraViewTests; productReference = BDFD0AA01789800800DF1A90 /* UnitTests.octest */; - productType = "com.apple.product-type.bundle"; + productType = "com.apple.product-type.bundle.ocunit-test"; }; /* End PBXNativeTarget section */ @@ -495,7 +485,6 @@ }; BDFD0AB51789800800DF1A90 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 305442DF5A6A4C36A0B159CD /* Pods.xcconfig */; buildSettings = { DSTROOT = /tmp/VLBCameraView.dst; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -512,7 +501,6 @@ }; BDFD0AB61789800800DF1A90 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 305442DF5A6A4C36A0B159CD /* Pods.xcconfig */; buildSettings = { DSTROOT = /tmp/VLBCameraView.dst; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -529,7 +517,6 @@ }; BDFD0AB81789800800DF1A90 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 35021534EBF8467782866427 /* Pods-UnitTests.xcconfig */; buildSettings = { FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -548,7 +535,6 @@ }; BDFD0AB91789800800DF1A90 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 35021534EBF8467782866427 /* Pods-UnitTests.xcconfig */; buildSettings = { FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", diff --git a/VLBCameraView.xcworkspace/contents.xcworkspacedata b/VLBCameraView.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index b57c8d1..0000000 --- a/VLBCameraView.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/VLBCameraView.xcworkspace/xcshareddata/VLBCameraView.xccheckout b/VLBCameraView.xcworkspace/xcshareddata/VLBCameraView.xccheckout deleted file mode 100644 index 43b5aa5..0000000 --- a/VLBCameraView.xcworkspace/xcshareddata/VLBCameraView.xccheckout +++ /dev/null @@ -1,41 +0,0 @@ - - - - - IDESourceControlProjectFavoriteDictionaryKey - - IDESourceControlProjectIdentifier - 0991394E-9D52-45F0-90F8-0F8102377FA5 - IDESourceControlProjectName - VLBCameraView - IDESourceControlProjectOriginsDictionary - - B119BC22-237D-40C8-A78B-1A366CBFEBCE - ssh://github.com/qnoid/VLBCameraView.git - - IDESourceControlProjectPath - VLBCameraView.xcworkspace - IDESourceControlProjectRelativeInstallPathDictionary - - B119BC22-237D-40C8-A78B-1A366CBFEBCE - .. - - IDESourceControlProjectURL - ssh://github.com/qnoid/VLBCameraView.git - IDESourceControlProjectVersion - 110 - IDESourceControlProjectWCCIdentifier - B119BC22-237D-40C8-A78B-1A366CBFEBCE - IDESourceControlProjectWCConfigurations - - - IDESourceControlRepositoryExtensionIdentifierKey - public.vcs.git - IDESourceControlWCCIdentifierKey - B119BC22-237D-40C8-A78B-1A366CBFEBCE - IDESourceControlWCCName - libVLBCameraView - - - - diff --git a/VLBCameraView/VLBCameraView.h b/VLBCameraView/VLBCameraView.h index 160722f..4975a59 100644 --- a/VLBCameraView/VLBCameraView.h +++ b/VLBCameraView/VLBCameraView.h @@ -139,7 +139,7 @@ extern VLBCameraViewMeta const VLBCameraViewMetaOriginalImage; /// @property(nonatomic, assign) BOOL writeToCameraRoll; - +@property(nonatomic, assign) AVCaptureDevicePosition *currentPosition; /** @@ -174,6 +174,7 @@ extern VLBCameraViewMeta const VLBCameraViewMetaOriginalImage; @callback on the main thread at VLBCameraViewDelegate#cameraView:willRetakePicture: */ - (void) retakePicture; --(AVCaptureDevice *)frontFacingCameraIfAvailable; +- (void) toggleCamera; +-(AVCaptureDevice *)getCamera:(AVCaptureDevicePosition *)postion; @end diff --git a/VLBCameraView/VLBCameraView.m b/VLBCameraView/VLBCameraView.m index 533ea89..e191e6a 100644 --- a/VLBCameraView/VLBCameraView.m +++ b/VLBCameraView/VLBCameraView.m @@ -66,6 +66,7 @@ @implementation VLBCameraView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; + self.currentPosition = AVCaptureDevicePositionBack VLB_IF_NOT_SELF_RETURN_NIL(); VLB_LOAD_VIEW() @@ -78,6 +79,7 @@ - (id)initWithFrame:(CGRect)frame -(id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; + self.currentPosition = AVCaptureDevicePositionBack VLB_IF_NOT_SELF_RETURN_NIL(); VLB_LOAD_VIEW() @@ -140,7 +142,7 @@ -(void)awakeFromNib if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { NSError *error = nil; - AVCaptureDevice *device = [self frontFacingCameraIfAvailable]; + AVCaptureDevice *device = [self getCamera:self.currentPosition] if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) { NSError *error; @@ -251,13 +253,23 @@ - (void)retakePicture:(UITapGestureRecognizer*) tapToRetakeGesture [self retakePicture]; } --(AVCaptureDevice *)frontFacingCameraIfAvailable +-(void)toggleCamera { + if (self.currentPosition == AVCaptureDevicePositionBack) { + self.currentPosition = AVCaptureDevicePositionFront + } else { + self.currentPosition = AVCaptureDevicePositionBack + } + + [self retakePicture] +} + +-(AVCaptureDevice *)getCamera:(AVCaptureDevicePosition *)postion { NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; AVCaptureDevice *captureDevice = nil; for (AVCaptureDevice *device in videoDevices) { - if (device.position == AVCaptureDevicePositionFront) + if (device.position == postion) { captureDevice = device; break; diff --git a/VLBCameraView/VLBCameraView.xib b/VLBCameraView/VLBCameraView.xib index a75a641..8dcbd09 100644 --- a/VLBCameraView/VLBCameraView.xib +++ b/VLBCameraView/VLBCameraView.xib @@ -1,14 +1,14 @@ - 1552 - 12E55 - 3084 - 1187.39 - 626.00 + 2048 + 14A314h + 6205 + 1328.11 + 745.00 com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 2083 + 6198 IBProxyObject @@ -31,11 +31,9 @@ IBCocoaTouchFramework - + 292 {320, 320} - - _NS:9 YES 2 @@ -43,7 +41,7 @@ - + preview @@ -66,17 +64,71 @@ File's Owner + + + + + -2 + + + + + 5 preview + + + + + + + + + + 1 + {0, 0} + + + + + + + + 2 + {320, 320} + + + + + + + + + + + + + + + + + + + + + + + + @@ -93,36 +145,15 @@ 7 - - - - VLBCameraView - UIView - - NSObject - UIImageView - - - - delegate - NSObject - - - preview - UIImageView - - - - IBProjectSource - ./Classes/VLBCameraView.h - - - - + 0 IBCocoaTouchFramework + NO + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + YES 3 - 2083 From 34df59950a83a9aac177a797be940329805e4273 Mon Sep 17 00:00:00 2001 From: Brian Vallelunga Date: Sat, 16 Aug 2014 03:58:46 -0700 Subject: [PATCH 06/11] toggling of camera working --- VLBCameraView/VLBCameraView.h | 21 +++++----- VLBCameraView/VLBCameraView.m | 75 ++++++++++++++++++++--------------- 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/VLBCameraView/VLBCameraView.h b/VLBCameraView/VLBCameraView.h index 4975a59..da5704c 100644 --- a/VLBCameraView/VLBCameraView.h +++ b/VLBCameraView/VLBCameraView.h @@ -51,7 +51,7 @@ extern VLBCameraViewMeta const VLBCameraViewMetaOriginalImage; @protocol VLBCameraViewDelegate /** - Implement to get a callaback on the main thread with the image on VLBCameraView#takePicture: only if an error didn't + Implement to get a callaback on the main thread with the image on VLBCameraView#takePicture: only if an error didn't occur. @param cameraView the VLBCameraView intance that this delegate is assigned to @@ -77,8 +77,8 @@ extern VLBCameraViewMeta const VLBCameraViewMetaOriginalImage; Will get a callback to customise the underlying AVCaptureConnection when created. AVCaptureConnection has the following properties already set: - - videoOrientation = AVCaptureVideoOrientationPortrait; + + videoOrientation = AVCaptureVideoOrientationPortrait; @param cameraView the VLBCameraView instance this delegate is assigned to @param captureConnection the AVCaptureConnection instance that will be used to capture the image @@ -114,9 +114,9 @@ extern VLBCameraViewMeta const VLBCameraViewMetaOriginalImage; The view controller that has VLBCameraView in its hierarchy should set the image from cameraView:didFinishTakingPicture:editingInfo #preview.image on #viewWillAppear - + Portrait, iPhone only orientation - @see + @see */ @interface VLBCameraView : UIView @@ -139,7 +139,7 @@ extern VLBCameraViewMeta const VLBCameraViewMetaOriginalImage; /// @property(nonatomic, assign) BOOL writeToCameraRoll; -@property(nonatomic, assign) AVCaptureDevicePosition *currentPosition; +@property(nonatomic, assign) BOOL *cameraIsFrontFacing; /** @@ -150,7 +150,7 @@ extern VLBCameraViewMeta const VLBCameraViewMetaOriginalImage; /** Set backgroundColor to a custom one - backgroundColor = [UIColor whiteColor]; + backgroundColor = [UIColor whiteColor]; */ @property(nonatomic, strong) UIView *flashView; @@ -167,14 +167,15 @@ extern VLBCameraViewMeta const VLBCameraViewMetaOriginalImage; /** - Restart the take picture session as if the user had tapped on the view with the VLBCameraView#allowPictureRetake property set to YES. + Restart the take picture session as if the user had tapped on the view with the VLBCameraView#allowPictureRetake property set to YES. Does not block. - + @callback on the main thread at VLBCameraViewDelegate#cameraView:willRetakePicture: */ - (void) retakePicture; - (void) toggleCamera; --(AVCaptureDevice *)getCamera:(AVCaptureDevicePosition *)postion; +-(AVCaptureDevice *)getCamera; +-(AVCaptureInput *)getDeviceInput; @end diff --git a/VLBCameraView/VLBCameraView.m b/VLBCameraView/VLBCameraView.m index e191e6a..1053f36 100644 --- a/VLBCameraView/VLBCameraView.m +++ b/VLBCameraView/VLBCameraView.m @@ -66,7 +66,7 @@ @implementation VLBCameraView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; - self.currentPosition = AVCaptureDevicePositionBack + self.cameraIsFrontFacing = NO; VLB_IF_NOT_SELF_RETURN_NIL(); VLB_LOAD_VIEW() @@ -79,7 +79,7 @@ - (id)initWithFrame:(CGRect)frame -(id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; - self.currentPosition = AVCaptureDevicePositionBack + self.cameraIsFrontFacing = NO; VLB_IF_NOT_SELF_RETURN_NIL(); VLB_LOAD_VIEW() @@ -140,33 +140,15 @@ -(VLBCaptureStillImageBlock) didFinishTakingPicture:(AVCaptureSession*) session -(void)awakeFromNib { if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { - NSError *error = nil; - - AVCaptureDevice *device = [self getCamera:self.currentPosition] - - if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) { - NSError *error; - if ([device lockForConfiguration:&error]) { - device.focusMode = AVCaptureFocusModeContinuousAutoFocus; - [device unlockForConfiguration]; - } + for (AVCaptureInput *oldInput in [self.session inputs]) { + [self.session removeInput:oldInput]; } - if([device isFlashModeSupported:AVCaptureFlashModeAuto]){ - if ([device lockForConfiguration:&error]) { - device.flashMode = AVCaptureFlashModeAuto; - [device unlockForConfiguration]; - } - } - - AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; - - if(error){ - [NSException raise:[NSString stringWithFormat:@"Failed with error %d", (int)[error code]] - format:[error localizedDescription], nil]; + for (AVCaptureOutput *oldOutput in [self.session outputs]) { + [self.session removeOutput:oldOutput]; } - [self.session addInput:deviceInput]; + [self.session addInput: [self getDeviceInput]]; self.stillImageOutput = [AVCaptureStillImageOutput new]; [self.session addOutput:self.stillImageOutput]; @@ -254,22 +236,51 @@ - (void)retakePicture:(UITapGestureRecognizer*) tapToRetakeGesture } -(void)toggleCamera { - if (self.currentPosition == AVCaptureDevicePositionBack) { - self.currentPosition = AVCaptureDevicePositionFront - } else { - self.currentPosition = AVCaptureDevicePositionBack + self.cameraIsFrontFacing = !self.cameraIsFrontFacing; + [self.session stopRunning]; + [self awakeFromNib]; +} + +-(AVCaptureInput *)getDeviceInput { + NSError *error = nil; + AVCaptureDevice *device = [self getCamera]; + + if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) { + NSError *error; + if ([device lockForConfiguration:&error]) { + device.focusMode = AVCaptureFocusModeContinuousAutoFocus; + [device unlockForConfiguration]; + } } - [self retakePicture] + if([device isFlashModeSupported:AVCaptureFlashModeAuto]){ + if ([device lockForConfiguration:&error]) { + device.flashMode = AVCaptureFlashModeAuto; + [device unlockForConfiguration]; + } + } + + AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error]; + + if(error){ + [NSException raise:[NSString stringWithFormat:@"Failed with error %d", (int)[error code]] + format:[error localizedDescription], nil]; + } + + return deviceInput; } --(AVCaptureDevice *)getCamera:(AVCaptureDevicePosition *)postion +-(AVCaptureDevice *)getCamera { NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; AVCaptureDevice *captureDevice = nil; for (AVCaptureDevice *device in videoDevices) { - if (device.position == postion) + if (self.cameraIsFrontFacing && device.position == AVCaptureDevicePositionFront) + { + captureDevice = device; + break; + } else if (!self.cameraIsFrontFacing && device.position == AVCaptureDevicePositionBack) { captureDevice = device; break; From 024250bdc75553d6ed2a7ab2c40f2eab507c8e17 Mon Sep 17 00:00:00 2001 From: Brian Vallelunga Date: Sat, 16 Aug 2014 03:59:54 -0700 Subject: [PATCH 07/11] Update VLBCameraView.podspec --- VLBCameraView.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VLBCameraView.podspec b/VLBCameraView.podspec index 3ff0012..fc3a0cf 100644 --- a/VLBCameraView.podspec +++ b/VLBCameraView.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "VLBCameraView" - s.version = "2.0" + s.version = "2.1" s.summary = "A UIVIew that shows a live feed of the camera, can be used to take a picture, preview the picture and return a UIImage of that preview." s.homepage = "https://github.com/verylargebox/VLBCameraView" s.license = "MIT" From 82fcf1a94a404bf07af81aa53ed8a6233c7c40d7 Mon Sep 17 00:00:00 2001 From: Brian Vallelunga Date: Sat, 16 Aug 2014 04:01:30 -0700 Subject: [PATCH 08/11] Update Podfile --- Podfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Podfile b/Podfile index 40f44b0..c94de87 100644 --- a/Podfile +++ b/Podfile @@ -3,7 +3,7 @@ platform :ios, '6.0' target :UnitTests do pod 'OCMock', '~> 2.1.1' - pod 'Kiwi', '~> 2.0.6' + pod 'Kiwi', '~> 2.0.6' end podspec :path => 'VLBCameraView.podspec' From e80566ccc17b07b9b1f059b3fe7c9aa01c3135b3 Mon Sep 17 00:00:00 2001 From: Brian Vallelunga Date: Sat, 16 Aug 2014 04:02:31 -0700 Subject: [PATCH 09/11] Update VLBCameraView.podspec --- VLBCameraView.podspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VLBCameraView.podspec b/VLBCameraView.podspec index fc3a0cf..5255937 100644 --- a/VLBCameraView.podspec +++ b/VLBCameraView.podspec @@ -2,11 +2,11 @@ Pod::Spec.new do |s| s.name = "VLBCameraView" s.version = "2.1" s.summary = "A UIVIew that shows a live feed of the camera, can be used to take a picture, preview the picture and return a UIImage of that preview." - s.homepage = "https://github.com/verylargebox/VLBCameraView" + s.homepage = "https://github.com/JuicyApp/VLBCameraView" s.license = "MIT" s.author = { "Markos Charatzas" => "markos@qnoid.com" } - s.source = { :git => "https://github.com/verylargebox/VLBCameraView.git", :tag => "2.0" } + s.source = { :git => "https://github.com/JuicyApp/VLBCameraView.git", :tag => "2.1" } s.platform = :ios, '6.0' s.source_files = 'VLBCameraView/**/*.{h,m}' From c33a49b71445850fac4c5d7e6039a6a0579d166e Mon Sep 17 00:00:00 2001 From: Brian Vallelunga Date: Sun, 17 Aug 2014 02:10:05 -0700 Subject: [PATCH 10/11] added flip mirroring to front facing camera --- Podfile.lock | 19 + .../ContextFilterLogFormatter.h | 1 + .../CocoaLumberjack/DDASLLogger.h | 1 + .../DDAbstractDatabaseLogger.h | 1 + .../CocoaLumberjack/DDFileLogger.h | 1 + Pods/BuildHeaders/CocoaLumberjack/DDLog.h | 1 + .../CocoaLumberjack/DDTTYLogger.h | 1 + .../DispatchQueueLogFormatter.h | 1 + Pods/BuildHeaders/Kiwi/KWAfterAllNode.h | 1 + Pods/BuildHeaders/Kiwi/KWAfterEachNode.h | 1 + Pods/BuildHeaders/Kiwi/KWAny.h | 1 + Pods/BuildHeaders/Kiwi/KWAsyncVerifier.h | 1 + Pods/BuildHeaders/Kiwi/KWBeBetweenMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWBeEmptyMatcher.h | 1 + .../Kiwi/KWBeIdenticalToMatcher.h | 1 + .../Kiwi/KWBeKindOfClassMatcher.h | 1 + .../Kiwi/KWBeMemberOfClassMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWBeNilMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWBeNonNilMatcher.h | 1 + .../Kiwi/KWBeSubclassOfClassMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWBeTrueMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWBeWithinMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWBeZeroMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWBeforeAllNode.h | 1 + Pods/BuildHeaders/Kiwi/KWBeforeEachNode.h | 1 + Pods/BuildHeaders/Kiwi/KWBlock.h | 1 + Pods/BuildHeaders/Kiwi/KWBlockNode.h | 1 + Pods/BuildHeaders/Kiwi/KWBlockRaiseMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWCallSite.h | 1 + Pods/BuildHeaders/Kiwi/KWCaptureSpy.h | 1 + Pods/BuildHeaders/Kiwi/KWChangeMatcher.h | 1 + .../Kiwi/KWConformToProtocolMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWContainMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWContextNode.h | 1 + Pods/BuildHeaders/Kiwi/KWCountType.h | 1 + Pods/BuildHeaders/Kiwi/KWDeviceInfo.h | 1 + Pods/BuildHeaders/Kiwi/KWEqualMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWExample.h | 1 + .../BuildHeaders/Kiwi/KWExampleGroupBuilder.h | 1 + .../Kiwi/KWExampleGroupDelegate.h | 1 + Pods/BuildHeaders/Kiwi/KWExampleNode.h | 1 + Pods/BuildHeaders/Kiwi/KWExampleNodeVisitor.h | 1 + Pods/BuildHeaders/Kiwi/KWExampleSuite.h | 1 + Pods/BuildHeaders/Kiwi/KWExistVerifier.h | 1 + Pods/BuildHeaders/Kiwi/KWExpectationType.h | 1 + Pods/BuildHeaders/Kiwi/KWFailure.h | 1 + Pods/BuildHeaders/Kiwi/KWFormatter.h | 1 + Pods/BuildHeaders/Kiwi/KWFutureObject.h | 1 + .../Kiwi/KWGenericMatchEvaluator.h | 1 + Pods/BuildHeaders/Kiwi/KWGenericMatcher.h | 1 + .../Kiwi/KWGenericMatchingAdditions.h | 1 + Pods/BuildHeaders/Kiwi/KWHaveMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWHaveValueMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWInequalityMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWIntercept.h | 1 + Pods/BuildHeaders/Kiwi/KWInvocationCapturer.h | 1 + Pods/BuildHeaders/Kiwi/KWItNode.h | 1 + Pods/BuildHeaders/Kiwi/KWMatchVerifier.h | 1 + Pods/BuildHeaders/Kiwi/KWMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWMatcherFactory.h | 1 + Pods/BuildHeaders/Kiwi/KWMatchers.h | 1 + Pods/BuildHeaders/Kiwi/KWMatching.h | 1 + Pods/BuildHeaders/Kiwi/KWMessagePattern.h | 1 + Pods/BuildHeaders/Kiwi/KWMessageSpying.h | 1 + Pods/BuildHeaders/Kiwi/KWMessageTracker.h | 1 + Pods/BuildHeaders/Kiwi/KWMock.h | 1 + Pods/BuildHeaders/Kiwi/KWNull.h | 1 + Pods/BuildHeaders/Kiwi/KWObjCUtilities.h | 1 + Pods/BuildHeaders/Kiwi/KWPendingNode.h | 1 + Pods/BuildHeaders/Kiwi/KWProbe.h | 1 + Pods/BuildHeaders/Kiwi/KWProbePoller.h | 1 + Pods/BuildHeaders/Kiwi/KWRaiseMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWReceiveMatcher.h | 1 + .../Kiwi/KWRegisterMatchersNode.h | 1 + Pods/BuildHeaders/Kiwi/KWReporting.h | 1 + .../Kiwi/KWRespondToSelectorMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWSpec.h | 1 + .../Kiwi/KWStringContainsMatcher.h | 1 + .../BuildHeaders/Kiwi/KWStringPrefixMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWStringUtilities.h | 1 + Pods/BuildHeaders/Kiwi/KWStub.h | 1 + Pods/BuildHeaders/Kiwi/KWTestCase.h | 1 + Pods/BuildHeaders/Kiwi/KWUserDefinedMatcher.h | 1 + Pods/BuildHeaders/Kiwi/KWValue.h | 1 + Pods/BuildHeaders/Kiwi/KWVerifying.h | 1 + Pods/BuildHeaders/Kiwi/KWWorkarounds.h | 1 + Pods/BuildHeaders/Kiwi/Kiwi.h | 1 + Pods/BuildHeaders/Kiwi/KiwiBlockMacros.h | 1 + Pods/BuildHeaders/Kiwi/KiwiConfiguration.h | 1 + Pods/BuildHeaders/Kiwi/KiwiMacros.h | 1 + Pods/BuildHeaders/Kiwi/KiwiNewMacros.h | 1 + .../Kiwi/NSInvocation+KiwiAdditions.h | 1 + .../Kiwi/NSInvocation+OCMAdditions.h | 1 + .../Kiwi/NSMethodSignature+KiwiAdditions.h | 1 + .../Kiwi/NSNumber+KiwiAdditions.h | 1 + .../Kiwi/NSObject+KiwiMockAdditions.h | 1 + .../Kiwi/NSObject+KiwiSpyAdditions.h | 1 + .../Kiwi/NSObject+KiwiStubAdditions.h | 1 + .../Kiwi/NSObject+KiwiVerifierAdditions.h | 1 + .../Kiwi/NSProxy+KiwiVerifierAdditions.h | 1 + .../BuildHeaders/Kiwi/NSValue+KiwiAdditions.h | 1 + .../OCMock/NSInvocation+OCMAdditions.h | 1 + .../OCMock/NSMethodSignature+OCMAdditions.h | 1 + .../NSNotificationCenter+OCMAdditions.h | 1 + Pods/BuildHeaders/OCMock/OCClassMockObject.h | 1 + Pods/BuildHeaders/OCMock/OCMArg.h | 1 + Pods/BuildHeaders/OCMock/OCMBlockCaller.h | 1 + .../OCMock/OCMBoxedReturnValueProvider.h | 1 + Pods/BuildHeaders/OCMock/OCMConstraint.h | 1 + .../OCMock/OCMExceptionReturnValueProvider.h | 1 + .../OCMock/OCMIndirectReturnValueProvider.h | 1 + .../OCMock/OCMNotificationPoster.h | 1 + .../BuildHeaders/OCMock/OCMObserverRecorder.h | 1 + Pods/BuildHeaders/OCMock/OCMPassByRefSetter.h | 1 + .../OCMock/OCMRealObjectForwarder.h | 1 + .../OCMock/OCMReturnValueProvider.h | 1 + Pods/BuildHeaders/OCMock/OCMock.h | 1 + Pods/BuildHeaders/OCMock/OCMockObject.h | 1 + Pods/BuildHeaders/OCMock/OCMockRecorder.h | 1 + .../OCMock/OCObserverMockObject.h | 1 + .../BuildHeaders/OCMock/OCPartialMockObject.h | 1 + .../OCMock/OCPartialMockRecorder.h | 1 + .../OCMock/OCProtocolMockObject.h | 1 + Pods/BuildHeaders/VLBFoundation/VLBMacros.h | 1 + Pods/CocoaLumberjack/LICENSE.txt | 18 + Pods/CocoaLumberjack/Lumberjack/DDASLLogger.h | 41 + Pods/CocoaLumberjack/Lumberjack/DDASLLogger.m | 99 + .../Lumberjack/DDAbstractDatabaseLogger.h | 102 + .../Lumberjack/DDAbstractDatabaseLogger.m | 727 ++ .../CocoaLumberjack/Lumberjack/DDFileLogger.h | 334 + .../CocoaLumberjack/Lumberjack/DDFileLogger.m | 1353 +++ Pods/CocoaLumberjack/Lumberjack/DDLog.h | 601 ++ Pods/CocoaLumberjack/Lumberjack/DDLog.m | 1083 +++ Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.h | 167 + Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.m | 1479 +++ .../Extensions/ContextFilterLogFormatter.h | 65 + .../Extensions/ContextFilterLogFormatter.m | 191 + .../Extensions/DispatchQueueLogFormatter.h | 116 + .../Extensions/DispatchQueueLogFormatter.m | 251 + .../Lumberjack/Extensions/README.txt | 7 + Pods/CocoaLumberjack/README.markdown | 37 + .../ContextFilterLogFormatter.h | 1 + Pods/Headers/CocoaLumberjack/DDASLLogger.h | 1 + .../DDAbstractDatabaseLogger.h | 1 + Pods/Headers/CocoaLumberjack/DDFileLogger.h | 1 + Pods/Headers/CocoaLumberjack/DDLog.h | 1 + Pods/Headers/CocoaLumberjack/DDTTYLogger.h | 1 + .../DispatchQueueLogFormatter.h | 1 + Pods/Headers/Kiwi/KWAfterAllNode.h | 1 + Pods/Headers/Kiwi/KWAfterEachNode.h | 1 + Pods/Headers/Kiwi/KWAny.h | 1 + Pods/Headers/Kiwi/KWAsyncVerifier.h | 1 + Pods/Headers/Kiwi/KWBeBetweenMatcher.h | 1 + Pods/Headers/Kiwi/KWBeEmptyMatcher.h | 1 + Pods/Headers/Kiwi/KWBeIdenticalToMatcher.h | 1 + Pods/Headers/Kiwi/KWBeKindOfClassMatcher.h | 1 + Pods/Headers/Kiwi/KWBeMemberOfClassMatcher.h | 1 + Pods/Headers/Kiwi/KWBeNilMatcher.h | 1 + Pods/Headers/Kiwi/KWBeNonNilMatcher.h | 1 + .../Headers/Kiwi/KWBeSubclassOfClassMatcher.h | 1 + Pods/Headers/Kiwi/KWBeTrueMatcher.h | 1 + Pods/Headers/Kiwi/KWBeWithinMatcher.h | 1 + Pods/Headers/Kiwi/KWBeZeroMatcher.h | 1 + Pods/Headers/Kiwi/KWBeforeAllNode.h | 1 + Pods/Headers/Kiwi/KWBeforeEachNode.h | 1 + Pods/Headers/Kiwi/KWBlock.h | 1 + Pods/Headers/Kiwi/KWBlockNode.h | 1 + Pods/Headers/Kiwi/KWBlockRaiseMatcher.h | 1 + Pods/Headers/Kiwi/KWCallSite.h | 1 + Pods/Headers/Kiwi/KWCaptureSpy.h | 1 + Pods/Headers/Kiwi/KWChangeMatcher.h | 1 + .../Headers/Kiwi/KWConformToProtocolMatcher.h | 1 + Pods/Headers/Kiwi/KWContainMatcher.h | 1 + Pods/Headers/Kiwi/KWContextNode.h | 1 + Pods/Headers/Kiwi/KWCountType.h | 1 + Pods/Headers/Kiwi/KWDeviceInfo.h | 1 + Pods/Headers/Kiwi/KWEqualMatcher.h | 1 + Pods/Headers/Kiwi/KWExample.h | 1 + Pods/Headers/Kiwi/KWExampleGroupBuilder.h | 1 + Pods/Headers/Kiwi/KWExampleGroupDelegate.h | 1 + Pods/Headers/Kiwi/KWExampleNode.h | 1 + Pods/Headers/Kiwi/KWExampleNodeVisitor.h | 1 + Pods/Headers/Kiwi/KWExampleSuite.h | 1 + Pods/Headers/Kiwi/KWExistVerifier.h | 1 + Pods/Headers/Kiwi/KWExpectationType.h | 1 + Pods/Headers/Kiwi/KWFailure.h | 1 + Pods/Headers/Kiwi/KWFormatter.h | 1 + Pods/Headers/Kiwi/KWFutureObject.h | 1 + Pods/Headers/Kiwi/KWGenericMatchEvaluator.h | 1 + Pods/Headers/Kiwi/KWGenericMatcher.h | 1 + .../Headers/Kiwi/KWGenericMatchingAdditions.h | 1 + Pods/Headers/Kiwi/KWHaveMatcher.h | 1 + Pods/Headers/Kiwi/KWHaveValueMatcher.h | 1 + Pods/Headers/Kiwi/KWInequalityMatcher.h | 1 + Pods/Headers/Kiwi/KWIntercept.h | 1 + Pods/Headers/Kiwi/KWInvocationCapturer.h | 1 + Pods/Headers/Kiwi/KWItNode.h | 1 + Pods/Headers/Kiwi/KWMatchVerifier.h | 1 + Pods/Headers/Kiwi/KWMatcher.h | 1 + Pods/Headers/Kiwi/KWMatcherFactory.h | 1 + Pods/Headers/Kiwi/KWMatchers.h | 1 + Pods/Headers/Kiwi/KWMatching.h | 1 + Pods/Headers/Kiwi/KWMessagePattern.h | 1 + Pods/Headers/Kiwi/KWMessageSpying.h | 1 + Pods/Headers/Kiwi/KWMessageTracker.h | 1 + Pods/Headers/Kiwi/KWMock.h | 1 + Pods/Headers/Kiwi/KWNull.h | 1 + Pods/Headers/Kiwi/KWObjCUtilities.h | 1 + Pods/Headers/Kiwi/KWPendingNode.h | 1 + Pods/Headers/Kiwi/KWProbe.h | 1 + Pods/Headers/Kiwi/KWProbePoller.h | 1 + Pods/Headers/Kiwi/KWRaiseMatcher.h | 1 + Pods/Headers/Kiwi/KWReceiveMatcher.h | 1 + Pods/Headers/Kiwi/KWRegisterMatchersNode.h | 1 + Pods/Headers/Kiwi/KWReporting.h | 1 + .../Headers/Kiwi/KWRespondToSelectorMatcher.h | 1 + Pods/Headers/Kiwi/KWSpec.h | 1 + Pods/Headers/Kiwi/KWStringContainsMatcher.h | 1 + Pods/Headers/Kiwi/KWStringPrefixMatcher.h | 1 + Pods/Headers/Kiwi/KWStringUtilities.h | 1 + Pods/Headers/Kiwi/KWStub.h | 1 + Pods/Headers/Kiwi/KWTestCase.h | 1 + Pods/Headers/Kiwi/KWUserDefinedMatcher.h | 1 + Pods/Headers/Kiwi/KWValue.h | 1 + Pods/Headers/Kiwi/KWVerifying.h | 1 + Pods/Headers/Kiwi/KWWorkarounds.h | 1 + Pods/Headers/Kiwi/Kiwi.h | 1 + Pods/Headers/Kiwi/KiwiBlockMacros.h | 1 + Pods/Headers/Kiwi/KiwiConfiguration.h | 1 + Pods/Headers/Kiwi/KiwiMacros.h | 1 + Pods/Headers/Kiwi/KiwiNewMacros.h | 1 + .../Headers/Kiwi/NSInvocation+KiwiAdditions.h | 1 + Pods/Headers/Kiwi/NSInvocation+OCMAdditions.h | 1 + .../Kiwi/NSMethodSignature+KiwiAdditions.h | 1 + Pods/Headers/Kiwi/NSNumber+KiwiAdditions.h | 1 + .../Headers/Kiwi/NSObject+KiwiMockAdditions.h | 1 + Pods/Headers/Kiwi/NSObject+KiwiSpyAdditions.h | 1 + .../Headers/Kiwi/NSObject+KiwiStubAdditions.h | 1 + .../Kiwi/NSObject+KiwiVerifierAdditions.h | 1 + .../Kiwi/NSProxy+KiwiVerifierAdditions.h | 1 + Pods/Headers/Kiwi/NSValue+KiwiAdditions.h | 1 + .../OCMock/NSInvocation+OCMAdditions.h | 1 + .../OCMock/NSMethodSignature+OCMAdditions.h | 1 + .../NSNotificationCenter+OCMAdditions.h | 1 + Pods/Headers/OCMock/OCClassMockObject.h | 1 + Pods/Headers/OCMock/OCMArg.h | 1 + Pods/Headers/OCMock/OCMBlockCaller.h | 1 + .../OCMock/OCMBoxedReturnValueProvider.h | 1 + Pods/Headers/OCMock/OCMConstraint.h | 1 + .../OCMock/OCMExceptionReturnValueProvider.h | 1 + .../OCMock/OCMIndirectReturnValueProvider.h | 1 + Pods/Headers/OCMock/OCMNotificationPoster.h | 1 + Pods/Headers/OCMock/OCMObserverRecorder.h | 1 + Pods/Headers/OCMock/OCMPassByRefSetter.h | 1 + Pods/Headers/OCMock/OCMRealObjectForwarder.h | 1 + Pods/Headers/OCMock/OCMReturnValueProvider.h | 1 + Pods/Headers/OCMock/OCMock.h | 1 + Pods/Headers/OCMock/OCMockObject.h | 1 + Pods/Headers/OCMock/OCMockRecorder.h | 1 + Pods/Headers/OCMock/OCObserverMockObject.h | 1 + Pods/Headers/OCMock/OCPartialMockObject.h | 1 + Pods/Headers/OCMock/OCPartialMockRecorder.h | 1 + Pods/Headers/OCMock/OCProtocolMockObject.h | 1 + Pods/Headers/VLBFoundation/VLBMacros.h | 1 + Pods/Kiwi/Classes/KWAfterAllNode.h | 18 + Pods/Kiwi/Classes/KWAfterAllNode.m | 26 + Pods/Kiwi/Classes/KWAfterEachNode.h | 18 + Pods/Kiwi/Classes/KWAfterEachNode.m | 26 + Pods/Kiwi/Classes/KWAny.h | 18 + Pods/Kiwi/Classes/KWAny.m | 47 + Pods/Kiwi/Classes/KWAsyncVerifier.h | 35 + Pods/Kiwi/Classes/KWAsyncVerifier.m | 99 + Pods/Kiwi/Classes/KWBeBetweenMatcher.h | 23 + Pods/Kiwi/Classes/KWBeBetweenMatcher.m | 84 + Pods/Kiwi/Classes/KWBeEmptyMatcher.h | 20 + Pods/Kiwi/Classes/KWBeEmptyMatcher.m | 79 + Pods/Kiwi/Classes/KWBeIdenticalToMatcher.h | 20 + Pods/Kiwi/Classes/KWBeIdenticalToMatcher.m | 77 + Pods/Kiwi/Classes/KWBeKindOfClassMatcher.h | 20 + Pods/Kiwi/Classes/KWBeKindOfClassMatcher.m | 60 + Pods/Kiwi/Classes/KWBeMemberOfClassMatcher.h | 20 + Pods/Kiwi/Classes/KWBeMemberOfClassMatcher.m | 61 + Pods/Kiwi/Classes/KWBeNilMatcher.h | 16 + Pods/Kiwi/Classes/KWBeNilMatcher.m | 48 + Pods/Kiwi/Classes/KWBeNonNilMatcher.h | 16 + Pods/Kiwi/Classes/KWBeNonNilMatcher.m | 48 + .../Kiwi/Classes/KWBeSubclassOfClassMatcher.h | 20 + .../Kiwi/Classes/KWBeSubclassOfClassMatcher.m | 61 + Pods/Kiwi/Classes/KWBeTrueMatcher.h | 23 + Pods/Kiwi/Classes/KWBeTrueMatcher.m | 77 + Pods/Kiwi/Classes/KWBeWithinMatcher.h | 22 + Pods/Kiwi/Classes/KWBeWithinMatcher.m | 114 + Pods/Kiwi/Classes/KWBeZeroMatcher.h | 17 + Pods/Kiwi/Classes/KWBeZeroMatcher.m | 48 + Pods/Kiwi/Classes/KWBeforeAllNode.h | 18 + Pods/Kiwi/Classes/KWBeforeAllNode.m | 26 + Pods/Kiwi/Classes/KWBeforeEachNode.h | 18 + Pods/Kiwi/Classes/KWBeforeEachNode.m | 26 + Pods/Kiwi/Classes/KWBlock.h | 33 + Pods/Kiwi/Classes/KWBlock.m | 63 + Pods/Kiwi/Classes/KWBlockNode.h | 44 + Pods/Kiwi/Classes/KWBlockNode.m | 53 + Pods/Kiwi/Classes/KWBlockRaiseMatcher.h | 24 + Pods/Kiwi/Classes/KWBlockRaiseMatcher.m | 126 + Pods/Kiwi/Classes/KWCallSite.h | 33 + Pods/Kiwi/Classes/KWCallSite.m | 56 + Pods/Kiwi/Classes/KWCaptureSpy.h | 14 + Pods/Kiwi/Classes/KWCaptureSpy.m | 49 + Pods/Kiwi/Classes/KWChangeMatcher.h | 21 + Pods/Kiwi/Classes/KWChangeMatcher.m | 84 + .../Kiwi/Classes/KWConformToProtocolMatcher.h | 20 + .../Kiwi/Classes/KWConformToProtocolMatcher.m | 60 + Pods/Kiwi/Classes/KWContainMatcher.h | 31 + Pods/Kiwi/Classes/KWContainMatcher.m | 110 + Pods/Kiwi/Classes/KWContextNode.h | 73 + Pods/Kiwi/Classes/KWContextNode.m | 147 + Pods/Kiwi/Classes/KWCountType.h | 15 + Pods/Kiwi/Classes/KWDeviceInfo.h | 17 + Pods/Kiwi/Classes/KWDeviceInfo.m | 32 + Pods/Kiwi/Classes/KWEqualMatcher.h | 20 + Pods/Kiwi/Classes/KWEqualMatcher.m | 79 + Pods/Kiwi/Classes/KWExample.h | 91 + Pods/Kiwi/Classes/KWExample.m | 349 + Pods/Kiwi/Classes/KWExampleGroupBuilder.h | 45 + Pods/Kiwi/Classes/KWExampleGroupBuilder.m | 200 + Pods/Kiwi/Classes/KWExampleGroupDelegate.h | 18 + Pods/Kiwi/Classes/KWExampleNode.h | 23 + Pods/Kiwi/Classes/KWExampleNodeVisitor.h | 34 + Pods/Kiwi/Classes/KWExampleSuite.h | 29 + Pods/Kiwi/Classes/KWExampleSuite.m | 87 + Pods/Kiwi/Classes/KWExistVerifier.h | 35 + Pods/Kiwi/Classes/KWExistVerifier.m | 78 + Pods/Kiwi/Classes/KWExpectationType.h | 15 + Pods/Kiwi/Classes/KWFailure.h | 37 + Pods/Kiwi/Classes/KWFailure.m | 68 + Pods/Kiwi/Classes/KWFormatter.h | 16 + Pods/Kiwi/Classes/KWFormatter.m | 51 + Pods/Kiwi/Classes/KWFutureObject.h | 20 + Pods/Kiwi/Classes/KWFutureObject.m | 43 + Pods/Kiwi/Classes/KWGenericMatchEvaluator.h | 17 + Pods/Kiwi/Classes/KWGenericMatchEvaluator.m | 67 + Pods/Kiwi/Classes/KWGenericMatcher.h | 19 + Pods/Kiwi/Classes/KWGenericMatcher.m | 62 + .../Kiwi/Classes/KWGenericMatchingAdditions.h | 34 + .../Kiwi/Classes/KWGenericMatchingAdditions.m | 72 + Pods/Kiwi/Classes/KWHaveMatcher.h | 54 + Pods/Kiwi/Classes/KWHaveMatcher.m | 262 + Pods/Kiwi/Classes/KWHaveValueMatcher.h | 28 + Pods/Kiwi/Classes/KWHaveValueMatcher.m | 152 + Pods/Kiwi/Classes/KWInequalityMatcher.h | 33 + Pods/Kiwi/Classes/KWInequalityMatcher.m | 122 + Pods/Kiwi/Classes/KWIntercept.h | 50 + Pods/Kiwi/Classes/KWIntercept.m | 336 + Pods/Kiwi/Classes/KWInvocationCapturer.h | 42 + Pods/Kiwi/Classes/KWInvocationCapturer.m | 97 + Pods/Kiwi/Classes/KWItNode.h | 28 + Pods/Kiwi/Classes/KWItNode.m | 72 + Pods/Kiwi/Classes/KWMatchVerifier.h | 45 + Pods/Kiwi/Classes/KWMatchVerifier.m | 181 + Pods/Kiwi/Classes/KWMatcher.h | 48 + Pods/Kiwi/Classes/KWMatcher.m | 91 + Pods/Kiwi/Classes/KWMatcherFactory.h | 51 + Pods/Kiwi/Classes/KWMatcherFactory.m | 155 + Pods/Kiwi/Classes/KWMatchers.h | 35 + Pods/Kiwi/Classes/KWMatchers.m | 72 + Pods/Kiwi/Classes/KWMatching.h | 45 + Pods/Kiwi/Classes/KWMessagePattern.h | 49 + Pods/Kiwi/Classes/KWMessagePattern.m | 231 + Pods/Kiwi/Classes/KWMessageSpying.h | 16 + Pods/Kiwi/Classes/KWMessageTracker.h | 53 + Pods/Kiwi/Classes/KWMessageTracker.m | 151 + Pods/Kiwi/Classes/KWMock.h | 103 + Pods/Kiwi/Classes/KWMock.m | 672 ++ Pods/Kiwi/Classes/KWNull.h | 19 + Pods/Kiwi/Classes/KWNull.m | 47 + Pods/Kiwi/Classes/KWObjCUtilities.h | 32 + Pods/Kiwi/Classes/KWObjCUtilities.m | 102 + Pods/Kiwi/Classes/KWPendingNode.h | 37 + Pods/Kiwi/Classes/KWPendingNode.m | 72 + Pods/Kiwi/Classes/KWProbe.h | 14 + Pods/Kiwi/Classes/KWProbePoller.h | 21 + Pods/Kiwi/Classes/KWProbePoller.m | 72 + Pods/Kiwi/Classes/KWRaiseMatcher.h | 25 + Pods/Kiwi/Classes/KWRaiseMatcher.m | 126 + Pods/Kiwi/Classes/KWReceiveMatcher.h | 63 + Pods/Kiwi/Classes/KWReceiveMatcher.m | 321 + Pods/Kiwi/Classes/KWRegisterMatchersNode.h | 35 + Pods/Kiwi/Classes/KWRegisterMatchersNode.m | 51 + Pods/Kiwi/Classes/KWReporting.h | 18 + .../Kiwi/Classes/KWRespondToSelectorMatcher.h | 20 + .../Kiwi/Classes/KWRespondToSelectorMatcher.m | 60 + Pods/Kiwi/Classes/KWSpec.h | 31 + Pods/Kiwi/Classes/KWSpec.m | 145 + Pods/Kiwi/Classes/KWStringContainsMatcher.h | 21 + Pods/Kiwi/Classes/KWStringContainsMatcher.m | 45 + Pods/Kiwi/Classes/KWStringPrefixMatcher.h | 18 + Pods/Kiwi/Classes/KWStringPrefixMatcher.m | 46 + Pods/Kiwi/Classes/KWStringUtilities.h | 20 + Pods/Kiwi/Classes/KWStringUtilities.m | 90 + Pods/Kiwi/Classes/KWStub.h | 48 + Pods/Kiwi/Classes/KWStub.m | 221 + Pods/Kiwi/Classes/KWTestCase.h | 45 + Pods/Kiwi/Classes/KWTestCase.m | 191 + Pods/Kiwi/Classes/KWUserDefinedMatcher.h | 62 + Pods/Kiwi/Classes/KWUserDefinedMatcher.m | 178 + Pods/Kiwi/Classes/KWValue.h | 97 + Pods/Kiwi/Classes/KWValue.m | 359 + Pods/Kiwi/Classes/KWVerifying.h | 23 + Pods/Kiwi/Classes/KWWorkarounds.h | 18 + Pods/Kiwi/Classes/KWWorkarounds.m | 26 + Pods/Kiwi/Classes/Kiwi.h | 100 + Pods/Kiwi/Classes/KiwiBlockMacros.h | 16 + Pods/Kiwi/Classes/KiwiConfiguration.h | 28 + Pods/Kiwi/Classes/KiwiMacros.h | 80 + Pods/Kiwi/Classes/KiwiNewMacros.h | 10 + .../Kiwi/Classes/NSInvocation+KiwiAdditions.h | 28 + .../Kiwi/Classes/NSInvocation+KiwiAdditions.m | 93 + Pods/Kiwi/Classes/NSInvocation+OCMAdditions.h | 34 + Pods/Kiwi/Classes/NSInvocation+OCMAdditions.m | 337 + .../Classes/NSMethodSignature+KiwiAdditions.h | 17 + .../Classes/NSMethodSignature+KiwiAdditions.m | 22 + Pods/Kiwi/Classes/NSNumber+KiwiAdditions.h | 31 + Pods/Kiwi/Classes/NSNumber+KiwiAdditions.m | 111 + .../Kiwi/Classes/NSObject+KiwiMockAdditions.h | 20 + .../Kiwi/Classes/NSObject+KiwiMockAdditions.m | 31 + Pods/Kiwi/Classes/NSObject+KiwiSpyAdditions.h | 14 + Pods/Kiwi/Classes/NSObject+KiwiSpyAdditions.m | 29 + .../Kiwi/Classes/NSObject+KiwiStubAdditions.h | 54 + .../Kiwi/Classes/NSObject+KiwiStubAdditions.m | 248 + .../Classes/NSObject+KiwiVerifierAdditions.h | 19 + .../Classes/NSObject+KiwiVerifierAdditions.m | 26 + .../Classes/NSProxy+KiwiVerifierAdditions.h | 21 + .../Classes/NSProxy+KiwiVerifierAdditions.m | 28 + Pods/Kiwi/Classes/NSValue+KiwiAdditions.h | 16 + Pods/Kiwi/Classes/NSValue+KiwiAdditions.m | 24 + Pods/Kiwi/License.txt | 27 + Pods/Kiwi/Readme.md | 51 + Pods/Manifest.lock | 19 + Pods/OCMock/README.md | 10 + .../Source/OCMock/NSInvocation+OCMAdditions.h | 34 + .../Source/OCMock/NSInvocation+OCMAdditions.m | 337 + .../OCMock/NSMethodSignature+OCMAdditions.h | 18 + .../OCMock/NSMethodSignature+OCMAdditions.m | 19 + .../NSNotificationCenter+OCMAdditions.h | 15 + .../NSNotificationCenter+OCMAdditions.m | 17 + Pods/OCMock/Source/OCMock/OCClassMockObject.h | 21 + Pods/OCMock/Source/OCMock/OCClassMockObject.m | 160 + Pods/OCMock/Source/OCMock/OCMArg.h | 34 + Pods/OCMock/Source/OCMock/OCMArg.m | 79 + Pods/OCMock/Source/OCMock/OCMBlockCaller.h | 21 + Pods/OCMock/Source/OCMock/OCMBlockCaller.m | 32 + .../OCMock/OCMBoxedReturnValueProvider.h | 12 + .../OCMock/OCMBoxedReturnValueProvider.m | 21 + Pods/OCMock/Source/OCMock/OCMConstraint.h | 64 + Pods/OCMock/Source/OCMock/OCMConstraint.m | 142 + .../OCMock/OCMExceptionReturnValueProvider.h | 12 + .../OCMock/OCMExceptionReturnValueProvider.m | 16 + .../OCMock/OCMIndirectReturnValueProvider.h | 18 + .../OCMock/OCMIndirectReturnValueProvider.m | 33 + .../Source/OCMock/OCMNotificationPoster.h | 17 + .../Source/OCMock/OCMNotificationPoster.m | 30 + .../Source/OCMock/OCMObserverRecorder.h | 19 + .../Source/OCMock/OCMObserverRecorder.m | 75 + .../OCMock/Source/OCMock/OCMPassByRefSetter.h | 17 + .../OCMock/Source/OCMock/OCMPassByRefSetter.m | 29 + .../Source/OCMock/OCMRealObjectForwarder.h | 14 + .../Source/OCMock/OCMRealObjectForwarder.m | 29 + .../Source/OCMock/OCMReturnValueProvider.h | 17 + .../Source/OCMock/OCMReturnValueProvider.m | 47 + Pods/OCMock/Source/OCMock/OCMock.h | 10 + Pods/OCMock/Source/OCMock/OCMockObject.h | 46 + Pods/OCMock/Source/OCMock/OCMockObject.m | 269 + Pods/OCMock/Source/OCMock/OCMockRecorder.h | 36 + Pods/OCMock/Source/OCMock/OCMockRecorder.m | 229 + .../Source/OCMock/OCObserverMockObject.h | 22 + .../Source/OCMock/OCObserverMockObject.m | 83 + .../Source/OCMock/OCPartialMockObject.h | 25 + .../Source/OCMock/OCPartialMockObject.m | 190 + .../Source/OCMock/OCPartialMockRecorder.h | 12 + .../Source/OCMock/OCPartialMockRecorder.m | 27 + .../Source/OCMock/OCProtocolMockObject.h | 16 + .../Source/OCMock/OCProtocolMockObject.m | 53 + Pods/Pods-CocoaLumberjack-Private.xcconfig | 5 + Pods/Pods-CocoaLumberjack-dummy.m | 5 + Pods/Pods-CocoaLumberjack-prefix.pch | 5 + Pods/Pods-CocoaLumberjack.xcconfig | 0 ...UnitTests-CocoaLumberjack-Private.xcconfig | 5 + Pods/Pods-UnitTests-CocoaLumberjack-dummy.m | 5 + .../Pods-UnitTests-CocoaLumberjack-prefix.pch | 5 + Pods/Pods-UnitTests-CocoaLumberjack.xcconfig | 0 Pods/Pods-UnitTests-Kiwi-Private.xcconfig | 6 + Pods/Pods-UnitTests-Kiwi-dummy.m | 5 + Pods/Pods-UnitTests-Kiwi-prefix.pch | 5 + Pods/Pods-UnitTests-Kiwi.xcconfig | 2 + Pods/Pods-UnitTests-OCMock-Private.xcconfig | 5 + Pods/Pods-UnitTests-OCMock-dummy.m | 5 + Pods/Pods-UnitTests-OCMock-prefix.pch | 5 + Pods/Pods-UnitTests-OCMock.xcconfig | 0 ...s-UnitTests-VLBFoundation-Private.xcconfig | 5 + Pods/Pods-UnitTests-VLBFoundation-dummy.m | 5 + Pods/Pods-UnitTests-VLBFoundation-prefix.pch | 5 + Pods/Pods-UnitTests-VLBFoundation.xcconfig | 1 + Pods/Pods-UnitTests-acknowledgements.markdown | 86 + Pods/Pods-UnitTests-acknowledgements.plist | 128 + Pods/Pods-UnitTests-dummy.m | 5 + Pods/Pods-UnitTests-environment.h | 32 + Pods/Pods-UnitTests-resources.sh | 68 + Pods/Pods-UnitTests.xcconfig | 6 + Pods/Pods-VLBFoundation-Private.xcconfig | 5 + Pods/Pods-VLBFoundation-dummy.m | 5 + Pods/Pods-VLBFoundation-prefix.pch | 5 + Pods/Pods-VLBFoundation.xcconfig | 1 + Pods/Pods-acknowledgements.markdown | 37 + Pods/Pods-acknowledgements.plist | 71 + Pods/Pods-dummy.m | 5 + Pods/Pods-environment.h | 20 + Pods/Pods-resources.sh | 68 + Pods/Pods.xcconfig | 5 + Pods/Pods.xcodeproj/project.pbxproj | 8474 +++++++++++++++++ .../xcschemes/Pods-CocoaLumberjack.xcscheme | 59 + .../Pods-UnitTests-CocoaLumberjack.xcscheme | 59 + .../xcschemes/Pods-UnitTests-Kiwi.xcscheme | 59 + .../xcschemes/Pods-UnitTests-OCMock.xcscheme | 59 + .../Pods-UnitTests-VLBFoundation.xcscheme | 59 + .../xcschemes/Pods-UnitTests.xcscheme | 59 + .../xcschemes/Pods-VLBFoundation.xcscheme | 59 + .../Brian.xcuserdatad/xcschemes/Pods.xcscheme | 59 + .../xcschemes/xcschememanagement.plist | 51 + Pods/VLBFoundation/LICENCE | 9 + Pods/VLBFoundation/README.md | 46 + Pods/VLBFoundation/VLBFoundation/VLBMacros.h | 48 + .../contents.xcworkspacedata | 1 + VLBCameraView/VLBCameraView.m | 18 +- 533 files changed, 30785 insertions(+), 13 deletions(-) create mode 100644 Podfile.lock create mode 120000 Pods/BuildHeaders/CocoaLumberjack/ContextFilterLogFormatter.h create mode 120000 Pods/BuildHeaders/CocoaLumberjack/DDASLLogger.h create mode 120000 Pods/BuildHeaders/CocoaLumberjack/DDAbstractDatabaseLogger.h create mode 120000 Pods/BuildHeaders/CocoaLumberjack/DDFileLogger.h create mode 120000 Pods/BuildHeaders/CocoaLumberjack/DDLog.h create mode 120000 Pods/BuildHeaders/CocoaLumberjack/DDTTYLogger.h create mode 120000 Pods/BuildHeaders/CocoaLumberjack/DispatchQueueLogFormatter.h create mode 120000 Pods/BuildHeaders/Kiwi/KWAfterAllNode.h create mode 120000 Pods/BuildHeaders/Kiwi/KWAfterEachNode.h create mode 120000 Pods/BuildHeaders/Kiwi/KWAny.h create mode 120000 Pods/BuildHeaders/Kiwi/KWAsyncVerifier.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBeBetweenMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBeEmptyMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBeIdenticalToMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBeKindOfClassMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBeMemberOfClassMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBeNilMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBeNonNilMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBeSubclassOfClassMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBeTrueMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBeWithinMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBeZeroMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBeforeAllNode.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBeforeEachNode.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBlock.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBlockNode.h create mode 120000 Pods/BuildHeaders/Kiwi/KWBlockRaiseMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWCallSite.h create mode 120000 Pods/BuildHeaders/Kiwi/KWCaptureSpy.h create mode 120000 Pods/BuildHeaders/Kiwi/KWChangeMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWConformToProtocolMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWContainMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWContextNode.h create mode 120000 Pods/BuildHeaders/Kiwi/KWCountType.h create mode 120000 Pods/BuildHeaders/Kiwi/KWDeviceInfo.h create mode 120000 Pods/BuildHeaders/Kiwi/KWEqualMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWExample.h create mode 120000 Pods/BuildHeaders/Kiwi/KWExampleGroupBuilder.h create mode 120000 Pods/BuildHeaders/Kiwi/KWExampleGroupDelegate.h create mode 120000 Pods/BuildHeaders/Kiwi/KWExampleNode.h create mode 120000 Pods/BuildHeaders/Kiwi/KWExampleNodeVisitor.h create mode 120000 Pods/BuildHeaders/Kiwi/KWExampleSuite.h create mode 120000 Pods/BuildHeaders/Kiwi/KWExistVerifier.h create mode 120000 Pods/BuildHeaders/Kiwi/KWExpectationType.h create mode 120000 Pods/BuildHeaders/Kiwi/KWFailure.h create mode 120000 Pods/BuildHeaders/Kiwi/KWFormatter.h create mode 120000 Pods/BuildHeaders/Kiwi/KWFutureObject.h create mode 120000 Pods/BuildHeaders/Kiwi/KWGenericMatchEvaluator.h create mode 120000 Pods/BuildHeaders/Kiwi/KWGenericMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWGenericMatchingAdditions.h create mode 120000 Pods/BuildHeaders/Kiwi/KWHaveMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWHaveValueMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWInequalityMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWIntercept.h create mode 120000 Pods/BuildHeaders/Kiwi/KWInvocationCapturer.h create mode 120000 Pods/BuildHeaders/Kiwi/KWItNode.h create mode 120000 Pods/BuildHeaders/Kiwi/KWMatchVerifier.h create mode 120000 Pods/BuildHeaders/Kiwi/KWMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWMatcherFactory.h create mode 120000 Pods/BuildHeaders/Kiwi/KWMatchers.h create mode 120000 Pods/BuildHeaders/Kiwi/KWMatching.h create mode 120000 Pods/BuildHeaders/Kiwi/KWMessagePattern.h create mode 120000 Pods/BuildHeaders/Kiwi/KWMessageSpying.h create mode 120000 Pods/BuildHeaders/Kiwi/KWMessageTracker.h create mode 120000 Pods/BuildHeaders/Kiwi/KWMock.h create mode 120000 Pods/BuildHeaders/Kiwi/KWNull.h create mode 120000 Pods/BuildHeaders/Kiwi/KWObjCUtilities.h create mode 120000 Pods/BuildHeaders/Kiwi/KWPendingNode.h create mode 120000 Pods/BuildHeaders/Kiwi/KWProbe.h create mode 120000 Pods/BuildHeaders/Kiwi/KWProbePoller.h create mode 120000 Pods/BuildHeaders/Kiwi/KWRaiseMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWReceiveMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWRegisterMatchersNode.h create mode 120000 Pods/BuildHeaders/Kiwi/KWReporting.h create mode 120000 Pods/BuildHeaders/Kiwi/KWRespondToSelectorMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWSpec.h create mode 120000 Pods/BuildHeaders/Kiwi/KWStringContainsMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWStringPrefixMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWStringUtilities.h create mode 120000 Pods/BuildHeaders/Kiwi/KWStub.h create mode 120000 Pods/BuildHeaders/Kiwi/KWTestCase.h create mode 120000 Pods/BuildHeaders/Kiwi/KWUserDefinedMatcher.h create mode 120000 Pods/BuildHeaders/Kiwi/KWValue.h create mode 120000 Pods/BuildHeaders/Kiwi/KWVerifying.h create mode 120000 Pods/BuildHeaders/Kiwi/KWWorkarounds.h create mode 120000 Pods/BuildHeaders/Kiwi/Kiwi.h create mode 120000 Pods/BuildHeaders/Kiwi/KiwiBlockMacros.h create mode 120000 Pods/BuildHeaders/Kiwi/KiwiConfiguration.h create mode 120000 Pods/BuildHeaders/Kiwi/KiwiMacros.h create mode 120000 Pods/BuildHeaders/Kiwi/KiwiNewMacros.h create mode 120000 Pods/BuildHeaders/Kiwi/NSInvocation+KiwiAdditions.h create mode 120000 Pods/BuildHeaders/Kiwi/NSInvocation+OCMAdditions.h create mode 120000 Pods/BuildHeaders/Kiwi/NSMethodSignature+KiwiAdditions.h create mode 120000 Pods/BuildHeaders/Kiwi/NSNumber+KiwiAdditions.h create mode 120000 Pods/BuildHeaders/Kiwi/NSObject+KiwiMockAdditions.h create mode 120000 Pods/BuildHeaders/Kiwi/NSObject+KiwiSpyAdditions.h create mode 120000 Pods/BuildHeaders/Kiwi/NSObject+KiwiStubAdditions.h create mode 120000 Pods/BuildHeaders/Kiwi/NSObject+KiwiVerifierAdditions.h create mode 120000 Pods/BuildHeaders/Kiwi/NSProxy+KiwiVerifierAdditions.h create mode 120000 Pods/BuildHeaders/Kiwi/NSValue+KiwiAdditions.h create mode 120000 Pods/BuildHeaders/OCMock/NSInvocation+OCMAdditions.h create mode 120000 Pods/BuildHeaders/OCMock/NSMethodSignature+OCMAdditions.h create mode 120000 Pods/BuildHeaders/OCMock/NSNotificationCenter+OCMAdditions.h create mode 120000 Pods/BuildHeaders/OCMock/OCClassMockObject.h create mode 120000 Pods/BuildHeaders/OCMock/OCMArg.h create mode 120000 Pods/BuildHeaders/OCMock/OCMBlockCaller.h create mode 120000 Pods/BuildHeaders/OCMock/OCMBoxedReturnValueProvider.h create mode 120000 Pods/BuildHeaders/OCMock/OCMConstraint.h create mode 120000 Pods/BuildHeaders/OCMock/OCMExceptionReturnValueProvider.h create mode 120000 Pods/BuildHeaders/OCMock/OCMIndirectReturnValueProvider.h create mode 120000 Pods/BuildHeaders/OCMock/OCMNotificationPoster.h create mode 120000 Pods/BuildHeaders/OCMock/OCMObserverRecorder.h create mode 120000 Pods/BuildHeaders/OCMock/OCMPassByRefSetter.h create mode 120000 Pods/BuildHeaders/OCMock/OCMRealObjectForwarder.h create mode 120000 Pods/BuildHeaders/OCMock/OCMReturnValueProvider.h create mode 120000 Pods/BuildHeaders/OCMock/OCMock.h create mode 120000 Pods/BuildHeaders/OCMock/OCMockObject.h create mode 120000 Pods/BuildHeaders/OCMock/OCMockRecorder.h create mode 120000 Pods/BuildHeaders/OCMock/OCObserverMockObject.h create mode 120000 Pods/BuildHeaders/OCMock/OCPartialMockObject.h create mode 120000 Pods/BuildHeaders/OCMock/OCPartialMockRecorder.h create mode 120000 Pods/BuildHeaders/OCMock/OCProtocolMockObject.h create mode 120000 Pods/BuildHeaders/VLBFoundation/VLBMacros.h create mode 100644 Pods/CocoaLumberjack/LICENSE.txt create mode 100755 Pods/CocoaLumberjack/Lumberjack/DDASLLogger.h create mode 100755 Pods/CocoaLumberjack/Lumberjack/DDASLLogger.m create mode 100644 Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.h create mode 100644 Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.m create mode 100644 Pods/CocoaLumberjack/Lumberjack/DDFileLogger.h create mode 100644 Pods/CocoaLumberjack/Lumberjack/DDFileLogger.m create mode 100755 Pods/CocoaLumberjack/Lumberjack/DDLog.h create mode 100755 Pods/CocoaLumberjack/Lumberjack/DDLog.m create mode 100755 Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.h create mode 100755 Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.m create mode 100644 Pods/CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.h create mode 100644 Pods/CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.m create mode 100644 Pods/CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.h create mode 100644 Pods/CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.m create mode 100644 Pods/CocoaLumberjack/Lumberjack/Extensions/README.txt create mode 100644 Pods/CocoaLumberjack/README.markdown create mode 120000 Pods/Headers/CocoaLumberjack/ContextFilterLogFormatter.h create mode 120000 Pods/Headers/CocoaLumberjack/DDASLLogger.h create mode 120000 Pods/Headers/CocoaLumberjack/DDAbstractDatabaseLogger.h create mode 120000 Pods/Headers/CocoaLumberjack/DDFileLogger.h create mode 120000 Pods/Headers/CocoaLumberjack/DDLog.h create mode 120000 Pods/Headers/CocoaLumberjack/DDTTYLogger.h create mode 120000 Pods/Headers/CocoaLumberjack/DispatchQueueLogFormatter.h create mode 120000 Pods/Headers/Kiwi/KWAfterAllNode.h create mode 120000 Pods/Headers/Kiwi/KWAfterEachNode.h create mode 120000 Pods/Headers/Kiwi/KWAny.h create mode 120000 Pods/Headers/Kiwi/KWAsyncVerifier.h create mode 120000 Pods/Headers/Kiwi/KWBeBetweenMatcher.h create mode 120000 Pods/Headers/Kiwi/KWBeEmptyMatcher.h create mode 120000 Pods/Headers/Kiwi/KWBeIdenticalToMatcher.h create mode 120000 Pods/Headers/Kiwi/KWBeKindOfClassMatcher.h create mode 120000 Pods/Headers/Kiwi/KWBeMemberOfClassMatcher.h create mode 120000 Pods/Headers/Kiwi/KWBeNilMatcher.h create mode 120000 Pods/Headers/Kiwi/KWBeNonNilMatcher.h create mode 120000 Pods/Headers/Kiwi/KWBeSubclassOfClassMatcher.h create mode 120000 Pods/Headers/Kiwi/KWBeTrueMatcher.h create mode 120000 Pods/Headers/Kiwi/KWBeWithinMatcher.h create mode 120000 Pods/Headers/Kiwi/KWBeZeroMatcher.h create mode 120000 Pods/Headers/Kiwi/KWBeforeAllNode.h create mode 120000 Pods/Headers/Kiwi/KWBeforeEachNode.h create mode 120000 Pods/Headers/Kiwi/KWBlock.h create mode 120000 Pods/Headers/Kiwi/KWBlockNode.h create mode 120000 Pods/Headers/Kiwi/KWBlockRaiseMatcher.h create mode 120000 Pods/Headers/Kiwi/KWCallSite.h create mode 120000 Pods/Headers/Kiwi/KWCaptureSpy.h create mode 120000 Pods/Headers/Kiwi/KWChangeMatcher.h create mode 120000 Pods/Headers/Kiwi/KWConformToProtocolMatcher.h create mode 120000 Pods/Headers/Kiwi/KWContainMatcher.h create mode 120000 Pods/Headers/Kiwi/KWContextNode.h create mode 120000 Pods/Headers/Kiwi/KWCountType.h create mode 120000 Pods/Headers/Kiwi/KWDeviceInfo.h create mode 120000 Pods/Headers/Kiwi/KWEqualMatcher.h create mode 120000 Pods/Headers/Kiwi/KWExample.h create mode 120000 Pods/Headers/Kiwi/KWExampleGroupBuilder.h create mode 120000 Pods/Headers/Kiwi/KWExampleGroupDelegate.h create mode 120000 Pods/Headers/Kiwi/KWExampleNode.h create mode 120000 Pods/Headers/Kiwi/KWExampleNodeVisitor.h create mode 120000 Pods/Headers/Kiwi/KWExampleSuite.h create mode 120000 Pods/Headers/Kiwi/KWExistVerifier.h create mode 120000 Pods/Headers/Kiwi/KWExpectationType.h create mode 120000 Pods/Headers/Kiwi/KWFailure.h create mode 120000 Pods/Headers/Kiwi/KWFormatter.h create mode 120000 Pods/Headers/Kiwi/KWFutureObject.h create mode 120000 Pods/Headers/Kiwi/KWGenericMatchEvaluator.h create mode 120000 Pods/Headers/Kiwi/KWGenericMatcher.h create mode 120000 Pods/Headers/Kiwi/KWGenericMatchingAdditions.h create mode 120000 Pods/Headers/Kiwi/KWHaveMatcher.h create mode 120000 Pods/Headers/Kiwi/KWHaveValueMatcher.h create mode 120000 Pods/Headers/Kiwi/KWInequalityMatcher.h create mode 120000 Pods/Headers/Kiwi/KWIntercept.h create mode 120000 Pods/Headers/Kiwi/KWInvocationCapturer.h create mode 120000 Pods/Headers/Kiwi/KWItNode.h create mode 120000 Pods/Headers/Kiwi/KWMatchVerifier.h create mode 120000 Pods/Headers/Kiwi/KWMatcher.h create mode 120000 Pods/Headers/Kiwi/KWMatcherFactory.h create mode 120000 Pods/Headers/Kiwi/KWMatchers.h create mode 120000 Pods/Headers/Kiwi/KWMatching.h create mode 120000 Pods/Headers/Kiwi/KWMessagePattern.h create mode 120000 Pods/Headers/Kiwi/KWMessageSpying.h create mode 120000 Pods/Headers/Kiwi/KWMessageTracker.h create mode 120000 Pods/Headers/Kiwi/KWMock.h create mode 120000 Pods/Headers/Kiwi/KWNull.h create mode 120000 Pods/Headers/Kiwi/KWObjCUtilities.h create mode 120000 Pods/Headers/Kiwi/KWPendingNode.h create mode 120000 Pods/Headers/Kiwi/KWProbe.h create mode 120000 Pods/Headers/Kiwi/KWProbePoller.h create mode 120000 Pods/Headers/Kiwi/KWRaiseMatcher.h create mode 120000 Pods/Headers/Kiwi/KWReceiveMatcher.h create mode 120000 Pods/Headers/Kiwi/KWRegisterMatchersNode.h create mode 120000 Pods/Headers/Kiwi/KWReporting.h create mode 120000 Pods/Headers/Kiwi/KWRespondToSelectorMatcher.h create mode 120000 Pods/Headers/Kiwi/KWSpec.h create mode 120000 Pods/Headers/Kiwi/KWStringContainsMatcher.h create mode 120000 Pods/Headers/Kiwi/KWStringPrefixMatcher.h create mode 120000 Pods/Headers/Kiwi/KWStringUtilities.h create mode 120000 Pods/Headers/Kiwi/KWStub.h create mode 120000 Pods/Headers/Kiwi/KWTestCase.h create mode 120000 Pods/Headers/Kiwi/KWUserDefinedMatcher.h create mode 120000 Pods/Headers/Kiwi/KWValue.h create mode 120000 Pods/Headers/Kiwi/KWVerifying.h create mode 120000 Pods/Headers/Kiwi/KWWorkarounds.h create mode 120000 Pods/Headers/Kiwi/Kiwi.h create mode 120000 Pods/Headers/Kiwi/KiwiBlockMacros.h create mode 120000 Pods/Headers/Kiwi/KiwiConfiguration.h create mode 120000 Pods/Headers/Kiwi/KiwiMacros.h create mode 120000 Pods/Headers/Kiwi/KiwiNewMacros.h create mode 120000 Pods/Headers/Kiwi/NSInvocation+KiwiAdditions.h create mode 120000 Pods/Headers/Kiwi/NSInvocation+OCMAdditions.h create mode 120000 Pods/Headers/Kiwi/NSMethodSignature+KiwiAdditions.h create mode 120000 Pods/Headers/Kiwi/NSNumber+KiwiAdditions.h create mode 120000 Pods/Headers/Kiwi/NSObject+KiwiMockAdditions.h create mode 120000 Pods/Headers/Kiwi/NSObject+KiwiSpyAdditions.h create mode 120000 Pods/Headers/Kiwi/NSObject+KiwiStubAdditions.h create mode 120000 Pods/Headers/Kiwi/NSObject+KiwiVerifierAdditions.h create mode 120000 Pods/Headers/Kiwi/NSProxy+KiwiVerifierAdditions.h create mode 120000 Pods/Headers/Kiwi/NSValue+KiwiAdditions.h create mode 120000 Pods/Headers/OCMock/NSInvocation+OCMAdditions.h create mode 120000 Pods/Headers/OCMock/NSMethodSignature+OCMAdditions.h create mode 120000 Pods/Headers/OCMock/NSNotificationCenter+OCMAdditions.h create mode 120000 Pods/Headers/OCMock/OCClassMockObject.h create mode 120000 Pods/Headers/OCMock/OCMArg.h create mode 120000 Pods/Headers/OCMock/OCMBlockCaller.h create mode 120000 Pods/Headers/OCMock/OCMBoxedReturnValueProvider.h create mode 120000 Pods/Headers/OCMock/OCMConstraint.h create mode 120000 Pods/Headers/OCMock/OCMExceptionReturnValueProvider.h create mode 120000 Pods/Headers/OCMock/OCMIndirectReturnValueProvider.h create mode 120000 Pods/Headers/OCMock/OCMNotificationPoster.h create mode 120000 Pods/Headers/OCMock/OCMObserverRecorder.h create mode 120000 Pods/Headers/OCMock/OCMPassByRefSetter.h create mode 120000 Pods/Headers/OCMock/OCMRealObjectForwarder.h create mode 120000 Pods/Headers/OCMock/OCMReturnValueProvider.h create mode 120000 Pods/Headers/OCMock/OCMock.h create mode 120000 Pods/Headers/OCMock/OCMockObject.h create mode 120000 Pods/Headers/OCMock/OCMockRecorder.h create mode 120000 Pods/Headers/OCMock/OCObserverMockObject.h create mode 120000 Pods/Headers/OCMock/OCPartialMockObject.h create mode 120000 Pods/Headers/OCMock/OCPartialMockRecorder.h create mode 120000 Pods/Headers/OCMock/OCProtocolMockObject.h create mode 120000 Pods/Headers/VLBFoundation/VLBMacros.h create mode 100644 Pods/Kiwi/Classes/KWAfterAllNode.h create mode 100644 Pods/Kiwi/Classes/KWAfterAllNode.m create mode 100644 Pods/Kiwi/Classes/KWAfterEachNode.h create mode 100644 Pods/Kiwi/Classes/KWAfterEachNode.m create mode 100644 Pods/Kiwi/Classes/KWAny.h create mode 100644 Pods/Kiwi/Classes/KWAny.m create mode 100644 Pods/Kiwi/Classes/KWAsyncVerifier.h create mode 100644 Pods/Kiwi/Classes/KWAsyncVerifier.m create mode 100644 Pods/Kiwi/Classes/KWBeBetweenMatcher.h create mode 100644 Pods/Kiwi/Classes/KWBeBetweenMatcher.m create mode 100644 Pods/Kiwi/Classes/KWBeEmptyMatcher.h create mode 100644 Pods/Kiwi/Classes/KWBeEmptyMatcher.m create mode 100644 Pods/Kiwi/Classes/KWBeIdenticalToMatcher.h create mode 100644 Pods/Kiwi/Classes/KWBeIdenticalToMatcher.m create mode 100644 Pods/Kiwi/Classes/KWBeKindOfClassMatcher.h create mode 100644 Pods/Kiwi/Classes/KWBeKindOfClassMatcher.m create mode 100644 Pods/Kiwi/Classes/KWBeMemberOfClassMatcher.h create mode 100644 Pods/Kiwi/Classes/KWBeMemberOfClassMatcher.m create mode 100644 Pods/Kiwi/Classes/KWBeNilMatcher.h create mode 100644 Pods/Kiwi/Classes/KWBeNilMatcher.m create mode 100644 Pods/Kiwi/Classes/KWBeNonNilMatcher.h create mode 100644 Pods/Kiwi/Classes/KWBeNonNilMatcher.m create mode 100644 Pods/Kiwi/Classes/KWBeSubclassOfClassMatcher.h create mode 100644 Pods/Kiwi/Classes/KWBeSubclassOfClassMatcher.m create mode 100644 Pods/Kiwi/Classes/KWBeTrueMatcher.h create mode 100644 Pods/Kiwi/Classes/KWBeTrueMatcher.m create mode 100644 Pods/Kiwi/Classes/KWBeWithinMatcher.h create mode 100644 Pods/Kiwi/Classes/KWBeWithinMatcher.m create mode 100644 Pods/Kiwi/Classes/KWBeZeroMatcher.h create mode 100644 Pods/Kiwi/Classes/KWBeZeroMatcher.m create mode 100644 Pods/Kiwi/Classes/KWBeforeAllNode.h create mode 100644 Pods/Kiwi/Classes/KWBeforeAllNode.m create mode 100644 Pods/Kiwi/Classes/KWBeforeEachNode.h create mode 100644 Pods/Kiwi/Classes/KWBeforeEachNode.m create mode 100644 Pods/Kiwi/Classes/KWBlock.h create mode 100644 Pods/Kiwi/Classes/KWBlock.m create mode 100644 Pods/Kiwi/Classes/KWBlockNode.h create mode 100644 Pods/Kiwi/Classes/KWBlockNode.m create mode 100644 Pods/Kiwi/Classes/KWBlockRaiseMatcher.h create mode 100644 Pods/Kiwi/Classes/KWBlockRaiseMatcher.m create mode 100644 Pods/Kiwi/Classes/KWCallSite.h create mode 100644 Pods/Kiwi/Classes/KWCallSite.m create mode 100644 Pods/Kiwi/Classes/KWCaptureSpy.h create mode 100644 Pods/Kiwi/Classes/KWCaptureSpy.m create mode 100644 Pods/Kiwi/Classes/KWChangeMatcher.h create mode 100644 Pods/Kiwi/Classes/KWChangeMatcher.m create mode 100644 Pods/Kiwi/Classes/KWConformToProtocolMatcher.h create mode 100644 Pods/Kiwi/Classes/KWConformToProtocolMatcher.m create mode 100644 Pods/Kiwi/Classes/KWContainMatcher.h create mode 100644 Pods/Kiwi/Classes/KWContainMatcher.m create mode 100644 Pods/Kiwi/Classes/KWContextNode.h create mode 100644 Pods/Kiwi/Classes/KWContextNode.m create mode 100644 Pods/Kiwi/Classes/KWCountType.h create mode 100644 Pods/Kiwi/Classes/KWDeviceInfo.h create mode 100644 Pods/Kiwi/Classes/KWDeviceInfo.m create mode 100644 Pods/Kiwi/Classes/KWEqualMatcher.h create mode 100644 Pods/Kiwi/Classes/KWEqualMatcher.m create mode 100644 Pods/Kiwi/Classes/KWExample.h create mode 100644 Pods/Kiwi/Classes/KWExample.m create mode 100644 Pods/Kiwi/Classes/KWExampleGroupBuilder.h create mode 100644 Pods/Kiwi/Classes/KWExampleGroupBuilder.m create mode 100644 Pods/Kiwi/Classes/KWExampleGroupDelegate.h create mode 100644 Pods/Kiwi/Classes/KWExampleNode.h create mode 100644 Pods/Kiwi/Classes/KWExampleNodeVisitor.h create mode 100644 Pods/Kiwi/Classes/KWExampleSuite.h create mode 100644 Pods/Kiwi/Classes/KWExampleSuite.m create mode 100644 Pods/Kiwi/Classes/KWExistVerifier.h create mode 100644 Pods/Kiwi/Classes/KWExistVerifier.m create mode 100644 Pods/Kiwi/Classes/KWExpectationType.h create mode 100644 Pods/Kiwi/Classes/KWFailure.h create mode 100644 Pods/Kiwi/Classes/KWFailure.m create mode 100644 Pods/Kiwi/Classes/KWFormatter.h create mode 100644 Pods/Kiwi/Classes/KWFormatter.m create mode 100644 Pods/Kiwi/Classes/KWFutureObject.h create mode 100644 Pods/Kiwi/Classes/KWFutureObject.m create mode 100644 Pods/Kiwi/Classes/KWGenericMatchEvaluator.h create mode 100644 Pods/Kiwi/Classes/KWGenericMatchEvaluator.m create mode 100644 Pods/Kiwi/Classes/KWGenericMatcher.h create mode 100644 Pods/Kiwi/Classes/KWGenericMatcher.m create mode 100644 Pods/Kiwi/Classes/KWGenericMatchingAdditions.h create mode 100644 Pods/Kiwi/Classes/KWGenericMatchingAdditions.m create mode 100644 Pods/Kiwi/Classes/KWHaveMatcher.h create mode 100644 Pods/Kiwi/Classes/KWHaveMatcher.m create mode 100644 Pods/Kiwi/Classes/KWHaveValueMatcher.h create mode 100644 Pods/Kiwi/Classes/KWHaveValueMatcher.m create mode 100644 Pods/Kiwi/Classes/KWInequalityMatcher.h create mode 100644 Pods/Kiwi/Classes/KWInequalityMatcher.m create mode 100644 Pods/Kiwi/Classes/KWIntercept.h create mode 100644 Pods/Kiwi/Classes/KWIntercept.m create mode 100644 Pods/Kiwi/Classes/KWInvocationCapturer.h create mode 100644 Pods/Kiwi/Classes/KWInvocationCapturer.m create mode 100644 Pods/Kiwi/Classes/KWItNode.h create mode 100644 Pods/Kiwi/Classes/KWItNode.m create mode 100644 Pods/Kiwi/Classes/KWMatchVerifier.h create mode 100644 Pods/Kiwi/Classes/KWMatchVerifier.m create mode 100644 Pods/Kiwi/Classes/KWMatcher.h create mode 100644 Pods/Kiwi/Classes/KWMatcher.m create mode 100644 Pods/Kiwi/Classes/KWMatcherFactory.h create mode 100644 Pods/Kiwi/Classes/KWMatcherFactory.m create mode 100644 Pods/Kiwi/Classes/KWMatchers.h create mode 100644 Pods/Kiwi/Classes/KWMatchers.m create mode 100644 Pods/Kiwi/Classes/KWMatching.h create mode 100644 Pods/Kiwi/Classes/KWMessagePattern.h create mode 100644 Pods/Kiwi/Classes/KWMessagePattern.m create mode 100644 Pods/Kiwi/Classes/KWMessageSpying.h create mode 100644 Pods/Kiwi/Classes/KWMessageTracker.h create mode 100644 Pods/Kiwi/Classes/KWMessageTracker.m create mode 100644 Pods/Kiwi/Classes/KWMock.h create mode 100644 Pods/Kiwi/Classes/KWMock.m create mode 100644 Pods/Kiwi/Classes/KWNull.h create mode 100644 Pods/Kiwi/Classes/KWNull.m create mode 100644 Pods/Kiwi/Classes/KWObjCUtilities.h create mode 100644 Pods/Kiwi/Classes/KWObjCUtilities.m create mode 100644 Pods/Kiwi/Classes/KWPendingNode.h create mode 100644 Pods/Kiwi/Classes/KWPendingNode.m create mode 100644 Pods/Kiwi/Classes/KWProbe.h create mode 100644 Pods/Kiwi/Classes/KWProbePoller.h create mode 100644 Pods/Kiwi/Classes/KWProbePoller.m create mode 100644 Pods/Kiwi/Classes/KWRaiseMatcher.h create mode 100644 Pods/Kiwi/Classes/KWRaiseMatcher.m create mode 100644 Pods/Kiwi/Classes/KWReceiveMatcher.h create mode 100644 Pods/Kiwi/Classes/KWReceiveMatcher.m create mode 100644 Pods/Kiwi/Classes/KWRegisterMatchersNode.h create mode 100644 Pods/Kiwi/Classes/KWRegisterMatchersNode.m create mode 100644 Pods/Kiwi/Classes/KWReporting.h create mode 100644 Pods/Kiwi/Classes/KWRespondToSelectorMatcher.h create mode 100644 Pods/Kiwi/Classes/KWRespondToSelectorMatcher.m create mode 100644 Pods/Kiwi/Classes/KWSpec.h create mode 100644 Pods/Kiwi/Classes/KWSpec.m create mode 100644 Pods/Kiwi/Classes/KWStringContainsMatcher.h create mode 100644 Pods/Kiwi/Classes/KWStringContainsMatcher.m create mode 100644 Pods/Kiwi/Classes/KWStringPrefixMatcher.h create mode 100644 Pods/Kiwi/Classes/KWStringPrefixMatcher.m create mode 100644 Pods/Kiwi/Classes/KWStringUtilities.h create mode 100644 Pods/Kiwi/Classes/KWStringUtilities.m create mode 100644 Pods/Kiwi/Classes/KWStub.h create mode 100644 Pods/Kiwi/Classes/KWStub.m create mode 100644 Pods/Kiwi/Classes/KWTestCase.h create mode 100644 Pods/Kiwi/Classes/KWTestCase.m create mode 100644 Pods/Kiwi/Classes/KWUserDefinedMatcher.h create mode 100644 Pods/Kiwi/Classes/KWUserDefinedMatcher.m create mode 100644 Pods/Kiwi/Classes/KWValue.h create mode 100644 Pods/Kiwi/Classes/KWValue.m create mode 100644 Pods/Kiwi/Classes/KWVerifying.h create mode 100644 Pods/Kiwi/Classes/KWWorkarounds.h create mode 100644 Pods/Kiwi/Classes/KWWorkarounds.m create mode 100644 Pods/Kiwi/Classes/Kiwi.h create mode 100644 Pods/Kiwi/Classes/KiwiBlockMacros.h create mode 100644 Pods/Kiwi/Classes/KiwiConfiguration.h create mode 100644 Pods/Kiwi/Classes/KiwiMacros.h create mode 100644 Pods/Kiwi/Classes/KiwiNewMacros.h create mode 100644 Pods/Kiwi/Classes/NSInvocation+KiwiAdditions.h create mode 100644 Pods/Kiwi/Classes/NSInvocation+KiwiAdditions.m create mode 100644 Pods/Kiwi/Classes/NSInvocation+OCMAdditions.h create mode 100644 Pods/Kiwi/Classes/NSInvocation+OCMAdditions.m create mode 100644 Pods/Kiwi/Classes/NSMethodSignature+KiwiAdditions.h create mode 100644 Pods/Kiwi/Classes/NSMethodSignature+KiwiAdditions.m create mode 100644 Pods/Kiwi/Classes/NSNumber+KiwiAdditions.h create mode 100644 Pods/Kiwi/Classes/NSNumber+KiwiAdditions.m create mode 100644 Pods/Kiwi/Classes/NSObject+KiwiMockAdditions.h create mode 100644 Pods/Kiwi/Classes/NSObject+KiwiMockAdditions.m create mode 100644 Pods/Kiwi/Classes/NSObject+KiwiSpyAdditions.h create mode 100644 Pods/Kiwi/Classes/NSObject+KiwiSpyAdditions.m create mode 100644 Pods/Kiwi/Classes/NSObject+KiwiStubAdditions.h create mode 100644 Pods/Kiwi/Classes/NSObject+KiwiStubAdditions.m create mode 100644 Pods/Kiwi/Classes/NSObject+KiwiVerifierAdditions.h create mode 100644 Pods/Kiwi/Classes/NSObject+KiwiVerifierAdditions.m create mode 100644 Pods/Kiwi/Classes/NSProxy+KiwiVerifierAdditions.h create mode 100644 Pods/Kiwi/Classes/NSProxy+KiwiVerifierAdditions.m create mode 100644 Pods/Kiwi/Classes/NSValue+KiwiAdditions.h create mode 100644 Pods/Kiwi/Classes/NSValue+KiwiAdditions.m create mode 100644 Pods/Kiwi/License.txt create mode 100644 Pods/Kiwi/Readme.md create mode 100644 Pods/Manifest.lock create mode 100644 Pods/OCMock/README.md create mode 100644 Pods/OCMock/Source/OCMock/NSInvocation+OCMAdditions.h create mode 100644 Pods/OCMock/Source/OCMock/NSInvocation+OCMAdditions.m create mode 100644 Pods/OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.h create mode 100644 Pods/OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.m create mode 100644 Pods/OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.h create mode 100644 Pods/OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.m create mode 100644 Pods/OCMock/Source/OCMock/OCClassMockObject.h create mode 100644 Pods/OCMock/Source/OCMock/OCClassMockObject.m create mode 100644 Pods/OCMock/Source/OCMock/OCMArg.h create mode 100644 Pods/OCMock/Source/OCMock/OCMArg.m create mode 100644 Pods/OCMock/Source/OCMock/OCMBlockCaller.h create mode 100644 Pods/OCMock/Source/OCMock/OCMBlockCaller.m create mode 100644 Pods/OCMock/Source/OCMock/OCMBoxedReturnValueProvider.h create mode 100644 Pods/OCMock/Source/OCMock/OCMBoxedReturnValueProvider.m create mode 100644 Pods/OCMock/Source/OCMock/OCMConstraint.h create mode 100644 Pods/OCMock/Source/OCMock/OCMConstraint.m create mode 100644 Pods/OCMock/Source/OCMock/OCMExceptionReturnValueProvider.h create mode 100644 Pods/OCMock/Source/OCMock/OCMExceptionReturnValueProvider.m create mode 100644 Pods/OCMock/Source/OCMock/OCMIndirectReturnValueProvider.h create mode 100644 Pods/OCMock/Source/OCMock/OCMIndirectReturnValueProvider.m create mode 100644 Pods/OCMock/Source/OCMock/OCMNotificationPoster.h create mode 100644 Pods/OCMock/Source/OCMock/OCMNotificationPoster.m create mode 100644 Pods/OCMock/Source/OCMock/OCMObserverRecorder.h create mode 100644 Pods/OCMock/Source/OCMock/OCMObserverRecorder.m create mode 100644 Pods/OCMock/Source/OCMock/OCMPassByRefSetter.h create mode 100644 Pods/OCMock/Source/OCMock/OCMPassByRefSetter.m create mode 100644 Pods/OCMock/Source/OCMock/OCMRealObjectForwarder.h create mode 100644 Pods/OCMock/Source/OCMock/OCMRealObjectForwarder.m create mode 100644 Pods/OCMock/Source/OCMock/OCMReturnValueProvider.h create mode 100644 Pods/OCMock/Source/OCMock/OCMReturnValueProvider.m create mode 100644 Pods/OCMock/Source/OCMock/OCMock.h create mode 100644 Pods/OCMock/Source/OCMock/OCMockObject.h create mode 100644 Pods/OCMock/Source/OCMock/OCMockObject.m create mode 100644 Pods/OCMock/Source/OCMock/OCMockRecorder.h create mode 100644 Pods/OCMock/Source/OCMock/OCMockRecorder.m create mode 100644 Pods/OCMock/Source/OCMock/OCObserverMockObject.h create mode 100644 Pods/OCMock/Source/OCMock/OCObserverMockObject.m create mode 100644 Pods/OCMock/Source/OCMock/OCPartialMockObject.h create mode 100644 Pods/OCMock/Source/OCMock/OCPartialMockObject.m create mode 100644 Pods/OCMock/Source/OCMock/OCPartialMockRecorder.h create mode 100644 Pods/OCMock/Source/OCMock/OCPartialMockRecorder.m create mode 100644 Pods/OCMock/Source/OCMock/OCProtocolMockObject.h create mode 100644 Pods/OCMock/Source/OCMock/OCProtocolMockObject.m create mode 100644 Pods/Pods-CocoaLumberjack-Private.xcconfig create mode 100644 Pods/Pods-CocoaLumberjack-dummy.m create mode 100644 Pods/Pods-CocoaLumberjack-prefix.pch create mode 100644 Pods/Pods-CocoaLumberjack.xcconfig create mode 100644 Pods/Pods-UnitTests-CocoaLumberjack-Private.xcconfig create mode 100644 Pods/Pods-UnitTests-CocoaLumberjack-dummy.m create mode 100644 Pods/Pods-UnitTests-CocoaLumberjack-prefix.pch create mode 100644 Pods/Pods-UnitTests-CocoaLumberjack.xcconfig create mode 100644 Pods/Pods-UnitTests-Kiwi-Private.xcconfig create mode 100644 Pods/Pods-UnitTests-Kiwi-dummy.m create mode 100644 Pods/Pods-UnitTests-Kiwi-prefix.pch create mode 100644 Pods/Pods-UnitTests-Kiwi.xcconfig create mode 100644 Pods/Pods-UnitTests-OCMock-Private.xcconfig create mode 100644 Pods/Pods-UnitTests-OCMock-dummy.m create mode 100644 Pods/Pods-UnitTests-OCMock-prefix.pch create mode 100644 Pods/Pods-UnitTests-OCMock.xcconfig create mode 100644 Pods/Pods-UnitTests-VLBFoundation-Private.xcconfig create mode 100644 Pods/Pods-UnitTests-VLBFoundation-dummy.m create mode 100644 Pods/Pods-UnitTests-VLBFoundation-prefix.pch create mode 100644 Pods/Pods-UnitTests-VLBFoundation.xcconfig create mode 100644 Pods/Pods-UnitTests-acknowledgements.markdown create mode 100644 Pods/Pods-UnitTests-acknowledgements.plist create mode 100644 Pods/Pods-UnitTests-dummy.m create mode 100644 Pods/Pods-UnitTests-environment.h create mode 100755 Pods/Pods-UnitTests-resources.sh create mode 100644 Pods/Pods-UnitTests.xcconfig create mode 100644 Pods/Pods-VLBFoundation-Private.xcconfig create mode 100644 Pods/Pods-VLBFoundation-dummy.m create mode 100644 Pods/Pods-VLBFoundation-prefix.pch create mode 100644 Pods/Pods-VLBFoundation.xcconfig create mode 100644 Pods/Pods-acknowledgements.markdown create mode 100644 Pods/Pods-acknowledgements.plist create mode 100644 Pods/Pods-dummy.m create mode 100644 Pods/Pods-environment.h create mode 100755 Pods/Pods-resources.sh create mode 100644 Pods/Pods.xcconfig create mode 100644 Pods/Pods.xcodeproj/project.pbxproj create mode 100644 Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-CocoaLumberjack.xcscheme create mode 100644 Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-CocoaLumberjack.xcscheme create mode 100644 Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-Kiwi.xcscheme create mode 100644 Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-OCMock.xcscheme create mode 100644 Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-VLBFoundation.xcscheme create mode 100644 Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests.xcscheme create mode 100644 Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-VLBFoundation.xcscheme create mode 100644 Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods.xcscheme create mode 100644 Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 Pods/VLBFoundation/LICENCE create mode 100644 Pods/VLBFoundation/README.md create mode 100644 Pods/VLBFoundation/VLBFoundation/VLBMacros.h create mode 100644 VLBCameraView.xcworkspace/contents.xcworkspacedata diff --git a/Podfile.lock b/Podfile.lock new file mode 100644 index 0000000..6747871 --- /dev/null +++ b/Podfile.lock @@ -0,0 +1,19 @@ +PODS: + - CocoaLumberjack (1.6.2) + - Kiwi (2.0.6) + - OCMock (2.1.1) + - VLBFoundation (1.0) + +DEPENDENCIES: + - CocoaLumberjack (= 1.6.2) + - Kiwi (~> 2.0.6) + - OCMock (~> 2.1.1) + - VLBFoundation + +SPEC CHECKSUMS: + CocoaLumberjack: 0a08f3092acaab5f92c139e1186aa255a1e39446 + Kiwi: 9fe70e93c30586b607c54ac8669c6424cc6f2737 + OCMock: 363db8429164eaa219ea96a51f06e830ef3e7393 + VLBFoundation: d5ddef89836c735841390706e136fbbd14a04387 + +COCOAPODS: 0.33.1 diff --git a/Pods/BuildHeaders/CocoaLumberjack/ContextFilterLogFormatter.h b/Pods/BuildHeaders/CocoaLumberjack/ContextFilterLogFormatter.h new file mode 120000 index 0000000..de4836b --- /dev/null +++ b/Pods/BuildHeaders/CocoaLumberjack/ContextFilterLogFormatter.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.h \ No newline at end of file diff --git a/Pods/BuildHeaders/CocoaLumberjack/DDASLLogger.h b/Pods/BuildHeaders/CocoaLumberjack/DDASLLogger.h new file mode 120000 index 0000000..663f808 --- /dev/null +++ b/Pods/BuildHeaders/CocoaLumberjack/DDASLLogger.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/DDASLLogger.h \ No newline at end of file diff --git a/Pods/BuildHeaders/CocoaLumberjack/DDAbstractDatabaseLogger.h b/Pods/BuildHeaders/CocoaLumberjack/DDAbstractDatabaseLogger.h new file mode 120000 index 0000000..950a053 --- /dev/null +++ b/Pods/BuildHeaders/CocoaLumberjack/DDAbstractDatabaseLogger.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.h \ No newline at end of file diff --git a/Pods/BuildHeaders/CocoaLumberjack/DDFileLogger.h b/Pods/BuildHeaders/CocoaLumberjack/DDFileLogger.h new file mode 120000 index 0000000..18c2149 --- /dev/null +++ b/Pods/BuildHeaders/CocoaLumberjack/DDFileLogger.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/DDFileLogger.h \ No newline at end of file diff --git a/Pods/BuildHeaders/CocoaLumberjack/DDLog.h b/Pods/BuildHeaders/CocoaLumberjack/DDLog.h new file mode 120000 index 0000000..8af615d --- /dev/null +++ b/Pods/BuildHeaders/CocoaLumberjack/DDLog.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/DDLog.h \ No newline at end of file diff --git a/Pods/BuildHeaders/CocoaLumberjack/DDTTYLogger.h b/Pods/BuildHeaders/CocoaLumberjack/DDTTYLogger.h new file mode 120000 index 0000000..6c7bb54 --- /dev/null +++ b/Pods/BuildHeaders/CocoaLumberjack/DDTTYLogger.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/DDTTYLogger.h \ No newline at end of file diff --git a/Pods/BuildHeaders/CocoaLumberjack/DispatchQueueLogFormatter.h b/Pods/BuildHeaders/CocoaLumberjack/DispatchQueueLogFormatter.h new file mode 120000 index 0000000..76d4c51 --- /dev/null +++ b/Pods/BuildHeaders/CocoaLumberjack/DispatchQueueLogFormatter.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWAfterAllNode.h b/Pods/BuildHeaders/Kiwi/KWAfterAllNode.h new file mode 120000 index 0000000..4e9be08 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWAfterAllNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWAfterAllNode.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWAfterEachNode.h b/Pods/BuildHeaders/Kiwi/KWAfterEachNode.h new file mode 120000 index 0000000..450df35 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWAfterEachNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWAfterEachNode.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWAny.h b/Pods/BuildHeaders/Kiwi/KWAny.h new file mode 120000 index 0000000..681893a --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWAny.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWAny.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWAsyncVerifier.h b/Pods/BuildHeaders/Kiwi/KWAsyncVerifier.h new file mode 120000 index 0000000..33cf289 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWAsyncVerifier.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWAsyncVerifier.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBeBetweenMatcher.h b/Pods/BuildHeaders/Kiwi/KWBeBetweenMatcher.h new file mode 120000 index 0000000..bbe5314 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBeBetweenMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeBetweenMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBeEmptyMatcher.h b/Pods/BuildHeaders/Kiwi/KWBeEmptyMatcher.h new file mode 120000 index 0000000..f5a0689 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBeEmptyMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeEmptyMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBeIdenticalToMatcher.h b/Pods/BuildHeaders/Kiwi/KWBeIdenticalToMatcher.h new file mode 120000 index 0000000..b746586 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBeIdenticalToMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeIdenticalToMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBeKindOfClassMatcher.h b/Pods/BuildHeaders/Kiwi/KWBeKindOfClassMatcher.h new file mode 120000 index 0000000..06fbe03 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBeKindOfClassMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeKindOfClassMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBeMemberOfClassMatcher.h b/Pods/BuildHeaders/Kiwi/KWBeMemberOfClassMatcher.h new file mode 120000 index 0000000..08101ce --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBeMemberOfClassMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeMemberOfClassMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBeNilMatcher.h b/Pods/BuildHeaders/Kiwi/KWBeNilMatcher.h new file mode 120000 index 0000000..be56da6 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBeNilMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeNilMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBeNonNilMatcher.h b/Pods/BuildHeaders/Kiwi/KWBeNonNilMatcher.h new file mode 120000 index 0000000..16c909a --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBeNonNilMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeNonNilMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBeSubclassOfClassMatcher.h b/Pods/BuildHeaders/Kiwi/KWBeSubclassOfClassMatcher.h new file mode 120000 index 0000000..264f776 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBeSubclassOfClassMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeSubclassOfClassMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBeTrueMatcher.h b/Pods/BuildHeaders/Kiwi/KWBeTrueMatcher.h new file mode 120000 index 0000000..321d347 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBeTrueMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeTrueMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBeWithinMatcher.h b/Pods/BuildHeaders/Kiwi/KWBeWithinMatcher.h new file mode 120000 index 0000000..895f860 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBeWithinMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeWithinMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBeZeroMatcher.h b/Pods/BuildHeaders/Kiwi/KWBeZeroMatcher.h new file mode 120000 index 0000000..9848160 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBeZeroMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeZeroMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBeforeAllNode.h b/Pods/BuildHeaders/Kiwi/KWBeforeAllNode.h new file mode 120000 index 0000000..139d69a --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBeforeAllNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeforeAllNode.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBeforeEachNode.h b/Pods/BuildHeaders/Kiwi/KWBeforeEachNode.h new file mode 120000 index 0000000..f72e71c --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBeforeEachNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeforeEachNode.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBlock.h b/Pods/BuildHeaders/Kiwi/KWBlock.h new file mode 120000 index 0000000..a6a57c3 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBlock.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBlock.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBlockNode.h b/Pods/BuildHeaders/Kiwi/KWBlockNode.h new file mode 120000 index 0000000..d6fc357 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBlockNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBlockNode.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWBlockRaiseMatcher.h b/Pods/BuildHeaders/Kiwi/KWBlockRaiseMatcher.h new file mode 120000 index 0000000..68a0b99 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWBlockRaiseMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBlockRaiseMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWCallSite.h b/Pods/BuildHeaders/Kiwi/KWCallSite.h new file mode 120000 index 0000000..e2a84e7 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWCallSite.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWCallSite.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWCaptureSpy.h b/Pods/BuildHeaders/Kiwi/KWCaptureSpy.h new file mode 120000 index 0000000..ed1d865 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWCaptureSpy.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWCaptureSpy.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWChangeMatcher.h b/Pods/BuildHeaders/Kiwi/KWChangeMatcher.h new file mode 120000 index 0000000..da16244 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWChangeMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWChangeMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWConformToProtocolMatcher.h b/Pods/BuildHeaders/Kiwi/KWConformToProtocolMatcher.h new file mode 120000 index 0000000..c4512e3 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWConformToProtocolMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWConformToProtocolMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWContainMatcher.h b/Pods/BuildHeaders/Kiwi/KWContainMatcher.h new file mode 120000 index 0000000..3b564a7 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWContainMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWContainMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWContextNode.h b/Pods/BuildHeaders/Kiwi/KWContextNode.h new file mode 120000 index 0000000..367e449 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWContextNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWContextNode.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWCountType.h b/Pods/BuildHeaders/Kiwi/KWCountType.h new file mode 120000 index 0000000..f48c43f --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWCountType.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWCountType.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWDeviceInfo.h b/Pods/BuildHeaders/Kiwi/KWDeviceInfo.h new file mode 120000 index 0000000..ad0e2df --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWDeviceInfo.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWDeviceInfo.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWEqualMatcher.h b/Pods/BuildHeaders/Kiwi/KWEqualMatcher.h new file mode 120000 index 0000000..d55c932 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWEqualMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWEqualMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWExample.h b/Pods/BuildHeaders/Kiwi/KWExample.h new file mode 120000 index 0000000..7c20cd1 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWExample.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExample.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWExampleGroupBuilder.h b/Pods/BuildHeaders/Kiwi/KWExampleGroupBuilder.h new file mode 120000 index 0000000..0fe8c73 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWExampleGroupBuilder.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExampleGroupBuilder.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWExampleGroupDelegate.h b/Pods/BuildHeaders/Kiwi/KWExampleGroupDelegate.h new file mode 120000 index 0000000..0ed4e5e --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWExampleGroupDelegate.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExampleGroupDelegate.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWExampleNode.h b/Pods/BuildHeaders/Kiwi/KWExampleNode.h new file mode 120000 index 0000000..261f507 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWExampleNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExampleNode.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWExampleNodeVisitor.h b/Pods/BuildHeaders/Kiwi/KWExampleNodeVisitor.h new file mode 120000 index 0000000..3d7f7d8 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWExampleNodeVisitor.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExampleNodeVisitor.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWExampleSuite.h b/Pods/BuildHeaders/Kiwi/KWExampleSuite.h new file mode 120000 index 0000000..fc62150 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWExampleSuite.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExampleSuite.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWExistVerifier.h b/Pods/BuildHeaders/Kiwi/KWExistVerifier.h new file mode 120000 index 0000000..fefc731 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWExistVerifier.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExistVerifier.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWExpectationType.h b/Pods/BuildHeaders/Kiwi/KWExpectationType.h new file mode 120000 index 0000000..bb33bfc --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWExpectationType.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExpectationType.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWFailure.h b/Pods/BuildHeaders/Kiwi/KWFailure.h new file mode 120000 index 0000000..b55a3bc --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWFailure.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWFailure.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWFormatter.h b/Pods/BuildHeaders/Kiwi/KWFormatter.h new file mode 120000 index 0000000..80c47df --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWFormatter.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWFormatter.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWFutureObject.h b/Pods/BuildHeaders/Kiwi/KWFutureObject.h new file mode 120000 index 0000000..401eaf0 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWFutureObject.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWFutureObject.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWGenericMatchEvaluator.h b/Pods/BuildHeaders/Kiwi/KWGenericMatchEvaluator.h new file mode 120000 index 0000000..c3aeaec --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWGenericMatchEvaluator.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWGenericMatchEvaluator.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWGenericMatcher.h b/Pods/BuildHeaders/Kiwi/KWGenericMatcher.h new file mode 120000 index 0000000..5c48a70 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWGenericMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWGenericMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWGenericMatchingAdditions.h b/Pods/BuildHeaders/Kiwi/KWGenericMatchingAdditions.h new file mode 120000 index 0000000..61c0fcd --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWGenericMatchingAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWGenericMatchingAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWHaveMatcher.h b/Pods/BuildHeaders/Kiwi/KWHaveMatcher.h new file mode 120000 index 0000000..c2bd283 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWHaveMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWHaveMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWHaveValueMatcher.h b/Pods/BuildHeaders/Kiwi/KWHaveValueMatcher.h new file mode 120000 index 0000000..19b108b --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWHaveValueMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWHaveValueMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWInequalityMatcher.h b/Pods/BuildHeaders/Kiwi/KWInequalityMatcher.h new file mode 120000 index 0000000..8d85cb4 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWInequalityMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWInequalityMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWIntercept.h b/Pods/BuildHeaders/Kiwi/KWIntercept.h new file mode 120000 index 0000000..b9fae62 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWIntercept.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWIntercept.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWInvocationCapturer.h b/Pods/BuildHeaders/Kiwi/KWInvocationCapturer.h new file mode 120000 index 0000000..383f8e8 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWInvocationCapturer.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWInvocationCapturer.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWItNode.h b/Pods/BuildHeaders/Kiwi/KWItNode.h new file mode 120000 index 0000000..37b3ed5 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWItNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWItNode.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWMatchVerifier.h b/Pods/BuildHeaders/Kiwi/KWMatchVerifier.h new file mode 120000 index 0000000..78de3b2 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWMatchVerifier.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMatchVerifier.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWMatcher.h b/Pods/BuildHeaders/Kiwi/KWMatcher.h new file mode 120000 index 0000000..a3869b4 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWMatcherFactory.h b/Pods/BuildHeaders/Kiwi/KWMatcherFactory.h new file mode 120000 index 0000000..d6ef256 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWMatcherFactory.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMatcherFactory.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWMatchers.h b/Pods/BuildHeaders/Kiwi/KWMatchers.h new file mode 120000 index 0000000..121cbff --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWMatchers.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMatchers.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWMatching.h b/Pods/BuildHeaders/Kiwi/KWMatching.h new file mode 120000 index 0000000..b46afda --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWMatching.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMatching.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWMessagePattern.h b/Pods/BuildHeaders/Kiwi/KWMessagePattern.h new file mode 120000 index 0000000..00983f2 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWMessagePattern.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMessagePattern.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWMessageSpying.h b/Pods/BuildHeaders/Kiwi/KWMessageSpying.h new file mode 120000 index 0000000..31fb60e --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWMessageSpying.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMessageSpying.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWMessageTracker.h b/Pods/BuildHeaders/Kiwi/KWMessageTracker.h new file mode 120000 index 0000000..af301a1 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWMessageTracker.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMessageTracker.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWMock.h b/Pods/BuildHeaders/Kiwi/KWMock.h new file mode 120000 index 0000000..5d2b688 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWMock.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMock.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWNull.h b/Pods/BuildHeaders/Kiwi/KWNull.h new file mode 120000 index 0000000..3a8677c --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWNull.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWNull.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWObjCUtilities.h b/Pods/BuildHeaders/Kiwi/KWObjCUtilities.h new file mode 120000 index 0000000..f9c04a2 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWObjCUtilities.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWObjCUtilities.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWPendingNode.h b/Pods/BuildHeaders/Kiwi/KWPendingNode.h new file mode 120000 index 0000000..6a2a4ab --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWPendingNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWPendingNode.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWProbe.h b/Pods/BuildHeaders/Kiwi/KWProbe.h new file mode 120000 index 0000000..8eae994 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWProbe.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWProbe.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWProbePoller.h b/Pods/BuildHeaders/Kiwi/KWProbePoller.h new file mode 120000 index 0000000..852d35e --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWProbePoller.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWProbePoller.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWRaiseMatcher.h b/Pods/BuildHeaders/Kiwi/KWRaiseMatcher.h new file mode 120000 index 0000000..bdcd8ae --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWRaiseMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWRaiseMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWReceiveMatcher.h b/Pods/BuildHeaders/Kiwi/KWReceiveMatcher.h new file mode 120000 index 0000000..5dfb172 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWReceiveMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWReceiveMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWRegisterMatchersNode.h b/Pods/BuildHeaders/Kiwi/KWRegisterMatchersNode.h new file mode 120000 index 0000000..6ee09af --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWRegisterMatchersNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWRegisterMatchersNode.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWReporting.h b/Pods/BuildHeaders/Kiwi/KWReporting.h new file mode 120000 index 0000000..76724b4 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWReporting.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWReporting.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWRespondToSelectorMatcher.h b/Pods/BuildHeaders/Kiwi/KWRespondToSelectorMatcher.h new file mode 120000 index 0000000..638ffc9 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWRespondToSelectorMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWRespondToSelectorMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWSpec.h b/Pods/BuildHeaders/Kiwi/KWSpec.h new file mode 120000 index 0000000..01ff65d --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWSpec.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWSpec.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWStringContainsMatcher.h b/Pods/BuildHeaders/Kiwi/KWStringContainsMatcher.h new file mode 120000 index 0000000..31a35fa --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWStringContainsMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWStringContainsMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWStringPrefixMatcher.h b/Pods/BuildHeaders/Kiwi/KWStringPrefixMatcher.h new file mode 120000 index 0000000..6332ce4 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWStringPrefixMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWStringPrefixMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWStringUtilities.h b/Pods/BuildHeaders/Kiwi/KWStringUtilities.h new file mode 120000 index 0000000..c6b107f --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWStringUtilities.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWStringUtilities.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWStub.h b/Pods/BuildHeaders/Kiwi/KWStub.h new file mode 120000 index 0000000..38e5d0d --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWStub.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWStub.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWTestCase.h b/Pods/BuildHeaders/Kiwi/KWTestCase.h new file mode 120000 index 0000000..04096f4 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWTestCase.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWTestCase.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWUserDefinedMatcher.h b/Pods/BuildHeaders/Kiwi/KWUserDefinedMatcher.h new file mode 120000 index 0000000..e6a74c1 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWUserDefinedMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWUserDefinedMatcher.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWValue.h b/Pods/BuildHeaders/Kiwi/KWValue.h new file mode 120000 index 0000000..1546da5 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWValue.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWValue.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWVerifying.h b/Pods/BuildHeaders/Kiwi/KWVerifying.h new file mode 120000 index 0000000..7e7e7f3 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWVerifying.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWVerifying.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KWWorkarounds.h b/Pods/BuildHeaders/Kiwi/KWWorkarounds.h new file mode 120000 index 0000000..4535bdc --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KWWorkarounds.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWWorkarounds.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/Kiwi.h b/Pods/BuildHeaders/Kiwi/Kiwi.h new file mode 120000 index 0000000..2a5426e --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/Kiwi.h @@ -0,0 +1 @@ +../../Kiwi/Classes/Kiwi.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KiwiBlockMacros.h b/Pods/BuildHeaders/Kiwi/KiwiBlockMacros.h new file mode 120000 index 0000000..0407704 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KiwiBlockMacros.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KiwiBlockMacros.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KiwiConfiguration.h b/Pods/BuildHeaders/Kiwi/KiwiConfiguration.h new file mode 120000 index 0000000..e592852 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KiwiConfiguration.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KiwiConfiguration.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KiwiMacros.h b/Pods/BuildHeaders/Kiwi/KiwiMacros.h new file mode 120000 index 0000000..eb8ad23 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KiwiMacros.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KiwiMacros.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/KiwiNewMacros.h b/Pods/BuildHeaders/Kiwi/KiwiNewMacros.h new file mode 120000 index 0000000..1dcc226 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/KiwiNewMacros.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KiwiNewMacros.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/NSInvocation+KiwiAdditions.h b/Pods/BuildHeaders/Kiwi/NSInvocation+KiwiAdditions.h new file mode 120000 index 0000000..0a19c57 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/NSInvocation+KiwiAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSInvocation+KiwiAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/NSInvocation+OCMAdditions.h b/Pods/BuildHeaders/Kiwi/NSInvocation+OCMAdditions.h new file mode 120000 index 0000000..1816d66 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/NSInvocation+OCMAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSInvocation+OCMAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/NSMethodSignature+KiwiAdditions.h b/Pods/BuildHeaders/Kiwi/NSMethodSignature+KiwiAdditions.h new file mode 120000 index 0000000..83429ba --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/NSMethodSignature+KiwiAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSMethodSignature+KiwiAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/NSNumber+KiwiAdditions.h b/Pods/BuildHeaders/Kiwi/NSNumber+KiwiAdditions.h new file mode 120000 index 0000000..48e2354 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/NSNumber+KiwiAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSNumber+KiwiAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/NSObject+KiwiMockAdditions.h b/Pods/BuildHeaders/Kiwi/NSObject+KiwiMockAdditions.h new file mode 120000 index 0000000..32160c6 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/NSObject+KiwiMockAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSObject+KiwiMockAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/NSObject+KiwiSpyAdditions.h b/Pods/BuildHeaders/Kiwi/NSObject+KiwiSpyAdditions.h new file mode 120000 index 0000000..4da2d79 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/NSObject+KiwiSpyAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSObject+KiwiSpyAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/NSObject+KiwiStubAdditions.h b/Pods/BuildHeaders/Kiwi/NSObject+KiwiStubAdditions.h new file mode 120000 index 0000000..a64ea2c --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/NSObject+KiwiStubAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSObject+KiwiStubAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/NSObject+KiwiVerifierAdditions.h b/Pods/BuildHeaders/Kiwi/NSObject+KiwiVerifierAdditions.h new file mode 120000 index 0000000..68f6f43 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/NSObject+KiwiVerifierAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSObject+KiwiVerifierAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/NSProxy+KiwiVerifierAdditions.h b/Pods/BuildHeaders/Kiwi/NSProxy+KiwiVerifierAdditions.h new file mode 120000 index 0000000..1e07874 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/NSProxy+KiwiVerifierAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSProxy+KiwiVerifierAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/Kiwi/NSValue+KiwiAdditions.h b/Pods/BuildHeaders/Kiwi/NSValue+KiwiAdditions.h new file mode 120000 index 0000000..5b15712 --- /dev/null +++ b/Pods/BuildHeaders/Kiwi/NSValue+KiwiAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSValue+KiwiAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/NSInvocation+OCMAdditions.h b/Pods/BuildHeaders/OCMock/NSInvocation+OCMAdditions.h new file mode 120000 index 0000000..b5f84f8 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/NSInvocation+OCMAdditions.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/NSInvocation+OCMAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/NSMethodSignature+OCMAdditions.h b/Pods/BuildHeaders/OCMock/NSMethodSignature+OCMAdditions.h new file mode 120000 index 0000000..78c96d0 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/NSMethodSignature+OCMAdditions.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/NSNotificationCenter+OCMAdditions.h b/Pods/BuildHeaders/OCMock/NSNotificationCenter+OCMAdditions.h new file mode 120000 index 0000000..b0c2371 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/NSNotificationCenter+OCMAdditions.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCClassMockObject.h b/Pods/BuildHeaders/OCMock/OCClassMockObject.h new file mode 120000 index 0000000..53c7c49 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCClassMockObject.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCClassMockObject.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMArg.h b/Pods/BuildHeaders/OCMock/OCMArg.h new file mode 120000 index 0000000..7f69f9b --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMArg.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMArg.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMBlockCaller.h b/Pods/BuildHeaders/OCMock/OCMBlockCaller.h new file mode 120000 index 0000000..1dea96c --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMBlockCaller.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMBlockCaller.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMBoxedReturnValueProvider.h b/Pods/BuildHeaders/OCMock/OCMBoxedReturnValueProvider.h new file mode 120000 index 0000000..e663e8d --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMBoxedReturnValueProvider.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMBoxedReturnValueProvider.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMConstraint.h b/Pods/BuildHeaders/OCMock/OCMConstraint.h new file mode 120000 index 0000000..8cf4176 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMConstraint.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMConstraint.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMExceptionReturnValueProvider.h b/Pods/BuildHeaders/OCMock/OCMExceptionReturnValueProvider.h new file mode 120000 index 0000000..7661d35 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMExceptionReturnValueProvider.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMExceptionReturnValueProvider.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMIndirectReturnValueProvider.h b/Pods/BuildHeaders/OCMock/OCMIndirectReturnValueProvider.h new file mode 120000 index 0000000..ad444fd --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMIndirectReturnValueProvider.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMIndirectReturnValueProvider.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMNotificationPoster.h b/Pods/BuildHeaders/OCMock/OCMNotificationPoster.h new file mode 120000 index 0000000..d555dbd --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMNotificationPoster.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMNotificationPoster.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMObserverRecorder.h b/Pods/BuildHeaders/OCMock/OCMObserverRecorder.h new file mode 120000 index 0000000..89d0a7b --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMObserverRecorder.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMObserverRecorder.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMPassByRefSetter.h b/Pods/BuildHeaders/OCMock/OCMPassByRefSetter.h new file mode 120000 index 0000000..8aed5e1 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMPassByRefSetter.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMPassByRefSetter.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMRealObjectForwarder.h b/Pods/BuildHeaders/OCMock/OCMRealObjectForwarder.h new file mode 120000 index 0000000..5664269 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMRealObjectForwarder.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMRealObjectForwarder.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMReturnValueProvider.h b/Pods/BuildHeaders/OCMock/OCMReturnValueProvider.h new file mode 120000 index 0000000..458db78 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMReturnValueProvider.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMReturnValueProvider.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMock.h b/Pods/BuildHeaders/OCMock/OCMock.h new file mode 120000 index 0000000..d908884 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMock.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMock.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMockObject.h b/Pods/BuildHeaders/OCMock/OCMockObject.h new file mode 120000 index 0000000..f6cf2f1 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMockObject.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMockObject.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCMockRecorder.h b/Pods/BuildHeaders/OCMock/OCMockRecorder.h new file mode 120000 index 0000000..183029a --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCMockRecorder.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMockRecorder.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCObserverMockObject.h b/Pods/BuildHeaders/OCMock/OCObserverMockObject.h new file mode 120000 index 0000000..7624fc8 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCObserverMockObject.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCObserverMockObject.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCPartialMockObject.h b/Pods/BuildHeaders/OCMock/OCPartialMockObject.h new file mode 120000 index 0000000..d497494 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCPartialMockObject.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCPartialMockObject.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCPartialMockRecorder.h b/Pods/BuildHeaders/OCMock/OCPartialMockRecorder.h new file mode 120000 index 0000000..87348dc --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCPartialMockRecorder.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCPartialMockRecorder.h \ No newline at end of file diff --git a/Pods/BuildHeaders/OCMock/OCProtocolMockObject.h b/Pods/BuildHeaders/OCMock/OCProtocolMockObject.h new file mode 120000 index 0000000..8ef0e20 --- /dev/null +++ b/Pods/BuildHeaders/OCMock/OCProtocolMockObject.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCProtocolMockObject.h \ No newline at end of file diff --git a/Pods/BuildHeaders/VLBFoundation/VLBMacros.h b/Pods/BuildHeaders/VLBFoundation/VLBMacros.h new file mode 120000 index 0000000..0ea9ebb --- /dev/null +++ b/Pods/BuildHeaders/VLBFoundation/VLBMacros.h @@ -0,0 +1 @@ +../../VLBFoundation/VLBFoundation/VLBMacros.h \ No newline at end of file diff --git a/Pods/CocoaLumberjack/LICENSE.txt b/Pods/CocoaLumberjack/LICENSE.txt new file mode 100644 index 0000000..66a942c --- /dev/null +++ b/Pods/CocoaLumberjack/LICENSE.txt @@ -0,0 +1,18 @@ +Software License Agreement (BSD License) + +Copyright (c) 2010, Deusty, LLC +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Neither the name of Deusty nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Deusty, LLC. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/Pods/CocoaLumberjack/Lumberjack/DDASLLogger.h b/Pods/CocoaLumberjack/Lumberjack/DDASLLogger.h new file mode 100755 index 0000000..0f2e963 --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/DDASLLogger.h @@ -0,0 +1,41 @@ +#import +#import + +#import "DDLog.h" + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" wiki. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted + * + * + * This class provides a logger for the Apple System Log facility. + * + * As described in the "Getting Started" page, + * the traditional NSLog() function directs it's output to two places: + * + * - Apple System Log + * - StdErr (if stderr is a TTY) so log statements show up in Xcode console + * + * To duplicate NSLog() functionality you can simply add this logger and a tty logger. + * However, if you instead choose to use file logging (for faster performance), + * you may choose to use a file logger and a tty logger. +**/ + +@interface DDASLLogger : DDAbstractLogger +{ + aslclient client; +} + ++ (DDASLLogger *)sharedInstance; + +// Inherited from DDAbstractLogger + +// - (id )logFormatter; +// - (void)setLogFormatter:(id )formatter; + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/DDASLLogger.m b/Pods/CocoaLumberjack/Lumberjack/DDASLLogger.m new file mode 100755 index 0000000..0c35f2f --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/DDASLLogger.m @@ -0,0 +1,99 @@ +#import "DDASLLogger.h" + +#import + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" wiki. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted +**/ + +#if ! __has_feature(objc_arc) +#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + + +@implementation DDASLLogger + +static DDASLLogger *sharedInstance; + +/** + * The runtime sends initialize to each class in a program exactly one time just before the class, + * or any class that inherits from it, is sent its first message from within the program. (Thus the + * method may never be invoked if the class is not used.) The runtime sends the initialize message to + * classes in a thread-safe manner. Superclasses receive this message before their subclasses. + * + * This method may also be called directly (assumably by accident), hence the safety mechanism. +**/ ++ (void)initialize +{ + static BOOL initialized = NO; + if (!initialized) + { + initialized = YES; + + sharedInstance = [[DDASLLogger alloc] init]; + } +} + ++ (DDASLLogger *)sharedInstance +{ + return sharedInstance; +} + +- (id)init +{ + if (sharedInstance != nil) + { + return nil; + } + + if ((self = [super init])) + { + // A default asl client is provided for the main thread, + // but background threads need to create their own client. + + client = asl_open(NULL, "com.apple.console", 0); + } + return self; +} + +- (void)logMessage:(DDLogMessage *)logMessage +{ + NSString *logMsg = logMessage->logMsg; + + if (formatter) + { + logMsg = [formatter formatLogMessage:logMessage]; + } + + if (logMsg) + { + const char *msg = [logMsg UTF8String]; + + int aslLogLevel; + switch (logMessage->logFlag) + { + // Note: By default ASL will filter anything above level 5 (Notice). + // So our mappings shouldn't go above that level. + + case LOG_FLAG_ERROR : aslLogLevel = ASL_LEVEL_CRIT; break; + case LOG_FLAG_WARN : aslLogLevel = ASL_LEVEL_ERR; break; + case LOG_FLAG_INFO : aslLogLevel = ASL_LEVEL_WARNING; break; + default : aslLogLevel = ASL_LEVEL_NOTICE; break; + } + + asl_log(client, NULL, aslLogLevel, "%s", msg); + } +} + +- (NSString *)loggerName +{ + return @"cocoa.lumberjack.aslLogger"; +} + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.h b/Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.h new file mode 100644 index 0000000..436234e --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.h @@ -0,0 +1,102 @@ +#import + +#import "DDLog.h" + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" wiki. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted + * + * + * This class provides an abstract implementation of a database logger. + * + * That is, it provides the base implementation for a database logger to build atop of. + * All that is needed for a concrete database logger is to extend this class + * and override the methods in the implementation file that are prefixed with "db_". +**/ + +@interface DDAbstractDatabaseLogger : DDAbstractLogger { +@protected + NSUInteger saveThreshold; + NSTimeInterval saveInterval; + NSTimeInterval maxAge; + NSTimeInterval deleteInterval; + BOOL deleteOnEverySave; + + BOOL saveTimerSuspended; + NSUInteger unsavedCount; + dispatch_time_t unsavedTime; + dispatch_source_t saveTimer; + dispatch_time_t lastDeleteTime; + dispatch_source_t deleteTimer; +} + +/** + * Specifies how often to save the data to disk. + * Since saving is an expensive operation (disk io) it is not done after every log statement. + * These properties allow you to configure how/when the logger saves to disk. + * + * A save is done when either (whichever happens first): + * + * - The number of unsaved log entries reaches saveThreshold + * - The amount of time since the oldest unsaved log entry was created reaches saveInterval + * + * You can optionally disable the saveThreshold by setting it to zero. + * If you disable the saveThreshold you are entirely dependent on the saveInterval. + * + * You can optionally disable the saveInterval by setting it to zero (or a negative value). + * If you disable the saveInterval you are entirely dependent on the saveThreshold. + * + * It's not wise to disable both saveThreshold and saveInterval. + * + * The default saveThreshold is 500. + * The default saveInterval is 60 seconds. +**/ +@property (assign, readwrite) NSUInteger saveThreshold; +@property (assign, readwrite) NSTimeInterval saveInterval; + +/** + * It is likely you don't want the log entries to persist forever. + * Doing so would allow the database to grow infinitely large over time. + * + * The maxAge property provides a way to specify how old a log statement can get + * before it should get deleted from the database. + * + * The deleteInterval specifies how often to sweep for old log entries. + * Since deleting is an expensive operation (disk io) is is done on a fixed interval. + * + * An alternative to the deleteInterval is the deleteOnEverySave option. + * This specifies that old log entries should be deleted during every save operation. + * + * You can optionally disable the maxAge by setting it to zero (or a negative value). + * If you disable the maxAge then old log statements are not deleted. + * + * You can optionally disable the deleteInterval by setting it to zero (or a negative value). + * + * If you disable both deleteInterval and deleteOnEverySave then old log statements are not deleted. + * + * It's not wise to enable both deleteInterval and deleteOnEverySave. + * + * The default maxAge is 7 days. + * The default deleteInterval is 5 minutes. + * The default deleteOnEverySave is NO. +**/ +@property (assign, readwrite) NSTimeInterval maxAge; +@property (assign, readwrite) NSTimeInterval deleteInterval; +@property (assign, readwrite) BOOL deleteOnEverySave; + +/** + * Forces a save of any pending log entries (flushes log entries to disk). +**/ +- (void)savePendingLogEntries; + +/** + * Removes any log entries that are older than maxAge. +**/ +- (void)deleteOldLogEntries; + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.m b/Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.m new file mode 100644 index 0000000..c7366a6 --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.m @@ -0,0 +1,727 @@ +#import "DDAbstractDatabaseLogger.h" +#import + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" wiki. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted +**/ + +#if ! __has_feature(objc_arc) +#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + +@interface DDAbstractDatabaseLogger () +- (void)destroySaveTimer; +- (void)destroyDeleteTimer; +@end + +#pragma mark - + +@implementation DDAbstractDatabaseLogger + +- (id)init +{ + if ((self = [super init])) + { + saveThreshold = 500; + saveInterval = 60; // 60 seconds + maxAge = (60 * 60 * 24 * 7); // 7 days + deleteInterval = (60 * 5); // 5 minutes + } + return self; +} + +- (void)dealloc +{ + [self destroySaveTimer]; + [self destroyDeleteTimer]; + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Override Me +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)db_log:(DDLogMessage *)logMessage +{ + // Override me and add your implementation. + // + // Return YES if an item was added to the buffer. + // Return NO if the logMessage was ignored. + + return NO; +} + +- (void)db_save +{ + // Override me and add your implementation. +} + +- (void)db_delete +{ + // Override me and add your implementation. +} + +- (void)db_saveAndDelete +{ + // Override me and add your implementation. +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Private API +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)performSaveAndSuspendSaveTimer +{ + if (unsavedCount > 0) + { + if (deleteOnEverySave) + [self db_saveAndDelete]; + else + [self db_save]; + } + + unsavedCount = 0; + unsavedTime = 0; + + if (saveTimer && !saveTimerSuspended) + { + dispatch_suspend(saveTimer); + saveTimerSuspended = YES; + } +} + +- (void)performDelete +{ + if (maxAge > 0.0) + { + [self db_delete]; + + lastDeleteTime = dispatch_time(DISPATCH_TIME_NOW, 0); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Timers +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)destroySaveTimer +{ + if (saveTimer) + { + dispatch_source_cancel(saveTimer); + if (saveTimerSuspended) + { + // Must resume a timer before releasing it (or it will crash) + dispatch_resume(saveTimer); + saveTimerSuspended = NO; + } + #if !OS_OBJECT_USE_OBJC + dispatch_release(saveTimer); + #endif + saveTimer = NULL; + } +} + +- (void)updateAndResumeSaveTimer +{ + if ((saveTimer != NULL) && (saveInterval > 0.0) && (unsavedTime > 0.0)) + { + uint64_t interval = (uint64_t)(saveInterval * NSEC_PER_SEC); + dispatch_time_t startTime = dispatch_time(unsavedTime, interval); + + dispatch_source_set_timer(saveTimer, startTime, interval, 1.0); + + if (saveTimerSuspended) + { + dispatch_resume(saveTimer); + saveTimerSuspended = NO; + } + } +} + +- (void)createSuspendedSaveTimer +{ + if ((saveTimer == NULL) && (saveInterval > 0.0)) + { + saveTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, loggerQueue); + + dispatch_source_set_event_handler(saveTimer, ^{ @autoreleasepool { + + [self performSaveAndSuspendSaveTimer]; + + }}); + + saveTimerSuspended = YES; + } +} + +- (void)destroyDeleteTimer +{ + if (deleteTimer) + { + dispatch_source_cancel(deleteTimer); + #if !OS_OBJECT_USE_OBJC + dispatch_release(deleteTimer); + #endif + deleteTimer = NULL; + } +} + +- (void)updateDeleteTimer +{ + if ((deleteTimer != NULL) && (deleteInterval > 0.0) && (maxAge > 0.0)) + { + uint64_t interval = (uint64_t)(deleteInterval * NSEC_PER_SEC); + dispatch_time_t startTime; + + if (lastDeleteTime > 0) + startTime = dispatch_time(lastDeleteTime, interval); + else + startTime = dispatch_time(DISPATCH_TIME_NOW, interval); + + dispatch_source_set_timer(deleteTimer, startTime, interval, 1.0); + } +} + +- (void)createAndStartDeleteTimer +{ + if ((deleteTimer == NULL) && (deleteInterval > 0.0) && (maxAge > 0.0)) + { + deleteTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, loggerQueue); + + if (deleteTimer != NULL) { + dispatch_source_set_event_handler(deleteTimer, ^{ @autoreleasepool { + + [self performDelete]; + + }}); + + [self updateDeleteTimer]; + + dispatch_resume(deleteTimer); + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Configuration +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (NSUInteger)saveThreshold +{ + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block NSUInteger result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(loggerQueue, ^{ + result = saveThreshold; + }); + }); + + return result; +} + +- (void)setSaveThreshold:(NSUInteger)threshold +{ + dispatch_block_t block = ^{ @autoreleasepool { + + if (saveThreshold != threshold) + { + saveThreshold = threshold; + + // Since the saveThreshold has changed, + // we check to see if the current unsavedCount has surpassed the new threshold. + // + // If it has, we immediately save the log. + + if ((unsavedCount >= saveThreshold) && (saveThreshold > 0)) + { + [self performSaveAndSuspendSaveTimer]; + } + } + }}; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) + { + block(); + } + else + { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); + } +} + +- (NSTimeInterval)saveInterval +{ + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block NSTimeInterval result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(loggerQueue, ^{ + result = saveInterval; + }); + }); + + return result; +} + +- (void)setSaveInterval:(NSTimeInterval)interval +{ + dispatch_block_t block = ^{ @autoreleasepool { + + // C99 recommended floating point comparison macro + // Read: isLessThanOrGreaterThan(floatA, floatB) + + if (/* saveInterval != interval */ islessgreater(saveInterval, interval)) + { + saveInterval = interval; + + // There are several cases we need to handle here. + // + // 1. If the saveInterval was previously enabled and it just got disabled, + // then we need to stop the saveTimer. (And we might as well release it.) + // + // 2. If the saveInterval was previously disabled and it just got enabled, + // then we need to setup the saveTimer. (Plus we might need to do an immediate save.) + // + // 3. If the saveInterval increased, then we need to reset the timer so that it fires at the later date. + // + // 4. If the saveInterval decreased, then we need to reset the timer so that it fires at an earlier date. + // (Plus we might need to do an immediate save.) + + if (saveInterval > 0.0) + { + if (saveTimer == NULL) + { + // Handles #2 + // + // Since the saveTimer uses the unsavedTime to calculate it's first fireDate, + // if a save is needed the timer will fire immediately. + + [self createSuspendedSaveTimer]; + [self updateAndResumeSaveTimer]; + } + else + { + // Handles #3 + // Handles #4 + // + // Since the saveTimer uses the unsavedTime to calculate it's first fireDate, + // if a save is needed the timer will fire immediately. + + [self updateAndResumeSaveTimer]; + } + } + else if (saveTimer) + { + // Handles #1 + + [self destroySaveTimer]; + } + } + }}; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) + { + block(); + } + else + { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); + } +} + +- (NSTimeInterval)maxAge +{ + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block NSTimeInterval result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(loggerQueue, ^{ + result = maxAge; + }); + }); + + return result; +} + +- (void)setMaxAge:(NSTimeInterval)interval +{ + dispatch_block_t block = ^{ @autoreleasepool { + + // C99 recommended floating point comparison macro + // Read: isLessThanOrGreaterThan(floatA, floatB) + + if (/* maxAge != interval */ islessgreater(maxAge, interval)) + { + NSTimeInterval oldMaxAge = maxAge; + NSTimeInterval newMaxAge = interval; + + maxAge = interval; + + // There are several cases we need to handle here. + // + // 1. If the maxAge was previously enabled and it just got disabled, + // then we need to stop the deleteTimer. (And we might as well release it.) + // + // 2. If the maxAge was previously disabled and it just got enabled, + // then we need to setup the deleteTimer. (Plus we might need to do an immediate delete.) + // + // 3. If the maxAge was increased, + // then we don't need to do anything. + // + // 4. If the maxAge was decreased, + // then we should do an immediate delete. + + BOOL shouldDeleteNow = NO; + + if (oldMaxAge > 0.0) + { + if (newMaxAge <= 0.0) + { + // Handles #1 + + [self destroyDeleteTimer]; + } + else if (oldMaxAge > newMaxAge) + { + // Handles #4 + shouldDeleteNow = YES; + } + } + else if (newMaxAge > 0.0) + { + // Handles #2 + shouldDeleteNow = YES; + } + + if (shouldDeleteNow) + { + [self performDelete]; + + if (deleteTimer) + [self updateDeleteTimer]; + else + [self createAndStartDeleteTimer]; + } + } + }}; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) + { + block(); + } + else + { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); + } +} + +- (NSTimeInterval)deleteInterval +{ + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block NSTimeInterval result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(loggerQueue, ^{ + result = deleteInterval; + }); + }); + + return result; +} + +- (void)setDeleteInterval:(NSTimeInterval)interval +{ + dispatch_block_t block = ^{ @autoreleasepool { + + // C99 recommended floating point comparison macro + // Read: isLessThanOrGreaterThan(floatA, floatB) + + if (/* deleteInterval != interval */ islessgreater(deleteInterval, interval)) + { + deleteInterval = interval; + + // There are several cases we need to handle here. + // + // 1. If the deleteInterval was previously enabled and it just got disabled, + // then we need to stop the deleteTimer. (And we might as well release it.) + // + // 2. If the deleteInterval was previously disabled and it just got enabled, + // then we need to setup the deleteTimer. (Plus we might need to do an immediate delete.) + // + // 3. If the deleteInterval increased, then we need to reset the timer so that it fires at the later date. + // + // 4. If the deleteInterval decreased, then we need to reset the timer so that it fires at an earlier date. + // (Plus we might need to do an immediate delete.) + + if (deleteInterval > 0.0) + { + if (deleteTimer == NULL) + { + // Handles #2 + // + // Since the deleteTimer uses the lastDeleteTime to calculate it's first fireDate, + // if a delete is needed the timer will fire immediately. + + [self createAndStartDeleteTimer]; + } + else + { + // Handles #3 + // Handles #4 + // + // Since the deleteTimer uses the lastDeleteTime to calculate it's first fireDate, + // if a save is needed the timer will fire immediately. + + [self updateDeleteTimer]; + } + } + else if (deleteTimer) + { + // Handles #1 + + [self destroyDeleteTimer]; + } + } + }}; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) + { + block(); + } + else + { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); + } +} + +- (BOOL)deleteOnEverySave +{ + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block BOOL result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(loggerQueue, ^{ + result = deleteOnEverySave; + }); + }); + + return result; +} + +- (void)setDeleteOnEverySave:(BOOL)flag +{ + dispatch_block_t block = ^{ + + deleteOnEverySave = flag; + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) + { + block(); + } + else + { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Public API +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)savePendingLogEntries +{ + dispatch_block_t block = ^{ @autoreleasepool { + + [self performSaveAndSuspendSaveTimer]; + }}; + + if ([self isOnInternalLoggerQueue]) + block(); + else + dispatch_async(loggerQueue, block); +} + +- (void)deleteOldLogEntries +{ + dispatch_block_t block = ^{ @autoreleasepool { + + [self performDelete]; + }}; + + if ([self isOnInternalLoggerQueue]) + block(); + else + dispatch_async(loggerQueue, block); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark DDLogger +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)didAddLogger +{ + // If you override me be sure to invoke [super didAddLogger]; + + [self createSuspendedSaveTimer]; + + [self createAndStartDeleteTimer]; +} + +- (void)willRemoveLogger +{ + // If you override me be sure to invoke [super willRemoveLogger]; + + [self performSaveAndSuspendSaveTimer]; + + [self destroySaveTimer]; + [self destroyDeleteTimer]; +} + +- (void)logMessage:(DDLogMessage *)logMessage +{ + if ([self db_log:logMessage]) + { + BOOL firstUnsavedEntry = (++unsavedCount == 1); + + if ((unsavedCount >= saveThreshold) && (saveThreshold > 0)) + { + [self performSaveAndSuspendSaveTimer]; + } + else if (firstUnsavedEntry) + { + unsavedTime = dispatch_time(DISPATCH_TIME_NOW, 0); + [self updateAndResumeSaveTimer]; + } + } +} + +- (void)flush +{ + // This method is invoked by DDLog's flushLog method. + // + // It is called automatically when the application quits, + // or if the developer invokes DDLog's flushLog method prior to crashing or something. + + [self performSaveAndSuspendSaveTimer]; +} + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/DDFileLogger.h b/Pods/CocoaLumberjack/Lumberjack/DDFileLogger.h new file mode 100644 index 0000000..5af6376 --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/DDFileLogger.h @@ -0,0 +1,334 @@ +#import +#import "DDLog.h" + +@class DDLogFileInfo; + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" wiki. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted + * + * + * This class provides a logger to write log statements to a file. +**/ + + +// Default configuration and safety/sanity values. +// +// maximumFileSize -> DEFAULT_LOG_MAX_FILE_SIZE +// rollingFrequency -> DEFAULT_LOG_ROLLING_FREQUENCY +// maximumNumberOfLogFiles -> DEFAULT_LOG_MAX_NUM_LOG_FILES +// +// You should carefully consider the proper configuration values for your application. + +#define DEFAULT_LOG_MAX_FILE_SIZE (1024 * 1024) // 1 MB +#define DEFAULT_LOG_ROLLING_FREQUENCY (60 * 60 * 24) // 24 Hours +#define DEFAULT_LOG_MAX_NUM_LOG_FILES (5) // 5 Files + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// The LogFileManager protocol is designed to allow you to control all aspects of your log files. +// +// The primary purpose of this is to allow you to do something with the log files after they have been rolled. +// Perhaps you want to compress them to save disk space. +// Perhaps you want to upload them to an FTP server. +// Perhaps you want to run some analytics on the file. +// +// A default LogFileManager is, of course, provided. +// The default LogFileManager simply deletes old log files according to the maximumNumberOfLogFiles property. +// +// This protocol provides various methods to fetch the list of log files. +// +// There are two variants: sorted and unsorted. +// If sorting is not necessary, the unsorted variant is obviously faster. +// The sorted variant will return an array sorted by when the log files were created, +// with the most recently created log file at index 0, and the oldest log file at the end of the array. +// +// You can fetch only the log file paths (full path including name), log file names (name only), +// or an array of DDLogFileInfo objects. +// The DDLogFileInfo class is documented below, and provides a handy wrapper that +// gives you easy access to various file attributes such as the creation date or the file size. + +@protocol DDLogFileManager +@required + +// Public properties + +/** + * The maximum number of archived log files to keep on disk. + * For example, if this property is set to 3, + * then the LogFileManager will only keep 3 archived log files (plus the current active log file) on disk. + * Once the active log file is rolled/archived, then the oldest of the existing 3 rolled/archived log files is deleted. + * + * You may optionally disable deleting old/rolled/archived log files by setting this property to zero. +**/ +@property (readwrite, assign) NSUInteger maximumNumberOfLogFiles; + +// Public methods + +- (NSString *)logsDirectory; + +- (NSArray *)unsortedLogFilePaths; +- (NSArray *)unsortedLogFileNames; +- (NSArray *)unsortedLogFileInfos; + +- (NSArray *)sortedLogFilePaths; +- (NSArray *)sortedLogFileNames; +- (NSArray *)sortedLogFileInfos; + +// Private methods (only to be used by DDFileLogger) + +- (NSString *)createNewLogFile; + +@optional + +// Notifications from DDFileLogger + +- (void)didArchiveLogFile:(NSString *)logFilePath; +- (void)didRollAndArchiveLogFile:(NSString *)logFilePath; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Default log file manager. + * + * All log files are placed inside the logsDirectory. + * If a specific logsDirectory isn't specified, the default directory is used. + * On Mac, this is in ~/Library/Logs/. + * On iPhone, this is in ~/Library/Caches/Logs. + * + * Log files are named "log-.txt", + * where uuid is a 6 character hexadecimal consisting of the set [0123456789ABCDEF]. + * + * Archived log files are automatically deleted according to the maximumNumberOfLogFiles property. +**/ +@interface DDLogFileManagerDefault : NSObject +{ + NSUInteger maximumNumberOfLogFiles; + NSString *_logsDirectory; +} + +- (id)init; +- (id)initWithLogsDirectory:(NSString *)logsDirectory; + +/* Inherited from DDLogFileManager protocol: + +@property (readwrite, assign) NSUInteger maximumNumberOfLogFiles; + +- (NSString *)logsDirectory; + +- (NSArray *)unsortedLogFilePaths; +- (NSArray *)unsortedLogFileNames; +- (NSArray *)unsortedLogFileInfos; + +- (NSArray *)sortedLogFilePaths; +- (NSArray *)sortedLogFileNames; +- (NSArray *)sortedLogFileInfos; + +*/ + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Most users will want file log messages to be prepended with the date and time. + * Rather than forcing the majority of users to write their own formatter, + * we will supply a logical default formatter. + * Users can easily replace this formatter with their own by invoking the setLogFormatter method. + * It can also be removed by calling setLogFormatter, and passing a nil parameter. + * + * In addition to the convenience of having a logical default formatter, + * it will also provide a template that makes it easy for developers to copy and change. +**/ +@interface DDLogFileFormatterDefault : NSObject +{ + NSDateFormatter *dateFormatter; +} + +- (id)init; +- (id)initWithDateFormatter:(NSDateFormatter *)dateFormatter; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface DDFileLogger : DDAbstractLogger +{ + __strong id logFileManager; + + DDLogFileInfo *currentLogFileInfo; + NSFileHandle *currentLogFileHandle; + + dispatch_source_t rollingTimer; + + unsigned long long maximumFileSize; + NSTimeInterval rollingFrequency; +} + +- (id)init; +- (id)initWithLogFileManager:(id )logFileManager; + +/** + * Log File Rolling: + * + * maximumFileSize: + * The approximate maximum size to allow log files to grow. + * If a log file is larger than this value after a log statement is appended, + * then the log file is rolled. + * + * rollingFrequency + * How often to roll the log file. + * The frequency is given as an NSTimeInterval, which is a double that specifies the interval in seconds. + * Once the log file gets to be this old, it is rolled. + * + * Both the maximumFileSize and the rollingFrequency are used to manage rolling. + * Whichever occurs first will cause the log file to be rolled. + * + * For example: + * The rollingFrequency is 24 hours, + * but the log file surpasses the maximumFileSize after only 20 hours. + * The log file will be rolled at that 20 hour mark. + * A new log file will be created, and the 24 hour timer will be restarted. + * + * You may optionally disable rolling due to filesize by setting maximumFileSize to zero. + * If you do so, rolling is based solely on rollingFrequency. + * + * You may optionally disable rolling due to time by setting rollingFrequency to zero (or any non-positive number). + * If you do so, rolling is based solely on maximumFileSize. + * + * If you disable both maximumFileSize and rollingFrequency, then the log file won't ever be rolled. + * This is strongly discouraged. +**/ +@property (readwrite, assign) unsigned long long maximumFileSize; +@property (readwrite, assign) NSTimeInterval rollingFrequency; + +/** + * The DDLogFileManager instance can be used to retrieve the list of log files, + * and configure the maximum number of archived log files to keep. + * + * @see DDLogFileManager.maximumNumberOfLogFiles +**/ +@property (strong, nonatomic, readonly) id logFileManager; + + +// You can optionally force the current log file to be rolled with this method. + +- (void)rollLogFile; + +// Inherited from DDAbstractLogger + +// - (id )logFormatter; +// - (void)setLogFormatter:(id )formatter; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * DDLogFileInfo is a simple class that provides access to various file attributes. + * It provides good performance as it only fetches the information if requested, + * and it caches the information to prevent duplicate fetches. + * + * It was designed to provide quick snapshots of the current state of log files, + * and to help sort log files in an array. + * + * This class does not monitor the files, or update it's cached attribute values if the file changes on disk. + * This is not what the class was designed for. + * + * If you absolutely must get updated values, + * you can invoke the reset method which will clear the cache. +**/ +@interface DDLogFileInfo : NSObject +{ + __strong NSString *filePath; + __strong NSString *fileName; + + __strong NSDictionary *fileAttributes; + + __strong NSDate *creationDate; + __strong NSDate *modificationDate; + + unsigned long long fileSize; +} + +@property (strong, nonatomic, readonly) NSString *filePath; +@property (strong, nonatomic, readonly) NSString *fileName; + +@property (strong, nonatomic, readonly) NSDictionary *fileAttributes; + +@property (strong, nonatomic, readonly) NSDate *creationDate; +@property (strong, nonatomic, readonly) NSDate *modificationDate; + +@property (nonatomic, readonly) unsigned long long fileSize; + +@property (nonatomic, readonly) NSTimeInterval age; + +@property (nonatomic, readwrite) BOOL isArchived; + ++ (id)logFileWithPath:(NSString *)filePath; + +- (id)initWithFilePath:(NSString *)filePath; + +- (void)reset; +- (void)renameFile:(NSString *)newFileName; + +#if TARGET_IPHONE_SIMULATOR + +// So here's the situation. +// Extended attributes are perfect for what we're trying to do here (marking files as archived). +// This is exactly what extended attributes were designed for. +// +// But Apple screws us over on the simulator. +// Everytime you build-and-go, they copy the application into a new folder on the hard drive, +// and as part of the process they strip extended attributes from our log files. +// Normally, a copy of a file preserves extended attributes. +// So obviously Apple has gone to great lengths to piss us off. +// +// Thus we use a slightly different tactic for marking log files as archived in the simulator. +// That way it "just works" and there's no confusion when testing. +// +// The difference in method names is indicative of the difference in functionality. +// On the simulator we add an attribute by appending a filename extension. +// +// For example: +// log-ABC123.txt -> log-ABC123.archived.txt + +- (BOOL)hasExtensionAttributeWithName:(NSString *)attrName; + +- (void)addExtensionAttributeWithName:(NSString *)attrName; +- (void)removeExtensionAttributeWithName:(NSString *)attrName; + +#else + +// Normal use of extended attributes used everywhere else, +// such as on Macs and on iPhone devices. + +- (BOOL)hasExtendedAttributeWithName:(NSString *)attrName; + +- (void)addExtendedAttributeWithName:(NSString *)attrName; +- (void)removeExtendedAttributeWithName:(NSString *)attrName; + +#endif + +- (NSComparisonResult)reverseCompareByCreationDate:(DDLogFileInfo *)another; +- (NSComparisonResult)reverseCompareByModificationDate:(DDLogFileInfo *)another; + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/DDFileLogger.m b/Pods/CocoaLumberjack/Lumberjack/DDFileLogger.m new file mode 100644 index 0000000..afe7cc1 --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/DDFileLogger.m @@ -0,0 +1,1353 @@ +#import "DDFileLogger.h" + +#import +#import +#import +#import + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" wiki. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted +**/ + +#if ! __has_feature(objc_arc) +#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + +// We probably shouldn't be using DDLog() statements within the DDLog implementation. +// But we still want to leave our log statements for any future debugging, +// and to allow other developers to trace the implementation (which is a great learning tool). +// +// So we use primitive logging macros around NSLog. +// We maintain the NS prefix on the macros to be explicit about the fact that we're using NSLog. + +#define LOG_LEVEL 2 + +#define NSLogError(frmt, ...) do{ if(LOG_LEVEL >= 1) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogWarn(frmt, ...) do{ if(LOG_LEVEL >= 2) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogInfo(frmt, ...) do{ if(LOG_LEVEL >= 3) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogVerbose(frmt, ...) do{ if(LOG_LEVEL >= 4) NSLog((frmt), ##__VA_ARGS__); } while(0) + +@interface DDLogFileManagerDefault (PrivateAPI) + +- (void)deleteOldLogFiles; +- (NSString *)defaultLogsDirectory; + +@end + +@interface DDFileLogger (PrivateAPI) + +- (void)rollLogFileNow; +- (void)maybeRollLogFileDueToAge; +- (void)maybeRollLogFileDueToSize; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDLogFileManagerDefault + +@synthesize maximumNumberOfLogFiles; + +- (id)init +{ + return [self initWithLogsDirectory:nil]; +} + +- (id)initWithLogsDirectory:(NSString *)aLogsDirectory +{ + if ((self = [super init])) + { + maximumNumberOfLogFiles = DEFAULT_LOG_MAX_NUM_LOG_FILES; + + if (aLogsDirectory) + _logsDirectory = [aLogsDirectory copy]; + else + _logsDirectory = [[self defaultLogsDirectory] copy]; + + NSKeyValueObservingOptions kvoOptions = NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew; + + [self addObserver:self forKeyPath:@"maximumNumberOfLogFiles" options:kvoOptions context:nil]; + + NSLogVerbose(@"DDFileLogManagerDefault: logsDirectory:\n%@", [self logsDirectory]); + NSLogVerbose(@"DDFileLogManagerDefault: sortedLogFileNames:\n%@", [self sortedLogFileNames]); + } + return self; +} + +- (void)dealloc +{ + [self removeObserver:self forKeyPath:@"maximumNumberOfLogFiles"]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Configuration +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context +{ + NSNumber *old = [change objectForKey:NSKeyValueChangeOldKey]; + NSNumber *new = [change objectForKey:NSKeyValueChangeNewKey]; + + if ([old isEqual:new]) + { + // No change in value - don't bother with any processing. + return; + } + + if ([keyPath isEqualToString:@"maximumNumberOfLogFiles"]) + { + NSLogInfo(@"DDFileLogManagerDefault: Responding to configuration change: maximumNumberOfLogFiles"); + + dispatch_async([DDLog loggingQueue], ^{ @autoreleasepool { + + [self deleteOldLogFiles]; + }}); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark File Deleting +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Deletes archived log files that exceed the maximumNumberOfLogFiles configuration value. +**/ +- (void)deleteOldLogFiles +{ + NSLogVerbose(@"DDLogFileManagerDefault: deleteOldLogFiles"); + + NSUInteger maxNumLogFiles = self.maximumNumberOfLogFiles; + if (maxNumLogFiles == 0) + { + // Unlimited - don't delete any log files + return; + } + + NSArray *sortedLogFileInfos = [self sortedLogFileInfos]; + + // Do we consider the first file? + // We are only supposed to be deleting archived files. + // In most cases, the first file is likely the log file that is currently being written to. + // So in most cases, we do not want to consider this file for deletion. + + NSUInteger count = [sortedLogFileInfos count]; + BOOL excludeFirstFile = NO; + + if (count > 0) + { + DDLogFileInfo *logFileInfo = [sortedLogFileInfos objectAtIndex:0]; + + if (!logFileInfo.isArchived) + { + excludeFirstFile = YES; + } + } + + NSArray *sortedArchivedLogFileInfos; + if (excludeFirstFile) + { + count--; + sortedArchivedLogFileInfos = [sortedLogFileInfos subarrayWithRange:NSMakeRange(1, count)]; + } + else + { + sortedArchivedLogFileInfos = sortedLogFileInfos; + } + + NSUInteger i; + for (i = maxNumLogFiles; i < count; i++) + { + DDLogFileInfo *logFileInfo = [sortedArchivedLogFileInfos objectAtIndex:i]; + + NSLogInfo(@"DDLogFileManagerDefault: Deleting file: %@", logFileInfo.fileName); + + [[NSFileManager defaultManager] removeItemAtPath:logFileInfo.filePath error:nil]; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Log Files +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Returns the path to the default logs directory. + * If the logs directory doesn't exist, this method automatically creates it. +**/ +- (NSString *)defaultLogsDirectory +{ +#if TARGET_OS_IPHONE + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + NSString *baseDir = ([paths count] > 0) ? [paths objectAtIndex:0] : nil; + NSString *logsDirectory = [baseDir stringByAppendingPathComponent:@"Logs"]; + +#else + NSString *appName = [[NSProcessInfo processInfo] processName]; + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); + NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : NSTemporaryDirectory(); + NSString *logsDirectory = [[basePath stringByAppendingPathComponent:@"Logs"] stringByAppendingPathComponent:appName]; + +#endif + + return logsDirectory; +} + +- (NSString *)logsDirectory +{ + // We could do this check once, during initalization, and not bother again. + // But this way the code continues to work if the directory gets deleted while the code is running. + + if (![[NSFileManager defaultManager] fileExistsAtPath:_logsDirectory]) + { + NSError *err = nil; + if (![[NSFileManager defaultManager] createDirectoryAtPath:_logsDirectory + withIntermediateDirectories:YES attributes:nil error:&err]) + { + NSLogError(@"DDFileLogManagerDefault: Error creating logsDirectory: %@", err); + } + } + + return _logsDirectory; +} + +- (BOOL)isLogFile:(NSString *)fileName +{ + // A log file has a name like "log-.txt", where is a HEX-string of 6 characters. + // + // For example: log-DFFE99.txt + + BOOL hasProperPrefix = [fileName hasPrefix:@"log-"]; + + BOOL hasProperLength = [fileName length] >= 10; + + + if (hasProperPrefix && hasProperLength) + { + NSCharacterSet *hexSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789ABCDEF"]; + + NSString *hex = [fileName substringWithRange:NSMakeRange(4, 6)]; + NSString *nohex = [hex stringByTrimmingCharactersInSet:hexSet]; + + if ([nohex length] == 0) + { + return YES; + } + } + + return NO; +} + +/** + * Returns an array of NSString objects, + * each of which is the filePath to an existing log file on disk. +**/ +- (NSArray *)unsortedLogFilePaths +{ + NSString *logsDirectory = [self logsDirectory]; + NSArray *fileNames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:logsDirectory error:nil]; + + NSMutableArray *unsortedLogFilePaths = [NSMutableArray arrayWithCapacity:[fileNames count]]; + + for (NSString *fileName in fileNames) + { + // Filter out any files that aren't log files. (Just for extra safety) + + if ([self isLogFile:fileName]) + { + NSString *filePath = [logsDirectory stringByAppendingPathComponent:fileName]; + + [unsortedLogFilePaths addObject:filePath]; + } + } + + return unsortedLogFilePaths; +} + +/** + * Returns an array of NSString objects, + * each of which is the fileName of an existing log file on disk. +**/ +- (NSArray *)unsortedLogFileNames +{ + NSArray *unsortedLogFilePaths = [self unsortedLogFilePaths]; + + NSMutableArray *unsortedLogFileNames = [NSMutableArray arrayWithCapacity:[unsortedLogFilePaths count]]; + + for (NSString *filePath in unsortedLogFilePaths) + { + [unsortedLogFileNames addObject:[filePath lastPathComponent]]; + } + + return unsortedLogFileNames; +} + +/** + * Returns an array of DDLogFileInfo objects, + * each representing an existing log file on disk, + * and containing important information about the log file such as it's modification date and size. +**/ +- (NSArray *)unsortedLogFileInfos +{ + NSArray *unsortedLogFilePaths = [self unsortedLogFilePaths]; + + NSMutableArray *unsortedLogFileInfos = [NSMutableArray arrayWithCapacity:[unsortedLogFilePaths count]]; + + for (NSString *filePath in unsortedLogFilePaths) + { + DDLogFileInfo *logFileInfo = [[DDLogFileInfo alloc] initWithFilePath:filePath]; + + [unsortedLogFileInfos addObject:logFileInfo]; + } + + return unsortedLogFileInfos; +} + +/** + * Just like the unsortedLogFilePaths method, but sorts the array. + * The items in the array are sorted by modification date. + * The first item in the array will be the most recently modified log file. +**/ +- (NSArray *)sortedLogFilePaths +{ + NSArray *sortedLogFileInfos = [self sortedLogFileInfos]; + + NSMutableArray *sortedLogFilePaths = [NSMutableArray arrayWithCapacity:[sortedLogFileInfos count]]; + + for (DDLogFileInfo *logFileInfo in sortedLogFileInfos) + { + [sortedLogFilePaths addObject:[logFileInfo filePath]]; + } + + return sortedLogFilePaths; +} + +/** + * Just like the unsortedLogFileNames method, but sorts the array. + * The items in the array are sorted by modification date. + * The first item in the array will be the most recently modified log file. +**/ +- (NSArray *)sortedLogFileNames +{ + NSArray *sortedLogFileInfos = [self sortedLogFileInfos]; + + NSMutableArray *sortedLogFileNames = [NSMutableArray arrayWithCapacity:[sortedLogFileInfos count]]; + + for (DDLogFileInfo *logFileInfo in sortedLogFileInfos) + { + [sortedLogFileNames addObject:[logFileInfo fileName]]; + } + + return sortedLogFileNames; +} + +/** + * Just like the unsortedLogFileInfos method, but sorts the array. + * The items in the array are sorted by modification date. + * The first item in the array will be the most recently modified log file. +**/ +- (NSArray *)sortedLogFileInfos +{ + return [[self unsortedLogFileInfos] sortedArrayUsingSelector:@selector(reverseCompareByCreationDate:)]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Creation +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Generates a short UUID suitable for use in the log file's name. + * The result will have six characters, all in the hexadecimal set [0123456789ABCDEF]. +**/ +- (NSString *)generateShortUUID +{ + CFUUIDRef uuid = CFUUIDCreate(NULL); + + CFStringRef fullStr = CFUUIDCreateString(NULL, uuid); + NSString *result = (__bridge_transfer NSString *)CFStringCreateWithSubstring(NULL, fullStr, CFRangeMake(0, 6)); + + CFRelease(fullStr); + CFRelease(uuid); + + return result; +} + +/** + * Generates a new unique log file path, and creates the corresponding log file. +**/ +- (NSString *)createNewLogFile +{ + // Generate a random log file name, and create the file (if there isn't a collision) + + NSString *logsDirectory = [self logsDirectory]; + do + { + NSString *fileName = [NSString stringWithFormat:@"log-%@.txt", [self generateShortUUID]]; + + NSString *filePath = [logsDirectory stringByAppendingPathComponent:fileName]; + + if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) + { + NSLogVerbose(@"DDLogFileManagerDefault: Creating new log file: %@", fileName); + + [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil]; + + // Since we just created a new log file, we may need to delete some old log files + [self deleteOldLogFiles]; + + return filePath; + } + + } while(YES); +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDLogFileFormatterDefault + +- (id)init +{ + return [self initWithDateFormatter:nil]; +} + +- (id)initWithDateFormatter:(NSDateFormatter *)aDateFormatter +{ + if ((self = [super init])) + { + if (aDateFormatter) + { + dateFormatter = aDateFormatter; + } + else + { + dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; // 10.4+ style + [dateFormatter setDateFormat:@"yyyy/MM/dd HH:mm:ss:SSS"]; + } + } + return self; +} + +- (NSString *)formatLogMessage:(DDLogMessage *)logMessage +{ + NSString *dateAndTime = [dateFormatter stringFromDate:(logMessage->timestamp)]; + + return [NSString stringWithFormat:@"%@ %@", dateAndTime, logMessage->logMsg]; +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDFileLogger + +- (id)init +{ + DDLogFileManagerDefault *defaultLogFileManager = [[DDLogFileManagerDefault alloc] init]; + + return [self initWithLogFileManager:defaultLogFileManager]; +} + +- (id)initWithLogFileManager:(id )aLogFileManager +{ + if ((self = [super init])) + { + maximumFileSize = DEFAULT_LOG_MAX_FILE_SIZE; + rollingFrequency = DEFAULT_LOG_ROLLING_FREQUENCY; + + logFileManager = aLogFileManager; + + formatter = [[DDLogFileFormatterDefault alloc] init]; + } + return self; +} + +- (void)dealloc +{ + [currentLogFileHandle synchronizeFile]; + [currentLogFileHandle closeFile]; + + if (rollingTimer) + { + dispatch_source_cancel(rollingTimer); + rollingTimer = NULL; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Properties +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@synthesize logFileManager; + +- (unsigned long long)maximumFileSize +{ + __block unsigned long long result; + + dispatch_block_t block = ^{ + result = maximumFileSize; + }; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the maximumFileSize variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(loggerQueue, block); + }); + + return result; +} + +- (void)setMaximumFileSize:(unsigned long long)newMaximumFileSize +{ + dispatch_block_t block = ^{ @autoreleasepool { + + maximumFileSize = newMaximumFileSize; + [self maybeRollLogFileDueToSize]; + + }}; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the maximumFileSize variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); +} + +- (NSTimeInterval)rollingFrequency +{ + __block NSTimeInterval result; + + dispatch_block_t block = ^{ + result = rollingFrequency; + }; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation should access the rollingFrequency variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(loggerQueue, block); + }); + + return result; +} + +- (void)setRollingFrequency:(NSTimeInterval)newRollingFrequency +{ + dispatch_block_t block = ^{ @autoreleasepool { + + rollingFrequency = newRollingFrequency; + [self maybeRollLogFileDueToAge]; + }}; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation should access the rollingFrequency variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark File Rolling +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)scheduleTimerToRollLogFileDueToAge +{ + if (rollingTimer) + { + dispatch_source_cancel(rollingTimer); + rollingTimer = NULL; + } + + if (currentLogFileInfo == nil || rollingFrequency <= 0.0) + { + return; + } + + NSDate *logFileCreationDate = [currentLogFileInfo creationDate]; + + NSTimeInterval ti = [logFileCreationDate timeIntervalSinceReferenceDate]; + ti += rollingFrequency; + + NSDate *logFileRollingDate = [NSDate dateWithTimeIntervalSinceReferenceDate:ti]; + + NSLogVerbose(@"DDFileLogger: scheduleTimerToRollLogFileDueToAge"); + + NSLogVerbose(@"DDFileLogger: logFileCreationDate: %@", logFileCreationDate); + NSLogVerbose(@"DDFileLogger: logFileRollingDate : %@", logFileRollingDate); + + rollingTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, loggerQueue); + + dispatch_source_set_event_handler(rollingTimer, ^{ @autoreleasepool { + + [self maybeRollLogFileDueToAge]; + + }}); + + #if !OS_OBJECT_USE_OBJC + dispatch_source_t theRollingTimer = rollingTimer; + dispatch_source_set_cancel_handler(rollingTimer, ^{ + dispatch_release(theRollingTimer); + }); + #endif + + uint64_t delay = (uint64_t)([logFileRollingDate timeIntervalSinceNow] * NSEC_PER_SEC); + dispatch_time_t fireTime = dispatch_time(DISPATCH_TIME_NOW, delay); + + dispatch_source_set_timer(rollingTimer, fireTime, DISPATCH_TIME_FOREVER, 1.0); + dispatch_resume(rollingTimer); +} + +- (void)rollLogFile +{ + // This method is public. + // We need to execute the rolling on our logging thread/queue. + + dispatch_block_t block = ^{ @autoreleasepool { + + [self rollLogFileNow]; + }}; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) + { + block(); + } + else + { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); + } +} + +- (void)rollLogFileNow +{ + NSLogVerbose(@"DDFileLogger: rollLogFileNow"); + + + if (currentLogFileHandle == nil) return; + + [currentLogFileHandle synchronizeFile]; + [currentLogFileHandle closeFile]; + currentLogFileHandle = nil; + + currentLogFileInfo.isArchived = YES; + + if ([logFileManager respondsToSelector:@selector(didRollAndArchiveLogFile:)]) + { + [logFileManager didRollAndArchiveLogFile:(currentLogFileInfo.filePath)]; + } + + currentLogFileInfo = nil; + + if (rollingTimer) + { + dispatch_source_cancel(rollingTimer); + rollingTimer = NULL; + } +} + +- (void)maybeRollLogFileDueToAge +{ + if (rollingFrequency > 0.0 && currentLogFileInfo.age >= rollingFrequency) + { + NSLogVerbose(@"DDFileLogger: Rolling log file due to age..."); + + [self rollLogFileNow]; + } + else + { + [self scheduleTimerToRollLogFileDueToAge]; + } +} + +- (void)maybeRollLogFileDueToSize +{ + // This method is called from logMessage. + // Keep it FAST. + + // Note: Use direct access to maximumFileSize variable. + // We specifically wrote our own getter/setter method to allow us to do this (for performance reasons). + + if (maximumFileSize > 0) + { + unsigned long long fileSize = [currentLogFileHandle offsetInFile]; + + if (fileSize >= maximumFileSize) + { + NSLogVerbose(@"DDFileLogger: Rolling log file due to size (%qu)...", fileSize); + + [self rollLogFileNow]; + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark File Logging +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Returns the log file that should be used. + * If there is an existing log file that is suitable, + * within the constraints of maximumFileSize and rollingFrequency, then it is returned. + * + * Otherwise a new file is created and returned. +**/ +- (DDLogFileInfo *)currentLogFileInfo +{ + if (currentLogFileInfo == nil) + { + NSArray *sortedLogFileInfos = [logFileManager sortedLogFileInfos]; + + if ([sortedLogFileInfos count] > 0) + { + DDLogFileInfo *mostRecentLogFileInfo = [sortedLogFileInfos objectAtIndex:0]; + + BOOL useExistingLogFile = YES; + BOOL shouldArchiveMostRecent = NO; + + if (mostRecentLogFileInfo.isArchived) + { + useExistingLogFile = NO; + shouldArchiveMostRecent = NO; + } + else if (maximumFileSize > 0 && mostRecentLogFileInfo.fileSize >= maximumFileSize) + { + useExistingLogFile = NO; + shouldArchiveMostRecent = YES; + } + else if (rollingFrequency > 0.0 && mostRecentLogFileInfo.age >= rollingFrequency) + { + useExistingLogFile = NO; + shouldArchiveMostRecent = YES; + } + + if (useExistingLogFile) + { + NSLogVerbose(@"DDFileLogger: Resuming logging with file %@", mostRecentLogFileInfo.fileName); + + currentLogFileInfo = mostRecentLogFileInfo; + } + else + { + if (shouldArchiveMostRecent) + { + mostRecentLogFileInfo.isArchived = YES; + + if ([logFileManager respondsToSelector:@selector(didArchiveLogFile:)]) + { + [logFileManager didArchiveLogFile:(mostRecentLogFileInfo.filePath)]; + } + } + } + } + + if (currentLogFileInfo == nil) + { + NSString *currentLogFilePath = [logFileManager createNewLogFile]; + + currentLogFileInfo = [[DDLogFileInfo alloc] initWithFilePath:currentLogFilePath]; + } + } + + return currentLogFileInfo; +} + +- (NSFileHandle *)currentLogFileHandle +{ + if (currentLogFileHandle == nil) + { + NSString *logFilePath = [[self currentLogFileInfo] filePath]; + + currentLogFileHandle = [NSFileHandle fileHandleForWritingAtPath:logFilePath]; + [currentLogFileHandle seekToEndOfFile]; + + if (currentLogFileHandle) + { + [self scheduleTimerToRollLogFileDueToAge]; + } + } + + return currentLogFileHandle; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark DDLogger Protocol +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)logMessage:(DDLogMessage *)logMessage +{ + NSString *logMsg = logMessage->logMsg; + + if (formatter) + { + logMsg = [formatter formatLogMessage:logMessage]; + } + + if (logMsg) + { + if (![logMsg hasSuffix:@"\n"]) + { + logMsg = [logMsg stringByAppendingString:@"\n"]; + } + + NSData *logData = [logMsg dataUsingEncoding:NSUTF8StringEncoding]; + + [[self currentLogFileHandle] writeData:logData]; + + [self maybeRollLogFileDueToSize]; + } +} + +- (void)willRemoveLogger +{ + // If you override me be sure to invoke [super willRemoveLogger]; + + [self rollLogFileNow]; +} + +- (NSString *)loggerName +{ + return @"cocoa.lumberjack.fileLogger"; +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#if TARGET_IPHONE_SIMULATOR + #define XATTR_ARCHIVED_NAME @"archived" +#else + #define XATTR_ARCHIVED_NAME @"lumberjack.log.archived" +#endif + +@implementation DDLogFileInfo + +@synthesize filePath; + +@dynamic fileName; +@dynamic fileAttributes; +@dynamic creationDate; +@dynamic modificationDate; +@dynamic fileSize; +@dynamic age; + +@dynamic isArchived; + + +#pragma mark Lifecycle + ++ (id)logFileWithPath:(NSString *)aFilePath +{ + return [[DDLogFileInfo alloc] initWithFilePath:aFilePath]; +} + +- (id)initWithFilePath:(NSString *)aFilePath +{ + if ((self = [super init])) + { + filePath = [aFilePath copy]; + } + return self; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Standard Info +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (NSDictionary *)fileAttributes +{ + if (fileAttributes == nil) + { + fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil]; + } + return fileAttributes; +} + +- (NSString *)fileName +{ + if (fileName == nil) + { + fileName = [filePath lastPathComponent]; + } + return fileName; +} + +- (NSDate *)modificationDate +{ + if (modificationDate == nil) + { + modificationDate = [[self fileAttributes] objectForKey:NSFileModificationDate]; + } + + return modificationDate; +} + +- (NSDate *)creationDate +{ + if (creationDate == nil) + { + + #if TARGET_OS_IPHONE + + const char *path = [filePath UTF8String]; + + struct attrlist attrList; + memset(&attrList, 0, sizeof(attrList)); + attrList.bitmapcount = ATTR_BIT_MAP_COUNT; + attrList.commonattr = ATTR_CMN_CRTIME; + + struct { + u_int32_t attrBufferSizeInBytes; + struct timespec crtime; + } attrBuffer; + + int result = getattrlist(path, &attrList, &attrBuffer, sizeof(attrBuffer), 0); + if (result == 0) + { + double seconds = (double)(attrBuffer.crtime.tv_sec); + double nanos = (double)(attrBuffer.crtime.tv_nsec); + + NSTimeInterval ti = seconds + (nanos / 1000000000.0); + + creationDate = [NSDate dateWithTimeIntervalSince1970:ti]; + } + else + { + NSLogError(@"DDLogFileInfo: creationDate(%@): getattrlist result = %i", self.fileName, result); + } + + #else + + creationDate = [[self fileAttributes] objectForKey:NSFileCreationDate]; + + #endif + + } + return creationDate; +} + +- (unsigned long long)fileSize +{ + if (fileSize == 0) + { + fileSize = [[[self fileAttributes] objectForKey:NSFileSize] unsignedLongLongValue]; + } + + return fileSize; +} + +- (NSTimeInterval)age +{ + return [[self creationDate] timeIntervalSinceNow] * -1.0; +} + +- (NSString *)description +{ + return [@{@"filePath": self.filePath, + @"fileName": self.fileName, + @"fileAttributes": self.fileAttributes, + @"creationDate": self.creationDate, + @"modificationDate": self.modificationDate, + @"fileSize": @(self.fileSize), + @"age": @(self.age), + @"isArchived": @(self.isArchived)} description]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Archiving +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)isArchived +{ + +#if TARGET_IPHONE_SIMULATOR + + // Extended attributes don't work properly on the simulator. + // So we have to use a less attractive alternative. + // See full explanation in the header file. + + return [self hasExtensionAttributeWithName:XATTR_ARCHIVED_NAME]; + +#else + + return [self hasExtendedAttributeWithName:XATTR_ARCHIVED_NAME]; + +#endif +} + +- (void)setIsArchived:(BOOL)flag +{ + +#if TARGET_IPHONE_SIMULATOR + + // Extended attributes don't work properly on the simulator. + // So we have to use a less attractive alternative. + // See full explanation in the header file. + + if (flag) + [self addExtensionAttributeWithName:XATTR_ARCHIVED_NAME]; + else + [self removeExtensionAttributeWithName:XATTR_ARCHIVED_NAME]; + +#else + + if (flag) + [self addExtendedAttributeWithName:XATTR_ARCHIVED_NAME]; + else + [self removeExtendedAttributeWithName:XATTR_ARCHIVED_NAME]; + +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Changes +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)reset +{ + fileName = nil; + fileAttributes = nil; + creationDate = nil; + modificationDate = nil; +} + +- (void)renameFile:(NSString *)newFileName +{ + // This method is only used on the iPhone simulator, where normal extended attributes are broken. + // See full explanation in the header file. + + if (![newFileName isEqualToString:[self fileName]]) + { + NSString *fileDir = [filePath stringByDeletingLastPathComponent]; + + NSString *newFilePath = [fileDir stringByAppendingPathComponent:newFileName]; + + NSLogVerbose(@"DDLogFileInfo: Renaming file: '%@' -> '%@'", self.fileName, newFileName); + + NSError *error = nil; + if (![[NSFileManager defaultManager] moveItemAtPath:filePath toPath:newFilePath error:&error]) + { + NSLogError(@"DDLogFileInfo: Error renaming file (%@): %@", self.fileName, error); + } + + filePath = newFilePath; + [self reset]; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Attribute Management +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#if TARGET_IPHONE_SIMULATOR + +// Extended attributes don't work properly on the simulator. +// So we have to use a less attractive alternative. +// See full explanation in the header file. + +- (BOOL)hasExtensionAttributeWithName:(NSString *)attrName +{ + // This method is only used on the iPhone simulator, where normal extended attributes are broken. + // See full explanation in the header file. + + // Split the file name into components. + // + // log-ABC123.archived.uploaded.txt + // + // 0. log-ABC123 + // 1. archived + // 2. uploaded + // 3. txt + // + // So we want to search for the attrName in the components (ignoring the first and last array indexes). + + NSArray *components = [[self fileName] componentsSeparatedByString:@"."]; + + // Watch out for file names without an extension + + NSUInteger count = [components count]; + NSUInteger max = (count >= 2) ? count-1 : count; + + NSUInteger i; + for (i = 1; i < max; i++) + { + NSString *attr = [components objectAtIndex:i]; + + if ([attrName isEqualToString:attr]) + { + return YES; + } + } + + return NO; +} + +- (void)addExtensionAttributeWithName:(NSString *)attrName +{ + // This method is only used on the iPhone simulator, where normal extended attributes are broken. + // See full explanation in the header file. + + if ([attrName length] == 0) return; + + // Example: + // attrName = "archived" + // + // "log-ABC123.txt" -> "log-ABC123.archived.txt" + + NSArray *components = [[self fileName] componentsSeparatedByString:@"."]; + + NSUInteger count = [components count]; + + NSUInteger estimatedNewLength = [[self fileName] length] + [attrName length] + 1; + NSMutableString *newFileName = [NSMutableString stringWithCapacity:estimatedNewLength]; + + if (count > 0) + { + [newFileName appendString:[components objectAtIndex:0]]; + } + + NSString *lastExt = @""; + + NSUInteger i; + for (i = 1; i < count; i++) + { + NSString *attr = [components objectAtIndex:i]; + if ([attr length] == 0) + { + continue; + } + + if ([attrName isEqualToString:attr]) + { + // Extension attribute already exists in file name + return; + } + + if ([lastExt length] > 0) + { + [newFileName appendFormat:@".%@", lastExt]; + } + + lastExt = attr; + } + + [newFileName appendFormat:@".%@", attrName]; + + if ([lastExt length] > 0) + { + [newFileName appendFormat:@".%@", lastExt]; + } + + [self renameFile:newFileName]; +} + +- (void)removeExtensionAttributeWithName:(NSString *)attrName +{ + // This method is only used on the iPhone simulator, where normal extended attributes are broken. + // See full explanation in the header file. + + if ([attrName length] == 0) return; + + // Example: + // attrName = "archived" + // + // "log-ABC123.txt" -> "log-ABC123.archived.txt" + + NSArray *components = [[self fileName] componentsSeparatedByString:@"."]; + + NSUInteger count = [components count]; + + NSUInteger estimatedNewLength = [[self fileName] length]; + NSMutableString *newFileName = [NSMutableString stringWithCapacity:estimatedNewLength]; + + if (count > 0) + { + [newFileName appendString:[components objectAtIndex:0]]; + } + + BOOL found = NO; + + NSUInteger i; + for (i = 1; i < count; i++) + { + NSString *attr = [components objectAtIndex:i]; + + if ([attrName isEqualToString:attr]) + { + found = YES; + } + else + { + [newFileName appendFormat:@".%@", attr]; + } + } + + if (found) + { + [self renameFile:newFileName]; + } +} + +#else + +- (BOOL)hasExtendedAttributeWithName:(NSString *)attrName +{ + const char *path = [filePath UTF8String]; + const char *name = [attrName UTF8String]; + + ssize_t result = getxattr(path, name, NULL, 0, 0, 0); + + return (result >= 0); +} + +- (void)addExtendedAttributeWithName:(NSString *)attrName +{ + const char *path = [filePath UTF8String]; + const char *name = [attrName UTF8String]; + + int result = setxattr(path, name, NULL, 0, 0, 0); + + if (result < 0) + { + NSLogError(@"DDLogFileInfo: setxattr(%@, %@): error = %i", attrName, self.fileName, result); + } +} + +- (void)removeExtendedAttributeWithName:(NSString *)attrName +{ + const char *path = [filePath UTF8String]; + const char *name = [attrName UTF8String]; + + int result = removexattr(path, name, 0); + + if (result < 0 && errno != ENOATTR) + { + NSLogError(@"DDLogFileInfo: removexattr(%@, %@): error = %i", attrName, self.fileName, result); + } +} + +#endif + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Comparisons +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)isEqual:(id)object +{ + if ([object isKindOfClass:[self class]]) + { + DDLogFileInfo *another = (DDLogFileInfo *)object; + + return [filePath isEqualToString:[another filePath]]; + } + + return NO; +} + +- (NSComparisonResult)reverseCompareByCreationDate:(DDLogFileInfo *)another +{ + NSDate *us = [self creationDate]; + NSDate *them = [another creationDate]; + + NSComparisonResult result = [us compare:them]; + + if (result == NSOrderedAscending) + return NSOrderedDescending; + + if (result == NSOrderedDescending) + return NSOrderedAscending; + + return NSOrderedSame; +} + +- (NSComparisonResult)reverseCompareByModificationDate:(DDLogFileInfo *)another +{ + NSDate *us = [self modificationDate]; + NSDate *them = [another modificationDate]; + + NSComparisonResult result = [us compare:them]; + + if (result == NSOrderedAscending) + return NSOrderedDescending; + + if (result == NSOrderedDescending) + return NSOrderedAscending; + + return NSOrderedSame; +} + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/DDLog.h b/Pods/CocoaLumberjack/Lumberjack/DDLog.h new file mode 100755 index 0000000..5da1849 --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/DDLog.h @@ -0,0 +1,601 @@ +#import + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" wiki. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted + * + * Otherwise, here is a quick refresher. + * There are three steps to using the macros: + * + * Step 1: + * Import the header in your implementation file: + * + * #import "DDLog.h" + * + * Step 2: + * Define your logging level in your implementation file: + * + * // Log levels: off, error, warn, info, verbose + * static const int ddLogLevel = LOG_LEVEL_VERBOSE; + * + * Step 3: + * Replace your NSLog statements with DDLog statements according to the severity of the message. + * + * NSLog(@"Fatal error, no dohickey found!"); -> DDLogError(@"Fatal error, no dohickey found!"); + * + * DDLog works exactly the same as NSLog. + * This means you can pass it multiple variables just like NSLog. +**/ + + +@class DDLogMessage; + +@protocol DDLogger; +@protocol DDLogFormatter; + +/** + * This is the single macro that all other macros below compile into. + * This big multiline macro makes all the other macros easier to read. +**/ + +#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \ + [DDLog log:isAsynchronous \ + level:lvl \ + flag:flg \ + context:ctx \ + file:__FILE__ \ + function:fnct \ + line:__LINE__ \ + tag:atag \ + format:(frmt), ##__VA_ARGS__] + +/** + * Define the Objective-C and C versions of the macro. + * These automatically inject the proper function name for either an objective-c method or c function. + * + * We also define shorthand versions for asynchronous and synchronous logging. +**/ + +#define LOG_OBJC_MACRO(async, lvl, flg, ctx, frmt, ...) \ + LOG_MACRO(async, lvl, flg, ctx, nil, sel_getName(_cmd), frmt, ##__VA_ARGS__) + +#define LOG_C_MACRO(async, lvl, flg, ctx, frmt, ...) \ + LOG_MACRO(async, lvl, flg, ctx, nil, __FUNCTION__, frmt, ##__VA_ARGS__) + +#define SYNC_LOG_OBJC_MACRO(lvl, flg, ctx, frmt, ...) \ + LOG_OBJC_MACRO( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__) + +#define ASYNC_LOG_OBJC_MACRO(lvl, flg, ctx, frmt, ...) \ + LOG_OBJC_MACRO(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__) + +#define SYNC_LOG_C_MACRO(lvl, flg, ctx, frmt, ...) \ + LOG_C_MACRO( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__) + +#define ASYNC_LOG_C_MACRO(lvl, flg, ctx, frmt, ...) \ + LOG_C_MACRO(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__) + +/** + * Define version of the macro that only execute if the logLevel is above the threshold. + * The compiled versions essentially look like this: + * + * if (logFlagForThisLogMsg & ddLogLevel) { execute log message } + * + * As shown further below, Lumberjack actually uses a bitmask as opposed to primitive log levels. + * This allows for a great amount of flexibility and some pretty advanced fine grained logging techniques. + * + * Note that when compiler optimizations are enabled (as they are for your release builds), + * the log messages above your logging threshold will automatically be compiled out. + * + * (If the compiler sees ddLogLevel declared as a constant, the compiler simply checks to see if the 'if' statement + * would execute, and if not it strips it from the binary.) + * + * We also define shorthand versions for asynchronous and synchronous logging. +**/ + +#define LOG_MAYBE(async, lvl, flg, ctx, fnct, frmt, ...) \ + do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, ##__VA_ARGS__); } while(0) + +#define LOG_OBJC_MAYBE(async, lvl, flg, ctx, frmt, ...) \ + LOG_MAYBE(async, lvl, flg, ctx, sel_getName(_cmd), frmt, ##__VA_ARGS__) + +#define LOG_C_MAYBE(async, lvl, flg, ctx, frmt, ...) \ + LOG_MAYBE(async, lvl, flg, ctx, __FUNCTION__, frmt, ##__VA_ARGS__) + +#define SYNC_LOG_OBJC_MAYBE(lvl, flg, ctx, frmt, ...) \ + LOG_OBJC_MAYBE( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__) + +#define ASYNC_LOG_OBJC_MAYBE(lvl, flg, ctx, frmt, ...) \ + LOG_OBJC_MAYBE(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__) + +#define SYNC_LOG_C_MAYBE(lvl, flg, ctx, frmt, ...) \ + LOG_C_MAYBE( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__) + +#define ASYNC_LOG_C_MAYBE(lvl, flg, ctx, frmt, ...) \ + LOG_C_MAYBE(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__) + +/** + * Define versions of the macros that also accept tags. + * + * The DDLogMessage object includes a 'tag' ivar that may be used for a variety of purposes. + * It may be used to pass custom information to loggers or formatters. + * Or it may be used by 3rd party extensions to the framework. + * + * Thes macros just make it a little easier to extend logging functionality. +**/ + +#define LOG_OBJC_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, ...) \ + LOG_MACRO(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, ##__VA_ARGS__) + +#define LOG_C_TAG_MACRO(async, lvl, flg, ctx, tag, frmt, ...) \ + LOG_MACRO(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, ##__VA_ARGS__) + +#define LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \ + do { if(lvl & flg) LOG_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0) + +#define LOG_OBJC_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, ...) \ + LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, sel_getName(_cmd), frmt, ##__VA_ARGS__) + +#define LOG_C_TAG_MAYBE(async, lvl, flg, ctx, tag, frmt, ...) \ + LOG_TAG_MAYBE(async, lvl, flg, ctx, tag, __FUNCTION__, frmt, ##__VA_ARGS__) + +/** + * Define the standard options. + * + * We default to only 4 levels because it makes it easier for beginners + * to make the transition to a logging framework. + * + * More advanced users may choose to completely customize the levels (and level names) to suite their needs. + * For more information on this see the "Custom Log Levels" page: + * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomLogLevels + * + * Advanced users may also notice that we're using a bitmask. + * This is to allow for custom fine grained logging: + * https://github.com/robbiehanson/CocoaLumberjack/wiki/FineGrainedLogging + * + * -- Flags -- + * + * Typically you will use the LOG_LEVELS (see below), but the flags may be used directly in certain situations. + * For example, say you have a lot of warning log messages, and you wanted to disable them. + * However, you still needed to see your error and info log messages. + * You could accomplish that with the following: + * + * static const int ddLogLevel = LOG_FLAG_ERROR | LOG_FLAG_INFO; + * + * Flags may also be consulted when writing custom log formatters, + * as the DDLogMessage class captures the individual flag that caused the log message to fire. + * + * -- Levels -- + * + * Log levels are simply the proper bitmask of the flags. + * + * -- Booleans -- + * + * The booleans may be used when your logging code involves more than one line. + * For example: + * + * if (LOG_VERBOSE) { + * for (id sprocket in sprockets) + * DDLogVerbose(@"sprocket: %@", [sprocket description]) + * } + * + * -- Async -- + * + * Defines the default asynchronous options. + * The default philosophy for asynchronous logging is very simple: + * + * Log messages with errors should be executed synchronously. + * After all, an error just occurred. The application could be unstable. + * + * All other log messages, such as debug output, are executed asynchronously. + * After all, if it wasn't an error, then it was just informational output, + * or something the application was easily able to recover from. + * + * -- Changes -- + * + * You are strongly discouraged from modifying this file. + * If you do, you make it more difficult on yourself to merge future bug fixes and improvements from the project. + * Instead, create your own MyLogging.h or ApplicationNameLogging.h or CompanyLogging.h + * + * For an example of customizing your logging experience, see the "Custom Log Levels" page: + * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomLogLevels +**/ + +#define LOG_FLAG_ERROR (1 << 0) // 0...0001 +#define LOG_FLAG_WARN (1 << 1) // 0...0010 +#define LOG_FLAG_INFO (1 << 2) // 0...0100 +#define LOG_FLAG_VERBOSE (1 << 3) // 0...1000 + +#define LOG_LEVEL_OFF 0 +#define LOG_LEVEL_ERROR (LOG_FLAG_ERROR) // 0...0001 +#define LOG_LEVEL_WARN (LOG_FLAG_ERROR | LOG_FLAG_WARN) // 0...0011 +#define LOG_LEVEL_INFO (LOG_FLAG_ERROR | LOG_FLAG_WARN | LOG_FLAG_INFO) // 0...0111 +#define LOG_LEVEL_VERBOSE (LOG_FLAG_ERROR | LOG_FLAG_WARN | LOG_FLAG_INFO | LOG_FLAG_VERBOSE) // 0...1111 + +#define LOG_ERROR (ddLogLevel & LOG_FLAG_ERROR) +#define LOG_WARN (ddLogLevel & LOG_FLAG_WARN) +#define LOG_INFO (ddLogLevel & LOG_FLAG_INFO) +#define LOG_VERBOSE (ddLogLevel & LOG_FLAG_VERBOSE) + +#define LOG_ASYNC_ENABLED YES + +#define LOG_ASYNC_ERROR ( NO && LOG_ASYNC_ENABLED) +#define LOG_ASYNC_WARN (YES && LOG_ASYNC_ENABLED) +#define LOG_ASYNC_INFO (YES && LOG_ASYNC_ENABLED) +#define LOG_ASYNC_VERBOSE (YES && LOG_ASYNC_ENABLED) + +#define DDLogError(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_ERROR, ddLogLevel, LOG_FLAG_ERROR, 0, frmt, ##__VA_ARGS__) +#define DDLogWarn(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_WARN, ddLogLevel, LOG_FLAG_WARN, 0, frmt, ##__VA_ARGS__) +#define DDLogInfo(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_INFO, ddLogLevel, LOG_FLAG_INFO, 0, frmt, ##__VA_ARGS__) +#define DDLogVerbose(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_VERBOSE, ddLogLevel, LOG_FLAG_VERBOSE, 0, frmt, ##__VA_ARGS__) + +#define DDLogCError(frmt, ...) LOG_C_MAYBE(LOG_ASYNC_ERROR, ddLogLevel, LOG_FLAG_ERROR, 0, frmt, ##__VA_ARGS__) +#define DDLogCWarn(frmt, ...) LOG_C_MAYBE(LOG_ASYNC_WARN, ddLogLevel, LOG_FLAG_WARN, 0, frmt, ##__VA_ARGS__) +#define DDLogCInfo(frmt, ...) LOG_C_MAYBE(LOG_ASYNC_INFO, ddLogLevel, LOG_FLAG_INFO, 0, frmt, ##__VA_ARGS__) +#define DDLogCVerbose(frmt, ...) LOG_C_MAYBE(LOG_ASYNC_VERBOSE, ddLogLevel, LOG_FLAG_VERBOSE, 0, frmt, ##__VA_ARGS__) + +/** + * The THIS_FILE macro gives you an NSString of the file name. + * For simplicity and clarity, the file name does not include the full path or file extension. + * + * For example: DDLogWarn(@"%@: Unable to find thingy", THIS_FILE) -> @"MyViewController: Unable to find thingy" +**/ + +NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy); + +#define THIS_FILE (DDExtractFileNameWithoutExtension(__FILE__, NO)) + +/** + * The THIS_METHOD macro gives you the name of the current objective-c method. + * + * For example: DDLogWarn(@"%@ - Requires non-nil strings", THIS_METHOD) -> @"setMake:model: requires non-nil strings" + * + * Note: This does NOT work in straight C functions (non objective-c). + * Instead you should use the predefined __FUNCTION__ macro. +**/ + +#define THIS_METHOD NSStringFromSelector(_cmd) + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface DDLog : NSObject + +/** + * Provides access to the underlying logging queue. + * This may be helpful to Logger classes for things like thread synchronization. +**/ + ++ (dispatch_queue_t)loggingQueue; + +/** + * Logging Primitive. + * + * This method is used by the macros above. + * It is suggested you stick with the macros as they're easier to use. +**/ + ++ (void)log:(BOOL)synchronous + level:(int)level + flag:(int)flag + context:(int)context + file:(const char *)file + function:(const char *)function + line:(int)line + tag:(id)tag + format:(NSString *)format, ... __attribute__ ((format (__NSString__, 9, 10))); + +/** + * Logging Primitive. + * + * This method can be used if you have a prepared va_list. +**/ + ++ (void)log:(BOOL)asynchronous + level:(int)level + flag:(int)flag + context:(int)context + file:(const char *)file + function:(const char *)function + line:(int)line + tag:(id)tag + format:(NSString *)format + args:(va_list)argList; + + +/** + * Since logging can be asynchronous, there may be times when you want to flush the logs. + * The framework invokes this automatically when the application quits. +**/ + ++ (void)flushLog; + +/** + * Loggers + * + * If you want your log statements to go somewhere, + * you should create and add a logger. +**/ + ++ (void)addLogger:(id )logger; ++ (void)removeLogger:(id )logger; + ++ (void)removeAllLoggers; + +/** + * Registered Dynamic Logging + * + * These methods allow you to obtain a list of classes that are using registered dynamic logging, + * and also provides methods to get and set their log level during run time. +**/ + ++ (NSArray *)registeredClasses; ++ (NSArray *)registeredClassNames; + ++ (int)logLevelForClass:(Class)aClass; ++ (int)logLevelForClassWithName:(NSString *)aClassName; + ++ (void)setLogLevel:(int)logLevel forClass:(Class)aClass; ++ (void)setLogLevel:(int)logLevel forClassWithName:(NSString *)aClassName; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@protocol DDLogger +@required + +- (void)logMessage:(DDLogMessage *)logMessage; + +/** + * Formatters may optionally be added to any logger. + * + * If no formatter is set, the logger simply logs the message as it is given in logMessage, + * or it may use its own built in formatting style. +**/ +- (id )logFormatter; +- (void)setLogFormatter:(id )formatter; + +@optional + +/** + * Since logging is asynchronous, adding and removing loggers is also asynchronous. + * In other words, the loggers are added and removed at appropriate times with regards to log messages. + * + * - Loggers will not receive log messages that were executed prior to when they were added. + * - Loggers will not receive log messages that were executed after they were removed. + * + * These methods are executed in the logging thread/queue. + * This is the same thread/queue that will execute every logMessage: invocation. + * Loggers may use these methods for thread synchronization or other setup/teardown tasks. +**/ +- (void)didAddLogger; +- (void)willRemoveLogger; + +/** + * Some loggers may buffer IO for optimization purposes. + * For example, a database logger may only save occasionaly as the disk IO is slow. + * In such loggers, this method should be implemented to flush any pending IO. + * + * This allows invocations of DDLog's flushLog method to be propogated to loggers that need it. + * + * Note that DDLog's flushLog method is invoked automatically when the application quits, + * and it may be also invoked manually by the developer prior to application crashes, or other such reasons. +**/ +- (void)flush; + +/** + * Each logger is executed concurrently with respect to the other loggers. + * Thus, a dedicated dispatch queue is used for each logger. + * Logger implementations may optionally choose to provide their own dispatch queue. +**/ +- (dispatch_queue_t)loggerQueue; + +/** + * If the logger implementation does not choose to provide its own queue, + * one will automatically be created for it. + * The created queue will receive its name from this method. + * This may be helpful for debugging or profiling reasons. +**/ +- (NSString *)loggerName; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@protocol DDLogFormatter +@required + +/** + * Formatters may optionally be added to any logger. + * This allows for increased flexibility in the logging environment. + * For example, log messages for log files may be formatted differently than log messages for the console. + * + * For more information about formatters, see the "Custom Formatters" page: + * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters + * + * The formatter may also optionally filter the log message by returning nil, + * in which case the logger will not log the message. +**/ +- (NSString *)formatLogMessage:(DDLogMessage *)logMessage; + +@optional + +/** + * A single formatter instance can be added to multiple loggers. + * These methods provides hooks to notify the formatter of when it's added/removed. + * + * This is primarily for thread-safety. + * If a formatter is explicitly not thread-safe, it may wish to throw an exception if added to multiple loggers. + * Or if a formatter has potentially thread-unsafe code (e.g. NSDateFormatter), + * it could possibly use these hooks to switch to thread-safe versions of the code. +**/ +- (void)didAddToLogger:(id )logger; +- (void)willRemoveFromLogger:(id )logger; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@protocol DDRegisteredDynamicLogging + +/** + * Implement these methods to allow a file's log level to be managed from a central location. + * + * This is useful if you'd like to be able to change log levels for various parts + * of your code from within the running application. + * + * Imagine pulling up the settings for your application, + * and being able to configure the logging level on a per file basis. + * + * The implementation can be very straight-forward: + * + * + (int)ddLogLevel + * { + * return ddLogLevel; + * } + * + * + (void)ddSetLogLevel:(int)logLevel + * { + * ddLogLevel = logLevel; + * } +**/ + ++ (int)ddLogLevel; ++ (void)ddSetLogLevel:(int)logLevel; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * The DDLogMessage class encapsulates information about the log message. + * If you write custom loggers or formatters, you will be dealing with objects of this class. +**/ + +enum { + DDLogMessageCopyFile = 1 << 0, + DDLogMessageCopyFunction = 1 << 1 +}; +typedef int DDLogMessageOptions; + +@interface DDLogMessage : NSObject +{ + +// The public variables below can be accessed directly (for speed). +// For example: logMessage->logLevel + +@public + int logLevel; + int logFlag; + int logContext; + NSString *logMsg; + NSDate *timestamp; + char *file; + char *function; + int lineNumber; + mach_port_t machThreadID; + char *queueLabel; + NSString *threadName; + + // For 3rd party extensions to the framework, where flags and contexts aren't enough. + id tag; + + // For 3rd party extensions that manually create DDLogMessage instances. + DDLogMessageOptions options; +} + +/** + * Standard init method for a log message object. + * Used by the logging primitives. (And the macros use the logging primitives.) + * + * If you find need to manually create logMessage objects, there is one thing you should be aware of: + * + * If no flags are passed, the method expects the file and function parameters to be string literals. + * That is, it expects the given strings to exist for the duration of the object's lifetime, + * and it expects the given strings to be immutable. + * In other words, it does not copy these strings, it simply points to them. + * This is due to the fact that __FILE__ and __FUNCTION__ are usually used to specify these parameters, + * so it makes sense to optimize and skip the unnecessary allocations. + * However, if you need them to be copied you may use the options parameter to specify this. + * Options is a bitmask which supports DDLogMessageCopyFile and DDLogMessageCopyFunction. +**/ +- (id)initWithLogMsg:(NSString *)logMsg + level:(int)logLevel + flag:(int)logFlag + context:(int)logContext + file:(const char *)file + function:(const char *)function + line:(int)line + tag:(id)tag + options:(DDLogMessageOptions)optionsMask; + +/** + * Returns the threadID as it appears in NSLog. + * That is, it is a hexadecimal value which is calculated from the machThreadID. +**/ +- (NSString *)threadID; + +/** + * Convenience property to get just the file name, as the file variable is generally the full file path. + * This method does not include the file extension, which is generally unwanted for logging purposes. +**/ +- (NSString *)fileName; + +/** + * Returns the function variable in NSString form. +**/ +- (NSString *)methodName; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * The DDLogger protocol specifies that an optional formatter can be added to a logger. + * Most (but not all) loggers will want to support formatters. + * + * However, writting getters and setters in a thread safe manner, + * while still maintaining maximum speed for the logging process, is a difficult task. + * + * To do it right, the implementation of the getter/setter has strict requiremenets: + * - Must NOT require the logMessage method to acquire a lock. + * - Must NOT require the logMessage method to access an atomic property (also a lock of sorts). + * + * To simplify things, an abstract logger is provided that implements the getter and setter. + * + * Logger implementations may simply extend this class, + * and they can ACCESS THE FORMATTER VARIABLE DIRECTLY from within their logMessage method! +**/ + +@interface DDAbstractLogger : NSObject +{ + id formatter; + + dispatch_queue_t loggerQueue; +} + +- (id )logFormatter; +- (void)setLogFormatter:(id )formatter; + +// For thread-safety assertions +- (BOOL)isOnGlobalLoggingQueue; +- (BOOL)isOnInternalLoggerQueue; + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/DDLog.m b/Pods/CocoaLumberjack/Lumberjack/DDLog.m new file mode 100755 index 0000000..1e1ddd6 --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/DDLog.m @@ -0,0 +1,1083 @@ +#import "DDLog.h" + +#import +#import +#import +#import +#import + + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" wiki. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted + * +**/ + +#if ! __has_feature(objc_arc) +#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + +// We probably shouldn't be using DDLog() statements within the DDLog implementation. +// But we still want to leave our log statements for any future debugging, +// and to allow other developers to trace the implementation (which is a great learning tool). +// +// So we use a primitive logging macro around NSLog. +// We maintain the NS prefix on the macros to be explicit about the fact that we're using NSLog. + +#define DD_DEBUG NO + +#define NSLogDebug(frmt, ...) do{ if(DD_DEBUG) NSLog((frmt), ##__VA_ARGS__); } while(0) + +// Specifies the maximum queue size of the logging thread. +// +// Since most logging is asynchronous, its possible for rogue threads to flood the logging queue. +// That is, to issue an abundance of log statements faster than the logging thread can keepup. +// Typically such a scenario occurs when log statements are added haphazardly within large loops, +// but may also be possible if relatively slow loggers are being used. +// +// This property caps the queue size at a given number of outstanding log statements. +// If a thread attempts to issue a log statement when the queue is already maxed out, +// the issuing thread will block until the queue size drops below the max again. + +#define LOG_MAX_QUEUE_SIZE 1000 // Should not exceed INT32_MAX + +// The "global logging queue" refers to [DDLog loggingQueue]. +// It is the queue that all log statements go through. +// +// The logging queue sets a flag via dispatch_queue_set_specific using this key. +// We can check for this key via dispatch_get_specific() to see if we're on the "global logging queue". + +static void *const GlobalLoggingQueueIdentityKey = (void *)&GlobalLoggingQueueIdentityKey; + + +@interface DDLoggerNode : NSObject { +@public + id logger; + dispatch_queue_t loggerQueue; +} + ++ (DDLoggerNode *)nodeWithLogger:(id )logger loggerQueue:(dispatch_queue_t)loggerQueue; + +@end + + +@interface DDLog (PrivateAPI) + ++ (void)lt_addLogger:(id )logger; ++ (void)lt_removeLogger:(id )logger; ++ (void)lt_removeAllLoggers; ++ (void)lt_log:(DDLogMessage *)logMessage; ++ (void)lt_flush; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDLog + +// An array used to manage all the individual loggers. +// The array is only modified on the loggingQueue/loggingThread. +static NSMutableArray *loggers; + +// All logging statements are added to the same queue to ensure FIFO operation. +static dispatch_queue_t loggingQueue; + +// Individual loggers are executed concurrently per log statement. +// Each logger has it's own associated queue, and a dispatch group is used for synchrnoization. +static dispatch_group_t loggingGroup; + +// In order to prevent to queue from growing infinitely large, +// a maximum size is enforced (LOG_MAX_QUEUE_SIZE). +static dispatch_semaphore_t queueSemaphore; + +// Minor optimization for uniprocessor machines +static unsigned int numProcessors; + +/** + * The runtime sends initialize to each class in a program exactly one time just before the class, + * or any class that inherits from it, is sent its first message from within the program. (Thus the + * method may never be invoked if the class is not used.) The runtime sends the initialize message to + * classes in a thread-safe manner. Superclasses receive this message before their subclasses. + * + * This method may also be called directly (assumably by accident), hence the safety mechanism. +**/ ++ (void)initialize +{ + static BOOL initialized = NO; + if (!initialized) + { + initialized = YES; + + loggers = [[NSMutableArray alloc] initWithCapacity:4]; + + NSLogDebug(@"DDLog: Using grand central dispatch"); + + loggingQueue = dispatch_queue_create("cocoa.lumberjack", NULL); + loggingGroup = dispatch_group_create(); + + void *nonNullValue = GlobalLoggingQueueIdentityKey; // Whatever, just not null + dispatch_queue_set_specific(loggingQueue, GlobalLoggingQueueIdentityKey, nonNullValue, NULL); + + queueSemaphore = dispatch_semaphore_create(LOG_MAX_QUEUE_SIZE); + + // Figure out how many processors are available. + // This may be used later for an optimization on uniprocessor machines. + + host_basic_info_data_t hostInfo; + mach_msg_type_number_t infoCount; + + infoCount = HOST_BASIC_INFO_COUNT; + host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount); + + unsigned int result = (unsigned int)(hostInfo.max_cpus); + unsigned int one = (unsigned int)(1); + + numProcessors = MAX(result, one); + + NSLogDebug(@"DDLog: numProcessors = %u", numProcessors); + + + #if TARGET_OS_IPHONE + NSString *notificationName = @"UIApplicationWillTerminateNotification"; + #else + NSString *notificationName = @"NSApplicationWillTerminateNotification"; + #endif + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationWillTerminate:) + name:notificationName + object:nil]; + } +} + +/** + * Provides access to the logging queue. +**/ ++ (dispatch_queue_t)loggingQueue +{ + return loggingQueue; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Notifications +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ++ (void)applicationWillTerminate:(NSNotification *)notification +{ + [self flushLog]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Logger Management +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ++ (void)addLogger:(id )logger +{ + if (logger == nil) return; + + dispatch_async(loggingQueue, ^{ @autoreleasepool { + + [self lt_addLogger:logger]; + }}); +} + ++ (void)removeLogger:(id )logger +{ + if (logger == nil) return; + + dispatch_async(loggingQueue, ^{ @autoreleasepool { + + [self lt_removeLogger:logger]; + }}); +} + ++ (void)removeAllLoggers +{ + dispatch_async(loggingQueue, ^{ @autoreleasepool { + + [self lt_removeAllLoggers]; + }}); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Master Logging +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ++ (void)queueLogMessage:(DDLogMessage *)logMessage asynchronously:(BOOL)asyncFlag +{ + // We have a tricky situation here... + // + // In the common case, when the queueSize is below the maximumQueueSize, + // we want to simply enqueue the logMessage. And we want to do this as fast as possible, + // which means we don't want to block and we don't want to use any locks. + // + // However, if the queueSize gets too big, we want to block. + // But we have very strict requirements as to when we block, and how long we block. + // + // The following example should help illustrate our requirements: + // + // Imagine that the maximum queue size is configured to be 5, + // and that there are already 5 log messages queued. + // Let us call these 5 queued log messages A, B, C, D, and E. (A is next to be executed) + // + // Now if our thread issues a log statement (let us call the log message F), + // it should block before the message is added to the queue. + // Furthermore, it should be unblocked immediately after A has been unqueued. + // + // The requirements are strict in this manner so that we block only as long as necessary, + // and so that blocked threads are unblocked in the order in which they were blocked. + // + // Returning to our previous example, let us assume that log messages A through E are still queued. + // Our aforementioned thread is blocked attempting to queue log message F. + // Now assume we have another separate thread that attempts to issue log message G. + // It should block until log messages A and B have been unqueued. + + + // We are using a counting semaphore provided by GCD. + // The semaphore is initialized with our LOG_MAX_QUEUE_SIZE value. + // Everytime we want to queue a log message we decrement this value. + // If the resulting value is less than zero, + // the semaphore function waits in FIFO order for a signal to occur before returning. + // + // A dispatch semaphore is an efficient implementation of a traditional counting semaphore. + // Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked. + // If the calling semaphore does not need to block, no kernel call is made. + + dispatch_semaphore_wait(queueSemaphore, DISPATCH_TIME_FOREVER); + + // We've now sure we won't overflow the queue. + // It is time to queue our log message. + + dispatch_block_t logBlock = ^{ @autoreleasepool { + + [self lt_log:logMessage]; + }}; + + if (asyncFlag) + dispatch_async(loggingQueue, logBlock); + else + dispatch_sync(loggingQueue, logBlock); +} + ++ (void)log:(BOOL)asynchronous + level:(int)level + flag:(int)flag + context:(int)context + file:(const char *)file + function:(const char *)function + line:(int)line + tag:(id)tag + format:(NSString *)format, ... +{ + va_list args; + if (format) + { + va_start(args, format); + + NSString *logMsg = [[NSString alloc] initWithFormat:format arguments:args]; + DDLogMessage *logMessage = [[DDLogMessage alloc] initWithLogMsg:logMsg + level:level + flag:flag + context:context + file:file + function:function + line:line + tag:tag + options:0]; + + [self queueLogMessage:logMessage asynchronously:asynchronous]; + + va_end(args); + } +} + ++ (void)log:(BOOL)asynchronous + level:(int)level + flag:(int)flag + context:(int)context + file:(const char *)file + function:(const char *)function + line:(int)line + tag:(id)tag + format:(NSString *)format + args:(va_list)args +{ + if (format) + { + NSString *logMsg = [[NSString alloc] initWithFormat:format arguments:args]; + DDLogMessage *logMessage = [[DDLogMessage alloc] initWithLogMsg:logMsg + level:level + flag:flag + context:context + file:file + function:function + line:line + tag:tag + options:0]; + + [self queueLogMessage:logMessage asynchronously:asynchronous]; + } +} + ++ (void)flushLog +{ + dispatch_sync(loggingQueue, ^{ @autoreleasepool { + + [self lt_flush]; + }}); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Registered Dynamic Logging +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ++ (BOOL)isRegisteredClass:(Class)class +{ + SEL getterSel = @selector(ddLogLevel); + SEL setterSel = @selector(ddSetLogLevel:); + +#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR + + // Issue #6 (GoogleCode) - Crashes on iOS 4.2.1 and iPhone 4 + // + // Crash caused by class_getClassMethod(2). + // + // "It's a bug with UIAccessibilitySafeCategory__NSObject so it didn't pop up until + // users had VoiceOver enabled [...]. I was able to work around it by searching the + // result of class_copyMethodList() instead of calling class_getClassMethod()" + + BOOL result = NO; + + unsigned int methodCount, i; + Method *methodList = class_copyMethodList(object_getClass(class), &methodCount); + + if (methodList != NULL) + { + BOOL getterFound = NO; + BOOL setterFound = NO; + + for (i = 0; i < methodCount; ++i) + { + SEL currentSel = method_getName(methodList[i]); + + if (currentSel == getterSel) + { + getterFound = YES; + } + else if (currentSel == setterSel) + { + setterFound = YES; + } + + if (getterFound && setterFound) + { + result = YES; + break; + } + } + + free(methodList); + } + + return result; + +#else + + // Issue #24 (GitHub) - Crashing in in ARC+Simulator + // + // The method +[DDLog isRegisteredClass] will crash a project when using it with ARC + Simulator. + // For running in the Simulator, it needs to execute the non-iOS code. + + Method getter = class_getClassMethod(class, getterSel); + Method setter = class_getClassMethod(class, setterSel); + + if ((getter != NULL) && (setter != NULL)) + { + return YES; + } + + return NO; + +#endif +} + ++ (NSArray *)registeredClasses +{ + int numClasses, i; + + // We're going to get the list of all registered classes. + // The Objective-C runtime library automatically registers all the classes defined in your source code. + // + // To do this we use the following method (documented in the Objective-C Runtime Reference): + // + // int objc_getClassList(Class *buffer, int bufferLen) + // + // We can pass (NULL, 0) to obtain the total number of + // registered class definitions without actually retrieving any class definitions. + // This allows us to allocate the minimum amount of memory needed for the application. + + numClasses = objc_getClassList(NULL, 0); + + // The numClasses method now tells us how many classes we have. + // So we can allocate our buffer, and get pointers to all the class definitions. + + Class *classes = (Class *)malloc(sizeof(Class) * numClasses); + + numClasses = objc_getClassList(classes, numClasses); + + // We can now loop through the classes, and test each one to see if it is a DDLogging class. + + NSMutableArray *result = [NSMutableArray arrayWithCapacity:numClasses]; + + for (i = 0; i < numClasses; i++) + { + Class class = classes[i]; + + if ([self isRegisteredClass:class]) + { + [result addObject:class]; + } + } + + free(classes); + + return result; +} + ++ (NSArray *)registeredClassNames +{ + NSArray *registeredClasses = [self registeredClasses]; + NSMutableArray *result = [NSMutableArray arrayWithCapacity:[registeredClasses count]]; + + for (Class class in registeredClasses) + { + [result addObject:NSStringFromClass(class)]; + } + + return result; +} + ++ (int)logLevelForClass:(Class)aClass +{ + if ([self isRegisteredClass:aClass]) + { + return [aClass ddLogLevel]; + } + + return -1; +} + ++ (int)logLevelForClassWithName:(NSString *)aClassName +{ + Class aClass = NSClassFromString(aClassName); + + return [self logLevelForClass:aClass]; +} + ++ (void)setLogLevel:(int)logLevel forClass:(Class)aClass +{ + if ([self isRegisteredClass:aClass]) + { + [aClass ddSetLogLevel:logLevel]; + } +} + ++ (void)setLogLevel:(int)logLevel forClassWithName:(NSString *)aClassName +{ + Class aClass = NSClassFromString(aClassName); + + [self setLogLevel:logLevel forClass:aClass]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Logging Thread +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * This method should only be run on the logging thread/queue. +**/ ++ (void)lt_addLogger:(id )logger +{ + // Add to loggers array. + // Need to create loggerQueue if loggerNode doesn't provide one. + + dispatch_queue_t loggerQueue = NULL; + + if ([logger respondsToSelector:@selector(loggerQueue)]) + { + // Logger may be providing its own queue + + loggerQueue = [logger loggerQueue]; + } + + if (loggerQueue == nil) + { + // Automatically create queue for the logger. + // Use the logger name as the queue name if possible. + + const char *loggerQueueName = NULL; + if ([logger respondsToSelector:@selector(loggerName)]) + { + loggerQueueName = [[logger loggerName] UTF8String]; + } + + loggerQueue = dispatch_queue_create(loggerQueueName, NULL); + } + + DDLoggerNode *loggerNode = [DDLoggerNode nodeWithLogger:logger loggerQueue:loggerQueue]; + [loggers addObject:loggerNode]; + + if ([logger respondsToSelector:@selector(didAddLogger)]) + { + dispatch_async(loggerNode->loggerQueue, ^{ @autoreleasepool { + + [logger didAddLogger]; + }}); + } +} + +/** + * This method should only be run on the logging thread/queue. +**/ ++ (void)lt_removeLogger:(id )logger +{ + // Find associated loggerNode in list of added loggers + + DDLoggerNode *loggerNode = nil; + + for (DDLoggerNode *node in loggers) + { + if (node->logger == logger) + { + loggerNode = node; + break; + } + } + + if (loggerNode == nil) + { + NSLogDebug(@"DDLog: Request to remove logger which wasn't added"); + return; + } + + // Notify logger + + if ([logger respondsToSelector:@selector(willRemoveLogger)]) + { + dispatch_async(loggerNode->loggerQueue, ^{ @autoreleasepool { + + [logger willRemoveLogger]; + }}); + } + + // Remove from loggers array + + [loggers removeObject:loggerNode]; +} + +/** + * This method should only be run on the logging thread/queue. +**/ ++ (void)lt_removeAllLoggers +{ + // Notify all loggers + + for (DDLoggerNode *loggerNode in loggers) + { + if ([loggerNode->logger respondsToSelector:@selector(willRemoveLogger)]) + { + dispatch_async(loggerNode->loggerQueue, ^{ @autoreleasepool { + + [loggerNode->logger willRemoveLogger]; + }}); + } + } + + // Remove all loggers from array + + [loggers removeAllObjects]; +} + +/** + * This method should only be run on the logging thread/queue. +**/ ++ (void)lt_log:(DDLogMessage *)logMessage +{ + // Execute the given log message on each of our loggers. + + if (numProcessors > 1) + { + // Execute each logger concurrently, each within its own queue. + // All blocks are added to same group. + // After each block has been queued, wait on group. + // + // The waiting ensures that a slow logger doesn't end up with a large queue of pending log messages. + // This would defeat the purpose of the efforts we made earlier to restrict the max queue size. + + for (DDLoggerNode *loggerNode in loggers) + { + dispatch_group_async(loggingGroup, loggerNode->loggerQueue, ^{ @autoreleasepool { + + [loggerNode->logger logMessage:logMessage]; + + }}); + } + + dispatch_group_wait(loggingGroup, DISPATCH_TIME_FOREVER); + } + else + { + // Execute each logger serialy, each within its own queue. + + for (DDLoggerNode *loggerNode in loggers) + { + dispatch_sync(loggerNode->loggerQueue, ^{ @autoreleasepool { + + [loggerNode->logger logMessage:logMessage]; + + }}); + } + } + + // If our queue got too big, there may be blocked threads waiting to add log messages to the queue. + // Since we've now dequeued an item from the log, we may need to unblock the next thread. + + // We are using a counting semaphore provided by GCD. + // The semaphore is initialized with our LOG_MAX_QUEUE_SIZE value. + // When a log message is queued this value is decremented. + // When a log message is dequeued this value is incremented. + // If the value ever drops below zero, + // the queueing thread blocks and waits in FIFO order for us to signal it. + // + // A dispatch semaphore is an efficient implementation of a traditional counting semaphore. + // Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked. + // If the calling semaphore does not need to block, no kernel call is made. + + dispatch_semaphore_signal(queueSemaphore); +} + +/** + * This method should only be run on the background logging thread. +**/ ++ (void)lt_flush +{ + // All log statements issued before the flush method was invoked have now been executed. + // + // Now we need to propogate the flush request to any loggers that implement the flush method. + // This is designed for loggers that buffer IO. + + for (DDLoggerNode *loggerNode in loggers) + { + if ([loggerNode->logger respondsToSelector:@selector(flush)]) + { + dispatch_group_async(loggingGroup, loggerNode->loggerQueue, ^{ @autoreleasepool { + + [loggerNode->logger flush]; + + }}); + } + } + + dispatch_group_wait(loggingGroup, DISPATCH_TIME_FOREVER); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Utilities +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy) +{ + if (filePath == NULL) return nil; + + char *lastSlash = NULL; + char *lastDot = NULL; + + char *p = (char *)filePath; + + while (*p != '\0') + { + if (*p == '/') + lastSlash = p; + else if (*p == '.') + lastDot = p; + + p++; + } + + char *subStr; + NSUInteger subLen; + + if (lastSlash) + { + if (lastDot) + { + // lastSlash -> lastDot + subStr = lastSlash + 1; + subLen = lastDot - subStr; + } + else + { + // lastSlash -> endOfString + subStr = lastSlash + 1; + subLen = p - subStr; + } + } + else + { + if (lastDot) + { + // startOfString -> lastDot + subStr = (char *)filePath; + subLen = lastDot - subStr; + } + else + { + // startOfString -> endOfString + subStr = (char *)filePath; + subLen = p - subStr; + } + } + + if (copy) + { + return [[NSString alloc] initWithBytes:subStr + length:subLen + encoding:NSUTF8StringEncoding]; + } + else + { + // We can take advantage of the fact that __FILE__ is a string literal. + // Specifically, we don't need to waste time copying the string. + // We can just tell NSString to point to a range within the string literal. + + return [[NSString alloc] initWithBytesNoCopy:subStr + length:subLen + encoding:NSUTF8StringEncoding + freeWhenDone:NO]; + } +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDLoggerNode + +- (id)initWithLogger:(id )aLogger loggerQueue:(dispatch_queue_t)aLoggerQueue +{ + if ((self = [super init])) + { + logger = aLogger; + + if (aLoggerQueue) { + loggerQueue = aLoggerQueue; + #if !OS_OBJECT_USE_OBJC + dispatch_retain(loggerQueue); + #endif + } + } + return self; +} + ++ (DDLoggerNode *)nodeWithLogger:(id )logger loggerQueue:(dispatch_queue_t)loggerQueue +{ + return [[DDLoggerNode alloc] initWithLogger:logger loggerQueue:loggerQueue]; +} + +- (void)dealloc +{ + #if !OS_OBJECT_USE_OBJC + if (loggerQueue) dispatch_release(loggerQueue); + #endif +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDLogMessage + +static char *dd_str_copy(const char *str) +{ + if (str == NULL) return NULL; + + size_t length = strlen(str); + char * result = malloc(length + 1); + strncpy(result, str, length); + result[length] = 0; + + return result; +} + +- (id)initWithLogMsg:(NSString *)msg + level:(int)level + flag:(int)flag + context:(int)context + file:(const char *)aFile + function:(const char *)aFunction + line:(int)line + tag:(id)aTag + options:(DDLogMessageOptions)optionsMask +{ + if ((self = [super init])) + { + logMsg = msg; + logLevel = level; + logFlag = flag; + logContext = context; + lineNumber = line; + tag = aTag; + options = optionsMask; + + if (options & DDLogMessageCopyFile) + file = dd_str_copy(aFile); + else + file = (char *)aFile; + + if (options & DDLogMessageCopyFunction) + function = dd_str_copy(aFunction); + else + function = (char *)aFunction; + + timestamp = [[NSDate alloc] init]; + + machThreadID = pthread_mach_thread_np(pthread_self()); + + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + // The documentation for dispatch_get_current_queue() states: + // + // > [This method is] "recommended for debugging and logging purposes only"... + // + // Well that's exactly how we're using it here. Literally for logging purposes only. + // However, Apple has decided to deprecate this method anyway. + // However they have not given us an alternate version of dispatch_queue_get_label() that + // automatically uses the current queue, thus dispatch_get_current_queue() is still required. + // + // If dispatch_get_current_queue() disappears, without a dispatch_queue_get_label() alternative, + // Apple will have effectively taken away our ability to properly log the name of executing dispatch queue. + + dispatch_queue_t currentQueue = dispatch_get_current_queue(); + #pragma clang diagnostic pop + + queueLabel = dd_str_copy(dispatch_queue_get_label(currentQueue)); + + threadName = [[NSThread currentThread] name]; + } + return self; +} + +- (NSString *)threadID +{ + return [[NSString alloc] initWithFormat:@"%x", machThreadID]; +} + +- (NSString *)fileName +{ + return DDExtractFileNameWithoutExtension(file, NO); +} + +- (NSString *)methodName +{ + if (function == NULL) + return nil; + else + return [[NSString alloc] initWithUTF8String:function]; +} + +- (void)dealloc +{ + if (file && (options & DDLogMessageCopyFile)) + free(file); + + if (function && (options & DDLogMessageCopyFunction)) + free(function); + + if (queueLabel) + free(queueLabel); +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDAbstractLogger + +- (id)init +{ + if ((self = [super init])) + { + const char *loggerQueueName = NULL; + if ([self respondsToSelector:@selector(loggerName)]) + { + loggerQueueName = [[self loggerName] UTF8String]; + } + + loggerQueue = dispatch_queue_create(loggerQueueName, NULL); + + // We're going to use dispatch_queue_set_specific() to "mark" our loggerQueue. + // Later we can use dispatch_get_specific() to determine if we're executing on our loggerQueue. + // The documentation states: + // + // > Keys are only compared as pointers and are never dereferenced. + // > Thus, you can use a pointer to a static variable for a specific subsystem or + // > any other value that allows you to identify the value uniquely. + // > Specifying a pointer to a string constant is not recommended. + // + // So we're going to use the very convenient key of "self", + // which also works when multiple logger classes extend this class, as each will have a different "self" key. + // + // This is used primarily for thread-safety assertions (via the isOnInternalLoggerQueue method below). + + void *key = (__bridge void *)self; + void *nonNullValue = (__bridge void *)self; + + dispatch_queue_set_specific(loggerQueue, key, nonNullValue, NULL); + } + return self; +} + +- (void)dealloc +{ + #if !OS_OBJECT_USE_OBJC + if (loggerQueue) dispatch_release(loggerQueue); + #endif +} + +- (void)logMessage:(DDLogMessage *)logMessage +{ + // Override me +} + +- (id )logFormatter +{ + // This method must be thread safe and intuitive. + // Therefore if somebody executes the following code: + // + // [logger setLogFormatter:myFormatter]; + // formatter = [logger logFormatter]; + // + // They would expect formatter to equal myFormatter. + // This functionality must be ensured by the getter and setter method. + // + // The thread safety must not come at a cost to the performance of the logMessage method. + // This method is likely called sporadically, while the logMessage method is called repeatedly. + // This means, the implementation of this method: + // - Must NOT require the logMessage method to acquire a lock. + // - Must NOT require the logMessage method to access an atomic property (also a lock of sorts). + // + // Thread safety is ensured by executing access to the formatter variable on the loggerQueue. + // This is the same queue that the logMessage method operates on. + // + // Note: The last time I benchmarked the performance of direct access vs atomic property access, + // direct access was over twice as fast on the desktop and over 6 times as fast on the iPhone. + // + // Furthermore, consider the following code: + // + // DDLogVerbose(@"log msg 1"); + // DDLogVerbose(@"log msg 2"); + // [logger setFormatter:myFormatter]; + // DDLogVerbose(@"log msg 3"); + // + // Our intuitive requirement means that the new formatter will only apply to the 3rd log message. + // This must remain true even when using asynchronous logging. + // We must keep in mind the various queue's that are in play here: + // + // loggerQueue : Our own private internal queue that the logMessage method runs on. + // Operations are added to this queue from the global loggingQueue. + // + // globalLoggingQueue : The queue that all log messages go through before they arrive in our loggerQueue. + // + // All log statements go through the serial gloabalLoggingQueue before they arrive at our loggerQueue. + // Thus this method also goes through the serial globalLoggingQueue to ensure intuitive operation. + + // IMPORTANT NOTE: + // + // Methods within the DDLogger implementation MUST access the formatter ivar directly. + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block id result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(loggerQueue, ^{ + result = formatter; + }); + }); + + return result; +} + +- (void)setLogFormatter:(id )logFormatter +{ + // The design of this method is documented extensively in the logFormatter message (above in code). + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_block_t block = ^{ @autoreleasepool { + + if (formatter != logFormatter) + { + if ([formatter respondsToSelector:@selector(willRemoveFromLogger:)]) { + [formatter willRemoveFromLogger:self]; + } + + formatter = logFormatter; + + if ([formatter respondsToSelector:@selector(didAddToLogger:)]) { + [formatter didAddToLogger:self]; + } + } + }}; + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); +} + +- (dispatch_queue_t)loggerQueue +{ + return loggerQueue; +} + +- (NSString *)loggerName +{ + return NSStringFromClass([self class]); +} + +- (BOOL)isOnGlobalLoggingQueue +{ + return (dispatch_get_specific(GlobalLoggingQueueIdentityKey) != NULL); +} + +- (BOOL)isOnInternalLoggerQueue +{ + void *key = (__bridge void *)self; + return (dispatch_get_specific(key) != NULL); +} + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.h b/Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.h new file mode 100755 index 0000000..4cbd2e8 --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.h @@ -0,0 +1,167 @@ +#import +#if TARGET_OS_IPHONE +#import +#else +#import +#endif + +#import "DDLog.h" + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" wiki. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted + * + * + * This class provides a logger for Terminal output or Xcode console output, + * depending on where you are running your code. + * + * As described in the "Getting Started" page, + * the traditional NSLog() function directs it's output to two places: + * + * - Apple System Log (so it shows up in Console.app) + * - StdErr (if stderr is a TTY, so log statements show up in Xcode console) + * + * To duplicate NSLog() functionality you can simply add this logger and an asl logger. + * However, if you instead choose to use file logging (for faster performance), + * you may choose to use only a file logger and a tty logger. +**/ + +@interface DDTTYLogger : DDAbstractLogger +{ + NSCalendar *calendar; + NSUInteger calendarUnitFlags; + + NSString *appName; + char *app; + size_t appLen; + + NSString *processID; + char *pid; + size_t pidLen; + + BOOL colorsEnabled; + NSMutableArray *colorProfilesArray; + NSMutableDictionary *colorProfilesDict; +} + ++ (DDTTYLogger *)sharedInstance; + +/* Inherited from the DDLogger protocol: + * + * Formatters may optionally be added to any logger. + * + * If no formatter is set, the logger simply logs the message as it is given in logMessage, + * or it may use its own built in formatting style. + * + * More information about formatters can be found here: + * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters + * + * The actual implementation of these methods is inherited from DDAbstractLogger. + +- (id )logFormatter; +- (void)setLogFormatter:(id )formatter; + +*/ + +/** + * Want to use different colors for different log levels? + * Enable this property. + * + * If you run the application via the Terminal (not Xcode), + * the logger will map colors to xterm-256color or xterm-color (if available). + * + * Xcode does NOT natively support colors in the Xcode debugging console. + * You'll need to install the XcodeColors plugin to see colors in the Xcode console. + * https://github.com/robbiehanson/XcodeColors + * + * The default value if NO. +**/ +@property (readwrite, assign) BOOL colorsEnabled; + +/** + * The default color set (foregroundColor, backgroundColor) is: + * + * - LOG_FLAG_ERROR = (red, nil) + * - LOG_FLAG_WARN = (orange, nil) + * + * You can customize the colors however you see fit. + * Please note that you are passing a flag, NOT a level. + * + * GOOD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_FLAG_INFO]; // <- Good :) + * BAD : [ttyLogger setForegroundColor:pink backgroundColor:nil forFlag:LOG_LEVEL_INFO]; // <- BAD! :( + * + * LOG_FLAG_INFO = 0...00100 + * LOG_LEVEL_INFO = 0...00111 <- Would match LOG_FLAG_INFO and LOG_FLAG_WARN and LOG_FLAG_ERROR + * + * If you run the application within Xcode, then the XcodeColors plugin is required. + * + * If you run the application from a shell, then DDTTYLogger will automatically map the given color to + * the closest available color. (xterm-256color or xterm-color which have 256 and 16 supported colors respectively.) + * + * This method invokes setForegroundColor:backgroundColor:forFlag:context: and passes the default context (0). +**/ +#if TARGET_OS_IPHONE +- (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forFlag:(int)mask; +#else +- (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forFlag:(int)mask; +#endif + +/** + * Just like setForegroundColor:backgroundColor:flag, but allows you to specify a particular logging context. + * + * A logging context is often used to identify log messages coming from a 3rd party framework, + * although logging context's can be used for many different functions. + * + * Logging context's are explained in further detail here: + * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomContext +**/ +#if TARGET_OS_IPHONE +- (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forFlag:(int)mask context:(int)ctxt; +#else +- (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forFlag:(int)mask context:(int)ctxt; +#endif + +/** + * Similar to the methods above, but allows you to map DDLogMessage->tag to a particular color profile. + * For example, you could do something like this: + * + * static NSString *const PurpleTag = @"PurpleTag"; + * + * #define DDLogPurple(frmt, ...) LOG_OBJC_TAG_MACRO(NO, 0, 0, 0, PurpleTag, frmt, ##__VA_ARGS__) + * + * And then in your applicationDidFinishLaunching, or wherever you configure Lumberjack: + * + * #if TARGET_OS_IPHONE + * UIColor *purple = [UIColor colorWithRed:(64/255.0) green:(0/255.0) blue:(128/255.0) alpha:1.0]; + * #else + * NSColor *purple = [NSColor colorWithCalibratedRed:(64/255.0) green:(0/255.0) blue:(128/255.0) alpha:1.0]; + * + * [[DDTTYLogger sharedInstance] setForegroundColor:purple backgroundColor:nil forTag:PurpleTag]; + * [DDLog addLogger:[DDTTYLogger sharedInstance]]; + * + * This would essentially give you a straight NSLog replacement that prints in purple: + * + * DDLogPurple(@"I'm a purple log message!"); +**/ +#if TARGET_OS_IPHONE +- (void)setForegroundColor:(UIColor *)txtColor backgroundColor:(UIColor *)bgColor forTag:(id )tag; +#else +- (void)setForegroundColor:(NSColor *)txtColor backgroundColor:(NSColor *)bgColor forTag:(id )tag; +#endif + +/** + * Clearing color profiles. +**/ +- (void)clearColorsForFlag:(int)mask; +- (void)clearColorsForFlag:(int)mask context:(int)context; +- (void)clearColorsForTag:(id )tag; +- (void)clearColorsForAllFlags; +- (void)clearColorsForAllTags; +- (void)clearAllColors; + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.m b/Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.m new file mode 100755 index 0000000..2906463 --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.m @@ -0,0 +1,1479 @@ +#import "DDTTYLogger.h" + +#import +#import + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" wiki. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted +**/ + +#if ! __has_feature(objc_arc) +#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + +// We probably shouldn't be using DDLog() statements within the DDLog implementation. +// But we still want to leave our log statements for any future debugging, +// and to allow other developers to trace the implementation (which is a great learning tool). +// +// So we use primitive logging macros around NSLog. +// We maintain the NS prefix on the macros to be explicit about the fact that we're using NSLog. + +#define LOG_LEVEL 2 + +#define NSLogError(frmt, ...) do{ if(LOG_LEVEL >= 1) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogWarn(frmt, ...) do{ if(LOG_LEVEL >= 2) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogInfo(frmt, ...) do{ if(LOG_LEVEL >= 3) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogVerbose(frmt, ...) do{ if(LOG_LEVEL >= 4) NSLog((frmt), ##__VA_ARGS__); } while(0) + +// Xcode does NOT natively support colors in the Xcode debugging console. +// You'll need to install the XcodeColors plugin to see colors in the Xcode console. +// https://github.com/robbiehanson/XcodeColors +// +// The following is documentation from the XcodeColors project: +// +// +// How to apply color formatting to your log statements: +// +// To set the foreground color: +// Insert the ESCAPE_SEQ into your string, followed by "fg124,12,255;" where r=124, g=12, b=255. +// +// To set the background color: +// Insert the ESCAPE_SEQ into your string, followed by "bg12,24,36;" where r=12, g=24, b=36. +// +// To reset the foreground color (to default value): +// Insert the ESCAPE_SEQ into your string, followed by "fg;" +// +// To reset the background color (to default value): +// Insert the ESCAPE_SEQ into your string, followed by "bg;" +// +// To reset the foreground and background color (to default values) in one operation: +// Insert the ESCAPE_SEQ into your string, followed by ";" + +#define XCODE_COLORS_ESCAPE_SEQ "\033[" + +#define XCODE_COLORS_RESET_FG XCODE_COLORS_ESCAPE_SEQ "fg;" // Clear any foreground color +#define XCODE_COLORS_RESET_BG XCODE_COLORS_ESCAPE_SEQ "bg;" // Clear any background color +#define XCODE_COLORS_RESET XCODE_COLORS_ESCAPE_SEQ ";" // Clear any foreground or background color + +// Some simple defines to make life easier on ourself + +#if TARGET_OS_IPHONE + #define MakeColor(r, g, b) [UIColor colorWithRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f] +#else + #define MakeColor(r, g, b) [NSColor colorWithCalibratedRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f] +#endif + +#if TARGET_OS_IPHONE + #define OSColor UIColor +#else + #define OSColor NSColor +#endif + +// If running in a shell, not all RGB colors will be supported. +// In this case we automatically map to the closest available color. +// In order to provide this mapping, we have a hard-coded set of the standard RGB values available in the shell. +// However, not every shell is the same, and Apple likes to think different even when it comes to shell colors. +// +// Map to standard Terminal.app colors (1), or +// map to standard xterm colors (0). + +#define MAP_TO_TERMINAL_APP_COLORS 1 + + +@interface DDTTYLoggerColorProfile : NSObject { +@public + int mask; + int context; + + uint8_t fg_r; + uint8_t fg_g; + uint8_t fg_b; + + uint8_t bg_r; + uint8_t bg_g; + uint8_t bg_b; + + NSUInteger fgCodeIndex; + NSString *fgCodeRaw; + + NSUInteger bgCodeIndex; + NSString *bgCodeRaw; + + char fgCode[24]; + size_t fgCodeLen; + + char bgCode[24]; + size_t bgCodeLen; + + char resetCode[8]; + size_t resetCodeLen; +} + +- (id)initWithForegroundColor:(OSColor *)fgColor backgroundColor:(OSColor *)bgColor flag:(int)mask context:(int)ctxt; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDTTYLogger + +static BOOL isaColorTTY; +static BOOL isaColor256TTY; +static BOOL isaXcodeColorTTY; + +static NSArray *codes_fg = nil; +static NSArray *codes_bg = nil; +static NSArray *colors = nil; + +static DDTTYLogger *sharedInstance; + +/** + * Initializes the colors array, as well as the codes_fg and codes_bg arrays, for 16 color mode. + * + * This method is used when the application is running from within a shell that only supports 16 color mode. + * This method is not invoked if the application is running within Xcode, or via normal UI app launch. +**/ ++ (void)initialize_colors_16 +{ + if (codes_fg || codes_bg || colors) return; + + NSMutableArray *m_codes_fg = [NSMutableArray arrayWithCapacity:16]; + NSMutableArray *m_codes_bg = [NSMutableArray arrayWithCapacity:16]; + NSMutableArray *m_colors = [NSMutableArray arrayWithCapacity:16]; + + // In a standard shell only 16 colors are supported. + // + // More information about ansi escape codes can be found online. + // http://en.wikipedia.org/wiki/ANSI_escape_code + + [m_codes_fg addObject:@"30m"]; // normal - black + [m_codes_fg addObject:@"31m"]; // normal - red + [m_codes_fg addObject:@"32m"]; // normal - green + [m_codes_fg addObject:@"33m"]; // normal - yellow + [m_codes_fg addObject:@"34m"]; // normal - blue + [m_codes_fg addObject:@"35m"]; // normal - magenta + [m_codes_fg addObject:@"36m"]; // normal - cyan + [m_codes_fg addObject:@"37m"]; // normal - gray + [m_codes_fg addObject:@"1;30m"]; // bright - darkgray + [m_codes_fg addObject:@"1;31m"]; // bright - red + [m_codes_fg addObject:@"1;32m"]; // bright - green + [m_codes_fg addObject:@"1;33m"]; // bright - yellow + [m_codes_fg addObject:@"1;34m"]; // bright - blue + [m_codes_fg addObject:@"1;35m"]; // bright - magenta + [m_codes_fg addObject:@"1;36m"]; // bright - cyan + [m_codes_fg addObject:@"1;37m"]; // bright - white + + [m_codes_bg addObject:@"40m"]; // normal - black + [m_codes_bg addObject:@"41m"]; // normal - red + [m_codes_bg addObject:@"42m"]; // normal - green + [m_codes_bg addObject:@"43m"]; // normal - yellow + [m_codes_bg addObject:@"44m"]; // normal - blue + [m_codes_bg addObject:@"45m"]; // normal - magenta + [m_codes_bg addObject:@"46m"]; // normal - cyan + [m_codes_bg addObject:@"47m"]; // normal - gray + [m_codes_bg addObject:@"1;40m"]; // bright - darkgray + [m_codes_bg addObject:@"1;41m"]; // bright - red + [m_codes_bg addObject:@"1;42m"]; // bright - green + [m_codes_bg addObject:@"1;43m"]; // bright - yellow + [m_codes_bg addObject:@"1;44m"]; // bright - blue + [m_codes_bg addObject:@"1;45m"]; // bright - magenta + [m_codes_bg addObject:@"1;46m"]; // bright - cyan + [m_codes_bg addObject:@"1;47m"]; // bright - white + +#if MAP_TO_TERMINAL_APP_COLORS + + // Standard Terminal.app colors: + // + // These are the default colors used by Apple's Terminal.app. + + [m_colors addObject:MakeColor( 0, 0, 0)]; // normal - black + [m_colors addObject:MakeColor(194, 54, 33)]; // normal - red + [m_colors addObject:MakeColor( 37, 188, 36)]; // normal - green + [m_colors addObject:MakeColor(173, 173, 39)]; // normal - yellow + [m_colors addObject:MakeColor( 73, 46, 225)]; // normal - blue + [m_colors addObject:MakeColor(211, 56, 211)]; // normal - magenta + [m_colors addObject:MakeColor( 51, 187, 200)]; // normal - cyan + [m_colors addObject:MakeColor(203, 204, 205)]; // normal - gray + [m_colors addObject:MakeColor(129, 131, 131)]; // bright - darkgray + [m_colors addObject:MakeColor(252, 57, 31)]; // bright - red + [m_colors addObject:MakeColor( 49, 231, 34)]; // bright - green + [m_colors addObject:MakeColor(234, 236, 35)]; // bright - yellow + [m_colors addObject:MakeColor( 88, 51, 255)]; // bright - blue + [m_colors addObject:MakeColor(249, 53, 248)]; // bright - magenta + [m_colors addObject:MakeColor( 20, 240, 240)]; // bright - cyan + [m_colors addObject:MakeColor(233, 235, 235)]; // bright - white + +#else + + // Standard xterm colors: + // + // These are the default colors used by most xterm shells. + + [m_colors addObject:MakeColor( 0, 0, 0)]; // normal - black + [m_colors addObject:MakeColor(205, 0, 0)]; // normal - red + [m_colors addObject:MakeColor( 0, 205, 0)]; // normal - green + [m_colors addObject:MakeColor(205, 205, 0)]; // normal - yellow + [m_colors addObject:MakeColor( 0, 0, 238)]; // normal - blue + [m_colors addObject:MakeColor(205, 0, 205)]; // normal - magenta + [m_colors addObject:MakeColor( 0, 205, 205)]; // normal - cyan + [m_colors addObject:MakeColor(229, 229, 229)]; // normal - gray + [m_colors addObject:MakeColor(127, 127, 127)]; // bright - darkgray + [m_colors addObject:MakeColor(255, 0, 0)]; // bright - red + [m_colors addObject:MakeColor( 0, 255, 0)]; // bright - green + [m_colors addObject:MakeColor(255, 255, 0)]; // bright - yellow + [m_colors addObject:MakeColor( 92, 92, 255)]; // bright - blue + [m_colors addObject:MakeColor(255, 0, 255)]; // bright - magenta + [m_colors addObject:MakeColor( 0, 255, 255)]; // bright - cyan + [m_colors addObject:MakeColor(255, 255, 255)]; // bright - white + +#endif + + codes_fg = [m_codes_fg copy]; + codes_bg = [m_codes_bg copy]; + colors = [m_colors copy]; + + NSAssert([codes_fg count] == [codes_bg count], @"Invalid colors/codes array(s)"); + NSAssert([codes_fg count] == [colors count], @"Invalid colors/codes array(s)"); +} + +/** + * Initializes the colors array, as well as the codes_fg and codes_bg arrays, for 256 color mode. + * + * This method is used when the application is running from within a shell that supports 256 color mode. + * This method is not invoked if the application is running within Xcode, or via normal UI app launch. +**/ ++ (void)initialize_colors_256 +{ + if (codes_fg || codes_bg || colors) return; + + NSMutableArray *m_codes_fg = [NSMutableArray arrayWithCapacity:(256-16)]; + NSMutableArray *m_codes_bg = [NSMutableArray arrayWithCapacity:(256-16)]; + NSMutableArray *m_colors = [NSMutableArray arrayWithCapacity:(256-16)]; + + #if MAP_TO_TERMINAL_APP_COLORS + + // Standard Terminal.app colors: + // + // These are the colors the Terminal.app uses in xterm-256color mode. + // In this mode, the terminal supports 256 different colors, specified by 256 color codes. + // + // The first 16 color codes map to the original 16 color codes supported by the earlier xterm-color mode. + // These are actually configurable, and thus we ignore them for the purposes of mapping, + // as we can't rely on them being constant. They are largely duplicated anyway. + // + // The next 216 color codes are designed to run the spectrum, with several shades of every color. + // While the color codes are standardized, the actual RGB values for each color code is not. + // Apple's Terminal.app uses different RGB values from that of a standard xterm. + // Apple's choices in colors are designed to be a little nicer on the eyes. + // + // The last 24 color codes represent a grayscale. + // + // Unfortunately, unlike the standard xterm color chart, + // Apple's RGB values cannot be calculated using a simple formula (at least not that I know of). + // Also, I don't know of any ways to programmatically query the shell for the RGB values. + // So this big giant color chart had to be made by hand. + // + // More information about ansi escape codes can be found online. + // http://en.wikipedia.org/wiki/ANSI_escape_code + + // Colors + + [m_colors addObject:MakeColor( 47, 49, 49)]; + [m_colors addObject:MakeColor( 60, 42, 144)]; + [m_colors addObject:MakeColor( 66, 44, 183)]; + [m_colors addObject:MakeColor( 73, 46, 222)]; + [m_colors addObject:MakeColor( 81, 50, 253)]; + [m_colors addObject:MakeColor( 88, 51, 255)]; + + [m_colors addObject:MakeColor( 42, 128, 37)]; + [m_colors addObject:MakeColor( 42, 127, 128)]; + [m_colors addObject:MakeColor( 44, 126, 169)]; + [m_colors addObject:MakeColor( 56, 125, 209)]; + [m_colors addObject:MakeColor( 59, 124, 245)]; + [m_colors addObject:MakeColor( 66, 123, 255)]; + + [m_colors addObject:MakeColor( 51, 163, 41)]; + [m_colors addObject:MakeColor( 39, 162, 121)]; + [m_colors addObject:MakeColor( 42, 161, 162)]; + [m_colors addObject:MakeColor( 53, 160, 202)]; + [m_colors addObject:MakeColor( 45, 159, 240)]; + [m_colors addObject:MakeColor( 58, 158, 255)]; + + [m_colors addObject:MakeColor( 31, 196, 37)]; + [m_colors addObject:MakeColor( 48, 196, 115)]; + [m_colors addObject:MakeColor( 39, 195, 155)]; + [m_colors addObject:MakeColor( 49, 195, 195)]; + [m_colors addObject:MakeColor( 32, 194, 235)]; + [m_colors addObject:MakeColor( 53, 193, 255)]; + + [m_colors addObject:MakeColor( 50, 229, 35)]; + [m_colors addObject:MakeColor( 40, 229, 109)]; + [m_colors addObject:MakeColor( 27, 229, 149)]; + [m_colors addObject:MakeColor( 49, 228, 189)]; + [m_colors addObject:MakeColor( 33, 228, 228)]; + [m_colors addObject:MakeColor( 53, 227, 255)]; + + [m_colors addObject:MakeColor( 27, 254, 30)]; + [m_colors addObject:MakeColor( 30, 254, 103)]; + [m_colors addObject:MakeColor( 45, 254, 143)]; + [m_colors addObject:MakeColor( 38, 253, 182)]; + [m_colors addObject:MakeColor( 38, 253, 222)]; + [m_colors addObject:MakeColor( 42, 253, 252)]; + + [m_colors addObject:MakeColor(140, 48, 40)]; + [m_colors addObject:MakeColor(136, 51, 136)]; + [m_colors addObject:MakeColor(135, 52, 177)]; + [m_colors addObject:MakeColor(134, 52, 217)]; + [m_colors addObject:MakeColor(135, 56, 248)]; + [m_colors addObject:MakeColor(134, 53, 255)]; + + [m_colors addObject:MakeColor(125, 125, 38)]; + [m_colors addObject:MakeColor(124, 125, 125)]; + [m_colors addObject:MakeColor(122, 124, 166)]; + [m_colors addObject:MakeColor(123, 124, 207)]; + [m_colors addObject:MakeColor(123, 122, 247)]; + [m_colors addObject:MakeColor(124, 121, 255)]; + + [m_colors addObject:MakeColor(119, 160, 35)]; + [m_colors addObject:MakeColor(117, 160, 120)]; + [m_colors addObject:MakeColor(117, 160, 160)]; + [m_colors addObject:MakeColor(115, 159, 201)]; + [m_colors addObject:MakeColor(116, 158, 240)]; + [m_colors addObject:MakeColor(117, 157, 255)]; + + [m_colors addObject:MakeColor(113, 195, 39)]; + [m_colors addObject:MakeColor(110, 194, 114)]; + [m_colors addObject:MakeColor(111, 194, 154)]; + [m_colors addObject:MakeColor(108, 194, 194)]; + [m_colors addObject:MakeColor(109, 193, 234)]; + [m_colors addObject:MakeColor(108, 192, 255)]; + + [m_colors addObject:MakeColor(105, 228, 30)]; + [m_colors addObject:MakeColor(103, 228, 109)]; + [m_colors addObject:MakeColor(105, 228, 148)]; + [m_colors addObject:MakeColor(100, 227, 188)]; + [m_colors addObject:MakeColor( 99, 227, 227)]; + [m_colors addObject:MakeColor( 99, 226, 253)]; + + [m_colors addObject:MakeColor( 92, 253, 34)]; + [m_colors addObject:MakeColor( 96, 253, 103)]; + [m_colors addObject:MakeColor( 97, 253, 142)]; + [m_colors addObject:MakeColor( 88, 253, 182)]; + [m_colors addObject:MakeColor( 93, 253, 221)]; + [m_colors addObject:MakeColor( 88, 254, 251)]; + + [m_colors addObject:MakeColor(177, 53, 34)]; + [m_colors addObject:MakeColor(174, 54, 131)]; + [m_colors addObject:MakeColor(172, 55, 172)]; + [m_colors addObject:MakeColor(171, 57, 213)]; + [m_colors addObject:MakeColor(170, 55, 249)]; + [m_colors addObject:MakeColor(170, 57, 255)]; + + [m_colors addObject:MakeColor(165, 123, 37)]; + [m_colors addObject:MakeColor(163, 123, 123)]; + [m_colors addObject:MakeColor(162, 123, 164)]; + [m_colors addObject:MakeColor(161, 122, 205)]; + [m_colors addObject:MakeColor(161, 121, 241)]; + [m_colors addObject:MakeColor(161, 121, 255)]; + + [m_colors addObject:MakeColor(158, 159, 33)]; + [m_colors addObject:MakeColor(157, 158, 118)]; + [m_colors addObject:MakeColor(157, 158, 159)]; + [m_colors addObject:MakeColor(155, 157, 199)]; + [m_colors addObject:MakeColor(155, 157, 239)]; + [m_colors addObject:MakeColor(154, 156, 255)]; + + [m_colors addObject:MakeColor(152, 193, 40)]; + [m_colors addObject:MakeColor(151, 193, 113)]; + [m_colors addObject:MakeColor(150, 193, 153)]; + [m_colors addObject:MakeColor(150, 192, 193)]; + [m_colors addObject:MakeColor(148, 192, 232)]; + [m_colors addObject:MakeColor(149, 191, 253)]; + + [m_colors addObject:MakeColor(146, 227, 28)]; + [m_colors addObject:MakeColor(144, 227, 108)]; + [m_colors addObject:MakeColor(144, 227, 147)]; + [m_colors addObject:MakeColor(144, 227, 187)]; + [m_colors addObject:MakeColor(142, 226, 227)]; + [m_colors addObject:MakeColor(142, 225, 252)]; + + [m_colors addObject:MakeColor(138, 253, 36)]; + [m_colors addObject:MakeColor(137, 253, 102)]; + [m_colors addObject:MakeColor(136, 253, 141)]; + [m_colors addObject:MakeColor(138, 254, 181)]; + [m_colors addObject:MakeColor(135, 255, 220)]; + [m_colors addObject:MakeColor(133, 255, 250)]; + + [m_colors addObject:MakeColor(214, 57, 30)]; + [m_colors addObject:MakeColor(211, 59, 126)]; + [m_colors addObject:MakeColor(209, 57, 168)]; + [m_colors addObject:MakeColor(208, 55, 208)]; + [m_colors addObject:MakeColor(207, 58, 247)]; + [m_colors addObject:MakeColor(206, 61, 255)]; + + [m_colors addObject:MakeColor(204, 121, 32)]; + [m_colors addObject:MakeColor(202, 121, 121)]; + [m_colors addObject:MakeColor(201, 121, 161)]; + [m_colors addObject:MakeColor(200, 120, 202)]; + [m_colors addObject:MakeColor(200, 120, 241)]; + [m_colors addObject:MakeColor(198, 119, 255)]; + + [m_colors addObject:MakeColor(198, 157, 37)]; + [m_colors addObject:MakeColor(196, 157, 116)]; + [m_colors addObject:MakeColor(195, 156, 157)]; + [m_colors addObject:MakeColor(195, 156, 197)]; + [m_colors addObject:MakeColor(194, 155, 236)]; + [m_colors addObject:MakeColor(193, 155, 255)]; + + [m_colors addObject:MakeColor(191, 192, 36)]; + [m_colors addObject:MakeColor(190, 191, 112)]; + [m_colors addObject:MakeColor(189, 191, 152)]; + [m_colors addObject:MakeColor(189, 191, 191)]; + [m_colors addObject:MakeColor(188, 190, 230)]; + [m_colors addObject:MakeColor(187, 190, 253)]; + + [m_colors addObject:MakeColor(185, 226, 28)]; + [m_colors addObject:MakeColor(184, 226, 106)]; + [m_colors addObject:MakeColor(183, 225, 146)]; + [m_colors addObject:MakeColor(183, 225, 186)]; + [m_colors addObject:MakeColor(182, 225, 225)]; + [m_colors addObject:MakeColor(181, 224, 252)]; + + [m_colors addObject:MakeColor(178, 255, 35)]; + [m_colors addObject:MakeColor(178, 255, 101)]; + [m_colors addObject:MakeColor(177, 254, 141)]; + [m_colors addObject:MakeColor(176, 254, 180)]; + [m_colors addObject:MakeColor(176, 254, 220)]; + [m_colors addObject:MakeColor(175, 253, 249)]; + + [m_colors addObject:MakeColor(247, 56, 30)]; + [m_colors addObject:MakeColor(245, 57, 122)]; + [m_colors addObject:MakeColor(243, 59, 163)]; + [m_colors addObject:MakeColor(244, 60, 204)]; + [m_colors addObject:MakeColor(242, 59, 241)]; + [m_colors addObject:MakeColor(240, 55, 255)]; + + [m_colors addObject:MakeColor(241, 119, 36)]; + [m_colors addObject:MakeColor(240, 120, 118)]; + [m_colors addObject:MakeColor(238, 119, 158)]; + [m_colors addObject:MakeColor(237, 119, 199)]; + [m_colors addObject:MakeColor(237, 118, 238)]; + [m_colors addObject:MakeColor(236, 118, 255)]; + + [m_colors addObject:MakeColor(235, 154, 36)]; + [m_colors addObject:MakeColor(235, 154, 114)]; + [m_colors addObject:MakeColor(234, 154, 154)]; + [m_colors addObject:MakeColor(232, 154, 194)]; + [m_colors addObject:MakeColor(232, 153, 234)]; + [m_colors addObject:MakeColor(232, 153, 255)]; + + [m_colors addObject:MakeColor(230, 190, 30)]; + [m_colors addObject:MakeColor(229, 189, 110)]; + [m_colors addObject:MakeColor(228, 189, 150)]; + [m_colors addObject:MakeColor(227, 189, 190)]; + [m_colors addObject:MakeColor(227, 189, 229)]; + [m_colors addObject:MakeColor(226, 188, 255)]; + + [m_colors addObject:MakeColor(224, 224, 35)]; + [m_colors addObject:MakeColor(223, 224, 105)]; + [m_colors addObject:MakeColor(222, 224, 144)]; + [m_colors addObject:MakeColor(222, 223, 184)]; + [m_colors addObject:MakeColor(222, 223, 224)]; + [m_colors addObject:MakeColor(220, 223, 253)]; + + [m_colors addObject:MakeColor(217, 253, 28)]; + [m_colors addObject:MakeColor(217, 253, 99)]; + [m_colors addObject:MakeColor(216, 252, 139)]; + [m_colors addObject:MakeColor(216, 252, 179)]; + [m_colors addObject:MakeColor(215, 252, 218)]; + [m_colors addObject:MakeColor(215, 251, 250)]; + + [m_colors addObject:MakeColor(255, 61, 30)]; + [m_colors addObject:MakeColor(255, 60, 118)]; + [m_colors addObject:MakeColor(255, 58, 159)]; + [m_colors addObject:MakeColor(255, 56, 199)]; + [m_colors addObject:MakeColor(255, 55, 238)]; + [m_colors addObject:MakeColor(255, 59, 255)]; + + [m_colors addObject:MakeColor(255, 117, 29)]; + [m_colors addObject:MakeColor(255, 117, 115)]; + [m_colors addObject:MakeColor(255, 117, 155)]; + [m_colors addObject:MakeColor(255, 117, 195)]; + [m_colors addObject:MakeColor(255, 116, 235)]; + [m_colors addObject:MakeColor(254, 116, 255)]; + + [m_colors addObject:MakeColor(255, 152, 27)]; + [m_colors addObject:MakeColor(255, 152, 111)]; + [m_colors addObject:MakeColor(254, 152, 152)]; + [m_colors addObject:MakeColor(255, 152, 192)]; + [m_colors addObject:MakeColor(254, 151, 231)]; + [m_colors addObject:MakeColor(253, 151, 253)]; + + [m_colors addObject:MakeColor(255, 187, 33)]; + [m_colors addObject:MakeColor(253, 187, 107)]; + [m_colors addObject:MakeColor(252, 187, 148)]; + [m_colors addObject:MakeColor(253, 187, 187)]; + [m_colors addObject:MakeColor(254, 187, 227)]; + [m_colors addObject:MakeColor(252, 186, 252)]; + + [m_colors addObject:MakeColor(252, 222, 34)]; + [m_colors addObject:MakeColor(251, 222, 103)]; + [m_colors addObject:MakeColor(251, 222, 143)]; + [m_colors addObject:MakeColor(250, 222, 182)]; + [m_colors addObject:MakeColor(251, 221, 222)]; + [m_colors addObject:MakeColor(252, 221, 252)]; + + [m_colors addObject:MakeColor(251, 252, 15)]; + [m_colors addObject:MakeColor(251, 252, 97)]; + [m_colors addObject:MakeColor(249, 252, 137)]; + [m_colors addObject:MakeColor(247, 252, 177)]; + [m_colors addObject:MakeColor(247, 253, 217)]; + [m_colors addObject:MakeColor(254, 255, 255)]; + + // Grayscale + + [m_colors addObject:MakeColor( 52, 53, 53)]; + [m_colors addObject:MakeColor( 57, 58, 59)]; + [m_colors addObject:MakeColor( 66, 67, 67)]; + [m_colors addObject:MakeColor( 75, 76, 76)]; + [m_colors addObject:MakeColor( 83, 85, 85)]; + [m_colors addObject:MakeColor( 92, 93, 94)]; + + [m_colors addObject:MakeColor(101, 102, 102)]; + [m_colors addObject:MakeColor(109, 111, 111)]; + [m_colors addObject:MakeColor(118, 119, 119)]; + [m_colors addObject:MakeColor(126, 127, 128)]; + [m_colors addObject:MakeColor(134, 136, 136)]; + [m_colors addObject:MakeColor(143, 144, 145)]; + + [m_colors addObject:MakeColor(151, 152, 153)]; + [m_colors addObject:MakeColor(159, 161, 161)]; + [m_colors addObject:MakeColor(167, 169, 169)]; + [m_colors addObject:MakeColor(176, 177, 177)]; + [m_colors addObject:MakeColor(184, 185, 186)]; + [m_colors addObject:MakeColor(192, 193, 194)]; + + [m_colors addObject:MakeColor(200, 201, 202)]; + [m_colors addObject:MakeColor(208, 209, 210)]; + [m_colors addObject:MakeColor(216, 218, 218)]; + [m_colors addObject:MakeColor(224, 226, 226)]; + [m_colors addObject:MakeColor(232, 234, 234)]; + [m_colors addObject:MakeColor(240, 242, 242)]; + + // Color codes + + int index = 16; + + while (index < 256) + { + [m_codes_fg addObject:[NSString stringWithFormat:@"38;5;%dm", index]]; + [m_codes_bg addObject:[NSString stringWithFormat:@"48;5;%dm", index]]; + + index++; + } + + #else + + // Standard xterm colors: + // + // These are the colors xterm shells use in xterm-256color mode. + // In this mode, the shell supports 256 different colors, specified by 256 color codes. + // + // The first 16 color codes map to the original 16 color codes supported by the earlier xterm-color mode. + // These are generally configurable, and thus we ignore them for the purposes of mapping, + // as we can't rely on them being constant. They are largely duplicated anyway. + // + // The next 216 color codes are designed to run the spectrum, with several shades of every color. + // The last 24 color codes represent a grayscale. + // + // While the color codes are standardized, the actual RGB values for each color code is not. + // However most standard xterms follow a well known color chart, + // which can easily be calculated using the simple formula below. + // + // More information about ansi escape codes can be found online. + // http://en.wikipedia.org/wiki/ANSI_escape_code + + int index = 16; + + int r; // red + int g; // green + int b; // blue + + int ri; // r increment + int gi; // g increment + int bi; // b increment + + // Calculate xterm colors (using standard algorithm) + + int r = 0; + int g = 0; + int b = 0; + + for (ri = 0; ri < 6; ri++) + { + r = (ri == 0) ? 0 : 95 + (40 * (ri - 1)); + + for (gi = 0; gi < 6; gi++) + { + g = (gi == 0) ? 0 : 95 + (40 * (gi - 1)); + + for (bi = 0; bi < 6; bi++) + { + b = (bi == 0) ? 0 : 95 + (40 * (bi - 1)); + + [m_codes_fg addObject:[NSString stringWithFormat:@"38;5;%dm", index]]; + [m_codes_bg addObject:[NSString stringWithFormat:@"48;5;%dm", index]]; + [m_colors addObject:MakeColor(r, g, b)]; + + index++; + } + } + } + + // Calculate xterm grayscale (using standard algorithm) + + r = 8; + g = 8; + b = 8; + + while (index < 256) + { + [m_codes_fg addObject:[NSString stringWithFormat:@"38;5;%dm", index]]; + [m_codes_bg addObject:[NSString stringWithFormat:@"48;5;%dm", index]]; + [m_colors addObject:MakeColor(r, g, b)]; + + r += 10; + g += 10; + b += 10; + + index++; + } + + #endif + + codes_fg = [m_codes_fg copy]; + codes_bg = [m_codes_bg copy]; + colors = [m_colors copy]; + + NSAssert([codes_fg count] == [codes_bg count], @"Invalid colors/codes array(s)"); + NSAssert([codes_fg count] == [colors count], @"Invalid colors/codes array(s)"); +} + ++ (void)getRed:(CGFloat *)rPtr green:(CGFloat *)gPtr blue:(CGFloat *)bPtr fromColor:(OSColor *)color +{ + #if TARGET_OS_IPHONE + + // iOS + + if ([color respondsToSelector:@selector(getRed:green:blue:alpha:)]) + { + [color getRed:rPtr green:gPtr blue:bPtr alpha:NULL]; + } + else + { + // The method getRed:green:blue:alpha: was only available starting iOS 5. + // So in iOS 4 and earlier, we have to jump through hoops. + + CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); + + unsigned char pixel[4]; + CGContextRef context = CGBitmapContextCreate(&pixel, 1, 1, 8, 4, rgbColorSpace, kCGImageAlphaNoneSkipLast); + + CGContextSetFillColorWithColor(context, [color CGColor]); + CGContextFillRect(context, CGRectMake(0, 0, 1, 1)); + + if (rPtr) { *rPtr = pixel[0] / 255.0f; } + if (gPtr) { *gPtr = pixel[1] / 255.0f; } + if (bPtr) { *bPtr = pixel[2] / 255.0f; } + + CGContextRelease(context); + CGColorSpaceRelease(rgbColorSpace); + } + + #else + + // Mac OS X + + [color getRed:rPtr green:gPtr blue:bPtr alpha:NULL]; + + #endif +} + +/** + * Maps the given color to the closest available color supported by the shell. + * The shell may support 256 colors, or only 16. + * + * This method loops through the known supported color set, and calculates the closest color. + * The array index of that color, within the colors array, is then returned. + * This array index may also be used as the index within the codes_fg and codes_bg arrays. +**/ ++ (NSUInteger)codeIndexForColor:(OSColor *)inColor +{ + CGFloat inR, inG, inB; + [self getRed:&inR green:&inG blue:&inB fromColor:inColor]; + + NSUInteger bestIndex = 0; + CGFloat lowestDistance = 100.0f; + + NSUInteger i = 0; + for (OSColor *color in colors) + { + // Calculate Euclidean distance (lower value means closer to given color) + + CGFloat r, g, b; + [self getRed:&r green:&g blue:&b fromColor:color]; + + #if CGFLOAT_IS_DOUBLE + CGFloat distance = sqrt(pow(r-inR, 2.0) + pow(g-inG, 2.0) + pow(b-inB, 2.0)); + #else + CGFloat distance = sqrtf(powf(r-inR, 2.0f) + powf(g-inG, 2.0f) + powf(b-inB, 2.0f)); + #endif + + NSLogVerbose(@"DDTTYLogger: %3lu : %.3f,%.3f,%.3f & %.3f,%.3f,%.3f = %.6f", + (unsigned long)i, inR, inG, inB, r, g, b, distance); + + if (distance < lowestDistance) + { + bestIndex = i; + lowestDistance = distance; + + NSLogVerbose(@"DDTTYLogger: New best index = %lu", (unsigned long)bestIndex); + } + + i++; + } + + return bestIndex; +} + +/** + * The runtime sends initialize to each class in a program exactly one time just before the class, + * or any class that inherits from it, is sent its first message from within the program. (Thus the + * method may never be invoked if the class is not used.) The runtime sends the initialize message to + * classes in a thread-safe manner. Superclasses receive this message before their subclasses. + * + * This method may also be called directly (assumably by accident), hence the safety mechanism. +**/ ++ (void)initialize +{ + static BOOL initialized = NO; + if (!initialized) + { + initialized = YES; + + char *term = getenv("TERM"); + if (term) + { + if (strcasestr(term, "color") != NULL) + { + isaColorTTY = YES; + isaColor256TTY = (strcasestr(term, "256") != NULL); + + if (isaColor256TTY) + [self initialize_colors_256]; + else + [self initialize_colors_16]; + } + } + else + { + // Xcode does NOT natively support colors in the Xcode debugging console. + // You'll need to install the XcodeColors plugin to see colors in the Xcode console. + // + // PS - Please read the header file before diving into the source code. + + char *xcode_colors = getenv("XcodeColors"); + if (xcode_colors && (strcmp(xcode_colors, "YES") == 0)) + { + isaXcodeColorTTY = YES; + } + } + + NSLogInfo(@"DDTTYLogger: isaColorTTY = %@", (isaColorTTY ? @"YES" : @"NO")); + NSLogInfo(@"DDTTYLogger: isaColor256TTY: %@", (isaColor256TTY ? @"YES" : @"NO")); + NSLogInfo(@"DDTTYLogger: isaXcodeColorTTY: %@", (isaXcodeColorTTY ? @"YES" : @"NO")); + + sharedInstance = [[DDTTYLogger alloc] init]; + } +} + ++ (DDTTYLogger *)sharedInstance +{ + return sharedInstance; +} + +- (id)init +{ + if (sharedInstance != nil) + { + return nil; + } + + if ((self = [super init])) + { + calendar = [NSCalendar autoupdatingCurrentCalendar]; + + calendarUnitFlags = 0; + calendarUnitFlags |= NSYearCalendarUnit; + calendarUnitFlags |= NSMonthCalendarUnit; + calendarUnitFlags |= NSDayCalendarUnit; + calendarUnitFlags |= NSHourCalendarUnit; + calendarUnitFlags |= NSMinuteCalendarUnit; + calendarUnitFlags |= NSSecondCalendarUnit; + + // Initialze 'app' variable (char *) + + appName = [[NSProcessInfo processInfo] processName]; + + appLen = [appName lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + app = (char *)malloc(appLen + 1); + + [appName getCString:app maxLength:(appLen+1) encoding:NSUTF8StringEncoding]; + + // Initialize 'pid' variable (char *) + + processID = [NSString stringWithFormat:@"%i", (int)getpid()]; + + pidLen = [processID lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + pid = (char *)malloc(pidLen + 1); + + [processID getCString:pid maxLength:(pidLen+1) encoding:NSUTF8StringEncoding]; + + // Initialize color stuff + + colorsEnabled = NO; + colorProfilesArray = [[NSMutableArray alloc] initWithCapacity:8]; + colorProfilesDict = [[NSMutableDictionary alloc] initWithCapacity:8]; + } + return self; +} + +- (void)loadDefaultColorProfiles +{ + [self setForegroundColor:MakeColor(214, 57, 30) backgroundColor:nil forFlag:LOG_FLAG_ERROR]; + [self setForegroundColor:MakeColor(204, 121, 32) backgroundColor:nil forFlag:LOG_FLAG_WARN]; +} + +- (BOOL)colorsEnabled +{ + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block BOOL result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(loggerQueue, ^{ + result = colorsEnabled; + }); + }); + + return result; +} + +- (void)setColorsEnabled:(BOOL)newColorsEnabled +{ + dispatch_block_t block = ^{ @autoreleasepool { + + colorsEnabled = newColorsEnabled; + + if ([colorProfilesArray count] == 0) { + [self loadDefaultColorProfiles]; + } + }}; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); +} + +- (void)setForegroundColor:(OSColor *)txtColor backgroundColor:(OSColor *)bgColor forFlag:(int)mask +{ + [self setForegroundColor:txtColor backgroundColor:bgColor forFlag:mask context:0]; +} + +- (void)setForegroundColor:(OSColor *)txtColor backgroundColor:(OSColor *)bgColor forFlag:(int)mask context:(int)ctxt +{ + dispatch_block_t block = ^{ @autoreleasepool { + + DDTTYLoggerColorProfile *newColorProfile = + [[DDTTYLoggerColorProfile alloc] initWithForegroundColor:txtColor + backgroundColor:bgColor + flag:mask + context:ctxt]; + + NSLogInfo(@"DDTTYLogger: newColorProfile: %@", newColorProfile); + + NSUInteger i = 0; + for (DDTTYLoggerColorProfile *colorProfile in colorProfilesArray) + { + if ((colorProfile->mask == mask) && (colorProfile->context == ctxt)) + { + break; + } + + i++; + } + + if (i < [colorProfilesArray count]) + [colorProfilesArray replaceObjectAtIndex:i withObject:newColorProfile]; + else + [colorProfilesArray addObject:newColorProfile]; + }}; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) + { + block(); + } + else + { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); + } +} + +- (void)setForegroundColor:(OSColor *)txtColor backgroundColor:(OSColor *)bgColor forTag:(id )tag +{ + NSAssert([(id )tag conformsToProtocol:@protocol(NSCopying)], @"Invalid tag"); + + dispatch_block_t block = ^{ @autoreleasepool { + + DDTTYLoggerColorProfile *newColorProfile = + [[DDTTYLoggerColorProfile alloc] initWithForegroundColor:txtColor + backgroundColor:bgColor + flag:0 + context:0]; + + NSLogInfo(@"DDTTYLogger: newColorProfile: %@", newColorProfile); + + [colorProfilesDict setObject:newColorProfile forKey:tag]; + }}; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) + { + block(); + } + else + { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); + } +} + +- (void)clearColorsForFlag:(int)mask +{ + [self clearColorsForFlag:mask context:0]; +} + +- (void)clearColorsForFlag:(int)mask context:(int)context +{ + dispatch_block_t block = ^{ @autoreleasepool { + + NSUInteger i = 0; + for (DDTTYLoggerColorProfile *colorProfile in colorProfilesArray) + { + if ((colorProfile->mask == mask) && (colorProfile->context == context)) + { + break; + } + + i++; + } + + if (i < [colorProfilesArray count]) + { + [colorProfilesArray removeObjectAtIndex:i]; + } + }}; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) + { + block(); + } + else + { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); + } +} + +- (void)clearColorsForTag:(id )tag +{ + NSAssert([(id )tag conformsToProtocol:@protocol(NSCopying)], @"Invalid tag"); + + dispatch_block_t block = ^{ @autoreleasepool { + + [colorProfilesDict removeObjectForKey:tag]; + }}; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) + { + block(); + } + else + { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); + } +} + +- (void)clearColorsForAllFlags +{ + dispatch_block_t block = ^{ @autoreleasepool { + + [colorProfilesArray removeAllObjects]; + }}; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) + { + block(); + } + else + { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); + } +} + +- (void)clearColorsForAllTags +{ + dispatch_block_t block = ^{ @autoreleasepool { + + [colorProfilesDict removeAllObjects]; + }}; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) + { + block(); + } + else + { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); + } +} + +- (void)clearAllColors +{ + dispatch_block_t block = ^{ @autoreleasepool { + + [colorProfilesArray removeAllObjects]; + [colorProfilesDict removeAllObjects]; + }}; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) + { + block(); + } + else + { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(loggerQueue, block); + }); + } +} + +- (void)logMessage:(DDLogMessage *)logMessage +{ + NSString *logMsg = logMessage->logMsg; + BOOL isFormatted = NO; + + if (formatter) + { + logMsg = [formatter formatLogMessage:logMessage]; + isFormatted = logMsg != logMessage->logMsg; + } + + if (logMsg) + { + // Search for a color profile associated with the log message + + DDTTYLoggerColorProfile *colorProfile = nil; + + if (colorsEnabled) + { + if (logMessage->tag) + { + colorProfile = [colorProfilesDict objectForKey:logMessage->tag]; + } + if (colorProfile == nil) + { + for (DDTTYLoggerColorProfile *cp in colorProfilesArray) + { + if ((logMessage->logFlag & cp->mask) && (logMessage->logContext == cp->context)) + { + colorProfile = cp; + break; + } + } + } + } + + // Convert log message to C string. + // + // We use the stack instead of the heap for speed if possible. + // But we're extra cautious to avoid a stack overflow. + + NSUInteger msgLen = [logMsg lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + const BOOL useStack = msgLen < (1024 * 4); + + char msgStack[useStack ? (msgLen + 1) : 1]; // Analyzer doesn't like zero-size array, hence the 1 + char *msg = useStack ? msgStack : (char *)malloc(msgLen + 1); + + [logMsg getCString:msg maxLength:(msgLen + 1) encoding:NSUTF8StringEncoding]; + + // Write the log message to STDERR + + if (isFormatted) + { + // The log message has already been formatted. + + struct iovec v[5]; + + if (colorProfile) + { + v[0].iov_base = colorProfile->fgCode; + v[0].iov_len = colorProfile->fgCodeLen; + + v[1].iov_base = colorProfile->bgCode; + v[1].iov_len = colorProfile->bgCodeLen; + + v[4].iov_base = colorProfile->resetCode; + v[4].iov_len = colorProfile->resetCodeLen; + } + else + { + v[0].iov_base = ""; + v[0].iov_len = 0; + + v[1].iov_base = ""; + v[1].iov_len = 0; + + v[4].iov_base = ""; + v[4].iov_len = 0; + } + + v[2].iov_base = (char *)msg; + v[2].iov_len = msgLen; + + v[3].iov_base = "\n"; + v[3].iov_len = (msg[msgLen] == '\n') ? 0 : 1; + + writev(STDERR_FILENO, v, 5); + } + else + { + // The log message is unformatted, so apply standard NSLog style formatting. + + int len; + + // Calculate timestamp. + // The technique below is faster than using NSDateFormatter. + + NSDateComponents *components = [calendar components:calendarUnitFlags fromDate:logMessage->timestamp]; + + NSTimeInterval epoch = [logMessage->timestamp timeIntervalSinceReferenceDate]; + int milliseconds = (int)((epoch - floor(epoch)) * 1000); + + char ts[24]; + len = snprintf(ts, 24, "%04ld-%02ld-%02ld %02ld:%02ld:%02ld:%03d", // yyyy-MM-dd HH:mm:ss:SSS + (long)components.year, + (long)components.month, + (long)components.day, + (long)components.hour, + (long)components.minute, + (long)components.second, milliseconds); + + size_t tsLen = MIN(24-1, len); + + // Calculate thread ID + // + // How many characters do we need for the thread id? + // logMessage->machThreadID is of type mach_port_t, which is an unsigned int. + // + // 1 hex char = 4 bits + // 8 hex chars for 32 bit, plus ending '\0' = 9 + + char tid[9]; + len = snprintf(tid, 9, "%x", logMessage->machThreadID); + + size_t tidLen = MIN(9-1, len); + + // Here is our format: "%s %s[%i:%s] %s", timestamp, appName, processID, threadID, logMsg + + struct iovec v[13]; + + if (colorProfile) + { + v[0].iov_base = colorProfile->fgCode; + v[0].iov_len = colorProfile->fgCodeLen; + + v[1].iov_base = colorProfile->bgCode; + v[1].iov_len = colorProfile->bgCodeLen; + + v[12].iov_base = colorProfile->resetCode; + v[12].iov_len = colorProfile->resetCodeLen; + } + else + { + v[0].iov_base = ""; + v[0].iov_len = 0; + + v[1].iov_base = ""; + v[1].iov_len = 0; + + v[12].iov_base = ""; + v[12].iov_len = 0; + } + + v[2].iov_base = ts; + v[2].iov_len = tsLen; + + v[3].iov_base = " "; + v[3].iov_len = 1; + + v[4].iov_base = app; + v[4].iov_len = appLen; + + v[5].iov_base = "["; + v[5].iov_len = 1; + + v[6].iov_base = pid; + v[6].iov_len = pidLen; + + v[7].iov_base = ":"; + v[7].iov_len = 1; + + v[8].iov_base = tid; + v[8].iov_len = MIN((size_t)8, tidLen); // snprintf doesn't return what you might think + + v[9].iov_base = "] "; + v[9].iov_len = 2; + + v[10].iov_base = (char *)msg; + v[10].iov_len = msgLen; + + v[11].iov_base = "\n"; + v[11].iov_len = (msg[msgLen] == '\n') ? 0 : 1; + + writev(STDERR_FILENO, v, 13); + } + + if (!useStack) { + free(msg); + } + } +} + +- (NSString *)loggerName +{ + return @"cocoa.lumberjack.ttyLogger"; +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDTTYLoggerColorProfile + +- (id)initWithForegroundColor:(OSColor *)fgColor backgroundColor:(OSColor *)bgColor flag:(int)aMask context:(int)ctxt +{ + if ((self = [super init])) + { + mask = aMask; + context = ctxt; + + CGFloat r, g, b; + + if (fgColor) + { + [DDTTYLogger getRed:&r green:&g blue:&b fromColor:fgColor]; + + fg_r = (uint8_t)(r * 255.0f); + fg_g = (uint8_t)(g * 255.0f); + fg_b = (uint8_t)(b * 255.0f); + } + if (bgColor) + { + [DDTTYLogger getRed:&r green:&g blue:&b fromColor:bgColor]; + + bg_r = (uint8_t)(r * 255.0f); + bg_g = (uint8_t)(g * 255.0f); + bg_b = (uint8_t)(b * 255.0f); + } + + if (fgColor && isaColorTTY) + { + // Map foreground color to closest available shell color + + fgCodeIndex = [DDTTYLogger codeIndexForColor:fgColor]; + fgCodeRaw = [codes_fg objectAtIndex:fgCodeIndex]; + + NSString *escapeSeq = @"\033["; + + NSUInteger len1 = [escapeSeq lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + NSUInteger len2 = [fgCodeRaw lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + [escapeSeq getCString:(fgCode) maxLength:(len1+1) encoding:NSUTF8StringEncoding]; + [fgCodeRaw getCString:(fgCode+len1) maxLength:(len2+1) encoding:NSUTF8StringEncoding]; + + fgCodeLen = len1+len2; + } + else if (fgColor && isaXcodeColorTTY) + { + // Convert foreground color to color code sequence + + const char *escapeSeq = XCODE_COLORS_ESCAPE_SEQ; + + int result = snprintf(fgCode, 24, "%sfg%u,%u,%u;", escapeSeq, fg_r, fg_g, fg_b); + fgCodeLen = MIN(result, (24-1)); + } + else + { + // No foreground color or no color support + + fgCode[0] = '\0'; + fgCodeLen = 0; + } + + if (bgColor && isaColorTTY) + { + // Map background color to closest available shell color + + bgCodeIndex = [DDTTYLogger codeIndexForColor:bgColor]; + bgCodeRaw = [codes_bg objectAtIndex:bgCodeIndex]; + + NSString *escapeSeq = @"\033["; + + NSUInteger len1 = [escapeSeq lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + NSUInteger len2 = [bgCodeRaw lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + [escapeSeq getCString:(bgCode) maxLength:(len1+1) encoding:NSUTF8StringEncoding]; + [bgCodeRaw getCString:(bgCode+len1) maxLength:(len2+1) encoding:NSUTF8StringEncoding]; + + bgCodeLen = len1+len2; + } + else if (bgColor && isaXcodeColorTTY) + { + // Convert background color to color code sequence + + const char *escapeSeq = XCODE_COLORS_ESCAPE_SEQ; + + int result = snprintf(bgCode, 24, "%sbg%u,%u,%u;", escapeSeq, bg_r, bg_g, bg_b); + bgCodeLen = MIN(result, (24-1)); + } + else + { + // No background color or no color support + + bgCode[0] = '\0'; + bgCodeLen = 0; + } + + if (isaColorTTY) + { + resetCodeLen = snprintf(resetCode, 8, "\033[0m"); + } + else if (isaXcodeColorTTY) + { + resetCodeLen = snprintf(resetCode, 8, XCODE_COLORS_RESET); + } + else + { + resetCode[0] = '\0'; + resetCodeLen = 0; + } + } + return self; +} + +- (NSString *)description +{ + return [NSString stringWithFormat: + @"", + self, mask, context, fg_r, fg_g, fg_b, bg_r, bg_g, bg_b, fgCodeRaw, bgCodeRaw]; +} + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.h b/Pods/CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.h new file mode 100644 index 0000000..dffc865 --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.h @@ -0,0 +1,65 @@ +#import +#import "DDLog.h" + +@class ContextFilterLogFormatter; + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" page. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted + * + * + * This class provides a log formatter that filters log statements from a logging context not on the whitelist. + * + * A log formatter can be added to any logger to format and/or filter its output. + * You can learn more about log formatters here: + * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters + * + * You can learn more about logging context's here: + * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomContext + * + * But here's a quick overview / refresher: + * + * Every log statement has a logging context. + * These come from the underlying logging macros defined in DDLog.h. + * The default logging context is zero. + * You can define multiple logging context's for use in your application. + * For example, logically separate parts of your app each have a different logging context. + * Also 3rd party frameworks that make use of Lumberjack generally use their own dedicated logging context. +**/ +@interface ContextWhitelistFilterLogFormatter : NSObject + +- (id)init; + +- (void)addToWhitelist:(int)loggingContext; +- (void)removeFromWhitelist:(int)loggingContext; + +- (NSArray *)whitelist; + +- (BOOL)isOnWhitelist:(int)loggingContext; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * This class provides a log formatter that filters log statements from a logging context on the blacklist. +**/ +@interface ContextBlacklistFilterLogFormatter : NSObject + +- (id)init; + +- (void)addToBlacklist:(int)loggingContext; +- (void)removeFromBlacklist:(int)loggingContext; + +- (NSArray *)blacklist; + +- (BOOL)isOnBlacklist:(int)loggingContext; + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.m b/Pods/CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.m new file mode 100644 index 0000000..9c024ac --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.m @@ -0,0 +1,191 @@ +#import "ContextFilterLogFormatter.h" +#import + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" wiki. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted +**/ + +#if ! __has_feature(objc_arc) +#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + +@interface LoggingContextSet : NSObject + +- (void)addToSet:(int)loggingContext; +- (void)removeFromSet:(int)loggingContext; + +- (NSArray *)currentSet; + +- (BOOL)isInSet:(int)loggingContext; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation ContextWhitelistFilterLogFormatter +{ + LoggingContextSet *contextSet; +} + +- (id)init +{ + if ((self = [super init])) + { + contextSet = [[LoggingContextSet alloc] init]; + } + return self; +} + + +- (void)addToWhitelist:(int)loggingContext +{ + [contextSet addToSet:loggingContext]; +} + +- (void)removeFromWhitelist:(int)loggingContext +{ + [contextSet removeFromSet:loggingContext]; +} + +- (NSArray *)whitelist +{ + return [contextSet currentSet]; +} + +- (BOOL)isOnWhitelist:(int)loggingContext +{ + return [contextSet isInSet:loggingContext]; +} + +- (NSString *)formatLogMessage:(DDLogMessage *)logMessage +{ + if ([self isOnWhitelist:logMessage->logContext]) + return logMessage->logMsg; + else + return nil; +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation ContextBlacklistFilterLogFormatter +{ + LoggingContextSet *contextSet; +} + +- (id)init +{ + if ((self = [super init])) + { + contextSet = [[LoggingContextSet alloc] init]; + } + return self; +} + + +- (void)addToBlacklist:(int)loggingContext +{ + [contextSet addToSet:loggingContext]; +} + +- (void)removeFromBlacklist:(int)loggingContext +{ + [contextSet removeFromSet:loggingContext]; +} + +- (NSArray *)blacklist +{ + return [contextSet currentSet]; +} + +- (BOOL)isOnBlacklist:(int)loggingContext +{ + return [contextSet isInSet:loggingContext]; +} + +- (NSString *)formatLogMessage:(DDLogMessage *)logMessage +{ + if ([self isOnBlacklist:logMessage->logContext]) + return nil; + else + return logMessage->logMsg; +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation LoggingContextSet +{ + OSSpinLock lock; + NSMutableSet *set; +} + +- (id)init +{ + if ((self = [super init])) + { + set = [[NSMutableSet alloc] init]; + } + return self; +} + + +- (void)addToSet:(int)loggingContext +{ + OSSpinLockLock(&lock); + { + [set addObject:@(loggingContext)]; + } + OSSpinLockUnlock(&lock); +} + +- (void)removeFromSet:(int)loggingContext +{ + OSSpinLockLock(&lock); + { + [set removeObject:@(loggingContext)]; + } + OSSpinLockUnlock(&lock); +} + +- (NSArray *)currentSet +{ + NSArray *result = nil; + + OSSpinLockLock(&lock); + { + result = [set allObjects]; + } + OSSpinLockUnlock(&lock); + + return result; +} + +- (BOOL)isInSet:(int)loggingContext +{ + BOOL result = NO; + + OSSpinLockLock(&lock); + { + result = [set containsObject:@(loggingContext)]; + } + OSSpinLockUnlock(&lock); + + return result; +} + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.h b/Pods/CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.h new file mode 100644 index 0000000..9ad8d3f --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.h @@ -0,0 +1,116 @@ +#import +#import +#import "DDLog.h" + + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" page. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted + * + * + * This class provides a log formatter that prints the dispatch_queue label instead of the mach_thread_id. + * + * A log formatter can be added to any logger to format and/or filter its output. + * You can learn more about log formatters here: + * https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters + * + * A typical NSLog (or DDTTYLogger) prints detailed info as [:]. + * For example: + * + * 2011-10-17 20:21:45.435 AppName[19928:5207] Your log message here + * + * Where: + * - 19928 = process id + * - 5207 = thread id (mach_thread_id printed in hex) + * + * When using grand central dispatch (GCD), this information is less useful. + * This is because a single serial dispatch queue may be run on any thread from an internally managed thread pool. + * For example: + * + * 2011-10-17 20:32:31.111 AppName[19954:4d07] Message from my_serial_dispatch_queue + * 2011-10-17 20:32:31.112 AppName[19954:5207] Message from my_serial_dispatch_queue + * 2011-10-17 20:32:31.113 AppName[19954:2c55] Message from my_serial_dispatch_queue + * + * This formatter allows you to replace the standard [box:info] with the dispatch_queue name. + * For example: + * + * 2011-10-17 20:32:31.111 AppName[img-scaling] Message from my_serial_dispatch_queue + * 2011-10-17 20:32:31.112 AppName[img-scaling] Message from my_serial_dispatch_queue + * 2011-10-17 20:32:31.113 AppName[img-scaling] Message from my_serial_dispatch_queue + * + * If the dispatch_queue doesn't have a set name, then it falls back to the thread name. + * If the current thread doesn't have a set name, then it falls back to the mach_thread_id in hex (like normal). + * + * Note: If manually creating your own background threads (via NSThread/alloc/init or NSThread/detachNeThread), + * you can use [[NSThread currentThread] setName:(NSString *)]. +**/ +@interface DispatchQueueLogFormatter : NSObject { +@protected + + NSString *dateFormatString; +} + +/** + * Standard init method. + * Configure using properties as desired. +**/ +- (id)init; + +/** + * The minQueueLength restricts the minimum size of the [detail box]. + * If the minQueueLength is set to 0, there is no restriction. + * + * For example, say a dispatch_queue has a label of "diskIO": + * + * If the minQueueLength is 0: [diskIO] + * If the minQueueLength is 4: [diskIO] + * If the minQueueLength is 5: [diskIO] + * If the minQueueLength is 6: [diskIO] + * If the minQueueLength is 7: [diskIO ] + * If the minQueueLength is 8: [diskIO ] + * + * The default minQueueLength is 0 (no minimum, so [detail box] won't be padded). + * + * If you want every [detail box] to have the exact same width, + * set both minQueueLength and maxQueueLength to the same value. +**/ +@property (assign) NSUInteger minQueueLength; + +/** + * The maxQueueLength restricts the number of characters that will be inside the [detail box]. + * If the maxQueueLength is 0, there is no restriction. + * + * For example, say a dispatch_queue has a label of "diskIO": + * + * If the maxQueueLength is 0: [diskIO] + * If the maxQueueLength is 4: [disk] + * If the maxQueueLength is 5: [diskI] + * If the maxQueueLength is 6: [diskIO] + * If the maxQueueLength is 7: [diskIO] + * If the maxQueueLength is 8: [diskIO] + * + * The default maxQueueLength is 0 (no maximum, so [detail box] won't be truncated). + * + * If you want every [detail box] to have the exact same width, + * set both minQueueLength and maxQueueLength to the same value. +**/ +@property (assign) NSUInteger maxQueueLength; + +/** + * Sometimes queue labels have long names like "com.apple.main-queue", + * but you'd prefer something shorter like simply "main". + * + * This method allows you to set such preferred replacements. + * The above example is set by default. + * + * To remove/undo a previous replacement, invoke this method with nil for the 'shortLabel' parameter. +**/ +- (NSString *)replacementStringForQueueLabel:(NSString *)longLabel; +- (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel; + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.m b/Pods/CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.m new file mode 100644 index 0000000..d348f3d --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.m @@ -0,0 +1,251 @@ +#import "DispatchQueueLogFormatter.h" +#import + +/** + * Welcome to Cocoa Lumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/robbiehanson/CocoaLumberjack + * + * If you're new to the project you may wish to read the "Getting Started" wiki. + * https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted +**/ + +#if ! __has_feature(objc_arc) +#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + + +@implementation DispatchQueueLogFormatter +{ + int32_t atomicLoggerCount; + NSDateFormatter *threadUnsafeDateFormatter; // Use [self stringFromDate] + + OSSpinLock lock; + + NSUInteger _minQueueLength; // _prefix == Only access via atomic property + NSUInteger _maxQueueLength; // _prefix == Only access via atomic property + NSMutableDictionary *_replacements; // _prefix == Only access from within spinlock +} + +- (id)init +{ + if ((self = [super init])) + { + dateFormatString = @"yyyy-MM-dd HH:mm:ss:SSS"; + + atomicLoggerCount = 0; + threadUnsafeDateFormatter = nil; + + _minQueueLength = 0; + _maxQueueLength = 0; + _replacements = [[NSMutableDictionary alloc] init]; + + // Set default replacements: + + [_replacements setObject:@"main" forKey:@"com.apple.main-thread"]; + } + return self; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Configuration +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@synthesize minQueueLength = _minQueueLength; +@synthesize maxQueueLength = _maxQueueLength; + +- (NSString *)replacementStringForQueueLabel:(NSString *)longLabel +{ + NSString *result = nil; + + OSSpinLockLock(&lock); + { + result = [_replacements objectForKey:longLabel]; + } + OSSpinLockUnlock(&lock); + + return result; +} + +- (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel +{ + OSSpinLockLock(&lock); + { + if (shortLabel) + [_replacements setObject:shortLabel forKey:longLabel]; + else + [_replacements removeObjectForKey:longLabel]; + } + OSSpinLockUnlock(&lock); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark DDLogFormatter +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (NSString *)stringFromDate:(NSDate *)date +{ + int32_t loggerCount = OSAtomicAdd32(0, &atomicLoggerCount); + + if (loggerCount <= 1) + { + // Single-threaded mode. + + if (threadUnsafeDateFormatter == nil) + { + threadUnsafeDateFormatter = [[NSDateFormatter alloc] init]; + [threadUnsafeDateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; + [threadUnsafeDateFormatter setDateFormat:dateFormatString]; + } + + return [threadUnsafeDateFormatter stringFromDate:date]; + } + else + { + // Multi-threaded mode. + // NSDateFormatter is NOT thread-safe. + + NSString *key = @"DispatchQueueLogFormatter_NSDateFormatter"; + + NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary]; + NSDateFormatter *dateFormatter = [threadDictionary objectForKey:key]; + + if (dateFormatter == nil) + { + dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; + [dateFormatter setDateFormat:dateFormatString]; + + [threadDictionary setObject:dateFormatter forKey:key]; + } + + return [dateFormatter stringFromDate:date]; + } +} + +- (NSString *)queueThreadLabelForLogMessage:(DDLogMessage *)logMessage +{ + // As per the DDLogFormatter contract, this method is always invoked on the same thread/dispatch_queue + + NSUInteger minQueueLength = self.minQueueLength; + NSUInteger maxQueueLength = self.maxQueueLength; + + // Get the name of the queue, thread, or machID (whichever we are to use). + + NSString *queueThreadLabel = nil; + + BOOL useQueueLabel = YES; + BOOL useThreadName = NO; + + if (logMessage->queueLabel) + { + // If you manually create a thread, it's dispatch_queue will have one of the thread names below. + // Since all such threads have the same name, we'd prefer to use the threadName or the machThreadID. + + char *names[] = { "com.apple.root.low-priority", + "com.apple.root.default-priority", + "com.apple.root.high-priority", + "com.apple.root.low-overcommit-priority", + "com.apple.root.default-overcommit-priority", + "com.apple.root.high-overcommit-priority" }; + + int length = sizeof(names) / sizeof(char *); + + int i; + for (i = 0; i < length; i++) + { + if (strcmp(logMessage->queueLabel, names[i]) == 0) + { + useQueueLabel = NO; + useThreadName = [logMessage->threadName length] > 0; + break; + } + } + } + else + { + useQueueLabel = NO; + useThreadName = [logMessage->threadName length] > 0; + } + + if (useQueueLabel || useThreadName) + { + NSString *fullLabel; + NSString *abrvLabel; + + if (useQueueLabel) + fullLabel = @(logMessage->queueLabel); + else + fullLabel = logMessage->threadName; + + OSSpinLockLock(&lock); + { + abrvLabel = [_replacements objectForKey:fullLabel]; + } + OSSpinLockUnlock(&lock); + + if (abrvLabel) + queueThreadLabel = abrvLabel; + else + queueThreadLabel = fullLabel; + } + else + { + queueThreadLabel = [NSString stringWithFormat:@"%x", logMessage->machThreadID]; + } + + // Now use the thread label in the output + + NSUInteger labelLength = [queueThreadLabel length]; + + // labelLength > maxQueueLength : truncate + // labelLength < minQueueLength : padding + // : exact + + if ((maxQueueLength > 0) && (labelLength > maxQueueLength)) + { + // Truncate + + return [queueThreadLabel substringToIndex:maxQueueLength]; + } + else if (labelLength < minQueueLength) + { + // Padding + + NSUInteger numSpaces = minQueueLength - labelLength; + + char spaces[numSpaces + 1]; + memset(spaces, ' ', numSpaces); + spaces[numSpaces] = '\0'; + + return [NSString stringWithFormat:@"%@%s", queueThreadLabel, spaces]; + } + else + { + // Exact + + return queueThreadLabel; + } +} + +- (NSString *)formatLogMessage:(DDLogMessage *)logMessage +{ + NSString *timestamp = [self stringFromDate:(logMessage->timestamp)]; + NSString *queueThreadLabel = [self queueThreadLabelForLogMessage:logMessage]; + + return [NSString stringWithFormat:@"%@ [%@] %@", timestamp, queueThreadLabel, logMessage->logMsg]; +} + +- (void)didAddToLogger:(id )logger +{ + OSAtomicIncrement32(&atomicLoggerCount); +} + +- (void)willRemoveFromLogger:(id )logger +{ + OSAtomicDecrement32(&atomicLoggerCount); +} + +@end diff --git a/Pods/CocoaLumberjack/Lumberjack/Extensions/README.txt b/Pods/CocoaLumberjack/Lumberjack/Extensions/README.txt new file mode 100644 index 0000000..eb20e50 --- /dev/null +++ b/Pods/CocoaLumberjack/Lumberjack/Extensions/README.txt @@ -0,0 +1,7 @@ +This folder contains some sample formatters that may be helpful. + +Feel free to change them, extend them, or use them as the basis for your own custom formatter(s). + +More information about creating your own custom formatters can be found on the wiki: +https://github.com/robbiehanson/CocoaLumberjack/wiki/CustomFormatters + diff --git a/Pods/CocoaLumberjack/README.markdown b/Pods/CocoaLumberjack/README.markdown new file mode 100644 index 0000000..8ee32fd --- /dev/null +++ b/Pods/CocoaLumberjack/README.markdown @@ -0,0 +1,37 @@ +### Lumberjack is Fast & Simple, yet Powerful & Flexible. + +It is similar in concept to other popular logging frameworks such as log4j, yet is designed specifically for Objective-C, and takes advantage of features such as multi-threading, grand central dispatch (if available), lockless atomic operations, and the dynamic nature of the Objective-C runtime. + +### Lumberjack is Fast + +In most cases it is an order of magnitude faster than NSLog. + +### Lumberjack is Simple + +It takes as little as a single line of code to configure lumberjack when your application launches. Then simply replace your NSLog statements with DDLog statements and that's about it. (And the DDLog macros have the exact same format and syntax as NSLog, so it's super easy.) + +### Lumberjack is Powerful: + +One log statement can be sent to multiple loggers, meaning you can log to a file and the console simultaneously. Want more? Create your own loggers (it's easy) and send your log statements over the network. Or to a database or distributed file system. The sky is the limit. + +### Lumberjack is Flexible: + +Configure your logging however you want. Change log levels per file (perfect for debugging). Change log levels per logger (verbose console, but concise log file). Change log levels per xcode configuration (verbose debug, but concise release). Have your log statements compiled out of the release build. Customize the number of log levels for your application. Add your own fine-grained logging. Dynamically change log levels during runtime. Choose how & when you want your log files to be rolled. Upload your log files to a central server. Compress archived log files to save disk space... + +
+This framework is for you if: + +- You're looking for a way to track down that impossible-to-reproduce bug that keeps popping up in the field. +- You're frustrated with the super short console log on the iPhone. +- You're looking to take your application to the next level in terms of support and stability. +- You're looking for an enterprise level logging solution for your application (Mac or iPhone). + +
+**[Get started using Lumberjack](https://github.com/robbiehanson/CocoaLumberjack/wiki/GettingStarted)**
+**[Learn more about Lumberjack](https://github.com/robbiehanson/CocoaLumberjack/wiki)**
+ +
+Can't find the answer to your question in any of the [wiki](https://github.com/robbiehanson/CocoaLumberjack/wiki) articles? Try the **[mailing list](http://groups.google.com/group/cocoalumberjack)**. +
+
+Love the project? Wanna buy me a coffee? (or a beer :D) [![donation](http://www.paypal.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UZRA26JPJB3DA) diff --git a/Pods/Headers/CocoaLumberjack/ContextFilterLogFormatter.h b/Pods/Headers/CocoaLumberjack/ContextFilterLogFormatter.h new file mode 120000 index 0000000..de4836b --- /dev/null +++ b/Pods/Headers/CocoaLumberjack/ContextFilterLogFormatter.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/Extensions/ContextFilterLogFormatter.h \ No newline at end of file diff --git a/Pods/Headers/CocoaLumberjack/DDASLLogger.h b/Pods/Headers/CocoaLumberjack/DDASLLogger.h new file mode 120000 index 0000000..663f808 --- /dev/null +++ b/Pods/Headers/CocoaLumberjack/DDASLLogger.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/DDASLLogger.h \ No newline at end of file diff --git a/Pods/Headers/CocoaLumberjack/DDAbstractDatabaseLogger.h b/Pods/Headers/CocoaLumberjack/DDAbstractDatabaseLogger.h new file mode 120000 index 0000000..950a053 --- /dev/null +++ b/Pods/Headers/CocoaLumberjack/DDAbstractDatabaseLogger.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.h \ No newline at end of file diff --git a/Pods/Headers/CocoaLumberjack/DDFileLogger.h b/Pods/Headers/CocoaLumberjack/DDFileLogger.h new file mode 120000 index 0000000..18c2149 --- /dev/null +++ b/Pods/Headers/CocoaLumberjack/DDFileLogger.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/DDFileLogger.h \ No newline at end of file diff --git a/Pods/Headers/CocoaLumberjack/DDLog.h b/Pods/Headers/CocoaLumberjack/DDLog.h new file mode 120000 index 0000000..8af615d --- /dev/null +++ b/Pods/Headers/CocoaLumberjack/DDLog.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/DDLog.h \ No newline at end of file diff --git a/Pods/Headers/CocoaLumberjack/DDTTYLogger.h b/Pods/Headers/CocoaLumberjack/DDTTYLogger.h new file mode 120000 index 0000000..6c7bb54 --- /dev/null +++ b/Pods/Headers/CocoaLumberjack/DDTTYLogger.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/DDTTYLogger.h \ No newline at end of file diff --git a/Pods/Headers/CocoaLumberjack/DispatchQueueLogFormatter.h b/Pods/Headers/CocoaLumberjack/DispatchQueueLogFormatter.h new file mode 120000 index 0000000..76d4c51 --- /dev/null +++ b/Pods/Headers/CocoaLumberjack/DispatchQueueLogFormatter.h @@ -0,0 +1 @@ +../../CocoaLumberjack/Lumberjack/Extensions/DispatchQueueLogFormatter.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWAfterAllNode.h b/Pods/Headers/Kiwi/KWAfterAllNode.h new file mode 120000 index 0000000..4e9be08 --- /dev/null +++ b/Pods/Headers/Kiwi/KWAfterAllNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWAfterAllNode.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWAfterEachNode.h b/Pods/Headers/Kiwi/KWAfterEachNode.h new file mode 120000 index 0000000..450df35 --- /dev/null +++ b/Pods/Headers/Kiwi/KWAfterEachNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWAfterEachNode.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWAny.h b/Pods/Headers/Kiwi/KWAny.h new file mode 120000 index 0000000..681893a --- /dev/null +++ b/Pods/Headers/Kiwi/KWAny.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWAny.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWAsyncVerifier.h b/Pods/Headers/Kiwi/KWAsyncVerifier.h new file mode 120000 index 0000000..33cf289 --- /dev/null +++ b/Pods/Headers/Kiwi/KWAsyncVerifier.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWAsyncVerifier.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBeBetweenMatcher.h b/Pods/Headers/Kiwi/KWBeBetweenMatcher.h new file mode 120000 index 0000000..bbe5314 --- /dev/null +++ b/Pods/Headers/Kiwi/KWBeBetweenMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeBetweenMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBeEmptyMatcher.h b/Pods/Headers/Kiwi/KWBeEmptyMatcher.h new file mode 120000 index 0000000..f5a0689 --- /dev/null +++ b/Pods/Headers/Kiwi/KWBeEmptyMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeEmptyMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBeIdenticalToMatcher.h b/Pods/Headers/Kiwi/KWBeIdenticalToMatcher.h new file mode 120000 index 0000000..b746586 --- /dev/null +++ b/Pods/Headers/Kiwi/KWBeIdenticalToMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeIdenticalToMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBeKindOfClassMatcher.h b/Pods/Headers/Kiwi/KWBeKindOfClassMatcher.h new file mode 120000 index 0000000..06fbe03 --- /dev/null +++ b/Pods/Headers/Kiwi/KWBeKindOfClassMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeKindOfClassMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBeMemberOfClassMatcher.h b/Pods/Headers/Kiwi/KWBeMemberOfClassMatcher.h new file mode 120000 index 0000000..08101ce --- /dev/null +++ b/Pods/Headers/Kiwi/KWBeMemberOfClassMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeMemberOfClassMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBeNilMatcher.h b/Pods/Headers/Kiwi/KWBeNilMatcher.h new file mode 120000 index 0000000..be56da6 --- /dev/null +++ b/Pods/Headers/Kiwi/KWBeNilMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeNilMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBeNonNilMatcher.h b/Pods/Headers/Kiwi/KWBeNonNilMatcher.h new file mode 120000 index 0000000..16c909a --- /dev/null +++ b/Pods/Headers/Kiwi/KWBeNonNilMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeNonNilMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBeSubclassOfClassMatcher.h b/Pods/Headers/Kiwi/KWBeSubclassOfClassMatcher.h new file mode 120000 index 0000000..264f776 --- /dev/null +++ b/Pods/Headers/Kiwi/KWBeSubclassOfClassMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeSubclassOfClassMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBeTrueMatcher.h b/Pods/Headers/Kiwi/KWBeTrueMatcher.h new file mode 120000 index 0000000..321d347 --- /dev/null +++ b/Pods/Headers/Kiwi/KWBeTrueMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeTrueMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBeWithinMatcher.h b/Pods/Headers/Kiwi/KWBeWithinMatcher.h new file mode 120000 index 0000000..895f860 --- /dev/null +++ b/Pods/Headers/Kiwi/KWBeWithinMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeWithinMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBeZeroMatcher.h b/Pods/Headers/Kiwi/KWBeZeroMatcher.h new file mode 120000 index 0000000..9848160 --- /dev/null +++ b/Pods/Headers/Kiwi/KWBeZeroMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeZeroMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBeforeAllNode.h b/Pods/Headers/Kiwi/KWBeforeAllNode.h new file mode 120000 index 0000000..139d69a --- /dev/null +++ b/Pods/Headers/Kiwi/KWBeforeAllNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeforeAllNode.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBeforeEachNode.h b/Pods/Headers/Kiwi/KWBeforeEachNode.h new file mode 120000 index 0000000..f72e71c --- /dev/null +++ b/Pods/Headers/Kiwi/KWBeforeEachNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBeforeEachNode.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBlock.h b/Pods/Headers/Kiwi/KWBlock.h new file mode 120000 index 0000000..a6a57c3 --- /dev/null +++ b/Pods/Headers/Kiwi/KWBlock.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBlock.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBlockNode.h b/Pods/Headers/Kiwi/KWBlockNode.h new file mode 120000 index 0000000..d6fc357 --- /dev/null +++ b/Pods/Headers/Kiwi/KWBlockNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBlockNode.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWBlockRaiseMatcher.h b/Pods/Headers/Kiwi/KWBlockRaiseMatcher.h new file mode 120000 index 0000000..68a0b99 --- /dev/null +++ b/Pods/Headers/Kiwi/KWBlockRaiseMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWBlockRaiseMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWCallSite.h b/Pods/Headers/Kiwi/KWCallSite.h new file mode 120000 index 0000000..e2a84e7 --- /dev/null +++ b/Pods/Headers/Kiwi/KWCallSite.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWCallSite.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWCaptureSpy.h b/Pods/Headers/Kiwi/KWCaptureSpy.h new file mode 120000 index 0000000..ed1d865 --- /dev/null +++ b/Pods/Headers/Kiwi/KWCaptureSpy.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWCaptureSpy.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWChangeMatcher.h b/Pods/Headers/Kiwi/KWChangeMatcher.h new file mode 120000 index 0000000..da16244 --- /dev/null +++ b/Pods/Headers/Kiwi/KWChangeMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWChangeMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWConformToProtocolMatcher.h b/Pods/Headers/Kiwi/KWConformToProtocolMatcher.h new file mode 120000 index 0000000..c4512e3 --- /dev/null +++ b/Pods/Headers/Kiwi/KWConformToProtocolMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWConformToProtocolMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWContainMatcher.h b/Pods/Headers/Kiwi/KWContainMatcher.h new file mode 120000 index 0000000..3b564a7 --- /dev/null +++ b/Pods/Headers/Kiwi/KWContainMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWContainMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWContextNode.h b/Pods/Headers/Kiwi/KWContextNode.h new file mode 120000 index 0000000..367e449 --- /dev/null +++ b/Pods/Headers/Kiwi/KWContextNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWContextNode.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWCountType.h b/Pods/Headers/Kiwi/KWCountType.h new file mode 120000 index 0000000..f48c43f --- /dev/null +++ b/Pods/Headers/Kiwi/KWCountType.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWCountType.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWDeviceInfo.h b/Pods/Headers/Kiwi/KWDeviceInfo.h new file mode 120000 index 0000000..ad0e2df --- /dev/null +++ b/Pods/Headers/Kiwi/KWDeviceInfo.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWDeviceInfo.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWEqualMatcher.h b/Pods/Headers/Kiwi/KWEqualMatcher.h new file mode 120000 index 0000000..d55c932 --- /dev/null +++ b/Pods/Headers/Kiwi/KWEqualMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWEqualMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWExample.h b/Pods/Headers/Kiwi/KWExample.h new file mode 120000 index 0000000..7c20cd1 --- /dev/null +++ b/Pods/Headers/Kiwi/KWExample.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExample.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWExampleGroupBuilder.h b/Pods/Headers/Kiwi/KWExampleGroupBuilder.h new file mode 120000 index 0000000..0fe8c73 --- /dev/null +++ b/Pods/Headers/Kiwi/KWExampleGroupBuilder.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExampleGroupBuilder.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWExampleGroupDelegate.h b/Pods/Headers/Kiwi/KWExampleGroupDelegate.h new file mode 120000 index 0000000..0ed4e5e --- /dev/null +++ b/Pods/Headers/Kiwi/KWExampleGroupDelegate.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExampleGroupDelegate.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWExampleNode.h b/Pods/Headers/Kiwi/KWExampleNode.h new file mode 120000 index 0000000..261f507 --- /dev/null +++ b/Pods/Headers/Kiwi/KWExampleNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExampleNode.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWExampleNodeVisitor.h b/Pods/Headers/Kiwi/KWExampleNodeVisitor.h new file mode 120000 index 0000000..3d7f7d8 --- /dev/null +++ b/Pods/Headers/Kiwi/KWExampleNodeVisitor.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExampleNodeVisitor.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWExampleSuite.h b/Pods/Headers/Kiwi/KWExampleSuite.h new file mode 120000 index 0000000..fc62150 --- /dev/null +++ b/Pods/Headers/Kiwi/KWExampleSuite.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExampleSuite.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWExistVerifier.h b/Pods/Headers/Kiwi/KWExistVerifier.h new file mode 120000 index 0000000..fefc731 --- /dev/null +++ b/Pods/Headers/Kiwi/KWExistVerifier.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExistVerifier.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWExpectationType.h b/Pods/Headers/Kiwi/KWExpectationType.h new file mode 120000 index 0000000..bb33bfc --- /dev/null +++ b/Pods/Headers/Kiwi/KWExpectationType.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWExpectationType.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWFailure.h b/Pods/Headers/Kiwi/KWFailure.h new file mode 120000 index 0000000..b55a3bc --- /dev/null +++ b/Pods/Headers/Kiwi/KWFailure.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWFailure.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWFormatter.h b/Pods/Headers/Kiwi/KWFormatter.h new file mode 120000 index 0000000..80c47df --- /dev/null +++ b/Pods/Headers/Kiwi/KWFormatter.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWFormatter.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWFutureObject.h b/Pods/Headers/Kiwi/KWFutureObject.h new file mode 120000 index 0000000..401eaf0 --- /dev/null +++ b/Pods/Headers/Kiwi/KWFutureObject.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWFutureObject.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWGenericMatchEvaluator.h b/Pods/Headers/Kiwi/KWGenericMatchEvaluator.h new file mode 120000 index 0000000..c3aeaec --- /dev/null +++ b/Pods/Headers/Kiwi/KWGenericMatchEvaluator.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWGenericMatchEvaluator.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWGenericMatcher.h b/Pods/Headers/Kiwi/KWGenericMatcher.h new file mode 120000 index 0000000..5c48a70 --- /dev/null +++ b/Pods/Headers/Kiwi/KWGenericMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWGenericMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWGenericMatchingAdditions.h b/Pods/Headers/Kiwi/KWGenericMatchingAdditions.h new file mode 120000 index 0000000..61c0fcd --- /dev/null +++ b/Pods/Headers/Kiwi/KWGenericMatchingAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWGenericMatchingAdditions.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWHaveMatcher.h b/Pods/Headers/Kiwi/KWHaveMatcher.h new file mode 120000 index 0000000..c2bd283 --- /dev/null +++ b/Pods/Headers/Kiwi/KWHaveMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWHaveMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWHaveValueMatcher.h b/Pods/Headers/Kiwi/KWHaveValueMatcher.h new file mode 120000 index 0000000..19b108b --- /dev/null +++ b/Pods/Headers/Kiwi/KWHaveValueMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWHaveValueMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWInequalityMatcher.h b/Pods/Headers/Kiwi/KWInequalityMatcher.h new file mode 120000 index 0000000..8d85cb4 --- /dev/null +++ b/Pods/Headers/Kiwi/KWInequalityMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWInequalityMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWIntercept.h b/Pods/Headers/Kiwi/KWIntercept.h new file mode 120000 index 0000000..b9fae62 --- /dev/null +++ b/Pods/Headers/Kiwi/KWIntercept.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWIntercept.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWInvocationCapturer.h b/Pods/Headers/Kiwi/KWInvocationCapturer.h new file mode 120000 index 0000000..383f8e8 --- /dev/null +++ b/Pods/Headers/Kiwi/KWInvocationCapturer.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWInvocationCapturer.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWItNode.h b/Pods/Headers/Kiwi/KWItNode.h new file mode 120000 index 0000000..37b3ed5 --- /dev/null +++ b/Pods/Headers/Kiwi/KWItNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWItNode.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWMatchVerifier.h b/Pods/Headers/Kiwi/KWMatchVerifier.h new file mode 120000 index 0000000..78de3b2 --- /dev/null +++ b/Pods/Headers/Kiwi/KWMatchVerifier.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMatchVerifier.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWMatcher.h b/Pods/Headers/Kiwi/KWMatcher.h new file mode 120000 index 0000000..a3869b4 --- /dev/null +++ b/Pods/Headers/Kiwi/KWMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWMatcherFactory.h b/Pods/Headers/Kiwi/KWMatcherFactory.h new file mode 120000 index 0000000..d6ef256 --- /dev/null +++ b/Pods/Headers/Kiwi/KWMatcherFactory.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMatcherFactory.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWMatchers.h b/Pods/Headers/Kiwi/KWMatchers.h new file mode 120000 index 0000000..121cbff --- /dev/null +++ b/Pods/Headers/Kiwi/KWMatchers.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMatchers.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWMatching.h b/Pods/Headers/Kiwi/KWMatching.h new file mode 120000 index 0000000..b46afda --- /dev/null +++ b/Pods/Headers/Kiwi/KWMatching.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMatching.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWMessagePattern.h b/Pods/Headers/Kiwi/KWMessagePattern.h new file mode 120000 index 0000000..00983f2 --- /dev/null +++ b/Pods/Headers/Kiwi/KWMessagePattern.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMessagePattern.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWMessageSpying.h b/Pods/Headers/Kiwi/KWMessageSpying.h new file mode 120000 index 0000000..31fb60e --- /dev/null +++ b/Pods/Headers/Kiwi/KWMessageSpying.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMessageSpying.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWMessageTracker.h b/Pods/Headers/Kiwi/KWMessageTracker.h new file mode 120000 index 0000000..af301a1 --- /dev/null +++ b/Pods/Headers/Kiwi/KWMessageTracker.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMessageTracker.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWMock.h b/Pods/Headers/Kiwi/KWMock.h new file mode 120000 index 0000000..5d2b688 --- /dev/null +++ b/Pods/Headers/Kiwi/KWMock.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWMock.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWNull.h b/Pods/Headers/Kiwi/KWNull.h new file mode 120000 index 0000000..3a8677c --- /dev/null +++ b/Pods/Headers/Kiwi/KWNull.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWNull.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWObjCUtilities.h b/Pods/Headers/Kiwi/KWObjCUtilities.h new file mode 120000 index 0000000..f9c04a2 --- /dev/null +++ b/Pods/Headers/Kiwi/KWObjCUtilities.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWObjCUtilities.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWPendingNode.h b/Pods/Headers/Kiwi/KWPendingNode.h new file mode 120000 index 0000000..6a2a4ab --- /dev/null +++ b/Pods/Headers/Kiwi/KWPendingNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWPendingNode.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWProbe.h b/Pods/Headers/Kiwi/KWProbe.h new file mode 120000 index 0000000..8eae994 --- /dev/null +++ b/Pods/Headers/Kiwi/KWProbe.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWProbe.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWProbePoller.h b/Pods/Headers/Kiwi/KWProbePoller.h new file mode 120000 index 0000000..852d35e --- /dev/null +++ b/Pods/Headers/Kiwi/KWProbePoller.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWProbePoller.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWRaiseMatcher.h b/Pods/Headers/Kiwi/KWRaiseMatcher.h new file mode 120000 index 0000000..bdcd8ae --- /dev/null +++ b/Pods/Headers/Kiwi/KWRaiseMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWRaiseMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWReceiveMatcher.h b/Pods/Headers/Kiwi/KWReceiveMatcher.h new file mode 120000 index 0000000..5dfb172 --- /dev/null +++ b/Pods/Headers/Kiwi/KWReceiveMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWReceiveMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWRegisterMatchersNode.h b/Pods/Headers/Kiwi/KWRegisterMatchersNode.h new file mode 120000 index 0000000..6ee09af --- /dev/null +++ b/Pods/Headers/Kiwi/KWRegisterMatchersNode.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWRegisterMatchersNode.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWReporting.h b/Pods/Headers/Kiwi/KWReporting.h new file mode 120000 index 0000000..76724b4 --- /dev/null +++ b/Pods/Headers/Kiwi/KWReporting.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWReporting.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWRespondToSelectorMatcher.h b/Pods/Headers/Kiwi/KWRespondToSelectorMatcher.h new file mode 120000 index 0000000..638ffc9 --- /dev/null +++ b/Pods/Headers/Kiwi/KWRespondToSelectorMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWRespondToSelectorMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWSpec.h b/Pods/Headers/Kiwi/KWSpec.h new file mode 120000 index 0000000..01ff65d --- /dev/null +++ b/Pods/Headers/Kiwi/KWSpec.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWSpec.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWStringContainsMatcher.h b/Pods/Headers/Kiwi/KWStringContainsMatcher.h new file mode 120000 index 0000000..31a35fa --- /dev/null +++ b/Pods/Headers/Kiwi/KWStringContainsMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWStringContainsMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWStringPrefixMatcher.h b/Pods/Headers/Kiwi/KWStringPrefixMatcher.h new file mode 120000 index 0000000..6332ce4 --- /dev/null +++ b/Pods/Headers/Kiwi/KWStringPrefixMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWStringPrefixMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWStringUtilities.h b/Pods/Headers/Kiwi/KWStringUtilities.h new file mode 120000 index 0000000..c6b107f --- /dev/null +++ b/Pods/Headers/Kiwi/KWStringUtilities.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWStringUtilities.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWStub.h b/Pods/Headers/Kiwi/KWStub.h new file mode 120000 index 0000000..38e5d0d --- /dev/null +++ b/Pods/Headers/Kiwi/KWStub.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWStub.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWTestCase.h b/Pods/Headers/Kiwi/KWTestCase.h new file mode 120000 index 0000000..04096f4 --- /dev/null +++ b/Pods/Headers/Kiwi/KWTestCase.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWTestCase.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWUserDefinedMatcher.h b/Pods/Headers/Kiwi/KWUserDefinedMatcher.h new file mode 120000 index 0000000..e6a74c1 --- /dev/null +++ b/Pods/Headers/Kiwi/KWUserDefinedMatcher.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWUserDefinedMatcher.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWValue.h b/Pods/Headers/Kiwi/KWValue.h new file mode 120000 index 0000000..1546da5 --- /dev/null +++ b/Pods/Headers/Kiwi/KWValue.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWValue.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWVerifying.h b/Pods/Headers/Kiwi/KWVerifying.h new file mode 120000 index 0000000..7e7e7f3 --- /dev/null +++ b/Pods/Headers/Kiwi/KWVerifying.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWVerifying.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KWWorkarounds.h b/Pods/Headers/Kiwi/KWWorkarounds.h new file mode 120000 index 0000000..4535bdc --- /dev/null +++ b/Pods/Headers/Kiwi/KWWorkarounds.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KWWorkarounds.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/Kiwi.h b/Pods/Headers/Kiwi/Kiwi.h new file mode 120000 index 0000000..2a5426e --- /dev/null +++ b/Pods/Headers/Kiwi/Kiwi.h @@ -0,0 +1 @@ +../../Kiwi/Classes/Kiwi.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KiwiBlockMacros.h b/Pods/Headers/Kiwi/KiwiBlockMacros.h new file mode 120000 index 0000000..0407704 --- /dev/null +++ b/Pods/Headers/Kiwi/KiwiBlockMacros.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KiwiBlockMacros.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KiwiConfiguration.h b/Pods/Headers/Kiwi/KiwiConfiguration.h new file mode 120000 index 0000000..e592852 --- /dev/null +++ b/Pods/Headers/Kiwi/KiwiConfiguration.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KiwiConfiguration.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KiwiMacros.h b/Pods/Headers/Kiwi/KiwiMacros.h new file mode 120000 index 0000000..eb8ad23 --- /dev/null +++ b/Pods/Headers/Kiwi/KiwiMacros.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KiwiMacros.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/KiwiNewMacros.h b/Pods/Headers/Kiwi/KiwiNewMacros.h new file mode 120000 index 0000000..1dcc226 --- /dev/null +++ b/Pods/Headers/Kiwi/KiwiNewMacros.h @@ -0,0 +1 @@ +../../Kiwi/Classes/KiwiNewMacros.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/NSInvocation+KiwiAdditions.h b/Pods/Headers/Kiwi/NSInvocation+KiwiAdditions.h new file mode 120000 index 0000000..0a19c57 --- /dev/null +++ b/Pods/Headers/Kiwi/NSInvocation+KiwiAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSInvocation+KiwiAdditions.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/NSInvocation+OCMAdditions.h b/Pods/Headers/Kiwi/NSInvocation+OCMAdditions.h new file mode 120000 index 0000000..1816d66 --- /dev/null +++ b/Pods/Headers/Kiwi/NSInvocation+OCMAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSInvocation+OCMAdditions.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/NSMethodSignature+KiwiAdditions.h b/Pods/Headers/Kiwi/NSMethodSignature+KiwiAdditions.h new file mode 120000 index 0000000..83429ba --- /dev/null +++ b/Pods/Headers/Kiwi/NSMethodSignature+KiwiAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSMethodSignature+KiwiAdditions.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/NSNumber+KiwiAdditions.h b/Pods/Headers/Kiwi/NSNumber+KiwiAdditions.h new file mode 120000 index 0000000..48e2354 --- /dev/null +++ b/Pods/Headers/Kiwi/NSNumber+KiwiAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSNumber+KiwiAdditions.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/NSObject+KiwiMockAdditions.h b/Pods/Headers/Kiwi/NSObject+KiwiMockAdditions.h new file mode 120000 index 0000000..32160c6 --- /dev/null +++ b/Pods/Headers/Kiwi/NSObject+KiwiMockAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSObject+KiwiMockAdditions.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/NSObject+KiwiSpyAdditions.h b/Pods/Headers/Kiwi/NSObject+KiwiSpyAdditions.h new file mode 120000 index 0000000..4da2d79 --- /dev/null +++ b/Pods/Headers/Kiwi/NSObject+KiwiSpyAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSObject+KiwiSpyAdditions.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/NSObject+KiwiStubAdditions.h b/Pods/Headers/Kiwi/NSObject+KiwiStubAdditions.h new file mode 120000 index 0000000..a64ea2c --- /dev/null +++ b/Pods/Headers/Kiwi/NSObject+KiwiStubAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSObject+KiwiStubAdditions.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/NSObject+KiwiVerifierAdditions.h b/Pods/Headers/Kiwi/NSObject+KiwiVerifierAdditions.h new file mode 120000 index 0000000..68f6f43 --- /dev/null +++ b/Pods/Headers/Kiwi/NSObject+KiwiVerifierAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSObject+KiwiVerifierAdditions.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/NSProxy+KiwiVerifierAdditions.h b/Pods/Headers/Kiwi/NSProxy+KiwiVerifierAdditions.h new file mode 120000 index 0000000..1e07874 --- /dev/null +++ b/Pods/Headers/Kiwi/NSProxy+KiwiVerifierAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSProxy+KiwiVerifierAdditions.h \ No newline at end of file diff --git a/Pods/Headers/Kiwi/NSValue+KiwiAdditions.h b/Pods/Headers/Kiwi/NSValue+KiwiAdditions.h new file mode 120000 index 0000000..5b15712 --- /dev/null +++ b/Pods/Headers/Kiwi/NSValue+KiwiAdditions.h @@ -0,0 +1 @@ +../../Kiwi/Classes/NSValue+KiwiAdditions.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/NSInvocation+OCMAdditions.h b/Pods/Headers/OCMock/NSInvocation+OCMAdditions.h new file mode 120000 index 0000000..b5f84f8 --- /dev/null +++ b/Pods/Headers/OCMock/NSInvocation+OCMAdditions.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/NSInvocation+OCMAdditions.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/NSMethodSignature+OCMAdditions.h b/Pods/Headers/OCMock/NSMethodSignature+OCMAdditions.h new file mode 120000 index 0000000..78c96d0 --- /dev/null +++ b/Pods/Headers/OCMock/NSMethodSignature+OCMAdditions.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/NSNotificationCenter+OCMAdditions.h b/Pods/Headers/OCMock/NSNotificationCenter+OCMAdditions.h new file mode 120000 index 0000000..b0c2371 --- /dev/null +++ b/Pods/Headers/OCMock/NSNotificationCenter+OCMAdditions.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCClassMockObject.h b/Pods/Headers/OCMock/OCClassMockObject.h new file mode 120000 index 0000000..53c7c49 --- /dev/null +++ b/Pods/Headers/OCMock/OCClassMockObject.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCClassMockObject.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMArg.h b/Pods/Headers/OCMock/OCMArg.h new file mode 120000 index 0000000..7f69f9b --- /dev/null +++ b/Pods/Headers/OCMock/OCMArg.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMArg.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMBlockCaller.h b/Pods/Headers/OCMock/OCMBlockCaller.h new file mode 120000 index 0000000..1dea96c --- /dev/null +++ b/Pods/Headers/OCMock/OCMBlockCaller.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMBlockCaller.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMBoxedReturnValueProvider.h b/Pods/Headers/OCMock/OCMBoxedReturnValueProvider.h new file mode 120000 index 0000000..e663e8d --- /dev/null +++ b/Pods/Headers/OCMock/OCMBoxedReturnValueProvider.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMBoxedReturnValueProvider.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMConstraint.h b/Pods/Headers/OCMock/OCMConstraint.h new file mode 120000 index 0000000..8cf4176 --- /dev/null +++ b/Pods/Headers/OCMock/OCMConstraint.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMConstraint.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMExceptionReturnValueProvider.h b/Pods/Headers/OCMock/OCMExceptionReturnValueProvider.h new file mode 120000 index 0000000..7661d35 --- /dev/null +++ b/Pods/Headers/OCMock/OCMExceptionReturnValueProvider.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMExceptionReturnValueProvider.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMIndirectReturnValueProvider.h b/Pods/Headers/OCMock/OCMIndirectReturnValueProvider.h new file mode 120000 index 0000000..ad444fd --- /dev/null +++ b/Pods/Headers/OCMock/OCMIndirectReturnValueProvider.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMIndirectReturnValueProvider.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMNotificationPoster.h b/Pods/Headers/OCMock/OCMNotificationPoster.h new file mode 120000 index 0000000..d555dbd --- /dev/null +++ b/Pods/Headers/OCMock/OCMNotificationPoster.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMNotificationPoster.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMObserverRecorder.h b/Pods/Headers/OCMock/OCMObserverRecorder.h new file mode 120000 index 0000000..89d0a7b --- /dev/null +++ b/Pods/Headers/OCMock/OCMObserverRecorder.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMObserverRecorder.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMPassByRefSetter.h b/Pods/Headers/OCMock/OCMPassByRefSetter.h new file mode 120000 index 0000000..8aed5e1 --- /dev/null +++ b/Pods/Headers/OCMock/OCMPassByRefSetter.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMPassByRefSetter.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMRealObjectForwarder.h b/Pods/Headers/OCMock/OCMRealObjectForwarder.h new file mode 120000 index 0000000..5664269 --- /dev/null +++ b/Pods/Headers/OCMock/OCMRealObjectForwarder.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMRealObjectForwarder.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMReturnValueProvider.h b/Pods/Headers/OCMock/OCMReturnValueProvider.h new file mode 120000 index 0000000..458db78 --- /dev/null +++ b/Pods/Headers/OCMock/OCMReturnValueProvider.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMReturnValueProvider.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMock.h b/Pods/Headers/OCMock/OCMock.h new file mode 120000 index 0000000..d908884 --- /dev/null +++ b/Pods/Headers/OCMock/OCMock.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMock.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMockObject.h b/Pods/Headers/OCMock/OCMockObject.h new file mode 120000 index 0000000..f6cf2f1 --- /dev/null +++ b/Pods/Headers/OCMock/OCMockObject.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMockObject.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCMockRecorder.h b/Pods/Headers/OCMock/OCMockRecorder.h new file mode 120000 index 0000000..183029a --- /dev/null +++ b/Pods/Headers/OCMock/OCMockRecorder.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCMockRecorder.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCObserverMockObject.h b/Pods/Headers/OCMock/OCObserverMockObject.h new file mode 120000 index 0000000..7624fc8 --- /dev/null +++ b/Pods/Headers/OCMock/OCObserverMockObject.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCObserverMockObject.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCPartialMockObject.h b/Pods/Headers/OCMock/OCPartialMockObject.h new file mode 120000 index 0000000..d497494 --- /dev/null +++ b/Pods/Headers/OCMock/OCPartialMockObject.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCPartialMockObject.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCPartialMockRecorder.h b/Pods/Headers/OCMock/OCPartialMockRecorder.h new file mode 120000 index 0000000..87348dc --- /dev/null +++ b/Pods/Headers/OCMock/OCPartialMockRecorder.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCPartialMockRecorder.h \ No newline at end of file diff --git a/Pods/Headers/OCMock/OCProtocolMockObject.h b/Pods/Headers/OCMock/OCProtocolMockObject.h new file mode 120000 index 0000000..8ef0e20 --- /dev/null +++ b/Pods/Headers/OCMock/OCProtocolMockObject.h @@ -0,0 +1 @@ +../../OCMock/Source/OCMock/OCProtocolMockObject.h \ No newline at end of file diff --git a/Pods/Headers/VLBFoundation/VLBMacros.h b/Pods/Headers/VLBFoundation/VLBMacros.h new file mode 120000 index 0000000..0ea9ebb --- /dev/null +++ b/Pods/Headers/VLBFoundation/VLBMacros.h @@ -0,0 +1 @@ +../../VLBFoundation/VLBFoundation/VLBMacros.h \ No newline at end of file diff --git a/Pods/Kiwi/Classes/KWAfterAllNode.h b/Pods/Kiwi/Classes/KWAfterAllNode.h new file mode 100644 index 0000000..c7af7ca --- /dev/null +++ b/Pods/Kiwi/Classes/KWAfterAllNode.h @@ -0,0 +1,18 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWBlockNode.h" +#import "KWExampleNode.h" + +@interface KWAfterAllNode : KWBlockNode + +#pragma mark - +#pragma mark Initializing + ++ (id)afterAllNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock; + +@end diff --git a/Pods/Kiwi/Classes/KWAfterAllNode.m b/Pods/Kiwi/Classes/KWAfterAllNode.m new file mode 100644 index 0000000..099de2e --- /dev/null +++ b/Pods/Kiwi/Classes/KWAfterAllNode.m @@ -0,0 +1,26 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWAfterAllNode.h" +#import "KWExampleNodeVisitor.h" + +@implementation KWAfterAllNode + +#pragma mark - +#pragma mark Initializing + ++ (id)afterAllNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock { + return [[[self alloc] initWithCallSite:aCallSite description:nil block:aBlock] autorelease]; +} + +#pragma mark - +#pragma mark Accepting Visitors + +- (void)acceptExampleNodeVisitor:(id)aVisitor { + [aVisitor visitAfterAllNode:self]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWAfterEachNode.h b/Pods/Kiwi/Classes/KWAfterEachNode.h new file mode 100644 index 0000000..4cc9ada --- /dev/null +++ b/Pods/Kiwi/Classes/KWAfterEachNode.h @@ -0,0 +1,18 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWBlockNode.h" +#import "KWExampleNode.h" + +@interface KWAfterEachNode : KWBlockNode + +#pragma mark - +#pragma mark Initializing + ++ (id)afterEachNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock; + +@end diff --git a/Pods/Kiwi/Classes/KWAfterEachNode.m b/Pods/Kiwi/Classes/KWAfterEachNode.m new file mode 100644 index 0000000..76d30fa --- /dev/null +++ b/Pods/Kiwi/Classes/KWAfterEachNode.m @@ -0,0 +1,26 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWAfterEachNode.h" +#import "KWExampleNodeVisitor.h" + +@implementation KWAfterEachNode + +#pragma mark - +#pragma mark Initializing + ++ (id)afterEachNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock { + return [[[self alloc] initWithCallSite:aCallSite description:nil block:aBlock] autorelease]; +} + +#pragma mark - +#pragma mark Accepting Visitors + +- (void)acceptExampleNodeVisitor:(id)aVisitor { + [aVisitor visitAfterEachNode:self]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWAny.h b/Pods/Kiwi/Classes/KWAny.h new file mode 100644 index 0000000..d997eca --- /dev/null +++ b/Pods/Kiwi/Classes/KWAny.h @@ -0,0 +1,18 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +// KWAny exists to determine arguments in a message pattern that should +// match any value. Used for pointers as well as for scalar values. +@interface KWAny : NSObject + +#pragma mark - +#pragma mark Initializing + ++ (id)any; + +@end diff --git a/Pods/Kiwi/Classes/KWAny.m b/Pods/Kiwi/Classes/KWAny.m new file mode 100644 index 0000000..6dbf099 --- /dev/null +++ b/Pods/Kiwi/Classes/KWAny.m @@ -0,0 +1,47 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWAny.h" + +@implementation KWAny + +#pragma mark - +#pragma mark Initializing + +static KWAny *sharedAny = nil; + ++ (id)any { + if (sharedAny == nil) { + sharedAny = [[super allocWithZone:nil] init]; + } + + return sharedAny; +} + ++ (id)allocWithZone:(NSZone *)zone { + return [[self any] retain]; +} + +- (id)copyWithZone:(NSZone *)zone { + return self; +} + +- (id)retain { + return self; +} + +- (NSUInteger)retainCount { + return NSUIntegerMax; +} + +- (oneway void)release { +} + +- (id)autorelease { + return self; +} + +@end diff --git a/Pods/Kiwi/Classes/KWAsyncVerifier.h b/Pods/Kiwi/Classes/KWAsyncVerifier.h new file mode 100644 index 0000000..5a5b8c2 --- /dev/null +++ b/Pods/Kiwi/Classes/KWAsyncVerifier.h @@ -0,0 +1,35 @@ +// +// KWAsyncVerifier.h +// iOSFalconCore +// +// Created by Luke Redpath on 13/01/2011. +// Copyright 2011 LJR Software Limited. All rights reserved. +// + +#import +#import "KWMatchVerifier.h" +#import "KWProbe.h" + +#define kKW_DEFAULT_PROBE_TIMEOUT 1.0 + +@class KWAsyncMatcherProbe; + +@interface KWAsyncVerifier : KWMatchVerifier +{ + NSTimeInterval timeout; +} +@property (nonatomic, assign) NSTimeInterval timeout; + ++ (id)asyncVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id)aReporter probeTimeout:(NSTimeInterval)probeTimeout; +- (void)verifyWithProbe:(KWAsyncMatcherProbe *)aProbe; +@end + +@interface KWAsyncMatcherProbe : NSObject +{ + id matcher; + BOOL matchResult; +} +@property (nonatomic, readonly) id matcher; + +- (id)initWithMatcher:(id)aMatcher; +@end diff --git a/Pods/Kiwi/Classes/KWAsyncVerifier.m b/Pods/Kiwi/Classes/KWAsyncVerifier.m new file mode 100644 index 0000000..c1548b3 --- /dev/null +++ b/Pods/Kiwi/Classes/KWAsyncVerifier.m @@ -0,0 +1,99 @@ +// +// KWAsyncVerifier.m +// iOSFalconCore +// +// Created by Luke Redpath on 13/01/2011. +// Copyright 2011 LJR Software Limited. All rights reserved. +// + +#import "KWAsyncVerifier.h" +#import "KWFailure.h" +#import "KWMatching.h" +#import "KWReporting.h" +#import "KWProbePoller.h" + +@implementation KWAsyncVerifier + +@synthesize timeout; + ++ (id)asyncVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id)aReporter probeTimeout:(NSTimeInterval)probeTimeout; +{ + KWAsyncVerifier *verifier = [[self alloc] initWithExpectationType:anExpectationType callSite:aCallSite matcherFactory:aMatcherFactory reporter:aReporter]; + verifier.timeout = probeTimeout; + return [verifier autorelease]; +} + +- (id)initWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id)aReporter { + if ((self = [super initWithExpectationType:anExpectationType callSite:aCallSite matcherFactory:aMatcherFactory reporter:aReporter])) { + self.timeout = kKW_DEFAULT_PROBE_TIMEOUT; + } + return self; +} + +- (void)verifyWithProbe:(KWAsyncMatcherProbe *)aProbe { + @try { + KWProbePoller *poller = [[KWProbePoller alloc] initWithTimeout:self.timeout delay:kKW_DEFAULT_PROBE_DELAY]; + + if (![poller check:aProbe]) { + if (self.expectationType == KWExpectationTypeShould) { + NSString *message = [aProbe.matcher failureMessageForShould]; + KWFailure *failure = [KWFailure failureWithCallSite:self.callSite message:message]; + [self.reporter reportFailure:failure]; + } else if (self.expectationType == KWExpectationTypeShouldNot) { + NSString *message = [aProbe.matcher failureMessageForShouldNot]; + KWFailure *failure = [KWFailure failureWithCallSite:self.callSite message:message]; + [self.reporter reportFailure:failure]; + } else if (self.expectationType == KWExpectationTypeMaybe) { + // don't do anything + } + } + [poller release]; + + } @catch (NSException *exception) { + KWFailure *failure = [KWFailure failureWithCallSite:self.callSite message:[exception description]]; + [self.reporter reportFailure:failure]; + } +} + +- (void)verifyWithMatcher:(id)aMatcher { + KWAsyncMatcherProbe *probe = [[[KWAsyncMatcherProbe alloc] initWithMatcher:aMatcher] autorelease]; + [self verifyWithProbe:probe]; +} + +@end + +@implementation KWAsyncMatcherProbe + +@synthesize matcher; + +- (id)initWithMatcher:(id)aMatcher; +{ + if ((self = [super init])) { + matcher = [aMatcher retain]; + + // make sure the matcher knows we are going to evaluate it multiple times + if ([aMatcher respondsToSelector:@selector(willEvaluateMultipleTimes)]) { + [aMatcher setWillEvaluateMultipleTimes:YES]; + } + } + return self; +} + +- (void)dealloc +{ + [matcher release]; + [super dealloc]; +} + +- (BOOL)isSatisfied; +{ + return matchResult; +} + +- (void)sample; +{ + matchResult = [matcher evaluate]; +} + +@end + diff --git a/Pods/Kiwi/Classes/KWBeBetweenMatcher.h b/Pods/Kiwi/Classes/KWBeBetweenMatcher.h new file mode 100644 index 0000000..c3bdc7c --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeBetweenMatcher.h @@ -0,0 +1,23 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWBeBetweenMatcher : KWMatcher { +@private + id lowerEndpoint; + id upperEndpoint; +} + +#pragma mark - +#pragma mark Configuring Matchers + +// TODO: 'and' below is a reserved word in C++ +- (void)beBetween:(id)aLowerEndpoint and:(id)anUpperEndpoint; +- (void)beInTheIntervalFrom:(id)aLowerEndpoint to:(id)anUpperEndpoint; + +@end diff --git a/Pods/Kiwi/Classes/KWBeBetweenMatcher.m b/Pods/Kiwi/Classes/KWBeBetweenMatcher.m new file mode 100644 index 0000000..1105ae3 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeBetweenMatcher.m @@ -0,0 +1,84 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBeBetweenMatcher.h" +#import "KWFormatter.h" + +@interface KWBeBetweenMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite, retain) id lowerEndpoint; +@property (nonatomic, readwrite, retain) id upperEndpoint; + +@end + +@implementation KWBeBetweenMatcher + +#pragma mark - +#pragma mark Initializing + +- (void)dealloc { + [lowerEndpoint release]; + [upperEndpoint release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize lowerEndpoint; +@synthesize upperEndpoint; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"beBetween:and:", @"beInTheIntervalFrom:to:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + if (![self.subject respondsToSelector:@selector(compare:)]) + [NSException raise:@"KWMatcherException" format:@"subject does not respond to -compare:"]; + + NSComparisonResult lowerResult = [self.subject compare:self.lowerEndpoint]; + NSComparisonResult upperResult = [self.subject compare:self.upperEndpoint]; + return (lowerResult == NSOrderedDescending || lowerResult == NSOrderedSame) && + (upperResult == NSOrderedAscending || upperResult == NSOrderedSame); +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to be in the interval [%@, %@], got %@", + [KWFormatter formatObject:self.lowerEndpoint], + [KWFormatter formatObject:self.upperEndpoint], + [KWFormatter formatObject:self.subject]]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"be between %@ and %@", self.lowerEndpoint, self.upperEndpoint]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beBetween:(id)aLowerEndpoint and:(id)anUpperEndpoint { + [self beInTheIntervalFrom:aLowerEndpoint to:anUpperEndpoint]; +} + +- (void)beInTheIntervalFrom:(id)aLowerEndpoint to:(id)anUpperEndpoint { + self.lowerEndpoint = aLowerEndpoint; + self.upperEndpoint = anUpperEndpoint; +} + +@end diff --git a/Pods/Kiwi/Classes/KWBeEmptyMatcher.h b/Pods/Kiwi/Classes/KWBeEmptyMatcher.h new file mode 100644 index 0000000..ee3537b --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeEmptyMatcher.h @@ -0,0 +1,20 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWBeEmptyMatcher : KWMatcher { +@private + NSUInteger count; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beEmpty; + +@end diff --git a/Pods/Kiwi/Classes/KWBeEmptyMatcher.m b/Pods/Kiwi/Classes/KWBeEmptyMatcher.m new file mode 100644 index 0000000..471287e --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeEmptyMatcher.m @@ -0,0 +1,79 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBeEmptyMatcher.h" +#import "KWFormatter.h" + +@interface KWBeEmptyMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite) NSUInteger count; + +@end + +@implementation KWBeEmptyMatcher + +#pragma mark - +#pragma mark Properties + +@synthesize count; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"beEmpty"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + if ([self.subject respondsToSelector:@selector(count)]) { + self.count = [self.subject count]; + return self.count == 0; + } + else if ([self.subject respondsToSelector:@selector(length)]) { + self.count = [self.subject length]; + return self.count == 0; + } + + [NSException raise:@"KWMatcherException" format:@"subject does not respond to -count or -length"]; + return NO; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)countPhrase { + if (self.count == 1) + return @"1 item"; + else + return [NSString stringWithFormat:@"%u items", (unsigned)self.count]; +} + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to be empty, got %@", [self countPhrase]]; +} + +- (NSString *)failureMessageForShouldNot { + return @"expected subject not to be empty"; +} + +- (NSString *)description +{ + return @"be empty"; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beEmpty { +} + +@end diff --git a/Pods/Kiwi/Classes/KWBeIdenticalToMatcher.h b/Pods/Kiwi/Classes/KWBeIdenticalToMatcher.h new file mode 100644 index 0000000..b2c1705 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeIdenticalToMatcher.h @@ -0,0 +1,20 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWBeIdenticalToMatcher : KWMatcher { +@private + id otherSubject; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beIdenticalTo:(id)anObject; + +@end diff --git a/Pods/Kiwi/Classes/KWBeIdenticalToMatcher.m b/Pods/Kiwi/Classes/KWBeIdenticalToMatcher.m new file mode 100644 index 0000000..2a736b4 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeIdenticalToMatcher.m @@ -0,0 +1,77 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBeIdenticalToMatcher.h" +#import "KWFormatter.h" + +@interface KWBeIdenticalToMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite, retain) id otherSubject; + +@end + +@implementation KWBeIdenticalToMatcher + +#pragma mark - +#pragma mark Initializing + +- (void)dealloc { + [otherSubject release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize otherSubject; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"beIdenticalTo:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + return self.subject == self.otherSubject; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to be identical to %@ (%p), got %@ (%p)", + [KWFormatter formatObject:self.otherSubject], + self.otherSubject, + [KWFormatter formatObject:self.subject], + self.subject]; +} + +- (NSString *)failureMessageForShouldNot { + return [NSString stringWithFormat:@"expected subject not to be identical to %@ (%p)", + [KWFormatter formatObject:self.otherSubject], + self.otherSubject]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"be identical to %@", self.otherSubject]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beIdenticalTo:(id)anObject { + self.otherSubject = anObject; +} + +@end diff --git a/Pods/Kiwi/Classes/KWBeKindOfClassMatcher.h b/Pods/Kiwi/Classes/KWBeKindOfClassMatcher.h new file mode 100644 index 0000000..c5000e6 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeKindOfClassMatcher.h @@ -0,0 +1,20 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWBeKindOfClassMatcher : KWMatcher { +@private + Class targetClass; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beKindOfClass:(Class)aClass; + +@end diff --git a/Pods/Kiwi/Classes/KWBeKindOfClassMatcher.m b/Pods/Kiwi/Classes/KWBeKindOfClassMatcher.m new file mode 100644 index 0000000..6f8d960 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeKindOfClassMatcher.m @@ -0,0 +1,60 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBeKindOfClassMatcher.h" +#import "KWFormatter.h" + +@interface KWBeKindOfClassMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite, assign) Class targetClass; + +@end + +@implementation KWBeKindOfClassMatcher + +#pragma mark - +#pragma mark Properties + +@synthesize targetClass; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"beKindOfClass:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + return [self.subject isKindOfClass:self.targetClass]; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to be kind of %@", + NSStringFromClass(self.targetClass)]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"be kind of %@", NSStringFromClass(self.targetClass)]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beKindOfClass:(Class)aClass { + self.targetClass = aClass; +} + +@end diff --git a/Pods/Kiwi/Classes/KWBeMemberOfClassMatcher.h b/Pods/Kiwi/Classes/KWBeMemberOfClassMatcher.h new file mode 100644 index 0000000..de8958a --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeMemberOfClassMatcher.h @@ -0,0 +1,20 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWBeMemberOfClassMatcher : KWMatcher { +@private + Class targetClass; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beMemberOfClass:(Class)aClass; + +@end diff --git a/Pods/Kiwi/Classes/KWBeMemberOfClassMatcher.m b/Pods/Kiwi/Classes/KWBeMemberOfClassMatcher.m new file mode 100644 index 0000000..3224b3f --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeMemberOfClassMatcher.m @@ -0,0 +1,61 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBeMemberOfClassMatcher.h" +#import "KWFormatter.h" + +@interface KWBeMemberOfClassMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite, assign) Class targetClass; + +@end + +@implementation KWBeMemberOfClassMatcher + +#pragma mark - +#pragma mark Properties + +@synthesize targetClass; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"beMemberOfClass:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + return [self.subject isMemberOfClass:self.targetClass]; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to be member of %@", + NSStringFromClass(self.targetClass)]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"be member of %@", + NSStringFromClass(self.targetClass)]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beMemberOfClass:(Class)aClass { + self.targetClass = aClass; +} + +@end diff --git a/Pods/Kiwi/Classes/KWBeNilMatcher.h b/Pods/Kiwi/Classes/KWBeNilMatcher.h new file mode 100644 index 0000000..74114b8 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeNilMatcher.h @@ -0,0 +1,16 @@ +// +// KWBeNilMatcher.h +// iOSFalconCore +// +// Created by Luke Redpath on 14/01/2011. +// Copyright 2011 LJR Software Limited. All rights reserved. +// + +#import +#import "KWMatcher.h" + +@interface KWBeNilMatcher : KWMatcher { + +} +- (void)beNil; +@end diff --git a/Pods/Kiwi/Classes/KWBeNilMatcher.m b/Pods/Kiwi/Classes/KWBeNilMatcher.m new file mode 100644 index 0000000..ceeea43 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeNilMatcher.m @@ -0,0 +1,48 @@ +// +// KWBeNilMatcher.m +// iOSFalconCore +// +// Created by Luke Redpath on 14/01/2011. +// Copyright 2011 LJR Software Limited. All rights reserved. +// + +#import "KWBeNilMatcher.h" +#import "KWFormatter.h" + +@implementation KWBeNilMatcher + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"beNil"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + return (BOOL)(self.subject == nil); +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to be nil, got %@", + [KWFormatter formatObject:self.subject]]; +} + +- (NSString *)failureMessageForShouldNot { + return [NSString stringWithFormat:@"expected %@ not to be nil", + [KWFormatter formatObject:self.subject]]; +} + +- (void)beNil {} + +- (NSString *)description +{ + return @"be nil"; +} + +@end diff --git a/Pods/Kiwi/Classes/KWBeNonNilMatcher.h b/Pods/Kiwi/Classes/KWBeNonNilMatcher.h new file mode 100644 index 0000000..83a7ba0 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeNonNilMatcher.h @@ -0,0 +1,16 @@ +// +// KWBeNotNilMatcher.h +// Kiwi +// +// Created by Luke Redpath on 17/01/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import +#import "KWMatcher.h" + +@interface KWBeNonNilMatcher : KWMatcher { + +} +- (void)beNonNil; +@end diff --git a/Pods/Kiwi/Classes/KWBeNonNilMatcher.m b/Pods/Kiwi/Classes/KWBeNonNilMatcher.m new file mode 100644 index 0000000..845a80d --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeNonNilMatcher.m @@ -0,0 +1,48 @@ +// +// KWBeNotNilMatcher.m +// Kiwi +// +// Created by Luke Redpath on 17/01/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import "KWBeNonNilMatcher.h" +#import "KWFormatter.h" + +@implementation KWBeNonNilMatcher + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"beNonNil"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + return (BOOL)(self.subject != nil); +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to be non-nil, got %@", + [KWFormatter formatObject:self.subject]]; +} + +- (NSString *)failureMessageForShouldNot { + return [NSString stringWithFormat:@"expected %@ not to be non-nil", + [KWFormatter formatObject:self.subject]]; +} + +- (NSString *)description +{ + return @"be non-nil"; +} + +- (void)beNonNil {} + +@end diff --git a/Pods/Kiwi/Classes/KWBeSubclassOfClassMatcher.h b/Pods/Kiwi/Classes/KWBeSubclassOfClassMatcher.h new file mode 100644 index 0000000..d170f73 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeSubclassOfClassMatcher.h @@ -0,0 +1,20 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWBeSubclassOfClassMatcher : KWMatcher { +@private + Class targetClass; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beSubclassOfClass:(Class)aClass; + +@end diff --git a/Pods/Kiwi/Classes/KWBeSubclassOfClassMatcher.m b/Pods/Kiwi/Classes/KWBeSubclassOfClassMatcher.m new file mode 100644 index 0000000..bf7ed6a --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeSubclassOfClassMatcher.m @@ -0,0 +1,61 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBeSubclassOfClassMatcher.h" +#import "KWFormatter.h" + +@interface KWBeSubclassOfClassMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite, assign) Class targetClass; + +@end + +@implementation KWBeSubclassOfClassMatcher + +#pragma mark - +#pragma mark Properties + +@synthesize targetClass; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"beSubclassOfClass:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + return [self.subject isSubclassOfClass:self.targetClass]; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to be subclass of %@", + NSStringFromClass(self.targetClass)]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"be member of %@", + NSStringFromClass(self.targetClass)]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beSubclassOfClass:(Class)aClass { + self.targetClass = aClass; +} + +@end diff --git a/Pods/Kiwi/Classes/KWBeTrueMatcher.h b/Pods/Kiwi/Classes/KWBeTrueMatcher.h new file mode 100644 index 0000000..aa589d5 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeTrueMatcher.h @@ -0,0 +1,23 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWBeTrueMatcher : KWMatcher { +@private + BOOL expectedValue; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beTrue; +- (void)beFalse; +- (void)beYes; +- (void)beNo; + +@end diff --git a/Pods/Kiwi/Classes/KWBeTrueMatcher.m b/Pods/Kiwi/Classes/KWBeTrueMatcher.m new file mode 100644 index 0000000..4af00da --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeTrueMatcher.m @@ -0,0 +1,77 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBeTrueMatcher.h" + +@interface KWBeTrueMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite) BOOL expectedValue; + +@end + +@implementation KWBeTrueMatcher + +#pragma mark - +#pragma mark Properties + +@synthesize expectedValue; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"beTrue", @"beFalse", @"beYes", @"beNo"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + if (![self.subject respondsToSelector:@selector(boolValue)]) + [NSException raise:@"KWMatcherException" format:@"subject does not respond to -boolValue"]; + + return [self.subject boolValue] == self.expectedValue; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to be %@", + expectedValue ? @"true" : @"false"]; +} + +- (NSString *)description +{ + if (self.expectedValue == YES) { + return @"be true"; + } + return @"be false"; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beTrue { + self.expectedValue = YES; +} + +- (void)beFalse { + self.expectedValue = NO; +} + +- (void)beYes { + self.expectedValue = YES; +} + +- (void)beNo { + self.expectedValue = NO; +} + +@end diff --git a/Pods/Kiwi/Classes/KWBeWithinMatcher.h b/Pods/Kiwi/Classes/KWBeWithinMatcher.h new file mode 100644 index 0000000..7493c42 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeWithinMatcher.h @@ -0,0 +1,22 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWBeWithinMatcher : KWMatcher { +@private + id distance; + id otherValue; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beWithin:(id)aDistance of:(id)aValue; +- (void)equal:(double)aValue withDelta:(double)aDelta; + +@end diff --git a/Pods/Kiwi/Classes/KWBeWithinMatcher.m b/Pods/Kiwi/Classes/KWBeWithinMatcher.m new file mode 100644 index 0000000..21e09f4 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeWithinMatcher.m @@ -0,0 +1,114 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBeWithinMatcher.h" +#import "KWFormatter.h" +#import "KWObjCUtilities.h" +#import "KWValue.h" + +@interface KWBeWithinMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite, retain) id distance; +@property (nonatomic, readwrite, retain) id otherValue; + +@end + +@implementation KWBeWithinMatcher + +#pragma mark - +#pragma mark Initializing + +- (void)dealloc { + [distance release]; + [otherValue release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize distance; +@synthesize otherValue; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"beWithin:of:", @"equal:withDelta:"]; +} + +#pragma mark - +#pragma mark Matching + +// Evaluation is done by getting the underlying values as the widest data +// types available. + +- (BOOL)evaluateForFloatingPoint { + double firstValue = [self.subject doubleValue]; + double secondValue = [self.otherValue doubleValue]; + double theDistance = [self.distance doubleValue]; + double absoluteDifference = firstValue > secondValue ? firstValue - secondValue : secondValue - firstValue; + return absoluteDifference <= theDistance; +} + +- (BOOL)evaluateForUnsignedIntegral { + unsigned long long firstValue = [self.subject unsignedLongLongValue]; + unsigned long long secondValue = [self.otherValue unsignedLongLongValue]; + unsigned long long theDistance = [self.distance unsignedLongLongValue]; + unsigned long long absoluteDifference = firstValue > secondValue ? firstValue - secondValue : secondValue - firstValue; + return absoluteDifference <= theDistance; +} + +- (BOOL)evaluateForSignedIntegral { + long long firstValue = [self.subject longLongValue]; + long long secondValue = [self.otherValue longLongValue]; + long long theDistance = [self.distance longLongValue]; + long long absoluteDifference = firstValue > secondValue ? firstValue - secondValue : secondValue - firstValue; + return absoluteDifference <= theDistance; +} + +- (BOOL)evaluate { + const char *objCType = [self.subject objCType]; + + if (KWObjCTypeIsFloatingPoint(objCType)) + return [self evaluateForFloatingPoint]; + else if (KWObjCTypeIsUnsignedIntegral(objCType)) + return [self evaluateForUnsignedIntegral]; + else + return [self evaluateForSignedIntegral]; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to be within %@ of %@, got %@", + [KWFormatter formatObject:self.distance], + [KWFormatter formatObject:self.otherValue], + [KWFormatter formatObject:self.subject]]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"be within %@ of %@", self.distance, self.otherValue]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beWithin:(id)aDistance of:(id)aValue { + self.distance = aDistance; + self.otherValue = aValue; +} + +- (void)equal:(double)aValue withDelta:(double)aDelta { + [self beWithin:[KWValue valueWithDouble:aDelta] of:[KWValue valueWithDouble:aValue]]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWBeZeroMatcher.h b/Pods/Kiwi/Classes/KWBeZeroMatcher.h new file mode 100644 index 0000000..a2bae5e --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeZeroMatcher.h @@ -0,0 +1,17 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWBeZeroMatcher : KWMatcher + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beZero; + +@end diff --git a/Pods/Kiwi/Classes/KWBeZeroMatcher.m b/Pods/Kiwi/Classes/KWBeZeroMatcher.m new file mode 100644 index 0000000..65c9bb0 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeZeroMatcher.m @@ -0,0 +1,48 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBeZeroMatcher.h" +#import "KWFormatter.h" +#import "KWValue.h" + +@implementation KWBeZeroMatcher + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"beZero"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + if (![self.subject respondsToSelector:@selector(boolValue)]) + [NSException raise:@"KWMatcherException" format:@"subject does not respond to -numberValue"]; + + return [[self.subject numberValue] isEqualToNumber:@0]; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to be zero, got %@", + [KWFormatter formatObject:self.subject]]; +} + +- (NSString *)failureMessageForShouldNot { + return [NSString stringWithFormat:@"expected subject not to be zero"]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beZero { +} + +@end diff --git a/Pods/Kiwi/Classes/KWBeforeAllNode.h b/Pods/Kiwi/Classes/KWBeforeAllNode.h new file mode 100644 index 0000000..e1063fd --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeforeAllNode.h @@ -0,0 +1,18 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWBlockNode.h" +#import "KWExampleNode.h" + +@interface KWBeforeAllNode : KWBlockNode + +#pragma mark - +#pragma mark Initializing + ++ (id)beforeAllNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock; + +@end diff --git a/Pods/Kiwi/Classes/KWBeforeAllNode.m b/Pods/Kiwi/Classes/KWBeforeAllNode.m new file mode 100644 index 0000000..a09c333 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeforeAllNode.m @@ -0,0 +1,26 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBeforeAllNode.h" +#import "KWExampleNodeVisitor.h" + +@implementation KWBeforeAllNode + +#pragma mark - +#pragma mark Initializing + ++ (id)beforeAllNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock { + return [[[self alloc] initWithCallSite:aCallSite description:nil block:aBlock] autorelease]; +} + +#pragma mark - +#pragma mark Accepting Visitors + +- (void)acceptExampleNodeVisitor:(id)aVisitor { + [aVisitor visitBeforeAllNode:self]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWBeforeEachNode.h b/Pods/Kiwi/Classes/KWBeforeEachNode.h new file mode 100644 index 0000000..aaae98d --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeforeEachNode.h @@ -0,0 +1,18 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWBlockNode.h" +#import "KWExampleNode.h" + +@interface KWBeforeEachNode : KWBlockNode + +#pragma mark - +#pragma mark Initializing + ++ (id)beforeEachNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock; + +@end diff --git a/Pods/Kiwi/Classes/KWBeforeEachNode.m b/Pods/Kiwi/Classes/KWBeforeEachNode.m new file mode 100644 index 0000000..c779255 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBeforeEachNode.m @@ -0,0 +1,26 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBeforeEachNode.h" +#import "KWExampleNodeVisitor.h" + +@implementation KWBeforeEachNode + +#pragma mark - +#pragma mark Initializing + ++ (id)beforeEachNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock { + return [[[self alloc] initWithCallSite:aCallSite description:nil block:aBlock] autorelease]; +} + +#pragma mark - +#pragma mark Accepting Visitors + +- (void)acceptExampleNodeVisitor:(id)aVisitor { + [aVisitor visitBeforeEachNode:self]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWBlock.h b/Pods/Kiwi/Classes/KWBlock.h new file mode 100644 index 0000000..cf259ba --- /dev/null +++ b/Pods/Kiwi/Classes/KWBlock.h @@ -0,0 +1,33 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +typedef void (^KWVoidBlock)(void); + +@interface KWBlock : NSObject { +@private + KWVoidBlock block; +} + +#pragma mark - +#pragma mark Initializing +- (id)initWithBlock:(KWVoidBlock)aBlock; + ++ (id)blockWithBlock:(KWVoidBlock)aBlock; + +#pragma mark - +#pragma mark Calling Blocks + +- (void)call; + +@end + +#pragma mark - +#pragma mark Creating Blocks + +KWBlock *theBlock(KWVoidBlock aBlock); +KWBlock *lambda(KWVoidBlock aBlock); diff --git a/Pods/Kiwi/Classes/KWBlock.m b/Pods/Kiwi/Classes/KWBlock.m new file mode 100644 index 0000000..82f91a7 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBlock.m @@ -0,0 +1,63 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBlock.h" + +@interface KWBlock() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly, assign) KWVoidBlock block; + +@end + +@implementation KWBlock + +#pragma mark - +#pragma mark Initializing + +- (id)initWithBlock:(KWVoidBlock)aBlock { + if ((self = [super init])) { + block = Block_copy(aBlock); + } + + return self; +} + ++ (id)blockWithBlock:(KWVoidBlock)aBlock { + return [[[self alloc] initWithBlock:aBlock] autorelease]; +} + +- (void)dealloc { + Block_release(block); + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize block; + +#pragma mark - +#pragma mark Calling Blocks + +- (void)call { + block(); +} + +@end + +#pragma mark - +#pragma mark Creating Blocks + +KWBlock *theBlock(KWVoidBlock aBlock) { + return lambda(aBlock); +} + +KWBlock *lambda(KWVoidBlock aBlock) { + return [KWBlock blockWithBlock:aBlock]; +} diff --git a/Pods/Kiwi/Classes/KWBlockNode.h b/Pods/Kiwi/Classes/KWBlockNode.h new file mode 100644 index 0000000..b5142c3 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBlockNode.h @@ -0,0 +1,44 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWBlock.h" + +@class KWCallSite; + +@interface KWBlockNode : NSObject { +@private + KWCallSite *callSite; + NSString *description; + KWVoidBlock block; +} + +#pragma mark - +#pragma mark Initializing + +- (id)initWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aDescription block:(KWVoidBlock)aBlock; + +#pragma mark - +#pragma mark Getting Call Sites + +@property (nonatomic, readonly) KWCallSite *callSite; + +#pragma mark - +#pragma mark Getting Descriptions + +@property (nonatomic, copy) NSString *description; + +#pragma mark - +#pragma mark Getting Blocks + +@property (nonatomic, readonly) KWVoidBlock block; + +#pragma mark - +#pragma mark Performing blocks + +- (void)performBlock; + +@end diff --git a/Pods/Kiwi/Classes/KWBlockNode.m b/Pods/Kiwi/Classes/KWBlockNode.m new file mode 100644 index 0000000..77617d7 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBlockNode.m @@ -0,0 +1,53 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBlockNode.h" + +@implementation KWBlockNode + +@synthesize description = _description; + +#pragma mark - +#pragma mark Initializing + +- (id)initWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aDescription block:(KWVoidBlock)aBlock{ + if ((self = [super init])) { + callSite = [aCallSite retain]; + _description = [aDescription copy]; + + if (aBlock != nil) + block = Block_copy(aBlock); + } + + return self; +} + +- (void)dealloc { + [callSite release]; + [description release]; + + if (block != nil) + Block_release(block); + + [super dealloc]; +} + +- (void)performBlock +{ + if (block != nil) { block(); } +} + +#pragma mark - +#pragma mark Getting Call Sites + +@synthesize callSite; + +#pragma mark - +#pragma mark Accepting Visitors + +@synthesize block; + +@end diff --git a/Pods/Kiwi/Classes/KWBlockRaiseMatcher.h b/Pods/Kiwi/Classes/KWBlockRaiseMatcher.h new file mode 100644 index 0000000..3750137 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBlockRaiseMatcher.h @@ -0,0 +1,24 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWBlockRaiseMatcher : KWMatcher { +@private + NSException *exception; + NSException *actualException; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)raise; +- (void)raiseWithName:(NSString *)aName; +- (void)raiseWithReason:(NSString *)aReason; +- (void)raiseWithName:(NSString *)aName reason:(NSString *)aReason; + +@end diff --git a/Pods/Kiwi/Classes/KWBlockRaiseMatcher.m b/Pods/Kiwi/Classes/KWBlockRaiseMatcher.m new file mode 100644 index 0000000..9d153c5 --- /dev/null +++ b/Pods/Kiwi/Classes/KWBlockRaiseMatcher.m @@ -0,0 +1,126 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWBlockRaiseMatcher.h" +#import "KWBlock.h" + +@interface KWBlockRaiseMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite, retain) NSException *exception; +@property (nonatomic, readwrite, retain) NSException *actualException; + +@end + +@implementation KWBlockRaiseMatcher + +#pragma mark - +#pragma mark Initializing + +- (void)dealloc { + [exception release]; + [actualException release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize exception; +@synthesize actualException; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"raise", + @"raiseWithName:", + @"raiseWithReason:", + @"raiseWithName:reason:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + if (![self.subject isKindOfClass:[KWBlock class]]) + [NSException raise:@"KWMatcherException" format:@"subject must be a KWBlock"]; + + @try { + [self.subject call]; + } @catch (NSException *anException) { + self.actualException = anException; + + if ([self.exception name] != nil && ![[self.exception name] isEqualToString:[anException name]]) + return NO; + + if ([self.exception reason] != nil && ![[self.exception reason] isEqualToString:[anException reason]]) + return NO; + + return YES; + } + + return NO; +} + +#pragma mark - +#pragma mark Getting Failure Messages + ++ (NSString *)exceptionPhraseWithException:(NSException *)anException { + if (anException == nil) + return @"nothing"; + + NSString *namePhrase = nil; + + if ([anException name] == nil) + namePhrase = @"exception"; + else + namePhrase = [anException name]; + + if ([anException reason] == nil) + return namePhrase; + + return [NSString stringWithFormat:@"%@ \"%@\"", namePhrase, [anException reason]]; +} + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected %@, but %@ raised", + [[self class] exceptionPhraseWithException:self.exception], + [[self class] exceptionPhraseWithException:self.actualException]]; +} + +- (NSString *)failureMessageForShouldNot { + return [NSString stringWithFormat:@"expected %@ not to be raised", + [[self class] exceptionPhraseWithException:self.actualException]]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)raise { + [self raiseWithName:nil reason:nil]; +} + +- (void)raiseWithName:(NSString *)aName { + [self raiseWithName:aName reason:nil]; +} + +- (void)raiseWithReason:(NSString *)aReason { + [self raiseWithName:nil reason:aReason]; +} + +- (void)raiseWithName:(NSString *)aName reason:(NSString *)aReason { + self.exception = [NSException exceptionWithName:aName reason:aReason userInfo:nil]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"raise %@", [[self class] exceptionPhraseWithException:self.exception]]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWCallSite.h b/Pods/Kiwi/Classes/KWCallSite.h new file mode 100644 index 0000000..899eef2 --- /dev/null +++ b/Pods/Kiwi/Classes/KWCallSite.h @@ -0,0 +1,33 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@interface KWCallSite : NSObject { +@private + NSString *filename; + NSUInteger lineNumber; +} + +#pragma mark - +#pragma mark Initializing + +- (id)initWithFilename:(NSString *)aFilename lineNumber:(NSUInteger)aLineNumber; + ++ (id)callSiteWithFilename:(NSString *)aFilename lineNumber:(NSUInteger)aLineNumber; + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly, copy) NSString *filename; +@property (nonatomic, readonly) NSUInteger lineNumber; + +#pragma mark - +#pragma mark Identifying and Comparing + +- (BOOL)isEqualToCallSite:(KWCallSite *)aCallSite; + +@end diff --git a/Pods/Kiwi/Classes/KWCallSite.m b/Pods/Kiwi/Classes/KWCallSite.m new file mode 100644 index 0000000..ee4eefe --- /dev/null +++ b/Pods/Kiwi/Classes/KWCallSite.m @@ -0,0 +1,56 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWCallSite.h" + +@implementation KWCallSite + +#pragma mark - +#pragma mark Initializing + +- (id)initWithFilename:(NSString *)aFilename lineNumber:(NSUInteger)aLineNumber { + if ((self = [super init])) { + filename = [aFilename copy]; + lineNumber = aLineNumber; + } + + return self; +} + ++ (id)callSiteWithFilename:(NSString *)aFilename lineNumber:(NSUInteger)aLineNumber { + return [[[self alloc] initWithFilename:aFilename lineNumber:aLineNumber] autorelease]; +} + +- (void)dealloc { + [filename release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Accessing Call Site Properties + +@synthesize filename; +@synthesize lineNumber; + +#pragma mark - +#pragma mark Identifying and Comparing + +- (NSUInteger)hash { + return [[NSString stringWithFormat:@"%@%u", self.filename, (unsigned)self.lineNumber] hash]; +} + +- (BOOL)isEqual:(id)anObject { + if (![anObject isKindOfClass:[KWCallSite class]]) + return NO; + + return [self isEqualToCallSite:anObject]; +} + +- (BOOL)isEqualToCallSite:(KWCallSite *)aCallSite { + return [self.filename isEqualToString:aCallSite.filename] && (self.lineNumber == aCallSite.lineNumber); +} + +@end diff --git a/Pods/Kiwi/Classes/KWCaptureSpy.h b/Pods/Kiwi/Classes/KWCaptureSpy.h new file mode 100644 index 0000000..9583bdf --- /dev/null +++ b/Pods/Kiwi/Classes/KWCaptureSpy.h @@ -0,0 +1,14 @@ +#import +#import "KWMock.h" +#import "KWMessageSpying.h" + +@interface KWCaptureSpy : NSObject { + BOOL _argumentCaptured; + id _argument; + NSUInteger _argumentIndex; +} + +- (id)initWithArgumentIndex:(NSUInteger)index; +@property(nonatomic, readonly, retain) id argument; + +@end diff --git a/Pods/Kiwi/Classes/KWCaptureSpy.m b/Pods/Kiwi/Classes/KWCaptureSpy.m new file mode 100644 index 0000000..23c3af7 --- /dev/null +++ b/Pods/Kiwi/Classes/KWCaptureSpy.m @@ -0,0 +1,49 @@ +#import "KWCaptureSpy.h" +#import "KWObjCUtilities.h" +#import "NSInvocation+KiwiAdditions.h" +#import "NSMethodSignature+KiwiAdditions.h" +#import "KWValue.h" + +@implementation KWCaptureSpy +@dynamic argument; + +- (id)initWithArgumentIndex:(NSUInteger)index { + if ((self = [super init])) { + _argumentIndex = index; + _argumentCaptured = NO; + } + return self; +} + +- (id)argument { + if (!_argumentCaptured) { + @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Argument requested has yet to be captured." userInfo:nil]; + } + return [[_argument retain] autorelease]; +} + +- (void)object:(id)anObject didReceiveInvocation:(NSInvocation *)anInvocation { + if (!_argumentCaptured) { + NSMethodSignature *signature = [anInvocation methodSignature]; + const char *objCType = [signature messageArgumentTypeAtIndex:_argumentIndex]; + if (KWObjCTypeIsObject(objCType)) { + id argument = nil; + [anInvocation getMessageArgument:&argument atIndex:_argumentIndex]; + if (KWObjCTypeIsBlock(objCType)) { + _argument = [argument copy]; + } else { + _argument = [argument retain]; + } + } else { + NSData *data = [anInvocation messageArgumentDataAtIndex:_argumentIndex]; + _argument = [[KWValue valueWithBytes:[data bytes] objCType:objCType] retain]; + } + _argumentCaptured = YES; + } +} + +- (void)dealloc { + [_argument release]; + [super dealloc]; +} +@end diff --git a/Pods/Kiwi/Classes/KWChangeMatcher.h b/Pods/Kiwi/Classes/KWChangeMatcher.h new file mode 100644 index 0000000..89d37d6 --- /dev/null +++ b/Pods/Kiwi/Classes/KWChangeMatcher.h @@ -0,0 +1,21 @@ +// +// KWChangeMatcher.h +// Kiwi +// +// Copyright (c) 2013 Eloy Durán . +// All rights reserved. +// + +#import "KWMatcher.h" + +typedef NSInteger (^KWChangeMatcherCountBlock)(); + +@interface KWChangeMatcher : KWMatcher + +// Expect _any_ change. +- (void)change:(KWChangeMatcherCountBlock)countBlock; + +// Expect changes by a specific amount. +- (void)change:(KWChangeMatcherCountBlock)countBlock by:(NSInteger)expectedDifference; + +@end diff --git a/Pods/Kiwi/Classes/KWChangeMatcher.m b/Pods/Kiwi/Classes/KWChangeMatcher.m new file mode 100644 index 0000000..321735c --- /dev/null +++ b/Pods/Kiwi/Classes/KWChangeMatcher.m @@ -0,0 +1,84 @@ +// +// KWChangeMatcher.m +// Kiwi +// +// Copyright (c) 2013 Eloy Durán . +// All rights reserved. +// + +#import "KWChangeMatcher.h" +#import "KWBlock.h" + +@interface KWChangeMatcher () +@property (nonatomic, copy) KWChangeMatcherCountBlock countBlock; +@property (nonatomic, assign) BOOL anyChange; +@property (nonatomic, assign) NSInteger expectedDifference, expectedTotal, actualTotal; +@end + +@implementation KWChangeMatcher + +@synthesize countBlock = _countBlock; +@synthesize anyChange = _anyChange; +@synthesize expectedDifference = _expectedDifference; +@synthesize expectedTotal = _expectedTotal; +@synthesize actualTotal = _actualTotal; + +- (void)dealloc { + Block_release(_countBlock); + [super dealloc]; +} + ++ (NSArray *)matcherStrings { + return @[@"change:by:", @"change:"]; +} + +- (NSString *)failureMessageForShould { + if (self.anyChange) { + return @"expected subject to change the count"; + } else { + return [NSString stringWithFormat:@"expected subject to change the count to %d, got %d", (int)self.expectedTotal, (int)self.actualTotal]; + } +} + +- (NSString *)failureMessageForShouldNot { + if (self.anyChange) { + return @"expected subject to not change the count"; + } else { + return [NSString stringWithFormat:@"expected subject not to change the count to %d", (int)self.actualTotal]; + } +} + +- (NSString *)description { + if (self.anyChange) { + return @"change count"; + } else { + return [NSString stringWithFormat:@"change count by %d", (int)self.expectedDifference]; + } +} + +- (BOOL)evaluate { + NSInteger before = self.countBlock(); + // Perform actual work, which is expected to change the result of countBlock. + [self.subject call]; + self.actualTotal = self.countBlock(); + + if (self.anyChange) { + return before != self.actualTotal; + } else { + self.expectedTotal = before + self.expectedDifference; + return self.expectedTotal == self.actualTotal; + } +} + +- (void)change:(KWChangeMatcherCountBlock)countBlock by:(NSInteger)expectedDifference { + self.anyChange = NO; + self.expectedDifference = expectedDifference; + self.countBlock = countBlock; +} + +- (void)change:(KWChangeMatcherCountBlock)countBlock { + self.anyChange = YES; + self.countBlock = countBlock; +} + +@end diff --git a/Pods/Kiwi/Classes/KWConformToProtocolMatcher.h b/Pods/Kiwi/Classes/KWConformToProtocolMatcher.h new file mode 100644 index 0000000..66a8e19 --- /dev/null +++ b/Pods/Kiwi/Classes/KWConformToProtocolMatcher.h @@ -0,0 +1,20 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWConformToProtocolMatcher : KWMatcher { +@private + Protocol *protocol; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)conformToProtocol:(Protocol *)aProtocol; + +@end diff --git a/Pods/Kiwi/Classes/KWConformToProtocolMatcher.m b/Pods/Kiwi/Classes/KWConformToProtocolMatcher.m new file mode 100644 index 0000000..3a0f1ba --- /dev/null +++ b/Pods/Kiwi/Classes/KWConformToProtocolMatcher.m @@ -0,0 +1,60 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWConformToProtocolMatcher.h" +#import "KWFormatter.h" + +@interface KWConformToProtocolMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite, assign) Protocol *protocol; + +@end + +@implementation KWConformToProtocolMatcher + +#pragma mark - +#pragma mark Properties + +@synthesize protocol; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"conformToProtocol:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + return [self.subject conformsToProtocol:self.protocol]; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to conform to %@ protocol", + NSStringFromProtocol(self.protocol)]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"conform to %@ protocol", NSStringFromProtocol(self.protocol)]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)conformToProtocol:(Protocol *)aProtocol { + self.protocol = aProtocol; +} + +@end diff --git a/Pods/Kiwi/Classes/KWContainMatcher.h b/Pods/Kiwi/Classes/KWContainMatcher.h new file mode 100644 index 0000000..90e8364 --- /dev/null +++ b/Pods/Kiwi/Classes/KWContainMatcher.h @@ -0,0 +1,31 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" +#import "KWMatchVerifier.h" + +@interface KWContainMatcher : KWMatcher { +@private + NSArray *objects; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)contain:(id)anObject; +- (void)containObjectsInArray:(NSArray *)anArray; + +@end + +@interface KWMatchVerifier(KWContainMatcherAdditions) + +#pragma mark - +#pragma mark Verifying + +- (void)containObjects:(id)firstObject, ... NS_REQUIRES_NIL_TERMINATION; + +@end diff --git a/Pods/Kiwi/Classes/KWContainMatcher.m b/Pods/Kiwi/Classes/KWContainMatcher.m new file mode 100644 index 0000000..a25fcf4 --- /dev/null +++ b/Pods/Kiwi/Classes/KWContainMatcher.m @@ -0,0 +1,110 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWContainMatcher.h" +#import "KWFormatter.h" +#import "KWGenericMatchingAdditions.h" + +@interface KWContainMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite, retain) id objects; + +@end + +@implementation KWContainMatcher + +#pragma mark - +#pragma mark Initializing + +- (void)dealloc { + [objects release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize objects; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"contain:", @"containObjectsInArray:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + if (![self.subject respondsToSelector:@selector(containsObjectEqualToOrMatching:)]) + [NSException raise:@"KWMatcherException" format:@"subject does not respond to -containsObjectEqualToOrMatching:"]; + + for (id object in self.objects) { + if (![self.subject containsObjectEqualToOrMatching:object]) + return NO; + } + + return YES; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)objectsPhrase { + if ([self.objects count] == 1) + return [KWFormatter formatObject:(self.objects)[0]]; + + return [NSString stringWithFormat:@"all of %@", [KWFormatter formatObject:self.objects]]; +} + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to contain %@", [self objectsPhrase]]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"contain %@", [self objectsPhrase]]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)contain:(id)anObject { + self.objects = @[anObject]; +} + +- (void)containObjectsInArray:(NSArray *)anArray { + self.objects = anArray; +} + +@end + +@implementation KWMatchVerifier(KWContainMatcherAdditions) + +#pragma mark - +#pragma mark Verifying + +- (void)containObjects:(id)firstObject, ... { + NSMutableArray *objects = [NSMutableArray array]; + + va_list argumentList; + va_start(argumentList, firstObject); + id object = firstObject; + + while (object != nil) { + [objects addObject:object]; + object = va_arg(argumentList, id); + } + + va_end(argumentList); + [(id)self containObjectsInArray:objects]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWContextNode.h b/Pods/Kiwi/Classes/KWContextNode.h new file mode 100644 index 0000000..d1b8e48 --- /dev/null +++ b/Pods/Kiwi/Classes/KWContextNode.h @@ -0,0 +1,73 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWExampleNode.h" + +@class KWAfterAllNode; +@class KWAfterEachNode; +@class KWBeforeAllNode; +@class KWBeforeEachNode; +@class KWCallSite; +@class KWItNode; +@class KWPendingNode; +@class KWRegisterMatchersNode; +@class KWExample; + +@interface KWContextNode : NSObject { +@private + KWContextNode *parentContext; + KWCallSite *callSite; + NSString *description; + KWRegisterMatchersNode *registerMatchersNode; + KWBeforeAllNode *beforeAllNode; + KWAfterAllNode *afterAllNode; + KWBeforeEachNode *beforeEachNode; + KWAfterEachNode *afterEachNode; + NSMutableArray *nodes; + BOOL performedExampleCount; +} + +#pragma mark - +#pragma mark Initializing + +- (id)initWithCallSite:(KWCallSite *)aCallSite parentContext:(KWContextNode *)node description:(NSString *)aDescription; + ++ (id)contextNodeWithCallSite:(KWCallSite *)aCallSite parentContext:(KWContextNode *)contextNode description:(NSString *)aDescription; + +#pragma mark - +#pragma mark Getting Call Sites + +@property (nonatomic, readonly) KWCallSite *callSite; + +#pragma mark - +#pragma mark Getting Descriptions + +@property (nonatomic, readonly) NSString *description; + +#pragma mark - +#pragma mark Managing Nodes + +@property (nonatomic, readwrite, retain) KWRegisterMatchersNode *registerMatchersNode; +@property (nonatomic, readwrite, retain) KWBeforeAllNode *beforeAllNode; +@property (nonatomic, readwrite, retain) KWAfterAllNode *afterAllNode; +@property (nonatomic, readwrite, retain) KWBeforeEachNode *beforeEachNode; +@property (nonatomic, readwrite, retain) KWAfterEachNode *afterEachNode; +@property (nonatomic, readonly) KWContextNode *parentContext; +@property (nonatomic, readonly) NSArray *nodes; + +- (void)addContextNode:(KWContextNode *)aNode; +- (void)addItNode:(KWItNode *)aNode; +- (void)addPendingNode:(KWPendingNode *)aNode; + +- (void)performExample:(KWExample *)example withBlock:(void (^)(void))exampleBlock; + +#pragma mark - +#pragma mark Accepting Visitors + +- (void)acceptExampleNodeVisitor:(id)aVisitor; + +@end diff --git a/Pods/Kiwi/Classes/KWContextNode.m b/Pods/Kiwi/Classes/KWContextNode.m new file mode 100644 index 0000000..d0bf238 --- /dev/null +++ b/Pods/Kiwi/Classes/KWContextNode.m @@ -0,0 +1,147 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWContextNode.h" +#import "KWExampleNodeVisitor.h" +#import "KWExample.h" +#import "KWFailure.h" + +@implementation KWContextNode + +@synthesize parentContext; + +#pragma mark - +#pragma mark Initializing + +- (id)initWithCallSite:(KWCallSite *)aCallSite parentContext:(KWContextNode *)node description:(NSString *)aDescription +{ + if ((self = [super init])) { + parentContext = [node retain]; + callSite = [aCallSite retain]; + description = [aDescription copy]; + nodes = [[NSMutableArray alloc] init]; + performedExampleCount = 0; + } + + return self; +} + ++ (id)contextNodeWithCallSite:(KWCallSite *)aCallSite parentContext:(KWContextNode *)contextNode description:(NSString *)aDescription { + return [[[self alloc] initWithCallSite:aCallSite parentContext:contextNode description:aDescription] autorelease]; +} + +- (void)dealloc { + [parentContext release]; + [callSite release]; + [description release]; + [registerMatchersNode release]; + [beforeAllNode release]; + [afterAllNode release]; + [beforeEachNode release]; + [afterEachNode release]; + [nodes release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Getting Call Sites + +@synthesize callSite; + +#pragma mark - +#pragma mark Getting Descriptions + +@synthesize description; + +#pragma mark - +#pragma mark Managing Nodes + +@synthesize registerMatchersNode; +@synthesize beforeAllNode; +@synthesize afterAllNode; +@synthesize beforeEachNode; +@synthesize afterEachNode; +@synthesize nodes; + +- (void)addContextNode:(KWContextNode *)aNode { + [(NSMutableArray *)self.nodes addObject:aNode]; +} + +- (void)setRegisterMatchersNode:(KWRegisterMatchersNode *)aNode { + if (self.registerMatchersNode != nil) + [NSException raise:@"KWContextNodeException" format:@"a register matchers node already exists"]; + + registerMatchersNode = [aNode retain]; +} + +- (void)setBeforeEachNode:(KWBeforeEachNode *)aNode { + if (self.beforeEachNode != nil) + [NSException raise:@"KWContextNodeException" format:@"a before each node already exists"]; + + beforeEachNode = [aNode retain]; +} + +- (void)setAfterEachNode:(KWAfterEachNode *)aNode { + if (self.afterEachNode != nil) + [NSException raise:@"KWContextNodeException" format:@"an after each node already exists"]; + + afterEachNode = [aNode retain]; +} + +- (void)addItNode:(KWItNode *)aNode { + [(NSMutableArray *)self.nodes addObject:aNode]; +} + +- (void)addPendingNode:(KWPendingNode *)aNode { + [(NSMutableArray *)self.nodes addObject:aNode]; +} + +- (void)performExample:(KWExample *)example withBlock:(void (^)(void))exampleBlock +{ + void (^innerExampleBlock)(void) = [exampleBlock copy]; + + void (^outerExampleBlock)(void) = ^{ + @try { + [self.registerMatchersNode acceptExampleNodeVisitor:example]; + + if (performedExampleCount == 0) { + [self.beforeAllNode acceptExampleNodeVisitor:example]; + } + + [self.beforeEachNode acceptExampleNodeVisitor:example]; + + innerExampleBlock(); + + [self.afterEachNode acceptExampleNodeVisitor:example]; + + if ([example isLastInContext:self]) { + [self.afterAllNode acceptExampleNodeVisitor:example]; + } + + } @catch (NSException *exception) { + KWFailure *failure = [KWFailure failureWithCallSite:self.callSite format:@"%@ \"%@\" raised", [exception name], [exception reason]]; + [example reportFailure:failure]; + } + + performedExampleCount++; + }; + if (parentContext == nil) { + outerExampleBlock(); + } + else { + [parentContext performExample:example withBlock:outerExampleBlock]; + } + [innerExampleBlock release]; +} + +#pragma mark - +#pragma mark Accepting Visitors + +- (void)acceptExampleNodeVisitor:(id)aVisitor { + [aVisitor visitContextNode:self]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWCountType.h b/Pods/Kiwi/Classes/KWCountType.h new file mode 100644 index 0000000..2ec5a66 --- /dev/null +++ b/Pods/Kiwi/Classes/KWCountType.h @@ -0,0 +1,15 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +enum { + KWCountTypeExact, + KWCountTypeAtLeast, + KWCountTypeAtMost +}; + +typedef NSUInteger KWCountType; diff --git a/Pods/Kiwi/Classes/KWDeviceInfo.h b/Pods/Kiwi/Classes/KWDeviceInfo.h new file mode 100644 index 0000000..e3a4a6a --- /dev/null +++ b/Pods/Kiwi/Classes/KWDeviceInfo.h @@ -0,0 +1,17 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@interface KWDeviceInfo : NSObject + +#pragma mark - +#pragma mark Getting the Device Type + ++ (BOOL)isSimulator; ++ (BOOL)isPhysical; + +@end diff --git a/Pods/Kiwi/Classes/KWDeviceInfo.m b/Pods/Kiwi/Classes/KWDeviceInfo.m new file mode 100644 index 0000000..294c1b5 --- /dev/null +++ b/Pods/Kiwi/Classes/KWDeviceInfo.m @@ -0,0 +1,32 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWDeviceInfo.h" + +#if TARGET_IPHONE_SIMULATOR + +#import + +#endif // #if TARGET_IPHONE_SIMULATOR + +@implementation KWDeviceInfo + +#pragma mark - +#pragma mark Getting the Device Type + ++ (BOOL)isSimulator { +#if TARGET_IPHONE_SIMULATOR + return YES; +#else + return NO; +#endif // #if TARGET_IPHONE_SIMULATOR +} + ++ (BOOL)isPhysical { + return ![self isSimulator]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWEqualMatcher.h b/Pods/Kiwi/Classes/KWEqualMatcher.h new file mode 100644 index 0000000..30f28e9 --- /dev/null +++ b/Pods/Kiwi/Classes/KWEqualMatcher.h @@ -0,0 +1,20 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWEqualMatcher : KWMatcher { +@private + id otherSubject; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)equal:(id)anObject; + +@end diff --git a/Pods/Kiwi/Classes/KWEqualMatcher.m b/Pods/Kiwi/Classes/KWEqualMatcher.m new file mode 100644 index 0000000..f203ebc --- /dev/null +++ b/Pods/Kiwi/Classes/KWEqualMatcher.m @@ -0,0 +1,79 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWEqualMatcher.h" +#import "KWFormatter.h" +#import "KWValue.h" + +@interface KWEqualMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite, retain) id otherSubject; + +@end + +@implementation KWEqualMatcher + +#pragma mark - +#pragma mark Initializing + +- (void)dealloc { + [otherSubject release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize otherSubject; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"equal:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + /** handle this as a special case; KWValue supports NSNumber equality but not vice-versa **/ + if ([self.subject isKindOfClass:[NSNumber class]] && [self.otherSubject isKindOfClass:[KWValue class]]) { + return [self.otherSubject isEqual:self.subject]; + } + return [self.subject isEqual:self.otherSubject]; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to equal %@, got %@", + [KWFormatter formatObject:self.otherSubject], + [KWFormatter formatObject:self.subject]]; +} + +- (NSString *)failureMessageForShouldNot { + return [NSString stringWithFormat:@"expected subject not to equal %@", + [KWFormatter formatObject:self.otherSubject]]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"equal %@", [KWFormatter formatObject:self.otherSubject]]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)equal:(id)anObject { + self.otherSubject = anObject; +} + +@end diff --git a/Pods/Kiwi/Classes/KWExample.h b/Pods/Kiwi/Classes/KWExample.h new file mode 100644 index 0000000..c0c100d --- /dev/null +++ b/Pods/Kiwi/Classes/KWExample.h @@ -0,0 +1,91 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWBlock.h" +#import "KWVerifying.h" +#import "KWExpectationType.h" +#import "KWExampleNode.h" +#import "KWExampleNodeVisitor.h" +#import "KWReporting.h" +#import "KWExampleGroupDelegate.h" + +@class KWCallSite; +@class KWExampleSuite; +@class KWContextNode; +@class KWSpec; +@class KWMatcherFactory; + +@interface KWExample : NSObject { + id exampleNode; + BOOL passed; +} +@property (nonatomic, retain, readonly) NSMutableArray *lastInContexts; +@property (nonatomic, assign) KWExampleSuite *suite; + +- (id)initWithExampleNode:(id)node; + +#pragma mark - Adding Verifiers + +- (id)addVerifier:(id)aVerifier; +- (id)addExistVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite; +- (id)addMatchVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite; +- (id)addAsyncVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite timeout:(NSInteger)timeout; + +#pragma mark - Running + +- (void)runWithDelegate:(id)delegate; + +#pragma mark - +#pragma mark Anonymous It Node Descriptions + +- (NSString *)generateDescriptionForAnonymousItNode; + +#pragma mark - +#pragma mark Checking if last in context + +- (BOOL)isLastInContext:(KWContextNode *)context; + +#pragma mark - +#pragma mark Full description with context + +- (NSString *)descriptionWithContext; + +@end + +#pragma mark - +#pragma mark Building Example Groups + +void describe(NSString *aDescription, KWVoidBlock aBlock); +void context(NSString *aDescription, KWVoidBlock aBlock); +void registerMatchers(NSString *aNamespacePrefix); +void beforeAll(KWVoidBlock aBlock); +void afterAll(KWVoidBlock aBlock); +void beforeEach(KWVoidBlock aBlock); +void afterEach(KWVoidBlock aBlock); +void it(NSString *aDescription, KWVoidBlock aBlock); +void specify(KWVoidBlock aBlock); +void pending_(NSString *aDescription, KWVoidBlock ignoredBlock); + +void describeWithCallSite(KWCallSite *aCallSite, NSString *aDescription, KWVoidBlock aBlock); +void contextWithCallSite(KWCallSite *aCallSite, NSString *aDescription, KWVoidBlock aBlock); +void registerMatchersWithCallSite(KWCallSite *aCallSite, NSString *aNamespacePrefix); +void beforeAllWithCallSite(KWCallSite *aCallSite, KWVoidBlock aBlock); +void afterAllWithCallSite(KWCallSite *aCallSite, KWVoidBlock aBlock); +void beforeEachWithCallSite(KWCallSite *aCallSite, KWVoidBlock aBlock); +void afterEachWithCallSite(KWCallSite *aCallSite, KWVoidBlock aBlock); +void itWithCallSite(KWCallSite *aCallSite, NSString *aDescription, KWVoidBlock aBlock); +void pendingWithCallSite(KWCallSite *aCallSite, NSString *aDescription, KWVoidBlock ignoredBlock); + +#define PRAGMA(x) _Pragma (#x) +#define PENDING(x) PRAGMA(message ( "Pending: " #x )) + +#define pending(title, args...) \ +PENDING(title) \ +pending_(title, ## args) +#define xit(title, args...) \ +PENDING(title) \ +pending_(title, ## args) diff --git a/Pods/Kiwi/Classes/KWExample.m b/Pods/Kiwi/Classes/KWExample.m new file mode 100644 index 0000000..88b4662 --- /dev/null +++ b/Pods/Kiwi/Classes/KWExample.m @@ -0,0 +1,349 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWExample.h" +#import "KWExampleGroupBuilder.h" +#import "KWContextNode.h" +#import "KWMatcherFactory.h" +#import "KWExistVerifier.h" +#import "KWMatchVerifier.h" +#import "KWAsyncVerifier.h" +#import "KWFailure.h" +#import "KWContextNode.h" +#import "KWBeforeEachNode.h" +#import "KWBeforeAllNode.h" +#import "KWItNode.h" +#import "KWAfterEachNode.h" +#import "KWAfterAllNode.h" +#import "KWPendingNode.h" +#import "KWRegisterMatchersNode.h" +#import "KWWorkarounds.h" +#import "KWIntercept.h" +#import "KWExampleNode.h" +#import "KWExampleSuite.h" + + +@interface KWExample () + +@property (nonatomic, readonly) NSMutableArray *verifiers; +@property (nonatomic, readonly) KWMatcherFactory *matcherFactory; +@property (nonatomic, assign) id delegate; +@property (nonatomic, assign) BOOL didNotFinish; + +- (void)reportResultForExampleNodeWithLabel:(NSString *)label; + +@end + +@implementation KWExample + +@synthesize matcherFactory; +@synthesize verifiers; +@synthesize delegate = _delegate; +@synthesize suite; +@synthesize lastInContexts; +@synthesize didNotFinish; + +- (id)initWithExampleNode:(id)node +{ + if ((self = [super init])) { + exampleNode = [node retain]; + matcherFactory = [[KWMatcherFactory alloc] init]; + verifiers = [[NSMutableArray alloc] init]; + lastInContexts = [[NSMutableArray alloc] init]; + passed = YES; + } + return self; +} + +- (void)dealloc +{ + [lastInContexts release]; + [exampleNode release]; + [matcherFactory release]; + [verifiers release]; + [super dealloc]; +} + +- (BOOL)isLastInContext:(KWContextNode *)context +{ + for (KWContextNode *contextWhereItLast in lastInContexts) { + if (context == contextWhereItLast) { + return YES; + } + } + return NO; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"", exampleNode.description]; +} + +#pragma mark - Adding Verifiers + +- (id)addVerifier:(id)aVerifier { + if (![self.verifiers containsObject:aVerifier]) + [self.verifiers addObject:aVerifier]; + + return aVerifier; +} + +- (id)addExistVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite { + id verifier = [KWExistVerifier existVerifierWithExpectationType:anExpectationType callSite:aCallSite reporter:self]; + [self addVerifier:verifier]; + return verifier; +} + +- (id)addMatchVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite { + id verifier = [KWMatchVerifier matchVerifierWithExpectationType:anExpectationType callSite:aCallSite matcherFactory:self.matcherFactory reporter:self]; + [self addVerifier:verifier]; + return verifier; +} + +- (id)addAsyncVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite timeout:(NSInteger)timeout { + id verifier = [KWAsyncVerifier asyncVerifierWithExpectationType:anExpectationType callSite:aCallSite matcherFactory:self.matcherFactory reporter:self probeTimeout:timeout]; + [self addVerifier:verifier]; + return verifier; +} + +#pragma mark - Running examples + +- (void)runWithDelegate:(id)delegate; +{ + self.delegate = delegate; + [self.matcherFactory registerMatcherClassesWithNamespacePrefix:@"KW"]; + [[KWExampleGroupBuilder sharedExampleGroupBuilder] setCurrentExample:self]; + [exampleNode acceptExampleNodeVisitor:self]; +} + +#pragma mark - Reporting failure + +- (NSString *)descriptionForExampleContext { + NSMutableArray *parts = [NSMutableArray array]; + + for (KWContextNode *context in [[exampleNode contextStack] reverseObjectEnumerator]) { + if ([context description] != nil) { + [parts addObject:[[context description] stringByAppendingString:@","]]; + } + } + + return [parts componentsJoinedByString:@" "]; +} + +- (KWFailure *)outputReadyFailureWithFailure:(KWFailure *)aFailure { + NSString *annotatedFailureMessage = [NSString stringWithFormat:@"'%@ %@' [FAILED], %@", + [self descriptionForExampleContext], [exampleNode description], + aFailure.message]; + +#if TARGET_IPHONE_SIMULATOR + // \uff1a is the unicode for a fill width colon, as opposed to a regular + // colon character (':'). This escape is performed so that Xcode doesn't + // truncate the error output in the build results window, which is running + // build time specs. + annotatedFailureMessage = [annotatedFailureMessage stringByReplacingOccurrencesOfString:@":" withString:@"\uff1a"]; +#endif // #if TARGET_IPHONE_SIMULATOR + + return [KWFailure failureWithCallSite:aFailure.callSite message:annotatedFailureMessage]; +} + +- (void)reportFailure:(KWFailure *)failure +{ + passed = NO; + [self.delegate example:self didFailWithFailure:[self outputReadyFailureWithFailure:failure]]; +} + +- (void)reportResultForExampleNodeWithLabel:(NSString *)label +{ + NSLog(@"+ '%@ %@' [%@]", [self descriptionForExampleContext], [exampleNode description], label); +} + +#pragma mark - Full description with context + +/** Pending cases will be marked yellow by XCode as not finished, because their description differs for -[SenTestCaseRun start] and -[SenTestCaseRun stop] methods + */ + +- (NSString *)pendingNotFinished { + BOOL reportPending = self.didNotFinish; + self.didNotFinish = YES; + return reportPending ? @"(PENDING)" : @""; +} + +- (NSString *)descriptionWithContext { + NSString *descriptionWithContext = [NSString stringWithFormat:@"%@ %@", + [self descriptionForExampleContext], + [exampleNode description] ? [exampleNode description] : @""]; + BOOL isPending = [exampleNode isKindOfClass:[KWPendingNode class]]; + return isPending ? [descriptionWithContext stringByAppendingString:[self pendingNotFinished]] : descriptionWithContext; +} + +#pragma mark - Visiting Nodes + +- (void)visitRegisterMatchersNode:(KWRegisterMatchersNode *)aNode { + [self.matcherFactory registerMatcherClassesWithNamespacePrefix:aNode.namespacePrefix]; +} + +- (void)visitBeforeAllNode:(KWBeforeAllNode *)aNode { + if (aNode.block == nil) + return; + + aNode.block(); +} + +- (void)visitAfterAllNode:(KWAfterAllNode *)aNode { + if (aNode.block == nil) + return; + + aNode.block(); +} + +- (void)visitBeforeEachNode:(KWBeforeEachNode *)aNode { + if (aNode.block == nil) + return; + + aNode.block(); +} + +- (void)visitAfterEachNode:(KWAfterEachNode *)aNode { + if (aNode.block == nil) + return; + + aNode.block(); +} + +- (void)visitItNode:(KWItNode *)aNode { + if (aNode.block == nil || aNode != exampleNode) + return; + + aNode.example = self; + + [aNode.context performExample:self withBlock:^{ + + @try { + + aNode.block(); + +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + NSException *invocationException = KWGetAndClearExceptionFromAcrossInvocationBoundary(); + [invocationException raise]; +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + + // Finish verifying and clear + for (id verifier in self.verifiers) { + [verifier exampleWillEnd]; + } + + } @catch (NSException *exception) { + KWFailure *failure = [KWFailure failureWithCallSite:aNode.callSite format:@"%@ \"%@\" raised", + [exception name], + [exception reason]]; + [self reportFailure:failure]; + } + + if (passed) { + [self reportResultForExampleNodeWithLabel:@"PASSED"]; + } + + // Always clear stubs and spies at the end of it blocks + KWClearStubsAndSpies(); + }]; +} + +- (void)visitPendingNode:(KWPendingNode *)aNode { + if (aNode != exampleNode) + return; + + [self reportResultForExampleNodeWithLabel:@"PENDING"]; +} + +- (NSString *)generateDescriptionForAnonymousItNode +{ + // anonymous specify blocks should only have one verifier, but use the first in any case + return [(self.verifiers)[0] descriptionForAnonymousItNode]; +} + +@end + +#pragma mark - +#pragma mark Building Example Groups + +void describe(NSString *aDescription, KWVoidBlock aBlock) { + describeWithCallSite(nil, aDescription, aBlock); +} + +void context(NSString *aDescription, KWVoidBlock aBlock) { + contextWithCallSite(nil, aDescription, aBlock); +} + +void registerMatchers(NSString *aNamespacePrefix) { + registerMatchersWithCallSite(nil, aNamespacePrefix); +} + +void beforeAll(KWVoidBlock aBlock) { + beforeAllWithCallSite(nil, aBlock); +} + +void afterAll(KWVoidBlock aBlock) { + afterAllWithCallSite(nil, aBlock); +} + +void beforeEach(KWVoidBlock aBlock) { + beforeEachWithCallSite(nil, aBlock); +} + +void afterEach(KWVoidBlock aBlock) { + afterEachWithCallSite(nil, aBlock); +} + +void it(NSString *aDescription, KWVoidBlock aBlock) { + itWithCallSite(nil, aDescription, aBlock); +} + +void specify(KWVoidBlock aBlock) +{ + itWithCallSite(nil, nil, aBlock); +} + +void pending_(NSString *aDescription, KWVoidBlock ignoredBlock) { + pendingWithCallSite(nil, aDescription, ignoredBlock); +} + +void describeWithCallSite(KWCallSite *aCallSite, NSString *aDescription, KWVoidBlock aBlock) { + contextWithCallSite(aCallSite, aDescription, aBlock); +} + +void contextWithCallSite(KWCallSite *aCallSite, NSString *aDescription, KWVoidBlock aBlock) { + [[KWExampleGroupBuilder sharedExampleGroupBuilder] pushContextNodeWithCallSite:aCallSite description:aDescription]; + aBlock(); + [[KWExampleGroupBuilder sharedExampleGroupBuilder] popContextNode]; +} + +void registerMatchersWithCallSite(KWCallSite *aCallSite, NSString *aNamespacePrefix) { + [[KWExampleGroupBuilder sharedExampleGroupBuilder] setRegisterMatchersNodeWithCallSite:aCallSite namespacePrefix:aNamespacePrefix]; +} + +void beforeAllWithCallSite(KWCallSite *aCallSite, KWVoidBlock aBlock) { + [[KWExampleGroupBuilder sharedExampleGroupBuilder] setBeforeAllNodeWithCallSite:aCallSite block:aBlock]; +} + +void afterAllWithCallSite(KWCallSite *aCallSite, KWVoidBlock aBlock) { + [[KWExampleGroupBuilder sharedExampleGroupBuilder] setAfterAllNodeWithCallSite:aCallSite block:aBlock]; +} + +void beforeEachWithCallSite(KWCallSite *aCallSite, KWVoidBlock aBlock) { + [[KWExampleGroupBuilder sharedExampleGroupBuilder] setBeforeEachNodeWithCallSite:aCallSite block:aBlock]; +} + +void afterEachWithCallSite(KWCallSite *aCallSite, KWVoidBlock aBlock) { + [[KWExampleGroupBuilder sharedExampleGroupBuilder] setAfterEachNodeWithCallSite:aCallSite block:aBlock]; +} + +void itWithCallSite(KWCallSite *aCallSite, NSString *aDescription, KWVoidBlock aBlock) { + [[KWExampleGroupBuilder sharedExampleGroupBuilder] addItNodeWithCallSite:aCallSite description:aDescription block:aBlock]; +} + +void pendingWithCallSite(KWCallSite *aCallSite, NSString *aDescription, KWVoidBlock ignoredBlock) { + [[KWExampleGroupBuilder sharedExampleGroupBuilder] addPendingNodeWithCallSite:aCallSite description:aDescription]; +} diff --git a/Pods/Kiwi/Classes/KWExampleGroupBuilder.h b/Pods/Kiwi/Classes/KWExampleGroupBuilder.h new file mode 100644 index 0000000..28e0685 --- /dev/null +++ b/Pods/Kiwi/Classes/KWExampleGroupBuilder.h @@ -0,0 +1,45 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWBlock.h" + +@class KWCallSite; +@class KWExample; +@class KWExampleSuite; + +@interface KWExampleGroupBuilder : NSObject { +@private + NSMutableArray *contextNodeStack; + NSMutableSet *suites; +} + +#pragma mark - +#pragma mark Initializing + ++ (id)sharedExampleGroupBuilder; + +#pragma mark - +#pragma mark Building Example Groups + +@property (nonatomic, readonly) BOOL isBuildingExampleGroup; +@property (nonatomic, retain, readonly) KWExampleSuite *exampleSuite; +@property (nonatomic, retain) KWExample *currentExample; + +- (KWExampleSuite *)buildExampleGroups:(void (^)(void))buildingBlock; +- (KWExample *)currentExample; + +- (void)pushContextNodeWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aDescription; +- (void)popContextNode; +- (void)setRegisterMatchersNodeWithCallSite:(KWCallSite *)aCallSite namespacePrefix:(NSString *)aNamespacePrefix; +- (void)setBeforeAllNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock; +- (void)setAfterAllNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock; +- (void)setBeforeEachNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock; +- (void)setAfterEachNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock; +- (void)addItNodeWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aDescription block:(KWVoidBlock)aBlock; +- (void)addPendingNodeWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aDescription; + +@end diff --git a/Pods/Kiwi/Classes/KWExampleGroupBuilder.m b/Pods/Kiwi/Classes/KWExampleGroupBuilder.m new file mode 100644 index 0000000..eb87416 --- /dev/null +++ b/Pods/Kiwi/Classes/KWExampleGroupBuilder.m @@ -0,0 +1,200 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWExampleGroupBuilder.h" +#import "KWExample.h" +#import "KWAfterAllNode.h" +#import "KWAfterEachNode.h" +#import "KWBeforeAllNode.h" +#import "KWBeforeEachNode.h" +#import "KWContextNode.h" +#import "KWItNode.h" +#import "KWPendingNode.h" +#import "KWRegisterMatchersNode.h" +#import "KWExampleSuite.h" + + +@interface KWExampleGroupBuilder() + +#pragma mark - +#pragma mark Building Example Groups + +@property (nonatomic, retain, readwrite) KWExampleSuite *exampleSuite; +@property (nonatomic, readonly) NSMutableArray *contextNodeStack; + +@end + +@implementation KWExampleGroupBuilder + +@synthesize exampleSuite; +@synthesize currentExample; + +#pragma mark - +#pragma mark Initializing + +static KWExampleGroupBuilder *sharedExampleGroupBuilder = nil; + +- (id)init { + if ((self = [super init])) { + contextNodeStack = [[NSMutableArray alloc] init]; + suites = [[NSMutableSet alloc] init]; + } + + return self; +} + +- (void)dealloc { + [suites release]; + [exampleSuite release]; + [contextNodeStack release]; + [super dealloc]; +} + ++ (id)sharedExampleGroupBuilder { + if (sharedExampleGroupBuilder == nil) { + sharedExampleGroupBuilder = [[super allocWithZone:nil] init]; + } + + return sharedExampleGroupBuilder; +} + ++ (id)allocWithZone:(NSZone *)zone { + return [[self sharedExampleGroupBuilder] retain]; +} + +- (id)copyWithZone:(NSZone *)zone { + return self; +} + +- (id)retain { + return self; +} + +- (NSUInteger)retainCount { + return NSUIntegerMax; +} + +- (oneway void)release { +} + +- (id)autorelease { + return self; +} + +#pragma mark - +#pragma mark Building Example Groups + +@synthesize contextNodeStack; + +- (BOOL)isBuildingExampleGroup { + return [self.contextNodeStack count] > 0; +} + +- (KWExampleSuite *)buildExampleGroups:(void (^)(void))buildingBlock +{ + KWContextNode *rootNode = [KWContextNode contextNodeWithCallSite:nil parentContext:nil description:nil]; + + self.exampleSuite = [[[KWExampleSuite alloc] initWithRootNode:rootNode] autorelease]; + + [suites addObject:self.exampleSuite]; + + [self.contextNodeStack addObject:rootNode]; + buildingBlock(); + [self.contextNodeStack removeAllObjects]; + + return self.exampleSuite; +} + +- (void)pushContextNodeWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aDescription { + KWContextNode *contextNode = [self.contextNodeStack lastObject]; + KWContextNode *node = [KWContextNode contextNodeWithCallSite:aCallSite parentContext:contextNode description:aDescription]; + [contextNode addContextNode:node]; + [self.contextNodeStack addObject:node]; +} + +- (void)popContextNode { + KWContextNode *contextNode = [self.contextNodeStack lastObject]; + + [self.exampleSuite markLastExampleAsLastInContext:contextNode]; + + if ([self.contextNodeStack count] == 1) + [NSException raise:@"KWExampleGroupBuilderException" format:@"there is no open context to pop"]; + + [self.contextNodeStack removeLastObject]; +} + +- (void)setRegisterMatchersNodeWithCallSite:(KWCallSite *)aCallSite namespacePrefix:(NSString *)aNamespacePrefix { + if ([self.contextNodeStack count] == 0) + [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"]; + + KWContextNode *contextNode = [self.contextNodeStack lastObject]; + KWRegisterMatchersNode *registerMatchersNode = [KWRegisterMatchersNode registerMatchersNodeWithCallSite:aCallSite namespacePrefix:aNamespacePrefix]; + [contextNode setRegisterMatchersNode:registerMatchersNode]; +} + +- (void)setBeforeAllNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock { + if ([self.contextNodeStack count] == 0) + [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"]; + + KWContextNode *contextNode = [self.contextNodeStack lastObject]; + KWBeforeAllNode *beforeAllNode = [KWBeforeAllNode beforeAllNodeWithCallSite:aCallSite block:aBlock]; + [contextNode setBeforeAllNode:beforeAllNode]; +} + +- (void)setAfterAllNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock { + if ([self.contextNodeStack count] == 0) + [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"]; + + KWContextNode *contextNode = [self.contextNodeStack lastObject]; + KWAfterAllNode *afterAllNode = [KWAfterAllNode afterAllNodeWithCallSite:aCallSite block:aBlock]; + [contextNode setAfterAllNode:afterAllNode]; +} + +- (void)setBeforeEachNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock { + if ([self.contextNodeStack count] == 0) + [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"]; + + KWContextNode *contextNode = [self.contextNodeStack lastObject]; + KWBeforeEachNode *beforeEachNode = [KWBeforeEachNode beforeEachNodeWithCallSite:aCallSite block:aBlock]; + [contextNode setBeforeEachNode:beforeEachNode]; +} + +- (void)setAfterEachNodeWithCallSite:(KWCallSite *)aCallSite block:(KWVoidBlock)aBlock { + if ([self.contextNodeStack count] == 0) + [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"]; + + KWContextNode *contextNode = [self.contextNodeStack lastObject]; + KWAfterEachNode *afterEachNode = [KWAfterEachNode afterEachNodeWithCallSite:aCallSite block:aBlock]; + [contextNode setAfterEachNode:afterEachNode]; +} + +- (void)addItNodeWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aDescription block:(KWVoidBlock)aBlock { + if ([self.contextNodeStack count] == 0) + [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"]; + + KWContextNode *contextNode = [self.contextNodeStack lastObject]; + KWItNode* itNode = [KWItNode itNodeWithCallSite:aCallSite description:aDescription context:contextNode block:aBlock]; + [contextNode addItNode:itNode]; + + KWExample *example = [[KWExample alloc] initWithExampleNode:itNode]; + [self.exampleSuite addExample:example]; + [example release]; +} + +- (void)addPendingNodeWithCallSite:(KWCallSite *)aCallSite description:(NSString *)aDescription { + if ([self.contextNodeStack count] == 0) + [NSException raise:@"KWExampleGroupBuilderException" format:@"an example group has not been started"]; + + KWContextNode *contextNode = [self.contextNodeStack lastObject]; + KWPendingNode *pendingNode = [KWPendingNode pendingNodeWithCallSite:aCallSite context:contextNode description:aDescription]; + [contextNode addPendingNode:pendingNode]; + + KWExample *example = [[KWExample alloc] initWithExampleNode:pendingNode]; + [self.exampleSuite addExample:example]; + [example release]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWExampleGroupDelegate.h b/Pods/Kiwi/Classes/KWExampleGroupDelegate.h new file mode 100644 index 0000000..cdcceab --- /dev/null +++ b/Pods/Kiwi/Classes/KWExampleGroupDelegate.h @@ -0,0 +1,18 @@ +// +// KWExampleGroupDelegate.h +// Kiwi +// +// Created by Luke Redpath on 08/09/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import + +@class KWExample; +@class KWFailure; + +@protocol KWExampleDelegate + +- (void)example:(KWExample *)example didFailWithFailure:(KWFailure *)failure; + +@end diff --git a/Pods/Kiwi/Classes/KWExampleNode.h b/Pods/Kiwi/Classes/KWExampleNode.h new file mode 100644 index 0000000..c1f25f4 --- /dev/null +++ b/Pods/Kiwi/Classes/KWExampleNode.h @@ -0,0 +1,23 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@class KWContextNode; +@protocol KWExampleNodeVisitor; + +@protocol KWExampleNode + +#pragma mark - +#pragma mark Accepting Visitors + +- (void)acceptExampleNodeVisitor:(id)aVisitor; + +@optional + +- (NSArray *)contextStack; + +@end diff --git a/Pods/Kiwi/Classes/KWExampleNodeVisitor.h b/Pods/Kiwi/Classes/KWExampleNodeVisitor.h new file mode 100644 index 0000000..18dcda4 --- /dev/null +++ b/Pods/Kiwi/Classes/KWExampleNodeVisitor.h @@ -0,0 +1,34 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@class KWAfterAllNode; +@class KWAfterEachNode; +@class KWBeforeAllNode; +@class KWBeforeEachNode; +@class KWContextNode; +@class KWItNode; +@class KWPendingNode; +@class KWRegisterMatchersNode; + +@protocol KWExampleNodeVisitor + +#pragma mark - +#pragma mark Visiting Nodes + +@optional + +- (void)visitContextNode:(KWContextNode *)aNode; +- (void)visitRegisterMatchersNode:(KWRegisterMatchersNode *)aNode; +- (void)visitBeforeAllNode:(KWBeforeAllNode *)aNode; +- (void)visitAfterAllNode:(KWAfterAllNode *)aNode; +- (void)visitBeforeEachNode:(KWBeforeEachNode *)aNode; +- (void)visitAfterEachNode:(KWAfterEachNode *)aNode; +- (void)visitItNode:(KWItNode *)aNode; +- (void)visitPendingNode:(KWPendingNode *)aNode; + +@end diff --git a/Pods/Kiwi/Classes/KWExampleSuite.h b/Pods/Kiwi/Classes/KWExampleSuite.h new file mode 100644 index 0000000..36fbdba --- /dev/null +++ b/Pods/Kiwi/Classes/KWExampleSuite.h @@ -0,0 +1,29 @@ +// +// KWExampleSuite.h +// Kiwi +// +// Created by Luke Redpath on 17/10/2011. +// Copyright (c) 2011 Allen Ding. All rights reserved. +// + +#import +#import "KWExampleNodeVisitor.h" + +@class KWContextNode; +@class KWExample; +@class SenTestCase; + +@interface KWExampleSuite : NSObject { + KWContextNode *rootNode; + NSMutableArray *examples; +} +- (id)initWithRootNode:(KWContextNode *)contextNode; +- (void)addExample:(KWExample *)example; +- (void)markLastExampleAsLastInContext:(KWContextNode *)context; +- (NSArray *)invocationsForTestCase; +@end + +@interface NSInvocation (KWExampleGroup) +- (void)kw_setExample:(KWExample *)exampleGroup; +- (KWExample *)kw_example; +@end diff --git a/Pods/Kiwi/Classes/KWExampleSuite.m b/Pods/Kiwi/Classes/KWExampleSuite.m new file mode 100644 index 0000000..957930a --- /dev/null +++ b/Pods/Kiwi/Classes/KWExampleSuite.m @@ -0,0 +1,87 @@ +// +// KWExampleSuite.m +// Kiwi +// +// Created by Luke Redpath on 17/10/2011. +// Copyright (c) 2011 Allen Ding. All rights reserved. +// + +#import "KWExampleSuite.h" +#import "KWExample.h" +#import "KWStringUtilities.h" +#import "KWBeforeAllNode.h" +#import "KWAfterAllNode.h" +#import "NSMethodSignature+KiwiAdditions.h" +#import + +#define kKWINVOCATION_EXAMPLE_GROUP_KEY @"__KWExampleGroupKey" + +@implementation KWExampleSuite + +- (id)initWithRootNode:(KWContextNode *)contextNode +{ + if ((self = [super init])) { + rootNode = [contextNode retain]; + examples = [[NSMutableArray alloc] init]; + } + return self; +} + +- (void)dealloc +{ + [examples release]; + [rootNode release]; + [super dealloc]; +} + +- (void)addExample:(KWExample *)example +{ + [examples addObject:example]; + [example setSuite:self]; +} + +- (void)markLastExampleAsLastInContext:(KWContextNode *)context +{ + if ([examples count] > 0) { + KWExample *lastExample = (KWExample *)[examples lastObject]; + [lastExample.lastInContexts addObject:context]; + } +} + +- (NSArray *)invocationsForTestCase; +{ + NSMutableArray *invocations = [NSMutableArray array]; + + // Add a single dummy invocation for each example group + + for (KWExample *exampleGroup in examples) { + NSMethodSignature *methodSignature = [NSMethodSignature signatureWithObjCTypes:[KWEncodingForVoidMethod() UTF8String]]; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; + [invocations addObject:invocation]; + [invocation kw_setExample:exampleGroup]; + } + + return invocations; +} + +@end + +#pragma mark - + +// because SenTest will modify the invocation target, we'll have to store +// another reference to the example group so we can retrieve it later + +@implementation NSInvocation (KWExampleGroup) + +- (void)kw_setExample:(KWExample *)exampleGroup +{ + objc_setAssociatedObject(self, kKWINVOCATION_EXAMPLE_GROUP_KEY, exampleGroup, OBJC_ASSOCIATION_RETAIN); +} + +- (KWExample *)kw_example +{ + return objc_getAssociatedObject(self, kKWINVOCATION_EXAMPLE_GROUP_KEY); +} + +@end + diff --git a/Pods/Kiwi/Classes/KWExistVerifier.h b/Pods/Kiwi/Classes/KWExistVerifier.h new file mode 100644 index 0000000..3233138 --- /dev/null +++ b/Pods/Kiwi/Classes/KWExistVerifier.h @@ -0,0 +1,35 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWExpectationType.h" +#import "KWVerifying.h" + +@class KWCallSite; + +@protocol KWReporting; + +@interface KWExistVerifier : NSObject { +@private + KWExpectationType expectationType; + KWCallSite *callSite; + id reporter; + id subject; +} + +#pragma mark - +#pragma mark Initializing + +- (id)initWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite reporter:(id)aReporter; + ++ (id)existVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite reporter:(id)aReporter; + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite, retain) id subject; + +@end diff --git a/Pods/Kiwi/Classes/KWExistVerifier.m b/Pods/Kiwi/Classes/KWExistVerifier.m new file mode 100644 index 0000000..f767ed5 --- /dev/null +++ b/Pods/Kiwi/Classes/KWExistVerifier.m @@ -0,0 +1,78 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWExistVerifier.h" +#import "KWFailure.h" +#import "KWFormatter.h" +#import "KWReporting.h" + +@interface KWExistVerifier() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) KWExpectationType expectationType; +@property (nonatomic, readonly) KWCallSite *callSite; +@property (nonatomic, readonly) id reporter; + +@end + +@implementation KWExistVerifier + +#pragma mark - +#pragma mark Initializing + +- (id)initWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite reporter:(id)aReporter { + if ((self = [super init])) { + expectationType = anExpectationType; + callSite = [aCallSite retain]; + reporter = aReporter; + } + + return self; +} + ++ (id)existVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite reporter:(id)aReporter { + return [[[self alloc] initWithExpectationType:anExpectationType callSite:aCallSite reporter:aReporter] autorelease]; +} + +- (void)dealloc { + [callSite release]; + [subject release]; + [super dealloc]; +} + +- (NSString *)descriptionForAnonymousItNode +{ + if (self.expectationType == KWExpectationTypeShould) { + return @"should exist"; + } + return @"should not exist"; +} + +#pragma mark - +#pragma mark Properties + +@synthesize expectationType; +@synthesize callSite; +@synthesize reporter; +@synthesize subject; + +#pragma mark - +#pragma mark Ending Examples + +- (void)exampleWillEnd { + if (self.expectationType == KWExpectationTypeShould && self.subject == nil) { + KWFailure *failure = [KWFailure failureWithCallSite:self.callSite message:@"expected subject not to be nil"]; + [self.reporter reportFailure:failure]; + } else if (self.expectationType == KWExpectationTypeShouldNot && self.subject != nil) { + KWFailure *failure = [KWFailure failureWithCallSite:self.callSite format:@"expected subject to be nil, got %@", + [KWFormatter formatObject:self.subject]]; + [self.reporter reportFailure:failure]; + } +} + +@end diff --git a/Pods/Kiwi/Classes/KWExpectationType.h b/Pods/Kiwi/Classes/KWExpectationType.h new file mode 100644 index 0000000..eca75a8 --- /dev/null +++ b/Pods/Kiwi/Classes/KWExpectationType.h @@ -0,0 +1,15 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +enum { + KWExpectationTypeShould, + KWExpectationTypeShouldNot, + KWExpectationTypeMaybe +}; + +typedef NSUInteger KWExpectationType; diff --git a/Pods/Kiwi/Classes/KWFailure.h b/Pods/Kiwi/Classes/KWFailure.h new file mode 100644 index 0000000..c5db155 --- /dev/null +++ b/Pods/Kiwi/Classes/KWFailure.h @@ -0,0 +1,37 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@class KWCallSite; + +@interface KWFailure : NSObject { +@private + KWCallSite *callSite; + NSString *message; +} + +#pragma mark - +#pragma mark Initializing + +- (id)initWithCallSite:(KWCallSite *)aCallSite message:(NSString *)aMessage; +- (id)initWithCallSite:(KWCallSite *)aCallSite format:(NSString *)format, ...; + ++ (id)failureWithCallSite:(KWCallSite *)aCallSite message:(NSString *)aMessage; ++ (id)failureWithCallSite:(KWCallSite *)aCallSite format:(NSString *)format, ...; + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) NSString *message; +@property (nonatomic, readonly) KWCallSite *callSite; + +#pragma mark - +#pragma mark Getting Exception Representations + +- (NSException *)exceptionValue; + +@end diff --git a/Pods/Kiwi/Classes/KWFailure.m b/Pods/Kiwi/Classes/KWFailure.m new file mode 100644 index 0000000..037dc3c --- /dev/null +++ b/Pods/Kiwi/Classes/KWFailure.m @@ -0,0 +1,68 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWFailure.h" +#import +#import "KWCallSite.h" + +@implementation KWFailure + +#pragma mark - +#pragma mark Initializing + +- (id)initWithCallSite:(KWCallSite *)aCallSite message:(NSString *)aMessage { + if ((self = [super init])) { + callSite = [aCallSite retain]; + message = [aMessage copy]; + } + + return self; +} + +- (id)initWithCallSite:(KWCallSite *)aCallSite format:(NSString *)format, ... { + va_list argumentList; + va_start(argumentList, format); + NSString *aMessage = [[[NSString alloc] initWithFormat:format arguments:argumentList] autorelease]; + return [self initWithCallSite:aCallSite message:aMessage]; +} + ++ (id)failureWithCallSite:(KWCallSite *)aCallSite message:(NSString *)aMessage { + return [[[self alloc] initWithCallSite:aCallSite message:aMessage] autorelease]; +} + ++ (id)failureWithCallSite:(KWCallSite *)aCallSite format:(NSString *)format, ... { + va_list argumentList; + va_start(argumentList, format); + NSString *message = [[[NSString alloc] initWithFormat:format arguments:argumentList] autorelease]; + return [self failureWithCallSite:aCallSite message:message]; +} + +- (void)dealloc { + [callSite release]; + [message release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize message; +@synthesize callSite; + +#pragma mark - +#pragma mark Getting Exception Representations + +- (NSException *)exceptionValue { + NSDictionary *userInfo = nil; + if (self.callSite) { + NSNumber *lineNumber = @(self.callSite.lineNumber); + userInfo = @{SenTestFilenameKey: self.callSite.filename, + SenTestLineNumberKey: lineNumber}; + } + return [NSException exceptionWithName:@"KWFailureException" reason:message userInfo:userInfo]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWFormatter.h b/Pods/Kiwi/Classes/KWFormatter.h new file mode 100644 index 0000000..a2e4ac6 --- /dev/null +++ b/Pods/Kiwi/Classes/KWFormatter.h @@ -0,0 +1,16 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@interface KWFormatter : NSObject + +#pragma mark - +#pragma mark Getting Descriptions + ++ (NSString *)formatObject:(id)anObject; + +@end diff --git a/Pods/Kiwi/Classes/KWFormatter.m b/Pods/Kiwi/Classes/KWFormatter.m new file mode 100644 index 0000000..bd801e0 --- /dev/null +++ b/Pods/Kiwi/Classes/KWFormatter.m @@ -0,0 +1,51 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWFormatter.h" + +@implementation KWFormatter + + +#pragma mark - Getting Descriptions + ++ (NSString *)formatObject:(id)anObject { + if ([anObject isKindOfClass:[NSString class]]) + return [NSString stringWithFormat:@"\"%@\"", anObject]; + + else if ([anObject isKindOfClass:[NSDictionary class]]) + return [anObject description]; // NSDictionary conforms to NSFastEnumeration + + else if ([anObject conformsToProtocol:@protocol(NSFastEnumeration)]) + return [self formattedCollection:anObject]; + + return [anObject description]; +} + + + +#pragma mark - Private + ++ (NSString *)formattedCollection:(id)collection { + + NSMutableString *description = [[[NSMutableString alloc] initWithString:@"("] autorelease]; + NSUInteger index = 0; + + for (id object in collection) { + if (index == 0) + [description appendFormat:@"%@", [self formatObject:object]]; + else + [description appendFormat:@", %@", [self formatObject:object]]; + + ++index; + } + + [description appendString:@")"]; + return description; +} + + + +@end diff --git a/Pods/Kiwi/Classes/KWFutureObject.h b/Pods/Kiwi/Classes/KWFutureObject.h new file mode 100644 index 0000000..a209991 --- /dev/null +++ b/Pods/Kiwi/Classes/KWFutureObject.h @@ -0,0 +1,20 @@ +// +// KWFutureObject.h +// iOSFalconCore +// +// Created by Luke Redpath on 13/01/2011. +// Copyright 2011 LJR Software Limited. All rights reserved. +// + +#import + +typedef id (^KWFutureObjectBlock)(void); + +@interface KWFutureObject : NSObject { + KWFutureObjectBlock block; +} ++ (id)objectWithObjectPointer:(id *)pointer; ++ (id)futureObjectWithBlock:(KWFutureObjectBlock)block; +- (id)initWithBlock:(KWFutureObjectBlock)aBlock; +- (id)object; +@end diff --git a/Pods/Kiwi/Classes/KWFutureObject.m b/Pods/Kiwi/Classes/KWFutureObject.m new file mode 100644 index 0000000..712cc36 --- /dev/null +++ b/Pods/Kiwi/Classes/KWFutureObject.m @@ -0,0 +1,43 @@ +// +// KWFutureObject.m +// iOSFalconCore +// +// Created by Luke Redpath on 13/01/2011. +// Copyright 2011 LJR Software Limited. All rights reserved. +// + +#import "KWFutureObject.h" + + +@implementation KWFutureObject + ++ (id)objectWithObjectPointer:(id *)pointer; +{ + return [self futureObjectWithBlock:^{ return *pointer; }]; +} + ++ (id)futureObjectWithBlock:(KWFutureObjectBlock)block; +{ + return [[[self alloc] initWithBlock:block] autorelease]; +} + +- (id)initWithBlock:(KWFutureObjectBlock)aBlock; +{ + if ((self = [super init])) { + block = [aBlock copy]; + } + return self; +} + +- (id)object; +{ + return block(); +} + +- (void)dealloc +{ + [block release]; + [super dealloc]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWGenericMatchEvaluator.h b/Pods/Kiwi/Classes/KWGenericMatchEvaluator.h new file mode 100644 index 0000000..c906ab1 --- /dev/null +++ b/Pods/Kiwi/Classes/KWGenericMatchEvaluator.h @@ -0,0 +1,17 @@ +// +// KWGenericMatcher.h +// Kiwi +// +// Created by Allen Ding on 1/31/13. +// Copyright (c) 2013 Allen Ding. All rights reserved. +// + +#import + +@interface KWGenericMatchEvaluator : NSObject + ++ (BOOL)isGenericMatcher:(id)object; + ++ (BOOL)genericMatcher:(id)matcher matches:(id)object; + +@end diff --git a/Pods/Kiwi/Classes/KWGenericMatchEvaluator.m b/Pods/Kiwi/Classes/KWGenericMatchEvaluator.m new file mode 100644 index 0000000..68e5717 --- /dev/null +++ b/Pods/Kiwi/Classes/KWGenericMatchEvaluator.m @@ -0,0 +1,67 @@ +// +// KWGenericMatcher.m +// Kiwi +// +// Created by Allen Ding on 1/31/13. +// Copyright (c) 2013 Allen Ding. All rights reserved. +// + +#import "KWGenericMatchEvaluator.h" +#import "KWStringUtilities.h" +#import "KWObjCUtilities.h" +#import + +@implementation KWGenericMatchEvaluator + +// Returns true only if the object has a method with the signature "- (void)matches:(id)object" ++ (BOOL)isGenericMatcher:(id)object +{ + Class theClass = object_getClass(object); + + if (theClass == NULL) { + return NO; + } + + Method method = class_getInstanceMethod(theClass, @selector(matches:)); + + if (method == NULL) { + return NO; + } + + const char *cEncoding = method_getTypeEncoding(method); + + if (cEncoding == NULL) { + return NO; + } + + NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:cEncoding]; + + if (!KWObjCTypeEqualToObjCType(@encode(BOOL), [signature methodReturnType])) { + return NO; + } + + if ([signature numberOfArguments] != 3) { + return NO; + } + + if (!KWObjCTypeEqualToObjCType(@encode(id), [signature getArgumentTypeAtIndex:2])) { + return NO; + } + + return YES; +} + ++ (BOOL)genericMatcher:(id)matcher matches:(id)object +{ + NSString *targetEncoding = KWEncodingWithObjCTypes(@encode(BOOL), @encode(id), @encode(SEL), @encode(id), nil); + NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:[targetEncoding UTF8String]]; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; + [invocation setSelector:@selector(matches:)]; + [invocation setArgument:&object atIndex:2]; + [invocation invokeWithTarget:matcher]; + BOOL result = NO; + [invocation getReturnValue:&result]; + return result; +} + +@end diff --git a/Pods/Kiwi/Classes/KWGenericMatcher.h b/Pods/Kiwi/Classes/KWGenericMatcher.h new file mode 100644 index 0000000..943058d --- /dev/null +++ b/Pods/Kiwi/Classes/KWGenericMatcher.h @@ -0,0 +1,19 @@ +// +// KWGenericMatcher.h +// Kiwi +// +// Created by Luke Redpath on 24/01/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import +#import "KWMatcher.h" + +@interface KWGenericMatcher : KWMatcher + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)match:(id)aMatcher; + +@end diff --git a/Pods/Kiwi/Classes/KWGenericMatcher.m b/Pods/Kiwi/Classes/KWGenericMatcher.m new file mode 100644 index 0000000..5aeff90 --- /dev/null +++ b/Pods/Kiwi/Classes/KWGenericMatcher.m @@ -0,0 +1,62 @@ +// +// KWGenericMatcher.m +// Kiwi +// +// Created by Luke Redpath on 24/01/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import "KWGenericMatcher.h" +#import "KWGenericMatchEvaluator.h" + +@interface KWGenericMatcher () + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, retain) id matcher; + +@end + +@implementation KWGenericMatcher + +@synthesize matcher; + +- (void)dealloc +{ + [matcher release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + return [KWGenericMatchEvaluator genericMatcher:self.matcher matches:self.subject]; +} + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to match %@", self.matcher]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"match %@", [self.matcher description]]; +} + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"match:"]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)match:(id)aMatcher; +{ + self.matcher = aMatcher; +} + +@end diff --git a/Pods/Kiwi/Classes/KWGenericMatchingAdditions.h b/Pods/Kiwi/Classes/KWGenericMatchingAdditions.h new file mode 100644 index 0000000..c7282ea --- /dev/null +++ b/Pods/Kiwi/Classes/KWGenericMatchingAdditions.h @@ -0,0 +1,34 @@ +// +// NSObject+KiwiAdditions.h +// Kiwi +// +// Created by Luke Redpath on 24/01/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import + +@interface NSObject (KiwiGenericMatchingAdditions) + +- (BOOL)isEqualOrMatches:(id)object; + +@end + +@interface NSArray (KiwiGenericMatchingAdditions) + +- (BOOL)containsObjectEqualToOrMatching:(id)object; +- (BOOL)containsObjectMatching:(id)matcher; + +@end + +@interface NSSet (KiwiGenericMatchingAdditions) + +- (BOOL)containsObjectEqualToOrMatching:(id)object; + +@end + +@interface NSOrderedSet (KiwiGenericMatchingAdditions) + +- (BOOL)containsObjectEqualToOrMatching:(id)object; + +@end \ No newline at end of file diff --git a/Pods/Kiwi/Classes/KWGenericMatchingAdditions.m b/Pods/Kiwi/Classes/KWGenericMatchingAdditions.m new file mode 100644 index 0000000..1df81f1 --- /dev/null +++ b/Pods/Kiwi/Classes/KWGenericMatchingAdditions.m @@ -0,0 +1,72 @@ +// +// NSObject+KiwiAdditions.m +// Kiwi +// +// Created by Luke Redpath on 24/01/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import "KWGenericMatchingAdditions.h" +#import "KWGenericMatcher.h" +#import "KWGenericMatchEvaluator.h" + +@implementation NSObject (KiwiGenericMatchingAdditions) + +- (BOOL)isEqualOrMatches:(id)object +{ + if ([KWGenericMatchEvaluator isGenericMatcher:self]) { + return [KWGenericMatchEvaluator genericMatcher:self matches:object]; + } + return [self isEqual:object]; +} + +@end + +@implementation NSArray (KiwiGenericMatchingAdditions) + +- (BOOL)containsObjectEqualToOrMatching:(id)object +{ + if ([KWGenericMatchEvaluator isGenericMatcher:object]) { + return [self containsObjectMatching:object]; + } + return [self containsObject:object]; +} + +- (BOOL)containsObjectMatching:(id)matcher +{ + NSIndexSet *indexSet = [self indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop) { + BOOL matches = [KWGenericMatchEvaluator genericMatcher:matcher matches:obj]; + if (matches) { + *stop = YES; + } + return matches; + }]; + + return (indexSet.count > 0); +} + +@end + +@implementation NSSet (KiwiGenericMatchingAdditions) + +- (BOOL)containsObjectEqualToOrMatching:(id)object +{ + if ([KWGenericMatchEvaluator isGenericMatcher:object]) { + return [[self allObjects] containsObjectMatching:object]; + } + return [self containsObject:object]; +} + +@end + +@implementation NSOrderedSet (KiwiGenericMatchingAdditions) + +- (BOOL)containsObjectEqualToOrMatching:(id)object +{ + if ([KWGenericMatchEvaluator isGenericMatcher:object]) { + return [[self array] containsObjectMatching:object]; + } + return [self containsObject:object]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWHaveMatcher.h b/Pods/Kiwi/Classes/KWHaveMatcher.h new file mode 100644 index 0000000..ba3a9a5 --- /dev/null +++ b/Pods/Kiwi/Classes/KWHaveMatcher.h @@ -0,0 +1,54 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWCountType.h" +#import "KWMatcher.h" +#import "KWMatchVerifier.h" + +@interface KWHaveMatcher : KWMatcher { +@private + KWCountType countType; + NSUInteger count; + NSInvocation *invocation; + NSUInteger actualCount; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)haveCountOf:(NSUInteger)aCount; +- (void)haveCountOfAtLeast:(NSUInteger)aCount; +- (void)haveCountOfAtMost:(NSUInteger)aCount; +- (void)have:(NSUInteger)aCount itemsForInvocation:(NSInvocation *)anInvocation; +- (void)haveAtLeast:(NSUInteger)aCount itemsForInvocation:(NSInvocation *)anInvocation; +- (void)haveAtMost:(NSUInteger)aCount itemsForInvocation:(NSInvocation *)anInvocation; + +@end + +@protocol KWContainmentCountMatcherTerminals + +#pragma mark - +#pragma mark Terminals + +- (id)objects; +- (id)items; +- (id)elements; + +@end + +@interface KWMatchVerifier(KWHaveMatcherAdditions) + +#pragma mark - +#pragma mark Verifying + +#pragma mark Invocation Capturing Methods + +- (id)have:(NSUInteger)aCount; +- (id)haveAtLeast:(NSUInteger)aCount; +- (id)haveAtMost:(NSUInteger)aCount; + +@end diff --git a/Pods/Kiwi/Classes/KWHaveMatcher.m b/Pods/Kiwi/Classes/KWHaveMatcher.m new file mode 100644 index 0000000..9cdcd76 --- /dev/null +++ b/Pods/Kiwi/Classes/KWHaveMatcher.m @@ -0,0 +1,262 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWHaveMatcher.h" +#import "KWFormatter.h" +#import "KWInvocationCapturer.h" +#import "KWObjCUtilities.h" +#import "KWStringUtilities.h" + +static NSString * const MatchVerifierKey = @"MatchVerifierKey"; +static NSString * const CountTypeKey = @"CountTypeKey"; +static NSString * const CountKey = @"CountKey"; + +@interface KWHaveMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite) KWCountType countType; +@property (nonatomic, readwrite) NSUInteger count; +@property (nonatomic, readwrite, retain) NSInvocation *invocation; +@property (nonatomic, readwrite) NSUInteger actualCount; + +@end + +@implementation KWHaveMatcher + +#pragma mark - +#pragma mark Initializing + +- (void)dealloc { + [invocation release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize countType; +@synthesize count; +@synthesize invocation; +@synthesize actualCount; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"haveCountOf:", + @"haveCountOfAtLeast:", + @"haveCountOfAtMost:", + @"have:itemsForInvocation:", + @"haveAtLeast:itemsForInvocation:", + @"haveAtMost:itemsForInvocation:"]; +} + +#pragma mark - +#pragma mark Matching + +- (id)targetObject { + if (self.invocation == nil) + return self.subject; + + SEL selector = [self.invocation selector]; + + if ([self.subject respondsToSelector:selector]) { + NSMethodSignature *signature = [self.subject methodSignatureForSelector:selector]; + + if (!KWObjCTypeIsObject([signature methodReturnType])) + [NSException raise:@"KWMatcherEception" format:@"a valid collection was not specified"]; + + id object = nil; + [self.invocation invokeWithTarget:self.subject]; + [self.invocation getReturnValue:&object]; + return object; + } else if (KWSelectorParameterCount(selector) == 0) { + return self.subject; + } else { + return nil; + } +} + +- (BOOL)evaluate { + id targetObject = [self targetObject]; + + if ([targetObject respondsToSelector:@selector(count)]) + self.actualCount = [targetObject count]; + else if ([targetObject respondsToSelector:@selector(length)]) + self.actualCount = [targetObject length]; + else + self.actualCount = 0; + + switch (self.countType) { + case KWCountTypeExact: + return self.actualCount == self.count; + case KWCountTypeAtLeast: + return self.actualCount >= self.count; + case KWCountTypeAtMost: + return self.actualCount <= self.count; + } + + assert(0 && "should never reach here"); + return NO; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)verbPhrase { + switch (self.countType) { + case KWCountTypeExact: + return @"have"; + case KWCountTypeAtLeast: + return @"have at least"; + case KWCountTypeAtMost: + return @"have at most"; + } + + assert(0 && "should never reach here"); + return nil; +} + +- (NSString *)itemPhrase { + if (self.invocation == nil) + return @"items"; + else + return NSStringFromSelector([self.invocation selector]); +} + +- (NSString *)actualCountPhrase { + if (self.actualCount == 1) + return @"1 item"; + else + return [NSString stringWithFormat:@"%u items", (unsigned)self.actualCount]; +} + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to %@ %u %@, got %@", + [self verbPhrase], + (unsigned)self.count, + [self itemPhrase], + [self actualCountPhrase]]; +} + +- (NSString *)failureMessageForShouldNot { + return [NSString stringWithFormat:@"expected subject not to %@ %u %@", + [self verbPhrase], + (unsigned)self.count, + [self itemPhrase]]; +} + +#pragma mark - +#pragma mark Description + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %u %@", [self verbPhrase], (unsigned)self.count, [self itemPhrase]]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)haveCountOf:(NSUInteger)aCount { + self.count = aCount; + self.countType = KWCountTypeExact; +} + +- (void)haveCountOfAtLeast:(NSUInteger)aCount { + self.count = aCount; + self.countType = KWCountTypeAtLeast; +} + +- (void)haveCountOfAtMost:(NSUInteger)aCount { + self.count = aCount; + self.countType = KWCountTypeAtMost; +} + +- (void)have:(NSUInteger)aCount itemsForInvocation:(NSInvocation *)anInvocation { + self.count = aCount; + self.countType = KWCountTypeExact; + self.invocation = anInvocation; +} + +- (void)haveAtLeast:(NSUInteger)aCount itemsForInvocation:(NSInvocation *)anInvocation { + self.count = aCount; + self.countType = KWCountTypeAtLeast; + self.invocation = anInvocation; +} + +- (void)haveAtMost:(NSUInteger)aCount itemsForInvocation:(NSInvocation *)anInvocation { + self.count = aCount; + self.countType = KWCountTypeAtMost; + self.invocation = anInvocation; +} + +#pragma mark - +#pragma mark Capturing Invocations + ++ (NSMethodSignature *)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer methodSignatureForSelector:(SEL)aSelector { + KWMatchVerifier *verifier = (anInvocationCapturer.userInfo)[MatchVerifierKey]; + + if ([verifier.subject respondsToSelector:aSelector]) + return [verifier.subject methodSignatureForSelector:aSelector]; + + // Arbitrary selectors are allowed as expectation expression terminals when + // the subject itself is a collection, so return a dummy method signature. + NSString *encoding = KWEncodingForVoidMethod(); + return [NSMethodSignature signatureWithObjCTypes:[encoding UTF8String]]; +} + ++ (void)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer didCaptureInvocation:(NSInvocation *)anInvocation { + NSDictionary *userInfo = anInvocationCapturer.userInfo; + id verifier = userInfo[MatchVerifierKey]; + KWCountType countType = [userInfo[CountTypeKey] unsignedIntegerValue]; + NSUInteger count = [userInfo[CountKey] unsignedIntegerValue]; + + switch (countType) { + case KWCountTypeExact: + [verifier have:count itemsForInvocation:anInvocation]; + break; + case KWCountTypeAtLeast: + [verifier haveAtLeast:count itemsForInvocation:anInvocation]; + break; + case KWCountTypeAtMost: + [verifier haveAtMost:count itemsForInvocation:anInvocation]; + break; + } +} + +@end + +@implementation KWMatchVerifier(KWHaveMatcherAdditions) + +#pragma mark - +#pragma mark Verifying + +#pragma mark Invocation Capturing Methods + +- (NSDictionary *)userInfoForHaveMatcherWithCountType:(KWCountType)aCountType count:(NSUInteger)aCount { + return @{MatchVerifierKey: self, + CountTypeKey: @(aCountType), + CountKey: @(aCount)}; +} + +- (id)have:(NSUInteger)aCount { + NSDictionary *userInfo = [self userInfoForHaveMatcherWithCountType:KWCountTypeExact count:aCount]; + return [KWInvocationCapturer invocationCapturerWithDelegate:[KWHaveMatcher class] userInfo:userInfo]; +} + +- (id)haveAtLeast:(NSUInteger)aCount { + NSDictionary *userInfo = [self userInfoForHaveMatcherWithCountType:KWCountTypeAtLeast count:aCount]; + return [KWInvocationCapturer invocationCapturerWithDelegate:[KWHaveMatcher class] userInfo:userInfo]; +} + +- (id)haveAtMost:(NSUInteger)aCount { + NSDictionary *userInfo = [self userInfoForHaveMatcherWithCountType:KWCountTypeAtMost count:aCount]; + return [KWInvocationCapturer invocationCapturerWithDelegate:[KWHaveMatcher class] userInfo:userInfo]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWHaveValueMatcher.h b/Pods/Kiwi/Classes/KWHaveValueMatcher.h new file mode 100644 index 0000000..a6d5a43 --- /dev/null +++ b/Pods/Kiwi/Classes/KWHaveValueMatcher.h @@ -0,0 +1,28 @@ +// +// KWHaveValueMatcher.h +// Kiwi +// +// Created by Luke Redpath on 24/01/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import +#import "KWMatcher.h" + +@interface KWHaveValueMatcher : KWMatcher { +@private + + NSString *expectedKey; + NSString *expectedKeyPath; + id expectedValue; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)haveValue:(id)value forKey:(NSString *)key; +- (void)haveValue:(id)value forKeyPath:(NSString *)keyPath; +- (void)haveValueForKey:(NSString *)key; +- (void)haveValueForKeyPath:(NSString *)keyPath; + +@end diff --git a/Pods/Kiwi/Classes/KWHaveValueMatcher.m b/Pods/Kiwi/Classes/KWHaveValueMatcher.m new file mode 100644 index 0000000..496c011 --- /dev/null +++ b/Pods/Kiwi/Classes/KWHaveValueMatcher.m @@ -0,0 +1,152 @@ +// +// KWHaveValueMatcher.m +// Kiwi +// +// Created by Luke Redpath on 24/01/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import "KWHaveValueMatcher.h" +#import "KWGenericMatchingAdditions.h" +#import "KWGenericMatcher.h" +#import "KWFormatter.h" + +@interface KWHaveValueMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, retain) NSString *expectedKey; +@property (nonatomic, retain) NSString *expectedKeyPath; +@property (nonatomic, retain) id expectedValue; + +- (id)subjectValue; + +@end + +@implementation KWHaveValueMatcher + +@synthesize expectedKey, expectedKeyPath, expectedValue; + +- (void)dealloc +{ + [expectedKeyPath release]; + [expectedKey release]; + [expectedValue release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"haveValue:forKey:", + @"haveValueForKey:", + @"haveValue:forKeyPath:", + @"haveValueForKeyPath:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + BOOL matched = NO; + + @try { + id value = [self subjectValue]; + + if (value) { + matched = YES; + + if (self.expectedValue) { + matched = [self.expectedValue isEqualOrMatches:value]; + } + } + } + @catch (NSException * e) {} // catch KVO non-existent key errors + + return matched; +} + +- (NSString *)failureMessageForShould { + if (self.expectedValue == nil) { + return [NSString stringWithFormat:@"expected subject to have a value for key %@", + [KWFormatter formatObject:self.expectedKey]]; + } + id subjectValue = [self subjectValue]; + if (subjectValue) { + return [NSString stringWithFormat:@"expected subject to have value %@ for key %@, but it had value %@ instead", + [KWFormatter formatObject:self.expectedValue], + [KWFormatter formatObject:self.expectedKey], + [KWFormatter formatObject:subjectValue]]; + } else { + return [NSString stringWithFormat:@"expected subject to have value %@ for key %@, but the key was not present", + [KWFormatter formatObject:self.expectedValue], + [KWFormatter formatObject:self.expectedKey]]; + } +} + +- (id)subjectValue +{ + id value = nil; + + if (self.expectedKey) { + value = [self.subject valueForKey:self.expectedKey]; + } else + if (self.expectedKeyPath) { + value = [self.subject valueForKeyPath:self.expectedKeyPath]; + } + return value; +} + +- (NSString *)description +{ + NSString *keyDescription = nil; + + if (self.expectedKey) { + keyDescription = [NSString stringWithFormat:@"key %@", [KWFormatter formatObject:self.expectedKey]]; + } + else { + keyDescription = [NSString stringWithFormat:@"keypath %@", [KWFormatter formatObject:self.expectedKeyPath]]; + } + + NSString *valueDescription = nil; + + if (self.expectedValue) { + valueDescription = [NSString stringWithFormat:@"value %@", [KWFormatter formatObject:self.expectedValue]]; + } + else { + valueDescription = @"value"; + } + + return [NSString stringWithFormat:@"have %@ for %@", valueDescription, keyDescription]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)haveValue:(id)value forKey:(NSString *)key; +{ + self.expectedKey = key; + self.expectedValue = value; +} + +- (void)haveValue:(id)value forKeyPath:(NSString *)key; +{ + self.expectedKeyPath = key; + self.expectedValue = value; +} + +- (void)haveValueForKey:(NSString *)key; +{ + self.expectedKey = key; + self.expectedValue = nil; +} + +- (void)haveValueForKeyPath:(NSString *)keyPath; +{ + self.expectedKeyPath = keyPath; + self.expectedValue = nil; +} + +@end diff --git a/Pods/Kiwi/Classes/KWInequalityMatcher.h b/Pods/Kiwi/Classes/KWInequalityMatcher.h new file mode 100644 index 0000000..7c03d89 --- /dev/null +++ b/Pods/Kiwi/Classes/KWInequalityMatcher.h @@ -0,0 +1,33 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +enum { + KWInequalityTypeLessThan, + KWInequalityTypeLessThanOrEqualTo, + KWInequalityTypeGreaterThan, + KWInequalityTypeGreaterThanOrEqualTo +}; + +typedef NSUInteger KWInequalityType; + +@interface KWInequalityMatcher : KWMatcher { +@private + KWInequalityType inequalityType; + id otherValue; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beLessThan:(id)aValue; +- (void)beLessThanOrEqualTo:(id)aValue; +- (void)beGreaterThan:(id)aValue; +- (void)beGreaterThanOrEqualTo:(id)aValue; + +@end diff --git a/Pods/Kiwi/Classes/KWInequalityMatcher.m b/Pods/Kiwi/Classes/KWInequalityMatcher.m new file mode 100644 index 0000000..632be0a --- /dev/null +++ b/Pods/Kiwi/Classes/KWInequalityMatcher.m @@ -0,0 +1,122 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWInequalityMatcher.h" +#import "KWFormatter.h" + +@interface KWInequalityMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite) KWInequalityType inequalityType; +@property (nonatomic, readwrite, retain) id otherValue; + +@end + +@implementation KWInequalityMatcher + +#pragma mark - +#pragma mark Initializing + +- (void)dealloc { + [otherValue release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize inequalityType; +@synthesize otherValue; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"beLessThan:", + @"beLessThanOrEqualTo:", + @"beGreaterThan:", + @"beGreaterThanOrEqualTo:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + if (![self.subject respondsToSelector:@selector(compare:)]) + [NSException raise:@"KWMatcherException" format:@"subject does not respond to -compare:"]; + + NSComparisonResult result = [self.subject compare:self.otherValue]; + + switch (result) { + case NSOrderedSame: + return self.inequalityType == KWInequalityTypeLessThanOrEqualTo || self.inequalityType == KWInequalityTypeGreaterThanOrEqualTo; + case NSOrderedAscending: + return self.inequalityType == KWInequalityTypeLessThan || self.inequalityType == KWInequalityTypeLessThanOrEqualTo; + case NSOrderedDescending: + return self.inequalityType == KWInequalityTypeGreaterThan || self.inequalityType == KWInequalityTypeGreaterThanOrEqualTo; + } + + assert(0 && "should never reach here"); + return NO; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)comparisonPhrase { + switch (self.inequalityType) { + case KWInequalityTypeLessThan: + return @"<"; + case KWInequalityTypeLessThanOrEqualTo: + return @"<="; + case KWInequalityTypeGreaterThan: + return @">"; + case KWInequalityTypeGreaterThanOrEqualTo: + return @">="; + } + + assert(0 && "should never reach here"); + return nil; +} + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to be %@ %@, got %@", + [self comparisonPhrase], + [KWFormatter formatObject:self.otherValue], + [KWFormatter formatObject:self.subject]]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"be %@ %@", [self comparisonPhrase], [KWFormatter formatObject:self.otherValue]]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)beLessThan:(id)aValue { + self.inequalityType = KWInequalityTypeLessThan; + self.otherValue = aValue; +} + +- (void)beLessThanOrEqualTo:(id)aValue { + self.inequalityType = KWInequalityTypeLessThanOrEqualTo; + self.otherValue = aValue; +} + +- (void)beGreaterThan:(id)aValue { + self.inequalityType = KWInequalityTypeGreaterThan; + self.otherValue = aValue; +} + +- (void)beGreaterThanOrEqualTo:(id)aValue { + self.inequalityType = KWInequalityTypeGreaterThanOrEqualTo; + self.otherValue = aValue; +} + +@end diff --git a/Pods/Kiwi/Classes/KWIntercept.h b/Pods/Kiwi/Classes/KWIntercept.h new file mode 100644 index 0000000..d238d63 --- /dev/null +++ b/Pods/Kiwi/Classes/KWIntercept.h @@ -0,0 +1,50 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import + +@class KWMessagePattern; +@class KWStub; + +#pragma mark - +#pragma mark Getting Forwarding Implementations + +IMP KWRegularForwardingImplementation(void); +IMP KWStretForwardingImplementation(void); +IMP KWForwardingImplementationForMethodEncoding(const char* encoding); + +#pragma mark - +#pragma mark Getting Intercept Class Information + +BOOL KWObjectIsClass(id anObject); +BOOL KWClassIsInterceptClass(Class aClass); +NSString *KWInterceptClassNameForClass(Class aClass); +Class KWInterceptClassForCanonicalClass(Class canonicalClass); +Class KWRealClassForClass(Class aClass); + +#pragma mark - +#pragma mark Enabling Intercepting + +Class KWSetupObjectInterceptSupport(id anObject); +void KWSetupMethodInterceptSupport(Class interceptClass, SEL aSelector); + +#pragma mark - Managing Stubs & Spies +void KWClearStubsAndSpies(void); + +#pragma mark - +#pragma mark Managing Objects Stubs + +void KWAssociateObjectStub(id anObject, KWStub *aStub, BOOL overrideExisting); +void KWClearObjectStubs(id anObject); +void KWClearAllObjectStubs(void); + +#pragma mark - +#pragma mark Managing Message Spies + +void KWAssociateMessageSpy(id anObject, id aSpy, KWMessagePattern *aMessagePattern); +void KWClearObjectSpy(id anObject, id aSpy, KWMessagePattern *aMessagePattern); +void KWClearAllMessageSpies(void); diff --git a/Pods/Kiwi/Classes/KWIntercept.m b/Pods/Kiwi/Classes/KWIntercept.m new file mode 100644 index 0000000..0e0f88c --- /dev/null +++ b/Pods/Kiwi/Classes/KWIntercept.m @@ -0,0 +1,336 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWIntercept.h" +#import "KWMessagePattern.h" +#import "KWMessageSpying.h" +#import "KWStub.h" + +static const char * const KWInterceptClassSuffix = "_KWIntercept"; +static NSMutableDictionary *KWObjectStubs = nil; +static NSMutableDictionary *KWMessageSpies = nil; +static NSMutableArray *KWRestoredObjects = nil; + +#pragma mark - +#pragma mark Intercept Enabled Method Implementations + +Class KWRestoreOriginalClass(id anObject); +void KWInterceptedForwardInvocation(id anObject, SEL aSelector, NSInvocation* anInvocation); +void KWInterceptedDealloc(id anObject, SEL aSelector); +Class KWInterceptedClass(id anObject, SEL aSelector); +Class KWInterceptedSuperclass(id anObject, SEL aSelector); + +#pragma mark - +#pragma mark Getting Forwarding Implementations + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" + +IMP KWRegularForwardingImplementation(void) { + return class_getMethodImplementation([NSObject class], @selector(KWNonExistantSelector)); +} + +IMP KWStretForwardingImplementation(void) { + return class_getMethodImplementation_stret([NSObject class], @selector(KWNonExistantSelector)); +} + +#pragma clang diagnostic pop + +IMP KWForwardingImplementationForMethodEncoding(const char* encoding) { +#if TARGET_CPU_ARM + const NSUInteger stretLengthThreshold = 4; +#elif TARGET_CPU_X86 + const NSUInteger stretLengthThreshold = 8; +#else + // TODO: This just makes an assumption right now. Expand to support all + // official architectures correctly. + const NSUInteger stretLengthThreshold = 8; +#endif // #if TARGET_CPU_ARM + + NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:encoding]; + + if (*[signature methodReturnType] == '{' && [signature methodReturnLength] > stretLengthThreshold) { + NSLog(@"Warning: The Objective-C runtime appears to have bugs when forwarding messages with certain struct layouts as return types, so if a crash occurs this could be the culprit"); + return KWStretForwardingImplementation(); + } else { + return KWRegularForwardingImplementation(); + } +} + +#pragma mark - +#pragma mark Getting Intercept Class Information + +BOOL KWObjectIsClass(id anObject) { + return class_isMetaClass(object_getClass(anObject)); +} + +BOOL KWClassIsInterceptClass(Class aClass) { + const char *name = class_getName(aClass); + char *result = strstr(name, KWInterceptClassSuffix); + return result != nil; +} + +int interceptCount = 0; + +NSString *KWInterceptClassNameForClass(Class aClass) { + const char *className = class_getName(aClass); + interceptCount++; + return [NSString stringWithFormat:@"%s%s%d", className, KWInterceptClassSuffix, interceptCount]; +} + +Class KWInterceptClassForCanonicalClass(Class canonicalClass) { + NSString *interceptClassName = KWInterceptClassNameForClass(canonicalClass); + Class interceptClass = NSClassFromString(interceptClassName); + + if (interceptClass != nil) + return interceptClass; + + interceptClass = objc_allocateClassPair(canonicalClass, [interceptClassName UTF8String], 0); + objc_registerClassPair(interceptClass); + + class_addMethod(interceptClass, @selector(forwardInvocation:), (IMP)KWInterceptedForwardInvocation, "v@:@"); + class_addMethod(interceptClass, @selector(dealloc), (IMP)KWInterceptedDealloc, "v@:"); + class_addMethod(interceptClass, @selector(class), (IMP)KWInterceptedClass, "#@:"); + class_addMethod(interceptClass, @selector(superclass), (IMP)KWInterceptedSuperclass, "#@:"); + + Class interceptMetaClass = object_getClass(interceptClass); + class_addMethod(interceptMetaClass, @selector(forwardInvocation:), (IMP)KWInterceptedForwardInvocation, "v@:@"); + + return interceptClass; +} + +Class KWRealClassForClass(Class aClass) { + if (KWClassIsInterceptClass(aClass)) + return [aClass superclass]; + + return aClass; +} + +#pragma mark - +#pragma mark Enabling Intercepting + +static BOOL IsTollFreeBridged(Class class, id obj) +{ + // this is a naive check, but good enough for the purposes of failing fast + return [NSStringFromClass(class) hasPrefix:@"NSCF"]; +} + +// Canonical class is the non-intercept, non-metaclass, class for an object. +// +// (e.g. [Animal class] would be canonical, not +// object_getClass([Animal class]), if the Animal class has not been touched +// by the intercept mechanism. + +Class KWSetupObjectInterceptSupport(id anObject) { + Class objectClass = object_getClass(anObject); + + if (IsTollFreeBridged(objectClass, anObject)) { + [NSException raise:@"KWTollFreeBridgingInterceptException" format:@"Attempted to stub object of class %@. Kiwi does not support setting expectation or stubbing methods on toll-free bridged objects.", NSStringFromClass(objectClass)]; + } + + if (KWClassIsInterceptClass(objectClass)) + return objectClass; + + BOOL objectIsClass = KWObjectIsClass(anObject); + Class canonicalClass = objectIsClass ? anObject : objectClass; + Class canonicalInterceptClass = KWInterceptClassForCanonicalClass(canonicalClass); + Class interceptClass = objectIsClass ? object_getClass(canonicalInterceptClass) : canonicalInterceptClass; + + object_setClass(anObject, interceptClass); + + return interceptClass; +} + +void KWSetupMethodInterceptSupport(Class interceptClass, SEL aSelector) { + BOOL isMetaClass = class_isMetaClass(interceptClass); + Method method = isMetaClass ? class_getClassMethod(interceptClass, aSelector) + : class_getInstanceMethod(interceptClass, aSelector); + + if (method == nil) { + [NSException raise:NSInvalidArgumentException format:@"cannot setup intercept support for -%@ because no such method exists", + NSStringFromSelector(aSelector)]; + } + + const char *encoding = method_getTypeEncoding(method); + IMP forwardingImplementation = KWForwardingImplementationForMethodEncoding(encoding); + class_addMethod(interceptClass, aSelector, forwardingImplementation, encoding); +} + +#pragma mark - +#pragma mark Intercept Enabled Method Implementations + +Class KWRestoreOriginalClass(id anObject) { + Class interceptClass = object_getClass(anObject); + if (KWClassIsInterceptClass(interceptClass)) + { + Class originalClass = class_getSuperclass(interceptClass); + // anObject->isa = originalClass; + object_setClass(anObject, originalClass); + } + return interceptClass; +} + +void KWInterceptedForwardInvocation(id anObject, SEL aSelector, NSInvocation* anInvocation) { + NSValue *key = [NSValue valueWithNonretainedObject:anObject]; + NSMutableDictionary *spyArrayDictionary = KWMessageSpies[key]; + + for (KWMessagePattern *messagePattern in spyArrayDictionary) { + if ([messagePattern matchesInvocation:anInvocation]) { + NSArray *spies = spyArrayDictionary[messagePattern]; + + for (NSValue *spyWrapper in spies) { + id spy = [spyWrapper nonretainedObjectValue]; + [spy object:anObject didReceiveInvocation:anInvocation]; + } + } + } + + NSMutableArray *stubs = KWObjectStubs[key]; + + for (KWStub *stub in stubs) { + if ([stub processInvocation:anInvocation]) + return; + } + + Class interceptClass = KWRestoreOriginalClass(anObject); + [anInvocation invoke]; + // anObject->isa = interceptClass; + object_setClass(anObject, interceptClass); +} + +void KWInterceptedDealloc(id anObject, SEL aSelector) { + NSValue *key = [NSValue valueWithNonretainedObject:anObject]; + [KWMessageSpies removeObjectForKey:key]; + [KWObjectStubs removeObjectForKey:key]; + + KWRestoreOriginalClass(anObject); + [anObject dealloc]; +} + +Class KWInterceptedClass(id anObject, SEL aSelector) { + Class interceptClass = object_getClass(anObject); + Class originalClass = class_getSuperclass(interceptClass); + return originalClass; +} + +Class KWInterceptedSuperclass(id anObject, SEL aSelector) { + Class interceptClass = object_getClass(anObject); + Class originalClass = class_getSuperclass(interceptClass); + Class originalSuperclass = class_getSuperclass(originalClass); + return originalSuperclass; +} + +#pragma mark - Managing Stubs & Spies + +void KWClearStubsAndSpies(void) { + KWRestoredObjects = [NSMutableArray array]; + KWClearAllMessageSpies(); + KWClearAllObjectStubs(); + KWRestoredObjects = nil; +} + +#pragma mark - +#pragma mark Managing Objects Stubs + +void KWAssociateObjectStub(id anObject, KWStub *aStub, BOOL overrideExisting) { + if (KWObjectStubs == nil) + KWObjectStubs = [[NSMutableDictionary alloc] init]; + + NSValue *key = [NSValue valueWithNonretainedObject:anObject]; + NSMutableArray *stubs = KWObjectStubs[key]; + + if (stubs == nil) { + stubs = [[NSMutableArray alloc] init]; + KWObjectStubs[key] = stubs; + [stubs release]; + } + + NSUInteger stubCount = [stubs count]; + + for (NSUInteger i = 0; i < stubCount; ++i) { + KWStub *existingStub = stubs[i]; + + if ([aStub.messagePattern isEqualToMessagePattern:existingStub.messagePattern]) { + if (overrideExisting) { + [stubs removeObjectAtIndex:i]; + break; + } else { + return; + } + } + } + + [stubs addObject:aStub]; +} + +void KWClearObjectStubs(id anObject) { + NSValue *key = [NSValue valueWithNonretainedObject:anObject]; + [KWObjectStubs removeObjectForKey:key]; +} + +void KWClearAllObjectStubs(void) { + for (NSValue *objectKey in KWObjectStubs) { + id stubbedObject = [objectKey nonretainedObjectValue]; + if ([KWRestoredObjects containsObject:stubbedObject]) { + continue; + } + KWRestoreOriginalClass(stubbedObject); + [KWRestoredObjects addObject:stubbedObject]; + } + [KWObjectStubs removeAllObjects]; +} + +#pragma mark - +#pragma mark Managing Message Spies + +void KWAssociateMessageSpy(id anObject, id aSpy, KWMessagePattern *aMessagePattern) { + if (KWMessageSpies == nil) + KWMessageSpies = [[NSMutableDictionary alloc] init]; + + NSValue *key = [NSValue valueWithNonretainedObject:anObject]; + NSMutableDictionary *spies = KWMessageSpies[key]; + + if (spies == nil) { + spies = [[NSMutableDictionary alloc] init]; + KWMessageSpies[key] = spies; + [spies release]; + } + + NSMutableArray *messagePatternSpies = spies[aMessagePattern]; + + if (messagePatternSpies == nil) { + messagePatternSpies = [[NSMutableArray alloc] init]; + spies[aMessagePattern] = messagePatternSpies; + [messagePatternSpies release]; + } + + NSValue *spyWrapper = [NSValue valueWithNonretainedObject:aSpy]; + + if ([messagePatternSpies containsObject:spyWrapper]) + return; + + [messagePatternSpies addObject:spyWrapper]; +} + +void KWClearObjectSpy(id anObject, id aSpy, KWMessagePattern *aMessagePattern) { + NSValue *key = [NSValue valueWithNonretainedObject:anObject]; + NSMutableDictionary *spyArrayDictionary = KWMessageSpies[key]; + NSMutableArray *spies = spyArrayDictionary[aMessagePattern]; + NSValue *spyWrapper = [NSValue valueWithNonretainedObject:aSpy]; + [spies removeObject:spyWrapper]; +} + +void KWClearAllMessageSpies(void) { + for (NSValue *objectKey in KWMessageSpies) { + id spiedObject = [objectKey nonretainedObjectValue]; + if ([KWRestoredObjects containsObject:spiedObject]) { + continue; + } + KWRestoreOriginalClass(spiedObject); + [KWRestoredObjects addObject:spiedObject]; + } + [KWMessageSpies removeAllObjects]; +} diff --git a/Pods/Kiwi/Classes/KWInvocationCapturer.h b/Pods/Kiwi/Classes/KWInvocationCapturer.h new file mode 100644 index 0000000..79c1a5e --- /dev/null +++ b/Pods/Kiwi/Classes/KWInvocationCapturer.h @@ -0,0 +1,42 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@protocol KWInvocationCapturerDelegate; + +@interface KWInvocationCapturer : NSProxy { +@private + id delegate; + NSDictionary *userInfo; +} + +#pragma mark - +#pragma mark Initializing + +- (id)initWithDelegate:(id)aDelegate; +- (id)initWithDelegate:(id)aDelegate userInfo:(NSDictionary *)aUserInfo; + ++ (id)invocationCapturerWithDelegate:(id)aDelegate; ++ (id)invocationCapturerWithDelegate:(id)aDelegate userInfo:(NSDictionary *)aUserInfo; + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) id delegate; +@property (nonatomic, readonly) NSDictionary *userInfo; + +@end + +@protocol KWInvocationCapturerDelegate + +#pragma mark - +#pragma mark Capturing Invocations + +- (NSMethodSignature *)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer methodSignatureForSelector:(SEL)aSelector; +- (void)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer didCaptureInvocation:(NSInvocation *)anInvocation; + +@end diff --git a/Pods/Kiwi/Classes/KWInvocationCapturer.m b/Pods/Kiwi/Classes/KWInvocationCapturer.m new file mode 100644 index 0000000..12599d6 --- /dev/null +++ b/Pods/Kiwi/Classes/KWInvocationCapturer.m @@ -0,0 +1,97 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWInvocationCapturer.h" +#import "KWWorkarounds.h" +#import "NSInvocation+KiwiAdditions.h" + +@implementation KWInvocationCapturer + +#pragma mark - +#pragma mark Initializing + +- (id)initWithDelegate:(id)aDelegate { + return [self initWithDelegate:aDelegate userInfo:nil]; +} + +- (id)initWithDelegate:(id)aDelegate userInfo:(NSDictionary *)aUserInfo { + delegate = aDelegate; + userInfo = [aUserInfo retain]; + return self; +} + ++ (id)invocationCapturerWithDelegate:(id)aDelegate { + return [self invocationCapturerWithDelegate:aDelegate userInfo:nil]; +} + ++ (id)invocationCapturerWithDelegate:(id)aDelegate userInfo:(NSDictionary *)aUserInfo { + return [[[self alloc] initWithDelegate:aDelegate userInfo:aUserInfo] autorelease]; +} + +- (void)dealloc { + [userInfo release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize delegate; +@synthesize userInfo; + +#pragma mark - +#pragma mark Capturing Invocations + +- (void)KW_captureInvocation:(NSInvocation *)anInvocation { + [self.delegate invocationCapturer:self didCaptureInvocation:anInvocation]; +} + +#pragma mark - +#pragma mark Handling Invocations + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { + return [self.delegate invocationCapturer:self methodSignatureForSelector:aSelector]; +} + +- (void)forwardInvocation:(NSInvocation *)anInvocation { +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + @try { +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + + [self KW_captureInvocation:anInvocation]; + +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + } @catch (NSException *exception) { + KWSetExceptionFromAcrossInvocationBoundary(exception); + } +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG +} + +#pragma mark - +#pragma mark Whitelisted NSObject Methods + +// The return values from these methods should never be needed, so just call +// the super implementation after capturing the invocation. + +- (BOOL)isEqual:(id)anObject { + NSInvocation *invocation = [NSInvocation invocationWithTarget:self selector:_cmd messageArguments:&anObject]; + [self KW_captureInvocation:invocation]; + return [super isEqual:anObject]; +} + +- (NSUInteger)hash { + NSInvocation *invocation = [NSInvocation invocationWithTarget:self selector:_cmd]; + [self KW_captureInvocation:invocation]; + return [super hash]; +} + +- (NSString *)description { + NSInvocation *invocation = [NSInvocation invocationWithTarget:self selector:_cmd]; + [self KW_captureInvocation:invocation]; + return [super description]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWItNode.h b/Pods/Kiwi/Classes/KWItNode.h new file mode 100644 index 0000000..bbb7fb9 --- /dev/null +++ b/Pods/Kiwi/Classes/KWItNode.h @@ -0,0 +1,28 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWBlockNode.h" +#import "KWExampleNode.h" + +@class KWPendingNode; +@class KWExample; +@class KWContextNode; + +@interface KWItNode : KWBlockNode + +@property (nonatomic, assign) KWExample *example; +@property (nonatomic, retain, readonly) KWContextNode *context; + +#pragma mark - +#pragma mark Initializing + ++ (id)itNodeWithCallSite:(KWCallSite *)aCallSite + description:(NSString *)aDescription + context:(KWContextNode *)context + block:(KWVoidBlock)aBlock; + +@end diff --git a/Pods/Kiwi/Classes/KWItNode.m b/Pods/Kiwi/Classes/KWItNode.m new file mode 100644 index 0000000..44b9dee --- /dev/null +++ b/Pods/Kiwi/Classes/KWItNode.m @@ -0,0 +1,72 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWItNode.h" +#import "KWExampleNodeVisitor.h" +#import "KWExample.h" +#import "KWVerifying.h" +#import "KWContextNode.h" + +@interface KWItNode () + +@property (nonatomic, retain, readwrite) KWContextNode *context; + +@end + +@implementation KWItNode + +@synthesize context = _context; +@synthesize example; + +#pragma mark - +#pragma mark Initializing + ++ (id)itNodeWithCallSite:(KWCallSite *)aCallSite + description:(NSString *)aDescription + context:(KWContextNode *)context + block:(KWVoidBlock)aBlock; +{ + KWItNode *itNode = [[self alloc] initWithCallSite:aCallSite description:aDescription block:aBlock]; + itNode.context = context; + return [itNode autorelease]; +} + +#pragma mark - +#pragma mark Accepting Visitors + +- (void)acceptExampleNodeVisitor:(id)aVisitor { + [aVisitor visitItNode:self]; +} + +#pragma mark - +#pragma mark Runtime Description support + +- (NSString *)description +{ + NSString *description = [super description]; + if (description == nil) { + description = [self.example generateDescriptionForAnonymousItNode]; + } + return description; +} + +#pragma mark - +#pragma mark - Accessing the context stack + +- (NSArray *)contextStack +{ + NSMutableArray *contextStack = [NSMutableArray array]; + + KWContextNode *currentContext = _context; + + while (currentContext) { + [contextStack addObject:currentContext]; + currentContext = currentContext.parentContext; + } + return contextStack; +} + +@end diff --git a/Pods/Kiwi/Classes/KWMatchVerifier.h b/Pods/Kiwi/Classes/KWMatchVerifier.h new file mode 100644 index 0000000..7d4c64c --- /dev/null +++ b/Pods/Kiwi/Classes/KWMatchVerifier.h @@ -0,0 +1,45 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWExpectationType.h" +#import "KWVerifying.h" + +@class KWCallSite; +@class KWMatcherFactory; + +@protocol KWMatching; +@protocol KWReporting; + +@interface KWMatchVerifier : NSObject { +@private + KWExpectationType expectationType; + KWCallSite *callSite; + KWMatcherFactory *matcherFactory; + id reporter; + id subject; + id endOfExampleMatcher; +} + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) KWExpectationType expectationType; +@property (nonatomic, readonly) KWCallSite *callSite; +@property (nonatomic, readonly) KWMatcherFactory *matcherFactory; +@property (nonatomic, readonly) id reporter; +@property (nonatomic, readwrite, retain) id subject; + +#pragma mark - +#pragma mark Initializing + +- (id)initForShouldWithCallSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id)aReporter; +- (id)initForShouldNotWithCallSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id)aReporter; +- (id)initWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id)aReporter; + ++ (id)matchVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id)aReporter; + +@end diff --git a/Pods/Kiwi/Classes/KWMatchVerifier.m b/Pods/Kiwi/Classes/KWMatchVerifier.m new file mode 100644 index 0000000..1015ea6 --- /dev/null +++ b/Pods/Kiwi/Classes/KWMatchVerifier.m @@ -0,0 +1,181 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWMatchVerifier.h" +#import "KWFailure.h" +#import "KWFormatter.h" +#import "KWInvocationCapturer.h" +#import "KWMatcherFactory.h" +#import "KWReporting.h" +#import "KWStringUtilities.h" +#import "KWWorkarounds.h" +#import "NSInvocation+KiwiAdditions.h" +#import "NSMethodSignature+KiwiAdditions.h" + +@interface KWMatchVerifier() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite, retain) id endOfExampleMatcher; +@property (nonatomic, readwrite, retain) id matcher; + +@end + +@implementation KWMatchVerifier + +@synthesize matcher; + +#pragma mark - +#pragma mark Initializing + +- (id)initForShouldWithCallSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id)aReporter { + return [self initWithExpectationType:KWExpectationTypeShould callSite:aCallSite matcherFactory:aMatcherFactory reporter:aReporter]; +} + +- (id)initForShouldNotWithCallSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id)aReporter { + return [self initWithExpectationType:KWExpectationTypeShouldNot callSite:aCallSite matcherFactory:aMatcherFactory reporter:aReporter]; +} + +- (id)initWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id)aReporter { + if ((self = [super init])) { + expectationType = anExpectationType; + callSite = [aCallSite retain]; + matcherFactory = aMatcherFactory; + reporter = aReporter; + } + + return self; +} + ++ (id)matchVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite matcherFactory:(KWMatcherFactory *)aMatcherFactory reporter:(id)aReporter { + return [[[self alloc] initWithExpectationType:anExpectationType callSite:aCallSite matcherFactory:aMatcherFactory reporter:aReporter] autorelease]; +} + +- (void)dealloc { + [subject release]; + [callSite release]; + [matcher release]; + [endOfExampleMatcher release]; + [super dealloc]; +} + +- (NSString *)descriptionForAnonymousItNode +{ + NSString *typeString = @""; + + switch (self.expectationType) { + case KWExpectationTypeShould: + typeString = @"should"; + break; + case KWExpectationTypeShouldNot: + typeString = @"should not"; + } + id actualMatcher = (self.endOfExampleMatcher == nil) ? self.matcher : self.endOfExampleMatcher; + return [NSString stringWithFormat:@"%@ %@", typeString, actualMatcher]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize expectationType; +@synthesize callSite; +@synthesize matcherFactory; +@synthesize reporter; +@synthesize subject; +@synthesize endOfExampleMatcher; + +#pragma mark - +#pragma mark Verifying + +- (void)verifyWithMatcher:(id)aMatcher { + @try { + BOOL matchResult = [aMatcher evaluate]; + + if (self.expectationType == KWExpectationTypeShould && !matchResult) { + NSString *message = [aMatcher failureMessageForShould]; + KWFailure *failure = [KWFailure failureWithCallSite:self.callSite message:message]; + [self.reporter reportFailure:failure]; + } else if (self.expectationType == KWExpectationTypeShouldNot && matchResult) { + NSString *message = [aMatcher failureMessageForShouldNot]; + KWFailure *failure = [KWFailure failureWithCallSite:self.callSite message:message]; + [self.reporter reportFailure:failure]; + } + } @catch (NSException *exception) { + KWFailure *failure = [KWFailure failureWithCallSite:self.callSite message:[exception description]]; + [self.reporter reportFailure:failure]; + } +} + +#pragma mark - +#pragma mark Ending Examples + +- (void)exampleWillEnd { + if (self.endOfExampleMatcher == nil) + return; + + [self verifyWithMatcher:self.endOfExampleMatcher]; +} + +#pragma mark - +#pragma mark Handling Invocations + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { + NSMethodSignature *signature = [super methodSignatureForSelector:aSelector]; + + if (signature != nil) + return signature; + + signature = [self.matcherFactory methodSignatureForMatcherSelector:aSelector]; + + if (signature != nil) + return signature; + + // Return a dummy method signature so that problems can be handled in + // -forwardInvocation:. + NSString *encoding = KWEncodingForVoidMethod(); + return [NSMethodSignature signatureWithObjCTypes:[encoding UTF8String]]; +} + +- (void)forwardInvocation:(NSInvocation *)anInvocation { +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + @try { +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + + self.matcher = (id)[self.matcherFactory matcherFromInvocation:anInvocation subject:self.subject]; + + if (self.matcher == nil) { + KWFailure *failure = [KWFailure failureWithCallSite:self.callSite format:@"could not create matcher for -%@", + NSStringFromSelector(anInvocation.selector)]; + [self.reporter reportFailure:failure]; + } + [anInvocation invokeWithTarget:self.matcher]; + +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + // A matcher might have set an exception within the -invokeWithTarget, so + // raise if one was set. + NSException *exception = KWGetAndClearExceptionFromAcrossInvocationBoundary(); + [exception raise]; +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + + if ([self.matcher respondsToSelector:@selector(shouldBeEvaluatedAtEndOfExample)] && [self.matcher shouldBeEvaluatedAtEndOfExample]) { + self.endOfExampleMatcher = self.matcher; + self.matcher = nil; + } + else { + [self verifyWithMatcher:self.matcher]; + } + +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + } @catch (NSException *exception) { + KWFailure *failure = [KWFailure failureWithCallSite:self.callSite format:[exception reason]]; + [self.reporter reportFailure:failure]; + return; + } +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG +} + +@end diff --git a/Pods/Kiwi/Classes/KWMatcher.h b/Pods/Kiwi/Classes/KWMatcher.h new file mode 100644 index 0000000..e459e88 --- /dev/null +++ b/Pods/Kiwi/Classes/KWMatcher.h @@ -0,0 +1,48 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatching.h" + +@interface KWMatcher : NSObject { +@protected + id subject; +} + +#pragma mark - +#pragma mark Initializing + +- (id)initWithSubject:(id)anObject; + ++ (id)matcherWithSubject:(id)anObject; + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) id subject; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings; + +#pragma mark - +#pragma mark Getting Matcher Compatability + ++ (BOOL)canMatchSubject:(id)anObject; + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate; + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould; +- (NSString *)failureMessageForShouldNot; + +@end diff --git a/Pods/Kiwi/Classes/KWMatcher.m b/Pods/Kiwi/Classes/KWMatcher.m new file mode 100644 index 0000000..1c4d6d7 --- /dev/null +++ b/Pods/Kiwi/Classes/KWMatcher.m @@ -0,0 +1,91 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWMatcher.h" +#import "KWFormatter.h" +#import "KWFutureObject.h" + +@implementation KWMatcher + +#pragma mark - +#pragma mark Initializing + +- (id)initWithSubject:(id)anObject { + if ((self = [super init])) { + subject = [anObject retain]; + } + + return self; +} + ++ (id)matcherWithSubject:(id)anObject { + return [[[self alloc] initWithSubject:anObject] autorelease]; +} + +- (void)dealloc { + [subject release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize subject; + +- (id)subject +{ + if ([subject isKindOfClass:[KWFutureObject class]]) { + return [(KWFutureObject *)subject object]; + } + return subject; +} + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return nil; +} + +#pragma mark - +#pragma mark Getting Matcher Compatability + ++ (BOOL)canMatchSubject:(id)anObject { + return YES; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + [NSException raise:NSInternalInconsistencyException format:@"%@ must override -evaluate", + [KWFormatter formatObject:[self class]]]; + return NO; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return @"subject did not meet expectation"; +} + +- (NSString *)failureMessageForShouldNot { + NSString *failureMessageForShould = [self failureMessageForShould]; + NSRange markerRange = [failureMessageForShould rangeOfString:@" to "]; + + if (markerRange.location == NSNotFound) + return @"subject did not meet expectation"; + + NSRange replacementRange = NSMakeRange(0, markerRange.location + markerRange.length); + NSString *message = [failureMessageForShould stringByReplacingOccurrencesOfString:@" to " + withString:@" not to " + options:0 + range:replacementRange]; + return message; +} + +@end diff --git a/Pods/Kiwi/Classes/KWMatcherFactory.h b/Pods/Kiwi/Classes/KWMatcherFactory.h new file mode 100644 index 0000000..7048ce8 --- /dev/null +++ b/Pods/Kiwi/Classes/KWMatcherFactory.h @@ -0,0 +1,51 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatching.h" + +@class KWFailure; +@class KWMatcher; +@class KWUserDefinedMatcherBuilder; + +@interface KWMatcherFactory : NSObject { +@private + NSMutableArray *registeredMatcherClasses; + NSMutableDictionary *matcherClassChains; +} + +#pragma mark - +#pragma mark Initializing + +- (id)init; + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) NSArray *registeredMatcherClasses; + +#pragma mark - +#pragma mark Registering Matcher Classes + +- (void)registerMatcherClass:(Class)aClass; +- (void)registerMatcherClassesWithNamespacePrefix:(NSString *)aNamespacePrefix; + +#pragma mark - +#pragma mark Registering User Defined Matchers + +//- (void)registerUserDefinedMatcherWithBuilder:(KWUserDefinedMatcherBuilder *)aBuilder; + +#pragma mark - +#pragma mark Getting Method Signatures + +- (NSMethodSignature *)methodSignatureForMatcherSelector:(SEL)aSelector; + +#pragma mark - +#pragma mark Getting Matchers + +- (KWMatcher *)matcherFromInvocation:(NSInvocation *)anInvocation subject:(id)subject; + +@end diff --git a/Pods/Kiwi/Classes/KWMatcherFactory.m b/Pods/Kiwi/Classes/KWMatcherFactory.m new file mode 100644 index 0000000..8a796ab --- /dev/null +++ b/Pods/Kiwi/Classes/KWMatcherFactory.m @@ -0,0 +1,155 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWMatcherFactory.h" +#import +#import "KWMatching.h" +#import "KWStringUtilities.h" +#import "KWUserDefinedMatcher.h" +#import "KWMatchers.h" + +@interface KWMatcherFactory() +- (Class)matcherClassForSelector:(SEL)aSelector subject:(id)anObject; +@end + +@implementation KWMatcherFactory + +#pragma mark - +#pragma mark Initializing + +- (id)init { + if ((self = [super init])) { + matcherClassChains = [[NSMutableDictionary alloc] init]; + registeredMatcherClasses = [[NSMutableArray alloc] init]; + } + + return self; +} + +- (void)dealloc { + [registeredMatcherClasses release]; + [matcherClassChains release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize registeredMatcherClasses; + +#pragma mark - +#pragma mark Registering Matcher Classes + +- (void)registerMatcherClass:(Class)aClass { + if ([self.registeredMatcherClasses containsObject:aClass]) + return; + + [registeredMatcherClasses addObject:aClass]; + + for (NSString *verificationSelectorString in [aClass matcherStrings]) { + NSMutableArray *matcherClassChain = matcherClassChains[verificationSelectorString]; + + if (matcherClassChain == nil) { + matcherClassChain = [[NSMutableArray alloc] init]; + matcherClassChains[verificationSelectorString] = matcherClassChain; + [matcherClassChain release]; + } + + [matcherClassChain removeObject:aClass]; + [matcherClassChain insertObject:aClass atIndex:0]; + } +} + +- (void)registerMatcherClassesWithNamespacePrefix:(NSString *)aNamespacePrefix { + static NSMutableArray *matcherClasses = nil; + + // Cache all classes that conform to KWMatching. + if (matcherClasses == nil) { + matcherClasses = [[NSMutableArray alloc] init]; + int numberOfClasses = objc_getClassList(NULL, 0); + Class *classes = malloc(sizeof(Class) * numberOfClasses); + numberOfClasses = objc_getClassList(classes, numberOfClasses); + + if (numberOfClasses == 0) { + free(classes); + return; + } + + for (int i = 0; i < numberOfClasses; ++i) { + Class candidateClass = classes[i]; + + if (!class_respondsToSelector(candidateClass, @selector(conformsToProtocol:))) + continue; + + if (![candidateClass conformsToProtocol:@protocol(KWMatching)]) + continue; + + [matcherClasses addObject:candidateClass]; + } + + free(classes); + } + + for (Class matcherClass in matcherClasses) { + NSString *className = NSStringFromClass(matcherClass); + + if (KWStringHasStrictWordPrefix(className, aNamespacePrefix)) + [self registerMatcherClass:matcherClass]; + } +} + +#pragma mark - +#pragma mark Registering User Defined Matchers + +//- (void)registerUserDefinedMatcherWithBuilder:(KWUserDefinedMatcherBuilder *)aBuilder +//{ +// +//} + +#pragma mark - +#pragma mark Getting Method Signatures + +- (NSMethodSignature *)methodSignatureForMatcherSelector:(SEL)aSelector { + NSMutableArray *matcherClassChain = matcherClassChains[NSStringFromSelector(aSelector)]; + + if ([matcherClassChain count] == 0) + return nil; + + Class matcherClass = matcherClassChain[0]; + return [matcherClass instanceMethodSignatureForSelector:aSelector]; +} + +#pragma mark - +#pragma mark Getting Matchers + +- (KWMatcher *)matcherFromInvocation:(NSInvocation *)anInvocation subject:(id)subject { + SEL selector = [anInvocation selector]; + + // try and match a built-in or registered matcher class + Class matcherClass = [self matcherClassForSelector:selector subject:subject]; + + if (matcherClass == nil) { + // see if we can match with a user-defined matcher instead + return [[KWMatchers matchers] matcherForSelector:selector subject:subject]; + } + return [[[matcherClass alloc] initWithSubject:subject] autorelease]; +} + +#pragma mark - +#pragma mark Private methods + +- (Class)matcherClassForSelector:(SEL)aSelector subject:(id)anObject { + NSArray *matcherClassChain = matcherClassChains[NSStringFromSelector(aSelector)]; + + for (Class matcherClass in matcherClassChain) { + if ([matcherClass canMatchSubject:anObject]) + return matcherClass; + } + + return nil; +} + +@end diff --git a/Pods/Kiwi/Classes/KWMatchers.h b/Pods/Kiwi/Classes/KWMatchers.h new file mode 100644 index 0000000..dfe3d9a --- /dev/null +++ b/Pods/Kiwi/Classes/KWMatchers.h @@ -0,0 +1,35 @@ +// +// KWMatchers.h +// Kiwi +// +// Created by Luke Redpath on 17/06/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import + +@class KWUserDefinedMatcherBuilder; + +typedef void (^KWMatchersBuildingBlock)(KWUserDefinedMatcherBuilder *); + +@class KWUserDefinedMatcher; + +@interface KWMatchers : NSObject { + NSMutableDictionary *userDefinedMatchers; +} ++ (id)matchers; + +#pragma mark - +#pragma mark Defining Matchers + ++ (void)defineMatcher:(NSString *)selectorString as:(KWMatchersBuildingBlock)block; +- (void)defineMatcher:(NSString *)selectorString as:(KWMatchersBuildingBlock)block; +- (void)addUserDefinedMatcherBuilder:(KWUserDefinedMatcherBuilder *)builder; + +#pragma mark - +#pragma mark Building Matchers + +- (KWUserDefinedMatcher *)matcherForSelector:(SEL)selector subject:(id)subject; +@end + +void KWDefineMatchers(NSString *selectorString, KWMatchersBuildingBlock block); diff --git a/Pods/Kiwi/Classes/KWMatchers.m b/Pods/Kiwi/Classes/KWMatchers.m new file mode 100644 index 0000000..9a680e1 --- /dev/null +++ b/Pods/Kiwi/Classes/KWMatchers.m @@ -0,0 +1,72 @@ +// +// KWMatchers.m +// Kiwi +// +// Created by Luke Redpath on 17/06/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import "KWMatchers.h" +#import "KWUserDefinedMatcher.h" + +@implementation KWMatchers + +#pragma mark - +#pragma mark Singleton implementation + +static id sharedMatchers = nil; + ++ (void)initialize { + if (self == [KWMatchers class]) { + sharedMatchers = [[self alloc] init]; + } +} + ++ (id)matchers { + return sharedMatchers; +} + +- (id)init { + if ((self = [super init])) { + userDefinedMatchers = [[NSMutableDictionary alloc] init]; + } + return self; +} + +#pragma mark - +#pragma mark Defining Matchers + ++ (void)defineMatcher:(NSString *)selectorString as:(KWMatchersBuildingBlock)block { + [[self matchers] defineMatcher:selectorString as:block]; +} + +- (void)defineMatcher:(NSString *)selectorString as:(KWMatchersBuildingBlock)block { + KWUserDefinedMatcherBuilder *builder = [KWUserDefinedMatcherBuilder builderForSelector:NSSelectorFromString(selectorString)]; + block(builder); + userDefinedMatchers[builder.key] = builder; +} + +- (void)addUserDefinedMatcherBuilder:(KWUserDefinedMatcherBuilder *)builder { + userDefinedMatchers[builder.key] = builder; +} + +#pragma mark - +#pragma mark Building Matchers + +- (KWUserDefinedMatcher *)matcherForSelector:(SEL)selector subject:(id)subject { + KWUserDefinedMatcherBuilder *builder = userDefinedMatchers[NSStringFromSelector(selector)]; + + if (builder == nil) + return nil; + + return [builder buildMatcherWithSubject:subject]; +} + + +@end + +void KWDefineMatchers(NSString *selectorString, KWMatchersBuildingBlock block) +{ + [KWMatchers defineMatcher:selectorString as:block]; +} + diff --git a/Pods/Kiwi/Classes/KWMatching.h b/Pods/Kiwi/Classes/KWMatching.h new file mode 100644 index 0000000..60a1f30 --- /dev/null +++ b/Pods/Kiwi/Classes/KWMatching.h @@ -0,0 +1,45 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@protocol KWMatching + +#pragma mark - +#pragma mark Initializing + +- (id)initWithSubject:(id)anObject; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings; + +#pragma mark - +#pragma mark Getting Matcher Compatability + ++ (BOOL)canMatchSubject:(id)anObject; + +#pragma mark - +#pragma mark Matching + +@optional + +- (BOOL)shouldBeEvaluatedAtEndOfExample; +- (BOOL)willEvaluateMultipleTimes; +- (void)setWillEvaluateMultipleTimes:(BOOL)shouldEvaluateMultipleTimes; + +@required + +- (BOOL)evaluate; + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould; +- (NSString *)failureMessageForShouldNot; + +@end diff --git a/Pods/Kiwi/Classes/KWMessagePattern.h b/Pods/Kiwi/Classes/KWMessagePattern.h new file mode 100644 index 0000000..213cb8d --- /dev/null +++ b/Pods/Kiwi/Classes/KWMessagePattern.h @@ -0,0 +1,49 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@interface KWMessagePattern : NSObject { +@private + SEL selector; + NSArray *argumentFilters; +} + +#pragma mark - +#pragma mark Initializing + +- (id)initWithSelector:(SEL)aSelector; +- (id)initWithSelector:(SEL)aSelector argumentFilters:(NSArray *)anArray; +- (id)initWithSelector:(SEL)aSelector firstArgumentFilter:(id)firstArgumentFilter argumentList:(va_list)argumentList; + ++ (id)messagePatternWithSelector:(SEL)aSelector; ++ (id)messagePatternWithSelector:(SEL)aSelector argumentFilters:(NSArray *)anArray; ++ (id)messagePatternWithSelector:(SEL)aSelector firstArgumentFilter:(id)firstArgumentFilter argumentList:(va_list)argumentList; + ++ (id)messagePatternFromInvocation:(NSInvocation *)anInvocation; + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) SEL selector; +@property (nonatomic, readonly) NSArray *argumentFilters; + +#pragma mark - +#pragma mark Matching Invocations + +- (BOOL)matchesInvocation:(NSInvocation *)anInvocation; + +#pragma mark - +#pragma mark Comparing Message Patterns + +- (BOOL)isEqualToMessagePattern:(KWMessagePattern *)aMessagePattern; + +#pragma mark - +#pragma mark Retrieving String Representations + +- (NSString *)stringValue; + +@end diff --git a/Pods/Kiwi/Classes/KWMessagePattern.m b/Pods/Kiwi/Classes/KWMessagePattern.m new file mode 100644 index 0000000..2a12c1f --- /dev/null +++ b/Pods/Kiwi/Classes/KWMessagePattern.m @@ -0,0 +1,231 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWMessagePattern.h" +#import "KWFormatter.h" +#import "KWNull.h" +#import "KWObjCUtilities.h" +#import "KWValue.h" +#import "NSInvocation+KiwiAdditions.h" +#import "NSMethodSignature+KiwiAdditions.h" +#import "KWGenericMatchEvaluator.h" +#import "Kiwi.h" + +@implementation KWMessagePattern + +#pragma mark - +#pragma mark Initializing + +- (id)initWithSelector:(SEL)aSelector { + return [self initWithSelector:aSelector argumentFilters:nil]; +} + +- (id)initWithSelector:(SEL)aSelector argumentFilters:(NSArray *)anArray { + if ((self = [super init])) { + selector = aSelector; + + if ([anArray count] > 0) + argumentFilters = [anArray copy]; + } + + return self; +} + +- (id)initWithSelector:(SEL)aSelector firstArgumentFilter:(id)firstArgumentFilter argumentList:(va_list)argumentList { + NSUInteger count = KWSelectorParameterCount(aSelector); + NSMutableArray *array = [NSMutableArray arrayWithCapacity:count]; + [array addObject:(firstArgumentFilter != nil) ? firstArgumentFilter : [KWNull null]]; + + for (NSUInteger i = 1; i < count; ++i) + { + id object = va_arg(argumentList, id); + [array addObject:(object != nil) ? object : [KWNull null]]; + } + + va_end(argumentList); + return [self initWithSelector:aSelector argumentFilters:array]; +} + ++ (id)messagePatternWithSelector:(SEL)aSelector { + return [self messagePatternWithSelector:aSelector argumentFilters:nil]; +} + ++ (id)messagePatternWithSelector:(SEL)aSelector argumentFilters:(NSArray *)anArray { + return [[[self alloc] initWithSelector:aSelector argumentFilters:anArray] autorelease]; +} + ++ (id)messagePatternWithSelector:(SEL)aSelector firstArgumentFilter:(id)firstArgumentFilter argumentList:(va_list)argumentList { + return [[[self alloc] initWithSelector:aSelector firstArgumentFilter:firstArgumentFilter argumentList:argumentList] autorelease]; +} + ++ (id)messagePatternFromInvocation:(NSInvocation *)anInvocation { + NSMethodSignature *signature = [anInvocation methodSignature]; + NSUInteger numberOfMessageArguments = [signature numberOfMessageArguments]; + NSMutableArray *argumentFilters = nil; + + if (numberOfMessageArguments > 0) { + argumentFilters = [[NSMutableArray alloc] initWithCapacity:numberOfMessageArguments]; + + for (NSUInteger i = 0; i < numberOfMessageArguments; ++i) { + const char *type = [signature messageArgumentTypeAtIndex:i]; + id object = nil; + + if (KWObjCTypeIsObject(type)) { + [anInvocation getMessageArgument:&object atIndex:i]; + } else { + NSData *data = [anInvocation messageArgumentDataAtIndex:i]; + object = [KWValue valueWithBytes:[data bytes] objCType:type]; + } + + + if (strcmp(type, "@?") == 0) object = [[object copy] autorelease]; // Converting NSStackBlock to NSMallocBlock + [argumentFilters addObject:(object != nil) ? object : [KWNull null]]; + } + } + + return [self messagePatternWithSelector:[anInvocation selector] argumentFilters:[argumentFilters autorelease]]; +} + +- (void)dealloc { + [argumentFilters release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Copying + +- (id)copyWithZone:(NSZone *)zone { + return [self retain]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize selector; +@synthesize argumentFilters; + +#pragma mark - +#pragma mark Matching Invocations + +- (BOOL)argumentFiltersMatchInvocationArguments:(NSInvocation *)anInvocation { + if (self.argumentFilters == nil) + return YES; + + NSMethodSignature *signature = [anInvocation methodSignature]; + NSUInteger numberOfArgumentFilters = [self.argumentFilters count]; + NSUInteger numberOfMessageArguments = [signature numberOfMessageArguments]; + + for (NSUInteger i = 0; i < numberOfMessageArguments && i < numberOfArgumentFilters; ++i) { + const char *objCType = [signature messageArgumentTypeAtIndex:i]; + id object = nil; + + // Extract message argument into object (wrapping values if neccesary) + if (KWObjCTypeIsObject(objCType)) { + [anInvocation getMessageArgument:&object atIndex:i]; + } else { + NSData *data = [anInvocation messageArgumentDataAtIndex:i]; + object = [KWValue valueWithBytes:[data bytes] objCType:objCType]; + } + + // Match argument filter to object + id argumentFilter = (self.argumentFilters)[i]; + + if ([argumentFilter isEqual:[KWAny any]]) { + continue; + } + + if ([KWGenericMatchEvaluator isGenericMatcher:argumentFilter]) { + id matcher = argumentFilter; + if ([object isKindOfClass:[KWValue class]] && [object isNumeric]) { + NSNumber *number = [object numberValue]; + if (![KWGenericMatchEvaluator genericMatcher:matcher matches:number]) { + return NO; + } + } else if (![KWGenericMatchEvaluator genericMatcher:matcher matches:object]) { + return NO; + } + } else if ([argumentFilter isEqual:[KWNull null]]) { + if (!KWObjCTypeIsPointerLike(objCType)) { + [NSException raise:@"KWMessagePatternException" format:@"nil was specified as an argument filter, but argument(%d) is not a pointer for @selector(%@)", (int)(i + 1), NSStringFromSelector([anInvocation selector])]; + } + void *p = nil; + [anInvocation getMessageArgument:&p atIndex:i]; + if (p != nil) + return NO; + } else if (![argumentFilter isEqual:object]) { + return NO; + } + } + + return YES; +} + +- (BOOL)matchesInvocation:(NSInvocation *)anInvocation { + return self.selector == [anInvocation selector] && [self argumentFiltersMatchInvocationArguments:anInvocation]; +} + +#pragma mark - +#pragma mark Comparing Message Patterns + +- (NSUInteger)hash { + return [NSStringFromSelector(self.selector) hash]; +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[KWMessagePattern class]]) + return NO; + + return [self isEqualToMessagePattern:object]; +} + +- (BOOL)isEqualToMessagePattern:(KWMessagePattern *)aMessagePattern { + if (self.selector != aMessagePattern.selector) + return NO; + + if (self.argumentFilters == nil && aMessagePattern.argumentFilters == nil) + return YES; + + return [self.argumentFilters isEqualToArray:aMessagePattern.argumentFilters]; +} + +#pragma mark - +#pragma mark Retrieving String Representations + +- (NSString *)selectorString { + return NSStringFromSelector(self.selector); +} + +- (NSString *)selectorAndArgumentFiltersString { + NSMutableString *description = [[[NSMutableString alloc] init] autorelease]; + NSArray *components = [NSStringFromSelector(self.selector) componentsSeparatedByString:@":"]; + NSUInteger count = [components count] - 1; + + for (NSUInteger i = 0; i < count; ++i) { + NSString *selectorComponent = components[i]; + NSString *argumentFilterString = [KWFormatter formatObject:(self.argumentFilters)[i]]; + [description appendFormat:@"%@:%@ ", selectorComponent, argumentFilterString]; + } + + return description; +} + +- (NSString *)stringValue { + if (self.argumentFilters == nil) + return [self selectorString]; + else + return [self selectorAndArgumentFiltersString]; +} + +#pragma mark - +#pragma mark Debugging + +- (NSString *)description { + return [NSString stringWithFormat:@"selector: %@\nargumentFilters: %@", + NSStringFromSelector(self.selector), + self.argumentFilters]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWMessageSpying.h b/Pods/Kiwi/Classes/KWMessageSpying.h new file mode 100644 index 0000000..7b7d46c --- /dev/null +++ b/Pods/Kiwi/Classes/KWMessageSpying.h @@ -0,0 +1,16 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@protocol KWMessageSpying + +#pragma mark - +#pragma mark Spying on Messages + +- (void)object:(id)anObject didReceiveInvocation:(NSInvocation *)anInvocation; + +@end diff --git a/Pods/Kiwi/Classes/KWMessageTracker.h b/Pods/Kiwi/Classes/KWMessageTracker.h new file mode 100644 index 0000000..188e563 --- /dev/null +++ b/Pods/Kiwi/Classes/KWMessageTracker.h @@ -0,0 +1,53 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWCountType.h" +#import "KWMessageSpying.h" + +@class KWMessagePattern; + +@interface KWMessageTracker : NSObject { +@private + id subject; + KWMessagePattern *messagePattern; + KWCountType countType; + NSUInteger count; + NSUInteger receivedCount; +} + +#pragma mark - +#pragma mark Initializing + +- (id)initWithSubject:(id)anObject messagePattern:(KWMessagePattern *)aMessagePattern countType:(KWCountType)aCountType count:(NSUInteger)aCount; + ++ (id)messageTrackerWithSubject:(id)anObject messagePattern:(KWMessagePattern *)aMessagePattern countType:(KWCountType)aCountType count:(NSUInteger)aCount; + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) id subject; +@property (nonatomic, readonly) KWMessagePattern *messagePattern; +@property (nonatomic, readonly) KWCountType countType; +@property (nonatomic, readonly) NSUInteger count; + +#pragma mark - +#pragma mark Stopping Tracking + +- (void)stopTracking; + +#pragma mark - +#pragma mark Getting Message Tracker Status + +- (BOOL)succeeded; + +#pragma mark - +#pragma mark Getting Phrases + +- (NSString *)expectedCountPhrase; +- (NSString *)receivedCountPhrase; + +@end diff --git a/Pods/Kiwi/Classes/KWMessageTracker.m b/Pods/Kiwi/Classes/KWMessageTracker.m new file mode 100644 index 0000000..5019441 --- /dev/null +++ b/Pods/Kiwi/Classes/KWMessageTracker.m @@ -0,0 +1,151 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWMessageTracker.h" +#import "KWMessagePattern.h" +#import "NSObject+KiwiStubAdditions.h" + +@interface KWMessageTracker() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite) NSUInteger receivedCount; + +@end + +@implementation KWMessageTracker + +#pragma mark - +#pragma mark Initializing + +- (id)initWithSubject:(id)anObject messagePattern:(KWMessagePattern *)aMessagePattern countType:(KWCountType)aCountType count:(NSUInteger)aCount { + if ((self = [super init])) { + subject = [anObject retain]; + messagePattern = [aMessagePattern retain]; + countType = aCountType; + count = aCount; + [anObject addMessageSpy:self forMessagePattern:messagePattern]; + } + + return self; +} + ++ (id)messageTrackerWithSubject:(id)anObject messagePattern:(KWMessagePattern *)aMessagePattern countType:(KWCountType)aCountType count:(NSUInteger)aCount { + return [[[self alloc] initWithSubject:anObject messagePattern:aMessagePattern countType:aCountType count:aCount] autorelease]; +} + +- (void)dealloc { + [subject release]; + [messagePattern release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize subject; +@synthesize messagePattern; +@synthesize countType; +@synthesize count; +@synthesize receivedCount; + +#pragma mark - +#pragma mark Spying on Messages + +- (void)object:(id)anObject didReceiveInvocation:(NSInvocation *)anInvocation { + if (![self.messagePattern matchesInvocation:anInvocation]) + return; + + ++self.receivedCount; +} + +#pragma mark - +#pragma mark Stopping Tracking + +- (void)stopTracking { + [self.subject removeMessageSpy:self forMessagePattern:self.messagePattern]; +} + +#pragma mark - +#pragma mark Getting Message Tracker Status + +- (BOOL)succeeded { + switch (self.countType) { + case KWCountTypeExact: + return self.receivedCount == self.count; + case KWCountTypeAtLeast: + return self.receivedCount >= self.count; + case KWCountTypeAtMost: + return self.receivedCount <= self.count; + default: + break; + } + + assert(0 && "should never reach here"); + return NO; +} + +#pragma mark - +#pragma mark Getting Phrases + +- (NSString *)phraseForCount:(NSUInteger)aCount { + if (aCount == 1) + return @"1 time"; + + return [NSString stringWithFormat:@"%d times", (int)aCount]; +} + +- (NSString *)expectedCountPhrase { + NSString *countPhrase = [self phraseForCount:self.count]; + + switch (self.countType) { + case KWCountTypeExact: + return [NSString stringWithFormat:@"exactly %@", countPhrase]; + case KWCountTypeAtLeast: + return [NSString stringWithFormat:@"at least %@", countPhrase]; + case KWCountTypeAtMost: + return [NSString stringWithFormat:@"at most %@", countPhrase]; + default: + break; + } + + assert(0 && "should never reach here"); + return nil; +} + +- (NSString *)receivedCountPhrase { + return [self phraseForCount:self.receivedCount]; +} + +#pragma mark - +#pragma mark Debugging + +- (NSString *)modeString { + switch (self.countType) { + case KWCountTypeExact: + return @"KWCountTypeExact"; + case KWCountTypeAtLeast: + return @"KWCountTypeAtLeast"; + case KWCountTypeAtMost: + return @"KWCountTypeAtMost"; + default: + break; + } + + assert(0 && "should never reach here"); + return nil; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"messagePattern: %@\nmode: %@\ncount: %d\nreceiveCount: %d", + self.messagePattern, + self.modeString, + (int)self.count, + (int)self.receivedCount]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWMock.h b/Pods/Kiwi/Classes/KWMock.h new file mode 100644 index 0000000..4ea222d --- /dev/null +++ b/Pods/Kiwi/Classes/KWMock.h @@ -0,0 +1,103 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWInvocationCapturer.h" + +@class KWMessagePattern; +@class KWCaptureSpy; + +@protocol KWMessageSpying; +@protocol KWVerifying; + +@interface KWMock : NSObject { +@private + BOOL isPartialMock; + BOOL isNullMock; + NSString *mockName; + id mockedObject; + Class mockedClass; + Protocol *mockedProtocol; + NSMutableArray *stubs; + NSMutableArray *expectedMessagePatterns; + NSMutableDictionary *messageSpies; +} + +#pragma mark - +#pragma mark Initializing + +- (id)initForClass:(Class)aClass; +- (id)initForProtocol:(Protocol *)aProtocol; +- (id)initWithName:(NSString *)aName forClass:(Class)aClass; +- (id)initWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol; + +- (id)initAsNullMockForClass:(Class)aClass; +- (id)initAsNullMockForProtocol:(Protocol *)aProtocol; +- (id)initAsNullMockWithName:(NSString *)aName forClass:(Class)aClass; +- (id)initAsNullMockWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol; + +- (id)initAsPartialMockForObject:(id)object; +- (id)initAsPartialMockWithName:(NSString *)aName forObject:(id)object; + ++ (id)mockForClass:(Class)aClass; ++ (id)mockForProtocol:(Protocol *)aProtocol; ++ (id)mockWithName:(NSString *)aName forClass:(Class)aClass; ++ (id)mockWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol; + ++ (id)nullMockForClass:(Class)aClass; ++ (id)nullMockForProtocol:(Protocol *)aProtocol; ++ (id)nullMockWithName:(NSString *)aName forClass:(Class)aClass ; ++ (id)nullMockWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol; + ++ (id)partialMockForObject:(id)object; ++ (id)partialMockWithName:(NSString *)aName forObject:(id)object; + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) BOOL isNullMock; +@property (nonatomic, readonly) BOOL isPartialMock; +@property (nonatomic, readonly) NSString *mockName; +@property (nonatomic, readonly) Class mockedClass; +@property (nonatomic, readonly) id mockedObject; +@property (nonatomic, readonly) Protocol *mockedProtocol; + +#pragma mark - +#pragma mark Stubbing Methods + +- (void)stub:(SEL)aSelector; +- (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *params))block; +- (void)stub:(SEL)aSelector withArguments:(id)firstArgument, ...; +- (void)stub:(SEL)aSelector andReturn:(id)aValue; +- (void)stub:(SEL)aSelector andReturn:(id)aValue withArguments:(id)firstArgument, ...; + +- (id)stub; +- (id)stubAndReturn:(id)aValue; +- (id)stubAndReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue; + +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue; +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue; + +- (void)clearStubs; + +#pragma mark - +#pragma mark Spying on Messages + +- (void)addMessageSpy:(id)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern; +- (void)removeMessageSpy:(id)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern; + + +#pragma mark - +#pragma mark Expecting Messages + +- (void)expect:(SEL)aSelector; +- (void)expect:(SEL)aSelector withArguments:(id)firstArgument, ...; + +- (id)expect; + +- (void)expectMessagePattern:(KWMessagePattern *)aMessagePattern; + +@end diff --git a/Pods/Kiwi/Classes/KWMock.m b/Pods/Kiwi/Classes/KWMock.m new file mode 100644 index 0000000..55d5c31 --- /dev/null +++ b/Pods/Kiwi/Classes/KWMock.m @@ -0,0 +1,672 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWMock.h" +#import +#import "KWFormatter.h" +#import "KWMessagePattern.h" +#import "KWMessageSpying.h" +#import "KWStringUtilities.h" +#import "KWStub.h" +#import "KWWorkarounds.h" +#import "NSInvocation+KiwiAdditions.h" +#import "KWCaptureSpy.h" + +static NSString * const ExpectOrStubTagKey = @"ExpectOrStubTagKey"; +static NSString * const StubTag = @"StubTag"; +static NSString * const ExpectTag = @"ExpectTag"; +static NSString * const StubValueKey = @"StubValueKey"; +static NSString * const StubSecondValueKey = @"StubSecondValueKey"; +static NSString * const ChangeStubValueAfterTimesKey = @"ChangeStubValueAfterTimesKey"; + +@interface KWMock() + +#pragma mark - +#pragma mark Initializing + +- (id)initAsNullMock:(BOOL)nullMockFlag withName:(NSString *)aName forClass:(Class)aClass protocol:(Protocol *)aProtocol; + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) NSMutableArray *stubs; +@property (nonatomic, readonly) NSMutableArray *expectedMessagePatterns; +@property (nonatomic, readonly) NSMutableDictionary *messageSpies; + + +#pragma mark - +#pragma mark Handling Invocations + +- (BOOL)processReceivedInvocation:(NSInvocation *)invocation; + +@end + +@implementation KWMock + +#pragma mark - +#pragma mark Initializing + +- (id)init { + // May already have been initialized since stubbing -init is allowed! + if (self.stubs != nil) { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:_cmd]; + [self expectMessagePattern:messagePattern]; + NSInvocation *invocation = [NSInvocation invocationWithTarget:self selector:_cmd]; + + if ([self processReceivedInvocation:invocation]) { + id result = nil; + [invocation getReturnValue:&result]; + return result; + } else { + return self; + } + } + + return [self initAsNullMock:NO withName:nil forClass:nil protocol:nil]; +} + +- (id)initForClass:(Class)aClass { + return [self initAsNullMock:NO withName:nil forClass:aClass protocol:nil]; +} + +- (id)initForProtocol:(Protocol *)aProtocol { + return [self initAsNullMock:NO withName:nil forClass:nil protocol:aProtocol]; +} + +- (id)initWithName:(NSString *)aName forClass:(Class)aClass { + return [self initAsNullMock:NO withName:aName forClass:aClass protocol:nil]; +} + +- (id)initWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol { + return [self initAsNullMock:NO withName:aName forClass:nil protocol:aProtocol]; +} + +- (id)initAsNullMockForClass:(Class)aClass { + return [self initAsNullMock:YES withName:nil forClass:aClass protocol:nil]; +} + +- (id)initAsNullMockForProtocol:(Protocol *)aProtocol { + return [self initAsNullMock:YES withName:nil forClass:nil protocol:aProtocol]; +} + +- (id)initAsNullMockWithName:(NSString *)aName forClass:(Class)aClass { + return [self initAsNullMock:YES withName:aName forClass:aClass protocol:nil]; +} + +- (id)initAsNullMockWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol { + return [self initAsNullMock:YES withName:aName forClass:nil protocol:aProtocol]; +} + +- (id)initAsNullMock:(BOOL)nullMockFlag withName:(NSString *)aName forClass:(Class)aClass protocol:(Protocol *)aProtocol { + if ((self = [super init])) { + isNullMock = nullMockFlag; + mockName = [aName copy]; + mockedClass = aClass; + mockedProtocol = aProtocol; + stubs = [[NSMutableArray alloc] init]; + expectedMessagePatterns = [[NSMutableArray alloc] init]; + messageSpies = [[NSMutableDictionary alloc] init]; + } + + return self; +} + +- (id)initAsPartialMockForObject:(id)object { + return [self initAsPartialMockWithName:nil forObject:object]; +} + +- (id)initAsPartialMockWithName:(NSString *)aName forObject:(id)object { + if ((self = [self initAsNullMock:YES withName:aName forClass:[object class] protocol:nil])) { + isPartialMock = YES; + mockedObject = [object retain]; + } + return self; +} + ++ (id)mockForClass:(Class)aClass { + return [[[self alloc] initForClass:aClass] autorelease]; +} + ++ (id)mockForProtocol:(Protocol *)aProtocol { + return [[[self alloc] initForProtocol:aProtocol] autorelease]; +} + ++ (id)mockWithName:(NSString *)aName forClass:(Class)aClass { + return [[[self alloc] initWithName:aName forClass:aClass] autorelease]; +} + ++ (id)mockWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol { + return [[[self alloc] initWithName:aName forProtocol:aProtocol] autorelease]; +} + ++ (id)nullMockForClass:(Class)aClass { + return [[[self alloc] initAsNullMockForClass:aClass] autorelease]; +} + ++ (id)nullMockForProtocol:(Protocol *)aProtocol { + return [[[self alloc] initAsNullMockForProtocol:aProtocol] autorelease]; +} + ++ (id)nullMockWithName:(NSString *)aName forClass:(Class)aClass { + return [[[self alloc] initAsNullMockWithName:aName forClass:aClass] autorelease]; +} + ++ (id)nullMockWithName:(NSString *)aName forProtocol:(Protocol *)aProtocol { + return [[[self alloc] initAsNullMockWithName:aName forProtocol:aProtocol] autorelease]; +} + ++ (id)partialMockWithName:(NSString *)aName forObject:(id)object { + return [[[self alloc] initAsPartialMockWithName:aName forObject:object] autorelease]; +} + ++ (id)partialMockForObject:(id)object { + return [[[self alloc] initAsPartialMockForObject:object] autorelease]; +} + +- (void)dealloc { + [mockedObject release]; + [mockName release]; + [stubs release]; + [expectedMessagePatterns release]; + [messageSpies release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize isPartialMock; +@synthesize isNullMock; +@synthesize mockName; +@synthesize mockedObject; +@synthesize mockedClass; +@synthesize mockedProtocol; +@synthesize stubs; +@synthesize expectedMessagePatterns; +@synthesize messageSpies; + +#pragma mark - +#pragma mark Getting Transitive Closure For Mocked Protocols + +- (NSSet *)mockedProtocolTransitiveClosureSet { + if (self.mockedProtocol == nil) + return nil; + + NSMutableSet *protocolSet = [NSMutableSet set]; + NSMutableArray *protocolQueue = [NSMutableArray array]; + [protocolQueue addObject:self.mockedProtocol]; + + do { + Protocol *protocol = [protocolQueue lastObject]; + [protocolSet addObject:protocol]; + [protocolQueue removeLastObject]; + + unsigned int count = 0; + Protocol **protocols = (Protocol **)protocol_copyProtocolList(protocol, &count); + + if (count == 0) + continue; + + for (unsigned int i = 0; i < count; ++i) + [protocolQueue addObject:protocols[i]]; + + free(protocols); + } while ([protocolQueue count] != 0); + + return protocolSet; +} + +#pragma mark - +#pragma mark Stubbing Methods + +- (void)removeStubWithMessagePattern:(KWMessagePattern *)messagePattern { + KWStub *stub = [self currentStubWithMessagePattern:messagePattern]; + if (stub) { + [self.stubs removeObject:stub]; + } +} + +- (KWStub *)currentStubWithMessagePattern:(KWMessagePattern *)messagePattern { + NSUInteger stubCount = [self.stubs count]; + + for (NSUInteger i = 0; i < stubCount; ++i) { + KWStub *stub = (self.stubs)[i]; + + if ([stub.messagePattern isEqualToMessagePattern:messagePattern]) { + return stub; + } + } + return nil; +} + +- (void)stub:(SEL)aSelector { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self stubMessagePattern:messagePattern andReturn:nil]; +} + +- (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *params))block { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self stubMessagePattern:messagePattern withBlock:block]; +} + +- (void)stub:(SEL)aSelector withArguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [self stubMessagePattern:messagePattern andReturn:nil]; +} + +- (void)stub:(SEL)aSelector andReturn:(id)aValue { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self stubMessagePattern:messagePattern andReturn:aValue]; +} + +- (void)stub:(SEL)aSelector andReturn:(id)aValue withArguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [self stubMessagePattern:messagePattern andReturn:aValue]; +} + +- (id)stub { + NSDictionary *userInfo = @{ExpectOrStubTagKey: StubTag}; + return [KWInvocationCapturer invocationCapturerWithDelegate:self userInfo:userInfo]; +} + +- (id)stubAndReturn:(id)aValue { + NSDictionary *userInfo = @{ExpectOrStubTagKey: StubTag, + StubValueKey: aValue}; + return [KWInvocationCapturer invocationCapturerWithDelegate:self userInfo:userInfo]; +} + +- (id)stubAndReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue { + NSDictionary *userInfo = @{ExpectOrStubTagKey: StubTag, StubValueKey: aValue, ChangeStubValueAfterTimesKey: times, StubSecondValueKey: aSecondValue}; + return [KWInvocationCapturer invocationCapturerWithDelegate:self userInfo:userInfo]; +} + +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue { + [self stubMessagePattern:aMessagePattern andReturn:aValue overrideExisting:YES]; +} + +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue overrideExisting:(BOOL)overrideExisting { + [self expectMessagePattern:aMessagePattern]; + KWStub *existingStub = [self currentStubWithMessagePattern:aMessagePattern]; + if (existingStub) { + if (overrideExisting) { + [self.stubs removeObject:existingStub]; + } else { + return; + } + } + KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern value:aValue]; + [self.stubs addObject:stub]; +} + +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern withBlock:(id (^)(NSArray *params))block { + [self expectMessagePattern:aMessagePattern]; + [self removeStubWithMessagePattern:aMessagePattern]; + KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern block:block]; + [self.stubs addObject:stub]; +} + +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue { + [self expectMessagePattern:aMessagePattern]; + [self removeStubWithMessagePattern:aMessagePattern]; + KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern value:aValue times:times afterThatReturn:aSecondValue]; + [self.stubs addObject:stub]; +} + +- (void)clearStubs { + [self.stubs removeAllObjects]; +} + +#pragma mark - +#pragma mark Spying on Messages + +- (void)addMessageSpy:(id)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern { + [self expectMessagePattern:aMessagePattern]; + NSMutableArray *messagePatternSpies = (self.messageSpies)[aMessagePattern]; + + if (messagePatternSpies == nil) { + messagePatternSpies = [[NSMutableArray alloc] init]; + (self.messageSpies)[aMessagePattern] = messagePatternSpies; + [messagePatternSpies release]; + } + NSValue *spyWrapper = [NSValue valueWithNonretainedObject:aSpy]; + + if (![messagePatternSpies containsObject:spyWrapper]) + [messagePatternSpies addObject:spyWrapper]; +} + +- (void)removeMessageSpy:(id)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern { + NSValue *spyWrapper = [NSValue valueWithNonretainedObject:aSpy]; + NSMutableArray *messagePatternSpies = (self.messageSpies)[aMessagePattern]; + [messagePatternSpies removeObject:spyWrapper]; +} + +#pragma mark - +#pragma mark Expecting Message Patterns + +- (void)expect:(SEL)aSelector { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self expectMessagePattern:messagePattern]; +} + +- (void)expect:(SEL)aSelector withArguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [self expectMessagePattern:messagePattern]; +} + +- (id)expect { + NSDictionary *userInfo = @{ExpectOrStubTagKey: ExpectTag}; + return [KWInvocationCapturer invocationCapturerWithDelegate:self userInfo:userInfo]; +} + +- (void)expectMessagePattern:(KWMessagePattern *)aMessagePattern { + if (![self.expectedMessagePatterns containsObject:aMessagePattern]) + [self.expectedMessagePatterns addObject:aMessagePattern]; +} + +#pragma mark - +#pragma mark Capturing Invocations + +- (NSMethodSignature *)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer methodSignatureForSelector:(SEL)aSelector { + return [self methodSignatureForSelector:aSelector]; +} + +- (void)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer didCaptureInvocation:(NSInvocation *)anInvocation { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternFromInvocation:anInvocation]; + NSString *tag = (anInvocationCapturer.userInfo)[ExpectOrStubTagKey]; + if ([tag isEqualToString:StubTag]) { + id value = (anInvocationCapturer.userInfo)[StubValueKey]; + if (!(anInvocationCapturer.userInfo)[StubSecondValueKey]) { + [self stubMessagePattern:messagePattern andReturn:value]; + } else { + id times = (anInvocationCapturer.userInfo)[ChangeStubValueAfterTimesKey]; + id secondValue = (anInvocationCapturer.userInfo)[StubSecondValueKey]; + [self stubMessagePattern:messagePattern andReturn:value times:times afterThatReturn:secondValue]; + } + } else { + [self expectMessagePattern:messagePattern]; + } +} + +#pragma mark - +#pragma mark Handling Invocations + +- (NSString *)namePhrase { + if (self.mockName == nil) + return @"mock"; + else + return [NSString stringWithFormat:@"mock \"%@\"", self.mockName]; +} + +- (BOOL)processReceivedInvocation:(NSInvocation *)invocation { + for (KWMessagePattern *messagePattern in self.messageSpies) { + if ([messagePattern matchesInvocation:invocation]) { + NSArray *spies = (self.messageSpies)[messagePattern]; + + for (NSValue *spyWrapper in spies) { + id spy = [spyWrapper nonretainedObjectValue]; + [spy object:self didReceiveInvocation:invocation]; + } + } + } + + for (KWStub *stub in self.stubs) { + if ([stub processInvocation:invocation]) + return YES; + } + + return NO; +} + +- (NSMethodSignature *)mockedProtocolMethodSignatureForSelector:(SEL)aSelector { + NSSet *protocols = [self mockedProtocolTransitiveClosureSet]; + + for (Protocol *protocol in protocols) { + struct objc_method_description description = protocol_getMethodDescription(protocol, aSelector, NO, YES); + + if (description.types == nil) + description = protocol_getMethodDescription(protocol, aSelector, YES, YES); + + if (description.types != nil) + return [NSMethodSignature signatureWithObjCTypes:description.types]; + } + + return nil; +} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { + NSMethodSignature *methodSignature = [self.mockedClass instanceMethodSignatureForSelector:aSelector]; + + if (methodSignature != nil) + return methodSignature; + + methodSignature = [self mockedProtocolMethodSignatureForSelector:aSelector]; + + if (methodSignature != nil) + return methodSignature; + + NSString *encoding = KWEncodingForVoidMethod(); + return [NSMethodSignature signatureWithObjCTypes:[encoding UTF8String]]; +} + +- (void)forwardInvocation:(NSInvocation *)anInvocation { +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + @try { +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + + if ([self processReceivedInvocation:anInvocation]) + return; + + if (isPartialMock) + [anInvocation invokeWithTarget:self.mockedObject]; + + if (self.isNullMock) + return; + + for (KWMessagePattern *expectedMessagePattern in self.expectedMessagePatterns) { + if ([expectedMessagePattern matchesInvocation:anInvocation]) + return; + } + + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternFromInvocation:anInvocation]; + [NSException raise:@"KWMockException" format:@"%@ received unexpected message -%@", + [self namePhrase], + [messagePattern stringValue]]; + +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + } @catch (NSException *exception) { + KWSetExceptionFromAcrossInvocationBoundary(exception); + } +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG +} + +#pragma mark - +#pragma mark Testing Objects + +- (BOOL)mockedClassHasAncestorClass:(Class)aClass { + Class currentClass = self.mockedClass; + + while (currentClass != nil) { + if (currentClass == aClass) + return YES; + + currentClass = [currentClass superclass]; + } + + return NO; +} + +- (BOOL)mockedClassRespondsToSelector:(SEL)aSelector { + return [self.mockedClass instancesRespondToSelector:aSelector]; +} + +- (BOOL)mockedClassConformsToProtocol:(Protocol *)aProtocol { + return [self.mockedClass conformsToProtocol:aProtocol]; +} + +- (BOOL)mockedProtocolRespondsToSelector:(SEL)aSelector { + NSSet *protocols = [self mockedProtocolTransitiveClosureSet]; + + for (Protocol *protocol in protocols) { + struct objc_method_description description = protocol_getMethodDescription(protocol, aSelector, NO, YES); + + if (description.types == nil) + description = protocol_getMethodDescription(protocol, aSelector, YES, YES); + + if (description.types != nil) + return YES; + } + + return NO; +} + +- (BOOL)mockedProtocolConformsToProtocol:(Protocol *)aProtocol { + if (self.mockedProtocol == nil) + return NO; + + return protocol_isEqual(self.mockedProtocol, aProtocol) || protocol_conformsToProtocol(self.mockedProtocol, aProtocol); +} + +- (BOOL)isKindOfClass:(Class)aClass { + return [self mockedClassHasAncestorClass:aClass] || [super isKindOfClass:aClass]; +} + +- (BOOL)isMemberOfClass:(Class)aClass { + return self.mockedClass == aClass || [super isMemberOfClass:aClass]; +} + +- (BOOL)respondsToSelector:(SEL)aSelector { + return [self mockedClassRespondsToSelector:aSelector] || + [self mockedProtocolRespondsToSelector:aSelector] || + [super respondsToSelector:aSelector]; +} + +- (BOOL)conformsToProtocol:(Protocol *)aProtocol { + return [self mockedClassConformsToProtocol:aProtocol] || + [self mockedProtocolConformsToProtocol:aProtocol] || + [super conformsToProtocol:aProtocol]; +} + +#pragma mark - +#pragma mark Whitelisted NSObject Methods + +- (BOOL)isEqual:(id)anObject { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:_cmd]; + [self expectMessagePattern:messagePattern]; + NSInvocation *invocation = [NSInvocation invocationWithTarget:self selector:_cmd messageArguments:&anObject]; + + if ([self processReceivedInvocation:invocation]) { + BOOL result = NO; + [invocation getReturnValue:&result]; + return result; + } else { + return [super isEqual:anObject]; + } +} + +- (NSUInteger)hash { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:_cmd]; + [self expectMessagePattern:messagePattern]; + NSInvocation *invocation = [NSInvocation invocationWithTarget:self selector:_cmd]; + + if ([self processReceivedInvocation:invocation]) { + NSUInteger result = 0; + [invocation getReturnValue:&result]; + return result; + } else { + return [super hash]; + } +} + +- (NSString *)description { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:_cmd]; + [self expectMessagePattern:messagePattern]; + NSInvocation *invocation = [NSInvocation invocationWithTarget:self selector:_cmd]; + + if ([self processReceivedInvocation:invocation]) { + NSString *result = nil; + [invocation getReturnValue:&result]; + return result; + } else { + return [super description]; + } +} + +- (id)copy { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:_cmd]; + [self expectMessagePattern:messagePattern]; + NSInvocation *invocation = [NSInvocation invocationWithTarget:self selector:_cmd]; + + if ([self processReceivedInvocation:invocation]) { + id result = nil; + [invocation getReturnValue:&result]; + return result; + } else { + return [super copy]; + } +} + +- (id)mutableCopy { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:_cmd]; + [self expectMessagePattern:messagePattern]; + NSInvocation *invocation = [NSInvocation invocationWithTarget:self selector:_cmd]; + + if ([self processReceivedInvocation:invocation]) { + id result = nil; + [invocation getReturnValue:&result]; + return result; + } else { + return [super mutableCopy]; + } +} + +#pragma mark - +#pragma mark Key-Value Coding Support + +static id valueForKeyImplementation(id self, SEL _cmd, id key) { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:_cmd]; + [self expectMessagePattern:messagePattern]; + NSInvocation *invocation = [NSInvocation invocationWithTarget:self selector:_cmd messageArguments:&key]; + + if ([self processReceivedInvocation:invocation]) { + id result = nil; + [invocation getReturnValue:&result]; + return result; + } else { + return nil; + } +} + +- (id)valueForKey:(NSString *)key { + return valueForKeyImplementation(self, _cmd, key); +} + +- (id)valueForKeyPath:(NSString *)keyPath { + return valueForKeyImplementation(self, _cmd, keyPath); +} + +static void setValueForKeyImplementation(id self, SEL _cmd, id a, id b) { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:_cmd]; + [self expectMessagePattern:messagePattern]; + NSInvocation *invocation = [NSInvocation invocationWithTarget:self selector:_cmd messageArguments:&a, &b]; + + [self processReceivedInvocation:invocation]; +} + +- (void)setValue:(id)value forKey:(NSString *)key { + setValueForKeyImplementation(self, _cmd, value, key); +} + +- (void)setValue:(id)value forKeyPath:(NSString *)keyPath { + setValueForKeyImplementation(self, _cmd, value, keyPath); +} + +@end diff --git a/Pods/Kiwi/Classes/KWNull.h b/Pods/Kiwi/Classes/KWNull.h new file mode 100644 index 0000000..4a91900 --- /dev/null +++ b/Pods/Kiwi/Classes/KWNull.h @@ -0,0 +1,19 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +// KWNull exists to represent the same thing as NSNull, except that Kiwi needs +// to distinguish between null singletons used internally and those a user +// is using as an object parameter. +@interface KWNull : NSObject + +#pragma mark - +#pragma mark Initializing + ++ (id)null; + +@end diff --git a/Pods/Kiwi/Classes/KWNull.m b/Pods/Kiwi/Classes/KWNull.m new file mode 100644 index 0000000..45b9f10 --- /dev/null +++ b/Pods/Kiwi/Classes/KWNull.m @@ -0,0 +1,47 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWNull.h" + +@implementation KWNull + +#pragma mark - +#pragma mark Initializing + +static KWNull *sharedNull = nil; + ++ (id)null { + if (sharedNull == nil) { + sharedNull = [[super allocWithZone:nil] init]; + } + + return sharedNull; +} + ++ (id)allocWithZone:(NSZone *)zone { + return [[self null] retain]; +} + +- (id)copyWithZone:(NSZone *)zone { + return self; +} + +- (id)retain { + return self; +} + +- (NSUInteger)retainCount { + return NSUIntegerMax; +} + +- (oneway void)release { +} + +- (id)autorelease { + return self; +} + +@end diff --git a/Pods/Kiwi/Classes/KWObjCUtilities.h b/Pods/Kiwi/Classes/KWObjCUtilities.h new file mode 100644 index 0000000..3dc842b --- /dev/null +++ b/Pods/Kiwi/Classes/KWObjCUtilities.h @@ -0,0 +1,32 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +#pragma mark - +#pragma mark Objective-C Type Utilities + +BOOL KWObjCTypeEqualToObjCType(const char *firstObjCType, const char *secondObjCType); +BOOL KWObjCTypeIsNumeric(const char *objCType); +BOOL KWObjCTypeIsFloatingPoint(const char *objCType); +BOOL KWObjCTypeIsIntegral(const char *objCType); +BOOL KWObjCTypeIsSignedIntegral(const char *objCType); +BOOL KWObjCTypeIsUnsignedIntegral(const char *objCType); +BOOL KWObjCTypeIsObject(const char *objCType); +BOOL KWObjCTypeIsCharString(const char *objCType); +BOOL KWObjCTypeIsClass(const char *objCType); +BOOL KWObjCTypeIsSelector(const char *objCType); +BOOL KWObjCTypeIsPointerToType(const char *objCType); +BOOL KWObjCTypeIsPointerLike(const char *objCType); +BOOL KWObjCTypeIsUnknown(const char *objCType); +BOOL KWObjCTypeIsBlock(const char *objCType); + +NSUInteger KWObjCTypeLength(const char *objCType); + +#pragma mark - +#pragma mark Selector Utlities + +NSUInteger KWSelectorParameterCount(SEL selector); diff --git a/Pods/Kiwi/Classes/KWObjCUtilities.m b/Pods/Kiwi/Classes/KWObjCUtilities.m new file mode 100644 index 0000000..f5d62b3 --- /dev/null +++ b/Pods/Kiwi/Classes/KWObjCUtilities.m @@ -0,0 +1,102 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWObjCUtilities.h" +#import "KWStringUtilities.h" + +#pragma mark - +#pragma mark Objective-C Type Utilities + +BOOL KWObjCTypeEqualToObjCType(const char *firstObjCType, const char *secondObjCType) { + return strcmp(firstObjCType, secondObjCType) == 0; +} + +BOOL KWObjCTypeIsNumeric(const char *objCType) { + return KWObjCTypeIsFloatingPoint(objCType) || KWObjCTypeIsIntegral(objCType); +} + +BOOL KWObjCTypeIsFloatingPoint(const char *objCType) { + return strcmp(objCType, @encode(float)) == 0 || strcmp(objCType, @encode(double)) == 0; +} + +BOOL KWObjCTypeIsIntegral(const char *objCType) { + return KWObjCTypeIsSignedIntegral(objCType) || KWObjCTypeIsUnsignedIntegral(objCType); +} + +BOOL KWObjCTypeIsSignedIntegral(const char *objCType) { + return strcmp(objCType, @encode(char)) == 0 || + strcmp(objCType, @encode(int)) == 0 || + strcmp(objCType, @encode(short)) == 0 || + strcmp(objCType, @encode(long)) == 0 || + strcmp(objCType, @encode(long long)) == 0; +} + +BOOL KWObjCTypeIsUnsignedIntegral(const char *objCType) { + return strcmp(objCType, @encode(unsigned char)) == 0 || + strcmp(objCType, @encode(unsigned int)) == 0 || + strcmp(objCType, @encode(unsigned short)) == 0 || + strcmp(objCType, @encode(unsigned long)) == 0 || + strcmp(objCType, @encode(unsigned long long)) == 0; +} + +BOOL KWObjCTypeIsObject(const char *objCType) { + return strcmp(objCType, @encode(id)) == 0 || strcmp(objCType, "@?") == 0; +} + +BOOL KWObjCTypeIsCharString(const char *objCType) { + return strcmp(objCType, @encode(char *)) == 0; +} + +BOOL KWObjCTypeIsClass(const char *objCType) { + return strcmp(objCType, @encode(Class)) == 0; +} + +BOOL KWObjCTypeIsSelector(const char *objCType) { + return strcmp(objCType, @encode(SEL)) == 0; +} + +BOOL KWObjCTypeIsPointerToType(const char *objCType) { + return *objCType == '^'; +} + +BOOL KWObjCTypeIsPointerLike(const char *objCType) { + return KWObjCTypeIsObject(objCType) || + KWObjCTypeIsCharString(objCType) || + KWObjCTypeIsClass(objCType) || + KWObjCTypeIsSelector(objCType) || + KWObjCTypeIsPointerToType(objCType); +} + +BOOL KWObjCTypeIsUnknown(const char *objCType) { + return *objCType == '?'; +} + +NSUInteger KWObjCTypeLength(const char *objCType) { + NSString *encoding = KWEncodingWithObjCTypes(objCType, @encode(id), @encode(SEL), nil); + NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:[encoding UTF8String]]; + return [signature methodReturnLength]; +} + +BOOL KWObjCTypeIsBlock(const char *objCType) { + return strcmp(objCType, "@?") == 0; +} + + +#pragma mark - +#pragma mark Selector Utlities + +NSUInteger KWSelectorParameterCount(SEL selector) { + NSString *selectorString = NSStringFromSelector(selector); + NSUInteger length = [selectorString length]; + NSUInteger parameterCount = 0; + + for (NSUInteger i = 0; i < length; ++i) { + if ([selectorString characterAtIndex:i] == ':') + ++parameterCount; + } + + return parameterCount; +} diff --git a/Pods/Kiwi/Classes/KWPendingNode.h b/Pods/Kiwi/Classes/KWPendingNode.h new file mode 100644 index 0000000..31fa61f --- /dev/null +++ b/Pods/Kiwi/Classes/KWPendingNode.h @@ -0,0 +1,37 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWExampleNode.h" + +@class KWContextNode; +@class KWCallSite; + +@interface KWPendingNode : NSObject { +@private + KWCallSite *callSite; + NSString *description; +} +@property (nonatomic, readonly, retain) KWContextNode *context; + +#pragma mark - +#pragma mark Initializing + +- (id)initWithCallSite:(KWCallSite *)aCallSite context:(KWContextNode *)context description:(NSString *)aDescription; + ++ (id)pendingNodeWithCallSite:(KWCallSite *)aCallSite context:(KWContextNode *)context description:(NSString *)aDescription; + +#pragma mark - +#pragma mark Getting Call Sites + +@property (nonatomic, readonly) KWCallSite *callSite; + +#pragma mark - +#pragma mark Getting Descriptions + +@property (nonatomic, readonly) NSString *description; + +@end diff --git a/Pods/Kiwi/Classes/KWPendingNode.m b/Pods/Kiwi/Classes/KWPendingNode.m new file mode 100644 index 0000000..ff9d6dc --- /dev/null +++ b/Pods/Kiwi/Classes/KWPendingNode.m @@ -0,0 +1,72 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWPendingNode.h" +#import "KWExampleNodeVisitor.h" +#import "KWContextNode.h" + +@implementation KWPendingNode + +@synthesize context = _context; + +#pragma mark - +#pragma mark Initializing + +- (id)initWithCallSite:(KWCallSite *)aCallSite context:(KWContextNode *)context description:(NSString *)aDescription { + if ((self = [super init])) { + callSite = [aCallSite retain]; + description = [aDescription copy]; + _context = [context retain]; + } + + return self; +} + ++ (id)pendingNodeWithCallSite:(KWCallSite *)aCallSite context:(KWContextNode *)context description:(NSString *)aDescription { + return [[[self alloc] initWithCallSite:aCallSite context:context description:aDescription] autorelease]; +} + +- (void)dealloc { + [_context release]; + [callSite release]; + [description release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Getting Call Sites + +@synthesize callSite; + +#pragma mark - +#pragma mark Getting Descriptions + +@synthesize description; + +#pragma mark - +#pragma mark Accepting Visitors + +- (void)acceptExampleNodeVisitor:(id)aVisitor { + [aVisitor visitPendingNode:self]; +} + +#pragma mark - +#pragma mark - Accessing the context stack + +- (NSArray *)contextStack +{ + NSMutableArray *contextStack = [NSMutableArray array]; + + KWContextNode *currentContext = _context; + + while (currentContext) { + [contextStack addObject:currentContext]; + currentContext = currentContext.parentContext; + } + return contextStack; +} + +@end diff --git a/Pods/Kiwi/Classes/KWProbe.h b/Pods/Kiwi/Classes/KWProbe.h new file mode 100644 index 0000000..d635c76 --- /dev/null +++ b/Pods/Kiwi/Classes/KWProbe.h @@ -0,0 +1,14 @@ +// +// KWProbe.h +// iOSFalconCore +// +// Created by Luke Redpath on 13/01/2011. +// Copyright 2011 LJR Software Limited. All rights reserved. +// + +#import + +@protocol KWProbe +- (BOOL)isSatisfied; +- (void)sample; +@end diff --git a/Pods/Kiwi/Classes/KWProbePoller.h b/Pods/Kiwi/Classes/KWProbePoller.h new file mode 100644 index 0000000..6acadbd --- /dev/null +++ b/Pods/Kiwi/Classes/KWProbePoller.h @@ -0,0 +1,21 @@ +// +// KWProbePoller.h +// iOSFalconCore +// +// Created by Luke Redpath on 13/01/2011. +// Copyright 2011 LJR Software Limited. All rights reserved. +// + +#import +#import "KWProbe.h" + +#define kKW_DEFAULT_PROBE_DELAY 0.1 + +@interface KWProbePoller : NSObject +{ + NSTimeInterval timeoutInterval; + NSTimeInterval delayInterval; +} +- (id)initWithTimeout:(NSTimeInterval)theTimeout delay:(NSTimeInterval)theDelay; +- (BOOL)check:(id)probe; +@end diff --git a/Pods/Kiwi/Classes/KWProbePoller.m b/Pods/Kiwi/Classes/KWProbePoller.m new file mode 100644 index 0000000..d065a12 --- /dev/null +++ b/Pods/Kiwi/Classes/KWProbePoller.m @@ -0,0 +1,72 @@ +// +// KWProbePoller.m +// iOSFalconCore +// +// Created by Luke Redpath on 13/01/2011. +// Copyright 2011 LJR Software Limited. All rights reserved. +// + +#import "KWProbePoller.h" + +@interface KWTimeout : NSObject +{ + NSDate *timeoutDate; +} +- (id)initWithTimeout:(NSTimeInterval)timeout; +- (BOOL)hasTimedOut; +@end + +@implementation KWTimeout + +- (id)initWithTimeout:(NSTimeInterval)timeout +{ + if ((self = [super init])) { + timeoutDate = [[NSDate alloc] initWithTimeIntervalSinceNow:timeout]; + } + return self; +} + +- (void)dealloc +{ + [timeoutDate release]; + [super dealloc]; +} + +- (BOOL)hasTimedOut +{ + return [timeoutDate timeIntervalSinceDate:[NSDate date]] < 0; +} + +@end + +#pragma mark - + +@implementation KWProbePoller + +- (id)initWithTimeout:(NSTimeInterval)theTimeout delay:(NSTimeInterval)theDelay; +{ + if ((self = [super init])) { + timeoutInterval = theTimeout; + delayInterval = theDelay; + } + return self; +} + +- (BOOL)check:(id)probe; +{ + KWTimeout *timeout = [[KWTimeout alloc] initWithTimeout:timeoutInterval]; + + while (![probe isSatisfied]) { + if ([timeout hasTimedOut]) { + [timeout release]; + return NO; + } + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:delayInterval]]; + [probe sample]; + } + [timeout release]; + + return YES; +} + +@end diff --git a/Pods/Kiwi/Classes/KWRaiseMatcher.h b/Pods/Kiwi/Classes/KWRaiseMatcher.h new file mode 100644 index 0000000..45588b5 --- /dev/null +++ b/Pods/Kiwi/Classes/KWRaiseMatcher.h @@ -0,0 +1,25 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWRaiseMatcher : KWMatcher { +@private + SEL selector; + NSException *exception; + NSException *actualException; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)raiseWhenSent:(SEL)aSelector; +- (void)raiseWithName:(NSString *)aName whenSent:(SEL)aSelector; +- (void)raiseWithReason:(NSString *)aReason whenSent:(SEL)aSelector; +- (void)raiseWithName:(NSString *)aName reason:(NSString *)aReason whenSent:(SEL)aSelector; + +@end diff --git a/Pods/Kiwi/Classes/KWRaiseMatcher.m b/Pods/Kiwi/Classes/KWRaiseMatcher.m new file mode 100644 index 0000000..20f034b --- /dev/null +++ b/Pods/Kiwi/Classes/KWRaiseMatcher.m @@ -0,0 +1,126 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWRaiseMatcher.h" +#import "KWFormatter.h" + +@interface KWRaiseMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite) SEL selector; +@property (nonatomic, readwrite, retain) NSException *exception; +@property (nonatomic, readwrite, retain) NSException *actualException; + +@end + +@implementation KWRaiseMatcher + +#pragma mark - +#pragma mark Initializing + +- (void)dealloc { + [exception release]; + [actualException release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize selector; +@synthesize exception; +@synthesize actualException; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"raiseWhenSent:", + @"raiseWithName:whenSent:", + @"raiseWithReason:whenSent:", + @"raiseWithName:reason:whenSent:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + @try { + [self.subject performSelector:self.selector]; + } @catch (NSException *anException) { + self.actualException = anException; + + if ([self.exception name] != nil && ![[self.exception name] isEqualToString:[anException name]]) + return NO; + + if ([self.exception reason] != nil && ![[self.exception reason] isEqualToString:[anException reason]]) + return NO; + + return YES; + } + + return NO; +} + +#pragma mark - +#pragma mark Getting Failure Messages + ++ (NSString *)exceptionPhraseWithException:(NSException *)anException { + if (anException == nil) + return @"nothing"; + + NSString *namePhrase = nil; + + if ([anException name] == nil) + namePhrase = @"exception"; + else + namePhrase = [anException name]; + + if ([anException reason] == nil) + return namePhrase; + + return [NSString stringWithFormat:@"%@ \"%@\"", namePhrase, [anException reason]]; +} + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected %@, but %@ raised", + [[self class] exceptionPhraseWithException:self.exception], + [[self class] exceptionPhraseWithException:self.actualException]]; +} + +- (NSString *)failureMessageForShouldNot { + return [NSString stringWithFormat:@"expected %@ not to be raised", + [[self class] exceptionPhraseWithException:self.actualException]]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"raise %@ when sent %@", [[self class] exceptionPhraseWithException:self.exception], NSStringFromSelector(self.selector)]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)raiseWhenSent:(SEL)aSelector { + [self raiseWithName:nil reason:nil whenSent:aSelector]; +} + +- (void)raiseWithName:(NSString *)aName whenSent:(SEL)aSelector { + [self raiseWithName:aName reason:nil whenSent:aSelector]; +} + +- (void)raiseWithReason:(NSString *)aReason whenSent:(SEL)aSelector { + [self raiseWithName:nil reason:aReason whenSent:aSelector]; +} + +- (void)raiseWithName:(NSString *)aName reason:(NSString *)aReason whenSent:(SEL)aSelector { + self.selector = aSelector; + self.exception = [NSException exceptionWithName:aName reason:aReason userInfo:nil]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWReceiveMatcher.h b/Pods/Kiwi/Classes/KWReceiveMatcher.h new file mode 100644 index 0000000..932b555 --- /dev/null +++ b/Pods/Kiwi/Classes/KWReceiveMatcher.h @@ -0,0 +1,63 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWCountType.h" +#import "KWMatcher.h" +#import "KWMatchVerifier.h" + +@class KWMessagePattern; +@class KWMessageTracker; + +@interface KWReceiveMatcher : KWMatcher { +@private + KWMessageTracker *messageTracker; + BOOL willEvaluateMultipleTimes; +} +@property (nonatomic, assign) BOOL willEvaluateMultipleTimes; + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)receive:(SEL)aSelector; +- (void)receive:(SEL)aSelector withCount:(NSUInteger)aCount; +- (void)receive:(SEL)aSelector withCountAtLeast:(NSUInteger)aCount; +- (void)receive:(SEL)aSelector withCountAtMost:(NSUInteger)aCount; +- (void)receive:(SEL)aSelector andReturn:(id)aValue; +- (void)receive:(SEL)aSelector andReturn:(id)aValue withCount:(NSUInteger)aCount; +- (void)receive:(SEL)aSelector andReturn:(id)aValue withCountAtLeast:(NSUInteger)aCount; +- (void)receive:(SEL)aSelector andReturn:(id)aValue withCountAtMost:(NSUInteger)aCount; +- (void)receiveMessagePattern:(KWMessagePattern *)aMessagePattern countType:(KWCountType)aCountType count:(NSUInteger)aCount; +- (void)receiveMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue countType:(KWCountType)aCountType count:(NSUInteger)aCount; + +@end + +@interface KWMatchVerifier(KWReceiveMatcherAdditions) + +#pragma mark - +#pragma mark Verifying + +- (void)receive:(SEL)aSelector withArguments:(id)firstArgument, ...; +- (void)receive:(SEL)aSelector withCount:(NSUInteger)aCount arguments:(id)firstArgument, ...; +- (void)receive:(SEL)aSelector withCountAtLeast:(NSUInteger)aCount arguments:(id)firstArgument, ...; +- (void)receive:(SEL)aSelector withCountAtMost:(NSUInteger)aCount arguments:(id)firstArgument, ...; +- (void)receive:(SEL)aSelector andReturn:(id)aValue withArguments:(id)firstArgument, ...; +- (void)receive:(SEL)aSelector andReturn:(id)aValue withCount:(NSUInteger)aCount arguments:(id)firstArgument, ...; +- (void)receive:(SEL)aSelector andReturn:(id)aValue withCountAtLeast:(NSUInteger)aCount arguments:(id)firstArgument, ...; +- (void)receive:(SEL)aSelector andReturn:(id)aValue withCountAtMost:(NSUInteger)aCount arguments:(id)firstArgument, ...; + +#pragma mark Invocation Capturing Methods + +- (id)receive; +- (id)receiveWithCount:(NSUInteger)aCount; +- (id)receiveWithCountAtLeast:(NSUInteger)aCount; +- (id)receiveWithCountAtMost:(NSUInteger)aCount; +- (id)receiveAndReturn:(id)aValue; +- (id)receiveAndReturn:(id)aValue withCount:(NSUInteger)aCount; +- (id)receiveAndReturn:(id)aValue withCountAtLeast:(NSUInteger)aCount; +- (id)receiveAndReturn:(id)aValue withCountAtMost:(NSUInteger)aCount; + +@end diff --git a/Pods/Kiwi/Classes/KWReceiveMatcher.m b/Pods/Kiwi/Classes/KWReceiveMatcher.m new file mode 100644 index 0000000..a3d9339 --- /dev/null +++ b/Pods/Kiwi/Classes/KWReceiveMatcher.m @@ -0,0 +1,321 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWReceiveMatcher.h" +#import "KWFormatter.h" +#import "KWInvocationCapturer.h" +#import "KWMessagePattern.h" +#import "KWMessageTracker.h" +#import "KWObjCUtilities.h" +#import "KWStringUtilities.h" +#import "KWWorkarounds.h" +#import "NSObject+KiwiStubAdditions.h" + +static NSString * const MatchVerifierKey = @"MatchVerifierKey"; +static NSString * const CountTypeKey = @"CountTypeKey"; +static NSString * const CountKey = @"CountKey"; +static NSString * const StubValueKey = @"StubValueKey"; + +@interface KWReceiveMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite, retain) KWMessageTracker *messageTracker; + +@end + +@implementation KWReceiveMatcher + +#pragma mark - +#pragma mark Initializing + +- (id)initWithSubject:(id)anObject { + if ((self = [super initWithSubject:anObject])) { + self.willEvaluateMultipleTimes = NO; + } + + return self; +} + +- (void)dealloc { + [messageTracker release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize messageTracker; +@synthesize willEvaluateMultipleTimes; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"receive:", + @"receive:withCount:", + @"receive:withCountAtLeast:", + @"receive:withCountAtMost:", + @"receive:andReturn:", + @"receive:andReturn:withCount:", + @"receive:andReturn:withCountAtLeast:", + @"receive:andReturn:withCountAtMost:", + @"receiveMessagePattern:countType:count:", + @"receiveMessagePattern:andReturn:countType:count:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)shouldBeEvaluatedAtEndOfExample { + return YES; +} + +- (BOOL)evaluate { + BOOL succeeded = [self.messageTracker succeeded]; + + if (!self.willEvaluateMultipleTimes) { + [self.messageTracker stopTracking]; + } + return succeeded; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to receive -%@ %@, but received it %@", + [self.messageTracker.messagePattern stringValue], + [self.messageTracker expectedCountPhrase], + [self.messageTracker receivedCountPhrase]]; +} + +- (NSString *)failureMessageForShouldNot { + return [NSString stringWithFormat:@"expected subject not to receive -%@, but received it %@", + [self.messageTracker.messagePattern stringValue], + [self.messageTracker receivedCountPhrase]]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)receive:(SEL)aSelector { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self receiveMessagePattern:messagePattern countType:KWCountTypeExact count:1]; +} + +- (void)receive:(SEL)aSelector withCount:(NSUInteger)aCount { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + return [self receiveMessagePattern:messagePattern countType:KWCountTypeExact count:aCount]; +} + +- (void)receive:(SEL)aSelector withCountAtLeast:(NSUInteger)aCount { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + return [self receiveMessagePattern:messagePattern countType:KWCountTypeAtLeast count:aCount]; +} + +- (void)receive:(SEL)aSelector withCountAtMost:(NSUInteger)aCount { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + return [self receiveMessagePattern:messagePattern countType:KWCountTypeAtMost count:aCount]; +} + +- (void)receive:(SEL)aSelector andReturn:(id)aValue { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self receiveMessagePattern:messagePattern andReturn:aValue countType:KWCountTypeExact count:1]; +} + +- (void)receive:(SEL)aSelector andReturn:(id)aValue withCount:(NSUInteger)aCount { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self receiveMessagePattern:messagePattern andReturn:aValue countType:KWCountTypeExact count:aCount]; +} + +- (void)receive:(SEL)aSelector andReturn:(id)aValue withCountAtLeast:(NSUInteger)aCount { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self receiveMessagePattern:messagePattern andReturn:aValue countType:KWCountTypeAtLeast count:aCount]; +} + +- (void)receive:(SEL)aSelector andReturn:(id)aValue withCountAtMost:(NSUInteger)aCount { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self receiveMessagePattern:messagePattern andReturn:aValue countType:KWCountTypeAtMost count:aCount]; +} + +- (void)receiveMessagePattern:(KWMessagePattern *)aMessagePattern countType:(KWCountType)aCountType count:(NSUInteger)aCount { +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + @try { +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + + [self.subject stubMessagePattern:aMessagePattern andReturn:nil overrideExisting:NO]; + self.messageTracker = [KWMessageTracker messageTrackerWithSubject:self.subject messagePattern:aMessagePattern countType:aCountType count:aCount]; + +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + } @catch(NSException *exception) { + KWSetExceptionFromAcrossInvocationBoundary(exception); + } +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG +} + +- (void)receiveMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue countType:(KWCountType)aCountType count:(NSUInteger)aCount { +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + @try { +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + + [self.subject stubMessagePattern:aMessagePattern andReturn:aValue]; + self.messageTracker = [KWMessageTracker messageTrackerWithSubject:self.subject messagePattern:aMessagePattern countType:aCountType count:aCount]; + +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + } @catch(NSException *exception) { + KWSetExceptionFromAcrossInvocationBoundary(exception); + } +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG +} + +#pragma mark - +#pragma mark Capturing Invocations + ++ (NSMethodSignature *)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer methodSignatureForSelector:(SEL)aSelector { + KWMatchVerifier *verifier = (anInvocationCapturer.userInfo)[MatchVerifierKey]; + + if ([verifier.subject respondsToSelector:aSelector]) + return [verifier.subject methodSignatureForSelector:aSelector]; + + NSString *encoding = KWEncodingForVoidMethod(); + return [NSMethodSignature signatureWithObjCTypes:[encoding UTF8String]]; +} + ++ (void)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer didCaptureInvocation:(NSInvocation *)anInvocation { + NSDictionary *userInfo = anInvocationCapturer.userInfo; + id verifier = userInfo[MatchVerifierKey]; + KWCountType countType = [userInfo[CountTypeKey] unsignedIntegerValue]; + NSUInteger count = [userInfo[CountKey] unsignedIntegerValue]; + NSValue *stubValue = userInfo[StubValueKey]; + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternFromInvocation:anInvocation]; + + if (stubValue != nil) + [verifier receiveMessagePattern:messagePattern andReturn:[stubValue nonretainedObjectValue] countType:countType count:count]; + else + [verifier receiveMessagePattern:messagePattern countType:countType count:count]; +} + +@end + +@implementation KWMatchVerifier(KWReceiveMatcherAdditions) + +#pragma mark - +#pragma mark Verifying + +- (void)receive:(SEL)aSelector withArguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [(id)self receiveMessagePattern:messagePattern countType:KWCountTypeExact count:1]; +} + +- (void)receive:(SEL)aSelector withCount:(NSUInteger)aCount arguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [(id)self receiveMessagePattern:messagePattern countType:KWCountTypeExact count:aCount]; +} + +- (void)receive:(SEL)aSelector withCountAtLeast:(NSUInteger)aCount arguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [(id)self receiveMessagePattern:messagePattern countType:KWCountTypeAtLeast count:aCount]; +} + +- (void)receive:(SEL)aSelector withCountAtMost:(NSUInteger)aCount arguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [(id)self receiveMessagePattern:messagePattern countType:KWCountTypeAtMost count:aCount]; +} + +- (void)receive:(SEL)aSelector andReturn:(id)aValue withArguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [(id)self receiveMessagePattern:messagePattern andReturn:aValue countType:KWCountTypeExact count:1]; +} + +- (void)receive:(SEL)aSelector andReturn:(id)aValue withCount:(NSUInteger)aCount arguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [(id)self receiveMessagePattern:messagePattern andReturn:aValue countType:KWCountTypeExact count:aCount]; +} + +- (void)receive:(SEL)aSelector andReturn:(id)aValue withCountAtLeast:(NSUInteger)aCount arguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [(id)self receiveMessagePattern:messagePattern andReturn:aValue countType:KWCountTypeAtLeast count:aCount]; +} + +- (void)receive:(SEL)aSelector andReturn:(id)aValue withCountAtMost:(NSUInteger)aCount arguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [(id)self receiveMessagePattern:messagePattern andReturn:aValue countType:KWCountTypeAtMost count:aCount]; +} + +#pragma mark Invocation Capturing Methods + +- (NSDictionary *)userInfoForReceiveMatcherWithCountType:(KWCountType)aCountType count:(NSUInteger)aCount { + return @{MatchVerifierKey: self, + CountTypeKey: @(aCountType), + CountKey: @(aCount)}; +} + +- (NSDictionary *)userInfoForReceiveMatcherWithCountType:(KWCountType)aCountType count:(NSUInteger)aCount value:(id)aValue { + return @{MatchVerifierKey: self, + CountTypeKey: @(aCountType), + CountKey: @(aCount), + StubValueKey: [NSValue valueWithNonretainedObject:aValue]}; +} + +- (id)receive { + NSDictionary *userInfo = [self userInfoForReceiveMatcherWithCountType:KWCountTypeExact count:1]; + return [KWInvocationCapturer invocationCapturerWithDelegate:[KWReceiveMatcher class] userInfo:userInfo]; +} + +- (id)receiveWithCount:(NSUInteger)aCount { + NSDictionary *userInfo = [self userInfoForReceiveMatcherWithCountType:KWCountTypeExact count:aCount]; + return [KWInvocationCapturer invocationCapturerWithDelegate:[KWReceiveMatcher class] userInfo:userInfo]; +} + +- (id)receiveWithCountAtLeast:(NSUInteger)aCount { + NSDictionary *userInfo = [self userInfoForReceiveMatcherWithCountType:KWCountTypeAtLeast count:aCount]; + return [KWInvocationCapturer invocationCapturerWithDelegate:[KWReceiveMatcher class] userInfo:userInfo]; +} + +- (id)receiveWithCountAtMost:(NSUInteger)aCount { + NSDictionary *userInfo = [self userInfoForReceiveMatcherWithCountType:KWCountTypeAtMost count:aCount]; + return [KWInvocationCapturer invocationCapturerWithDelegate:[KWReceiveMatcher class] userInfo:userInfo]; +} + +- (id)receiveAndReturn:(id)aValue { + NSDictionary *userInfo = [self userInfoForReceiveMatcherWithCountType:KWCountTypeExact count:1 value:aValue]; + return [KWInvocationCapturer invocationCapturerWithDelegate:[KWReceiveMatcher class] userInfo:userInfo]; +} + +- (id)receiveAndReturn:(id)aValue withCount:(NSUInteger)aCount { + NSDictionary *userInfo = [self userInfoForReceiveMatcherWithCountType:KWCountTypeExact count:aCount value:aValue]; + return [KWInvocationCapturer invocationCapturerWithDelegate:[KWReceiveMatcher class] userInfo:userInfo]; +} + +- (id)receiveAndReturn:(id)aValue withCountAtLeast:(NSUInteger)aCount { + NSDictionary *userInfo = [self userInfoForReceiveMatcherWithCountType:KWCountTypeAtLeast count:aCount value:aValue]; + return [KWInvocationCapturer invocationCapturerWithDelegate:[KWReceiveMatcher class] userInfo:userInfo]; +} + +- (id)receiveAndReturn:(id)aValue withCountAtMost:(NSUInteger)aCount { + NSDictionary *userInfo = [self userInfoForReceiveMatcherWithCountType:KWCountTypeAtMost count:aCount value:aValue]; + return [KWInvocationCapturer invocationCapturerWithDelegate:[KWReceiveMatcher class] userInfo:userInfo]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWRegisterMatchersNode.h b/Pods/Kiwi/Classes/KWRegisterMatchersNode.h new file mode 100644 index 0000000..d0517fc --- /dev/null +++ b/Pods/Kiwi/Classes/KWRegisterMatchersNode.h @@ -0,0 +1,35 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWExampleNode.h" + +@class KWCallSite; + +@interface KWRegisterMatchersNode : NSObject { +@private + KWCallSite *callSite; + NSString *namespacePrefix; +} + +#pragma mark - +#pragma mark Initializing + +- (id)initWithCallSite:(KWCallSite *)aCallSite namespacePrefix:(NSString *)aNamespacePrefix; + ++ (id)registerMatchersNodeWithCallSite:(KWCallSite *)aCallSite namespacePrefix:(NSString *)aNamespacePrefix; + +#pragma mark - +#pragma mark Getting Call Sites + +@property (nonatomic, readonly) KWCallSite *callSite; + +#pragma mark - +#pragma mark Getting Namespace Prefixes + +@property (nonatomic, readonly) NSString *namespacePrefix; + +@end diff --git a/Pods/Kiwi/Classes/KWRegisterMatchersNode.m b/Pods/Kiwi/Classes/KWRegisterMatchersNode.m new file mode 100644 index 0000000..e1e7cbe --- /dev/null +++ b/Pods/Kiwi/Classes/KWRegisterMatchersNode.m @@ -0,0 +1,51 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWRegisterMatchersNode.h" +#import "KWExampleNodeVisitor.h" + +@implementation KWRegisterMatchersNode + +#pragma mark - +#pragma mark Initializing + +- (id)initWithCallSite:(KWCallSite *)aCallSite namespacePrefix:(NSString *)aNamespacePrefix { + if ((self = [super init])) { + callSite = [aCallSite retain]; + namespacePrefix = [aNamespacePrefix copy]; + } + + return self; +} + ++ (id)registerMatchersNodeWithCallSite:(KWCallSite *)aCallSite namespacePrefix:(NSString *)aNamespacePrefix { + return [[[self alloc] initWithCallSite:aCallSite namespacePrefix:aNamespacePrefix] autorelease]; +} + +- (void)dealloc { + [callSite release]; + [namespacePrefix release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Getting Call Sites + +@synthesize callSite; + +#pragma mark - +#pragma mark Getting Namespace Prefixes + +@synthesize namespacePrefix; + +#pragma mark - +#pragma mark Accepting Visitors + +- (void)acceptExampleNodeVisitor:(id)aVisitor { + [aVisitor visitRegisterMatchersNode:self]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWReporting.h b/Pods/Kiwi/Classes/KWReporting.h new file mode 100644 index 0000000..595b2ca --- /dev/null +++ b/Pods/Kiwi/Classes/KWReporting.h @@ -0,0 +1,18 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@class KWFailure; + +@protocol KWReporting + +#pragma mark - +#pragma mark Reporting Failures + +- (void)reportFailure:(KWFailure *)failure; + +@end diff --git a/Pods/Kiwi/Classes/KWRespondToSelectorMatcher.h b/Pods/Kiwi/Classes/KWRespondToSelectorMatcher.h new file mode 100644 index 0000000..d41c82e --- /dev/null +++ b/Pods/Kiwi/Classes/KWRespondToSelectorMatcher.h @@ -0,0 +1,20 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import "KWMatcher.h" + +@interface KWRespondToSelectorMatcher : KWMatcher { +@private + SEL selector; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)respondToSelector:(SEL)aSelector; + +@end diff --git a/Pods/Kiwi/Classes/KWRespondToSelectorMatcher.m b/Pods/Kiwi/Classes/KWRespondToSelectorMatcher.m new file mode 100644 index 0000000..89517d2 --- /dev/null +++ b/Pods/Kiwi/Classes/KWRespondToSelectorMatcher.m @@ -0,0 +1,60 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWRespondToSelectorMatcher.h" +#import "KWFormatter.h" + +@interface KWRespondToSelectorMatcher() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readwrite) SEL selector; + +@end + +@implementation KWRespondToSelectorMatcher + +#pragma mark - +#pragma mark Properties + +@synthesize selector; + +#pragma mark - +#pragma mark Getting Matcher Strings + ++ (NSArray *)matcherStrings { + return @[@"respondToSelector:"]; +} + +#pragma mark - +#pragma mark Matching + +- (BOOL)evaluate { + return [self.subject respondsToSelector:self.selector]; +} + +#pragma mark - +#pragma mark Getting Failure Messages + +- (NSString *)failureMessageForShould { + return [NSString stringWithFormat:@"expected subject to respond to -%@", + NSStringFromSelector(self.selector)]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"respond to -%@", NSStringFromSelector(self.selector)]; +} + +#pragma mark - +#pragma mark Configuring Matchers + +- (void)respondToSelector:(SEL)aSelector { + self.selector = aSelector; +} + +@end diff --git a/Pods/Kiwi/Classes/KWSpec.h b/Pods/Kiwi/Classes/KWSpec.h new file mode 100644 index 0000000..81bc9c4 --- /dev/null +++ b/Pods/Kiwi/Classes/KWSpec.h @@ -0,0 +1,31 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import +#import "KWExpectationType.h" +#import "KWVerifying.h" +#import "KWExampleGroupDelegate.h" + + +@class KWCallSite; + +@interface KWSpec : SenTestCase + +#pragma mark - +#pragma mark Adding Verifiers + ++ (id)addVerifier:(id)aVerifier; ++ (id)addExistVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite; ++ (id)addMatchVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite; ++ (id)addAsyncVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite timeout:(NSInteger)timeout; + +#pragma mark - +#pragma mark Building Example Groups + ++ (void)buildExampleGroups; + +@end diff --git a/Pods/Kiwi/Classes/KWSpec.m b/Pods/Kiwi/Classes/KWSpec.m new file mode 100644 index 0000000..789f78c --- /dev/null +++ b/Pods/Kiwi/Classes/KWSpec.m @@ -0,0 +1,145 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWSpec.h" +#import +#import "KWExample.h" +#import "KWExampleGroupBuilder.h" +#import "KWIntercept.h" +#import "KWObjCUtilities.h" +#import "KWStringUtilities.h" +#import "NSMethodSignature+KiwiAdditions.h" +#import "KWFailure.h" +#import "KWExampleSuite.h" + + +@interface KWSpec() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, retain) KWExample *example; + +@end + +@implementation KWSpec + +@synthesize example; + +- (void)dealloc +{ + [example release]; + [super dealloc]; +} + +/* This method is only implemented by sub-classes */ + ++ (void)buildExampleGroups {} + +/* Reported by XCode SenTestingKit Runner before and after invocation of the test + Use camel case to make method friendly names from example description + */ + +- (NSString *)description +{ + KWExample *currentExample = self.example ? self.example : [[self invocation] kw_example]; + NSString *name = [currentExample descriptionWithContext]; + + // CamelCase the string + NSArray *words = [name componentsSeparatedByString:@" "]; + name = @""; + for (NSString *word in words) { + if ([word length] < 1) + { + continue; + } + name = [name stringByAppendingString:[[word substringToIndex:1] uppercaseString]]; + name = [name stringByAppendingString:[word substringFromIndex:1]]; + } + + // Replace the commas with underscores to separate the levels of context + name = [name stringByReplacingOccurrencesOfString:@"," withString:@"_"]; + + // Strip out characters not legal in function names + NSError *error = nil; + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^a-zA-Z0-9_]*" options:0 error:&error]; + name = [regex stringByReplacingMatchesInString:name options:0 range:NSMakeRange(0, name.length) withTemplate:@""]; + + return [NSString stringWithFormat:@"-[%@ %@]", NSStringFromClass([self class]), name]; +} + +#pragma mark - +#pragma mark Getting Invocations + +/* Called by the SenTestingKit test suite to get an array of invocations that + should be run on instances of test cases. */ + ++ (NSArray *)testInvocations +{ + SEL selector = @selector(buildExampleGroups); + + // Only return invocation if the receiver is a concrete spec that has overridden -buildExampleGroups. + if ([self methodForSelector:selector] == [KWSpec methodForSelector:selector]) + return nil; + + KWExampleSuite *exampleSuite = [[KWExampleGroupBuilder sharedExampleGroupBuilder] buildExampleGroups:^{ + [self buildExampleGroups]; + }]; + + return [exampleSuite invocationsForTestCase]; +} + +#pragma mark - +#pragma mark Running Specs + +- (void)invokeTest +{ + self.example = [[self invocation] kw_example]; + + NSAutoreleasePool *subPool = [[NSAutoreleasePool alloc] init]; + + @try { + [self.example runWithDelegate:self]; + } @catch (NSException *exception) { + [self failWithException:exception]; + } + + [[self invocation] kw_setExample:nil]; + + [subPool release]; +} + +#pragma mark - KWExampleGroupDelegate methods + +- (void)example:(KWExample *)example didFailWithFailure:(KWFailure *)failure +{ + [self failWithException:[failure exceptionValue]]; +} + +#pragma mark - +#pragma mark Verification proxies + ++ (id)addVerifier:(id)aVerifier +{ + return [[[KWExampleGroupBuilder sharedExampleGroupBuilder] currentExample] addVerifier:aVerifier]; +} + ++ (id)addExistVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite +{ + return [[[KWExampleGroupBuilder sharedExampleGroupBuilder] currentExample] addExistVerifierWithExpectationType:anExpectationType callSite:aCallSite]; +} + ++ (id)addMatchVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite +{ + return [[[KWExampleGroupBuilder sharedExampleGroupBuilder] currentExample] addMatchVerifierWithExpectationType:anExpectationType callSite:aCallSite]; +} + ++ (id)addAsyncVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite timeout:(NSInteger)timeout +{ + return [[[KWExampleGroupBuilder sharedExampleGroupBuilder] currentExample] addAsyncVerifierWithExpectationType:anExpectationType callSite:aCallSite timeout:timeout]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWStringContainsMatcher.h b/Pods/Kiwi/Classes/KWStringContainsMatcher.h new file mode 100644 index 0000000..31a22ae --- /dev/null +++ b/Pods/Kiwi/Classes/KWStringContainsMatcher.h @@ -0,0 +1,21 @@ +// +// KWStringContainsMatcher.h +// Kiwi +// +// Created by Stewart Gleadow on 7/06/12. +// Copyright (c) 2012 Allen Ding. All rights reserved. +// + +#import + +@interface KWStringContainsMatcher : NSObject { + NSString *substring; +} + ++ (id)matcherWithSubstring:(NSString *)aSubstring; +- (id)initWithSubstring:(NSString *)aSubstring; +- (BOOL)matches:(id)object; + +@end + +#define hasSubstring(substring) [KWStringContainsMatcher matcherWithSubstring:substring] diff --git a/Pods/Kiwi/Classes/KWStringContainsMatcher.m b/Pods/Kiwi/Classes/KWStringContainsMatcher.m new file mode 100644 index 0000000..1853058 --- /dev/null +++ b/Pods/Kiwi/Classes/KWStringContainsMatcher.m @@ -0,0 +1,45 @@ +// +// StringContainsMatcher.m +// Kiwi +// +// Created by Stewart Gleadow on 7/06/12. +// Copyright (c) 2012 Allen Ding. All rights reserved. +// + +#import "KWStringContainsMatcher.h" + +@implementation KWStringContainsMatcher + ++ (id)matcherWithSubstring:(NSString *)aSubstring; +{ + return [[[self alloc] initWithSubstring:aSubstring] autorelease]; +} + +- (id)initWithSubstring:(NSString *)aSubstring; +{ + if ((self = [super init])) { + substring = [aSubstring copy]; + } + return self; +} + +- (void)dealloc +{ + [substring release]; + [super dealloc]; +} + +- (BOOL)matches:(id)item +{ + if (![item respondsToSelector:@selector(rangeOfString:)]) + return NO; + + return [item rangeOfString:substring].location != NSNotFound; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"a string with substring '%@'", substring]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWStringPrefixMatcher.h b/Pods/Kiwi/Classes/KWStringPrefixMatcher.h new file mode 100644 index 0000000..afa8d57 --- /dev/null +++ b/Pods/Kiwi/Classes/KWStringPrefixMatcher.h @@ -0,0 +1,18 @@ +// +// StringPrefixMatcher.h +// Kiwi +// +// Created by Luke Redpath on 17/01/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import + +@interface KWStringPrefixMatcher : NSObject { + NSString *prefix; +} ++ (id)matcherWithPrefix:(NSString *)aPrefix; +- (id)initWithPrefix:(NSString *)aPrefix; +@end + +#define hasPrefix(prefix) [KWStringPrefixMatcher matcherWithPrefix:prefix] diff --git a/Pods/Kiwi/Classes/KWStringPrefixMatcher.m b/Pods/Kiwi/Classes/KWStringPrefixMatcher.m new file mode 100644 index 0000000..50ce559 --- /dev/null +++ b/Pods/Kiwi/Classes/KWStringPrefixMatcher.m @@ -0,0 +1,46 @@ +// +// StringPrefixMatcher.m +// Kiwi +// +// Created by Luke Redpath on 17/01/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import "KWStringPrefixMatcher.h" + + +@implementation KWStringPrefixMatcher + ++ (id)matcherWithPrefix:(NSString *)aPrefix; +{ + return [[[self alloc] initWithPrefix:aPrefix] autorelease]; +} + +- (id)initWithPrefix:(NSString *)aPrefix; +{ + if ((self = [super init])) { + prefix = [aPrefix copy]; + } + return self; +} + +- (void)dealloc +{ + [prefix release]; + [super dealloc]; +} + +- (BOOL)matches:(id)item +{ + if (![item respondsToSelector:@selector(hasPrefix:)]) + return NO; + + return [item hasPrefix:prefix]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"a string with prefix '%@'", prefix]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWStringUtilities.h b/Pods/Kiwi/Classes/KWStringUtilities.h new file mode 100644 index 0000000..e4ab0bd --- /dev/null +++ b/Pods/Kiwi/Classes/KWStringUtilities.h @@ -0,0 +1,20 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +#pragma mark - +#pragma mark Checking for Case Separated Words + +BOOL KWStringHasWordPrefix(NSString *string, NSString *prefix); +BOOL KWStringHasStrictWordPrefix(NSString *string, NSString *prefix); +BOOL KWStringHasWord(NSString *string, NSString *word); + +#pragma mark - +#pragma mark Getting Type Encodings + +NSString *KWEncodingWithObjCTypes(const char *firstType, ...) NS_REQUIRES_NIL_TERMINATION; +NSString *KWEncodingForVoidMethod(void); diff --git a/Pods/Kiwi/Classes/KWStringUtilities.m b/Pods/Kiwi/Classes/KWStringUtilities.m new file mode 100644 index 0000000..4ceceb5 --- /dev/null +++ b/Pods/Kiwi/Classes/KWStringUtilities.m @@ -0,0 +1,90 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWStringUtilities.h" + +#pragma mark - +#pragma mark Checking for Case Separated Words + +BOOL KWStringHasWordPrefix(NSString *string, NSString *prefix) { + return [string isEqualToString:prefix] || KWStringHasStrictWordPrefix(string, prefix); +} + +BOOL KWStringHasStrictWordPrefix(NSString *string, NSString *prefix) { + if (![string hasPrefix:prefix] || [string length] == [prefix length]) + return NO; + + unichar firstCharacterAfterPrefix = [string characterAtIndex:[prefix length]]; + NSCharacterSet *uppercaseCharacterSet = [NSCharacterSet uppercaseLetterCharacterSet]; + return [uppercaseCharacterSet characterIsMember:firstCharacterAfterPrefix]; +} + +BOOL KWStringHasWord(NSString *string, NSString *word) { + if (KWStringHasWordPrefix(string, word)) + return YES; + + NSCharacterSet *lowercaseCharacterSet = [NSCharacterSet lowercaseLetterCharacterSet]; + NSCharacterSet *uppercaseCharacterSet = [NSCharacterSet uppercaseLetterCharacterSet]; + NSRange searchRange = NSMakeRange(0, [string length]); + + // Never match if word begins with a lowercase letter and was not a prefix. + if ([lowercaseCharacterSet characterIsMember:[word characterAtIndex:0]]) + return NO; + + while (1) { + if (searchRange.location >= [string length]) + return NO; + + NSRange range = [string rangeOfString:word options:0 range:searchRange]; + searchRange.location = range.location + range.length; + searchRange.length = [string length] - searchRange.location; + + if (range.location == NSNotFound) + return NO; + + if (range.location > 0) { + unichar charBeforeRange = [string characterAtIndex:range.location - 1]; + + + if (![lowercaseCharacterSet characterIsMember:charBeforeRange]) + continue; + } + + if (range.location + range.length < [string length]) { + unichar charAfterRange = [string characterAtIndex:range.location + range.length]; + + if (![uppercaseCharacterSet characterIsMember:charAfterRange]) + continue; + } + + return YES; + } +} + +#pragma mark - +#pragma mark Getting Type Encodings + +NSString *KWEncodingWithObjCTypes(const char *firstType, ...) { + if (firstType == nil) + return nil; + + NSMutableString *encoding = [NSMutableString stringWithCapacity:8]; + va_list argumentList; + va_start(argumentList, firstType); + const char *type = firstType; + + do { + [encoding appendFormat:@"%s", type]; + type = va_arg(argumentList, const char *); + } while (type != nil); + + va_end(argumentList); + return encoding; +} + +NSString *KWEncodingForVoidMethod(void) { + return KWEncodingWithObjCTypes(@encode(void), @encode(id), @encode(SEL), nil); +} diff --git a/Pods/Kiwi/Classes/KWStub.h b/Pods/Kiwi/Classes/KWStub.h new file mode 100644 index 0000000..f742843 --- /dev/null +++ b/Pods/Kiwi/Classes/KWStub.h @@ -0,0 +1,48 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@class KWMessagePattern; + +@interface KWStub : NSObject { +@private + KWMessagePattern *messagePattern; + id value; + id returnValueTimes; + int returnedValueTimes; + id secondValue; + id (^block)(NSArray *params); +} + +#pragma mark - +#pragma mark Initializing + +- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern; +- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern value:(id)aValue; +- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern block:(id (^)(NSArray *params))aBlock; +- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern value:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue; + ++ (id)stubWithMessagePattern:(KWMessagePattern *)aMessagePattern; ++ (id)stubWithMessagePattern:(KWMessagePattern *)aMessagePattern value:(id)aValue; ++ (id)stubWithMessagePattern:(KWMessagePattern *)aMessagePattern block:(id (^)(NSArray *params))aBlock; ++ (id)stubWithMessagePattern:(KWMessagePattern *)aMessagePattern value:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue; + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) KWMessagePattern *messagePattern; +@property (nonatomic, readonly) id value; +@property (nonatomic, readonly) id returnValueTimes; +@property (nonatomic, readonly) int returnedValueTimes; +@property (nonatomic, readonly) id secondValue; + +#pragma mark - +#pragma mark Processing Invocations + +- (BOOL)processInvocation:(NSInvocation *)anInvocation; + +@end diff --git a/Pods/Kiwi/Classes/KWStub.m b/Pods/Kiwi/Classes/KWStub.m new file mode 100644 index 0000000..95b518e --- /dev/null +++ b/Pods/Kiwi/Classes/KWStub.m @@ -0,0 +1,221 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWStub.h" +#import "KWMessagePattern.h" +#import "KWObjCUtilities.h" +#import "KWStringUtilities.h" +#import "KWValue.h" + +#import "NSInvocation+OCMAdditions.h" + +@implementation KWStub + +#pragma mark - +#pragma mark Initializing + +- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern { + return [self initWithMessagePattern:aMessagePattern value:nil]; +} + +- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern value:(id)aValue { + if ((self = [super init])) { + messagePattern = [aMessagePattern retain]; + value = [aValue retain]; + } + + return self; +} + +- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern block:(id (^)(NSArray *params))aBlock { + if ((self = [super init])) { + messagePattern = [aMessagePattern retain]; + block = [aBlock copy]; + } + + return self; +} + +- (id)initWithMessagePattern:(KWMessagePattern *)aMessagePattern value:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue { + if ((self = [super init])) { + messagePattern = [aMessagePattern retain]; + value = [aValue retain]; + returnValueTimes = [times retain]; + secondValue = [aSecondValue retain]; + } + + return self; +} + ++ (id)stubWithMessagePattern:(KWMessagePattern *)aMessagePattern { + return [self stubWithMessagePattern:aMessagePattern value:nil]; +} + ++ (id)stubWithMessagePattern:(KWMessagePattern *)aMessagePattern value:(id)aValue { + return [[[self alloc] initWithMessagePattern:aMessagePattern value:aValue] autorelease]; +} + ++ (id)stubWithMessagePattern:(KWMessagePattern *)aMessagePattern block:(id (^)(NSArray *params))aBlock { + return [[[self alloc] initWithMessagePattern:aMessagePattern block:aBlock] autorelease]; +} + ++ (id)stubWithMessagePattern:(KWMessagePattern *)aMessagePattern value:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue { + return [[[self alloc] initWithMessagePattern:aMessagePattern value:aValue times:times afterThatReturn:aSecondValue] autorelease]; +} + +- (void)dealloc { + [messagePattern release]; + [value release]; + [returnValueTimes release]; + [secondValue release]; + [block release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize messagePattern; +@synthesize value; +@synthesize secondValue; +@synthesize returnValueTimes; +@synthesize returnedValueTimes; + +#pragma mark - +#pragma mark Processing Invocations + +- (void)writeZerosToInvocationReturnValue:(NSInvocation *)anInvocation { + NSUInteger returnLength = [[anInvocation methodSignature] methodReturnLength]; + + if (returnLength == 0) + return; + + void *bytes = malloc(returnLength); + memset(bytes, 0, returnLength); + [anInvocation setReturnValue:bytes]; + free(bytes); +} + +- (NSData *)valueDataWithObjCType:(const char *)objCType { + assert(self.value && "self.value must not be nil"); + NSData *data = [self.value dataForObjCType:objCType]; + + if (data == nil) { + [NSException raise:@"KWStubException" format:@"wrapped stub value type (%s) could not be converted to the target type (%s)", + [self.value objCType], + objCType]; + } + + return data; +} + +- (void)writeWrappedValueToInvocationReturnValue:(NSInvocation *)anInvocation { + assert(self.value && "self.value must not be nil"); + const char *returnType = [[anInvocation methodSignature] methodReturnType]; + NSData *data = nil; + + NSData *choosedForData = [self.value dataValue]; + + if (returnValueTimes != nil) { + NSString *returnValueTimesString = returnValueTimes; + int returnValueTimesInt = [returnValueTimesString intValue]; + + if (returnedValueTimes >= returnValueTimesInt) { + choosedForData = [self.secondValue dataValue]; + } + returnedValueTimes++; + } + + + // When the return type is not the same as the type of the wrapped value, + // attempt to convert the wrapped value to the desired type. + + if (KWObjCTypeEqualToObjCType([self.value objCType], returnType)) + data = choosedForData; + else + data = [self valueDataWithObjCType:returnType]; + + [anInvocation setReturnValue:(void *)[data bytes]]; +} + +- (void)writeObjectValueToInvocationReturnValue:(NSInvocation *)anInvocation { + assert(self.value && "self.value must not be nil"); + + void *choosedForData = &value; + + if (returnValueTimes != nil) { + NSString *returnValueTimesString = returnValueTimes; + int returnValueTimesInt = [returnValueTimesString intValue]; + + if (returnedValueTimes >= returnValueTimesInt) { + choosedForData = &secondValue; + } + returnedValueTimes++; + } + + [anInvocation setReturnValue:choosedForData]; + +#ifndef __clang_analyzer__ + NSString *selectorString = NSStringFromSelector([anInvocation selector]); + + // To conform to memory management conventions, retain if writing a result + // that begins with alloc, new or contains copy. This shows up as a false + // positive in clang due to the runtime conditional, so ignore it. + if (KWStringHasWordPrefix(selectorString, @"alloc") || + KWStringHasWordPrefix(selectorString, @"new") || + KWStringHasWord(selectorString, @"copy") || + KWStringHasWord(selectorString, @"Copy")) { + [self.value retain]; + } +#endif +} + +- (BOOL)processInvocation:(NSInvocation *)anInvocation { + if (![self.messagePattern matchesInvocation:anInvocation]) + return NO; + + if (block) { + NSUInteger numberOfArguments = [[anInvocation methodSignature] numberOfArguments]; + NSMutableArray *args = [NSMutableArray arrayWithCapacity:(numberOfArguments-2)]; + for (NSUInteger i = 2; i < numberOfArguments; ++i) { + id arg = [anInvocation getArgumentAtIndexAsObject:i]; + + const char *argType = [[anInvocation methodSignature] getArgumentTypeAtIndex:i]; + if (strcmp(argType, "@?") == 0) arg = [[arg copy] autorelease]; + + if (arg == nil) + arg = [NSNull null]; + + [args addObject:arg]; + } + + id newValue = block(args); + if (newValue != value) { + [value release]; + value = [newValue retain]; + } + + [args removeAllObjects]; // We don't want these objects to be in autorelease pool + } + + if (self.value == nil) + [self writeZerosToInvocationReturnValue:anInvocation]; + else if ([self.value isKindOfClass:[KWValue class]]) + [self writeWrappedValueToInvocationReturnValue:anInvocation]; + else + [self writeObjectValueToInvocationReturnValue:anInvocation]; + + return YES; +} + +#pragma mark - +#pragma mark Debugging + +- (NSString *)description { + return [NSString stringWithFormat:@"messagePattern: %@\nvalue: %@", self.messagePattern, self.value]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWTestCase.h b/Pods/Kiwi/Classes/KWTestCase.h new file mode 100644 index 0000000..d3e5e7d --- /dev/null +++ b/Pods/Kiwi/Classes/KWTestCase.h @@ -0,0 +1,45 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" +#import +#import "KWExpectationType.h" +#import "KWReporting.h" + +@class KWCallSite; +@class KWMatcherFactory; + +@protocol KWVerifying; + +// Deprecated. This is here just in case blocks are not enabled. +@interface KWTestCase : SenTestCase { +@private + KWMatcherFactory *matcherFactory; + NSMutableArray *verifiers; + NSMutableArray *failures; +} + +#pragma mark - +#pragma mark Configuring Example Environments + +- (void)setUpExampleEnvironment; +- (void)tearDownExampleEnvironment; + +#pragma mark - +#pragma mark Marking Pending Examples + +- (void)markPendingWithCallSite:(KWCallSite *)aCallSite; +- (void)markPendingWithCallSite:(KWCallSite *)aCallSite :(NSString *)aDescription; + +#pragma mark - +#pragma mark Adding Verifiers + +- (id)addVerifier:(id)aVerifier; +- (id)addExistVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite; +- (id)addMatchVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite; +- (id)addAsyncVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite timeout:(NSInteger)timeout; + +@end diff --git a/Pods/Kiwi/Classes/KWTestCase.m b/Pods/Kiwi/Classes/KWTestCase.m new file mode 100644 index 0000000..35f9774 --- /dev/null +++ b/Pods/Kiwi/Classes/KWTestCase.m @@ -0,0 +1,191 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWTestCase.h" +#import +#import "KWDeviceInfo.h" +#import "KWExistVerifier.h" +#import "KWFailure.h" +#import "KWIntercept.h" +#import "KWMatcherFactory.h" +#import "KWMatchVerifier.h" +#import "KWAsyncVerifier.h" +#import "KWObjCUtilities.h" +#import "KWStringUtilities.h" +#import "KWVerifying.h" +#import "NSMethodSignature+KiwiAdditions.h" + +@interface KWTestCase() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) KWMatcherFactory *matcherFactory; +@property (nonatomic, readonly) NSMutableArray *verifiers; +@property (nonatomic, readonly) NSMutableArray *failures; +@end + +@implementation KWTestCase + +#pragma mark - +#pragma mark Initializing + +// Initializer used by the SenTestingKit test suite to initialize a test case +// for each test invocation returned in +testInvocations. +- (id)initWithInvocation:(NSInvocation *)anInvocation { + if ((self = [super initWithInvocation:anInvocation])) { + matcherFactory = [[KWMatcherFactory alloc] init]; + verifiers = [[NSMutableArray alloc] init]; + failures = [[NSMutableArray alloc] init]; + } + + return self; +} + +- (void)dealloc { + [matcherFactory release]; + [verifiers release]; + [failures release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize verifiers; +@synthesize matcherFactory; +@synthesize failures; + +#pragma mark - +#pragma mark Configuring Example Environments + +- (void)setUpExampleEnvironment { + [self.matcherFactory registerMatcherClassesWithNamespacePrefix:@"KW"]; +} + +- (void)tearDownExampleEnvironment { + KWClearStubsAndSpies(); +} + +#pragma mark - +#pragma mark Marking Pending Examples + +- (void)markPendingWithCallSite:(KWCallSite *)aCallSite { + KWFailure *failure = [KWFailure failureWithCallSite:aCallSite format:@"PENDING"]; + [self reportFailure:failure]; +} + +- (void)markPendingWithCallSite:(KWCallSite *)aCallSite :(NSString *)aDescription { + KWFailure *failure = [KWFailure failureWithCallSite:aCallSite format:@"PENDING (%@)", aDescription]; + [self reportFailure:failure]; +} + +#pragma mark - +#pragma mark Adding Verifiers + +- (id)addVerifier:(id)aVerifier { + if (![self.verifiers containsObject:aVerifier]) + [self.verifiers addObject:aVerifier]; + + return aVerifier; +} + +- (id)addExistVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite { + id verifier = [KWExistVerifier existVerifierWithExpectationType:anExpectationType callSite:aCallSite reporter:self]; + [self.verifiers addObject:verifier]; + return verifier; +} + +- (id)addMatchVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite { + id verifier = [KWMatchVerifier matchVerifierWithExpectationType:anExpectationType callSite:aCallSite matcherFactory:self.matcherFactory reporter:self]; + [self.verifiers addObject:verifier]; + return verifier; +} + +- (id)addAsyncVerifierWithExpectationType:(KWExpectationType)anExpectationType callSite:(KWCallSite *)aCallSite timeout:(NSInteger)timeout { + id verifier = [KWAsyncVerifier asyncVerifierWithExpectationType:anExpectationType callSite:aCallSite matcherFactory:self.matcherFactory reporter:self probeTimeout:timeout]; + [self.verifiers addObject:verifier]; + return verifier; +} + +#pragma mark - +#pragma mark Reporting Failures + ++ (KWFailure *)tidiedFailureWithFailure:(KWFailure *)aFailure { + if ([KWDeviceInfo isSimulator]) { + // \uff1a is the unicode for a fill width colon, as opposed to a + // regular :. This escape is performed so that Xcode doesn't truncate + // the error in the build results window, which is nice for build + // tests. + NSString *escapedMessage = [aFailure.message stringByReplacingOccurrencesOfString:@":" withString:@"\uff1a"]; + return [KWFailure failureWithCallSite:aFailure.callSite message:escapedMessage]; + } else { + return aFailure; + } +} + +- (void)reportFailure:(KWFailure *)aFailure; { + [self.failures addObject:aFailure]; + KWFailure *tidiedFailure = [[self class] tidiedFailureWithFailure:aFailure]; + [self failWithException:[tidiedFailure exceptionValue]]; +} + +#pragma mark - +#pragma mark Getting Invocations + +// Called by the SenTestingKit test suite to get an array of invocations that +// should be run on instances of test cases. ++ (NSArray *)testInvocations { + // Examples are methods returning void with no parameters in the receiver + // that begin with "it" followed by an uppercase word. + NSMutableArray *exampleInvocations = [[[NSMutableArray alloc] init] autorelease]; + unsigned int methodCount = 0; + Method *methods = class_copyMethodList([self class], &methodCount); + + for (unsigned int i = 0; i < methodCount; i++) { + SEL selector = method_getName(methods[i]); + NSString *selectorString = NSStringFromSelector(selector); + + if (KWStringHasStrictWordPrefix(selectorString, @"it")) { + const char *encoding = method_getTypeEncoding(methods[i]); + NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:encoding]; + + if ([signature numberOfMessageArguments] > 0 || + !KWObjCTypeEqualToObjCType([signature methodReturnType], @encode(void))) + continue; + + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; + [invocation setSelector:selector]; + [exampleInvocations addObject:invocation]; + } + } + + free(methods); + return exampleInvocations; +} + +#pragma mark - +#pragma mark Running Test Cases + +// Called by the SenTestingKit test suite when it is time to run the test. +- (void)invokeTest { + NSAutoreleasePool *subPool = [[NSAutoreleasePool alloc] init]; + [self setUpExampleEnvironment]; + + @try { + [super invokeTest]; + + for (id verifier in self.verifiers) + [verifier exampleWillEnd]; + } @catch (NSException *exception) { + [self failWithException:exception]; + } + + [self tearDownExampleEnvironment]; + [subPool release]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWUserDefinedMatcher.h b/Pods/Kiwi/Classes/KWUserDefinedMatcher.h new file mode 100644 index 0000000..5662a14 --- /dev/null +++ b/Pods/Kiwi/Classes/KWUserDefinedMatcher.h @@ -0,0 +1,62 @@ +// +// KWUserDefinedMatcher.h +// Kiwi +// +// Created by Luke Redpath on 16/06/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import +#import "KWMatcher.h" + +typedef BOOL (^KWUserDefinedMatcherBlock)(); + +@interface KWUserDefinedMatcher : KWMatcher +{ + KWUserDefinedMatcherBlock matcherBlock; + SEL selector; + NSInvocation *invocation; + NSString *failureMessageForShould; + NSString *failureMessageForShouldNot; +} +@property (nonatomic, assign) SEL selector; +@property (nonatomic, copy) NSString *failureMessageForShould; +@property (nonatomic, copy) NSString *failureMessageForShouldNot; +@property (nonatomic, assign) KWUserDefinedMatcherBlock matcherBlock; +@property (nonatomic, copy) NSString *description; + ++ (id)matcherWithSubject:(id)aSubject block:(KWUserDefinedMatcherBlock)aBlock; +- (id)initWithSubject:(id)aSubject block:(KWUserDefinedMatcherBlock)aBlock; +- (void)setSubject:(id)aSubject; +@end + +#pragma mark - + +typedef NSString * (^KWUserDefinedMatcherMessageBlock)(id); + +@interface KWUserDefinedMatcherBuilder : NSObject +{ + KWUserDefinedMatcher *matcher; + KWUserDefinedMatcherMessageBlock failureMessageForShouldBlock; + KWUserDefinedMatcherMessageBlock failureMessageForShouldNotBlock; + NSString *description; +} +@property (nonatomic, readonly) NSString *key; + ++ (id)builder; ++ (id)builderForSelector:(SEL)aSelector; +- (id)initWithSelector:(SEL)aSelector; + +#pragma mark - +#pragma mark Configuring The Matcher + +- (void)match:(KWUserDefinedMatcherBlock)block; +- (void)failureMessageForShould:(KWUserDefinedMatcherMessageBlock)block; +- (void)failureMessageForShouldNot:(KWUserDefinedMatcherMessageBlock)block; +- (void)description:(NSString *)description; + +#pragma mark - +#pragma mark Buiding The Matcher + +- (KWUserDefinedMatcher *)buildMatcherWithSubject:(id)subject; +@end diff --git a/Pods/Kiwi/Classes/KWUserDefinedMatcher.m b/Pods/Kiwi/Classes/KWUserDefinedMatcher.m new file mode 100644 index 0000000..c83d669 --- /dev/null +++ b/Pods/Kiwi/Classes/KWUserDefinedMatcher.m @@ -0,0 +1,178 @@ +// +// KWUserDefinedMatcher.m +// Kiwi +// +// Created by Luke Redpath on 16/06/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import "KWUserDefinedMatcher.h" + +@implementation KWUserDefinedMatcher + +@synthesize selector; +@synthesize failureMessageForShould; +@synthesize failureMessageForShouldNot; +@synthesize matcherBlock; +@synthesize description; + ++ (id)matcherWithSubject:(id)aSubject block:(KWUserDefinedMatcherBlock)aBlock +{ + return [[[self alloc] initWithSubject:aSubject block:aBlock] autorelease]; +} + +- (id)initWithSubject:(id)aSubject block:(KWUserDefinedMatcherBlock)aBlock +{ + if ((self = [super initWithSubject:aSubject])) { + matcherBlock = [aBlock copy]; + self.description = @"match user defined matcher"; + } + return self; +} + +- (void)dealloc +{ + [invocation release]; + [matcherBlock release]; + [super dealloc]; +} + +- (BOOL)evaluate +{ + BOOL result; + + if (invocation.methodSignature.numberOfArguments == 3) { + id argument; + [invocation getArgument:&argument atIndex:2]; + result = matcherBlock(self.subject, argument); + } else { + result = matcherBlock(self.subject); + } + return result; +} + +- (void)setSubject:(id)aSubject { + if (aSubject != subject) { + [subject release]; + subject = [aSubject retain]; + } +} + +#pragma mark - +#pragma mark Message forwarding + +- (BOOL)respondsToSelector:(SEL)aSelector +{ + if (aSelector == self.selector) { + return YES; + } + return [super respondsToSelector:aSelector]; +} + +- (void)forwardInvocation:(NSInvocation *)anInvocation +{ + [invocation autorelease]; + invocation = [anInvocation retain]; +} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector +{ + if (aSelector == self.selector) { + NSString *selectorString = NSStringFromSelector(self.selector); + + /** + * TODO: find a way of doing this that: + * - doesn't require dummy methods (create the method signatures manually) + * - supports an unlimited number of arguments + */ + if ([selectorString hasSuffix:@":"]) { + return [self methodSignatureForSelector:@selector(matcherMethodWithArgument:)]; + } else { + return [self methodSignatureForSelector:@selector(matcherMethodWithoutArguments)]; + } + } + return [super methodSignatureForSelector:aSelector]; +} + +- (void)matcherMethodWithoutArguments {} +- (void)matcherMethodWithArgument:(id)argument {} + +@end + +#pragma mark - + +@implementation KWUserDefinedMatcherBuilder + ++ (id)builder +{ + return [self builderForSelector:nil]; +} + ++ (id)builderForSelector:(SEL)aSelector { + return [[[self alloc] initWithSelector:aSelector] autorelease]; +} + +- (id)initWithSelector:(SEL)aSelector { + if ((self = [super init])) { + matcher = [[KWUserDefinedMatcher alloc] init]; + matcher.selector = aSelector; + } + return self; +} + +- (void)dealloc +{ + [matcher release]; + [failureMessageForShouldBlock release]; + [super dealloc]; +} + +- (NSString *)key { + return NSStringFromSelector(matcher.selector); +} + +#pragma mark - +#pragma mark Configuring The Matcher + +- (void)match:(KWUserDefinedMatcherBlock)block { + matcher.matcherBlock = block; +} + +- (void)failureMessageForShould:(KWUserDefinedMatcherMessageBlock)block { + [failureMessageForShouldBlock release]; + failureMessageForShouldBlock = [block copy]; +} + +- (void)failureMessageForShouldNot:(KWUserDefinedMatcherMessageBlock)block { + [failureMessageForShouldNotBlock release]; + failureMessageForShouldNotBlock = [block copy]; +} + +- (void)description:(NSString *)aDescription +{ + [description release]; + description = [aDescription copy]; +} + +#pragma mark - +#pragma mark Buiding The Matcher + +- (KWUserDefinedMatcher *)buildMatcherWithSubject:(id)subject { + [matcher setSubject:subject]; + + if (failureMessageForShouldBlock) { + [matcher setFailureMessageForShould:failureMessageForShouldBlock(subject)]; + } + + if (failureMessageForShouldNotBlock) { + [matcher setFailureMessageForShouldNot:failureMessageForShouldNotBlock(subject)]; + } + + if (description) { + [matcher setDescription:description]; + } + + return matcher; +} + +@end diff --git a/Pods/Kiwi/Classes/KWValue.h b/Pods/Kiwi/Classes/KWValue.h new file mode 100644 index 0000000..8205426 --- /dev/null +++ b/Pods/Kiwi/Classes/KWValue.h @@ -0,0 +1,97 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@interface KWValue : NSObject { +@private + const char *objCType; + id value; +} + +#pragma mark - +#pragma mark Initializing + +- (id)initWithBytes:(const void *)bytes objCType:(const char *)anObjCType; + ++ (id)valueWithBytes:(const void *)bytes objCType:(const char *)anObjCType; ++ (id)valueWithBool:(BOOL)aValue; ++ (id)valueWithChar:(char)aValue; ++ (id)valueWithDouble:(double)aValue; ++ (id)valueWithFloat:(float)aValue; ++ (id)valueWithInt:(int)aValue; ++ (id)valueWithInteger:(NSInteger)aValue; ++ (id)valueWithLong:(long)aValue; ++ (id)valueWithLongLong:(long long)value; ++ (id)valueWithShort:(short)aValue; ++ (id)valueWithUnsignedChar:(unsigned char)aValue; ++ (id)valueWithUnsignedInt:(unsigned int)aValue; ++ (id)valueWithUnsignedInteger:(NSUInteger)aValue; ++ (id)valueWithUnsignedLong:(unsigned long)aValue; ++ (id)valueWithUnsignedLongLong:(unsigned long long)aValue; ++ (id)valueWithUnsignedShort:(unsigned short)aValue; + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) const char *objCType; +@property (nonatomic, readonly) BOOL isNumeric; + +#pragma mark - +#pragma mark Accessing Numeric Values + +- (NSNumber *)numberValue; +- (BOOL)boolValue; +- (char)charValue; +- (double)doubleValue; +- (float)floatValue; +- (int)intValue; +- (NSInteger)integerValue; +- (long)longValue; +- (long long)longLongValue; +- (short)shortValue; +- (unsigned char)unsignedCharValue; +- (unsigned int)unsignedIntValue; +- (NSUInteger)unsignedIntegerValue; +- (unsigned long)unsignedLongValue; +- (unsigned long long)unsignedLongLongValue; +- (unsigned short)unsignedShortValue; + +#pragma mark - +#pragma mark Accessing Data + +- (NSData *)dataValue; +- (void)getValue:(void *)buffer; + +#pragma mark - +#pragma mark Accessing Numeric Data + +- (NSData *)dataForObjCType:(const char *)anObjCType; +- (NSData *)boolData; +- (NSData *)charData; +- (NSData *)doubleData; +- (NSData *)floatData; +- (NSData *)intData; +- (NSData *)integerData; +- (NSData *)longData; +- (NSData *)longLongData; +- (NSData *)shortData; +- (NSData *)unsignedCharData; +- (NSData *)unsignedIntData; +- (NSData *)unsignedIntegerData; +- (NSData *)unsignedLongData; +- (NSData *)unsignedLongLongData; +- (NSData *)unsignedShortData; + +#pragma mark - +#pragma mark Comparing Values + +- (NSComparisonResult)compare:(KWValue *)aValue; + +- (BOOL)isEqualToKWValue:(KWValue *)aValue; +- (BOOL)isEqualToNumber:(NSNumber *)aValue; + +@end diff --git a/Pods/Kiwi/Classes/KWValue.m b/Pods/Kiwi/Classes/KWValue.m new file mode 100644 index 0000000..e76ca86 --- /dev/null +++ b/Pods/Kiwi/Classes/KWValue.m @@ -0,0 +1,359 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWValue.h" +#import "KWObjCUtilities.h" +#import "NSNumber+KiwiAdditions.h" + +@interface KWValue() + +#pragma mark - +#pragma mark Properties + +@property (nonatomic, readonly) id value; + +@end + +@implementation KWValue + +#pragma mark - +#pragma mark Initializing + +- (id)initWithBytes:(const void *)bytes objCType:(const char *)anObjCType { + if ((self = [super init])) { + objCType = anObjCType; + value = [[NSValue alloc] initWithBytes:bytes objCType:anObjCType]; + } + + return self; +} + ++ (id)valueWithBytes:(const void *)bytes objCType:(const char *)type { + return [[[self alloc] initWithBytes:bytes objCType:type] autorelease]; +} + ++ (id)valueWithBool:(BOOL)aValue { + return [self valueWithBytes:&aValue objCType:@encode(BOOL)]; +} + ++ (id)valueWithChar:(char)aValue { + return [self valueWithBytes:&aValue objCType:@encode(char)]; +} + ++ (id)valueWithDouble:(double)aValue { + return [self valueWithBytes:&aValue objCType:@encode(double)]; +} + ++ (id)valueWithFloat:(float)aValue { + return [self valueWithBytes:&aValue objCType:@encode(float)]; +} + ++ (id)valueWithInt:(int)aValue { + return [self valueWithBytes:&aValue objCType:@encode(int)]; +} + ++ (id)valueWithInteger:(NSInteger)aValue { + return [self valueWithBytes:&aValue objCType:@encode(NSInteger)]; +} + ++ (id)valueWithLong:(long)aValue { + return [self valueWithBytes:&aValue objCType:@encode(long)]; +} + ++ (id)valueWithLongLong:(long long)value { + return [self valueWithBytes:&value objCType:@encode(long long)]; +} + ++ (id)valueWithShort:(short)aValue { + return [self valueWithBytes:&aValue objCType:@encode(short)]; +} + ++ (id)valueWithUnsignedChar:(unsigned char)aValue { + return [self valueWithBytes:&aValue objCType:@encode(unsigned char)]; +} + ++ (id)valueWithUnsignedInt:(unsigned int)aValue { + return [self valueWithBytes:&aValue objCType:@encode(unsigned int)]; +} + ++ (id)valueWithUnsignedInteger:(NSUInteger)aValue { + return [self valueWithBytes:&aValue objCType:@encode(NSUInteger)]; +} + ++ (id)valueWithUnsignedLong:(unsigned long)aValue { + return [self valueWithBytes:&aValue objCType:@encode(unsigned long)]; +} + ++ (id)valueWithUnsignedLongLong:(unsigned long long)aValue { + return [self valueWithBytes:&aValue objCType:@encode(long long)]; +} + ++ (id)valueWithUnsignedShort:(unsigned short)aValue { + return [self valueWithBytes:&aValue objCType:@encode(unsigned short)]; +} + +- (void)dealloc { + [value release]; + [super dealloc]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize objCType; + +- (BOOL)isNumeric { + return KWObjCTypeIsNumeric(self.objCType); +} + +@synthesize value; + +#pragma mark - +#pragma mark Accessing Numeric Values + +- (NSNumber *)numberValue { + if (!KWObjCTypeIsNumeric(self.objCType)) + [NSException raise:NSInternalInconsistencyException format:@"cannot return number value because wrapped value is non-numeric"]; + + NSData *data = [self dataValue]; + return [NSNumber numberWithBytes:[data bytes] objCType:self.objCType]; +} + +- (BOOL)boolValue { + return [[self numberValue] boolValue]; +} + +- (char)charValue { + return [[self numberValue] charValue]; +} + +- (double)doubleValue { + return [[self numberValue] doubleValue]; +} + +- (float)floatValue { + return [[self numberValue] floatValue]; +} + +- (int)intValue { + return [[self numberValue] intValue]; +} + +- (NSInteger)integerValue { + return [[self numberValue] integerValue]; +} + +- (long)longValue { + return [[self numberValue] longValue]; +} + +- (long long)longLongValue { + return [[self numberValue] longLongValue]; +} +- (short)shortValue { + return [[self numberValue] shortValue]; +} + +- (unsigned char)unsignedCharValue { + return [[self numberValue] unsignedCharValue]; +} + +- (unsigned int)unsignedIntValue { + return [[self numberValue] unsignedIntValue]; +} + +- (NSUInteger)unsignedIntegerValue { + return [[self numberValue] unsignedIntegerValue]; +} + +- (unsigned long)unsignedLongValue { + return [[self numberValue] unsignedLongValue]; +} + +- (unsigned long long)unsignedLongLongValue { + return [[self numberValue] unsignedLongLongValue]; +} + +- (unsigned short)unsignedShortValue { + return [[self numberValue] unsignedShortValue]; +} + +#pragma mark - +#pragma mark Accessing Data + +- (NSData *)dataValue { + NSUInteger length = KWObjCTypeLength(self.objCType); + void *buffer = malloc(length); + [self.value getValue:buffer]; + NSData *data = [NSData dataWithBytes:buffer length:length]; + free(buffer); + return data; +} + +- (void)getValue:(void *)buffer { + [self.value getValue:buffer]; +} + +#pragma mark - +#pragma mark Accessing Numeric Data + +- (NSData *)dataForObjCType:(const char *)anObjCType { + // Yeah, this is ugly. + if (KWObjCTypeEqualToObjCType(anObjCType, @encode(BOOL))) + return [self boolData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(char))) + return [self charData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(double))) + return [self doubleData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(float))) + return [self floatData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(int))) + return [self intData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(NSInteger))) + return [self integerData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(long))) + return [self longData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(long long))) + return [self longLongData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(short))) + return [self shortData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(unsigned char))) + return [self unsignedCharData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(unsigned int))) + return [self unsignedIntData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(NSUInteger))) + return [self unsignedIntegerData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(unsigned long))) + return [self unsignedLongData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(unsigned long long))) + return [self unsignedLongLongData]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(unsigned short))) + return [self unsignedShortData]; + else + return nil; +} + +- (NSData *)boolData { + BOOL aValue = [self boolValue]; + return [NSData dataWithBytes:&aValue length:sizeof(BOOL)]; +} + +- (NSData *)charData { + char aValue = [self charValue]; + return [NSData dataWithBytes:&aValue length:sizeof(char)]; +} + +- (NSData *)doubleData { + double aValue = [self doubleValue]; + return [NSData dataWithBytes:&aValue length:sizeof(double)]; +} + +- (NSData *)floatData { + float aValue = [self floatValue]; + return [NSData dataWithBytes:&aValue length:sizeof(float)]; +} + +- (NSData *)intData { + int aValue = [self intValue]; + return [NSData dataWithBytes:&aValue length:sizeof(int)]; +} + +- (NSData *)integerData { + NSInteger aValue = [self integerValue]; + return [NSData dataWithBytes:&aValue length:sizeof(NSInteger)]; +} + +- (NSData *)longData { + long aValue = [self longValue]; + return [NSData dataWithBytes:&aValue length:sizeof(long)]; +} + +- (NSData *)longLongData { + long long aValue = [self longLongValue]; + return [NSData dataWithBytes:&aValue length:sizeof(long long)]; +} + +- (NSData *)shortData { + short aValue = [self shortValue]; + return [NSData dataWithBytes:&aValue length:sizeof(short)]; +} + +- (NSData *)unsignedCharData { + unsigned char aValue = [self unsignedCharValue]; + return [NSData dataWithBytes:&aValue length:sizeof(unsigned char)]; +} + +- (NSData *)unsignedIntData { + unsigned int aValue = [self unsignedIntValue]; + return [NSData dataWithBytes:&aValue length:sizeof(unsigned int)]; +} + +- (NSData *)unsignedIntegerData { + NSUInteger aValue = [self unsignedIntegerValue]; + return [NSData dataWithBytes:&aValue length:sizeof(NSUInteger)]; +} + +- (NSData *)unsignedLongData { + unsigned long aValue = [self unsignedLongValue]; + return [NSData dataWithBytes:&aValue length:sizeof(unsigned long)]; +} + +- (NSData *)unsignedLongLongData { + unsigned long long aValue = [self unsignedLongLongValue]; + return [NSData dataWithBytes:&aValue length:sizeof(unsigned long long)]; +} + +- (NSData *)unsignedShortData { + unsigned short aValue = [self unsignedShortValue]; + return [NSData dataWithBytes:&aValue length:sizeof(unsigned short)]; +} + +#pragma mark - +#pragma mark Comparing Objects + +- (NSUInteger)hash { + if (self.isNumeric) + return [[self numberValue] hash]; + + return [self.value hash]; +} + +- (NSComparisonResult)compare:(KWValue *)aValue { + return [[self numberValue] compare:[aValue numberValue]]; +} + +- (BOOL)isEqual:(id)object { + if ([object isKindOfClass:[KWValue class]]) + return [self isEqualToKWValue:object]; + + if ([object isKindOfClass:[NSNumber class]]) + return [self isEqualToNumber:object]; + + return NO; +} + +- (BOOL)isEqualToKWValue:(KWValue *)aValue { + if (self.isNumeric && aValue.isNumeric) + return [self isEqualToNumber:[aValue numberValue]]; + else + return [self.value isEqual:aValue.value]; +} + +- (BOOL)isEqualToNumber:(NSNumber *)aValue { + return [[self numberValue] isEqualToNumber:aValue]; +} + +#pragma mark - +#pragma mark Representing Values + +- (NSString *)description { + if ([self isNumeric]) + return [[self numberValue] description]; + + return [self.value description]; +} + +@end diff --git a/Pods/Kiwi/Classes/KWVerifying.h b/Pods/Kiwi/Classes/KWVerifying.h new file mode 100644 index 0000000..4fe730d --- /dev/null +++ b/Pods/Kiwi/Classes/KWVerifying.h @@ -0,0 +1,23 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@protocol KWVerifying + +- (NSString *)descriptionForAnonymousItNode; + +#pragma mark - +#pragma mark Setting Subjects + +- (void)setSubject:(id)anObject; + +#pragma mark - +#pragma mark Ending Examples + +- (void)exampleWillEnd; + +@end diff --git a/Pods/Kiwi/Classes/KWWorkarounds.h b/Pods/Kiwi/Classes/KWWorkarounds.h new file mode 100644 index 0000000..91926e3 --- /dev/null +++ b/Pods/Kiwi/Classes/KWWorkarounds.h @@ -0,0 +1,18 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + +#pragma mark - +#pragma mark Invocation Exception Bug Workaround + +// See KiwiConfiguration.h for notes. +void KWSetExceptionFromAcrossInvocationBoundary(NSException *anException); +NSException *KWGetAndClearExceptionFromAcrossInvocationBoundary(void); + +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG diff --git a/Pods/Kiwi/Classes/KWWorkarounds.m b/Pods/Kiwi/Classes/KWWorkarounds.m new file mode 100644 index 0000000..e4e98e9 --- /dev/null +++ b/Pods/Kiwi/Classes/KWWorkarounds.m @@ -0,0 +1,26 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KWWorkarounds.h" + +#if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG + +static NSException *KWExceptionAcrossInvokeBoundary = nil; + +void KWSetExceptionFromAcrossInvocationBoundary(NSException *anException) { + if (KWExceptionAcrossInvokeBoundary != nil) + return; + + KWExceptionAcrossInvokeBoundary = [anException retain]; +} + +NSException *KWGetAndClearExceptionFromAcrossInvocationBoundary(void) { + NSException *exception = [KWExceptionAcrossInvokeBoundary autorelease]; + KWExceptionAcrossInvokeBoundary = nil; + return exception; +} + +#endif // #if KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG diff --git a/Pods/Kiwi/Classes/Kiwi.h b/Pods/Kiwi/Classes/Kiwi.h new file mode 100644 index 0000000..3f040c1 --- /dev/null +++ b/Pods/Kiwi/Classes/Kiwi.h @@ -0,0 +1,100 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +// This needs to come first. +#import "KiwiConfiguration.h" +#import + +#if defined(__cplusplus) +extern "C" { +#endif + +#import "KWAfterAllNode.h" +#import "KWAfterEachNode.h" +#import "KWAny.h" +#import "KWAsyncVerifier.h" +#import "KWBeBetweenMatcher.h" +#import "KWBeEmptyMatcher.h" +#import "KWBeIdenticalToMatcher.h" +#import "KWBeKindOfClassMatcher.h" +#import "KWBeMemberOfClassMatcher.h" +#import "KWBeSubclassOfClassMatcher.h" +#import "KWBeTrueMatcher.h" +#import "KWBeNilMatcher.h" +#import "KWBeNonNilMatcher.h" +#import "KWBeWithinMatcher.h" +#import "KWBeZeroMatcher.h" +#import "KWBeforeAllNode.h" +#import "KWBeforeEachNode.h" +#import "KWBlock.h" +#import "KWBlockNode.h" +#import "KWBlockRaiseMatcher.h" +#import "KWCallSite.h" +#import "KWChangeMatcher.h" +#import "KWConformToProtocolMatcher.h" +#import "KWContainMatcher.h" +#import "KWContextNode.h" +#import "KWDeviceInfo.h" +#import "KWEqualMatcher.h" +#import "KWExample.h" +#import "KWExampleGroupBuilder.h" +#import "KWExampleNode.h" +#import "KWExampleNodeVisitor.h" +#import "KWExistVerifier.h" +#import "KWExpectationType.h" +#import "KWFailure.h" +#import "KWFormatter.h" +#import "KWFutureObject.h" +#import "KWGenericMatcher.h" +#import "KWHaveMatcher.h" +#import "KWHaveValueMatcher.h" +#import "KWInequalityMatcher.h" +#import "KWInvocationCapturer.h" +#import "KWItNode.h" +#import "KWMatchVerifier.h" +#import "KWMatcher.h" +#import "KWMatchers.h" +#import "KWMatcherFactory.h" +#import "KWMatching.h" +#import "KWMessagePattern.h" +#import "KWMessageSpying.h" +#import "KWMock.h" +#import "KWNull.h" +#import "KWObjCUtilities.h" +#import "KWPendingNode.h" +#import "KWRaiseMatcher.h" +#import "KWReceiveMatcher.h" +#import "KWRegisterMatchersNode.h" +#import "KWRespondToSelectorMatcher.h" +#import "KWSpec.h" +#import "KWStringUtilities.h" +#import "KWStub.h" +#import "KWTestCase.h" +#import "KWUserDefinedMatcher.h" +#import "KWValue.h" +#import "KWVerifying.h" +#import "KWCaptureSpy.h" +#import "KWStringPrefixMatcher.h" +#import "KWStringContainsMatcher.h" + + +// Public Foundation Categories +#import "NSObject+KiwiMockAdditions.h" +#import "NSObject+KiwiSpyAdditions.h" +#import "NSObject+KiwiStubAdditions.h" +#import "NSObject+KiwiVerifierAdditions.h" + +#import "KiwiMacros.h" + +// Some Foundation headers use Kiwi keywords (e.g. 'should') as identifiers for +// parameter names. Including this last allows the use of Kiwi keywords without +// conflicting with these headers (hopefully!). +#import "KiwiBlockMacros.h" + +#if defined(__cplusplus) +} +#endif + diff --git a/Pods/Kiwi/Classes/KiwiBlockMacros.h b/Pods/Kiwi/Classes/KiwiBlockMacros.h new file mode 100644 index 0000000..57f0bd8 --- /dev/null +++ b/Pods/Kiwi/Classes/KiwiBlockMacros.h @@ -0,0 +1,16 @@ +// +// KiwiBlockMacros.h +// Kiwi +// +// Created by Luke Redpath on 11/07/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +// user defined matchers +#define registerMatcher(name) \ +\ +@interface NSObject (KWUserDefinedMatchersDefinitions) \ +- (void)name; \ +@end \ + +#define defineMatcher(...) KWDefineMatchers(__VA_ARGS__) diff --git a/Pods/Kiwi/Classes/KiwiConfiguration.h b/Pods/Kiwi/Classes/KiwiConfiguration.h new file mode 100644 index 0000000..9dc59ba --- /dev/null +++ b/Pods/Kiwi/Classes/KiwiConfiguration.h @@ -0,0 +1,28 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import + +#define KW_VERSION 0.9001 + +// Blocks being unavailable cripples the usability of Kiwi, but is supported +// because they are not available on anything less than a device running 3.2. +#if !defined(__BLOCKS__) +#error "Kiwi requires blocks support." +#endif + +// As of iPhone SDK 4 GM, exceptions thrown across an NSInvocation -invoke or +// forwardInvocation: boundary in the simulator will terminate the app instead +// of being caught in @catch blocks from the caller side of the -invoke. Kiwi +// tries to handle this by storing the first exception that it would have +// otherwise thrown in a nasty global that callers can look for and handle. +// (Buggy termination is less desirable than global variables). +// +// Obviously, this can only handles cases where Kiwi itself would have raised +// an exception. +#if TARGET_IPHONE_SIMULATOR + #define KW_TARGET_HAS_INVOCATION_EXCEPTION_BUG 1 +#endif diff --git a/Pods/Kiwi/Classes/KiwiMacros.h b/Pods/Kiwi/Classes/KiwiMacros.h new file mode 100644 index 0000000..52776c7 --- /dev/null +++ b/Pods/Kiwi/Classes/KiwiMacros.h @@ -0,0 +1,80 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +// This category is solely meant to coax Xcode into exposing the method names below during autocompletion. +// There is no implementation and this class definition must come before the macro definitions below. +@interface NSObject (KiwiVerifierMacroNames) + +- (void)should; +- (void)shouldNot; +- (void)shouldBeNil; +- (void)shouldNotBeNil; +- (void)shouldEventually; +- (void)shouldEventuallyBeforeTimingOutAfter; + +@end + +#pragma mark - +#pragma mark Support Macros + +#define KW_THIS_CALLSITE [KWCallSite callSiteWithFilename:@__FILE__ lineNumber:__LINE__] +#define KW_ADD_EXIST_VERIFIER(expectationType) [self addExistVerifierWithExpectationType:expectationType callSite:KW_THIS_CALLSITE] +#define KW_ADD_MATCH_VERIFIER(expectationType) [self addMatchVerifierWithExpectationType:expectationType callSite:KW_THIS_CALLSITE] +#define KW_ADD_ASYNC_VERIFIER(expectationType, timeOut) [self addAsyncVerifierWithExpectationType:expectationType callSite:KW_THIS_CALLSITE timeout:timeOut] + +#pragma mark - +#pragma mark Keywords + +// Kiwi macros used in specs for verifying expectations. +#define should attachToVerifier:KW_ADD_MATCH_VERIFIER(KWExpectationTypeShould) verifier:KW_ADD_EXIST_VERIFIER(KWExpectationTypeShould) +#define shouldNot attachToVerifier:KW_ADD_MATCH_VERIFIER(KWExpectationTypeShouldNot) verifier:KW_ADD_EXIST_VERIFIER(KWExpectationTypeShould) +#define shouldBeNil attachToVerifier:KW_ADD_EXIST_VERIFIER(KWExpectationTypeShouldNot) +#define shouldNotBeNil attachToVerifier:KW_ADD_EXIST_VERIFIER(KWExpectationTypeShould) +#define shouldEventually attachToVerifier:KW_ADD_ASYNC_VERIFIER(KWExpectationTypeShould, kKW_DEFAULT_PROBE_TIMEOUT) +#define shouldEventuallyBeforeTimingOutAfter(timeout) attachToVerifier:KW_ADD_ASYNC_VERIFIER(KWExpectationTypeShould, timeout) + +// waitFor is like a shouldEventually but will not fail if it's never satisfied +#define waitFor attachToVerifier:KW_ADD_ASYNC_VERIFIER(KWExpectationTypeMaybe, kKW_DEFAULT_PROBE_TIMEOUT) + +// used to wrap a pointer to an object that will change in the future (used with shouldEventually) +#define theObject(objectPtr) [KWFutureObject objectWithObjectPointer:objectPtr] // DEPRECATED +#define theReturnValueOfBlock(block) [KWFutureObject futureObjectWithBlock:block] // DEPRECATED +#define expectFutureValue(futureValue) [KWFutureObject futureObjectWithBlock:^{ return futureValue; }] + +// used for message patterns to allow matching any value +#define any() [KWAny any] + +// If a gcc compatible compiler is available, use the statement and +// declarations in expression extension to provide a convenient catch-all macro +// to create KWValues. +#if defined(__GNUC__) + #define theValue(expr) \ + ({ \ + __typeof__(expr) kiwiReservedPrefix_lVar = expr; \ + [KWValue valueWithBytes:&kiwiReservedPrefix_lVar objCType:@encode(__typeof__(expr))]; \ + }) +#endif // #if defined(__GNUC__) + +// Allows for comparision of pointer values in expectations +#define thePointerValue(expr) [NSValue valueWithPointer:(expr)] + +// Example group declarations. +#define SPEC_BEGIN(name) \ + \ + @interface name : KWSpec \ + \ + @end \ + \ + @implementation name \ + \ + + (void)buildExampleGroups { \ + +#define SPEC_END \ + } \ + \ + @end diff --git a/Pods/Kiwi/Classes/KiwiNewMacros.h b/Pods/Kiwi/Classes/KiwiNewMacros.h new file mode 100644 index 0000000..c4afe41 --- /dev/null +++ b/Pods/Kiwi/Classes/KiwiNewMacros.h @@ -0,0 +1,10 @@ +// +// KiwiNewMacros.h +// Kiwi +// +// Created by Luke Redpath on 11/07/2011. +// Copyright 2011 Allen Ding. All rights reserved. +// + +#import + diff --git a/Pods/Kiwi/Classes/NSInvocation+KiwiAdditions.h b/Pods/Kiwi/Classes/NSInvocation+KiwiAdditions.h new file mode 100644 index 0000000..573dfd6 --- /dev/null +++ b/Pods/Kiwi/Classes/NSInvocation+KiwiAdditions.h @@ -0,0 +1,28 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@interface NSInvocation(KiwiAdditions) + +#pragma mark - +#pragma mark Creating NSInvocation Objects + ++ (NSInvocation *)invocationWithTarget:(id)anObject selector:(SEL)aSelector; ++ (NSInvocation *)invocationWithTarget:(id)anObject selector:(SEL)aSelector messageArguments:(const void *)firstBytes, ...; + +#pragma mark - +#pragma mark Accessing Message Arguments + +// Message arguments are invocation arguments that begin after the target and selector arguments. These methods provide +// convenient ways to access them. + +- (NSData *)messageArgumentDataAtIndex:(NSUInteger)anIndex; +- (void)getMessageArgument:(void *)buffer atIndex:(NSUInteger)anIndex; +- (void)setMessageArgument:(const void *)bytes atIndex:(NSUInteger)anIndex; +- (void)setMessageArguments:(const void *)firstBytes, ...; + +@end diff --git a/Pods/Kiwi/Classes/NSInvocation+KiwiAdditions.m b/Pods/Kiwi/Classes/NSInvocation+KiwiAdditions.m new file mode 100644 index 0000000..6f9cb78 --- /dev/null +++ b/Pods/Kiwi/Classes/NSInvocation+KiwiAdditions.m @@ -0,0 +1,93 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "NSInvocation+KiwiAdditions.h" +#import "KWFormatter.h" +#import "KWObjCUtilities.h" +#import "NSMethodSignature+KiwiAdditions.h" + +@implementation NSInvocation(KiwiAdditions) + +#pragma mark - +#pragma mark Creating NSInvocation Objects + ++ (NSInvocation *)invocationWithTarget:(id)anObject selector:(SEL)aSelector { + return [self invocationWithTarget:anObject selector:aSelector messageArguments:nil]; +} + ++ (NSInvocation *)invocationWithTarget:(id)anObject selector:(SEL)aSelector messageArguments:(const void *)firstBytes, ... { + if (anObject == nil) { + [NSException raise:NSInvalidArgumentException format:@"%@ - target must not be nil", + NSStringFromSelector(_cmd)]; + } + + NSMethodSignature *signature = [anObject methodSignatureForSelector:aSelector]; + + if (signature == nil) { + [NSException raise:NSInvalidArgumentException format:@"%@ - target returned nil for -methodSignatureForSelector", + NSStringFromSelector(_cmd)]; + } + + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; + [invocation setTarget:anObject]; + [invocation setSelector:aSelector]; + NSUInteger numberOfMessageArguments = [signature numberOfMessageArguments]; + + if (numberOfMessageArguments == 0) + return invocation; + + va_list argumentList; + va_start(argumentList, firstBytes); + const void *bytes = firstBytes; + + for (NSUInteger i = 0; i < numberOfMessageArguments && bytes != nil; ++i) { + [invocation setMessageArgument:bytes atIndex:i]; + bytes = va_arg(argumentList, const void *); + } + + va_end(argumentList); + return invocation; +} + +#pragma mark - +#pragma mark Accessing Message Arguments + +- (NSData *)messageArgumentDataAtIndex:(NSUInteger)anIndex { + NSUInteger length = KWObjCTypeLength([[self methodSignature] messageArgumentTypeAtIndex:anIndex]); + void *buffer = malloc(length); + [self getMessageArgument:buffer atIndex:anIndex]; + // NSData takes over ownership of buffer + NSData* data = [NSData dataWithBytesNoCopy:buffer length:length]; + return data; +} + +- (void)getMessageArgument:(void *)buffer atIndex:(NSUInteger)anIndex { + [self getArgument:buffer atIndex:anIndex + 2]; +} + +- (void)setMessageArgument:(const void *)bytes atIndex:(NSUInteger)anIndex { + [self setArgument:(void *)bytes atIndex:anIndex + 2]; +} + +- (void)setMessageArguments:(const void *)firstBytes, ... { + NSUInteger numberOfMessageArguments = [[self methodSignature] numberOfMessageArguments]; + + if (numberOfMessageArguments == 0) + return; + + va_list argumentList; + va_start(argumentList, firstBytes); + const void *bytes = firstBytes; + + for (NSUInteger i = 0; i < numberOfMessageArguments && bytes != nil; ++i) { + [self setMessageArgument:bytes atIndex:i]; + bytes = va_arg(argumentList, const void *); + } + + va_end(argumentList); +} + +@end diff --git a/Pods/Kiwi/Classes/NSInvocation+OCMAdditions.h b/Pods/Kiwi/Classes/NSInvocation+OCMAdditions.h new file mode 100644 index 0000000..04f22cd --- /dev/null +++ b/Pods/Kiwi/Classes/NSInvocation+OCMAdditions.h @@ -0,0 +1,34 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2006-2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface NSInvocation(OCMAdditions) + +- (id)getArgumentAtIndexAsObject:(int)argIndex; + +- (NSString *)invocationDescription; + +- (NSString *)argumentDescriptionAtIndex:(int)argIndex; + +- (NSString *)objectDescriptionAtIndex:(int)anInt; +- (NSString *)charDescriptionAtIndex:(int)anInt; +- (NSString *)unsignedCharDescriptionAtIndex:(int)anInt; +- (NSString *)intDescriptionAtIndex:(int)anInt; +- (NSString *)unsignedIntDescriptionAtIndex:(int)anInt; +- (NSString *)shortDescriptionAtIndex:(int)anInt; +- (NSString *)unsignedShortDescriptionAtIndex:(int)anInt; +- (NSString *)longDescriptionAtIndex:(int)anInt; +- (NSString *)unsignedLongDescriptionAtIndex:(int)anInt; +- (NSString *)longLongDescriptionAtIndex:(int)anInt; +- (NSString *)unsignedLongLongDescriptionAtIndex:(int)anInt; +- (NSString *)doubleDescriptionAtIndex:(int)anInt; +- (NSString *)floatDescriptionAtIndex:(int)anInt; +- (NSString *)structDescriptionAtIndex:(int)anInt; +- (NSString *)pointerDescriptionAtIndex:(int)anInt; +- (NSString *)cStringDescriptionAtIndex:(int)anInt; +- (NSString *)selectorDescriptionAtIndex:(int)anInt; + +@end diff --git a/Pods/Kiwi/Classes/NSInvocation+OCMAdditions.m b/Pods/Kiwi/Classes/NSInvocation+OCMAdditions.m new file mode 100644 index 0000000..6348396 --- /dev/null +++ b/Pods/Kiwi/Classes/NSInvocation+OCMAdditions.m @@ -0,0 +1,337 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2006-2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "NSInvocation+OCMAdditions.h" + + +@implementation NSInvocation(OCMAdditions) + +- (id)getArgumentAtIndexAsObject:(int)argIndex +{ + const char* argType; + + argType = [[self methodSignature] getArgumentTypeAtIndex:argIndex]; + while(strchr("rnNoORV", argType[0]) != NULL) + argType += 1; + + if((strlen(argType) > 1) && (strchr("{^", argType[0]) == NULL) && (strcmp("@?", argType) != 0)) + [NSException raise:NSInvalidArgumentException format:@"Cannot handle argument type '%s'.", argType]; + + switch (argType[0]) + { + case '#': + case '@': + { + id value; + [self getArgument:&value atIndex:argIndex]; + return value; + } + case ':': + { + SEL s = (SEL)0; + [self getArgument:&s atIndex:argIndex]; + id value = NSStringFromSelector(s); + return value; + } + case 'i': + { + int value; + [self getArgument:&value atIndex:argIndex]; + return @(value); + } + case 's': + { + short value; + [self getArgument:&value atIndex:argIndex]; + return @(value); + } + case 'l': + { + long value; + [self getArgument:&value atIndex:argIndex]; + return @(value); + } + case 'q': + { + long long value; + [self getArgument:&value atIndex:argIndex]; + return @(value); + } + case 'c': + { + char value; + [self getArgument:&value atIndex:argIndex]; + return @(value); + } + case 'C': + { + unsigned char value; + [self getArgument:&value atIndex:argIndex]; + return @(value); + } + case 'I': + { + unsigned int value; + [self getArgument:&value atIndex:argIndex]; + return @(value); + } + case 'S': + { + unsigned short value; + [self getArgument:&value atIndex:argIndex]; + return @(value); + } + case 'L': + { + unsigned long value; + [self getArgument:&value atIndex:argIndex]; + return @(value); + } + case 'Q': + { + unsigned long long value; + [self getArgument:&value atIndex:argIndex]; + return @(value); + } + case 'f': + { + float value; + [self getArgument:&value atIndex:argIndex]; + return @(value); + } + case 'd': + { + double value; + [self getArgument:&value atIndex:argIndex]; + return @(value); + } + case 'B': + { + bool value; + [self getArgument:&value atIndex:argIndex]; + return @(value); + } + case '^': + { + void *value = NULL; + [self getArgument:&value atIndex:argIndex]; + return [NSValue valueWithPointer:value]; + } + case '{': // structure + { + NSUInteger maxArgSize = [[self methodSignature] frameLength]; + NSMutableData *argumentData = [[[NSMutableData alloc] initWithLength:maxArgSize] autorelease]; + [self getArgument:[argumentData mutableBytes] atIndex:argIndex]; + return [NSValue valueWithBytes:[argumentData bytes] objCType:argType]; + } + + } + [NSException raise:NSInvalidArgumentException format:@"Argument type '%s' not supported", argType]; + return nil; +} + +- (NSString *)invocationDescription +{ + NSMethodSignature *methodSignature = [self methodSignature]; + NSUInteger numberOfArgs = [methodSignature numberOfArguments]; + + if (numberOfArgs == 2) + return NSStringFromSelector([self selector]); + + NSArray *selectorParts = [NSStringFromSelector([self selector]) componentsSeparatedByString:@":"]; + NSMutableString *description = [[NSMutableString alloc] init]; + unsigned int i; + for(i = 2; i < numberOfArgs; i++) + { + [description appendFormat:@"%@%@:", (i > 2 ? @" " : @""), selectorParts[(i - 2)]]; + [description appendString:[self argumentDescriptionAtIndex:i]]; + } + + return [description autorelease]; +} + +- (NSString *)argumentDescriptionAtIndex:(int)argIndex +{ + const char *argType = [[self methodSignature] getArgumentTypeAtIndex:argIndex]; + if(strchr("rnNoORV", argType[0]) != NULL) + argType += 1; + + switch(*argType) + { + case '@': return [self objectDescriptionAtIndex:argIndex]; + case 'c': return [self charDescriptionAtIndex:argIndex]; + case 'C': return [self unsignedCharDescriptionAtIndex:argIndex]; + case 'i': return [self intDescriptionAtIndex:argIndex]; + case 'I': return [self unsignedIntDescriptionAtIndex:argIndex]; + case 's': return [self shortDescriptionAtIndex:argIndex]; + case 'S': return [self unsignedShortDescriptionAtIndex:argIndex]; + case 'l': return [self longDescriptionAtIndex:argIndex]; + case 'L': return [self unsignedLongDescriptionAtIndex:argIndex]; + case 'q': return [self longLongDescriptionAtIndex:argIndex]; + case 'Q': return [self unsignedLongLongDescriptionAtIndex:argIndex]; + case 'd': return [self doubleDescriptionAtIndex:argIndex]; + case 'f': return [self floatDescriptionAtIndex:argIndex]; + // Why does this throw EXC_BAD_ACCESS when appending the string? + // case NSObjCStructType: return [self structDescriptionAtIndex:index]; + case '^': return [self pointerDescriptionAtIndex:argIndex]; + case '*': return [self cStringDescriptionAtIndex:argIndex]; + case ':': return [self selectorDescriptionAtIndex:argIndex]; + default: return [@""]; // avoid confusion with trigraphs... + } + +} + + +- (NSString *)objectDescriptionAtIndex:(int)anInt +{ + id object; + + [self getArgument:&object atIndex:anInt]; + if (object == nil) + return @"nil"; + else if(![object isProxy] && [object isKindOfClass:[NSString class]]) + return [NSString stringWithFormat:@"@\"%@\"", [object description]]; + else + return [object description]; +} + +- (NSString *)charDescriptionAtIndex:(int)anInt +{ + unsigned char buffer[128]; + memset(buffer, 0x0, 128); + + [self getArgument:&buffer atIndex:anInt]; + + // If there's only one character in the buffer, and it's 0 or 1, then we have a BOOL + if (buffer[1] == '\0' && (buffer[0] == 0 || buffer[0] == 1)) + return [NSString stringWithFormat:@"%@", (buffer[0] == 1 ? @"YES" : @"NO")]; + else + return [NSString stringWithFormat:@"'%c'", *buffer]; +} + +- (NSString *)unsignedCharDescriptionAtIndex:(int)anInt +{ + unsigned char buffer[128]; + memset(buffer, 0x0, 128); + + [self getArgument:&buffer atIndex:anInt]; + return [NSString stringWithFormat:@"'%c'", *buffer]; +} + +- (NSString *)intDescriptionAtIndex:(int)anInt +{ + int intValue; + + [self getArgument:&intValue atIndex:anInt]; + return [NSString stringWithFormat:@"%d", intValue]; +} + +- (NSString *)unsignedIntDescriptionAtIndex:(int)anInt +{ + unsigned int intValue; + + [self getArgument:&intValue atIndex:anInt]; + return [NSString stringWithFormat:@"%d", intValue]; +} + +- (NSString *)shortDescriptionAtIndex:(int)anInt +{ + short shortValue; + + [self getArgument:&shortValue atIndex:anInt]; + return [NSString stringWithFormat:@"%hi", shortValue]; +} + +- (NSString *)unsignedShortDescriptionAtIndex:(int)anInt +{ + unsigned short shortValue; + + [self getArgument:&shortValue atIndex:anInt]; + return [NSString stringWithFormat:@"%hu", shortValue]; +} + +- (NSString *)longDescriptionAtIndex:(int)anInt +{ + long longValue; + + [self getArgument:&longValue atIndex:anInt]; + return [NSString stringWithFormat:@"%ld", longValue]; +} + +- (NSString *)unsignedLongDescriptionAtIndex:(int)anInt +{ + unsigned long longValue; + + [self getArgument:&longValue atIndex:anInt]; + return [NSString stringWithFormat:@"%lu", longValue]; +} + +- (NSString *)longLongDescriptionAtIndex:(int)anInt +{ + long long longLongValue; + + [self getArgument:&longLongValue atIndex:anInt]; + return [NSString stringWithFormat:@"%qi", longLongValue]; +} + +- (NSString *)unsignedLongLongDescriptionAtIndex:(int)anInt +{ + unsigned long long longLongValue; + + [self getArgument:&longLongValue atIndex:anInt]; + return [NSString stringWithFormat:@"%qu", longLongValue]; +} + +- (NSString *)doubleDescriptionAtIndex:(int)anInt; +{ + double doubleValue; + + [self getArgument:&doubleValue atIndex:anInt]; + return [NSString stringWithFormat:@"%f", doubleValue]; +} + +- (NSString *)floatDescriptionAtIndex:(int)anInt +{ + float floatValue; + + [self getArgument:&floatValue atIndex:anInt]; + return [NSString stringWithFormat:@"%f", floatValue]; +} + +- (NSString *)structDescriptionAtIndex:(int)anInt; +{ + void *buffer; + + [self getArgument:&buffer atIndex:anInt]; + return [NSString stringWithFormat:@":(struct)%p", buffer]; +} + +- (NSString *)pointerDescriptionAtIndex:(int)anInt +{ + void *buffer; + + [self getArgument:&buffer atIndex:anInt]; + return [NSString stringWithFormat:@"%p", buffer]; +} + +- (NSString *)cStringDescriptionAtIndex:(int)anInt +{ + char buffer[128]; + + memset(buffer, 0x0, 128); + + [self getArgument:&buffer atIndex:anInt]; + return [NSString stringWithFormat:@"\"%s\"", buffer]; +} + +- (NSString *)selectorDescriptionAtIndex:(int)anInt +{ + SEL selectorValue; + + [self getArgument:&selectorValue atIndex:anInt]; + return [NSString stringWithFormat:@"@selector(%@)", NSStringFromSelector(selectorValue)]; +} + +@end diff --git a/Pods/Kiwi/Classes/NSMethodSignature+KiwiAdditions.h b/Pods/Kiwi/Classes/NSMethodSignature+KiwiAdditions.h new file mode 100644 index 0000000..e854a41 --- /dev/null +++ b/Pods/Kiwi/Classes/NSMethodSignature+KiwiAdditions.h @@ -0,0 +1,17 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@interface NSMethodSignature(KiwiAdditions) + +#pragma mark - +#pragma mark Getting Information on Message Arguments + +- (NSUInteger)numberOfMessageArguments; +- (const char *)messageArgumentTypeAtIndex:(NSUInteger)anIndex; + +@end diff --git a/Pods/Kiwi/Classes/NSMethodSignature+KiwiAdditions.m b/Pods/Kiwi/Classes/NSMethodSignature+KiwiAdditions.m new file mode 100644 index 0000000..68b99a5 --- /dev/null +++ b/Pods/Kiwi/Classes/NSMethodSignature+KiwiAdditions.m @@ -0,0 +1,22 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "NSMethodSignature+KiwiAdditions.h" + +@implementation NSMethodSignature(KiwiAdditions) + +#pragma mark - +#pragma mark Getting Information on Message Arguments + +- (NSUInteger)numberOfMessageArguments { + return [self numberOfArguments] - 2; +} + +- (const char *)messageArgumentTypeAtIndex:(NSUInteger)anIndex { + return [self getArgumentTypeAtIndex:anIndex + 2]; +} + +@end diff --git a/Pods/Kiwi/Classes/NSNumber+KiwiAdditions.h b/Pods/Kiwi/Classes/NSNumber+KiwiAdditions.h new file mode 100644 index 0000000..43ad4db --- /dev/null +++ b/Pods/Kiwi/Classes/NSNumber+KiwiAdditions.h @@ -0,0 +1,31 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@interface NSNumber(KiwiAdditions) + +#pragma mark - +#pragma mark Creating Numbers + ++ (id)numberWithBytes:(const void *)bytes objCType:(const char *)anObjCType; ++ (id)numberWithBoolBytes:(const void *)bytes; ++ (id)numberWithCharBytes:(const void *)bytes; ++ (id)numberWithDoubleBytes:(const void *)bytes; ++ (id)numberWithFloatBytes:(const void *)bytes; ++ (id)numberWithIntBytes:(const void *)bytes; ++ (id)numberWithIntegerBytes:(const void *)bytes; ++ (id)numberWithLongBytes:(const void *)bytes; ++ (id)numberWithLongLongBytes:(const void *)bytes; ++ (id)numberWithShortBytes:(const void *)bytes; ++ (id)numberWithUnsignedCharBytes:(const void *)bytes; ++ (id)numberWithUnsignedIntBytes:(const void *)bytes; ++ (id)numberWithUnsignedIntegerBytes:(const void *)bytes; ++ (id)numberWithUnsignedLongBytes:(const void *)bytes; ++ (id)numberWithUnsignedLongLongBytes:(const void *)bytes; ++ (id)numberWithUnsignedShortBytes:(const void *)bytes; + +@end diff --git a/Pods/Kiwi/Classes/NSNumber+KiwiAdditions.m b/Pods/Kiwi/Classes/NSNumber+KiwiAdditions.m new file mode 100644 index 0000000..4a04372 --- /dev/null +++ b/Pods/Kiwi/Classes/NSNumber+KiwiAdditions.m @@ -0,0 +1,111 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "NSNumber+KiwiAdditions.h" +#import "KWObjCUtilities.h" + +@implementation NSNumber(KiwiAdditions) + +#pragma mark - +#pragma mark Creating Numbers + ++ (id)numberWithBytes:(const void *)bytes objCType:(const char *)anObjCType { + // Yeah, this is ugly. + if (KWObjCTypeEqualToObjCType(anObjCType, @encode(BOOL))) + return [self numberWithBoolBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(char))) + return [self numberWithCharBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(double))) + return [self numberWithDoubleBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(float))) + return [self numberWithFloatBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(int))) + return [self numberWithIntBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(NSInteger))) + return [self numberWithIntegerBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(long))) + return [self numberWithLongBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(long long))) + return [self numberWithLongLongBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(short))) + return [self numberWithShortBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(unsigned char))) + return [self numberWithUnsignedCharBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(unsigned int))) + return [self numberWithUnsignedIntBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(NSUInteger))) + return [self numberWithUnsignedIntegerBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(unsigned long))) + return [self numberWithUnsignedLongBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(unsigned long long))) + return [self numberWithUnsignedLongLongBytes:bytes]; + else if (KWObjCTypeEqualToObjCType(anObjCType, @encode(unsigned short))) + return [self numberWithUnsignedShortBytes:bytes]; + else + return nil; +} + ++ (id)numberWithBoolBytes:(const void *)bytes { + return @(*(const BOOL *)bytes); +} + ++ (id)numberWithCharBytes:(const void *)bytes { + return @(*(const char *)bytes); +} + ++ (id)numberWithDoubleBytes:(const void *)bytes { + return @(*(const double *)bytes); +} + ++ (id)numberWithFloatBytes:(const void *)bytes { + return @(*(const float *)bytes); +} + ++ (id)numberWithIntBytes:(const void *)bytes { + return @(*(const int *)bytes); +} + ++ (id)numberWithIntegerBytes:(const void *)bytes { + return @(*(const NSInteger *)bytes); +} + ++ (id)numberWithLongBytes:(const void *)bytes { + return @(*(const long *)bytes); +} + ++ (id)numberWithLongLongBytes:(const void *)bytes { + return @(*(const long long *)bytes); +} + ++ (id)numberWithShortBytes:(const void *)bytes { + return @(*(const short *)bytes); +} + ++ (id)numberWithUnsignedCharBytes:(const void *)bytes { + return @(*(const unsigned char *)bytes); +} + ++ (id)numberWithUnsignedIntBytes:(const void *)bytes { + return @(*(const unsigned int *)bytes); +} + ++ (id)numberWithUnsignedIntegerBytes:(const void *)bytes { + return @(*(const NSUInteger *)bytes); +} + ++ (id)numberWithUnsignedLongBytes:(const void *)bytes { + return @(*(const unsigned long *)bytes); +} + ++ (id)numberWithUnsignedLongLongBytes:(const void *)bytes { + return @(*(const unsigned long long *)bytes); +} + ++ (id)numberWithUnsignedShortBytes:(const void *)bytes { + return @(*(const unsigned short *)bytes); +} + +@end diff --git a/Pods/Kiwi/Classes/NSObject+KiwiMockAdditions.h b/Pods/Kiwi/Classes/NSObject+KiwiMockAdditions.h new file mode 100644 index 0000000..cbe6c5c --- /dev/null +++ b/Pods/Kiwi/Classes/NSObject+KiwiMockAdditions.h @@ -0,0 +1,20 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@interface NSObject(KiwiMockAdditions) + +#pragma mark - +#pragma mark Creating Mocks + ++ (id)mock; ++ (id)mockWithName:(NSString *)aName; + ++ (id)nullMock; ++ (id)nullMockWithName:(NSString *)aName; + +@end diff --git a/Pods/Kiwi/Classes/NSObject+KiwiMockAdditions.m b/Pods/Kiwi/Classes/NSObject+KiwiMockAdditions.m new file mode 100644 index 0000000..a9e8637 --- /dev/null +++ b/Pods/Kiwi/Classes/NSObject+KiwiMockAdditions.m @@ -0,0 +1,31 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "NSObject+KiwiMockAdditions.h" +#import "KWMock.h" + +@implementation NSObject(KiwiMockAdditions) + +#pragma mark - +#pragma mark Creating Mocks + ++ (id)mock { + return [KWMock mockForClass:[self class]]; +} + ++ (id)mockWithName:(NSString *)aName { + return [KWMock mockWithName:aName forClass:[self class]]; +} + ++ (id)nullMock { + return [KWMock nullMockForClass:[self class]]; +} + ++ (id)nullMockWithName:(NSString *)aName { + return [KWMock nullMockWithName:aName forClass:[self class]]; +} + +@end diff --git a/Pods/Kiwi/Classes/NSObject+KiwiSpyAdditions.h b/Pods/Kiwi/Classes/NSObject+KiwiSpyAdditions.h new file mode 100644 index 0000000..ac0427b --- /dev/null +++ b/Pods/Kiwi/Classes/NSObject+KiwiSpyAdditions.h @@ -0,0 +1,14 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@class KWCaptureSpy; + +@interface NSObject (KiwiSpyAdditions) +- (KWCaptureSpy *)captureArgument:(SEL)selector atIndex:(NSUInteger)index; ++ (KWCaptureSpy *)captureArgument:(SEL)selector atIndex:(NSUInteger)index; +@end diff --git a/Pods/Kiwi/Classes/NSObject+KiwiSpyAdditions.m b/Pods/Kiwi/Classes/NSObject+KiwiSpyAdditions.m new file mode 100644 index 0000000..8730bde --- /dev/null +++ b/Pods/Kiwi/Classes/NSObject+KiwiSpyAdditions.m @@ -0,0 +1,29 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "NSObject+KiwiSpyAdditions.h" + +#import "KWCaptureSpy.h" +#import "KWMessagePattern.h" +#import "NSObject+KiwiStubAdditions.h" + +@implementation NSObject (KiwiSpyAdditions) + +- (KWCaptureSpy *)captureArgument:(SEL)selector atIndex:(NSUInteger)index { + KWCaptureSpy *spy = [[[KWCaptureSpy alloc] initWithArgumentIndex:index] autorelease]; + KWMessagePattern *pattern = [[[KWMessagePattern alloc] initWithSelector:selector] autorelease]; + [self addMessageSpy:spy forMessagePattern:pattern]; + return spy; +} + ++ (KWCaptureSpy *)captureArgument:(SEL)selector atIndex:(NSUInteger)index { + KWCaptureSpy *spy = [[[KWCaptureSpy alloc] initWithArgumentIndex:index] autorelease]; + KWMessagePattern *pattern = [[[KWMessagePattern alloc] initWithSelector:selector] autorelease]; + [self addMessageSpy:spy forMessagePattern:pattern]; + return spy; +} + +@end diff --git a/Pods/Kiwi/Classes/NSObject+KiwiStubAdditions.h b/Pods/Kiwi/Classes/NSObject+KiwiStubAdditions.h new file mode 100644 index 0000000..ffa2c6e --- /dev/null +++ b/Pods/Kiwi/Classes/NSObject+KiwiStubAdditions.h @@ -0,0 +1,54 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@class KWMessagePattern; + +@protocol KWMessageSpying; + +@interface NSObject(KiwiStubAdditions) + +#pragma mark - +#pragma mark Stubbing Methods + +- (void)stub:(SEL)aSelector; +- (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *params))block; +- (void)stub:(SEL)aSelector withArguments:(id)firstArgument, ...; +- (void)stub:(SEL)aSelector andReturn:(id)aValue; +- (void)stub:(SEL)aSelector andReturn:(id)aValue withArguments:(id)firstArgument, ...; + ++ (void)stub:(SEL)aSelector; ++ (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *params))block; ++ (void)stub:(SEL)aSelector withArguments:(id)firstArgument, ...; ++ (void)stub:(SEL)aSelector andReturn:(id)aValue; ++ (void)stub:(SEL)aSelector andReturn:(id)aValue withArguments:(id)firstArgument, ...; + +- (id)stub; +- (id)stubAndReturn:(id)aValue; +- (id)stubAndReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue; + +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue; +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue overrideExisting:(BOOL)overrideExisting; +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue; +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern withBlock:(id (^)(NSArray *params))block; + ++ (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue; ++ (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue; ++ (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern withBlock:(id (^)(NSArray *params))block; + +- (void)clearStubs; + +#pragma mark - +#pragma mark Spying on Messages + +- (void)addMessageSpy:(id)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern; +- (void)removeMessageSpy:(id)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern; + ++ (void)addMessageSpy:(id)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern; ++ (void)removeMessageSpy:(id)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern; + +@end diff --git a/Pods/Kiwi/Classes/NSObject+KiwiStubAdditions.m b/Pods/Kiwi/Classes/NSObject+KiwiStubAdditions.m new file mode 100644 index 0000000..b125245 --- /dev/null +++ b/Pods/Kiwi/Classes/NSObject+KiwiStubAdditions.m @@ -0,0 +1,248 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "NSObject+KiwiStubAdditions.h" +#import "KWIntercept.h" +#import "KWInvocationCapturer.h" +#import "KWMessagePattern.h" +#import "KWObjCUtilities.h" +#import "KWStringUtilities.h" +#import "KWStub.h" + +static NSString * const StubValueKey = @"StubValueKey"; +static NSString * const StubSecondValueKey = @"StubSecondValueKey"; +static NSString * const ChangeStubValueAfterTimesKey = @"ChangeStubValueAfterTimesKey"; + +@implementation NSObject(KiwiStubAdditions) + +#pragma mark - +#pragma mark Capturing Invocations + +- (NSMethodSignature *)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer methodSignatureForSelector:(SEL)aSelector { + NSMethodSignature *signature = [self methodSignatureForSelector:aSelector]; + + if (signature != nil) + return signature; + + NSString *encoding = KWEncodingForVoidMethod(); + return [NSMethodSignature signatureWithObjCTypes:[encoding UTF8String]]; +} + +- (void)invocationCapturer:(KWInvocationCapturer *)anInvocationCapturer didCaptureInvocation:(NSInvocation *)anInvocation { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternFromInvocation:anInvocation]; + id value = (anInvocationCapturer.userInfo)[StubValueKey]; + if (!(anInvocationCapturer.userInfo)[StubSecondValueKey]) { + [self stubMessagePattern:messagePattern andReturn:value]; + } else { + id times = (anInvocationCapturer.userInfo)[ChangeStubValueAfterTimesKey]; + id secondValue = (anInvocationCapturer.userInfo)[StubSecondValueKey]; + [self stubMessagePattern:messagePattern andReturn:value times:times afterThatReturn:secondValue]; + } +} + +#pragma mark - +#pragma mark Stubbing Methods + +- (void)stub:(SEL)aSelector { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self stubMessagePattern:messagePattern andReturn:nil]; +} + +- (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *))block { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self stubMessagePattern:messagePattern withBlock:block]; +} + +- (void)stub:(SEL)aSelector withArguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [self stubMessagePattern:messagePattern andReturn:nil]; +} + +- (void)stub:(SEL)aSelector andReturn:(id)aValue { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self stubMessagePattern:messagePattern andReturn:aValue]; +} + +- (void)stub:(SEL)aSelector andReturn:(id)aValue withArguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [self stubMessagePattern:messagePattern andReturn:aValue]; +} + ++ (void)stub:(SEL)aSelector { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self stubMessagePattern:messagePattern andReturn:nil]; +} + ++ (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *))block { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self stubMessagePattern:messagePattern withBlock:block]; +} + ++ (void)stub:(SEL)aSelector withArguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [self stubMessagePattern:messagePattern andReturn:nil]; +} + ++ (void)stub:(SEL)aSelector andReturn:(id)aValue { + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector]; + [self stubMessagePattern:messagePattern andReturn:aValue]; +} + ++ (void)stub:(SEL)aSelector andReturn:(id)aValue withArguments:(id)firstArgument, ... { + va_list argumentList; + va_start(argumentList, firstArgument); + KWMessagePattern *messagePattern = [KWMessagePattern messagePatternWithSelector:aSelector firstArgumentFilter:firstArgument argumentList:argumentList]; + [self stubMessagePattern:messagePattern andReturn:aValue]; +} + +- (id)stub { + return [KWInvocationCapturer invocationCapturerWithDelegate:self]; +} + +- (id)stubAndReturn:(id)aValue { + NSDictionary *userInfo = @{StubValueKey: aValue}; + return [KWInvocationCapturer invocationCapturerWithDelegate:self userInfo:userInfo]; +} + +- (id)stubAndReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue { + NSDictionary *userInfo = @{StubValueKey: aValue, ChangeStubValueAfterTimesKey: times, StubSecondValueKey: aSecondValue}; + return [KWInvocationCapturer invocationCapturerWithDelegate:self userInfo:userInfo]; +} + +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue { + [self stubMessagePattern:aMessagePattern andReturn:aValue overrideExisting:YES]; +} + +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue overrideExisting:(BOOL)overrideExisting { + if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) { + [NSException raise:@"KWStubException" format:@"cannot stub -%@ because no such method exists", + NSStringFromSelector(aMessagePattern.selector)]; + } + + Class interceptClass = KWSetupObjectInterceptSupport(self); + KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector); + KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern value:aValue]; + KWAssociateObjectStub(self, stub, overrideExisting); +} + +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue { + if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) { + [NSException raise:@"KWStubException" format:@"cannot stub -%@ because no such method exists", + NSStringFromSelector(aMessagePattern.selector)]; + } + + Class interceptClass = KWSetupObjectInterceptSupport(self); + KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector); + KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern value:aValue times:times afterThatReturn:aSecondValue]; + KWAssociateObjectStub(self, stub, YES); +} + +- (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern withBlock:(id (^)(NSArray *params))block { + if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) { + [NSException raise:@"KWStubException" format:@"cannot stub -%@ because no such method exists", + NSStringFromSelector(aMessagePattern.selector)]; + } + + Class interceptClass = KWSetupObjectInterceptSupport(self); + KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector); + KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern block:block]; + KWAssociateObjectStub(self, stub, YES); +} + ++ (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue +{ + [self stubMessagePattern:aMessagePattern andReturn:aValue overrideExisting:YES]; +} + ++ (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue overrideExisting:(BOOL)override +{ + if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) { + [NSException raise:@"KWStubException" format:@"cannot stub -%@ because no such method exists", + NSStringFromSelector(aMessagePattern.selector)]; + } + + Class interceptClass = KWSetupObjectInterceptSupport(self); + KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector); + KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern value:aValue]; + KWAssociateObjectStub(self, stub, override); +} + ++ (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue { + [self stubMessagePattern:aMessagePattern andReturn:aValue times:times afterThatReturn:aSecondValue overrideExisting:YES]; +} + ++ (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern andReturn:(id)aValue times:(id)times afterThatReturn:(id)aSecondValue overrideExisting:(BOOL)override { + if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) { + [NSException raise:@"KWStubException" format:@"cannot stub -%@ because no such method exists", + NSStringFromSelector(aMessagePattern.selector)]; + } + + Class interceptClass = KWSetupObjectInterceptSupport(self); + KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector); + KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern value:aValue times:times afterThatReturn:aSecondValue]; + KWAssociateObjectStub(self, stub, override); +} + ++ (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern withBlock:(id (^)(NSArray *params))block { + [self stubMessagePattern:aMessagePattern withBlock:block overrideExisting:YES]; +} + ++ (void)stubMessagePattern:(KWMessagePattern *)aMessagePattern withBlock:(id (^)(NSArray *params))block overrideExisting:(BOOL)override { + if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) { + [NSException raise:@"KWStubException" format:@"cannot stub -%@ because no such method exists", + NSStringFromSelector(aMessagePattern.selector)]; + } + + Class interceptClass = KWSetupObjectInterceptSupport(self); + KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector); + KWStub *stub = [KWStub stubWithMessagePattern:aMessagePattern block:block]; + KWAssociateObjectStub(self, stub, override); +} + +- (void)clearStubs { + KWClearObjectStubs(self); +} + +#pragma mark - +#pragma mark Spying on Messages + +- (void)addMessageSpy:(id)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern { + if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) { + [NSException raise:@"KWSpyException" format:@"cannot add spy for -%@ because no such method exists", + NSStringFromSelector(aMessagePattern.selector)]; + } + + Class interceptClass = KWSetupObjectInterceptSupport(self); + KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector); + KWAssociateMessageSpy(self, aSpy, aMessagePattern); +} + +- (void)removeMessageSpy:(id)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern { + KWClearObjectSpy(self, aSpy, aMessagePattern); +} + ++ (void)addMessageSpy:(id)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern { + if ([self methodSignatureForSelector:aMessagePattern.selector] == nil) { + [NSException raise:@"KWSpyException" format:@"cannot add spy for -%@ because no such method exists", + NSStringFromSelector(aMessagePattern.selector)]; + } + + Class interceptClass = KWSetupObjectInterceptSupport(self); + KWSetupMethodInterceptSupport(interceptClass, aMessagePattern.selector); + KWAssociateMessageSpy(self, aSpy, aMessagePattern); +} + ++ (void)removeMessageSpy:(id)aSpy forMessagePattern:(KWMessagePattern *)aMessagePattern { + KWClearObjectSpy(self, aSpy, aMessagePattern); +} + +@end diff --git a/Pods/Kiwi/Classes/NSObject+KiwiVerifierAdditions.h b/Pods/Kiwi/Classes/NSObject+KiwiVerifierAdditions.h new file mode 100644 index 0000000..23d1f29 --- /dev/null +++ b/Pods/Kiwi/Classes/NSObject+KiwiVerifierAdditions.h @@ -0,0 +1,19 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@protocol KWVerifying; + +@interface NSObject(KiwiVerifierAdditions) + +#pragma mark - +#pragma mark Attaching to Verifiers + +- (id)attachToVerifier:(id)aVerifier; +- (id)attachToVerifier:(id)firstVerifier verifier:(id)secondVerifier; + +@end diff --git a/Pods/Kiwi/Classes/NSObject+KiwiVerifierAdditions.m b/Pods/Kiwi/Classes/NSObject+KiwiVerifierAdditions.m new file mode 100644 index 0000000..f839e42 --- /dev/null +++ b/Pods/Kiwi/Classes/NSObject+KiwiVerifierAdditions.m @@ -0,0 +1,26 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "NSObject+KiwiVerifierAdditions.h" +#import "KWVerifying.h" + +@implementation NSObject(KiwiVerifierAdditions) + +#pragma mark - +#pragma mark Attaching to Verifiers + +- (id)attachToVerifier:(id)aVerifier { + [aVerifier setSubject:self]; + return aVerifier; +} + +- (id)attachToVerifier:(id)firstVerifier verifier:(id)secondVerifier { + [firstVerifier setSubject:self]; + [secondVerifier setSubject:self]; + return firstVerifier; +} + +@end diff --git a/Pods/Kiwi/Classes/NSProxy+KiwiVerifierAdditions.h b/Pods/Kiwi/Classes/NSProxy+KiwiVerifierAdditions.h new file mode 100644 index 0000000..a2f8d85 --- /dev/null +++ b/Pods/Kiwi/Classes/NSProxy+KiwiVerifierAdditions.h @@ -0,0 +1,21 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2013 Allen Ding. All rights reserved. +// +// Contributed by https://github.com/dwlnetnl +// + +#import "KiwiConfiguration.h" + +@protocol KWVerifying; + +@interface NSProxy (KiwiVerifierAdditions) + +#pragma mark - +#pragma mark Attaching to Verifiers + +- (id)attachToVerifier:(id)aVerifier; +- (id)attachToVerifier:(id)firstVerifier verifier:(id)secondVerifier; + +@end diff --git a/Pods/Kiwi/Classes/NSProxy+KiwiVerifierAdditions.m b/Pods/Kiwi/Classes/NSProxy+KiwiVerifierAdditions.m new file mode 100644 index 0000000..ab19628 --- /dev/null +++ b/Pods/Kiwi/Classes/NSProxy+KiwiVerifierAdditions.m @@ -0,0 +1,28 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2013 Allen Ding. All rights reserved. +// +// Contributed by https://github.com/dwlnetnl +// + +#import "NSProxy+KiwiVerifierAdditions.h" +#import "KWVerifying.h" + +@implementation NSProxy (KiwiVerifierAdditions) + +#pragma mark - +#pragma mark Attaching to Verifiers + +- (id)attachToVerifier:(id)aVerifier { + [aVerifier setSubject:self]; + return aVerifier; +} + +- (id)attachToVerifier:(id)firstVerifier verifier:(id)secondVerifier { + [firstVerifier setSubject:self]; + [secondVerifier setSubject:self]; + return firstVerifier; +} + +@end diff --git a/Pods/Kiwi/Classes/NSValue+KiwiAdditions.h b/Pods/Kiwi/Classes/NSValue+KiwiAdditions.h new file mode 100644 index 0000000..c231ba9 --- /dev/null +++ b/Pods/Kiwi/Classes/NSValue+KiwiAdditions.h @@ -0,0 +1,16 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "KiwiConfiguration.h" + +@interface NSValue(KiwiAdditions) + +#pragma mark - +#pragma mark Accessing Data + +- (NSData *)dataValue; + +@end diff --git a/Pods/Kiwi/Classes/NSValue+KiwiAdditions.m b/Pods/Kiwi/Classes/NSValue+KiwiAdditions.m new file mode 100644 index 0000000..99454ae --- /dev/null +++ b/Pods/Kiwi/Classes/NSValue+KiwiAdditions.m @@ -0,0 +1,24 @@ +// +// Licensed under the terms in License.txt +// +// Copyright 2010 Allen Ding. All rights reserved. +// + +#import "NSValue+KiwiAdditions.h" +#import "KWObjCUtilities.h" + +@implementation NSValue(KiwiAdditions) + +#pragma mark - +#pragma mark Accessing Data + +- (NSData *)dataValue { + NSUInteger length = KWObjCTypeLength([self objCType]); + void *buffer = malloc(length); + [self getValue:buffer]; + NSData *data = [NSData dataWithBytes:buffer length:length]; + free(buffer); + return data; +} + +@end diff --git a/Pods/Kiwi/License.txt b/Pods/Kiwi/License.txt new file mode 100644 index 0000000..5591081 --- /dev/null +++ b/Pods/Kiwi/License.txt @@ -0,0 +1,27 @@ +Copyright (c) 2010, Allen Ding +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of Allen Ding nor the names of any contributors may be +used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Pods/Kiwi/Readme.md b/Pods/Kiwi/Readme.md new file mode 100644 index 0000000..64dabbb --- /dev/null +++ b/Pods/Kiwi/Readme.md @@ -0,0 +1,51 @@ +# Simple BDD for iOS # +Kiwi is a Behavior Driven Development library for iOS development. +The goal is to provide a BDD library that is exquisitely simple to setup and use. + +# Kiwi 2.0 - Reboot +https://github.com/allending/Kiwi/issues/176 + +# Requirements # + +* Xcode 4.x +* LLVM compiler recommended + +# Contributors # + +Kiwi is open-source and is developed by the community. The full list of Kiwi individual contributors is [here](https://github.com/allending/Kiwi/graphs/contributors). + +# Why? # +The idea behind Kiwi is to have tests that are more readable than what is possible with the bundled test framework. + +Tests (or rather specs) are written in Objective-C and run within the comfort of Xcode to provide a test environment that is as unobtrusive and seamless as possible in terms of running tests and error reporting. + +Specs look like this: + +```objective-c +describe(@"Team", ^{ + context(@"when newly created", ^{ + it(@"should have a name", ^{ + id team = [Team team]; + [[team.name should] equal:@"Black Hawks"]; + }); + + it(@"should have 11 players", ^{ + id team = [Team team]; + [[[team should] have:11] players]; + }); + }); +}); +``` + +To some of you, this might seem like an abomination. To the rest, read on... + +# License # +Kiwi is open source software. You may freely distribute it under the terms of +the license agreement found in __License.txt__. + +# Documentation # +The [Kiwi Wiki](https://github.com/allending/Kiwi/wiki) is the official documentation source. + +# Getting it # +The best way to get Kiwi is by using [CocoaPods](https://github.com/cocoapods/cocoapods). For all the installation details, check out the [Wiki](https://github.com/allending/kiwi/wiki) + diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock new file mode 100644 index 0000000..6747871 --- /dev/null +++ b/Pods/Manifest.lock @@ -0,0 +1,19 @@ +PODS: + - CocoaLumberjack (1.6.2) + - Kiwi (2.0.6) + - OCMock (2.1.1) + - VLBFoundation (1.0) + +DEPENDENCIES: + - CocoaLumberjack (= 1.6.2) + - Kiwi (~> 2.0.6) + - OCMock (~> 2.1.1) + - VLBFoundation + +SPEC CHECKSUMS: + CocoaLumberjack: 0a08f3092acaab5f92c139e1186aa255a1e39446 + Kiwi: 9fe70e93c30586b607c54ac8669c6424cc6f2737 + OCMock: 363db8429164eaa219ea96a51f06e830ef3e7393 + VLBFoundation: d5ddef89836c735841390706e136fbbd14a04387 + +COCOAPODS: 0.33.1 diff --git a/Pods/OCMock/README.md b/Pods/OCMock/README.md new file mode 100644 index 0000000..2f8d6e6 --- /dev/null +++ b/Pods/OCMock/README.md @@ -0,0 +1,10 @@ +OCMock +====== + +OCMock is an Objective-C implementation of mock objects. + +Github is used to store and manage the source code. + +For documentation and support please visit [ocmock.org][]. + + [ocmock.org]: http://ocmock.org/ diff --git a/Pods/OCMock/Source/OCMock/NSInvocation+OCMAdditions.h b/Pods/OCMock/Source/OCMock/NSInvocation+OCMAdditions.h new file mode 100644 index 0000000..04f22cd --- /dev/null +++ b/Pods/OCMock/Source/OCMock/NSInvocation+OCMAdditions.h @@ -0,0 +1,34 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2006-2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface NSInvocation(OCMAdditions) + +- (id)getArgumentAtIndexAsObject:(int)argIndex; + +- (NSString *)invocationDescription; + +- (NSString *)argumentDescriptionAtIndex:(int)argIndex; + +- (NSString *)objectDescriptionAtIndex:(int)anInt; +- (NSString *)charDescriptionAtIndex:(int)anInt; +- (NSString *)unsignedCharDescriptionAtIndex:(int)anInt; +- (NSString *)intDescriptionAtIndex:(int)anInt; +- (NSString *)unsignedIntDescriptionAtIndex:(int)anInt; +- (NSString *)shortDescriptionAtIndex:(int)anInt; +- (NSString *)unsignedShortDescriptionAtIndex:(int)anInt; +- (NSString *)longDescriptionAtIndex:(int)anInt; +- (NSString *)unsignedLongDescriptionAtIndex:(int)anInt; +- (NSString *)longLongDescriptionAtIndex:(int)anInt; +- (NSString *)unsignedLongLongDescriptionAtIndex:(int)anInt; +- (NSString *)doubleDescriptionAtIndex:(int)anInt; +- (NSString *)floatDescriptionAtIndex:(int)anInt; +- (NSString *)structDescriptionAtIndex:(int)anInt; +- (NSString *)pointerDescriptionAtIndex:(int)anInt; +- (NSString *)cStringDescriptionAtIndex:(int)anInt; +- (NSString *)selectorDescriptionAtIndex:(int)anInt; + +@end diff --git a/Pods/OCMock/Source/OCMock/NSInvocation+OCMAdditions.m b/Pods/OCMock/Source/OCMock/NSInvocation+OCMAdditions.m new file mode 100644 index 0000000..4157958 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/NSInvocation+OCMAdditions.m @@ -0,0 +1,337 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2006-2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "NSInvocation+OCMAdditions.h" + + +@implementation NSInvocation(OCMAdditions) + +- (id)getArgumentAtIndexAsObject:(int)argIndex +{ + const char* argType; + + argType = [[self methodSignature] getArgumentTypeAtIndex:argIndex]; + while(strchr("rnNoORV", argType[0]) != NULL) + argType += 1; + + if((strlen(argType) > 1) && (strchr("{^", argType[0]) == NULL) && (strcmp("@?", argType) != 0)) + [NSException raise:NSInvalidArgumentException format:@"Cannot handle argument type '%s'.", argType]; + + switch (argType[0]) + { + case '#': + case '@': + { + id value; + [self getArgument:&value atIndex:argIndex]; + return value; + } + case ':': + { + SEL s = (SEL)0; + [self getArgument:&s atIndex:argIndex]; + id value = NSStringFromSelector(s); + return value; + } + case 'i': + { + int value; + [self getArgument:&value atIndex:argIndex]; + return [NSNumber numberWithInt:value]; + } + case 's': + { + short value; + [self getArgument:&value atIndex:argIndex]; + return [NSNumber numberWithShort:value]; + } + case 'l': + { + long value; + [self getArgument:&value atIndex:argIndex]; + return [NSNumber numberWithLong:value]; + } + case 'q': + { + long long value; + [self getArgument:&value atIndex:argIndex]; + return [NSNumber numberWithLongLong:value]; + } + case 'c': + { + char value; + [self getArgument:&value atIndex:argIndex]; + return [NSNumber numberWithChar:value]; + } + case 'C': + { + unsigned char value; + [self getArgument:&value atIndex:argIndex]; + return [NSNumber numberWithUnsignedChar:value]; + } + case 'I': + { + unsigned int value; + [self getArgument:&value atIndex:argIndex]; + return [NSNumber numberWithUnsignedInt:value]; + } + case 'S': + { + unsigned short value; + [self getArgument:&value atIndex:argIndex]; + return [NSNumber numberWithUnsignedShort:value]; + } + case 'L': + { + unsigned long value; + [self getArgument:&value atIndex:argIndex]; + return [NSNumber numberWithUnsignedLong:value]; + } + case 'Q': + { + unsigned long long value; + [self getArgument:&value atIndex:argIndex]; + return [NSNumber numberWithUnsignedLongLong:value]; + } + case 'f': + { + float value; + [self getArgument:&value atIndex:argIndex]; + return [NSNumber numberWithFloat:value]; + } + case 'd': + { + double value; + [self getArgument:&value atIndex:argIndex]; + return [NSNumber numberWithDouble:value]; + } + case 'B': + { + bool value; + [self getArgument:&value atIndex:argIndex]; + return [NSNumber numberWithBool:value]; + } + case '^': + { + void *value = NULL; + [self getArgument:&value atIndex:argIndex]; + return [NSValue valueWithPointer:value]; + } + case '{': // structure + { + NSUInteger maxArgSize = [[self methodSignature] frameLength]; + NSMutableData *argumentData = [[[NSMutableData alloc] initWithLength:maxArgSize] autorelease]; + [self getArgument:[argumentData mutableBytes] atIndex:argIndex]; + return [NSValue valueWithBytes:[argumentData bytes] objCType:argType]; + } + + } + [NSException raise:NSInvalidArgumentException format:@"Argument type '%s' not supported", argType]; + return nil; +} + +- (NSString *)invocationDescription +{ + NSMethodSignature *methodSignature = [self methodSignature]; + NSUInteger numberOfArgs = [methodSignature numberOfArguments]; + + if (numberOfArgs == 2) + return NSStringFromSelector([self selector]); + + NSArray *selectorParts = [NSStringFromSelector([self selector]) componentsSeparatedByString:@":"]; + NSMutableString *description = [[NSMutableString alloc] init]; + unsigned int i; + for(i = 2; i < numberOfArgs; i++) + { + [description appendFormat:@"%@%@:", (i > 2 ? @" " : @""), [selectorParts objectAtIndex:(i - 2)]]; + [description appendString:[self argumentDescriptionAtIndex:i]]; + } + + return [description autorelease]; +} + +- (NSString *)argumentDescriptionAtIndex:(int)argIndex +{ + const char *argType = [[self methodSignature] getArgumentTypeAtIndex:argIndex]; + if(strchr("rnNoORV", argType[0]) != NULL) + argType += 1; + + switch(*argType) + { + case '@': return [self objectDescriptionAtIndex:argIndex]; + case 'c': return [self charDescriptionAtIndex:argIndex]; + case 'C': return [self unsignedCharDescriptionAtIndex:argIndex]; + case 'i': return [self intDescriptionAtIndex:argIndex]; + case 'I': return [self unsignedIntDescriptionAtIndex:argIndex]; + case 's': return [self shortDescriptionAtIndex:argIndex]; + case 'S': return [self unsignedShortDescriptionAtIndex:argIndex]; + case 'l': return [self longDescriptionAtIndex:argIndex]; + case 'L': return [self unsignedLongDescriptionAtIndex:argIndex]; + case 'q': return [self longLongDescriptionAtIndex:argIndex]; + case 'Q': return [self unsignedLongLongDescriptionAtIndex:argIndex]; + case 'd': return [self doubleDescriptionAtIndex:argIndex]; + case 'f': return [self floatDescriptionAtIndex:argIndex]; + // Why does this throw EXC_BAD_ACCESS when appending the string? + // case NSObjCStructType: return [self structDescriptionAtIndex:index]; + case '^': return [self pointerDescriptionAtIndex:argIndex]; + case '*': return [self cStringDescriptionAtIndex:argIndex]; + case ':': return [self selectorDescriptionAtIndex:argIndex]; + default: return [@""]; // avoid confusion with trigraphs... + } + +} + + +- (NSString *)objectDescriptionAtIndex:(int)anInt +{ + id object; + + [self getArgument:&object atIndex:anInt]; + if (object == nil) + return @"nil"; + else if(![object isProxy] && [object isKindOfClass:[NSString class]]) + return [NSString stringWithFormat:@"@\"%@\"", [object description]]; + else + return [object description]; +} + +- (NSString *)charDescriptionAtIndex:(int)anInt +{ + unsigned char buffer[128]; + memset(buffer, 0x0, 128); + + [self getArgument:&buffer atIndex:anInt]; + + // If there's only one character in the buffer, and it's 0 or 1, then we have a BOOL + if (buffer[1] == '\0' && (buffer[0] == 0 || buffer[0] == 1)) + return [NSString stringWithFormat:@"%@", (buffer[0] == 1 ? @"YES" : @"NO")]; + else + return [NSString stringWithFormat:@"'%c'", *buffer]; +} + +- (NSString *)unsignedCharDescriptionAtIndex:(int)anInt +{ + unsigned char buffer[128]; + memset(buffer, 0x0, 128); + + [self getArgument:&buffer atIndex:anInt]; + return [NSString stringWithFormat:@"'%c'", *buffer]; +} + +- (NSString *)intDescriptionAtIndex:(int)anInt +{ + int intValue; + + [self getArgument:&intValue atIndex:anInt]; + return [NSString stringWithFormat:@"%d", intValue]; +} + +- (NSString *)unsignedIntDescriptionAtIndex:(int)anInt +{ + unsigned int intValue; + + [self getArgument:&intValue atIndex:anInt]; + return [NSString stringWithFormat:@"%d", intValue]; +} + +- (NSString *)shortDescriptionAtIndex:(int)anInt +{ + short shortValue; + + [self getArgument:&shortValue atIndex:anInt]; + return [NSString stringWithFormat:@"%hi", shortValue]; +} + +- (NSString *)unsignedShortDescriptionAtIndex:(int)anInt +{ + unsigned short shortValue; + + [self getArgument:&shortValue atIndex:anInt]; + return [NSString stringWithFormat:@"%hu", shortValue]; +} + +- (NSString *)longDescriptionAtIndex:(int)anInt +{ + long longValue; + + [self getArgument:&longValue atIndex:anInt]; + return [NSString stringWithFormat:@"%ld", longValue]; +} + +- (NSString *)unsignedLongDescriptionAtIndex:(int)anInt +{ + unsigned long longValue; + + [self getArgument:&longValue atIndex:anInt]; + return [NSString stringWithFormat:@"%lu", longValue]; +} + +- (NSString *)longLongDescriptionAtIndex:(int)anInt +{ + long long longLongValue; + + [self getArgument:&longLongValue atIndex:anInt]; + return [NSString stringWithFormat:@"%qi", longLongValue]; +} + +- (NSString *)unsignedLongLongDescriptionAtIndex:(int)anInt +{ + unsigned long long longLongValue; + + [self getArgument:&longLongValue atIndex:anInt]; + return [NSString stringWithFormat:@"%qu", longLongValue]; +} + +- (NSString *)doubleDescriptionAtIndex:(int)anInt; +{ + double doubleValue; + + [self getArgument:&doubleValue atIndex:anInt]; + return [NSString stringWithFormat:@"%f", doubleValue]; +} + +- (NSString *)floatDescriptionAtIndex:(int)anInt +{ + float floatValue; + + [self getArgument:&floatValue atIndex:anInt]; + return [NSString stringWithFormat:@"%f", floatValue]; +} + +- (NSString *)structDescriptionAtIndex:(int)anInt; +{ + void *buffer; + + [self getArgument:&buffer atIndex:anInt]; + return [NSString stringWithFormat:@":(struct)%p", buffer]; +} + +- (NSString *)pointerDescriptionAtIndex:(int)anInt +{ + void *buffer; + + [self getArgument:&buffer atIndex:anInt]; + return [NSString stringWithFormat:@"%p", buffer]; +} + +- (NSString *)cStringDescriptionAtIndex:(int)anInt +{ + char buffer[128]; + + memset(buffer, 0x0, 128); + + [self getArgument:&buffer atIndex:anInt]; + return [NSString stringWithFormat:@"\"%s\"", buffer]; +} + +- (NSString *)selectorDescriptionAtIndex:(int)anInt +{ + SEL selectorValue; + + [self getArgument:&selectorValue atIndex:anInt]; + return [NSString stringWithFormat:@"@selector(%@)", NSStringFromSelector(selectorValue)]; +} + +@end diff --git a/Pods/OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.h b/Pods/OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.h new file mode 100644 index 0000000..23741e3 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.h @@ -0,0 +1,18 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface NSMethodSignature(PrivateAPI) + ++ (id)signatureWithObjCTypes:(const char *)types; + +@end + +@interface NSMethodSignature(OCMAdditions) + +- (const char *)methodReturnTypeWithoutQualifiers; + +@end diff --git a/Pods/OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.m b/Pods/OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.m new file mode 100644 index 0000000..a69bb14 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/NSMethodSignature+OCMAdditions.m @@ -0,0 +1,19 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "NSMethodSignature+OCMAdditions.h" + + +@implementation NSMethodSignature(OCMAdditions) + +- (const char *)methodReturnTypeWithoutQualifiers +{ + const char *returnType = [self methodReturnType]; + while(strchr("rnNoORV", returnType[0]) != NULL) + returnType += 1; + return returnType; +} + +@end diff --git a/Pods/OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.h b/Pods/OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.h new file mode 100644 index 0000000..ab4832b --- /dev/null +++ b/Pods/OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.h @@ -0,0 +1,15 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@class OCMockObserver; + + +@interface NSNotificationCenter(OCMAdditions) + +- (void)addMockObserver:(OCMockObserver *)notificationObserver name:(NSString *)notificationName object:(id)notificationSender; + +@end diff --git a/Pods/OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.m b/Pods/OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.m new file mode 100644 index 0000000..286cb68 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/NSNotificationCenter+OCMAdditions.m @@ -0,0 +1,17 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "NSNotificationCenter+OCMAdditions.h" +#import "OCObserverMockObject.h" + + +@implementation NSNotificationCenter(OCMAdditions) + +- (void)addMockObserver:(OCMockObserver *)notificationObserver name:(NSString *)notificationName object:(id)notificationSender +{ + [self addObserver:notificationObserver selector:@selector(handleNotification:) name:notificationName object:notificationSender]; +} + +@end diff --git a/Pods/OCMock/Source/OCMock/OCClassMockObject.h b/Pods/OCMock/Source/OCMock/OCClassMockObject.h new file mode 100644 index 0000000..3642240 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCClassMockObject.h @@ -0,0 +1,21 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2005-2013 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface OCClassMockObject : OCMockObject +{ + Class mockedClass; + NSMutableDictionary *replacedClassMethods; +} + +- (id)initWithClass:(Class)aClass; + +- (Class)mockedClass; + +- (void)setupClassForClassMethodMocking; +- (void)setupForwarderForClassMethodSelector:(SEL)selector; + +@end diff --git a/Pods/OCMock/Source/OCMock/OCClassMockObject.m b/Pods/OCMock/Source/OCMock/OCClassMockObject.m new file mode 100644 index 0000000..a479a8a --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCClassMockObject.m @@ -0,0 +1,160 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2005-2013 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import +#import "OCClassMockObject.h" + + +@implementation OCClassMockObject + +#pragma mark Mock table + +static NSMutableDictionary *mockTable; + ++ (void)initialize +{ + if(self == [OCClassMockObject class]) + mockTable = [[NSMutableDictionary alloc] init]; +} + ++ (void)rememberMock:(OCClassMockObject *)mock forClass:(Class)aClass +{ + @synchronized(mockTable) + { + [mockTable setObject:[NSValue valueWithNonretainedObject:mock] forKey:[NSValue valueWithNonretainedObject:aClass]]; + } +} + ++ (void)forgetMockForClass:(Class)aClass +{ + @synchronized(mockTable) + { + [mockTable removeObjectForKey:[NSValue valueWithNonretainedObject:aClass]]; + } +} + ++ (OCClassMockObject *)existingMockForClass:(Class)aClass +{ + @synchronized(mockTable) + { + OCClassMockObject *mock = [[mockTable objectForKey:[NSValue valueWithNonretainedObject:aClass]] nonretainedObjectValue]; + if(mock == nil) + [NSException raise:NSInternalInconsistencyException format:@"No mock for class %p", aClass]; + return mock; + } +} + +#pragma mark Initialisers, description, accessors, etc. + +- (id)initWithClass:(Class)aClass +{ + [super init]; + mockedClass = aClass; + return self; +} + +- (void)dealloc +{ + if(replacedClassMethods != nil) + { + [self stopMocking]; + [[self class] forgetMockForClass:mockedClass]; + [replacedClassMethods release]; + } + [super dealloc]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"OCMockObject[%@]", NSStringFromClass(mockedClass)]; +} + +- (Class)mockedClass +{ + return mockedClass; +} + + +#pragma mark Class method mocking + +- (void)setupClassForClassMethodMocking +{ + if(replacedClassMethods != nil) + return; + + replacedClassMethods = [[NSMutableDictionary alloc] init]; + [[self class] rememberMock:self forClass:mockedClass]; + + Method myForwardInvocationMethod = class_getInstanceMethod([self class], @selector(forwardInvocationForClassObject:)); + IMP myForwardInvocationImp = method_getImplementation(myForwardInvocationMethod); + const char *forwardInvocationTypes = method_getTypeEncoding(myForwardInvocationMethod); + Class metaClass = objc_getMetaClass(class_getName(mockedClass)); + + IMP replacedForwardInvocationImp = class_replaceMethod(metaClass, @selector(forwardInvocation:), myForwardInvocationImp, forwardInvocationTypes); + + [replacedClassMethods setObject:[NSValue valueWithPointer:replacedForwardInvocationImp] forKey:NSStringFromSelector(@selector(forwardInvocation:))]; +} + +- (void)setupForwarderForClassMethodSelector:(SEL)selector +{ + Method originalMethod = class_getClassMethod(mockedClass, selector); + Class metaClass = objc_getMetaClass(class_getName(mockedClass)); + + IMP forwarderImp = [metaClass instanceMethodForSelector:@selector(aMethodThatMustNotExist)]; + IMP replacedMethod = class_replaceMethod(metaClass, method_getName(originalMethod), forwarderImp, method_getTypeEncoding(originalMethod)); + + [replacedClassMethods setObject:[NSValue valueWithPointer:replacedMethod] forKey:NSStringFromSelector(selector)]; +} + +- (void)removeForwarderForClassMethodSelector:(SEL)selector +{ + Class metaClass = objc_getMetaClass(class_getName(mockedClass)); + NSValue *originalMethodPointer = [replacedClassMethods objectForKey:NSStringFromSelector(selector)]; + IMP originalMethod = [originalMethodPointer pointerValue]; + if(originalMethod) { + class_replaceMethod(metaClass, selector, originalMethod, 0); + } else { + IMP forwarderImp = [metaClass instanceMethodForSelector:@selector(aMethodThatMustNotExist)]; + class_replaceMethod(metaClass, selector, forwarderImp, 0); + } +} + +- (void)forwardInvocationForClassObject:(NSInvocation *)anInvocation +{ + // in here "self" is a reference to the real class, not the mock + OCClassMockObject *mock = [OCClassMockObject existingMockForClass:(Class)self]; + if([mock handleInvocation:anInvocation] == NO) + { + // if mock doesn't want to handle the invocation, maybe all expects have occurred, we remove the forwarder and try again + [mock removeForwarderForClassMethodSelector:[anInvocation selector]]; + [anInvocation invoke]; + } +} + +- (void)stopMocking +{ + for(NSString *replacedMethod in replacedClassMethods) + [self removeForwarderForClassMethodSelector:NSSelectorFromString(replacedMethod)]; +} + + +#pragma mark Proxy API + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector +{ + return [mockedClass instanceMethodSignatureForSelector:aSelector]; +} + +- (BOOL)respondsToSelector:(SEL)selector +{ + return [mockedClass instancesRespondToSelector:selector]; +} + +- (BOOL)isKindOfClass:(Class)aClass +{ + return [mockedClass isSubclassOfClass:aClass]; +} + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMArg.h b/Pods/OCMock/Source/OCMock/OCMArg.h new file mode 100644 index 0000000..ef652ab --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMArg.h @@ -0,0 +1,34 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009-2013 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface OCMArg : NSObject + +// constraining arguments + ++ (id)any; ++ (void *)anyPointer; ++ (id)isNil; ++ (id)isNotNil; ++ (id)isNotEqual:(id)value; ++ (id)checkWithSelector:(SEL)selector onObject:(id)anObject; +#if NS_BLOCKS_AVAILABLE ++ (id)checkWithBlock:(BOOL (^)(id))block; +#endif + +// manipulating arguments + ++ (id *)setTo:(id)value; ++ (void *)setToValue:(NSValue *)value; + +// internal use only + ++ (id)resolveSpecialValues:(NSValue *)value; + +@end + +#define OCMOCK_ANY [OCMArg any] +#define OCMOCK_VALUE(variable) [NSValue value:&variable withObjCType:@encode(__typeof__(variable))] diff --git a/Pods/OCMock/Source/OCMock/OCMArg.m b/Pods/OCMock/Source/OCMock/OCMArg.m new file mode 100644 index 0000000..00989ff --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMArg.m @@ -0,0 +1,79 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009-2013 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import +#import +#import +#import "OCMPassByRefSetter.h" +#import "OCMConstraint.h" + +@implementation OCMArg + ++ (id)any +{ + return [OCMAnyConstraint constraint]; +} + ++ (void *)anyPointer +{ + return (void *)0x01234567; +} + ++ (id)isNil +{ + return [OCMIsNilConstraint constraint]; +} + ++ (id)isNotNil +{ + return [OCMIsNotNilConstraint constraint]; +} + ++ (id)isNotEqual:(id)value +{ + OCMIsNotEqualConstraint *constraint = [OCMIsNotEqualConstraint constraint]; + constraint->testValue = value; + return constraint; +} + ++ (id)checkWithSelector:(SEL)selector onObject:(id)anObject +{ + return [OCMConstraint constraintWithSelector:selector onObject:anObject]; +} + +#if NS_BLOCKS_AVAILABLE + ++ (id)checkWithBlock:(BOOL (^)(id))block +{ + return [[[OCMBlockConstraint alloc] initWithConstraintBlock:block] autorelease]; +} + +#endif + ++ (id *)setTo:(id)value +{ + return (id *)[[[OCMPassByRefSetter alloc] initWithValue:value] autorelease]; +} + ++ (void *)setToValue:(NSValue *)value +{ + return (id *)[[[OCMPassByRefSetter alloc] initWithValue:value] autorelease]; +} + ++ (id)resolveSpecialValues:(NSValue *)value +{ + const char *type = [value objCType]; + if(type[0] == '^') + { + void *pointer = [value pointerValue]; + if(pointer == (void *)0x01234567) + return [OCMArg any]; + if((pointer != NULL) && (object_getClass((id)pointer) == [OCMPassByRefSetter class])) + return (id)pointer; + } + return value; +} + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMBlockCaller.h b/Pods/OCMock/Source/OCMock/OCMBlockCaller.h new file mode 100644 index 0000000..652acc3 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMBlockCaller.h @@ -0,0 +1,21 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2010 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +#if NS_BLOCKS_AVAILABLE + +@interface OCMBlockCaller : NSObject +{ + void (^block)(NSInvocation *); +} + +- (id)initWithCallBlock:(void (^)(NSInvocation *))theBlock; + +- (void)handleInvocation:(NSInvocation *)anInvocation; + +@end + +#endif diff --git a/Pods/OCMock/Source/OCMock/OCMBlockCaller.m b/Pods/OCMock/Source/OCMock/OCMBlockCaller.m new file mode 100644 index 0000000..439d885 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMBlockCaller.m @@ -0,0 +1,32 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2010 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "OCMBlockCaller.h" + +#if NS_BLOCKS_AVAILABLE + +@implementation OCMBlockCaller + +-(id)initWithCallBlock:(void (^)(NSInvocation *))theBlock +{ + self = [super init]; + block = [theBlock copy]; + return self; +} + +-(void)dealloc +{ + [block release]; + [super dealloc]; +} + +- (void)handleInvocation:(NSInvocation *)anInvocation +{ + block(anInvocation); +} + +@end + +#endif diff --git a/Pods/OCMock/Source/OCMock/OCMBoxedReturnValueProvider.h b/Pods/OCMock/Source/OCMock/OCMBoxedReturnValueProvider.h new file mode 100644 index 0000000..f2d9c91 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMBoxedReturnValueProvider.h @@ -0,0 +1,12 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "OCMReturnValueProvider.h" + +@interface OCMBoxedReturnValueProvider : OCMReturnValueProvider +{ +} + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMBoxedReturnValueProvider.m b/Pods/OCMock/Source/OCMock/OCMBoxedReturnValueProvider.m new file mode 100644 index 0000000..cdeaa02 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMBoxedReturnValueProvider.m @@ -0,0 +1,21 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "OCMBoxedReturnValueProvider.h" + + +@implementation OCMBoxedReturnValueProvider + +- (void)handleInvocation:(NSInvocation *)anInvocation +{ + if(strcmp([[anInvocation methodSignature] methodReturnType], [(NSValue *)returnValue objCType]) != 0) + @throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"Return value does not match method signature; signature declares '%s' but value is '%s'.", [[anInvocation methodSignature] methodReturnType], [(NSValue *)returnValue objCType]] userInfo:nil]; + void *buffer = malloc([[anInvocation methodSignature] methodReturnLength]); + [returnValue getValue:buffer]; + [anInvocation setReturnValue:buffer]; + free(buffer); +} + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMConstraint.h b/Pods/OCMock/Source/OCMock/OCMConstraint.h new file mode 100644 index 0000000..3ae1264 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMConstraint.h @@ -0,0 +1,64 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2007-2010 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + + +@interface OCMConstraint : NSObject + ++ (id)constraint; +- (BOOL)evaluate:(id)value; + +// if you are looking for any, isNil, etc, they have moved to OCMArg + +// try to use [OCMArg checkWith...] instead of the constraintWith... methods below + ++ (id)constraintWithSelector:(SEL)aSelector onObject:(id)anObject; ++ (id)constraintWithSelector:(SEL)aSelector onObject:(id)anObject withValue:(id)aValue; + + +@end + +@interface OCMAnyConstraint : OCMConstraint +@end + +@interface OCMIsNilConstraint : OCMConstraint +@end + +@interface OCMIsNotNilConstraint : OCMConstraint +@end + +@interface OCMIsNotEqualConstraint : OCMConstraint +{ + @public + id testValue; +} + +@end + +@interface OCMInvocationConstraint : OCMConstraint +{ + @public + NSInvocation *invocation; +} + +@end + +#if NS_BLOCKS_AVAILABLE + +@interface OCMBlockConstraint : OCMConstraint +{ + BOOL (^block)(id); +} + +- (id)initWithConstraintBlock:(BOOL (^)(id))block; + +@end + +#endif + + +#define CONSTRAINT(aSelector) [OCMConstraint constraintWithSelector:aSelector onObject:self] +#define CONSTRAINTV(aSelector, aValue) [OCMConstraint constraintWithSelector:aSelector onObject:self withValue:(aValue)] diff --git a/Pods/OCMock/Source/OCMock/OCMConstraint.m b/Pods/OCMock/Source/OCMock/OCMConstraint.m new file mode 100644 index 0000000..b16a678 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMConstraint.m @@ -0,0 +1,142 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2007-2010 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + + +@implementation OCMConstraint + ++ (id)constraint +{ + return [[[self alloc] init] autorelease]; +} + +- (BOOL)evaluate:(id)value +{ + return NO; +} + + ++ (id)constraintWithSelector:(SEL)aSelector onObject:(id)anObject +{ + OCMInvocationConstraint *constraint = [OCMInvocationConstraint constraint]; + NSMethodSignature *signature = [anObject methodSignatureForSelector:aSelector]; + if(signature == nil) + [NSException raise:NSInvalidArgumentException format:@"Unkown selector %@ used in constraint.", NSStringFromSelector(aSelector)]; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; + [invocation setTarget:anObject]; + [invocation setSelector:aSelector]; + constraint->invocation = invocation; + return constraint; +} + ++ (id)constraintWithSelector:(SEL)aSelector onObject:(id)anObject withValue:(id)aValue +{ + OCMInvocationConstraint *constraint = [self constraintWithSelector:aSelector onObject:anObject]; + if([[constraint->invocation methodSignature] numberOfArguments] < 4) + [NSException raise:NSInvalidArgumentException format:@"Constraint with value requires selector with two arguments."]; + [constraint->invocation setArgument:&aValue atIndex:3]; + return constraint; +} + + +@end + + + +#pragma mark - + +@implementation OCMAnyConstraint + +- (BOOL)evaluate:(id)value +{ + return YES; +} + +@end + + + +#pragma mark - + +@implementation OCMIsNilConstraint + +- (BOOL)evaluate:(id)value +{ + return value == nil; +} + +@end + + + +#pragma mark - + +@implementation OCMIsNotNilConstraint + +- (BOOL)evaluate:(id)value +{ + return value != nil; +} + +@end + + + +#pragma mark - + +@implementation OCMIsNotEqualConstraint + +- (BOOL)evaluate:(id)value +{ + return ![value isEqual:testValue]; +} + +@end + + + +#pragma mark - + +@implementation OCMInvocationConstraint + +- (BOOL)evaluate:(id)value +{ + [invocation setArgument:&value atIndex:2]; // should test if constraint takes arg + [invocation invoke]; + BOOL returnValue; + [invocation getReturnValue:&returnValue]; + return returnValue; +} + +@end + +#pragma mark - + +#if NS_BLOCKS_AVAILABLE + +@implementation OCMBlockConstraint + +- (id)initWithConstraintBlock:(BOOL (^)(id))aBlock; +{ + self = [super init]; + block = [aBlock copy]; + return self; +} + +- (void)dealloc { + [block release]; + [super dealloc]; +} + +- (BOOL)evaluate:(id)value +{ + return block(value); +} + + +@end + +#endif diff --git a/Pods/OCMock/Source/OCMock/OCMExceptionReturnValueProvider.h b/Pods/OCMock/Source/OCMock/OCMExceptionReturnValueProvider.h new file mode 100644 index 0000000..8e97469 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMExceptionReturnValueProvider.h @@ -0,0 +1,12 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "OCMReturnValueProvider.h" + +@interface OCMExceptionReturnValueProvider : OCMReturnValueProvider +{ +} + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMExceptionReturnValueProvider.m b/Pods/OCMock/Source/OCMock/OCMExceptionReturnValueProvider.m new file mode 100644 index 0000000..784d1a7 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMExceptionReturnValueProvider.m @@ -0,0 +1,16 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "OCMExceptionReturnValueProvider.h" + + +@implementation OCMExceptionReturnValueProvider + +- (void)handleInvocation:(NSInvocation *)anInvocation +{ + @throw returnValue; +} + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMIndirectReturnValueProvider.h b/Pods/OCMock/Source/OCMock/OCMIndirectReturnValueProvider.h new file mode 100644 index 0000000..4efeacb --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMIndirectReturnValueProvider.h @@ -0,0 +1,18 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface OCMIndirectReturnValueProvider : NSObject +{ + id provider; + SEL selector; +} + +- (id)initWithProvider:(id)aProvider andSelector:(SEL)aSelector; + +- (void)handleInvocation:(NSInvocation *)anInvocation; + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMIndirectReturnValueProvider.m b/Pods/OCMock/Source/OCMock/OCMIndirectReturnValueProvider.m new file mode 100644 index 0000000..c8b734d --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMIndirectReturnValueProvider.m @@ -0,0 +1,33 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "NSMethodSignature+OCMAdditions.h" +#import "OCMIndirectReturnValueProvider.h" + + +@implementation OCMIndirectReturnValueProvider + +- (id)initWithProvider:(id)aProvider andSelector:(SEL)aSelector +{ + self = [super init]; + provider = [aProvider retain]; + selector = aSelector; + return self; +} + +- (void)dealloc +{ + [provider release]; + [super dealloc]; +} + +- (void)handleInvocation:(NSInvocation *)anInvocation +{ + [anInvocation setTarget:provider]; + [anInvocation setSelector:selector]; + [anInvocation invoke]; +} + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMNotificationPoster.h b/Pods/OCMock/Source/OCMock/OCMNotificationPoster.h new file mode 100644 index 0000000..817da78 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMNotificationPoster.h @@ -0,0 +1,17 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface OCMNotificationPoster : NSObject +{ + NSNotification *notification; +} + +- (id)initWithNotification:(id)aNotification; + +- (void)handleInvocation:(NSInvocation *)anInvocation; + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMNotificationPoster.m b/Pods/OCMock/Source/OCMock/OCMNotificationPoster.m new file mode 100644 index 0000000..64973a2 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMNotificationPoster.m @@ -0,0 +1,30 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "OCMNotificationPoster.h" + + +@implementation OCMNotificationPoster + +- (id)initWithNotification:(id)aNotification +{ + self = [super init]; + notification = [aNotification retain]; + return self; +} + +- (void)dealloc +{ + [notification release]; + [super dealloc]; +} + +- (void)handleInvocation:(NSInvocation *)anInvocation +{ + [[NSNotificationCenter defaultCenter] postNotification:notification]; +} + + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMObserverRecorder.h b/Pods/OCMock/Source/OCMock/OCMObserverRecorder.h new file mode 100644 index 0000000..556da3c --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMObserverRecorder.h @@ -0,0 +1,19 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface OCMObserverRecorder : NSObject +{ + NSNotification *recordedNotification; +} + +- (void)notificationWithName:(NSString *)name object:(id)sender; + +- (BOOL)matchesNotification:(NSNotification *)aNotification; + +- (BOOL)argument:(id)expectedArg matchesArgument:(id)observedArg; + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMObserverRecorder.m b/Pods/OCMock/Source/OCMock/OCMObserverRecorder.m new file mode 100644 index 0000000..e50be50 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMObserverRecorder.m @@ -0,0 +1,75 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import +#import +#import "NSInvocation+OCMAdditions.h" +#import "OCMObserverRecorder.h" + +@interface NSObject(HCMatcherDummy) +- (BOOL)matches:(id)item; +@end + +#pragma mark - + + +@implementation OCMObserverRecorder + +#pragma mark Initialisers, description, accessors, etc. + +- (void)dealloc +{ + [recordedNotification release]; + [super dealloc]; +} + + +#pragma mark Recording + +- (void)notificationWithName:(NSString *)name object:(id)sender +{ + recordedNotification = [[NSNotification notificationWithName:name object:sender] retain]; +} + +- (void)notificationWithName:(NSString *)name object:(id)sender userInfo:(NSDictionary *)userInfo +{ + recordedNotification = [[NSNotification notificationWithName:name object:sender userInfo:userInfo] retain]; +} + + +#pragma mark Verification + +- (BOOL)matchesNotification:(NSNotification *)aNotification +{ + return [self argument:[recordedNotification name] matchesArgument:[aNotification name]] && + [self argument:[recordedNotification object] matchesArgument:[aNotification object]] && + [self argument:[recordedNotification userInfo] matchesArgument:[aNotification userInfo]]; +} + +- (BOOL)argument:(id)expectedArg matchesArgument:(id)observedArg +{ + if([expectedArg isKindOfClass:[OCMConstraint class]]) + { + if([expectedArg evaluate:observedArg] == NO) + return NO; + } + else if([expectedArg conformsToProtocol:objc_getProtocol("HCMatcher")]) + { + if([expectedArg matches:observedArg] == NO) + return NO; + } + else + { + if([expectedArg class] != [observedArg class]) + return NO; + if(([expectedArg isEqual:observedArg] == NO) && + !((expectedArg == nil) && (observedArg == nil))) + return NO; + } + return YES; +} + + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMPassByRefSetter.h b/Pods/OCMock/Source/OCMock/OCMPassByRefSetter.h new file mode 100644 index 0000000..12b99e3 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMPassByRefSetter.h @@ -0,0 +1,17 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface OCMPassByRefSetter : NSObject +{ + id value; +} + +- (id)initWithValue:(id)value; + +- (id)value; + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMPassByRefSetter.m b/Pods/OCMock/Source/OCMock/OCMPassByRefSetter.m new file mode 100644 index 0000000..919b81a --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMPassByRefSetter.m @@ -0,0 +1,29 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "OCMPassByRefSetter.h" + + +@implementation OCMPassByRefSetter + +- (id)initWithValue:(id)aValue +{ + self = [super init]; + value = [aValue retain]; + return self; +} + +- (void)dealloc +{ + [value release]; + [super dealloc]; +} + +- (id)value +{ + return value; +} + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMRealObjectForwarder.h b/Pods/OCMock/Source/OCMock/OCMRealObjectForwarder.h new file mode 100644 index 0000000..9357a42 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMRealObjectForwarder.h @@ -0,0 +1,14 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2010 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface OCMRealObjectForwarder : NSObject +{ +} + +- (void)handleInvocation:(NSInvocation *)anInvocation; + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMRealObjectForwarder.m b/Pods/OCMock/Source/OCMock/OCMRealObjectForwarder.m new file mode 100644 index 0000000..7c0a7db --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMRealObjectForwarder.m @@ -0,0 +1,29 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2010 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import +#import "OCPartialMockObject.h" +#import "OCMRealObjectForwarder.h" + + +@implementation OCMRealObjectForwarder + +- (void)handleInvocation:(NSInvocation *)anInvocation +{ + id invocationTarget = [anInvocation target]; + SEL invocationSelector = [anInvocation selector]; + SEL aliasedSelector = NSSelectorFromString([OCMRealMethodAliasPrefix stringByAppendingString:NSStringFromSelector(invocationSelector)]); + + [anInvocation setSelector:aliasedSelector]; + if([invocationTarget isProxy] && (class_getInstanceMethod([invocationTarget class], @selector(realObject)))) + { + // the method has been invoked on the mock, we need to change the target to the real object + [anInvocation setTarget:[(OCPartialMockObject *)invocationTarget realObject]]; + } + [anInvocation invoke]; +} + + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMReturnValueProvider.h b/Pods/OCMock/Source/OCMock/OCMReturnValueProvider.h new file mode 100644 index 0000000..3566c6d --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMReturnValueProvider.h @@ -0,0 +1,17 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface OCMReturnValueProvider : NSObject +{ + id returnValue; +} + +- (id)initWithValue:(id)aValue; + +- (void)handleInvocation:(NSInvocation *)anInvocation; + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMReturnValueProvider.m b/Pods/OCMock/Source/OCMock/OCMReturnValueProvider.m new file mode 100644 index 0000000..7bc9072 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMReturnValueProvider.m @@ -0,0 +1,47 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "NSMethodSignature+OCMAdditions.h" +#import "OCMReturnValueProvider.h" + + +@implementation OCMReturnValueProvider + +- (id)initWithValue:(id)aValue +{ + self = [super init]; + returnValue = [aValue retain]; + return self; +} + +- (void)dealloc +{ + [returnValue release]; + [super dealloc]; +} + +- (void)handleInvocation:(NSInvocation *)anInvocation +{ + const char *returnType = [[anInvocation methodSignature] methodReturnTypeWithoutQualifiers]; + if(strcmp(returnType, @encode(id)) != 0) { + // if the returnType is a typedef to an object, it has the form ^{OriginalClass=#} + NSString *regexString = @"^\\^\\{(.*)=#\\}"; + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString options:0 error:NULL]; + NSString *type = [NSString stringWithCString:returnType encoding:NSASCIIStringEncoding]; + if([regex numberOfMatchesInString:type options:0 range:NSMakeRange(0, type.length)] == 0) + { + @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Expected invocation with object return type. Did you mean to use andReturnValue: instead?" userInfo:nil]; + } + } + NSString *sel = NSStringFromSelector([anInvocation selector]); + if([sel hasPrefix:@"alloc"] || [sel hasPrefix:@"new"] || [sel hasPrefix:@"copy"] || [sel hasPrefix:@"mutableCopy"]) + { + // methods that "create" an object return it with an extra retain count + [returnValue retain]; + } + [anInvocation setReturnValue:&returnValue]; +} + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMock.h b/Pods/OCMock/Source/OCMock/OCMock.h new file mode 100644 index 0000000..e18de58 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMock.h @@ -0,0 +1,10 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2004-2008 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import +#import +#import +#import +#import diff --git a/Pods/OCMock/Source/OCMock/OCMockObject.h b/Pods/OCMock/Source/OCMock/OCMockObject.h new file mode 100644 index 0000000..e796705 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMockObject.h @@ -0,0 +1,46 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2004-2008 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface OCMockObject : NSProxy +{ + BOOL isNice; + BOOL expectationOrderMatters; + NSMutableArray *recorders; + NSMutableArray *expectations; + NSMutableArray *rejections; + NSMutableArray *exceptions; +} + ++ (id)mockForClass:(Class)aClass; ++ (id)mockForProtocol:(Protocol *)aProtocol; ++ (id)partialMockForObject:(NSObject *)anObject; + ++ (id)niceMockForClass:(Class)aClass; ++ (id)niceMockForProtocol:(Protocol *)aProtocol; + ++ (id)observerMock; + +- (id)init; + +- (void)setExpectationOrderMatters:(BOOL)flag; + +- (id)stub; +- (id)expect; +- (id)reject; + +- (void)verify; + +- (void)stopMocking; + +// internal use only + +- (id)getNewRecorder; +- (BOOL)handleInvocation:(NSInvocation *)anInvocation; +- (void)handleUnRecordedInvocation:(NSInvocation *)anInvocation; +- (BOOL)handleSelector:(SEL)sel; + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMockObject.m b/Pods/OCMock/Source/OCMock/OCMockObject.m new file mode 100644 index 0000000..2729e5c --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMockObject.m @@ -0,0 +1,269 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2004-2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import +#import "OCClassMockObject.h" +#import "OCProtocolMockObject.h" +#import "OCPartialMockObject.h" +#import "OCObserverMockObject.h" +#import +#import "NSInvocation+OCMAdditions.h" + +@interface OCMockObject(Private) ++ (id)_makeNice:(OCMockObject *)mock; +- (NSString *)_recorderDescriptions:(BOOL)onlyExpectations; +@end + +#pragma mark - + + +@implementation OCMockObject + +#pragma mark Class initialisation + ++ (void)initialize +{ + if([[NSInvocation class] instanceMethodSignatureForSelector:@selector(getArgumentAtIndexAsObject:)] == NULL) + [NSException raise:NSInternalInconsistencyException format:@"** Expected method not present; the method getArgumentAtIndexAsObject: is not implemented by NSInvocation. If you see this exception it is likely that you are using the static library version of OCMock and your project is not configured correctly to load categories from static libraries. Did you forget to add the -force_load linker flag?"]; +} + + +#pragma mark Factory methods + ++ (id)mockForClass:(Class)aClass +{ + return [[[OCClassMockObject alloc] initWithClass:aClass] autorelease]; +} + ++ (id)mockForProtocol:(Protocol *)aProtocol +{ + return [[[OCProtocolMockObject alloc] initWithProtocol:aProtocol] autorelease]; +} + ++ (id)partialMockForObject:(NSObject *)anObject +{ + return [[[OCPartialMockObject alloc] initWithObject:anObject] autorelease]; +} + + ++ (id)niceMockForClass:(Class)aClass +{ + return [self _makeNice:[self mockForClass:aClass]]; +} + ++ (id)niceMockForProtocol:(Protocol *)aProtocol +{ + return [self _makeNice:[self mockForProtocol:aProtocol]]; +} + + ++ (id)_makeNice:(OCMockObject *)mock +{ + mock->isNice = YES; + return mock; +} + + ++ (id)observerMock +{ + return [[[OCObserverMockObject alloc] init] autorelease]; +} + + + +#pragma mark Initialisers, description, accessors, etc. + +- (id)init +{ + // no [super init], we're inheriting from NSProxy + expectationOrderMatters = NO; + recorders = [[NSMutableArray alloc] init]; + expectations = [[NSMutableArray alloc] init]; + rejections = [[NSMutableArray alloc] init]; + exceptions = [[NSMutableArray alloc] init]; + return self; +} + +- (void)dealloc +{ + [recorders release]; + [expectations release]; + [rejections release]; + [exceptions release]; + [super dealloc]; +} + +- (NSString *)description +{ + return @"OCMockObject"; +} + + +- (void)setExpectationOrderMatters:(BOOL)flag +{ + expectationOrderMatters = flag; +} + + +#pragma mark Public API + +- (id)stub +{ + OCMockRecorder *recorder = [self getNewRecorder]; + [recorders addObject:recorder]; + return recorder; +} + + +- (id)expect +{ + OCMockRecorder *recorder = [self stub]; + [expectations addObject:recorder]; + return recorder; +} + + +- (id)reject +{ + OCMockRecorder *recorder = [self stub]; + [rejections addObject:recorder]; + return recorder; +} + + +- (void)verify +{ + if([expectations count] == 1) + { + [NSException raise:NSInternalInconsistencyException format:@"%@: expected method was not invoked: %@", + [self description], [[expectations objectAtIndex:0] description]]; + } + if([expectations count] > 0) + { + [NSException raise:NSInternalInconsistencyException format:@"%@ : %ld expected methods were not invoked: %@", + [self description], [expectations count], [self _recorderDescriptions:YES]]; + } + if([exceptions count] > 0) + { + [[exceptions objectAtIndex:0] raise]; + } +} + +- (void)stopMocking +{ + // no-op for mock objects that are not class object or partial mocks +} + + +#pragma mark Handling invocations + +- (BOOL)handleSelector:(SEL)sel +{ + for (OCMockRecorder *recorder in recorders) + if ([recorder matchesSelector:sel]) + return YES; + + return NO; +} + +- (void)forwardInvocation:(NSInvocation *)anInvocation +{ + if([self handleInvocation:anInvocation] == NO) + [self handleUnRecordedInvocation:anInvocation]; +} + +- (BOOL)handleInvocation:(NSInvocation *)anInvocation +{ + OCMockRecorder *recorder = nil; + unsigned int i; + + for(i = 0; i < [recorders count]; i++) + { + recorder = [recorders objectAtIndex:i]; + if([recorder matchesInvocation:anInvocation]) + break; + } + + if(i == [recorders count]) + return NO; + + if([rejections containsObject:recorder]) + { + NSException *exception = [NSException exceptionWithName:NSInternalInconsistencyException reason: + [NSString stringWithFormat:@"%@: explicitly disallowed method invoked: %@", [self description], + [anInvocation invocationDescription]] userInfo:nil]; + [exceptions addObject:exception]; + [exception raise]; + } + + if([expectations containsObject:recorder]) + { + if(expectationOrderMatters && ([expectations objectAtIndex:0] != recorder)) + { + [NSException raise:NSInternalInconsistencyException format:@"%@: unexpected method invoked: %@\n\texpected:\t%@", + [self description], [recorder description], [[expectations objectAtIndex:0] description]]; + + } + [[recorder retain] autorelease]; + [expectations removeObject:recorder]; + [recorders removeObjectAtIndex:i]; + } + [[recorder invocationHandlers] makeObjectsPerformSelector:@selector(handleInvocation:) withObject:anInvocation]; + + return YES; +} + +- (void)handleUnRecordedInvocation:(NSInvocation *)anInvocation +{ + if(isNice == NO) + { + NSException *exception = [NSException exceptionWithName:NSInternalInconsistencyException reason: + [NSString stringWithFormat:@"%@: unexpected method invoked: %@ %@", [self description], + [anInvocation invocationDescription], [self _recorderDescriptions:NO]] userInfo:nil]; + [exceptions addObject:exception]; + [exception raise]; + } +} + + +#pragma mark Helper methods + +- (id)getNewRecorder +{ + return [[[OCMockRecorder alloc] initWithSignatureResolver:self] autorelease]; +} + + +- (NSString *)_recorderDescriptions:(BOOL)onlyExpectations +{ + NSMutableString *outputString = [NSMutableString string]; + + OCMockRecorder *currentObject; + NSEnumerator *recorderEnumerator = [recorders objectEnumerator]; + while((currentObject = [recorderEnumerator nextObject]) != nil) + { + NSString *prefix; + + if(onlyExpectations) + { + if(![expectations containsObject:currentObject]) + continue; + prefix = @" "; + } + else + { + if ([expectations containsObject:currentObject]) + prefix = @"expected: "; + else + prefix = @"stubbed: "; + } + [outputString appendFormat:@"\n\t%@\t%@", prefix, [currentObject description]]; + } + + return outputString; +} + + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMockRecorder.h b/Pods/OCMock/Source/OCMock/OCMockRecorder.h new file mode 100644 index 0000000..1b6e2dd --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMockRecorder.h @@ -0,0 +1,36 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2004-2013 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface OCMockRecorder : NSProxy +{ + id signatureResolver; + BOOL recordedAsClassMethod; + NSInvocation *recordedInvocation; + NSMutableArray *invocationHandlers; +} + +- (id)initWithSignatureResolver:(id)anObject; + +- (BOOL)matchesSelector:(SEL)sel; +- (BOOL)matchesInvocation:(NSInvocation *)anInvocation; +- (void)releaseInvocation; + +- (id)andReturn:(id)anObject; +- (id)andReturnValue:(NSValue *)aValue; +- (id)andThrow:(NSException *)anException; +- (id)andPost:(NSNotification *)aNotification; +- (id)andCall:(SEL)selector onObject:(id)anObject; +#if NS_BLOCKS_AVAILABLE +- (id)andDo:(void (^)(NSInvocation *))block; +#endif +- (id)andForwardToRealObject; + +- (id)classMethod; + +- (NSArray *)invocationHandlers; + +@end diff --git a/Pods/OCMock/Source/OCMock/OCMockRecorder.m b/Pods/OCMock/Source/OCMock/OCMockRecorder.m new file mode 100644 index 0000000..89ab150 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCMockRecorder.m @@ -0,0 +1,229 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2004-2013 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import +#import +#import +#import +#import "OCClassMockObject.h" +#import "OCMPassByRefSetter.h" +#import "OCMReturnValueProvider.h" +#import "OCMBoxedReturnValueProvider.h" +#import "OCMExceptionReturnValueProvider.h" +#import "OCMIndirectReturnValueProvider.h" +#import "OCMNotificationPoster.h" +#import "OCMBlockCaller.h" +#import "NSInvocation+OCMAdditions.h" + +@interface NSObject(HCMatcherDummy) +- (BOOL)matches:(id)item; +@end + +#pragma mark - + + +@implementation OCMockRecorder + +#pragma mark Initialisers, description, accessors, etc. + +- (id)initWithSignatureResolver:(id)anObject +{ + signatureResolver = anObject; + invocationHandlers = [[NSMutableArray alloc] init]; + return self; +} + +- (void)dealloc +{ + [recordedInvocation release]; + [invocationHandlers release]; + [super dealloc]; +} + +- (NSString *)description +{ + return [recordedInvocation invocationDescription]; +} + +- (void)releaseInvocation +{ + [recordedInvocation release]; + recordedInvocation = nil; +} + + +#pragma mark Recording invocation handlers + +- (id)andReturn:(id)anObject +{ + [invocationHandlers addObject:[[[OCMReturnValueProvider alloc] initWithValue:anObject] autorelease]]; + return self; +} + +- (id)andReturnValue:(NSValue *)aValue +{ + [invocationHandlers addObject:[[[OCMBoxedReturnValueProvider alloc] initWithValue:aValue] autorelease]]; + return self; +} + +- (id)andThrow:(NSException *)anException +{ + [invocationHandlers addObject:[[[OCMExceptionReturnValueProvider alloc] initWithValue:anException] autorelease]]; + return self; +} + +- (id)andPost:(NSNotification *)aNotification +{ + [invocationHandlers addObject:[[[OCMNotificationPoster alloc] initWithNotification:aNotification] autorelease]]; + return self; +} + +- (id)andCall:(SEL)selector onObject:(id)anObject +{ + [invocationHandlers addObject:[[[OCMIndirectReturnValueProvider alloc] initWithProvider:anObject andSelector:selector] autorelease]]; + return self; +} + +#if NS_BLOCKS_AVAILABLE + +- (id)andDo:(void (^)(NSInvocation *))aBlock +{ + [invocationHandlers addObject:[[[OCMBlockCaller alloc] initWithCallBlock:aBlock] autorelease]]; + return self; +} + +#endif + +- (id)andForwardToRealObject +{ + [NSException raise:NSInternalInconsistencyException format:@"Method %@ can only be used with partial mocks.", + NSStringFromSelector(_cmd)]; + return self; // keep compiler happy +} + + +- (NSArray *)invocationHandlers +{ + return invocationHandlers; +} + + +#pragma mark Switching to class methods + +- (id)classMethod +{ + recordedAsClassMethod = YES; + [signatureResolver setupClassForClassMethodMocking]; + return self; +} + + +#pragma mark Recording the actual invocation + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector +{ + if(recordedAsClassMethod) + return [[signatureResolver mockedClass] methodSignatureForSelector:aSelector]; + + NSMethodSignature *signature = [signatureResolver methodSignatureForSelector:aSelector]; + if(signature == nil) + { + // if we're a working with a class mock and there is a class method, auto-switch + if(([[signatureResolver class] isSubclassOfClass:[OCClassMockObject class]]) && + ([[signatureResolver mockedClass] respondsToSelector:aSelector])) + { + [self classMethod]; + signature = [self methodSignatureForSelector:aSelector]; + } + } + return signature; +} + +- (void)forwardInvocation:(NSInvocation *)anInvocation +{ + if(recordedAsClassMethod) + [signatureResolver setupForwarderForClassMethodSelector:[anInvocation selector]]; + if(recordedInvocation != nil) + [NSException raise:NSInternalInconsistencyException format:@"Recorder received two methods to record."]; + [anInvocation setTarget:nil]; + [anInvocation retainArguments]; + recordedInvocation = [anInvocation retain]; +} + + + +#pragma mark Checking the invocation + +- (BOOL)matchesSelector:(SEL)sel +{ + return (sel == [recordedInvocation selector]); +} + +- (BOOL)matchesInvocation:(NSInvocation *)anInvocation +{ + id target, recordedArg, passedArg; + int i, n; + BOOL isClassMethodInvocation; + + target = [anInvocation target]; + isClassMethodInvocation = (target != nil) && (target == [target class]); + if(isClassMethodInvocation != recordedAsClassMethod) + return NO; + + if([anInvocation selector] != [recordedInvocation selector]) + return NO; + + n = (int)[[recordedInvocation methodSignature] numberOfArguments]; + for(i = 2; i < n; i++) + { + recordedArg = [recordedInvocation getArgumentAtIndexAsObject:i]; + passedArg = [anInvocation getArgumentAtIndexAsObject:i]; + + if([recordedArg isProxy]) + { + if(![recordedArg isEqual:passedArg]) + return NO; + continue; + } + + if([recordedArg isKindOfClass:[NSValue class]]) + recordedArg = [OCMArg resolveSpecialValues:recordedArg]; + + if([recordedArg isKindOfClass:[OCMConstraint class]]) + { + if([recordedArg evaluate:passedArg] == NO) + return NO; + } + else if([recordedArg isKindOfClass:[OCMPassByRefSetter class]]) + { + id valueToSet = [(OCMPassByRefSetter *)recordedArg value]; + // side effect but easier to do here than in handleInvocation + if(![valueToSet isKindOfClass:[NSValue class]]) + *(id *)[passedArg pointerValue] = valueToSet; + else + [(NSValue *)valueToSet getValue:[passedArg pointerValue]]; + } + else if([recordedArg conformsToProtocol:objc_getProtocol("HCMatcher")]) + { + if([recordedArg matches:passedArg] == NO) + return NO; + } + else + { + if(([recordedArg class] == [NSNumber class]) && + ([(NSNumber*)recordedArg compare:(NSNumber*)passedArg] != NSOrderedSame)) + return NO; + if(([recordedArg isEqual:passedArg] == NO) && + !((recordedArg == nil) && (passedArg == nil))) + return NO; + } + } + return YES; +} + + + + +@end diff --git a/Pods/OCMock/Source/OCMock/OCObserverMockObject.h b/Pods/OCMock/Source/OCMock/OCObserverMockObject.h new file mode 100644 index 0000000..908ad2f --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCObserverMockObject.h @@ -0,0 +1,22 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface OCObserverMockObject : NSObject +{ + BOOL expectationOrderMatters; + NSMutableArray *recorders; +} + +- (void)setExpectationOrderMatters:(BOOL)flag; + +- (id)expect; + +- (void)verify; + +- (void)handleNotification:(NSNotification *)aNotification; + +@end diff --git a/Pods/OCMock/Source/OCMock/OCObserverMockObject.m b/Pods/OCMock/Source/OCMock/OCObserverMockObject.m new file mode 100644 index 0000000..50ba984 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCObserverMockObject.m @@ -0,0 +1,83 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "OCObserverMockObject.h" +#import "OCMObserverRecorder.h" + + +@implementation OCObserverMockObject + +#pragma mark Initialisers, description, accessors, etc. + +- (id)init +{ + self = [super init]; + recorders = [[NSMutableArray alloc] init]; + return self; +} + +- (void)dealloc +{ + [recorders release]; + [super dealloc]; +} + +- (NSString *)description +{ + return @"OCMockObserver"; +} + +- (void)setExpectationOrderMatters:(BOOL)flag +{ + expectationOrderMatters = flag; +} + + +#pragma mark Public API + +- (id)expect +{ + OCMObserverRecorder *recorder = [[[OCMObserverRecorder alloc] init] autorelease]; + [recorders addObject:recorder]; + return recorder; +} + +- (void)verify +{ + if([recorders count] == 1) + { + [NSException raise:NSInternalInconsistencyException format:@"%@: expected notification was not observed: %@", + [self description], [[recorders lastObject] description]]; + } + if([recorders count] > 0) + { + [NSException raise:NSInternalInconsistencyException format:@"%@ : %ld expected notifications were not observed.", + [self description], [recorders count]]; + } +} + + + +#pragma mark Receiving notifications + +- (void)handleNotification:(NSNotification *)aNotification +{ + NSUInteger i, limit; + + limit = expectationOrderMatters ? 1 : [recorders count]; + for(i = 0; i < limit; i++) + { + if([[recorders objectAtIndex:i] matchesNotification:aNotification]) + { + [recorders removeObjectAtIndex:i]; + return; + } + } + [NSException raise:NSInternalInconsistencyException format:@"%@: unexpected notification observed: %@", [self description], + [aNotification description]]; +} + + +@end diff --git a/Pods/OCMock/Source/OCMock/OCPartialMockObject.h b/Pods/OCMock/Source/OCMock/OCPartialMockObject.h new file mode 100644 index 0000000..d932d28 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCPartialMockObject.h @@ -0,0 +1,25 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "OCClassMockObject.h" + +@interface OCPartialMockObject : OCClassMockObject +{ + NSObject *realObject; +} + +- (id)initWithObject:(NSObject *)anObject; + +- (NSObject *)realObject; + +- (void)stopMocking; + +- (void)setupSubclassForObject:(id)anObject; +- (void)setupForwarderForSelector:(SEL)selector; + +@end + + +extern NSString *OCMRealMethodAliasPrefix; diff --git a/Pods/OCMock/Source/OCMock/OCPartialMockObject.m b/Pods/OCMock/Source/OCMock/OCPartialMockObject.m new file mode 100644 index 0000000..7a678b6 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCPartialMockObject.m @@ -0,0 +1,190 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import +#import "OCPartialMockRecorder.h" +#import "OCPartialMockObject.h" + + +@interface OCPartialMockObject (Private) +- (void)forwardInvocationForRealObject:(NSInvocation *)anInvocation; +@end + + +NSString *OCMRealMethodAliasPrefix = @"ocmock_replaced_"; + +@implementation OCPartialMockObject + + +#pragma mark Mock table + +static NSMutableDictionary *mockTable; + ++ (void)initialize +{ + if(self == [OCPartialMockObject class]) + mockTable = [[NSMutableDictionary alloc] init]; +} + ++ (void)rememberPartialMock:(OCPartialMockObject *)mock forObject:(id)anObject +{ + @synchronized(mockTable) + { + [mockTable setObject:[NSValue valueWithNonretainedObject:mock] forKey:[NSValue valueWithNonretainedObject:anObject]]; + } +} + ++ (void)forgetPartialMockForObject:(id)anObject +{ + @synchronized(mockTable) + { + [mockTable removeObjectForKey:[NSValue valueWithNonretainedObject:anObject]]; + } +} + ++ (OCPartialMockObject *)existingPartialMockForObject:(id)anObject +{ + @synchronized(mockTable) + { + OCPartialMockObject *mock = [[mockTable objectForKey:[NSValue valueWithNonretainedObject:anObject]] nonretainedObjectValue]; + if(mock == nil) + [NSException raise:NSInternalInconsistencyException format:@"No partial mock for object %p", anObject]; + return mock; + } +} + + + +#pragma mark Initialisers, description, accessors, etc. + +- (id)initWithObject:(NSObject *)anObject +{ + [super initWithClass:[anObject class]]; + realObject = [anObject retain]; + [[self class] rememberPartialMock:self forObject:anObject]; + [self setupSubclassForObject:realObject]; + return self; +} + +- (void)dealloc +{ + if(realObject != nil) + [self stopMocking]; + [super dealloc]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"OCPartialMockObject[%@]", NSStringFromClass(mockedClass)]; +} + +- (NSObject *)realObject +{ + return realObject; +} + +- (void)stopMocking +{ + object_setClass(realObject, [self mockedClass]); + [realObject release]; + [[self class] forgetPartialMockForObject:realObject]; + realObject = nil; +} + + +#pragma mark Subclass management + +- (void)setupSubclassForObject:(id)anObject +{ + Class realClass = [anObject class]; + double timestamp = [NSDate timeIntervalSinceReferenceDate]; + const char *className = [[NSString stringWithFormat:@"%@-%p-%f", realClass, anObject, timestamp] UTF8String]; + Class subclass = objc_allocateClassPair(realClass, className, 0); + objc_registerClassPair(subclass); + object_setClass(anObject, subclass); + + Method myForwardInvocationMethod = class_getInstanceMethod([self class], @selector(forwardInvocationForRealObject:)); + IMP myForwardInvocationImp = method_getImplementation(myForwardInvocationMethod); + const char *forwardInvocationTypes = method_getTypeEncoding(myForwardInvocationMethod); + class_addMethod(subclass, @selector(forwardInvocation:), myForwardInvocationImp, forwardInvocationTypes); + + + Method myForwardingTargetForSelectorMethod = class_getInstanceMethod([self class], @selector(forwardingTargetForSelectorForRealObject:)); + IMP myForwardingTargetForSelectorImp = method_getImplementation(myForwardingTargetForSelectorMethod); + const char *forwardingTargetForSelectorTypes = method_getTypeEncoding(myForwardingTargetForSelectorMethod); + + IMP originalForwardingTargetForSelectorImp = [realClass instanceMethodForSelector:@selector(forwardingTargetForSelector:)]; + + class_addMethod(subclass, @selector(forwardingTargetForSelector:), myForwardingTargetForSelectorImp, forwardingTargetForSelectorTypes); + class_addMethod(subclass, @selector(forwardingTargetForSelector_Original:), originalForwardingTargetForSelectorImp, forwardingTargetForSelectorTypes); +} + +- (void)setupForwarderForSelector:(SEL)selector +{ + Class subclass = [[self realObject] class]; + Method originalMethod = class_getInstanceMethod([subclass superclass], selector); + IMP originalImp = method_getImplementation(originalMethod); + + IMP forwarderImp = [subclass instanceMethodForSelector:@selector(aMethodThatMustNotExist)]; + class_addMethod(subclass, method_getName(originalMethod), forwarderImp, method_getTypeEncoding(originalMethod)); + + SEL aliasSelector = NSSelectorFromString([OCMRealMethodAliasPrefix stringByAppendingString:NSStringFromSelector(selector)]); + class_addMethod(subclass, aliasSelector, originalImp, method_getTypeEncoding(originalMethod)); +} + +- (void)removeForwarderForSelector:(SEL)selector +{ + Class subclass = [[self realObject] class]; + SEL aliasSelector = NSSelectorFromString([OCMRealMethodAliasPrefix stringByAppendingString:NSStringFromSelector(selector)]); + Method originalMethod = class_getInstanceMethod([subclass superclass], aliasSelector); + IMP originalImp = method_getImplementation(originalMethod); + class_replaceMethod(subclass, selector, originalImp, method_getTypeEncoding(originalMethod)); +} + +// Make the compiler happy in -forwardingTargetForSelectorForRealObject: because it can't find the message… +- (id)forwardingTargetForSelector_Original:(SEL)sel +{ + return nil; +} + +- (id)forwardingTargetForSelectorForRealObject:(SEL)sel +{ + // in here "self" is a reference to the real object, not the mock + OCPartialMockObject *mock = [OCPartialMockObject existingPartialMockForObject:self]; + if ([mock handleSelector:sel]) + return self; + + return [self forwardingTargetForSelector_Original:sel]; +} + +- (void)forwardInvocationForRealObject:(NSInvocation *)anInvocation +{ + // in here "self" is a reference to the real object, not the mock + OCPartialMockObject *mock = [OCPartialMockObject existingPartialMockForObject:self]; + if([mock handleInvocation:anInvocation] == NO) + { + // if mock doesn't want to handle the invocation, maybe all expects have occurred, we forward to real object + SEL aliasSelector = NSSelectorFromString([OCMRealMethodAliasPrefix stringByAppendingString:NSStringFromSelector([anInvocation selector])]); + [anInvocation setSelector:aliasSelector]; + [anInvocation invoke]; + } +} + + + +#pragma mark Overrides + +- (id)getNewRecorder +{ + return [[[OCPartialMockRecorder alloc] initWithSignatureResolver:self] autorelease]; +} + +- (void)handleUnRecordedInvocation:(NSInvocation *)anInvocation +{ + [anInvocation invokeWithTarget:realObject]; +} + + +@end diff --git a/Pods/OCMock/Source/OCMock/OCPartialMockRecorder.h b/Pods/OCMock/Source/OCMock/OCPartialMockRecorder.h new file mode 100644 index 0000000..95ce4e6 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCPartialMockRecorder.h @@ -0,0 +1,12 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "OCMockRecorder.h" + +@interface OCPartialMockRecorder : OCMockRecorder +{ +} + +@end diff --git a/Pods/OCMock/Source/OCMock/OCPartialMockRecorder.m b/Pods/OCMock/Source/OCMock/OCPartialMockRecorder.m new file mode 100644 index 0000000..f40cb7c --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCPartialMockRecorder.m @@ -0,0 +1,27 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2009-2010 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import "OCPartialMockObject.h" +#import "OCMRealObjectForwarder.h" +#import "OCPartialMockRecorder.h" + + +@implementation OCPartialMockRecorder + +- (id)andForwardToRealObject +{ + [invocationHandlers addObject:[[[OCMRealObjectForwarder alloc] init] autorelease]]; + return self; +} + + +- (void)forwardInvocation:(NSInvocation *)anInvocation +{ + [super forwardInvocation:anInvocation]; + // not as clean as I'd wish... + [(OCPartialMockObject *)signatureResolver setupForwarderForSelector:[anInvocation selector]]; +} + +@end diff --git a/Pods/OCMock/Source/OCMock/OCProtocolMockObject.h b/Pods/OCMock/Source/OCMock/OCProtocolMockObject.h new file mode 100644 index 0000000..88f3229 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCProtocolMockObject.h @@ -0,0 +1,16 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2005-2008 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import + +@interface OCProtocolMockObject : OCMockObject +{ + Protocol *mockedProtocol; +} + +- (id)initWithProtocol:(Protocol *)aProtocol; + +@end + diff --git a/Pods/OCMock/Source/OCMock/OCProtocolMockObject.m b/Pods/OCMock/Source/OCMock/OCProtocolMockObject.m new file mode 100644 index 0000000..19e25e8 --- /dev/null +++ b/Pods/OCMock/Source/OCMock/OCProtocolMockObject.m @@ -0,0 +1,53 @@ +//--------------------------------------------------------------------------------------- +// $Id$ +// Copyright (c) 2005-2008 by Mulle Kybernetik. See License file for details. +//--------------------------------------------------------------------------------------- + +#import +#import "NSMethodSignature+OCMAdditions.h" +#import "OCProtocolMockObject.h" + +@implementation OCProtocolMockObject + +#pragma mark Initialisers, description, accessors, etc. + +- (id)initWithProtocol:(Protocol *)aProtocol +{ + [super init]; + mockedProtocol = aProtocol; + return self; +} + +- (NSString *)description +{ + const char* name = protocol_getName(mockedProtocol); + return [NSString stringWithFormat:@"OCMockObject[%s]", name]; +} + +#pragma mark Proxy API + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector +{ + struct objc_method_description methodDescription = protocol_getMethodDescription(mockedProtocol, aSelector, YES, YES); + if(methodDescription.name == NULL) + { + methodDescription = protocol_getMethodDescription(mockedProtocol, aSelector, NO, YES); + } + if(methodDescription.name == NULL) + { + return nil; + } + return [NSMethodSignature signatureWithObjCTypes:methodDescription.types]; +} + +- (BOOL)conformsToProtocol:(Protocol *)aProtocol +{ + return protocol_conformsToProtocol(mockedProtocol, aProtocol); +} + +- (BOOL)respondsToSelector:(SEL)selector +{ + return ([self methodSignatureForSelector:selector] != nil); +} + +@end diff --git a/Pods/Pods-CocoaLumberjack-Private.xcconfig b/Pods/Pods-CocoaLumberjack-Private.xcconfig new file mode 100644 index 0000000..e7d8b9d --- /dev/null +++ b/Pods/Pods-CocoaLumberjack-Private.xcconfig @@ -0,0 +1,5 @@ +#include "Pods-CocoaLumberjack.xcconfig" +GCC_PREPROCESSOR_DEFINITIONS = COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/BuildHeaders" "${PODS_ROOT}/BuildHeaders/CocoaLumberjack" "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/CocoaLumberjack" "${PODS_ROOT}/Headers/Kiwi" "${PODS_ROOT}/Headers/OCMock" "${PODS_ROOT}/Headers/VLBFoundation" +OTHER_LDFLAGS = -ObjC +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/Pods/Pods-CocoaLumberjack-dummy.m b/Pods/Pods-CocoaLumberjack-dummy.m new file mode 100644 index 0000000..57d9274 --- /dev/null +++ b/Pods/Pods-CocoaLumberjack-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_CocoaLumberjack : NSObject +@end +@implementation PodsDummy_Pods_CocoaLumberjack +@end diff --git a/Pods/Pods-CocoaLumberjack-prefix.pch b/Pods/Pods-CocoaLumberjack-prefix.pch new file mode 100644 index 0000000..95cf11d --- /dev/null +++ b/Pods/Pods-CocoaLumberjack-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-environment.h" diff --git a/Pods/Pods-CocoaLumberjack.xcconfig b/Pods/Pods-CocoaLumberjack.xcconfig new file mode 100644 index 0000000..e69de29 diff --git a/Pods/Pods-UnitTests-CocoaLumberjack-Private.xcconfig b/Pods/Pods-UnitTests-CocoaLumberjack-Private.xcconfig new file mode 100644 index 0000000..7b02670 --- /dev/null +++ b/Pods/Pods-UnitTests-CocoaLumberjack-Private.xcconfig @@ -0,0 +1,5 @@ +#include "Pods-UnitTests-CocoaLumberjack.xcconfig" +GCC_PREPROCESSOR_DEFINITIONS = COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/BuildHeaders" "${PODS_ROOT}/BuildHeaders/CocoaLumberjack" "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/CocoaLumberjack" "${PODS_ROOT}/Headers/Kiwi" "${PODS_ROOT}/Headers/OCMock" "${PODS_ROOT}/Headers/VLBFoundation" +OTHER_LDFLAGS = -ObjC +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/Pods/Pods-UnitTests-CocoaLumberjack-dummy.m b/Pods/Pods-UnitTests-CocoaLumberjack-dummy.m new file mode 100644 index 0000000..39460d6 --- /dev/null +++ b/Pods/Pods-UnitTests-CocoaLumberjack-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_UnitTests_CocoaLumberjack : NSObject +@end +@implementation PodsDummy_Pods_UnitTests_CocoaLumberjack +@end diff --git a/Pods/Pods-UnitTests-CocoaLumberjack-prefix.pch b/Pods/Pods-UnitTests-CocoaLumberjack-prefix.pch new file mode 100644 index 0000000..d54854a --- /dev/null +++ b/Pods/Pods-UnitTests-CocoaLumberjack-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-UnitTests-environment.h" diff --git a/Pods/Pods-UnitTests-CocoaLumberjack.xcconfig b/Pods/Pods-UnitTests-CocoaLumberjack.xcconfig new file mode 100644 index 0000000..e69de29 diff --git a/Pods/Pods-UnitTests-Kiwi-Private.xcconfig b/Pods/Pods-UnitTests-Kiwi-Private.xcconfig new file mode 100644 index 0000000..8cac2da --- /dev/null +++ b/Pods/Pods-UnitTests-Kiwi-Private.xcconfig @@ -0,0 +1,6 @@ +#include "Pods-UnitTests-Kiwi.xcconfig" +FRAMEWORK_SEARCH_PATHS = ${PODS_UNITTESTS_KIWI_FRAMEWORK_SEARCH_PATHS} +GCC_PREPROCESSOR_DEFINITIONS = COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/BuildHeaders" "${PODS_ROOT}/BuildHeaders/Kiwi" "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/CocoaLumberjack" "${PODS_ROOT}/Headers/Kiwi" "${PODS_ROOT}/Headers/OCMock" "${PODS_ROOT}/Headers/VLBFoundation" +OTHER_LDFLAGS = -ObjC ${PODS_UNITTESTS_KIWI_OTHER_LDFLAGS} +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/Pods/Pods-UnitTests-Kiwi-dummy.m b/Pods/Pods-UnitTests-Kiwi-dummy.m new file mode 100644 index 0000000..283b687 --- /dev/null +++ b/Pods/Pods-UnitTests-Kiwi-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_UnitTests_Kiwi : NSObject +@end +@implementation PodsDummy_Pods_UnitTests_Kiwi +@end diff --git a/Pods/Pods-UnitTests-Kiwi-prefix.pch b/Pods/Pods-UnitTests-Kiwi-prefix.pch new file mode 100644 index 0000000..d54854a --- /dev/null +++ b/Pods/Pods-UnitTests-Kiwi-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-UnitTests-environment.h" diff --git a/Pods/Pods-UnitTests-Kiwi.xcconfig b/Pods/Pods-UnitTests-Kiwi.xcconfig new file mode 100644 index 0000000..ce5f496 --- /dev/null +++ b/Pods/Pods-UnitTests-Kiwi.xcconfig @@ -0,0 +1,2 @@ +PODS_UNITTESTS_KIWI_FRAMEWORK_SEARCH_PATHS = $(inherited) "$(SDKROOT)/Developer/Library/Frameworks" "$(DEVELOPER_LIBRARY_DIR)/Frameworks" +PODS_UNITTESTS_KIWI_OTHER_LDFLAGS = -framework SenTestingKit \ No newline at end of file diff --git a/Pods/Pods-UnitTests-OCMock-Private.xcconfig b/Pods/Pods-UnitTests-OCMock-Private.xcconfig new file mode 100644 index 0000000..5916bec --- /dev/null +++ b/Pods/Pods-UnitTests-OCMock-Private.xcconfig @@ -0,0 +1,5 @@ +#include "Pods-UnitTests-OCMock.xcconfig" +GCC_PREPROCESSOR_DEFINITIONS = COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/BuildHeaders" "${PODS_ROOT}/BuildHeaders/OCMock" "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/CocoaLumberjack" "${PODS_ROOT}/Headers/Kiwi" "${PODS_ROOT}/Headers/OCMock" "${PODS_ROOT}/Headers/VLBFoundation" +OTHER_LDFLAGS = -ObjC +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/Pods/Pods-UnitTests-OCMock-dummy.m b/Pods/Pods-UnitTests-OCMock-dummy.m new file mode 100644 index 0000000..4360d34 --- /dev/null +++ b/Pods/Pods-UnitTests-OCMock-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_UnitTests_OCMock : NSObject +@end +@implementation PodsDummy_Pods_UnitTests_OCMock +@end diff --git a/Pods/Pods-UnitTests-OCMock-prefix.pch b/Pods/Pods-UnitTests-OCMock-prefix.pch new file mode 100644 index 0000000..d54854a --- /dev/null +++ b/Pods/Pods-UnitTests-OCMock-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-UnitTests-environment.h" diff --git a/Pods/Pods-UnitTests-OCMock.xcconfig b/Pods/Pods-UnitTests-OCMock.xcconfig new file mode 100644 index 0000000..e69de29 diff --git a/Pods/Pods-UnitTests-VLBFoundation-Private.xcconfig b/Pods/Pods-UnitTests-VLBFoundation-Private.xcconfig new file mode 100644 index 0000000..457b190 --- /dev/null +++ b/Pods/Pods-UnitTests-VLBFoundation-Private.xcconfig @@ -0,0 +1,5 @@ +#include "Pods-UnitTests-VLBFoundation.xcconfig" +GCC_PREPROCESSOR_DEFINITIONS = COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/BuildHeaders" "${PODS_ROOT}/BuildHeaders/VLBFoundation" "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/CocoaLumberjack" "${PODS_ROOT}/Headers/Kiwi" "${PODS_ROOT}/Headers/OCMock" "${PODS_ROOT}/Headers/VLBFoundation" +OTHER_LDFLAGS = -ObjC ${PODS_UNITTESTS_VLBFOUNDATION_OTHER_LDFLAGS} +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/Pods/Pods-UnitTests-VLBFoundation-dummy.m b/Pods/Pods-UnitTests-VLBFoundation-dummy.m new file mode 100644 index 0000000..a13fa5e --- /dev/null +++ b/Pods/Pods-UnitTests-VLBFoundation-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_UnitTests_VLBFoundation : NSObject +@end +@implementation PodsDummy_Pods_UnitTests_VLBFoundation +@end diff --git a/Pods/Pods-UnitTests-VLBFoundation-prefix.pch b/Pods/Pods-UnitTests-VLBFoundation-prefix.pch new file mode 100644 index 0000000..d54854a --- /dev/null +++ b/Pods/Pods-UnitTests-VLBFoundation-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-UnitTests-environment.h" diff --git a/Pods/Pods-UnitTests-VLBFoundation.xcconfig b/Pods/Pods-UnitTests-VLBFoundation.xcconfig new file mode 100644 index 0000000..6205932 --- /dev/null +++ b/Pods/Pods-UnitTests-VLBFoundation.xcconfig @@ -0,0 +1 @@ +PODS_UNITTESTS_VLBFOUNDATION_OTHER_LDFLAGS = -framework Foundation \ No newline at end of file diff --git a/Pods/Pods-UnitTests-acknowledgements.markdown b/Pods/Pods-UnitTests-acknowledgements.markdown new file mode 100644 index 0000000..dba2576 --- /dev/null +++ b/Pods/Pods-UnitTests-acknowledgements.markdown @@ -0,0 +1,86 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## CocoaLumberjack + +Software License Agreement (BSD License) + +Copyright (c) 2010, Deusty, LLC +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Neither the name of Deusty nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Deusty, LLC. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +## Kiwi + +Copyright (c) 2010, Allen Ding +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of Allen Ding nor the names of any contributors may be +used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +## OCMock + +Copyright (c) 2004-2013 by Mulle Kybernetik. All rights reserved. + + Permission to use, copy, modify and distribute this software and its documentation + is hereby granted, provided that both the copyright notice and this permission + notice appear in all copies of the software, derivative works or modified versions, + and any portions thereof, and that both notices appear in supporting documentation, + and that credit is given to Mulle Kybernetik in all documents and publicity + pertaining to direct or indirect use of this code or its derivatives. + + THIS IS EXPERIMENTAL SOFTWARE AND IT IS KNOWN TO HAVE BUGS, SOME OF WHICH MAY HAVE + SERIOUS CONSEQUENCES. THE COPYRIGHT HOLDER ALLOWS FREE USE OF THIS SOFTWARE IN ITS + "AS IS" CONDITION. THE COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY + DAMAGES WHATSOEVER RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE + OR OF ANY DERIVATIVE WORK. + + +## VLBFoundation + +VLBFoundation published under the MIT license: + +Copyright (C) 2013, www.verylargebox.com + +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. + +Generated by CocoaPods - http://cocoapods.org diff --git a/Pods/Pods-UnitTests-acknowledgements.plist b/Pods/Pods-UnitTests-acknowledgements.plist new file mode 100644 index 0000000..fd0847e --- /dev/null +++ b/Pods/Pods-UnitTests-acknowledgements.plist @@ -0,0 +1,128 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Software License Agreement (BSD License) + +Copyright (c) 2010, Deusty, LLC +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Neither the name of Deusty nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Deusty, LLC. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + Title + CocoaLumberjack + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2010, Allen Ding +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of Allen Ding nor the names of any contributors may be +used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Title + Kiwi + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2004-2013 by Mulle Kybernetik. All rights reserved. + + Permission to use, copy, modify and distribute this software and its documentation + is hereby granted, provided that both the copyright notice and this permission + notice appear in all copies of the software, derivative works or modified versions, + and any portions thereof, and that both notices appear in supporting documentation, + and that credit is given to Mulle Kybernetik in all documents and publicity + pertaining to direct or indirect use of this code or its derivatives. + + THIS IS EXPERIMENTAL SOFTWARE AND IT IS KNOWN TO HAVE BUGS, SOME OF WHICH MAY HAVE + SERIOUS CONSEQUENCES. THE COPYRIGHT HOLDER ALLOWS FREE USE OF THIS SOFTWARE IN ITS + "AS IS" CONDITION. THE COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY + DAMAGES WHATSOEVER RESULTING DIRECTLY OR INDIRECTLY FROM THE USE OF THIS SOFTWARE + OR OF ANY DERIVATIVE WORK. + + Title + OCMock + Type + PSGroupSpecifier + + + FooterText + VLBFoundation published under the MIT license: + +Copyright (C) 2013, www.verylargebox.com + +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. + + Title + VLBFoundation + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - http://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Pods/Pods-UnitTests-dummy.m b/Pods/Pods-UnitTests-dummy.m new file mode 100644 index 0000000..21f7e28 --- /dev/null +++ b/Pods/Pods-UnitTests-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_UnitTests : NSObject +@end +@implementation PodsDummy_Pods_UnitTests +@end diff --git a/Pods/Pods-UnitTests-environment.h b/Pods/Pods-UnitTests-environment.h new file mode 100644 index 0000000..a50aaf0 --- /dev/null +++ b/Pods/Pods-UnitTests-environment.h @@ -0,0 +1,32 @@ + +// To check if a library is compiled with CocoaPods you +// can use the `COCOAPODS` macro definition which is +// defined in the xcconfigs so it is available in +// headers also when they are imported in the client +// project. + + +// CocoaLumberjack +#define COCOAPODS_POD_AVAILABLE_CocoaLumberjack +#define COCOAPODS_VERSION_MAJOR_CocoaLumberjack 1 +#define COCOAPODS_VERSION_MINOR_CocoaLumberjack 6 +#define COCOAPODS_VERSION_PATCH_CocoaLumberjack 2 + +// Kiwi +#define COCOAPODS_POD_AVAILABLE_Kiwi +#define COCOAPODS_VERSION_MAJOR_Kiwi 2 +#define COCOAPODS_VERSION_MINOR_Kiwi 0 +#define COCOAPODS_VERSION_PATCH_Kiwi 6 + +// OCMock +#define COCOAPODS_POD_AVAILABLE_OCMock +#define COCOAPODS_VERSION_MAJOR_OCMock 2 +#define COCOAPODS_VERSION_MINOR_OCMock 1 +#define COCOAPODS_VERSION_PATCH_OCMock 1 + +// VLBFoundation +#define COCOAPODS_POD_AVAILABLE_VLBFoundation +#define COCOAPODS_VERSION_MAJOR_VLBFoundation 1 +#define COCOAPODS_VERSION_MINOR_VLBFoundation 0 +#define COCOAPODS_VERSION_PATCH_VLBFoundation 0 + diff --git a/Pods/Pods-UnitTests-resources.sh b/Pods/Pods-UnitTests-resources.sh new file mode 100755 index 0000000..39c2549 --- /dev/null +++ b/Pods/Pods-UnitTests-resources.sh @@ -0,0 +1,68 @@ +#!/bin/sh +set -e + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +install_resource() +{ + case $1 in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" + ;; + *.framework) + echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" + xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" + xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" + ;; + *.xcassets) + ;; + /*) + echo "$1" + echo "$1" >> "$RESOURCES_TO_COPY" + ;; + *) + echo "${PODS_ROOT}/$1" + echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]]; then + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ `xcrun --find actool` ] && [ `find . -name '*.xcassets' | wc -l` -ne 0 ] +then + case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; + esac + find "${PWD}" -name "*.xcassets" -print0 | xargs -0 actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi diff --git a/Pods/Pods-UnitTests.xcconfig b/Pods/Pods-UnitTests.xcconfig new file mode 100644 index 0000000..11a6728 --- /dev/null +++ b/Pods/Pods-UnitTests.xcconfig @@ -0,0 +1,6 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "$(SDKROOT)/Developer/Library/Frameworks" "$(DEVELOPER_LIBRARY_DIR)/Frameworks" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/CocoaLumberjack" "${PODS_ROOT}/Headers/Kiwi" "${PODS_ROOT}/Headers/OCMock" "${PODS_ROOT}/Headers/VLBFoundation" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers" -isystem "${PODS_ROOT}/Headers/CocoaLumberjack" -isystem "${PODS_ROOT}/Headers/Kiwi" -isystem "${PODS_ROOT}/Headers/OCMock" -isystem "${PODS_ROOT}/Headers/VLBFoundation" +OTHER_LDFLAGS = -ObjC -framework Foundation -framework SenTestingKit +PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/Pods/Pods-VLBFoundation-Private.xcconfig b/Pods/Pods-VLBFoundation-Private.xcconfig new file mode 100644 index 0000000..9ebc054 --- /dev/null +++ b/Pods/Pods-VLBFoundation-Private.xcconfig @@ -0,0 +1,5 @@ +#include "Pods-VLBFoundation.xcconfig" +GCC_PREPROCESSOR_DEFINITIONS = COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/BuildHeaders" "${PODS_ROOT}/BuildHeaders/VLBFoundation" "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/CocoaLumberjack" "${PODS_ROOT}/Headers/Kiwi" "${PODS_ROOT}/Headers/OCMock" "${PODS_ROOT}/Headers/VLBFoundation" +OTHER_LDFLAGS = -ObjC ${PODS_VLBFOUNDATION_OTHER_LDFLAGS} +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/Pods/Pods-VLBFoundation-dummy.m b/Pods/Pods-VLBFoundation-dummy.m new file mode 100644 index 0000000..187d02f --- /dev/null +++ b/Pods/Pods-VLBFoundation-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_VLBFoundation : NSObject +@end +@implementation PodsDummy_Pods_VLBFoundation +@end diff --git a/Pods/Pods-VLBFoundation-prefix.pch b/Pods/Pods-VLBFoundation-prefix.pch new file mode 100644 index 0000000..95cf11d --- /dev/null +++ b/Pods/Pods-VLBFoundation-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-environment.h" diff --git a/Pods/Pods-VLBFoundation.xcconfig b/Pods/Pods-VLBFoundation.xcconfig new file mode 100644 index 0000000..42c8b38 --- /dev/null +++ b/Pods/Pods-VLBFoundation.xcconfig @@ -0,0 +1 @@ +PODS_VLBFOUNDATION_OTHER_LDFLAGS = -framework Foundation \ No newline at end of file diff --git a/Pods/Pods-acknowledgements.markdown b/Pods/Pods-acknowledgements.markdown new file mode 100644 index 0000000..d33105b --- /dev/null +++ b/Pods/Pods-acknowledgements.markdown @@ -0,0 +1,37 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## CocoaLumberjack + +Software License Agreement (BSD License) + +Copyright (c) 2010, Deusty, LLC +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Neither the name of Deusty nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Deusty, LLC. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +## VLBFoundation + +VLBFoundation published under the MIT license: + +Copyright (C) 2013, www.verylargebox.com + +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. + +Generated by CocoaPods - http://cocoapods.org diff --git a/Pods/Pods-acknowledgements.plist b/Pods/Pods-acknowledgements.plist new file mode 100644 index 0000000..465202d --- /dev/null +++ b/Pods/Pods-acknowledgements.plist @@ -0,0 +1,71 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Software License Agreement (BSD License) + +Copyright (c) 2010, Deusty, LLC +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Neither the name of Deusty nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Deusty, LLC. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + Title + CocoaLumberjack + Type + PSGroupSpecifier + + + FooterText + VLBFoundation published under the MIT license: + +Copyright (C) 2013, www.verylargebox.com + +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. + + Title + VLBFoundation + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - http://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Pods/Pods-dummy.m b/Pods/Pods-dummy.m new file mode 100644 index 0000000..ade64bd --- /dev/null +++ b/Pods/Pods-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods : NSObject +@end +@implementation PodsDummy_Pods +@end diff --git a/Pods/Pods-environment.h b/Pods/Pods-environment.h new file mode 100644 index 0000000..553599b --- /dev/null +++ b/Pods/Pods-environment.h @@ -0,0 +1,20 @@ + +// To check if a library is compiled with CocoaPods you +// can use the `COCOAPODS` macro definition which is +// defined in the xcconfigs so it is available in +// headers also when they are imported in the client +// project. + + +// CocoaLumberjack +#define COCOAPODS_POD_AVAILABLE_CocoaLumberjack +#define COCOAPODS_VERSION_MAJOR_CocoaLumberjack 1 +#define COCOAPODS_VERSION_MINOR_CocoaLumberjack 6 +#define COCOAPODS_VERSION_PATCH_CocoaLumberjack 2 + +// VLBFoundation +#define COCOAPODS_POD_AVAILABLE_VLBFoundation +#define COCOAPODS_VERSION_MAJOR_VLBFoundation 1 +#define COCOAPODS_VERSION_MINOR_VLBFoundation 0 +#define COCOAPODS_VERSION_PATCH_VLBFoundation 0 + diff --git a/Pods/Pods-resources.sh b/Pods/Pods-resources.sh new file mode 100755 index 0000000..39c2549 --- /dev/null +++ b/Pods/Pods-resources.sh @@ -0,0 +1,68 @@ +#!/bin/sh +set -e + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +install_resource() +{ + case $1 in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" + ;; + *.framework) + echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" + xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" + xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" + ;; + *.xcassets) + ;; + /*) + echo "$1" + echo "$1" >> "$RESOURCES_TO_COPY" + ;; + *) + echo "${PODS_ROOT}/$1" + echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]]; then + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ `xcrun --find actool` ] && [ `find . -name '*.xcassets' | wc -l` -ne 0 ] +then + case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; + esac + find "${PWD}" -name "*.xcassets" -print0 | xargs -0 actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi diff --git a/Pods/Pods.xcconfig b/Pods/Pods.xcconfig new file mode 100644 index 0000000..e9e172d --- /dev/null +++ b/Pods/Pods.xcconfig @@ -0,0 +1,5 @@ +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers" "${PODS_ROOT}/Headers/CocoaLumberjack" "${PODS_ROOT}/Headers/Kiwi" "${PODS_ROOT}/Headers/OCMock" "${PODS_ROOT}/Headers/VLBFoundation" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers" -isystem "${PODS_ROOT}/Headers/CocoaLumberjack" -isystem "${PODS_ROOT}/Headers/Kiwi" -isystem "${PODS_ROOT}/Headers/OCMock" -isystem "${PODS_ROOT}/Headers/VLBFoundation" +OTHER_LDFLAGS = -ObjC -framework Foundation +PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..622d9af --- /dev/null +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,8474 @@ + + + + + archiveVersion + 1 + classes + + objectVersion + 46 + objects + + 0033BF1124E544778C678C61 + + fileRef + 88897762E1DB42CEA21B9073 + isa + PBXBuildFile + + 00A2B3C5871A43CB8A372CFE + + buildConfigurationList + A83FC1D68B914EEF89759EB4 + buildPhases + + 822FB9DF736B4994A406818D + A434C123AC6C498CB8D0B058 + 949C61BABDA34BA0BC879DB5 + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-VLBFoundation + productName + Pods-VLBFoundation + productReference + D1A6FF6D7EF74D9BBC91FA36 + productType + com.apple.product-type.library.static + + 00FAA90E6D7F43118C0F6DB5 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + DDLog.m + path + Lumberjack/DDLog.m + sourceTree + <group> + + 012E35389FD046CBBA9A36C8 + + isa + PBXTargetDependency + target + E1AB1C02919A47998D69B21A + targetProxy + 644D7BA94C8043BAB641AA59 + + 016C2E3AA65F4712BDF420B9 + + fileRef + CFA482AD6223477C9CA05509 + isa + PBXBuildFile + + 01AB5659FE9241038689FD57 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWRaiseMatcher.m + path + Classes/KWRaiseMatcher.m + sourceTree + <group> + + 0216198B471E494A86990A72 + + fileRef + DCA2DDE2BEBA42CEAEFABD39 + isa + PBXBuildFile + + 02528A11FCD848F3B24E24B3 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + DispatchQueueLogFormatter.h + path + Lumberjack/Extensions/DispatchQueueLogFormatter.h + sourceTree + <group> + + 0267876190534E6F88627596 + + buildConfigurationList + C5B8B69668BF4B618EC9C62A + buildPhases + + E5D3A1725DA546DE8CB2CB6C + 7EAF9B464585471CA1AF99F0 + + buildRules + + dependencies + + F405A4D4E40243D8A0CBDA6C + 442439254A8143B695827035 + + isa + PBXNativeTarget + name + Pods + productName + Pods + productReference + 16C5CB78443C4C0FBEF8A89B + productType + com.apple.product-type.library.static + + 035CDD9A9AD04611A124A0D2 + + fileRef + EFC06CED3626490FA4FC7F3D + isa + PBXBuildFile + + 0401DC63550F43A9B4EE19C1 + + buildConfigurationList + D647D76E4297401A80D267B4 + buildPhases + + BB35A75DC401410A8C9F4747 + CFC493FD5DA04B7FB6ACF593 + 072E5329CC0B4B02995C997A + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-UnitTests-Kiwi + productName + Pods-UnitTests-Kiwi + productReference + 06D9B225A8504500AE75D71B + productType + com.apple.product-type.library.static + + 045FA1F483DD43CD82DF2D28 + + baseConfigurationReference + 7EE630493F6F427D9D2DB13F + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Pods-UnitTests-CocoaLumberjack-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 0467ED54EFFA488EBA9FCA62 + + buildConfigurations + + E7CD5F673166423BA57DDE54 + B4E201BAA95E42DDBF943779 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 04B9DAB058324D39BD5B1C4A + + fileRef + 6D5594E813F4416D99CB8675 + isa + PBXBuildFile + + 04E5E23C376041E3B37F0188 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KiwiConfiguration.h + path + Classes/KiwiConfiguration.h + sourceTree + <group> + + 04F3958022C74505A00C6060 + + fileRef + 3D2923B995604AE6A5952605 + isa + PBXBuildFile + + 0581590B29A141AD9F08CA82 + + fileRef + 7069CC77FB954200A2A00B4B + isa + PBXBuildFile + + 0613CEDF264D498092B71EA5 + + fileRef + 9C8E45406A7A424A8CEABD89 + isa + PBXBuildFile + + 06B83EC8C24A41C5AF77F234 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWStub.m + path + Classes/KWStub.m + sourceTree + <group> + + 06CBDD05B623419B99097EC3 + + fileRef + 16B5F03C94EE426D90A3F9FF + isa + PBXBuildFile + + 06D9B225A8504500AE75D71B + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-UnitTests-Kiwi.a + sourceTree + BUILT_PRODUCTS_DIR + + 071234FFEDA54F6D9A776E83 + + containerPortal + 62298A1970D14909914BA53E + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + D781C4F75B4C464486E9569A + remoteInfo + Pods-UnitTests-OCMock + + 072E5329CC0B4B02995C997A + + buildActionMask + 2147483647 + files + + A57BA61462AC44C7B2E3F37E + AA298D4D3A094E1298FDBDD9 + 653CA191EE604B35A5402F24 + A2E34A0DDD984239B91E77E1 + FE62CD8148264AA8B096BE6E + A9C8E4FF4CF0464BA192A670 + 7F0CBCE7D5B4477BBEA737A2 + 52F5B478B05641E180754C5F + D4C6D94092D54C88AF8131C2 + B2F72827D1F24CB194979357 + CB6BEEC0E9BD4ED28F7004DF + C1A22CDEFF4A4FA5BF6D4D9A + 53E23F9AB2DF4661A1FCA241 + 8400A7F1224240E29992CC57 + 41737AD95B5C4855A1067354 + 4F33FC8D5C1B44FD98ACEEF2 + A8E9F7217400459D93310D05 + DB954B5437E546248B77980F + 0581590B29A141AD9F08CA82 + E667A92389F4469EB9D01ED2 + 38F5882012774F78A850E779 + 5911A76CD355431DA1A8E296 + E6C418B02CD942A88F4DDA30 + 87DA9DF4237042BBB4466800 + F4B8D3BA7387410E867E7931 + BD4A3296D70245CC97613D24 + AFE2E61751E74D809B4A342F + 144DFD275D37426CBC7E8601 + 81F9605E59BD4591B177662F + DD6941E36EC5402CB64E633F + F247ABE403DD429D82167C00 + CE6DF279FFEB41B0963B9461 + A347E66EF2FC41E1AD9E65E7 + 654F1BE6A7E6425491C142C6 + BD819B61443E48AEBBE4E2F1 + 89AE2A8C87A54F01A4ECBEEE + 167A80B2C1E64278996F1414 + 11E23A99AFB1487B90C32881 + B9CC3FA07BCD4B108AB46F85 + 6B0FC044C90F4560A08C65E4 + 7A41C7A2AC7E4255B817F1E9 + BE31C86F7819483AB2900902 + 8C52C0EED6514C89A538E344 + FCEE0B9AD0A74220A5208019 + 9D9272C5137B424B8B2D41E2 + 7949794DDFBC4E77B3E6F854 + F297C38516F74F8BAA70FA0B + 9878EAC5217D41F087376365 + 2916FAF89C484577B57F339B + 9E57C8D2B4B54CF880860847 + 86CB11C36367440EBA1F6AEC + 1C8BAEBB7B19435096D482AB + 8B4C6145789947EDADDF415C + F75E20DA865A407B8ED33F3B + 106A17C0E28842DFA7470AF7 + A17550E6131D480E83D974D7 + 1B1DD0F7FFBC42A9AB08D118 + 8F78AA1EFC044065AF906C64 + 841AB2C9CB844FAC881A09B5 + A175118AB1BC4136B9B51773 + 510B82739D814079854F07D9 + 9670F77F354A47A28AC129D7 + FC8C70D60B824E1D902A19DC + A3CE512AE507454A804A88AD + F687972FFD504AB2BAFA29FC + 570913C8640E49F2BCAAFADE + 21671E8C8DB145FF8538EE31 + CB87B075B57249A2A096F2B5 + 0C248D3145BE430DB5178D44 + 57A245D88DA54A0B958C4CBE + 0C2B81B5A2DE405EAD3A3BD5 + FEF48B68DFE1460EA203723C + 0613CEDF264D498092B71EA5 + FD06F2408A4C4D39A461BF5B + C66D3E39ABB14FC5A5B92677 + 3750105DF8AD4BF2B3716D7F + F8842EAF9B4747C08FCCC091 + E048C3A41040472FA0883D07 + 8F160958E4194FE28150CC87 + 98162B13CAA44893A9AAAE03 + 19FA7AB62595489BB3E1A524 + 85241210B56346FDA69273AF + E199E308ABE749A78EF963D1 + 4CC083D06092465C8BE10329 + C2A2FD87F77042FEB633C86A + C8678C205C6640ACA84AE954 + BAB79777092D448D9A29CD1D + C7B82C6600AE449085458D1F + D149EAB9D30949B9A04EF6CC + FA68A876112A4C58B012FBD3 + 20F3EBF0D3A44BB983B30C05 + 7C27E1A75D7A4310BC64A5A0 + B0035F552DBC4252AF63B1A9 + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 084647FB89B5417AB6D97FB5 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text + path + Pods-acknowledgements.markdown + sourceTree + <group> + + 089BBF6BAA574DB5A8EBCE79 + + fileRef + 4F3898891BE042D398E93C6A + isa + PBXBuildFile + + 09A2DE10B39E4336AAA67347 + + fileRef + 23F7FB448051463C800AEF7E + isa + PBXBuildFile + + 0AA7A9A4A11B42F585A2077C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-UnitTests-dummy.m + sourceTree + <group> + + 0AE4CB00CF524C83BE349517 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-UnitTests-OCMock.xcconfig + sourceTree + <group> + + 0C248D3145BE430DB5178D44 + + fileRef + BA321641026C451489493E5B + isa + PBXBuildFile + + 0C2B81B5A2DE405EAD3A3BD5 + + fileRef + 6DFD05ECE30F4FFBB527C526 + isa + PBXBuildFile + + 0C428E5F278A4B24A61CAAF2 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-UnitTests-OCMock.a + sourceTree + BUILT_PRODUCTS_DIR + + 0CC73CDDBBD3430F9D035DC6 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCObserverMockObject.h + path + Source/OCMock/OCObserverMockObject.h + sourceTree + <group> + + 0D0345D4FDFD49DA82D1BD63 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWConformToProtocolMatcher.m + path + Classes/KWConformToProtocolMatcher.m + sourceTree + <group> + + 0D0984F7EC6C43E198F39846 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBeNilMatcher.h + path + Classes/KWBeNilMatcher.h + sourceTree + <group> + + 0E2606EBFEBB4D0D97797E65 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWObjCUtilities.m + path + Classes/KWObjCUtilities.m + sourceTree + <group> + + 0EB28603707245AF8906432F + + buildActionMask + 2147483647 + files + + 9F36157ED9EA47AC9BB478CC + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 0F06C4E43AD649D3A7B847B8 + + buildActionMask + 2147483647 + files + + 2E9A15B0DA714DC7A8F18E7F + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 0FBA129B61B4442A9602F6A9 + + buildConfigurationList + 729D82C1F76C455BADF94806 + buildPhases + + B87E4FBAF54B42F5B18B7F3B + 9412EB7635374BA39766BDF2 + 76B4DF0E3A96480498A15140 + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-UnitTests-CocoaLumberjack + productName + Pods-UnitTests-CocoaLumberjack + productReference + 3D2923B995604AE6A5952605 + productType + com.apple.product-type.library.static + + 10358EC2BDF74CF6B79B62A1 + + fileRef + 2AAC7814C9294FB8B9512F4C + isa + PBXBuildFile + + 106A17C0E28842DFA7470AF7 + + fileRef + 42C18AD8A8DE414FA6828FFA + isa + PBXBuildFile + + 10997194309B42ABB7178A8A + + fileRef + 23D6199981254F8688C3CC51 + isa + PBXBuildFile + + 10A11E402D6449C988C39EFA + + fileRef + A68489497CC14845ABD4EC56 + isa + PBXBuildFile + + 10FCA8A2A5754B408CAAF626 + + fileRef + C91150BAB9AD4C16B993CE7B + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + 110175426B9142ACB1DAA177 + + fileRef + DD2691DC782C4F2A849C3DB6 + isa + PBXBuildFile + + 119C5659662144F4A82E1C32 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBeforeAllNode.h + path + Classes/KWBeforeAllNode.h + sourceTree + <group> + + 11E23A99AFB1487B90C32881 + + fileRef + 663FAB73084240D782144B3E + isa + PBXBuildFile + + 122CE66D14584BF99DF20A18 + + fileRef + 3CDC72F8A3544377834F5A1A + isa + PBXBuildFile + + 123DED21C2674E1290469787 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWExampleGroupBuilder.m + path + Classes/KWExampleGroupBuilder.m + sourceTree + <group> + + 1242FCF848B5427784903A47 + + baseConfigurationReference + A75F896BEEDB4B5A95C16B05 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 126D2A6759D94F56B85C7859 + + fileRef + 83C907C51842492A81A95A6F + isa + PBXBuildFile + + 1301DC1B53354DF8B1473DCD + + fileRef + DC38F59C0C7A4E7292843699 + isa + PBXBuildFile + + 133681FAC86544B496860F81 + + fileRef + 22CD521A310547CD95E3E7F2 + isa + PBXBuildFile + + 144DFD275D37426CBC7E8601 + + fileRef + A4856330EE8044F79DC17088 + isa + PBXBuildFile + + 1452A8B9B8CB454A8A583A7C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWNull.m + path + Classes/KWNull.m + sourceTree + <group> + + 151056C67969419AA3769211 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWProbe.h + path + Classes/KWProbe.h + sourceTree + <group> + + 151E98A46C68434C90DC17C1 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMPassByRefSetter.h + path + Source/OCMock/OCMPassByRefSetter.h + sourceTree + <group> + + 154264DB08074A5CABB5AE25 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWHaveMatcher.h + path + Classes/KWHaveMatcher.h + sourceTree + <group> + + 1587952DBC5244038D493A61 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBeforeEachNode.m + path + Classes/KWBeforeEachNode.m + sourceTree + <group> + + 1604C4170864429F98504E49 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text + name + Podfile + path + ../Podfile + sourceTree + SOURCE_ROOT + xcLanguageSpecificationIdentifier + xcode.lang.ruby + + 1620AC589F60448382BCBCA7 + + fileRef + 895485F401A8405A961FAF2D + isa + PBXBuildFile + + 167A80B2C1E64278996F1414 + + fileRef + 74630004768B43299BB49714 + isa + PBXBuildFile + + 16B5F03C94EE426D90A3F9FF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWEqualMatcher.m + path + Classes/KWEqualMatcher.m + sourceTree + <group> + + 16C5CB78443C4C0FBEF8A89B + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods.a + sourceTree + BUILT_PRODUCTS_DIR + + 173B60F790FE4579B2547F8E + + fileRef + 5B1A50542D644B51BADA856E + isa + PBXBuildFile + + 178E3CE05FC146AEBDAA27DF + + fileRef + B5223FE66BDE468095CC6331 + isa + PBXBuildFile + + 17E2AD5C6D7C4DB6B0004C5E + + fileRef + 56FC2CE32EF748219BB40A9F + isa + PBXBuildFile + + 19FA7AB62595489BB3E1A524 + + fileRef + 04E5E23C376041E3B37F0188 + isa + PBXBuildFile + + 1A75AEE9D63F405FB615244D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCProtocolMockObject.h + path + Source/OCMock/OCProtocolMockObject.h + sourceTree + <group> + + 1B1DD0F7FFBC42A9AB08D118 + + fileRef + CAFE9DCAEEA04DE483D38FD5 + isa + PBXBuildFile + + 1B6D7616CF4C4257BB3644EF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSProxy+KiwiVerifierAdditions.m + path + Classes/NSProxy+KiwiVerifierAdditions.m + sourceTree + <group> + + 1B85DAA25FD44EA0A89567D0 + + fileRef + 858AB146D4C0477E8EB760AC + isa + PBXBuildFile + + 1BD2D3C92FF640FCA98B7367 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWEqualMatcher.h + path + Classes/KWEqualMatcher.h + sourceTree + <group> + + 1C40E59264ED4D0C8E674E2F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-UnitTests-Kiwi-Private.xcconfig + sourceTree + <group> + + 1C50028B76CC45BC8F468914 + + fileRef + 1587952DBC5244038D493A61 + isa + PBXBuildFile + + 1C73C1CE00D241D48036CDDE + + children + + 56FC2CE32EF748219BB40A9F + CBF2FBA9CE884F6EBC6D8588 + + isa + PBXGroup + name + iOS + sourceTree + <group> + + 1C8BAEBB7B19435096D482AB + + fileRef + DA93D3859B8B40368F38D003 + isa + PBXBuildFile + + 1D10C584C2F94060B1E7BCAB + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWContextNode.h + path + Classes/KWContextNode.h + sourceTree + <group> + + 1D4970EB4CF64FB1A126C9BC + + fileRef + 7F05BB47EBFC40998744E733 + isa + PBXBuildFile + + 1D9B6DA82CD744A989904E5A + + children + + 9AF9B17A77B44CB08BAFEF91 + 3454B812D38147E1AC9415FD + + isa + PBXGroup + name + VLBFoundation + path + VLBFoundation + sourceTree + <group> + + 1D9CF34526E240D2BC7B06F8 + + fileRef + 8223D229C75040C187F967A4 + isa + PBXBuildFile + + 1DF4924DDF6D44688BFC5FD9 + + fileRef + FC90A76FEC0D491B9EF29454 + isa + PBXBuildFile + + 1DFCDC6F166D456485293705 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCPartialMockObject.h + path + Source/OCMock/OCPartialMockObject.h + sourceTree + <group> + + 20F3EBF0D3A44BB983B30C05 + + fileRef + 6AD5AA4D934A4FA4BD9AA805 + isa + PBXBuildFile + + 20FDF07318D14336B76C4055 + + isa + PBXTargetDependency + target + 0401DC63550F43A9B4EE19C1 + targetProxy + 554D7B2B308B4C1586F08003 + + 2161A8FA3B36491C83C12118 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWNull.h + path + Classes/KWNull.h + sourceTree + <group> + + 21671E8C8DB145FF8538EE31 + + fileRef + BE9DE41BB9A14C27B476AA71 + isa + PBXBuildFile + + 219E82EC6E4D4BA59D10E872 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWAny.h + path + Classes/KWAny.h + sourceTree + <group> + + 2218514B2A254488BEFCF6A3 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMock.h + path + Source/OCMock/OCMock.h + sourceTree + <group> + + 22752DE780F2420C9C3F80B1 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWIntercept.h + path + Classes/KWIntercept.h + sourceTree + <group> + + 2283168AF34A4154873911CC + + fileRef + FC4F7838F8C94C9C9BDDA462 + isa + PBXBuildFile + + 22CD521A310547CD95E3E7F2 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + DDFileLogger.h + path + Lumberjack/DDFileLogger.h + sourceTree + <group> + + 2311871F694F4BEDB3A8544A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWMessagePattern.m + path + Classes/KWMessagePattern.m + sourceTree + <group> + + 232F16A6905F41EEB245A859 + + fileRef + E9D22B81DC694D61B8F61BC4 + isa + PBXBuildFile + + 23C86114432D43BABED43237 + + fileRef + AFCE0DA00DFD4B6AAC1F4903 + isa + PBXBuildFile + + 23D6199981254F8688C3CC51 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + DDASLLogger.h + path + Lumberjack/DDASLLogger.h + sourceTree + <group> + + 23F7FB448051463C800AEF7E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSNotificationCenter+OCMAdditions.h + path + Source/OCMock/NSNotificationCenter+OCMAdditions.h + sourceTree + <group> + + 243A839C1FB742AFB47451A5 + + fileRef + 123DED21C2674E1290469787 + isa + PBXBuildFile + + 2452E09D24E34E3598D53881 + + fileRef + C8F97772BC004F7580E7E1A8 + isa + PBXBuildFile + + 248503F568F74FC5BA26247F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCMRealObjectForwarder.m + path + Source/OCMock/OCMRealObjectForwarder.m + sourceTree + <group> + + 24C46E7F3563462ABFA08F50 + + fileRef + 0E2606EBFEBB4D0D97797E65 + isa + PBXBuildFile + + 259EA7FF228348FA9CBBD349 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-VLBFoundation-prefix.pch + sourceTree + <group> + + 25E1EAACE7994F80A553B656 + + fileRef + 88897762E1DB42CEA21B9073 + isa + PBXBuildFile + + 2717FEB554024156A5F82E73 + + fileRef + 56FC2CE32EF748219BB40A9F + isa + PBXBuildFile + + 272ECD3F376C426693FAACD5 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-CocoaLumberjack-Private.xcconfig + sourceTree + <group> + + 27800A166E224D4782041F9F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-UnitTests-CocoaLumberjack-dummy.m + sourceTree + <group> + + 27910367AB8C44029E27E3B5 + + fileRef + CBF2FBA9CE884F6EBC6D8588 + isa + PBXBuildFile + + 27BE17AD6A474DB3BEDC55C8 + + fileRef + 0CC73CDDBBD3430F9D035DC6 + isa + PBXBuildFile + + 28E98EB14CDB4D70A386BA5C + + fileRef + 8FA930996A55476F932FDE4D + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + 2916FAF89C484577B57F339B + + fileRef + 2ED7222FDA524035A12E3EDF + isa + PBXBuildFile + + 29870C4CE9774F3E9BE5DDC9 + + baseConfigurationReference + A42411FB09404932B1B7515A + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Pods-VLBFoundation-prefix.pch + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + 2992CDD17D454FC1AD0E15FB + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-UnitTests-OCMock-prefix.pch + sourceTree + <group> + + 2AAC7814C9294FB8B9512F4C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCMockObject.m + path + Source/OCMock/OCMockObject.m + sourceTree + <group> + + 2C266D1F4AFE4671846F567F + + containerPortal + 62298A1970D14909914BA53E + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 768F895B23B94C52A36EC63B + remoteInfo + Pods-CocoaLumberjack + + 2DC8FEA8E5BD44FE83286AF3 + + fileRef + 3C1221BA5B684C1893006C13 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + 2E9A15B0DA714DC7A8F18E7F + + fileRef + 56FC2CE32EF748219BB40A9F + isa + PBXBuildFile + + 2ED7222FDA524035A12E3EDF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWItNode.h + path + Classes/KWItNode.h + sourceTree + <group> + + 2F578BCEC37B4254B4ABF002 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSMethodSignature+OCMAdditions.h + path + Source/OCMock/NSMethodSignature+OCMAdditions.h + sourceTree + <group> + + 2FCB3792BD8C407DA3ACA95C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWChangeMatcher.h + path + Classes/KWChangeMatcher.h + sourceTree + <group> + + 2FE6B55C721545328FDBF021 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWExampleNodeVisitor.h + path + Classes/KWExampleNodeVisitor.h + sourceTree + <group> + + 305FDEBDE143448CA7CCA9B0 + + buildConfigurations + + 1242FCF848B5427784903A47 + A2412F7880ED43098DF25570 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 3088F06FAB1C4F8287853C80 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCMReturnValueProvider.m + path + Source/OCMock/OCMReturnValueProvider.m + sourceTree + <group> + + 3191D02B9161444AA112FBF7 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCPartialMockRecorder.m + path + Source/OCMock/OCPartialMockRecorder.m + sourceTree + <group> + + 31BAACEAC9C741E99D03B588 + + fileRef + 564EA32B161E4C1D9FF80DC8 + isa + PBXBuildFile + + 31EA73E3B88B4008B33E3BFB + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWSpec.m + path + Classes/KWSpec.m + sourceTree + <group> + + 3289CD5A569F426981A445DD + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSValue+KiwiAdditions.m + path + Classes/NSValue+KiwiAdditions.m + sourceTree + <group> + + 33B6E18ED07D4CC9B5BE81AE + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWStringUtilities.m + path + Classes/KWStringUtilities.m + sourceTree + <group> + + 3454B812D38147E1AC9415FD + + children + + F99E1927E74F4AF9B0B576FE + D79870C993384021B89C3243 + AA039908D4384594875633A4 + E23BA0F7BE2340C3A3092F6C + 5F5FFA2DE1B341BABF9C7570 + A42411FB09404932B1B7515A + DD2691DC782C4F2A849C3DB6 + 259EA7FF228348FA9CBBD349 + + isa + PBXGroup + name + Support Files + sourceTree + SOURCE_ROOT + + 34CA30117E13479C93BF0DEE + + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + CLANG_CXX_LANGUAGE_STANDARD + gnu++0x + CLANG_CXX_LIBRARY + libc++ + CLANG_ENABLE_MODULES + YES + CLANG_ENABLE_OBJC_ARC + NO + CLANG_WARN_BOOL_CONVERSION + YES + CLANG_WARN_CONSTANT_CONVERSION + YES + CLANG_WARN_DIRECT_OBJC_ISA_USAGE + YES + CLANG_WARN_EMPTY_BODY + YES + CLANG_WARN_ENUM_CONVERSION + YES + CLANG_WARN_INT_CONVERSION + YES + CLANG_WARN_OBJC_ROOT_CLASS + YES + COPY_PHASE_STRIP + NO + ENABLE_NS_ASSERTIONS + NO + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_WARN_64_TO_32_BIT_CONVERSION + YES + GCC_WARN_ABOUT_RETURN_TYPE + YES + GCC_WARN_UNDECLARED_SELECTOR + YES + GCC_WARN_UNINITIALIZED_AUTOS + YES + GCC_WARN_UNUSED_FUNCTION + YES + GCC_WARN_UNUSED_VARIABLE + YES + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + STRIP_INSTALLED_PRODUCT + NO + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + 34CEE4F3A303452E9A2C0B8F + + containerPortal + 62298A1970D14909914BA53E + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 00A2B3C5871A43CB8A372CFE + remoteInfo + Pods-VLBFoundation + + 35722B7C0773444A90A4239C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSObject+KiwiMockAdditions.h + path + Classes/NSObject+KiwiMockAdditions.h + sourceTree + <group> + + 357F92EAE84344798ABBE168 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWFutureObject.m + path + Classes/KWFutureObject.m + sourceTree + <group> + + 35EDD8F81C134AC687B1F0EB + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWPendingNode.h + path + Classes/KWPendingNode.h + sourceTree + <group> + + 3750105DF8AD4BF2B3716D7F + + fileRef + EEFF537C453E4725BFCC981C + isa + PBXBuildFile + + 38F5882012774F78A850E779 + + fileRef + A8D1412974344204950DC86C + isa + PBXBuildFile + + 3B29C1D4651E4909A7F12DD9 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWChangeMatcher.m + path + Classes/KWChangeMatcher.m + sourceTree + <group> + + 3C1221BA5B684C1893006C13 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + DDASLLogger.m + path + Lumberjack/DDASLLogger.m + sourceTree + <group> + + 3CDC72F8A3544377834F5A1A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBeMemberOfClassMatcher.m + path + Classes/KWBeMemberOfClassMatcher.m + sourceTree + <group> + + 3CF814D8B39F48CDA704F152 + + fileRef + 4F7DFF809AEC4390A018457D + isa + PBXBuildFile + + 3D2923B995604AE6A5952605 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-UnitTests-CocoaLumberjack.a + sourceTree + BUILT_PRODUCTS_DIR + + 3D546BB0FEAB4C15BAE6C818 + + fileRef + 2311871F694F4BEDB3A8544A + isa + PBXBuildFile + + 3D6C6797EA4140EC8263605A + + fileRef + 02528A11FCD848F3B24E24B3 + isa + PBXBuildFile + + 3E5EAE6AB6F5483AAC9C49F9 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMNotificationPoster.h + path + Source/OCMock/OCMNotificationPoster.h + sourceTree + <group> + + 3EE902F50EC641139B097F88 + + fileRef + D2C1E42347BE4534B4D189F2 + isa + PBXBuildFile + + 3FBEF7951E18448CA75A1907 + + children + + EF9B2EB23E864FC5A31275E2 + 895485F401A8405A961FAF2D + 2F578BCEC37B4254B4ABF002 + 46305760D41240EE87887C29 + 23F7FB448051463C800AEF7E + FC90A76FEC0D491B9EF29454 + DAF9CF2174AC4B8ABC5939D5 + A518FF7796E74B4CAD8B39C7 + 4C1B54FA052E4AE6B2C804B1 + D2C1E42347BE4534B4D189F2 + 53A4056AB80443159F670FC9 + AF23259EF2244B8C98AF8A64 + F513667F0B634C42A4EF312F + 90F1A5108C4A43889DCF7FE4 + CFA482AD6223477C9CA05509 + 419BF12F732240D2AF093D33 + 8223D229C75040C187F967A4 + 858AB146D4C0477E8EB760AC + 7C64B5704E374A708BD23834 + A68489497CC14845ABD4EC56 + 3E5EAE6AB6F5483AAC9C49F9 + BE4ED5A4DD334508B6277BF1 + 8CA8FA8A76714778A520CFC8 + 5598DDE9EA014EAA99B2A2EE + 151E98A46C68434C90DC17C1 + 5C04AB1F7BB04C68A7A6F61A + 5F1463A3F0944FE5B14BE7A2 + 248503F568F74FC5BA26247F + 6D5594E813F4416D99CB8675 + 3088F06FAB1C4F8287853C80 + 2218514B2A254488BEFCF6A3 + 92995B21E32F46ECA6C9B4C9 + 2AAC7814C9294FB8B9512F4C + D268DDFE2A7E418F82EA3F22 + 8076A47287CB4F8B87AC86DD + 0CC73CDDBBD3430F9D035DC6 + DC38F59C0C7A4E7292843699 + 1DFCDC6F166D456485293705 + D841148CA16E4D138B7A5869 + A4D9047FD2794958A878186C + 3191D02B9161444AA112FBF7 + 1A75AEE9D63F405FB615244D + 9E139C1E3D83496BAF62DCC8 + AF30BF6C31AF48E784E5D9AF + + isa + PBXGroup + name + OCMock + path + OCMock + sourceTree + <group> + + 3FC7E5AAF10D413D860D4AAD + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWWorkarounds.h + path + Classes/KWWorkarounds.h + sourceTree + <group> + + 3FE85E104CBF4940A021185D + + fileRef + D841148CA16E4D138B7A5869 + isa + PBXBuildFile + + 4025FDCABDAB4E7A97FA4E33 + + fileRef + 22CD521A310547CD95E3E7F2 + isa + PBXBuildFile + + 41737AD95B5C4855A1067354 + + fileRef + 95EC90A5F6554A85890C333D + isa + PBXBuildFile + + 419BF12F732240D2AF093D33 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCMConstraint.m + path + Source/OCMock/OCMConstraint.m + sourceTree + <group> + + 41E31871954449DFBB1A6BF2 + + fileRef + 7C64B5704E374A708BD23834 + isa + PBXBuildFile + + 41E647DB70DD432298E224FA + + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + CLANG_CXX_LANGUAGE_STANDARD + gnu++0x + CLANG_CXX_LIBRARY + libc++ + CLANG_ENABLE_MODULES + YES + CLANG_ENABLE_OBJC_ARC + NO + CLANG_WARN_BOOL_CONVERSION + YES + CLANG_WARN_CONSTANT_CONVERSION + YES + CLANG_WARN_DIRECT_OBJC_ISA_USAGE + YES + CLANG_WARN_EMPTY_BODY + YES + CLANG_WARN_ENUM_CONVERSION + YES + CLANG_WARN_INT_CONVERSION + YES + CLANG_WARN_OBJC_ROOT_CLASS + YES + COPY_PHASE_STRIP + YES + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + GCC_WARN_64_TO_32_BIT_CONVERSION + YES + GCC_WARN_ABOUT_RETURN_TYPE + YES + GCC_WARN_UNDECLARED_SELECTOR + YES + GCC_WARN_UNINITIALIZED_AUTOS + YES + GCC_WARN_UNUSED_FUNCTION + YES + GCC_WARN_UNUSED_VARIABLE + YES + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + ONLY_ACTIVE_ARCH + YES + STRIP_INSTALLED_PRODUCT + NO + + isa + XCBuildConfiguration + name + Debug + + 42B9EB3C734540A685BDDAEF + + fileRef + 0AA7A9A4A11B42F585A2077C + isa + PBXBuildFile + + 42C18AD8A8DE414FA6828FFA + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWMessagePattern.h + path + Classes/KWMessagePattern.h + sourceTree + <group> + + 4380C4DA489D4B95A7A91E90 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.plist.xml + path + Pods-acknowledgements.plist + sourceTree + <group> + + 442439254A8143B695827035 + + isa + PBXTargetDependency + target + 00A2B3C5871A43CB8A372CFE + targetProxy + 34CEE4F3A303452E9A2C0B8F + + 44320CC871AF48B581C2576F + + fileRef + DF989EB4144B45669D3BC987 + isa + PBXBuildFile + + 453B9B7DBC8A4151B6E60F36 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWExistVerifier.m + path + Classes/KWExistVerifier.m + sourceTree + <group> + + 45AD9F45E093468391227EB3 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSInvocation+OCMAdditions.m + path + Classes/NSInvocation+OCMAdditions.m + sourceTree + <group> + + 45D6D18EE14549ACADBEB99E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBeWithinMatcher.h + path + Classes/KWBeWithinMatcher.h + sourceTree + <group> + + 46305760D41240EE87887C29 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSMethodSignature+OCMAdditions.m + path + Source/OCMock/NSMethodSignature+OCMAdditions.m + sourceTree + <group> + + 46E35DB37E164B2597D0981B + + fileRef + 3191D02B9161444AA112FBF7 + isa + PBXBuildFile + + 47CCEFD1D7EB4EAEAC448F5C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWGenericMatchingAdditions.m + path + Classes/KWGenericMatchingAdditions.m + sourceTree + <group> + + 47EED8FAF4F74D96B8C82AF3 + + baseConfigurationReference + EC239C20E4EC4AB6BCB865E0 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Pods-UnitTests-OCMock-prefix.pch + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + 48B64D578CC9480986428E1C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-dummy.m + sourceTree + <group> + + 48C28A338854477091C392DC + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + Kiwi.h + path + Classes/Kiwi.h + sourceTree + <group> + + 49349E57B46F4A86BA410194 + + fileRef + 0D0345D4FDFD49DA82D1BD63 + isa + PBXBuildFile + + 4A6C338EAE7E48238D3B7D50 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBeKindOfClassMatcher.m + path + Classes/KWBeKindOfClassMatcher.m + sourceTree + <group> + + 4AE75555D809410495C55362 + + fileRef + E817D9B8CC51418EBB02D10C + isa + PBXBuildFile + + 4BE5773E373F4D27BF45A9FB + + fileRef + 3088F06FAB1C4F8287853C80 + isa + PBXBuildFile + + 4C1B54FA052E4AE6B2C804B1 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMArg.h + path + Source/OCMock/OCMArg.h + sourceTree + <group> + + 4CC083D06092465C8BE10329 + + fileRef + 9C15F28EB97143AE96B7E768 + isa + PBXBuildFile + + 4CF26262D7BE4FEBA3ACCE48 + + fileRef + 52B8DA1F77774F1BBFE03723 + isa + PBXBuildFile + + 4D0D8E95D26644C880032E91 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBeTrueMatcher.h + path + Classes/KWBeTrueMatcher.h + sourceTree + <group> + + 4D492F8CE6A848108604D42B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSObject+KiwiStubAdditions.m + path + Classes/NSObject+KiwiStubAdditions.m + sourceTree + <group> + + 4D74CCEB004C4F578ACBE306 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWStringContainsMatcher.m + path + Classes/KWStringContainsMatcher.m + sourceTree + <group> + + 4DA6664B887F4CEE800EBE1C + + fileRef + D02CBCC3D7F24CEF8C2CEB71 + isa + PBXBuildFile + + 4DDC75E2432D40069C5CDCC4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWAfterEachNode.m + path + Classes/KWAfterEachNode.m + sourceTree + <group> + + 4E0AF3DE8446440CBD8DD99C + + fileRef + 893CF0638DAB4DF3A853B36C + isa + PBXBuildFile + + 4E0BF3B33AED4F8CB0F9C8EF + + fileRef + A4D9047FD2794958A878186C + isa + PBXBuildFile + + 4E2C9BAF89FE4E0AB781BE00 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWMatchers.m + path + Classes/KWMatchers.m + sourceTree + <group> + + 4F33FC8D5C1B44FD98ACEEF2 + + fileRef + 119C5659662144F4A82E1C32 + isa + PBXBuildFile + + 4F3898891BE042D398E93C6A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBeIdenticalToMatcher.m + path + Classes/KWBeIdenticalToMatcher.m + sourceTree + <group> + + 4F715407345D4D29AEC7E0C0 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-UnitTests-CocoaLumberjack-prefix.pch + sourceTree + <group> + + 4F7DFF809AEC4390A018457D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + DDAbstractDatabaseLogger.h + path + Lumberjack/DDAbstractDatabaseLogger.h + sourceTree + <group> + + 4FFD193BAD474648BE687917 + + fileRef + 53A4056AB80443159F670FC9 + isa + PBXBuildFile + + 510B82739D814079854F07D9 + + fileRef + 35EDD8F81C134AC687B1F0EB + isa + PBXBuildFile + + 5142CD36F8E840A98C5C4CEE + + fileRef + EE896E9C37E74F2A8EFC0714 + isa + PBXBuildFile + + 52AF7231606C4501BCDFDC1A + + fileRef + 48B64D578CC9480986428E1C + isa + PBXBuildFile + + 52B8DA1F77774F1BBFE03723 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWCaptureSpy.m + path + Classes/KWCaptureSpy.m + sourceTree + <group> + + 52F5B478B05641E180754C5F + + fileRef + 7C2974883AD347C79346007A + isa + PBXBuildFile + + 53A4056AB80443159F670FC9 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMBlockCaller.h + path + Source/OCMock/OCMBlockCaller.h + sourceTree + <group> + + 53BC7509CB554BDFAE9305C7 + + fileRef + E5A752DC4D694CD8AA941BDE + isa + PBXBuildFile + + 53E23F9AB2DF4661A1FCA241 + + fileRef + 4D0D8E95D26644C880032E91 + isa + PBXBuildFile + + 547ABC679A2F43479B874A17 + + buildActionMask + 2147483647 + files + + 8CCBCC32E917442C82B0015C + A54FE47F8171499C8CB0159F + 09A2DE10B39E4336AAA67347 + 69A3A35BB776487EB9C3BCD7 + 83D8883AEBDA443CAF978214 + 4FFD193BAD474648BE687917 + EB9720A284D64E10B7041E03 + 016C2E3AA65F4712BDF420B9 + 1D9CF34526E240D2BC7B06F8 + 41E31871954449DFBB1A6BF2 + AE4C1F3BE3864AD1AA7F96DA + 7FCC99E234144BE0AD1F6F96 + 9DA4245402474DC3A18AD54A + C34A7AF612C4461B91D0321E + 04B9DAB058324D39BD5B1C4A + 62A5C992B7FE434D898A9AF7 + 79A4FE9B405746B4A98C3292 + C58971B67AAB4CC2A5737A2A + 27BE17AD6A474DB3BEDC55C8 + 7CAF069376D54D00ABEF9722 + 4E0BF3B33AED4F8CB0F9C8EF + A44E2D71F5014CC2BF1B9FF0 + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 554D7B2B308B4C1586F08003 + + containerPortal + 62298A1970D14909914BA53E + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 0401DC63550F43A9B4EE19C1 + remoteInfo + Pods-UnitTests-Kiwi + + 5598DDE9EA014EAA99B2A2EE + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCMObserverRecorder.m + path + Source/OCMock/OCMObserverRecorder.m + sourceTree + <group> + + 55FB86EEFFEF4235862FEF9C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBeforeAllNode.m + path + Classes/KWBeforeAllNode.m + sourceTree + <group> + + 564EA32B161E4C1D9FF80DC8 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWDeviceInfo.m + path + Classes/KWDeviceInfo.m + sourceTree + <group> + + 5653AD9B53584A7EBE0C50F2 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBeNilMatcher.m + path + Classes/KWBeNilMatcher.m + sourceTree + <group> + + 56BA77BE81A04BDB8E451E3F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWCountType.h + path + Classes/KWCountType.h + sourceTree + <group> + + 56D75A59ECD04319A5F42A45 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWExampleGroupDelegate.h + path + Classes/KWExampleGroupDelegate.h + sourceTree + <group> + + 56FC2CE32EF748219BB40A9F + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + Foundation.framework + path + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework + sourceTree + DEVELOPER_DIR + + 570913C8640E49F2BCAAFADE + + fileRef + AFE8A5FCC8CF447489AF2B84 + isa + PBXBuildFile + + 57A245D88DA54A0B958C4CBE + + fileRef + E5FE56EF52A94BB3A5E96CD8 + isa + PBXBuildFile + + 57B7BC74DED54238989776E7 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWCaptureSpy.h + path + Classes/KWCaptureSpy.h + sourceTree + <group> + + 5911A76CD355431DA1A8E296 + + fileRef + 57B7BC74DED54238989776E7 + isa + PBXBuildFile + + 592B69C778B24557B2B03661 + + children + + 9D9EFFB7F3A44CA190529407 + 1C40E59264ED4D0C8E674E2F + E817D9B8CC51418EBB02D10C + 70A8DDB86FA146C08087F952 + + isa + PBXGroup + name + Support Files + sourceTree + SOURCE_ROOT + + 5A06B7D8F6A0498CA786F29F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWExistVerifier.h + path + Classes/KWExistVerifier.h + sourceTree + <group> + + 5AB371818BC4432EB127DE31 + + children + + 16C5CB78443C4C0FBEF8A89B + 94AD633C3A434EC6AE478FA7 + 8FBC76237DF74BBCB9DCB38D + 3D2923B995604AE6A5952605 + 06D9B225A8504500AE75D71B + 0C428E5F278A4B24A61CAAF2 + C54C19CAD49E497A8512BC73 + D1A6FF6D7EF74D9BBC91FA36 + + isa + PBXGroup + name + Products + sourceTree + <group> + + 5B1A50542D644B51BADA856E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWAfterAllNode.m + path + Classes/KWAfterAllNode.m + sourceTree + <group> + + 5C04AB1F7BB04C68A7A6F61A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCMPassByRefSetter.m + path + Source/OCMock/OCMPassByRefSetter.m + sourceTree + <group> + + 5C72ADEF282941A187547EA4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWGenericMatchingAdditions.h + path + Classes/KWGenericMatchingAdditions.h + sourceTree + <group> + + 5C8557CF54C5416F85E68518 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWStringPrefixMatcher.m + path + Classes/KWStringPrefixMatcher.m + sourceTree + <group> + + 5CF1BD904FAF4277A4A8352F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-CocoaLumberjack-prefix.pch + sourceTree + <group> + + 5DAB05A87B294C3AB15820E7 + + fileRef + B4808F054BCF42D6A2DCA4E0 + isa + PBXBuildFile + + 5DE8EE24336040C6B70A86A6 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSObject+KiwiSpyAdditions.h + path + Classes/NSObject+KiwiSpyAdditions.h + sourceTree + <group> + + 5F1463A3F0944FE5B14BE7A2 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMRealObjectForwarder.h + path + Source/OCMock/OCMRealObjectForwarder.h + sourceTree + <group> + + 5F5FFA2DE1B341BABF9C7570 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-VLBFoundation.xcconfig + sourceTree + <group> + + 5FBFCB258190433FA6C0F587 + + fileRef + 5653AD9B53584A7EBE0C50F2 + isa + PBXBuildFile + + 62298A1970D14909914BA53E + + attributes + + LastUpgradeCheck + 0510 + + buildConfigurationList + AA054C90CF1C44A5A69B477C + compatibilityVersion + Xcode 3.2 + developmentRegion + English + hasScannedForEncodings + 0 + isa + PBXProject + knownRegions + + en + + mainGroup + 99EB9FF727914262B6C8E433 + productRefGroup + 5AB371818BC4432EB127DE31 + projectDirPath + + projectReferences + + projectRoot + + targets + + 0267876190534E6F88627596 + 768F895B23B94C52A36EC63B + 8EA03957C0C541578DB61C97 + 0FBA129B61B4442A9602F6A9 + 0401DC63550F43A9B4EE19C1 + D781C4F75B4C464486E9569A + E1AB1C02919A47998D69B21A + 00A2B3C5871A43CB8A372CFE + + + 62A5C992B7FE434D898A9AF7 + + fileRef + 2218514B2A254488BEFCF6A3 + isa + PBXBuildFile + + 630E321AC2C9488C9036AE7C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBlockRaiseMatcher.h + path + Classes/KWBlockRaiseMatcher.h + sourceTree + <group> + + 63FF6242C2734B31922435D0 + + fileRef + C6DA4E53441440EB95F79790 + isa + PBXBuildFile + + 64097FF8DB0F478693248229 + + fileRef + 4D492F8CE6A848108604D42B + isa + PBXBuildFile + + 642F4C5C97F942FDB0D730E6 + + fileRef + 02528A11FCD848F3B24E24B3 + isa + PBXBuildFile + + 644D7BA94C8043BAB641AA59 + + containerPortal + 62298A1970D14909914BA53E + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + E1AB1C02919A47998D69B21A + remoteInfo + Pods-UnitTests-VLBFoundation + + 64690C9DF0B94BBCA3D367AF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWAfterEachNode.h + path + Classes/KWAfterEachNode.h + sourceTree + <group> + + 64AE571089DA4191AA13CD13 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-UnitTests-environment.h + sourceTree + <group> + + 653CA191EE604B35A5402F24 + + fileRef + 219E82EC6E4D4BA59D10E872 + isa + PBXBuildFile + + 654F1BE6A7E6425491C142C6 + + fileRef + 2FE6B55C721545328FDBF021 + isa + PBXBuildFile + + 65AE80B513B14050891F1622 + + baseConfigurationReference + 789ECDF5086D444FBE9631BF + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 65D551FCCEDA42D1A635032C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWReceiveMatcher.h + path + Classes/KWReceiveMatcher.h + sourceTree + <group> + + 65E83DC61FDF4978B12E870E + + buildActionMask + 2147483647 + files + + 95D4E76CF5244412BE1279CA + EA42BF81F15746E5AC64DC7E + 3CF814D8B39F48CDA704F152 + 4025FDCABDAB4E7A97FA4E33 + 25E1EAACE7994F80A553B656 + 8204F234108842F68FE6CFE1 + 3D6C6797EA4140EC8263605A + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 663FAB73084240D782144B3E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWFailure.h + path + Classes/KWFailure.h + sourceTree + <group> + + 66F71FB6F6DF43F9AB4A2FF9 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KiwiBlockMacros.h + path + Classes/KiwiBlockMacros.h + sourceTree + <group> + + 67E91F2B2C694AE79AD06E81 + + fileRef + E8D5ABDD703D4DBFB1B17848 + isa + PBXBuildFile + + 68177922B3AC45C9B01E6408 + + fileRef + C1B59E413C5A4B049669AE01 + isa + PBXBuildFile + + 694001AC5429471FAF626F3E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBeNonNilMatcher.h + path + Classes/KWBeNonNilMatcher.h + sourceTree + <group> + + 69A3A35BB776487EB9C3BCD7 + + fileRef + DAF9CF2174AC4B8ABC5939D5 + isa + PBXBuildFile + + 6AD5AA4D934A4FA4BD9AA805 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSObject+KiwiVerifierAdditions.h + path + Classes/NSObject+KiwiVerifierAdditions.h + sourceTree + <group> + + 6B0FC044C90F4560A08C65E4 + + fileRef + CD0252BB0DE64E968283C908 + isa + PBXBuildFile + + 6D419600AA23424383D69069 + + baseConfigurationReference + 1C40E59264ED4D0C8E674E2F + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Pods-UnitTests-Kiwi-prefix.pch + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + 6D5594E813F4416D99CB8675 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMReturnValueProvider.h + path + Source/OCMock/OCMReturnValueProvider.h + sourceTree + <group> + + 6D57368E1A054788968D82B3 + + fileRef + A3FFCEA6BDF44EC59BF9DA00 + isa + PBXBuildFile + + 6D64D8D0922A41219ADB7125 + + fileRef + B610BD7A5ADD44A2A2FECE85 + isa + PBXBuildFile + + 6DDE908C1D014DF2A9237B45 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWAsyncVerifier.h + path + Classes/KWAsyncVerifier.h + sourceTree + <group> + + 6DFD05ECE30F4FFBB527C526 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWStringPrefixMatcher.h + path + Classes/KWStringPrefixMatcher.h + sourceTree + <group> + + 6EAE1B4E3FA74CBFA4E103BE + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWMessageSpying.h + path + Classes/KWMessageSpying.h + sourceTree + <group> + + 6F3F78F404694F10AB1A76CD + + fileRef + 06B83EC8C24A41C5AF77F234 + isa + PBXBuildFile + + 6F5A1899642F4C22B3246AE5 + + fileRef + 4F7DFF809AEC4390A018457D + isa + PBXBuildFile + + 7069CC77FB954200A2A00B4B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBlockNode.h + path + Classes/KWBlockNode.h + sourceTree + <group> + + 70A8DDB86FA146C08087F952 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-UnitTests-Kiwi-prefix.pch + sourceTree + <group> + + 729AD441AAFB4B8CA7214548 + + buildConfigurations + + F444DD05FF014030812F4C36 + 88A8F799FAE34EF8A202DA78 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 729D82C1F76C455BADF94806 + + buildConfigurations + + 045FA1F483DD43CD82DF2D28 + A894C7BAB81E42C4B6E29EA6 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 732C92250677421785717247 + + buildActionMask + 2147483647 + files + + 1620AC589F60448382BCBCA7 + 84BCB67C651C4B7386F5BDF7 + 1DF4924DDF6D44688BFC5FD9 + C62CA5B9CF0049B182C971AE + 3EE902F50EC641139B097F88 + C9F34675E1D94703BC85C923 + 80D2FDD83DD444FF9F983911 + FE17C3F1EFCF4665A67F6CEF + 1B85DAA25FD44EA0A89567D0 + 10A11E402D6449C988C39EFA + F33D0835A9174FA79F9D29A7 + BFEE35B1906A4FA08FF3EC59 + 8084CE647DF843658612AEB6 + A1BCDAA63CE64D55930678F6 + 4BE5773E373F4D27BF45A9FB + 10358EC2BDF74CF6B79B62A1 + C93444EC84394BEB9AF907A2 + 1301DC1B53354DF8B1473DCD + 3FE85E104CBF4940A021185D + 46E35DB37E164B2597D0981B + F3E70B24B06144DEAC6A6BDA + C5C44CA0903A4176A377863A + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 741CA305FBEA48F8B4099F42 + + fileRef + 4E2C9BAF89FE4E0AB781BE00 + isa + PBXBuildFile + + 742B5DA40EAA4D33A98B3DE6 + + fileRef + 3289CD5A569F426981A445DD + isa + PBXBuildFile + + 74630004768B43299BB49714 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWExpectationType.h + path + Classes/KWExpectationType.h + sourceTree + <group> + + 747F6B50A23A4007A405F281 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWVerifying.h + path + Classes/KWVerifying.h + sourceTree + <group> + + 750A2ABA92FA47FF9CEE3F21 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWTestCase.h + path + Classes/KWTestCase.h + sourceTree + <group> + + 7547A2DCCB58438DBE7FCE2E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWExampleNode.h + path + Classes/KWExampleNode.h + sourceTree + <group> + + 75ADADE06DA541F5B0F44CDE + + fileRef + C154B55412DB492DB6EA44DE + isa + PBXBuildFile + + 768F895B23B94C52A36EC63B + + buildConfigurationList + 729AD441AAFB4B8CA7214548 + buildPhases + + C11E2A934CB94E4994DC8F8D + D1282DA7BEF042E8B8377279 + 65E83DC61FDF4978B12E870E + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-CocoaLumberjack + productName + Pods-CocoaLumberjack + productReference + 94AD633C3A434EC6AE478FA7 + productType + com.apple.product-type.library.static + + 76B4DF0E3A96480498A15140 + + buildActionMask + 2147483647 + files + + 53BC7509CB554BDFAE9305C7 + 10997194309B42ABB7178A8A + 6F5A1899642F4C22B3246AE5 + 133681FAC86544B496860F81 + 0033BF1124E544778C678C61 + 89C4A7E8124C412AB8ED1CBB + 642F4C5C97F942FDB0D730E6 + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 772B4704E72D439C90869B99 + + fileRef + 00FAA90E6D7F43118C0F6DB5 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + 7893E443E3F346328058F24F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-UnitTests-CocoaLumberjack.xcconfig + sourceTree + <group> + + 789ECDF5086D444FBE9631BF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods.xcconfig + sourceTree + <group> + + 7949794DDFBC4E77B3E6F854 + + fileRef + CF68AB5780C6478FBD3727EA + isa + PBXBuildFile + + 79A4FE9B405746B4A98C3292 + + fileRef + 92995B21E32F46ECA6C9B4C9 + isa + PBXBuildFile + + 7A41C7A2AC7E4255B817F1E9 + + fileRef + C2E918CA58E04BB384217490 + isa + PBXBuildFile + + 7A85D5CCBCC44BF995939E02 + + fileRef + C91150BAB9AD4C16B993CE7B + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + 7B1E2BE7D276449CBB160CB0 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSNumber+KiwiAdditions.h + path + Classes/NSNumber+KiwiAdditions.h + sourceTree + <group> + + 7C27E1A75D7A4310BC64A5A0 + + fileRef + 7F658A7358A241A7A1942E7C + isa + PBXBuildFile + + 7C2974883AD347C79346007A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBeKindOfClassMatcher.h + path + Classes/KWBeKindOfClassMatcher.h + sourceTree + <group> + + 7C445B88E7D7455DA3BBA9AF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSObject+KiwiMockAdditions.m + path + Classes/NSObject+KiwiMockAdditions.m + sourceTree + <group> + + 7C566FEF89244765AFC1D758 + + fileRef + D1F41A2DED414A64854DBCCE + isa + PBXBuildFile + + 7C64B5704E374A708BD23834 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMIndirectReturnValueProvider.h + path + Source/OCMock/OCMIndirectReturnValueProvider.h + sourceTree + <group> + + 7C7F4A0A2C8D45CE92FCD646 + + fileRef + 0C428E5F278A4B24A61CAAF2 + isa + PBXBuildFile + + 7CAF069376D54D00ABEF9722 + + fileRef + 1DFCDC6F166D456485293705 + isa + PBXBuildFile + + 7D1C41E9A80E427683368945 + + fileRef + BE9AC1FBD03C497DB3FB9E11 + isa + PBXBuildFile + + 7DE5A24BAAE94F78964B7D10 + + containerPortal + 62298A1970D14909914BA53E + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 0FBA129B61B4442A9602F6A9 + remoteInfo + Pods-UnitTests-CocoaLumberjack + + 7EAF9B464585471CA1AF99F0 + + buildActionMask + 2147483647 + files + + DB65414E461F4117A9F6E94D + 9DA11B0EB68A4C7F9CB40831 + F0E54A2E819E480BA4A7BB59 + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 7EE630493F6F427D9D2DB13F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-UnitTests-CocoaLumberjack-Private.xcconfig + sourceTree + <group> + + 7F05BB47EBFC40998744E733 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBeEmptyMatcher.m + path + Classes/KWBeEmptyMatcher.m + sourceTree + <group> + + 7F0CBCE7D5B4477BBEA737A2 + + fileRef + 9A9DD290198649ECAB9D6E46 + isa + PBXBuildFile + + 7F658A7358A241A7A1942E7C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSProxy+KiwiVerifierAdditions.h + path + Classes/NSProxy+KiwiVerifierAdditions.h + sourceTree + <group> + + 7FCC99E234144BE0AD1F6F96 + + fileRef + 8CA8FA8A76714778A520CFC8 + isa + PBXBuildFile + + 8076A47287CB4F8B87AC86DD + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCMockRecorder.m + path + Source/OCMock/OCMockRecorder.m + sourceTree + <group> + + 8084CE647DF843658612AEB6 + + fileRef + 5C04AB1F7BB04C68A7A6F61A + isa + PBXBuildFile + + 808F04F665AC4ED8BF73B9DF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.script.sh + path + Pods-resources.sh + sourceTree + <group> + + 80D2FDD83DD444FF9F983911 + + fileRef + 90F1A5108C4A43889DCF7FE4 + isa + PBXBuildFile + + 81070F9BAAE84653ACC185CC + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWInvocationCapturer.m + path + Classes/KWInvocationCapturer.m + sourceTree + <group> + + 81F9605E59BD4591B177662F + + fileRef + 1BD2D3C92FF640FCA98B7367 + isa + PBXBuildFile + + 8204F234108842F68FE6CFE1 + + fileRef + C4879E86DD07410380F25654 + isa + PBXBuildFile + + 8223D229C75040C187F967A4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMExceptionReturnValueProvider.h + path + Source/OCMock/OCMExceptionReturnValueProvider.h + sourceTree + <group> + + 822FB9DF736B4994A406818D + + buildActionMask + 2147483647 + files + + 110175426B9142ACB1DAA177 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 82B2231B0ECF4A5D9AB5495C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWObjCUtilities.h + path + Classes/KWObjCUtilities.h + sourceTree + <group> + + 82CF689FB8EC466E8D910565 + + fileRef + D1F84C8C76CC4A23906BA4AD + isa + PBXBuildFile + + 82F4563B311D47FA87A012F1 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KiwiNewMacros.h + path + Classes/KiwiNewMacros.h + sourceTree + <group> + + 83C907C51842492A81A95A6F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWItNode.m + path + Classes/KWItNode.m + sourceTree + <group> + + 83D8883AEBDA443CAF978214 + + fileRef + 4C1B54FA052E4AE6B2C804B1 + isa + PBXBuildFile + + 8400A7F1224240E29992CC57 + + fileRef + 45D6D18EE14549ACADBEB99E + isa + PBXBuildFile + + 840628C3DF654C6B93CC21C6 + + children + + 1C73C1CE00D241D48036CDDE + + isa + PBXGroup + name + Frameworks + sourceTree + <group> + + 841AB2C9CB844FAC881A09B5 + + fileRef + 2161A8FA3B36491C83C12118 + isa + PBXBuildFile + + 848E986DFDCA4687823873C0 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWHaveValueMatcher.h + path + Classes/KWHaveValueMatcher.h + sourceTree + <group> + + 84A06998F7224A448A70BF22 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWFailure.m + path + Classes/KWFailure.m + sourceTree + <group> + + 84BCB67C651C4B7386F5BDF7 + + fileRef + 46305760D41240EE87887C29 + isa + PBXBuildFile + + 84DCF2520A93493EB9B651AB + + fileRef + EE133A054BDD4A8C9458DAB6 + isa + PBXBuildFile + + 850A25AFC37548FBB7BF4503 + + fileRef + 56FC2CE32EF748219BB40A9F + isa + PBXBuildFile + + 85241210B56346FDA69273AF + + fileRef + D18E6B06386C4FB4A06CE4FF + isa + PBXBuildFile + + 858AB146D4C0477E8EB760AC + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCMExceptionReturnValueProvider.m + path + Source/OCMock/OCMExceptionReturnValueProvider.m + sourceTree + <group> + + 861E6C1FCDDF4A33B5BCD40B + + fileRef + 3C1221BA5B684C1893006C13 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + 86CB11C36367440EBA1F6AEC + + fileRef + 9A573C8270DE4307841AD429 + isa + PBXBuildFile + + 86E983786BD54472BF166A88 + + fileRef + BBC23363061C4B2184772A70 + isa + PBXBuildFile + + 876308926E034E298DA94147 + + fileRef + 9B7C5E6ABF0D4BA2815A3432 + isa + PBXBuildFile + + 87AAE59A065042D9BD68E5BF + + fileRef + 4D74CCEB004C4F578ACBE306 + isa + PBXBuildFile + + 87ACA0034E374A5587719068 + + fileRef + C54C19CAD49E497A8512BC73 + isa + PBXBuildFile + + 87DA9DF4237042BBB4466800 + + fileRef + D9D31291F7224E5EB1641FF4 + isa + PBXBuildFile + + 88897762E1DB42CEA21B9073 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + DDLog.h + path + Lumberjack/DDLog.h + sourceTree + <group> + + 88A8F799FAE34EF8A202DA78 + + baseConfigurationReference + 272ECD3F376C426693FAACD5 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Pods-CocoaLumberjack-prefix.pch + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + 893CF0638DAB4DF3A853B36C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBeNonNilMatcher.m + path + Classes/KWBeNonNilMatcher.m + sourceTree + <group> + + 895485F401A8405A961FAF2D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSInvocation+OCMAdditions.m + path + Source/OCMock/NSInvocation+OCMAdditions.m + sourceTree + <group> + + 89AE2A8C87A54F01A4ECBEEE + + fileRef + 5A06B7D8F6A0498CA786F29F + isa + PBXBuildFile + + 89C4A7E8124C412AB8ED1CBB + + fileRef + C4879E86DD07410380F25654 + isa + PBXBuildFile + + 89F7B3F102F34D4CB875156A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWRespondToSelectorMatcher.h + path + Classes/KWRespondToSelectorMatcher.h + sourceTree + <group> + + 8A1C9C344FF54C9EB1733FED + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBeSubclassOfClassMatcher.h + path + Classes/KWBeSubclassOfClassMatcher.h + sourceTree + <group> + + 8A280FF00E534AE3B409421E + + fileRef + E25691B7830F41D9B8633C23 + isa + PBXBuildFile + + 8B4C6145789947EDADDF415C + + fileRef + C54D5B20FD074B78B86ECD43 + isa + PBXBuildFile + + 8C52C0EED6514C89A538E344 + + fileRef + 5C72ADEF282941A187547EA4 + isa + PBXBuildFile + + 8C8EF244252F49FAB163B66D + + fileRef + E6815438D9374F04B720B4C7 + isa + PBXBuildFile + + 8CA8FA8A76714778A520CFC8 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMObserverRecorder.h + path + Source/OCMock/OCMObserverRecorder.h + sourceTree + <group> + + 8CCBCC32E917442C82B0015C + + fileRef + EF9B2EB23E864FC5A31275E2 + isa + PBXBuildFile + + 8E5AE2BE8E434E3AAED5BADD + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWCallSite.m + path + Classes/KWCallSite.m + sourceTree + <group> + + 8EA03957C0C541578DB61C97 + + buildConfigurationList + 305FDEBDE143448CA7CCA9B0 + buildPhases + + C46259EB96C64FB7BE40E0CC + EC402269F3A344EF8D292398 + + buildRules + + dependencies + + D59F19CE3FD648DDB9B677E8 + 20FDF07318D14336B76C4055 + BC4D6554D0D0424DBF7EAF1A + 012E35389FD046CBBA9A36C8 + + isa + PBXNativeTarget + name + Pods-UnitTests + productName + Pods-UnitTests + productReference + 8FBC76237DF74BBCB9DCB38D + productType + com.apple.product-type.library.static + + 8EE4E45D252F4B85A43700EF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWGenericMatchEvaluator.m + path + Classes/KWGenericMatchEvaluator.m + sourceTree + <group> + + 8F160958E4194FE28150CC87 + + fileRef + 48C28A338854477091C392DC + isa + PBXBuildFile + + 8F78AA1EFC044065AF906C64 + + fileRef + DE42B001360E49D68AD3B861 + isa + PBXBuildFile + + 8FA930996A55476F932FDE4D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + DDAbstractDatabaseLogger.m + path + Lumberjack/DDAbstractDatabaseLogger.m + sourceTree + <group> + + 8FBC76237DF74BBCB9DCB38D + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-UnitTests.a + sourceTree + BUILT_PRODUCTS_DIR + + 90F1A5108C4A43889DCF7FE4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCMBoxedReturnValueProvider.m + path + Source/OCMock/OCMBoxedReturnValueProvider.m + sourceTree + <group> + + 911A1639AD3945AD81725058 + + fileRef + 93819543C2F24C9B85D1ECFA + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + 92995B21E32F46ECA6C9B4C9 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMockObject.h + path + Source/OCMock/OCMockObject.h + sourceTree + <group> + + 93819543C2F24C9B85D1ECFA + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + DDFileLogger.m + path + Lumberjack/DDFileLogger.m + sourceTree + <group> + + 93ABE810C75D45118ACA1381 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-UnitTests-OCMock-dummy.m + sourceTree + <group> + + 9406803A3551474E893EC322 + + fileRef + C85C8614E1B543189238662C + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + 9412EB7635374BA39766BDF2 + + buildActionMask + 2147483647 + files + + 17E2AD5C6D7C4DB6B0004C5E + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 949C61BABDA34BA0BC879DB5 + + buildActionMask + 2147483647 + files + + BA2C41F476874FE4B43A5A99 + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 94AD633C3A434EC6AE478FA7 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-CocoaLumberjack.a + sourceTree + BUILT_PRODUCTS_DIR + + 950ACF936A5F4CE1ADC75154 + + fileRef + 1B6D7616CF4C4257BB3644EF + isa + PBXBuildFile + + 95D4E76CF5244412BE1279CA + + fileRef + E5A752DC4D694CD8AA941BDE + isa + PBXBuildFile + + 95EC90A5F6554A85890C333D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBeZeroMatcher.h + path + Classes/KWBeZeroMatcher.h + sourceTree + <group> + + 964E357A15BC47F3AEFE43C1 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWAfterAllNode.h + path + Classes/KWAfterAllNode.h + sourceTree + <group> + + 9670F77F354A47A28AC129D7 + + fileRef + 151056C67969419AA3769211 + isa + PBXBuildFile + + 975DCB1B741E4B6BBC32B3D3 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBeBetweenMatcher.m + path + Classes/KWBeBetweenMatcher.m + sourceTree + <group> + + 97ECFDA7C11943FAB73791A5 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWExampleGroupBuilder.h + path + Classes/KWExampleGroupBuilder.h + sourceTree + <group> + + 98162B13CAA44893A9AAAE03 + + fileRef + 66F71FB6F6DF43F9AB4A2FF9 + isa + PBXBuildFile + + 9878EAC5217D41F087376365 + + fileRef + D9BAE52757AC408E9C05107A + isa + PBXBuildFile + + 98904853EB564D7996B465FB + + fileRef + 7C445B88E7D7455DA3BBA9AF + isa + PBXBuildFile + + 98E00E4286A042BBB547CE8C + + fileRef + 5C8557CF54C5416F85E68518 + isa + PBXBuildFile + + 9902146426A44889A795C286 + + fileRef + 975DCB1B741E4B6BBC32B3D3 + isa + PBXBuildFile + + 99EB9FF727914262B6C8E433 + + children + + 1604C4170864429F98504E49 + 840628C3DF654C6B93CC21C6 + F52295B4915E4CD5B650D005 + 5AB371818BC4432EB127DE31 + CBF970AC040F4030A6ACC20B + + isa + PBXGroup + sourceTree + <group> + + 9A573C8270DE4307841AD429 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWMatcher.h + path + Classes/KWMatcher.h + sourceTree + <group> + + 9A9DD290198649ECAB9D6E46 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBeIdenticalToMatcher.h + path + Classes/KWBeIdenticalToMatcher.h + sourceTree + <group> + + 9AF2FAE5486D48818B2E21D4 + + fileRef + 8FA930996A55476F932FDE4D + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + 9AF9B17A77B44CB08BAFEF91 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + VLBMacros.h + path + VLBFoundation/VLBMacros.h + sourceTree + <group> + + 9B35367EBB5F40E6A0CA9706 + + children + + 789ECDF5086D444FBE9631BF + 084647FB89B5417AB6D97FB5 + 4380C4DA489D4B95A7A91E90 + 48B64D578CC9480986428E1C + BEF241A43AD74C6096CDD803 + 808F04F665AC4ED8BF73B9DF + + isa + PBXGroup + name + Pods + sourceTree + <group> + + 9B7C5E6ABF0D4BA2815A3432 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWHaveValueMatcher.m + path + Classes/KWHaveValueMatcher.m + sourceTree + <group> + + 9C083CC54D76448C97CDA77F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBeSubclassOfClassMatcher.m + path + Classes/KWBeSubclassOfClassMatcher.m + sourceTree + <group> + + 9C15F28EB97143AE96B7E768 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSInvocation+KiwiAdditions.h + path + Classes/NSInvocation+KiwiAdditions.h + sourceTree + <group> + + 9C42316E27D6402698F1C4A3 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSObject+KiwiStubAdditions.h + path + Classes/NSObject+KiwiStubAdditions.h + sourceTree + <group> + + 9C8E45406A7A424A8CEABD89 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWStub.h + path + Classes/KWStub.h + sourceTree + <group> + + 9D9272C5137B424B8B2D41E2 + + fileRef + 848E986DFDCA4687823873C0 + isa + PBXBuildFile + + 9D9EFFB7F3A44CA190529407 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-UnitTests-Kiwi.xcconfig + sourceTree + <group> + + 9DA11B0EB68A4C7F9CB40831 + + fileRef + 94AD633C3A434EC6AE478FA7 + isa + PBXBuildFile + + 9DA4245402474DC3A18AD54A + + fileRef + 151E98A46C68434C90DC17C1 + isa + PBXBuildFile + + 9E139C1E3D83496BAF62DCC8 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCProtocolMockObject.m + path + Source/OCMock/OCProtocolMockObject.m + sourceTree + <group> + + 9E57C8D2B4B54CF880860847 + + fileRef + EAD86ABC219C4D25ACC8B0C4 + isa + PBXBuildFile + + 9F36157ED9EA47AC9BB478CC + + fileRef + 56FC2CE32EF748219BB40A9F + isa + PBXBuildFile + + 9F3E6171410F46AEA6E06CA4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWContainMatcher.h + path + Classes/KWContainMatcher.h + sourceTree + <group> + + 9F662F34ED4843BCB6E5BBFA + + children + + A75F896BEEDB4B5A95C16B05 + D8EAB6F3EC064D2DA39DC3B7 + FFFAFFFDE5B64DB6903E2F37 + 0AA7A9A4A11B42F585A2077C + 64AE571089DA4191AA13CD13 + D187CF337E5340A1A8EBB141 + + isa + PBXGroup + name + Pods-UnitTests + sourceTree + <group> + + 9F6723F650A84DB5BA9F175D + + fileRef + 1452A8B9B8CB454A8A583A7C + isa + PBXBuildFile + + A175118AB1BC4136B9B51773 + + fileRef + 82B2231B0ECF4A5D9AB5495C + isa + PBXBuildFile + + A17550E6131D480E83D974D7 + + fileRef + 6EAE1B4E3FA74CBFA4E103BE + isa + PBXBuildFile + + A1BCDAA63CE64D55930678F6 + + fileRef + 248503F568F74FC5BA26247F + isa + PBXBuildFile + + A2412F7880ED43098DF25570 + + baseConfigurationReference + A75F896BEEDB4B5A95C16B05 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + A2E34A0DDD984239B91E77E1 + + fileRef + 6DDE908C1D014DF2A9237B45 + isa + PBXBuildFile + + A33EFCAF67CC46BEB7DF6961 + + buildConfigurations + + DD5CFE8011AE4BBEB35967DE + 47EED8FAF4F74D96B8C82AF3 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + A347E66EF2FC41E1AD9E65E7 + + fileRef + 7547A2DCCB58438DBE7FCE2E + isa + PBXBuildFile + + A372A182EC3A4339B9C869FC + + fileRef + DBBD3E9283BE402482D928BA + isa + PBXBuildFile + + A3CE512AE507454A804A88AD + + fileRef + E3D819D86A834C71B95CA1BF + isa + PBXBuildFile + + A3FFCEA6BDF44EC59BF9DA00 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWPendingNode.m + path + Classes/KWPendingNode.m + sourceTree + <group> + + A42411FB09404932B1B7515A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-VLBFoundation-Private.xcconfig + sourceTree + <group> + + A434C123AC6C498CB8D0B058 + + buildActionMask + 2147483647 + files + + F451775F4FF4487588A912B0 + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + A44E2D71F5014CC2BF1B9FF0 + + fileRef + 1A75AEE9D63F405FB615244D + isa + PBXBuildFile + + A4856330EE8044F79DC17088 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWDeviceInfo.h + path + Classes/KWDeviceInfo.h + sourceTree + <group> + + A4D9047FD2794958A878186C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCPartialMockRecorder.h + path + Source/OCMock/OCPartialMockRecorder.h + sourceTree + <group> + + A518FF7796E74B4CAD8B39C7 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCClassMockObject.m + path + Source/OCMock/OCClassMockObject.m + sourceTree + <group> + + A52BDE689ACA4A28A949FDF7 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWExample.h + path + Classes/KWExample.h + sourceTree + <group> + + A54FE47F8171499C8CB0159F + + fileRef + 2F578BCEC37B4254B4ABF002 + isa + PBXBuildFile + + A56CD8A217824623BCD642D6 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWHaveMatcher.m + path + Classes/KWHaveMatcher.m + sourceTree + <group> + + A57BA61462AC44C7B2E3F37E + + fileRef + 964E357A15BC47F3AEFE43C1 + isa + PBXBuildFile + + A68489497CC14845ABD4EC56 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCMIndirectReturnValueProvider.m + path + Source/OCMock/OCMIndirectReturnValueProvider.m + sourceTree + <group> + + A6C54BA8D5EC4580B33D18C5 + + fileRef + 33B6E18ED07D4CC9B5BE81AE + isa + PBXBuildFile + + A75F896BEEDB4B5A95C16B05 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-UnitTests.xcconfig + sourceTree + <group> + + A83FC1D68B914EEF89759EB4 + + buildConfigurations + + DC3FDF49696C4687840CD897 + 29870C4CE9774F3E9BE5DDC9 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + A84DDCE2A10140A4B4FBC506 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBeEmptyMatcher.h + path + Classes/KWBeEmptyMatcher.h + sourceTree + <group> + + A894C7BAB81E42C4B6E29EA6 + + baseConfigurationReference + 7EE630493F6F427D9D2DB13F + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Pods-UnitTests-CocoaLumberjack-prefix.pch + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + A8D1412974344204950DC86C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWCallSite.h + path + Classes/KWCallSite.h + sourceTree + <group> + + A8E9F7217400459D93310D05 + + fileRef + B75DD7DF6D6748C291BDB131 + isa + PBXBuildFile + + A9BB15A8CBFB401CAE8D9010 + + fileRef + 81070F9BAAE84653ACC185CC + isa + PBXBuildFile + + A9C8E4FF4CF0464BA192A670 + + fileRef + A84DDCE2A10140A4B4FBC506 + isa + PBXBuildFile + + AA039908D4384594875633A4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-UnitTests-VLBFoundation-dummy.m + sourceTree + <group> + + AA054C90CF1C44A5A69B477C + + buildConfigurations + + 41E647DB70DD432298E224FA + 34CA30117E13479C93BF0DEE + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + AA298D4D3A094E1298FDBDD9 + + fileRef + 64690C9DF0B94BBCA3D367AF + isa + PBXBuildFile + + AA39CD948D6743718D1943A4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-CocoaLumberjack.xcconfig + sourceTree + <group> + + AA8C8050FB4340F48D69BC9E + + fileRef + 06D9B225A8504500AE75D71B + isa + PBXBuildFile + + AB456F4BD524441FB0D30E11 + + fileRef + 453B9B7DBC8A4151B6E60F36 + isa + PBXBuildFile + + ABAC88EC19A94827BA7646ED + + fileRef + C85C8614E1B543189238662C + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + AC19FE9AD1E749208B74F269 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWValue.m + path + Classes/KWValue.m + sourceTree + <group> + + AC468E25708C44439B0580FD + + fileRef + CB3E5E2A15BE479892C79911 + isa + PBXBuildFile + + AD53D116951B4F929F4F990C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSValue+KiwiAdditions.h + path + Classes/NSValue+KiwiAdditions.h + sourceTree + <group> + + AE4C1F3BE3864AD1AA7F96DA + + fileRef + 3E5EAE6AB6F5483AAC9C49F9 + isa + PBXBuildFile + + AE5BC1A780F34C1387284707 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWStringUtilities.h + path + Classes/KWStringUtilities.h + sourceTree + <group> + + AE9E612CB9CA4FE5BEE4BEE5 + + fileRef + FFB75DDC829849B192496C3F + isa + PBXBuildFile + + AF23259EF2244B8C98AF8A64 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCMBlockCaller.m + path + Source/OCMock/OCMBlockCaller.m + sourceTree + <group> + + AF30BF6C31AF48E784E5D9AF + + children + + 0AE4CB00CF524C83BE349517 + EC239C20E4EC4AB6BCB865E0 + 93ABE810C75D45118ACA1381 + 2992CDD17D454FC1AD0E15FB + + isa + PBXGroup + name + Support Files + sourceTree + SOURCE_ROOT + + AFCE0DA00DFD4B6AAC1F4903 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWMatcherFactory.m + path + Classes/KWMatcherFactory.m + sourceTree + <group> + + AFE2E61751E74D809B4A342F + + fileRef + 56BA77BE81A04BDB8E451E3F + isa + PBXBuildFile + + AFE8A5FCC8CF447489AF2B84 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWRegisterMatchersNode.h + path + Classes/KWRegisterMatchersNode.h + sourceTree + <group> + + B0035F552DBC4252AF63B1A9 + + fileRef + AD53D116951B4F929F4F990C + isa + PBXBuildFile + + B05BE7AA106E4E2B930BB862 + + fileRef + 00FAA90E6D7F43118C0F6DB5 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + B2F72827D1F24CB194979357 + + fileRef + 0D0984F7EC6C43E198F39846 + isa + PBXBuildFile + + B30F9DA32E3F45C9B9980DFD + + children + + AA39CD948D6743718D1943A4 + 272ECD3F376C426693FAACD5 + B610BD7A5ADD44A2A2FECE85 + 5CF1BD904FAF4277A4A8352F + 7893E443E3F346328058F24F + 7EE630493F6F427D9D2DB13F + 27800A166E224D4782041F9F + 4F715407345D4D29AEC7E0C0 + + isa + PBXGroup + name + Support Files + sourceTree + SOURCE_ROOT + + B385CF2FB5944607963014C6 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSNumber+KiwiAdditions.m + path + Classes/NSNumber+KiwiAdditions.m + sourceTree + <group> + + B4808F054BCF42D6A2DCA4E0 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWRespondToSelectorMatcher.m + path + Classes/KWRespondToSelectorMatcher.m + sourceTree + <group> + + B4ACDC4134C8428BBABCC7B4 + + fileRef + 8E5AE2BE8E434E3AAED5BADD + isa + PBXBuildFile + + B4E201BAA95E42DDBF943779 + + baseConfigurationReference + D79870C993384021B89C3243 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Pods-UnitTests-VLBFoundation-prefix.pch + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + B4FE6DFEE5A14C519286EF06 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSMethodSignature+KiwiAdditions.m + path + Classes/NSMethodSignature+KiwiAdditions.m + sourceTree + <group> + + B5223FE66BDE468095CC6331 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWInequalityMatcher.m + path + Classes/KWInequalityMatcher.m + sourceTree + <group> + + B610BD7A5ADD44A2A2FECE85 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-CocoaLumberjack-dummy.m + sourceTree + <group> + + B6EC75421B31458DB61B8BD0 + + fileRef + A56CD8A217824623BCD642D6 + isa + PBXBuildFile + + B75DD7DF6D6748C291BDB131 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBeforeEachNode.h + path + Classes/KWBeforeEachNode.h + sourceTree + <group> + + B7FCAEF753C844508C75957C + + fileRef + 01AB5659FE9241038689FD57 + isa + PBXBuildFile + + B81180E55DFB4C589C3FA44E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWMatching.h + path + Classes/KWMatching.h + sourceTree + <group> + + B87E4FBAF54B42F5B18B7F3B + + buildActionMask + 2147483647 + files + + ABAC88EC19A94827BA7646ED + 2DC8FEA8E5BD44FE83286AF3 + 28E98EB14CDB4D70A386BA5C + F192EE8E59E741B4A506444A + B05BE7AA106E4E2B930BB862 + 10FCA8A2A5754B408CAAF626 + D7CE9BCAD6EF4498B574ED02 + C16D0A981CA946B39A0ED677 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + B932C762527847159FEFC7E4 + + fileRef + 47CCEFD1D7EB4EAEAC448F5C + isa + PBXBuildFile + + B9CC3FA07BCD4B108AB46F85 + + fileRef + BAB716179281414F82B1BCDC + isa + PBXBuildFile + + BA2C41F476874FE4B43A5A99 + + fileRef + 9AF9B17A77B44CB08BAFEF91 + isa + PBXBuildFile + + BA321641026C451489493E5B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWSpec.h + path + Classes/KWSpec.h + sourceTree + <group> + + BA891F5C951B45AEB0AF4D08 + + fileRef + 3B29C1D4651E4909A7F12DD9 + isa + PBXBuildFile + + BA93424266A74800B1E98EE9 + + fileRef + B385CF2FB5944607963014C6 + isa + PBXBuildFile + + BAB716179281414F82B1BCDC + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWFormatter.h + path + Classes/KWFormatter.h + sourceTree + <group> + + BAB79777092D448D9A29CD1D + + fileRef + 7B1E2BE7D276449CBB160CB0 + isa + PBXBuildFile + + BB35A75DC401410A8C9F4747 + + buildActionMask + 2147483647 + files + + 173B60F790FE4579B2547F8E + E59D658DA5AA4AA6A4A0E10E + 63FF6242C2734B31922435D0 + 5142CD36F8E840A98C5C4CEE + 9902146426A44889A795C286 + 1D4970EB4CF64FB1A126C9BC + 089BBF6BAA574DB5A8EBCE79 + C0417457FFE348508FB48506 + 122CE66D14584BF99DF20A18 + 5FBFCB258190433FA6C0F587 + 4E0AF3DE8446440CBD8DD99C + D8F84B156E984949B2456085 + A372A182EC3A4339B9C869FC + E8020472945D45EC9EDE0AEA + 67E91F2B2C694AE79AD06E81 + CCF1BF05C9C34EBBB523EFE7 + 1C50028B76CC45BC8F468914 + 4DA6664B887F4CEE800EBE1C + 75ADADE06DA541F5B0F44CDE + 2452E09D24E34E3598D53881 + B4ACDC4134C8428BBABCC7B4 + 4CF26262D7BE4FEBA3ACCE48 + BA891F5C951B45AEB0AF4D08 + 49349E57B46F4A86BA410194 + AE9E612CB9CA4FE5BEE4BEE5 + 86E983786BD54472BF166A88 + 31BAACEAC9C741E99D03B588 + 06CBDD05B623419B99097EC3 + 0216198B471E494A86990A72 + 243A839C1FB742AFB47451A5 + 68177922B3AC45C9B01E6408 + AB456F4BD524441FB0D30E11 + E5DAA50A12884A9F8C197BBA + 7C566FEF89244765AFC1D758 + C74EB32DC98A48CCBB19A0AB + F1D7B8CCF57647819B54C564 + 82CF689FB8EC466E8D910565 + B932C762527847159FEFC7E4 + B6EC75421B31458DB61B8BD0 + 876308926E034E298DA94147 + 178E3CE05FC146AEBDAA27DF + 2283168AF34A4154873911CC + A9BB15A8CBFB401CAE8D9010 + 126D2A6759D94F56B85C7859 + F4C405B69D284BEA8557EB4B + 8C8EF244252F49FAB163B66D + 23C86114432D43BABED43237 + 741CA305FBEA48F8B4099F42 + 3D546BB0FEAB4C15BAE6C818 + CB7D7374DF32462FB017E7E1 + 7D1C41E9A80E427683368945 + 9F6723F650A84DB5BA9F175D + 24C46E7F3563462ABFA08F50 + 6D57368E1A054788968D82B3 + 84DCF2520A93493EB9B651AB + B7FCAEF753C844508C75957C + AC468E25708C44439B0580FD + D22622AC238A40358423493A + 5DAB05A87B294C3AB15820E7 + D6D429B3C59D41F6A5DA7CEF + 87AAE59A065042D9BD68E5BF + 98E00E4286A042BBB547CE8C + A6C54BA8D5EC4580B33D18C5 + 6F3F78F404694F10AB1A76CD + FFDCB4D98B19407D89756AF9 + 232F16A6905F41EEB245A859 + C7A14A55A2CF4C09859062CF + 8A280FF00E534AE3B409421E + 035CDD9A9AD04611A124A0D2 + CCDC364CFB0242FAA0987381 + D252BF42F612400C9AF6350D + BA93424266A74800B1E98EE9 + 98904853EB564D7996B465FB + C854A452662E4404AF5DB39F + 64097FF8DB0F478693248229 + 44320CC871AF48B581C2576F + 950ACF936A5F4CE1ADC75154 + 742B5DA40EAA4D33A98B3DE6 + 4AE75555D809410495C55362 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + BBC23363061C4B2184772A70 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWContextNode.m + path + Classes/KWContextNode.m + sourceTree + <group> + + BC4D6554D0D0424DBF7EAF1A + + isa + PBXTargetDependency + target + D781C4F75B4C464486E9569A + targetProxy + 071234FFEDA54F6D9A776E83 + + BD4A3296D70245CC97613D24 + + fileRef + 1D10C584C2F94060B1E7BCAB + isa + PBXBuildFile + + BD819B61443E48AEBBE4E2F1 + + fileRef + CD4E895778324B55A60B0822 + isa + PBXBuildFile + + BE31C86F7819483AB2900902 + + fileRef + DCA42BA4E79B471B9690B526 + isa + PBXBuildFile + + BE4ED5A4DD334508B6277BF1 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCMNotificationPoster.m + path + Source/OCMock/OCMNotificationPoster.m + sourceTree + <group> + + BE9AC1FBD03C497DB3FB9E11 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWMock.m + path + Classes/KWMock.m + sourceTree + <group> + + BE9DE41BB9A14C27B476AA71 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWReporting.h + path + Classes/KWReporting.h + sourceTree + <group> + + BEF241A43AD74C6096CDD803 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-environment.h + sourceTree + <group> + + BFEE35B1906A4FA08FF3EC59 + + fileRef + 5598DDE9EA014EAA99B2A2EE + isa + PBXBuildFile + + C0417457FFE348508FB48506 + + fileRef + 4A6C338EAE7E48238D3B7D50 + isa + PBXBuildFile + + C0EBAD893511415992AB76BF + + buildActionMask + 2147483647 + files + + E4DE128393D9435F9D0D8E9F + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + C11E2A934CB94E4994DC8F8D + + buildActionMask + 2147483647 + files + + 9406803A3551474E893EC322 + 861E6C1FCDDF4A33B5BCD40B + 9AF2FAE5486D48818B2E21D4 + 911A1639AD3945AD81725058 + 772B4704E72D439C90869B99 + 7A85D5CCBCC44BF995939E02 + F0833DE4737F4A4F924FB89A + 6D64D8D0922A41219ADB7125 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + C154B55412DB492DB6EA44DE + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBlockNode.m + path + Classes/KWBlockNode.m + sourceTree + <group> + + C16D0A981CA946B39A0ED677 + + fileRef + 27800A166E224D4782041F9F + isa + PBXBuildFile + + C1A22CDEFF4A4FA5BF6D4D9A + + fileRef + 8A1C9C344FF54C9EB1733FED + isa + PBXBuildFile + + C1B59E413C5A4B049669AE01 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWExampleSuite.m + path + Classes/KWExampleSuite.m + sourceTree + <group> + + C266E5C196744E43B8576987 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSMethodSignature+KiwiAdditions.h + path + Classes/NSMethodSignature+KiwiAdditions.h + sourceTree + <group> + + C2A2FD87F77042FEB633C86A + + fileRef + FC7C92E1C7814B1BBC57E176 + isa + PBXBuildFile + + C2E918CA58E04BB384217490 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWGenericMatchEvaluator.h + path + Classes/KWGenericMatchEvaluator.h + sourceTree + <group> + + C34A7AF612C4461B91D0321E + + fileRef + 5F1463A3F0944FE5B14BE7A2 + isa + PBXBuildFile + + C381763F0A7846B0B7D7A56C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBeMemberOfClassMatcher.h + path + Classes/KWBeMemberOfClassMatcher.h + sourceTree + <group> + + C46259EB96C64FB7BE40E0CC + + buildActionMask + 2147483647 + files + + 42B9EB3C734540A685BDDAEF + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + C4879E86DD07410380F25654 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + DDTTYLogger.h + path + Lumberjack/DDTTYLogger.h + sourceTree + <group> + + C4F289B6DC724DD689793632 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBlock.h + path + Classes/KWBlock.h + sourceTree + <group> + + C54C19CAD49E497A8512BC73 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-UnitTests-VLBFoundation.a + sourceTree + BUILT_PRODUCTS_DIR + + C54D5B20FD074B78B86ECD43 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWMatchers.h + path + Classes/KWMatchers.h + sourceTree + <group> + + C58971B67AAB4CC2A5737A2A + + fileRef + D268DDFE2A7E418F82EA3F22 + isa + PBXBuildFile + + C5B8B69668BF4B618EC9C62A + + buildConfigurations + + 65AE80B513B14050891F1622 + DDA467D26ADA4D6B9CF5E0EC + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + C5C44CA0903A4176A377863A + + fileRef + 93ABE810C75D45118ACA1381 + isa + PBXBuildFile + + C62CA5B9CF0049B182C971AE + + fileRef + A518FF7796E74B4CAD8B39C7 + isa + PBXBuildFile + + C66D3E39ABB14FC5A5B92677 + + fileRef + F40669C7442A4A3693995655 + isa + PBXBuildFile + + C6DA4E53441440EB95F79790 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWAny.m + path + Classes/KWAny.m + sourceTree + <group> + + C74EB32DC98A48CCBB19A0AB + + fileRef + 357F92EAE84344798ABBE168 + isa + PBXBuildFile + + C7A14A55A2CF4C09859062CF + + fileRef + AC19FE9AD1E749208B74F269 + isa + PBXBuildFile + + C7B82C6600AE449085458D1F + + fileRef + 35722B7C0773444A90A4239C + isa + PBXBuildFile + + C854A452662E4404AF5DB39F + + fileRef + D688BD734FD74153A6CE6AD0 + isa + PBXBuildFile + + C85C8614E1B543189238662C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + ContextFilterLogFormatter.m + path + Lumberjack/Extensions/ContextFilterLogFormatter.m + sourceTree + <group> + + C8678C205C6640ACA84AE954 + + fileRef + C266E5C196744E43B8576987 + isa + PBXBuildFile + + C8C3925E2F6740EE958EFFFA + + baseConfigurationReference + 1C40E59264ED4D0C8E674E2F + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Pods-UnitTests-Kiwi-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + C8F97772BC004F7580E7E1A8 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBlockRaiseMatcher.m + path + Classes/KWBlockRaiseMatcher.m + sourceTree + <group> + + C91150BAB9AD4C16B993CE7B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + DDTTYLogger.m + path + Lumberjack/DDTTYLogger.m + sourceTree + <group> + + C93444EC84394BEB9AF907A2 + + fileRef + 8076A47287CB4F8B87AC86DD + isa + PBXBuildFile + + C9F34675E1D94703BC85C923 + + fileRef + AF23259EF2244B8C98AF8A64 + isa + PBXBuildFile + + CAFE9DCAEEA04DE483D38FD5 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWMessageTracker.h + path + Classes/KWMessageTracker.h + sourceTree + <group> + + CB3E5E2A15BE479892C79911 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWReceiveMatcher.m + path + Classes/KWReceiveMatcher.m + sourceTree + <group> + + CB6BEEC0E9BD4ED28F7004DF + + fileRef + 694001AC5429471FAF626F3E + isa + PBXBuildFile + + CB7D7374DF32462FB017E7E1 + + fileRef + E3AA9B6AFC47438BBBFDE4A3 + isa + PBXBuildFile + + CB87B075B57249A2A096F2B5 + + fileRef + 89F7B3F102F34D4CB875156A + isa + PBXBuildFile + + CBF2FBA9CE884F6EBC6D8588 + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + SenTestingKit.framework + path + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/SenTestingKit.framework + sourceTree + DEVELOPER_DIR + + CBF970AC040F4030A6ACC20B + + children + + 9B35367EBB5F40E6A0CA9706 + 9F662F34ED4843BCB6E5BBFA + + isa + PBXGroup + name + Targets Support Files + sourceTree + <group> + + CCDC364CFB0242FAA0987381 + + fileRef + 45AD9F45E093468391227EB3 + isa + PBXBuildFile + + CCF1BF05C9C34EBBB523EFE7 + + fileRef + 55FB86EEFFEF4235862FEF9C + isa + PBXBuildFile + + CD0252BB0DE64E968283C908 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWFutureObject.h + path + Classes/KWFutureObject.h + sourceTree + <group> + + CD4E895778324B55A60B0822 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWExampleSuite.h + path + Classes/KWExampleSuite.h + sourceTree + <group> + + CE6DF279FFEB41B0963B9461 + + fileRef + 56D75A59ECD04319A5F42A45 + isa + PBXBuildFile + + CF68AB5780C6478FBD3727EA + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWInequalityMatcher.h + path + Classes/KWInequalityMatcher.h + sourceTree + <group> + + CFA482AD6223477C9CA05509 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMConstraint.h + path + Source/OCMock/OCMConstraint.h + sourceTree + <group> + + CFC493FD5DA04B7FB6ACF593 + + buildActionMask + 2147483647 + files + + 2717FEB554024156A5F82E73 + 27910367AB8C44029E27E3B5 + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + D02CBCC3D7F24CEF8C2CEB71 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBlock.m + path + Classes/KWBlock.m + sourceTree + <group> + + D1282DA7BEF042E8B8377279 + + buildActionMask + 2147483647 + files + + 850A25AFC37548FBB7BF4503 + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + D149EAB9D30949B9A04EF6CC + + fileRef + 5DE8EE24336040C6B70A86A6 + isa + PBXBuildFile + + D187CF337E5340A1A8EBB141 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.script.sh + path + Pods-UnitTests-resources.sh + sourceTree + <group> + + D18E6B06386C4FB4A06CE4FF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KiwiMacros.h + path + Classes/KiwiMacros.h + sourceTree + <group> + + D1A6FF6D7EF74D9BBC91FA36 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-VLBFoundation.a + sourceTree + BUILT_PRODUCTS_DIR + + D1F41A2DED414A64854DBCCE + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWFormatter.m + path + Classes/KWFormatter.m + sourceTree + <group> + + D1F84C8C76CC4A23906BA4AD + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWGenericMatcher.m + path + Classes/KWGenericMatcher.m + sourceTree + <group> + + D22622AC238A40358423493A + + fileRef + FECC6D0691B94D35AC41F46A + isa + PBXBuildFile + + D252BF42F612400C9AF6350D + + fileRef + B4FE6DFEE5A14C519286EF06 + isa + PBXBuildFile + + D25C0219AAD54833BA8088C2 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBeWithinMatcher.m + path + Classes/KWBeWithinMatcher.m + sourceTree + <group> + + D268DDFE2A7E418F82EA3F22 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMockRecorder.h + path + Source/OCMock/OCMockRecorder.h + sourceTree + <group> + + D2C1E42347BE4534B4D189F2 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCMArg.m + path + Source/OCMock/OCMArg.m + sourceTree + <group> + + D4C6D94092D54C88AF8131C2 + + fileRef + C381763F0A7846B0B7D7A56C + isa + PBXBuildFile + + D59F19CE3FD648DDB9B677E8 + + isa + PBXTargetDependency + target + 0FBA129B61B4442A9602F6A9 + targetProxy + 7DE5A24BAAE94F78964B7D10 + + D647D76E4297401A80D267B4 + + buildConfigurations + + C8C3925E2F6740EE958EFFFA + 6D419600AA23424383D69069 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + D687DE72EA5C4D85A7B10879 + + fileRef + 56FC2CE32EF748219BB40A9F + isa + PBXBuildFile + + D688BD734FD74153A6CE6AD0 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSObject+KiwiSpyAdditions.m + path + Classes/NSObject+KiwiSpyAdditions.m + sourceTree + <group> + + D6D429B3C59D41F6A5DA7CEF + + fileRef + 31EA73E3B88B4008B33E3BFB + isa + PBXBuildFile + + D75152D8625743E68672846B + + children + + E5A752DC4D694CD8AA941BDE + C85C8614E1B543189238662C + 23D6199981254F8688C3CC51 + 3C1221BA5B684C1893006C13 + 4F7DFF809AEC4390A018457D + 8FA930996A55476F932FDE4D + 22CD521A310547CD95E3E7F2 + 93819543C2F24C9B85D1ECFA + 88897762E1DB42CEA21B9073 + 00FAA90E6D7F43118C0F6DB5 + C4879E86DD07410380F25654 + C91150BAB9AD4C16B993CE7B + 02528A11FCD848F3B24E24B3 + E5856B3A01B444CE90F9062C + B30F9DA32E3F45C9B9980DFD + + isa + PBXGroup + name + CocoaLumberjack + path + CocoaLumberjack + sourceTree + <group> + + D781C4F75B4C464486E9569A + + buildConfigurationList + A33EFCAF67CC46BEB7DF6961 + buildPhases + + 732C92250677421785717247 + 0F06C4E43AD649D3A7B847B8 + 547ABC679A2F43479B874A17 + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-UnitTests-OCMock + productName + Pods-UnitTests-OCMock + productReference + 0C428E5F278A4B24A61CAAF2 + productType + com.apple.product-type.library.static + + D79870C993384021B89C3243 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-UnitTests-VLBFoundation-Private.xcconfig + sourceTree + <group> + + D7CE9BCAD6EF4498B574ED02 + + fileRef + E5856B3A01B444CE90F9062C + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + D841148CA16E4D138B7A5869 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCPartialMockObject.m + path + Source/OCMock/OCPartialMockObject.m + sourceTree + <group> + + D8EAB6F3EC064D2DA39DC3B7 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text + path + Pods-UnitTests-acknowledgements.markdown + sourceTree + <group> + + D8F84B156E984949B2456085 + + fileRef + 9C083CC54D76448C97CDA77F + isa + PBXBuildFile + + D9BAE52757AC408E9C05107A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWInvocationCapturer.h + path + Classes/KWInvocationCapturer.h + sourceTree + <group> + + D9D31291F7224E5EB1641FF4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWConformToProtocolMatcher.h + path + Classes/KWConformToProtocolMatcher.h + sourceTree + <group> + + DA93D3859B8B40368F38D003 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWMatcherFactory.h + path + Classes/KWMatcherFactory.h + sourceTree + <group> + + DADB6E6B35244391B8C1D345 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWMatchVerifier.m + path + Classes/KWMatchVerifier.m + sourceTree + <group> + + DAF9CF2174AC4B8ABC5939D5 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCClassMockObject.h + path + Source/OCMock/OCClassMockObject.h + sourceTree + <group> + + DB65414E461F4117A9F6E94D + + fileRef + 56FC2CE32EF748219BB40A9F + isa + PBXBuildFile + + DB954B5437E546248B77980F + + fileRef + C4F289B6DC724DD689793632 + isa + PBXBuildFile + + DBBD3E9283BE402482D928BA + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBeTrueMatcher.m + path + Classes/KWBeTrueMatcher.m + sourceTree + <group> + + DC38F59C0C7A4E7292843699 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + OCObserverMockObject.m + path + Source/OCMock/OCObserverMockObject.m + sourceTree + <group> + + DC3FDF49696C4687840CD897 + + baseConfigurationReference + A42411FB09404932B1B7515A + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Pods-VLBFoundation-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + DCA2DDE2BEBA42CEAEFABD39 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWExample.m + path + Classes/KWExample.m + sourceTree + <group> + + DCA42BA4E79B471B9690B526 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWGenericMatcher.h + path + Classes/KWGenericMatcher.h + sourceTree + <group> + + DCC1EC4014574B518B077F31 + + children + + 964E357A15BC47F3AEFE43C1 + 5B1A50542D644B51BADA856E + 64690C9DF0B94BBCA3D367AF + 4DDC75E2432D40069C5CDCC4 + 219E82EC6E4D4BA59D10E872 + C6DA4E53441440EB95F79790 + 6DDE908C1D014DF2A9237B45 + EE896E9C37E74F2A8EFC0714 + FD474B4945BC4BFB8B7E4FFC + 975DCB1B741E4B6BBC32B3D3 + A84DDCE2A10140A4B4FBC506 + 7F05BB47EBFC40998744E733 + 9A9DD290198649ECAB9D6E46 + 4F3898891BE042D398E93C6A + 7C2974883AD347C79346007A + 4A6C338EAE7E48238D3B7D50 + C381763F0A7846B0B7D7A56C + 3CDC72F8A3544377834F5A1A + 0D0984F7EC6C43E198F39846 + 5653AD9B53584A7EBE0C50F2 + 694001AC5429471FAF626F3E + 893CF0638DAB4DF3A853B36C + 8A1C9C344FF54C9EB1733FED + 9C083CC54D76448C97CDA77F + 4D0D8E95D26644C880032E91 + DBBD3E9283BE402482D928BA + 45D6D18EE14549ACADBEB99E + D25C0219AAD54833BA8088C2 + 95EC90A5F6554A85890C333D + E8D5ABDD703D4DBFB1B17848 + 119C5659662144F4A82E1C32 + 55FB86EEFFEF4235862FEF9C + B75DD7DF6D6748C291BDB131 + 1587952DBC5244038D493A61 + C4F289B6DC724DD689793632 + D02CBCC3D7F24CEF8C2CEB71 + 7069CC77FB954200A2A00B4B + C154B55412DB492DB6EA44DE + 630E321AC2C9488C9036AE7C + C8F97772BC004F7580E7E1A8 + A8D1412974344204950DC86C + 8E5AE2BE8E434E3AAED5BADD + 57B7BC74DED54238989776E7 + 52B8DA1F77774F1BBFE03723 + 2FCB3792BD8C407DA3ACA95C + 3B29C1D4651E4909A7F12DD9 + D9D31291F7224E5EB1641FF4 + 0D0345D4FDFD49DA82D1BD63 + 9F3E6171410F46AEA6E06CA4 + FFB75DDC829849B192496C3F + 1D10C584C2F94060B1E7BCAB + BBC23363061C4B2184772A70 + 56BA77BE81A04BDB8E451E3F + A4856330EE8044F79DC17088 + 564EA32B161E4C1D9FF80DC8 + 1BD2D3C92FF640FCA98B7367 + 16B5F03C94EE426D90A3F9FF + A52BDE689ACA4A28A949FDF7 + DCA2DDE2BEBA42CEAEFABD39 + 97ECFDA7C11943FAB73791A5 + 123DED21C2674E1290469787 + 56D75A59ECD04319A5F42A45 + 7547A2DCCB58438DBE7FCE2E + 2FE6B55C721545328FDBF021 + CD4E895778324B55A60B0822 + C1B59E413C5A4B049669AE01 + 5A06B7D8F6A0498CA786F29F + 453B9B7DBC8A4151B6E60F36 + 74630004768B43299BB49714 + 663FAB73084240D782144B3E + 84A06998F7224A448A70BF22 + BAB716179281414F82B1BCDC + D1F41A2DED414A64854DBCCE + CD0252BB0DE64E968283C908 + 357F92EAE84344798ABBE168 + C2E918CA58E04BB384217490 + 8EE4E45D252F4B85A43700EF + DCA42BA4E79B471B9690B526 + D1F84C8C76CC4A23906BA4AD + 5C72ADEF282941A187547EA4 + 47CCEFD1D7EB4EAEAC448F5C + 154264DB08074A5CABB5AE25 + A56CD8A217824623BCD642D6 + 848E986DFDCA4687823873C0 + 9B7C5E6ABF0D4BA2815A3432 + CF68AB5780C6478FBD3727EA + B5223FE66BDE468095CC6331 + 22752DE780F2420C9C3F80B1 + FC4F7838F8C94C9C9BDDA462 + D9BAE52757AC408E9C05107A + 81070F9BAAE84653ACC185CC + 2ED7222FDA524035A12E3EDF + 83C907C51842492A81A95A6F + EAD86ABC219C4D25ACC8B0C4 + DADB6E6B35244391B8C1D345 + 9A573C8270DE4307841AD429 + E6815438D9374F04B720B4C7 + DA93D3859B8B40368F38D003 + AFCE0DA00DFD4B6AAC1F4903 + C54D5B20FD074B78B86ECD43 + 4E2C9BAF89FE4E0AB781BE00 + B81180E55DFB4C589C3FA44E + 42C18AD8A8DE414FA6828FFA + 2311871F694F4BEDB3A8544A + 6EAE1B4E3FA74CBFA4E103BE + CAFE9DCAEEA04DE483D38FD5 + E3AA9B6AFC47438BBBFDE4A3 + DE42B001360E49D68AD3B861 + BE9AC1FBD03C497DB3FB9E11 + 2161A8FA3B36491C83C12118 + 1452A8B9B8CB454A8A583A7C + 82B2231B0ECF4A5D9AB5495C + 0E2606EBFEBB4D0D97797E65 + 35EDD8F81C134AC687B1F0EB + A3FFCEA6BDF44EC59BF9DA00 + 151056C67969419AA3769211 + FA38283E9DEC49A48F999C3B + EE133A054BDD4A8C9458DAB6 + E3D819D86A834C71B95CA1BF + 01AB5659FE9241038689FD57 + 65D551FCCEDA42D1A635032C + CB3E5E2A15BE479892C79911 + AFE8A5FCC8CF447489AF2B84 + FECC6D0691B94D35AC41F46A + BE9DE41BB9A14C27B476AA71 + 89F7B3F102F34D4CB875156A + B4808F054BCF42D6A2DCA4E0 + BA321641026C451489493E5B + 31EA73E3B88B4008B33E3BFB + E5FE56EF52A94BB3A5E96CD8 + 4D74CCEB004C4F578ACBE306 + 6DFD05ECE30F4FFBB527C526 + 5C8557CF54C5416F85E68518 + AE5BC1A780F34C1387284707 + 33B6E18ED07D4CC9B5BE81AE + 9C8E45406A7A424A8CEABD89 + 06B83EC8C24A41C5AF77F234 + 750A2ABA92FA47FF9CEE3F21 + E4547DB0247F4CCC9AC74D73 + F40669C7442A4A3693995655 + E9D22B81DC694D61B8F61BC4 + EEFF537C453E4725BFCC981C + AC19FE9AD1E749208B74F269 + 747F6B50A23A4007A405F281 + 3FC7E5AAF10D413D860D4AAD + E25691B7830F41D9B8633C23 + 48C28A338854477091C392DC + 66F71FB6F6DF43F9AB4A2FF9 + 04E5E23C376041E3B37F0188 + D18E6B06386C4FB4A06CE4FF + 82F4563B311D47FA87A012F1 + 9C15F28EB97143AE96B7E768 + EFC06CED3626490FA4FC7F3D + FC7C92E1C7814B1BBC57E176 + 45AD9F45E093468391227EB3 + C266E5C196744E43B8576987 + B4FE6DFEE5A14C519286EF06 + 7B1E2BE7D276449CBB160CB0 + B385CF2FB5944607963014C6 + 35722B7C0773444A90A4239C + 7C445B88E7D7455DA3BBA9AF + 5DE8EE24336040C6B70A86A6 + D688BD734FD74153A6CE6AD0 + 9C42316E27D6402698F1C4A3 + 4D492F8CE6A848108604D42B + 6AD5AA4D934A4FA4BD9AA805 + DF989EB4144B45669D3BC987 + 7F658A7358A241A7A1942E7C + 1B6D7616CF4C4257BB3644EF + AD53D116951B4F929F4F990C + 3289CD5A569F426981A445DD + 592B69C778B24557B2B03661 + + isa + PBXGroup + name + Kiwi + path + Kiwi + sourceTree + <group> + + DD2691DC782C4F2A849C3DB6 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-VLBFoundation-dummy.m + sourceTree + <group> + + DD5CFE8011AE4BBEB35967DE + + baseConfigurationReference + EC239C20E4EC4AB6BCB865E0 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Pods-UnitTests-OCMock-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + DD6941E36EC5402CB64E633F + + fileRef + A52BDE689ACA4A28A949FDF7 + isa + PBXBuildFile + + DDA467D26ADA4D6B9CF5E0EC + + baseConfigurationReference + 789ECDF5086D444FBE9631BF + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + DE42B001360E49D68AD3B861 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWMock.h + path + Classes/KWMock.h + sourceTree + <group> + + DF989EB4144B45669D3BC987 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSObject+KiwiVerifierAdditions.m + path + Classes/NSObject+KiwiVerifierAdditions.m + sourceTree + <group> + + E048C3A41040472FA0883D07 + + fileRef + 3FC7E5AAF10D413D860D4AAD + isa + PBXBuildFile + + E199E308ABE749A78EF963D1 + + fileRef + 82F4563B311D47FA87A012F1 + isa + PBXBuildFile + + E1AB1C02919A47998D69B21A + + buildConfigurationList + 0467ED54EFFA488EBA9FCA62 + buildPhases + + F968E417FF7D4C05BB8E4E1B + 0EB28603707245AF8906432F + C0EBAD893511415992AB76BF + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-UnitTests-VLBFoundation + productName + Pods-UnitTests-VLBFoundation + productReference + C54C19CAD49E497A8512BC73 + productType + com.apple.product-type.library.static + + E23BA0F7BE2340C3A3092F6C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-UnitTests-VLBFoundation-prefix.pch + sourceTree + <group> + + E25691B7830F41D9B8633C23 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWWorkarounds.m + path + Classes/KWWorkarounds.m + sourceTree + <group> + + E3AA9B6AFC47438BBBFDE4A3 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWMessageTracker.m + path + Classes/KWMessageTracker.m + sourceTree + <group> + + E3D819D86A834C71B95CA1BF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWRaiseMatcher.h + path + Classes/KWRaiseMatcher.h + sourceTree + <group> + + E4547DB0247F4CCC9AC74D73 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWTestCase.m + path + Classes/KWTestCase.m + sourceTree + <group> + + E4DE128393D9435F9D0D8E9F + + fileRef + 9AF9B17A77B44CB08BAFEF91 + isa + PBXBuildFile + + E5856B3A01B444CE90F9062C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + DispatchQueueLogFormatter.m + path + Lumberjack/Extensions/DispatchQueueLogFormatter.m + sourceTree + <group> + + E59D658DA5AA4AA6A4A0E10E + + fileRef + 4DDC75E2432D40069C5CDCC4 + isa + PBXBuildFile + + E5A752DC4D694CD8AA941BDE + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + ContextFilterLogFormatter.h + path + Lumberjack/Extensions/ContextFilterLogFormatter.h + sourceTree + <group> + + E5D3A1725DA546DE8CB2CB6C + + buildActionMask + 2147483647 + files + + 52AF7231606C4501BCDFDC1A + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + E5DAA50A12884A9F8C197BBA + + fileRef + 84A06998F7224A448A70BF22 + isa + PBXBuildFile + + E5FE56EF52A94BB3A5E96CD8 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWStringContainsMatcher.h + path + Classes/KWStringContainsMatcher.h + sourceTree + <group> + + E667A92389F4469EB9D01ED2 + + fileRef + 630E321AC2C9488C9036AE7C + isa + PBXBuildFile + + E6815438D9374F04B720B4C7 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWMatcher.m + path + Classes/KWMatcher.m + sourceTree + <group> + + E6C418B02CD942A88F4DDA30 + + fileRef + 2FCB3792BD8C407DA3ACA95C + isa + PBXBuildFile + + E7CD5F673166423BA57DDE54 + + baseConfigurationReference + D79870C993384021B89C3243 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Pods-UnitTests-VLBFoundation-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + E8020472945D45EC9EDE0AEA + + fileRef + D25C0219AAD54833BA8088C2 + isa + PBXBuildFile + + E817D9B8CC51418EBB02D10C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-UnitTests-Kiwi-dummy.m + sourceTree + <group> + + E8D5ABDD703D4DBFB1B17848 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWBeZeroMatcher.m + path + Classes/KWBeZeroMatcher.m + sourceTree + <group> + + E9D22B81DC694D61B8F61BC4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWUserDefinedMatcher.m + path + Classes/KWUserDefinedMatcher.m + sourceTree + <group> + + EA42BF81F15746E5AC64DC7E + + fileRef + 23D6199981254F8688C3CC51 + isa + PBXBuildFile + + EAD86ABC219C4D25ACC8B0C4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWMatchVerifier.h + path + Classes/KWMatchVerifier.h + sourceTree + <group> + + EB9720A284D64E10B7041E03 + + fileRef + F513667F0B634C42A4EF312F + isa + PBXBuildFile + + EC239C20E4EC4AB6BCB865E0 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-UnitTests-OCMock-Private.xcconfig + sourceTree + <group> + + EC402269F3A344EF8D292398 + + buildActionMask + 2147483647 + files + + D687DE72EA5C4D85A7B10879 + 04F3958022C74505A00C6060 + AA8C8050FB4340F48D69BC9E + 7C7F4A0A2C8D45CE92FCD646 + 87ACA0034E374A5587719068 + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + EE133A054BDD4A8C9458DAB6 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWProbePoller.m + path + Classes/KWProbePoller.m + sourceTree + <group> + + EE896E9C37E74F2A8EFC0714 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWAsyncVerifier.m + path + Classes/KWAsyncVerifier.m + sourceTree + <group> + + EEFF537C453E4725BFCC981C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWValue.h + path + Classes/KWValue.h + sourceTree + <group> + + EF9B2EB23E864FC5A31275E2 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSInvocation+OCMAdditions.h + path + Source/OCMock/NSInvocation+OCMAdditions.h + sourceTree + <group> + + EFC06CED3626490FA4FC7F3D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSInvocation+KiwiAdditions.m + path + Classes/NSInvocation+KiwiAdditions.m + sourceTree + <group> + + F0833DE4737F4A4F924FB89A + + fileRef + E5856B3A01B444CE90F9062C + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + F0E54A2E819E480BA4A7BB59 + + fileRef + D1A6FF6D7EF74D9BBC91FA36 + isa + PBXBuildFile + + F192EE8E59E741B4A506444A + + fileRef + 93819543C2F24C9B85D1ECFA + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -fobjc-arc -DOS_OBJECT_USE_OBJC=0 + + + F1D7B8CCF57647819B54C564 + + fileRef + 8EE4E45D252F4B85A43700EF + isa + PBXBuildFile + + F247ABE403DD429D82167C00 + + fileRef + 97ECFDA7C11943FAB73791A5 + isa + PBXBuildFile + + F297C38516F74F8BAA70FA0B + + fileRef + 22752DE780F2420C9C3F80B1 + isa + PBXBuildFile + + F33D0835A9174FA79F9D29A7 + + fileRef + BE4ED5A4DD334508B6277BF1 + isa + PBXBuildFile + + F3E70B24B06144DEAC6A6BDA + + fileRef + 9E139C1E3D83496BAF62DCC8 + isa + PBXBuildFile + + F405A4D4E40243D8A0CBDA6C + + isa + PBXTargetDependency + target + 768F895B23B94C52A36EC63B + targetProxy + 2C266D1F4AFE4671846F567F + + F40669C7442A4A3693995655 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWUserDefinedMatcher.h + path + Classes/KWUserDefinedMatcher.h + sourceTree + <group> + + F444DD05FF014030812F4C36 + + baseConfigurationReference + 272ECD3F376C426693FAACD5 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Pods-CocoaLumberjack-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + GCC_VERSION + com.apple.compilers.llvm.clang.1_0 + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 6.0 + OTHER_LDFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + F451775F4FF4487588A912B0 + + fileRef + 56FC2CE32EF748219BB40A9F + isa + PBXBuildFile + + F4B8D3BA7387410E867E7931 + + fileRef + 9F3E6171410F46AEA6E06CA4 + isa + PBXBuildFile + + F4C405B69D284BEA8557EB4B + + fileRef + DADB6E6B35244391B8C1D345 + isa + PBXBuildFile + + F513667F0B634C42A4EF312F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + OCMBoxedReturnValueProvider.h + path + Source/OCMock/OCMBoxedReturnValueProvider.h + sourceTree + <group> + + F52295B4915E4CD5B650D005 + + children + + D75152D8625743E68672846B + DCC1EC4014574B518B077F31 + 3FBEF7951E18448CA75A1907 + 1D9B6DA82CD744A989904E5A + + isa + PBXGroup + name + Pods + sourceTree + <group> + + F687972FFD504AB2BAFA29FC + + fileRef + 65D551FCCEDA42D1A635032C + isa + PBXBuildFile + + F75E20DA865A407B8ED33F3B + + fileRef + B81180E55DFB4C589C3FA44E + isa + PBXBuildFile + + F8842EAF9B4747C08FCCC091 + + fileRef + 747F6B50A23A4007A405F281 + isa + PBXBuildFile + + F968E417FF7D4C05BB8E4E1B + + buildActionMask + 2147483647 + files + + FC6497110D1D4364BE764AA8 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + F99E1927E74F4AF9B0B576FE + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-UnitTests-VLBFoundation.xcconfig + sourceTree + <group> + + FA38283E9DEC49A48F999C3B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWProbePoller.h + path + Classes/KWProbePoller.h + sourceTree + <group> + + FA68A876112A4C58B012FBD3 + + fileRef + 9C42316E27D6402698F1C4A3 + isa + PBXBuildFile + + FC4F7838F8C94C9C9BDDA462 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWIntercept.m + path + Classes/KWIntercept.m + sourceTree + <group> + + FC6497110D1D4364BE764AA8 + + fileRef + AA039908D4384594875633A4 + isa + PBXBuildFile + + FC7C92E1C7814B1BBC57E176 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSInvocation+OCMAdditions.h + path + Classes/NSInvocation+OCMAdditions.h + sourceTree + <group> + + FC8C70D60B824E1D902A19DC + + fileRef + FA38283E9DEC49A48F999C3B + isa + PBXBuildFile + + FC90A76FEC0D491B9EF29454 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSNotificationCenter+OCMAdditions.m + path + Source/OCMock/NSNotificationCenter+OCMAdditions.m + sourceTree + <group> + + FCEE0B9AD0A74220A5208019 + + fileRef + 154264DB08074A5CABB5AE25 + isa + PBXBuildFile + + FD06F2408A4C4D39A461BF5B + + fileRef + 750A2ABA92FA47FF9CEE3F21 + isa + PBXBuildFile + + FD474B4945BC4BFB8B7E4FFC + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + KWBeBetweenMatcher.h + path + Classes/KWBeBetweenMatcher.h + sourceTree + <group> + + FE17C3F1EFCF4665A67F6CEF + + fileRef + 419BF12F732240D2AF093D33 + isa + PBXBuildFile + + FE62CD8148264AA8B096BE6E + + fileRef + FD474B4945BC4BFB8B7E4FFC + isa + PBXBuildFile + + FECC6D0691B94D35AC41F46A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWRegisterMatchersNode.m + path + Classes/KWRegisterMatchersNode.m + sourceTree + <group> + + FEF48B68DFE1460EA203723C + + fileRef + AE5BC1A780F34C1387284707 + isa + PBXBuildFile + + FFB75DDC829849B192496C3F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + KWContainMatcher.m + path + Classes/KWContainMatcher.m + sourceTree + <group> + + FFDCB4D98B19407D89756AF9 + + fileRef + E4547DB0247F4CCC9AC74D73 + isa + PBXBuildFile + + FFFAFFFDE5B64DB6903E2F37 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.plist.xml + path + Pods-UnitTests-acknowledgements.plist + sourceTree + <group> + + + rootObject + 62298A1970D14909914BA53E + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-CocoaLumberjack.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-CocoaLumberjack.xcscheme new file mode 100644 index 0000000..4e7d86d --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-CocoaLumberjack.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-CocoaLumberjack.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-CocoaLumberjack.xcscheme new file mode 100644 index 0000000..fe26cfb --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-CocoaLumberjack.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-Kiwi.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-Kiwi.xcscheme new file mode 100644 index 0000000..35d6899 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-Kiwi.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-OCMock.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-OCMock.xcscheme new file mode 100644 index 0000000..ebd877f --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-OCMock.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-VLBFoundation.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-VLBFoundation.xcscheme new file mode 100644 index 0000000..1eef1c4 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests-VLBFoundation.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests.xcscheme new file mode 100644 index 0000000..32b1f45 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-UnitTests.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-VLBFoundation.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-VLBFoundation.xcscheme new file mode 100644 index 0000000..40d9694 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods-VLBFoundation.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods.xcscheme new file mode 100644 index 0000000..a3d9a64 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/Pods.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/xcschememanagement.plist b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..78e4050 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/Brian.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,51 @@ + + + + + SchemeUserState + + Pods-CocoaLumberjack.xcscheme + + isShown + + + Pods-UnitTests-CocoaLumberjack.xcscheme + + isShown + + + Pods-UnitTests-Kiwi.xcscheme + + isShown + + + Pods-UnitTests-OCMock.xcscheme + + isShown + + + Pods-UnitTests-VLBFoundation.xcscheme + + isShown + + + Pods-UnitTests.xcscheme + + isShown + + + Pods-VLBFoundation.xcscheme + + isShown + + + Pods.xcscheme + + isShown + + + + SuppressBuildableAutocreation + + + diff --git a/Pods/VLBFoundation/LICENCE b/Pods/VLBFoundation/LICENCE new file mode 100644 index 0000000..5ea3d9e --- /dev/null +++ b/Pods/VLBFoundation/LICENCE @@ -0,0 +1,9 @@ +VLBFoundation published under the MIT license: + +Copyright (C) 2013, www.verylargebox.com + +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. diff --git a/Pods/VLBFoundation/README.md b/Pods/VLBFoundation/README.md new file mode 100644 index 0000000..fe1d89a --- /dev/null +++ b/Pods/VLBFoundation/README.md @@ -0,0 +1,46 @@ +# Introduction +A library of classes used throughout the codebase of verylargebox.app + + +# VLBMacros + +A collection of macro definitions, including the one to use when creating a [reusable UIView][1](s). + +# What is included + +* VLBFoundation +The 'VLBFoundation.xcodeproj' builds a static library 'libVLBFoundation.a' + +# Cocoapods + +Pending pull request. + +# Versions +1.0 initial version. Only macros available. + +# How to use + +N/A + +# Future Work + +TBD + +# Notes + +N/A + +# Licence + +VLBFoundation published under the MIT license: + +Copyright (C) 2013, www.verylargebox.com + +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. + + +[1]: http://qnoid.com/2013/03/20/How-to-implement-a-reusable-UIView.html diff --git a/Pods/VLBFoundation/VLBFoundation/VLBMacros.h b/Pods/VLBFoundation/VLBFoundation/VLBMacros.h new file mode 100644 index 0000000..c97caa9 --- /dev/null +++ b/Pods/VLBFoundation/VLBFoundation/VLBMacros.h @@ -0,0 +1,48 @@ +// +// VLBMacros.h +// VLBFoundation +// +// Created by Markos Charatzas on 21/04/2013. +// Copyright (c) 2013 verylargebox.com +// +// 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. +// + +#define VLB_LOAD_VIEW() \ +NSBundle *mainBundle = [NSBundle mainBundle]; \ +NSArray *views = [mainBundle loadNibNamed:NSStringFromClass([self class]) owner:self options:nil]; \ +[self addSubview:views[0]]; + +#define VLB_Integer(value) [NSNumber numberWithInt:value] + +#define VLB_INIT_OR_RETURN_NIL() \ +self = [super init]; \ +if (!self) { \ + return nil; \ +} + +#define VLB_IF_NOT_SELF_RETURN_NIL() \ +if (!self) { \ +return nil; \ +} + +#define VLB_RETURN_IF_NIL(obj) \ +if (!obj) { \ +return nil; \ +} diff --git a/VLBCameraView.xcworkspace/contents.xcworkspacedata b/VLBCameraView.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..b57c8d1 --- /dev/null +++ b/VLBCameraView.xcworkspace/contents.xcworkspacedata @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/VLBCameraView/VLBCameraView.m b/VLBCameraView/VLBCameraView.m index 1053f36..a6e7a45 100644 --- a/VLBCameraView/VLBCameraView.m +++ b/VLBCameraView/VLBCameraView.m @@ -54,11 +54,6 @@ - (void)retakePicture:(UITapGestureRecognizer*) tapToRetakeGesture; cameraView.videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:cameraView.session]; cameraView.videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; cameraView.videoPreviewLayer.frame = cameraView.layer.bounds; - - cameraView.flashView = [[UIView alloc] initWithFrame:cameraView.preview.bounds]; - cameraView.flashView.backgroundColor = [UIColor whiteColor]; - cameraView.flashView.alpha = 0.0f; - [cameraView.videoPreviewLayer addSublayer:cameraView.flashView.layer]; }; @implementation VLBCameraView @@ -114,6 +109,11 @@ -(VLBCaptureStillImageBlock) didFinishTakingPicture:(AVCaptureSession*) session kCMAttachmentMode_ShouldPropagate); NSDictionary *info = (__bridge NSDictionary*)attachments; + if(wself.cameraIsFrontFacing) { + image = [UIImage imageWithCGImage: image.CGImage scale:image.scale orientation:UIImageOrientationLeftMirrored]; + } + + if(wself.writeToCameraRoll) { [wself.delegate cameraView:wself willRriteToCameraRollWithMetadata:info]; @@ -129,9 +129,7 @@ -(VLBCaptureStillImageBlock) didFinishTakingPicture:(AVCaptureSession*) session dispatch_async(dispatch_get_main_queue(), ^(void) { preview.image = image; - [wself cameraView:wself didFinishTakingPicture:image withInfo:info meta:nil]; - CFRelease(attachments); }); }; @@ -186,7 +184,6 @@ -(void)cameraView:(VLBCameraView *)cameraView didFinishTakingPicture:(UIImage *) UIImage *newImage = [UIImage imageWithCGImage:imageRef scale:1.0f orientation:image.imageOrientation]; //preserve camera orientation CGImageRelease(imageRef); - [self.delegate cameraView:cameraView didFinishTakingPicture:newImage withInfo:info meta:@{VLBCameraViewMetaCrop:[NSValue valueWithCGRect:crop], @@ -200,11 +197,6 @@ -(void)cameraView:(VLBCameraView *)cameraView didErrorOnTakePicture:(NSError *)e - (void)takePicture { - [UIView animateWithDuration:0.4f - animations:^{ self.flashView.alpha = 1.0f; } - completion:^(BOOL finished){ self.flashView.alpha = 0.0f; } - ]; - VLBCaptureStillImageBlock didFinishTakingPicture = [self didFinishTakingPicture:self.session preview:self.preview]; From ba43c07642703e8c35489b1b4a8ca44fa82b8722 Mon Sep 17 00:00:00 2001 From: Brian Vallelunga Date: Sun, 17 Aug 2014 04:03:09 -0700 Subject: [PATCH 11/11] made session not private --- VLBCameraView/VLBCameraView.h | 10 +--------- VLBCameraView/VLBCameraView.m | 4 +--- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/VLBCameraView/VLBCameraView.h b/VLBCameraView/VLBCameraView.h index da5704c..dd98a8a 100644 --- a/VLBCameraView/VLBCameraView.h +++ b/VLBCameraView/VLBCameraView.h @@ -140,6 +140,7 @@ extern VLBCameraViewMeta const VLBCameraViewMetaOriginalImage; /// @property(nonatomic, assign) BOOL writeToCameraRoll; @property(nonatomic, assign) BOOL *cameraIsFrontFacing; +@property(nonatomic, strong) AVCaptureSession *session; /** @@ -147,15 +148,6 @@ extern VLBCameraViewMeta const VLBCameraViewMetaOriginalImage; @property(nonatomic, assign) IBOutlet NSObject* delegate; -/** - Set backgroundColor to a custom one - - backgroundColor = [UIColor whiteColor]; - - */ -@property(nonatomic, strong) UIView *flashView; - - /** Takes a still image of the current frame from the video feed. diff --git a/VLBCameraView/VLBCameraView.m b/VLBCameraView/VLBCameraView.m index a6e7a45..1d9b7b4 100644 --- a/VLBCameraView/VLBCameraView.m +++ b/VLBCameraView/VLBCameraView.m @@ -38,7 +38,6 @@ VLBCameraViewMeta const VLBCameraViewMetaOriginalImage = @"VLBCameraViewMetaOriginalImage"; @interface VLBCameraView () -@property(nonatomic, strong) AVCaptureSession *session; @property(nonatomic, strong) AVCaptureStillImageOutput *stillImageOutput; @property(nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer; @property(nonatomic, strong) AVCaptureConnection *stillImageConnection; @@ -206,8 +205,7 @@ - (void)takePicture [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:self.stillImageConnection completionHandler:didFinishTakingPicture]; - //test - if(self.allowPictureRetake){ + if(self.allowPictureRetake) { UITapGestureRecognizer *tapToRetakeGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(retakePicture:)];