Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Programming in Paradise
RSS Email
Search
Navigate
Configuration
Here are the gems Im currently using for testing. Im using an two test environments: test and ci. The reason for two is that Ive got guard constantly running specs, and sometimes I use a debugger. If guard and the debugger use the same database, then hangs occur due to transaction issues with database cleaner.
Gems
Unless the gem has a version specified, I try to keep my testing gems up to date with the latest. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3
# h t t p : / / s o u p m a t t . c o m / f i x i n g b u n d l e w i t h o u t o n h e r o k u c e d a r # H a c k t o m a k e h e r o k u w o r k . W o r k s b / c o n h e r o k u , t h e E N V [ ' H O M E ' ] w i l l b e ' a p p ' # a n d t h i s w i l l t h e n r e t u r n t e s t , w h i c h h e r o k u k n o w s t o e x c l u d e d e f h g ( g ) ( E N V [ ' H O M E ' ] . g s u b ( ' / ' , ' ' ) = = ' a p p ' ? ' t e s t ' : g ) e n d g r o u p : t e s t , h g ( : c i ) d o g e m ' s i m p l e c o v ' , r e q u i r e : f a l s e g e m ' d a t a b a s e _ c l e a n e r ' g e m ' t u r n ' , r e q u i r e : f a l s e g e m ' f a c t o r y _ g i r l _ r a i l s ' g e m ' l a u n c h y ' # t h i s l e t s u s c a l l s a v e _ a n d _ o p e n _ p a g e t o s e e w h a t ' s o n a p a g e f o r d e b u g g i n g c a p y b a r a g e m ' c a p y b a r a ' g e m ' c a p y b a r a s c r e e n s h o t ' , g i t h u b : ' p a r n d t / c a p y b a r a s c r e e n s h o t ' , b r a n c h : ' f i x r s p e c 3 0 0 d e p r e c a t i g e m ' s h o w _ m e _ t h e _ c o o k i e s ' g e m ' r s p e c i n s t a f a i l ' g e m ' s h o u l d a m a t c h e r s ' g e m ' p o l t e r g e i s t ' g e m ' r s p e c r e t r y ' , g i t h u b : ' j u s t i n 8 0 8 / r s p e c r e t r y ' , b r a n c h : ' j u s t i n 8 0 8 r s p e c 2 9 9 ' g e m ' r e s q u e _ s p e c ' , g i t h u b : ' j u s t i n 8 0 8 / r e s q u e _ s p e c ' , b r a n c h : ' f i x f o r r e s q u e h e r o k u ' g e m ' v c r '
2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4 3 5 3 6
g e m ' f a k e w e b ' g e m ' z e u s ' , ' ~ > 0 . 1 3 . 4 . p r e 2 ' e n d g r o u p : t e s t , : d e v e l o p m e n t d o # h t t p : / / r a i l s c a s t s . c o m / e p i s o d e s / 4 1 3 f a s t t e s t s g e m ' r s p e c r a i l s ' , ' ~ > 2 . 9 9 . 0 . b e t a 2 ' g e m ' r s p e c ' , ' > = 2 . 9 . 9 . b e t a 2 ' g e m ' r s p e c i t s ' , ' ~ > 1 . 0 . 0 ' g e m ' p a r a l l e l _ t e s t s ' g e m ' z e u s p a r a l l e l _ t e s t s ' g e m ' h e r o k u _ s a n ' , ' ~ > 4 . 3 . 2 ' e n d
view raw
spec_helper.rb
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4 3 5 3 6 3 7 3 8 3 9 4 0 4 1 4 2 # I M P T : # C o n f i g u r e E N V [ ' L O G _ L E V E L ' ] t o b e o n e o f D E B U G , I N F O , W A R N , E R R O R , F A T A L # f i g u r e o u t w h e r e w e a r e b e i n g l o a d e d f r o m i f $ L O A D E D _ F E A T U R E S . g r e p ( / s p e c \ / s p e c _ h e l p e r \ . r b / ) . a n y ? b e g i n r a i s e " f o o " r e s c u e = > e p u t s < < M S G = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = I t l o o k s l i k e s p e c _ h e l p e r . r b h a s b e e n l o a d e d m u l t i p l e t i m e s . N o r m a l i z e t h e r e q u i r e t o : r e q u i r e " s p e c / s p e c _ h e l p e r " T h i n g s l i k e F i l e . j o i n a n d F i l e . e x p a n d _ p a t h w i l l c a u s e i t t o b e l o a d e d m u l t i p l e t i m e s . L o a d e d t h i s t i m e f r o m : # { e . b a c k t r a c e . j o i n ( " \ n " ) } = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = M S G e n d e n d i f E N V [ " R U B Y M I N E _ H O M E " ] # t h i s i s n e c e s s a r y t o r u n t e s t s i n r u b y m i n e i n c a s e g u a r d i s r u n n i n g $ : . u n s h i f t ( F i l e . e x p a n d _ p a t h ( " r b / t e s t i n g / p a t c h / c o m m o n " , E N V [ " R U B Y M I N E _ H O M E " ] ) ) $ : . u n s h i f t ( F i l e . e x p a n d _ p a t h ( " r b / t e s t i n g / p a t c h / b d d " , E N V [ " R U B Y M I N E _ H O M E " ] ) ) e n d # i f b e l o w l i n e i s u s e d , t h e n w a r n i n g m e s s a g e s f r o m z e u s # B u t i f l i n e i s n o t u s e d a n d n o E N V i s s e t i n t h e s h e l l , t h e n f a c t o r y g i r l w o n ' t l o a d E N V [ " R A I L S _ E N V " ] | | = ' t e s t ' r e q u i r e F i l e . e x p a n d _ p a t h ( " . . / . . / c o n f i g / e n v i r o n m e n t " , _ _ F I L E _ _ ) r e q u i r e ' r s p e c / r a i l s ' r e q u i r e ' c a p y b a r a s c r e e n s h o t / r s p e c ' r e q u i r e ' r e s q u e _ s p e c / s c h e d u l e r ' # R e q u i r e s s u p p o r t i n g f i l e s w i t h c u s t o m m a t c h e r s a n d m a c r o s , e t c ,
4 3 4 4 4 5 4 6 4 7 4 8 4 9 5 0 5 1 5 2 5 3 5 4 5 5 5 6 5 7 5 8 5 9 6 0 6 1 6 2 6 3 6 4 6 5 6 6 6 7 6 8 6 9 7 0 7 1 7 2 7 3 7 4 7 5 7 6 7 7 7 8 7 9 8 0
# i n . / s u p p o r t / a n d i t s s u b d i r e c t o r i e s . D i r [ R a i l s . r o o t . j o i n ( " s p e c / s u p p o r t / * * / * . r b " ) ] . e a c h { | f | r e q u i r e f } R S p e c . c o n f i g u r e d o | c o n f i g | c o n f i g . o r d e r = ' r a n d o m ' c o n f i g . m o c k _ w i t h : r s p e c c o n f i g . f i x t u r e _ p a t h = " # { : : R a i l s . r o o t } / s p e c / f i x t u r e s " # I f y o u ' r e n o t u s i n g A c t i v e R e c o r d , o r y o u ' d p r e f e r n o t t o r u n e a c h o f y o u r # e x a m p l e s w i t h i n a t r a n s a c t i o n , c o m m e n t t h e f o l l o w i n g l i n e o r a s s i g n f a l s e # i n s t e a d o f t r u e . # c o n f i g . u s e _ t r a n s a c t i o n a l _ f i x t u r e s = t r u e # h t t p : / / r a i n u x . g i t h u b . c o m / 2 0 1 1 / 0 7 / 2 3 / c o n f i g u r e c a p y b a r a w e b k i t t o r u n a c c e p t a n c e s p e c s w i t h j a v a s c r i c o n f i g . u s e _ t r a n s a c t i o n a l _ f i x t u r e s = f a l s e c o n f i g . i n c l u d e I n t e g r a t i o n S p e c H e l p e r , : t y p e = > : r e q u e s t c o n f i g . i n c l u d e D e v i s e : : T e s t H e l p e r s , : t y p e = > : c o n t r o l l e r c o n f i g . i n c l u d e C o n t r o l l e r M a c r o s , : t y p e = > : c o n t r o l l e r c o n f i g . i n c l u d e F a c t o r y G i r l : : S y n t a x : : M e t h o d s c o n f i g . i n c l u d e S h o w M e T h e C o o k i e s , : t y p e = > : f e a t u r e # V C R s e t u p # s o w e c a n u s e : v c r r a t h e r t h a n : v c r = > t r u e ; # i n R S p e c 3 t h i s w i l l n o l o n g e r b e n e c e s s a r y . c o n f i g . t r e a t _ s y m b o l s _ a s _ m e t a d a t a _ k e y s _ w i t h _ t r u e _ v a l u e s = t r u e c o n f i g . i n c l u d e ( M a i l e r M a c r o s ) c o n f i g . b e f o r e ( : e a c h ) { r e s e t _ e m a i l } # h t t p : / / r a i l s c a s t s . c o m / e p i s o d e s / 4 1 3 f a s t t e s t s c o n f i g . f i l t e r _ r u n : f o c u s u n l e s s E N V [ " S K I P _ R S P E C _ F O C U S " ] . p r e s e n t ? c o n f i g . r u n _ a l l _ w h e n _ e v e r y t h i n g _ f i l t e r e d = t r u e c o n f i g . b e f o r e ( : a l l ) { D e f e r r e d G a r b a g e C o l l e c t i o n . s t a r t } c o n f i g . a f t e r ( : a l l ) { D e f e r r e d G a r b a g e C o l l e c t i o n . r e c o n s i d e r } c o n f i g . m o c k _ w i t h : r s p e c d o | c | c . y i e l d _ r e c e i v e r _ t o _ a n y _ i n s t a n c e _ i m p l e m e n t a t i o n _ b l o c k s = t r u e e n d e n d
view raw
.rspec file
This file configures the defaults for running tests. I really like the instalfail gem so that I can see errors immediately.
c o l o r r e q u i r es p e c _ h e l p e r r e q u i r er s p e c / i n s t a f a i l f o r m a tR S p e c : : I n s t a f a i l b a c k t r a c e f o r m a td o c u m e n t a t i o n
5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1
c m d : ' z e u s r s p e c ' , n o t i f i c a t i o n : t r u e , f a i l e d _ m o d e : : k e e p ) d o w a t c h ( % r { ^ s p e c / . + _ s p e c \ . r b $ } ) w a t c h ( % r { ^ l i b / ( . + ) \ . r b $ } ) { | m | " s p e c / l i b / # { m [ 1 ] } _ s p e c . r b " } w a t c h ( " s p e c / s p e c _ h e l p e r . r b " ) { " s p e c " } w a t c h ( % r { ^ a p p / ( . + ) \ . r b $ } ) { | m | " s p e c / # { m [ 1 ] } _ s p e c . r b " } w a t c h ( % r { ^ a p p / ( . * ) ( \ . e r b | \ . s l i m | \ . h a m l ) $ } ) { | m | " s p e c / # { m [ 1 ] } # { m [ 2 ] } _ s p e c . r b " } w a t c h ( % r { ^ a p p / c o n t r o l l e r s / ( . + ) _ ( c o n t r o l l e r ) \ . r b $ } ) { | m | [ " s p e c / r o u t i n g / # { m [ 1 ] } _ r o u t i n g _ s p e c . r b " w a t c h ( % r { ^ s p e c / s u p p o r t / ( . + ) \ . r b $ } ) { " s p e c " } w a t c h ( " c o n f i g / r o u t e s . r b " ) { " s p e c / r o u t i n g " } w a t c h ( " a p p / c o n t r o l l e r s / a p p l i c a t i o n _ c o n t r o l l e r . r b " ) { " s p e c / c o n t r o l l e r s " } w a t c h ( % r { ^ a p p / v i e w s / ( . + ) / . * \ . ( e r b | s l i m | h a m l ) $ } ) { | m | " s p e c / f e a t u r e s / # { m [ 1 ] } _ s p e c . r b " } e n d e n d
view raw
Heres my workflow for refining a test, and then running all tests in parallel: 1. Flag test (either d e s c r i b e ,c o n t e x t ,i t ,f e a t u r e , or s c e n a r i o ) with : f o c u slike this:
1f e a t u r e" U s e r s " ,: j s ,: f o c u sd o 2s c e n a r i o" s i g n u pf a i l u r es h o u l dn o tm a k ean e wu s e r " ,: f o c u sd o
2. In guard console for your specs, run command afor all tests (or just hit return). That will run only the tests youve marked with : f o c u s . 3. Sometimes guard picks up the changes and re-runs your test automatically. Many times, I just cmd-tab to iterm2 and hit return, which runs the default command of all specs. 4. Be sure to search and replace for , :focus so that you can run the whole test suite. If you forget to remove a :focus, then youll see that the total number of tests is less than you expect. 5. Once your new tests pass, run the whole test suite in parallel with the command z p s , defined below.
Xpath
Sometimes a Capybara test requires an xpath for more advanced finding of just the right dom node. For example, heres a useful xpath snippet for finding the xpath to the page one link.
If you use a context (within), then be sure to use .// and not / as / means anywhere on the page, not just in the current context! Another case where I had to use an xpath was to find the parent of a node. While the Capybara node object has a method p a r e n t , that does not give you the same sort of dome node parent that jQuery would. Thus, you can use an xpath like this, which finds an anchor with attribute d a t a s o m e t h i n ghaving value in ruby variable d a t a _ v a l u e .
1t h e _ n o d e=f i n d ( : x p a t h ," / / a [ @ d a t a s o m e t h i n g = ' # { d a t a _ v a l u e } ' ] / . . " )
Print Statements
1. Very fast to see exactly the data you need. 2. No issues with multiple threads when running integration tests. 3. Print statements help with the coffeescript code. Just do a:
1c o n s o l e . l o g" s o m em e s s a g e ,m y _ v a r# { m y _ v a r } "
4. With Zeus running, its much faster to re-run a test and get the print statements rather than starting the RubyMine debugger.
Debugger
1. For tough problems, the debugger can really help. 2. Allows you to evaluate code and dig into variables. 3. Ill tend to use the RubyMine debugger more for running the Rails server, since theres no waiting for the process to start if the debugger is already running the server. 4. Its key to set breakpoints where you think youll need them, start your test, and then move your cursor to some point where the problem is manifesting. The hit menu choice Run -> Force Run to Cursor. That is a HUGE time saver.
Database Cleaner
Its pretty critical to use Database Cleaner correctly when using Capybara with Poltergeist. Heres my setup. The only thing specific is that I have a couple tables that are seeded when the database is created. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 R S p e c . c o n f i g u r e d o | c o n f i g | c o n f i g . a d d _ s e t t i n g ( : s e e d _ t a b l e s ) c o n f i g . s e e d _ t a b l e s = % w ( s e e d _ t a b l e _ 1 s e e d _ t a b l e _ 2 ) c o n f i g . b e f o r e ( : s u i t e ) d o D a t a b a s e C l e a n e r . c l e a n _ w i t h ( : t r u n c a t i o n , e x c e p t : c o n f i g . s e e d _ t a b l e s ) e n d c o n f i g . b e f o r e ( : e a c h ) d o D a t a b a s e C l e a n e r . s t r a t e g y = : t r a n s a c t i o n e n d c o n f i g . b e f o r e ( : e a c h , j s : t r u e ) d o D a t a b a s e C l e a n e r . s t r a t e g y = : t r u n c a t i o n , { e x c e p t : c o n f i g . s e e d _ t a b l e s } e n d c o n f i g . b e f o r e ( : e a c h ) d o D a t a b a s e C l e a n e r . s t a r t e n d c o n f i g . a f t e r ( : e a c h ) d o
2 2 D a t a b a s e C l e a n e r . c l e a n 2 3 e n d 2 4 e n d
database_cleaner.rb hosted with by GitHub view raw
Tricky Testing
AJAX
This is well documented on the Capybara website. Read the part about AJAX very closely. The key thing is to think of what will change on the page once your AJAX response comes back. Then use a statement like:
1e x p e c t ( p a g e ) . t oh a v e _ c o n t e n t ( " s o m ev a l u e " )
Capybara will be smart about waiting until that condition is true. However, you have to be clever to come up with just the right condition. Be sure to understand how e x p e c t ( p a g e ) . t oh a v e _ c o n t e n t ( " b l a h " )will poll the page until the timeout or blah appears. On the contrary, e x p e c t ( p a g e ) . t o _ n o th a v e _ c o n t e n tc o n t a i n ( " b l a h " )will not poll! So be sure to use a positive expectation after you take some action invoking an AJAX request (or even an animation). Or else you may get a false positive that something is not on the page just because the page has not finished loading.
Heres the most relevant links on this topic: 1. How to Do jQuery UI Autocomplete With Capybara 2 2. Poltergeist github issues: 439, 274, 43
Hover effects
Heres how you test a mouseover effect. This was recently fixed for Capybara and Poltergeist and this absolutely rocks!
1s o m e _ n o d e=f i n d ( " c s ss e l e c t o r " ) 2s o m e _ n o d e . h o v e r 3e x p e c t ( p a g e ) . t oh a v e _ s e l e c t o r ( " s o m eo t h e rc s s _ s e l e c t o r " )
For fun, you can put some console.log in your event handler, and run the tests, and see in your console output that Capybara triggers the event.
Its not perfect that I have to use rspec-retry to get past random failures with PhantomJs. However, its way better than to let rspec simply retry before considering the test a failure. Note, you dont to have the : r e t r y _ c o u n tat anything other than 1 when youre re-running a test while developing it, as that would really slow you down.
1# D i s c u s s i o no fr e t r y 2# h t t p s : / / g i t h u b . c o m / r s p e c / r s p e c c o r e / i s s u e s / 4 5 6 3R S p e c . c o n f i g u r ed o| c o n f i g | 4 c o n f i g . v e r b o s e _ r e t r y =t r u e#s h o wr e t r ys t a t u si ns p e cp r o c e s s 5 r e t r y _ c o u n t =E N V [ ' R S P E C _ R E T R Y _ C O U N T ' ] 6 c o n f i g . d e f a u l t _ r e t r y _ c o u n t=r e t r y _ c o u n t . t r y ( : t o _ i )| |1 7 p u t s" R S p e cr e t r yc o u n ti s# { c o n f i g . d e f a u l t _ r e t r y _ c o u n t } " 8e n d
Every once in a while, my setup borks, and I need to kill all my zeus, guard, phantomjs processes at once. Heres a couple useful zsh functions:
1 p g r ( ){ 2 f o rxi nr a i l sp h a n t o m j sz e u s ;d o 3 p g r e pf l$ x ; 4 d o n e 5 } 6 7 p g k ( ){ 8 f o rxi nr a i l sp h a n t o m j sz e u s ;d o 9 p k i l lf l$ x ; 1 0 d o n e 1 1}
Parallel Tests
As mentioned above, I got a stunning performance difference using the parallel_tests gem. However, it defaults to using as many threads as one has processors (8 on my Macbook). Since that is too many if you want to keep using your Mac, I use this zsh function, which defaults to 6 processors.
1z p s( ){ 2 p = $ { 1 : 6 } 3 e c h o R u n" z e u sp a r a l l e l _ r s p e cn$ ps p e c " 4}
The trickiest part of the parallel_tests gem is setting up and migrating the extra test databases. Heres my rake task for doing migrations, which updates test, development, and my parallel test databases, and annotates. 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4 3 5 3 6 3 7 3 8 3 9 4 0 d e f r u n _ c o m m a n d _ r a i s e _ i f _ e r r o r ( c o m m a n d ) p u t s " E x e c u t i n g : # { c o m m a n d } " r e s u l t = % x [ # { c o m m a n d } ] r a i s e " r a k e t a s k f a i l e d . . . . . . . . . . \ n # { r e s u l t } " i f r e s u l t . i n c l u d e ? ( ' r a k e a b o r t e d ! ' ) e n d d e f r u n _ r a k e _ c o m m a n d _ r a i s e _ i f _ e r r o r ( c o m m a n d ) r u n _ c o m m a n d _ r a i s e _ i f _ e r r o r ( " b u n d l e e x e c r a k e # { c o m m a n d } " ) e n d n a m e s p a c e : d b d o d e s c " M i g r a t e D B s f o r e n v s t e s t , c i , d e v e l o p m e n t . T h e n s e t u p p a r a l l e l . " t a s k m i g r a t e _ a l l : : e n v i r o n m e n t d o | t , a r g s | u n l e s s R a i l s . e n v . d e v e l o p m e n t ? r a i s e " C a n o n l y r u n u n d e r d e v e l o p m e n t e n v i r o n m e n t , b u t s p e c i f i e d e n v w a s # { R a i l s . e n v } " e n d e n v s = % W ( t e s t c i d e v e l o p m e n t ) e n v s . e a c h d o | e n v | r u n _ r a k e _ c o m m a n d _ r a i s e _ i f _ e r r o r ( " R A I L S _ E N V = # { e n v } d b : m i g r a t e " ) e n d r u n _ r a k e _ c o m m a n d _ r a i s e _ i f _ e r r o r ( " p a r a l l e l : c r e a t e " ) r u n _ r a k e _ c o m m a n d _ r a i s e _ i f _ e r r o r ( " p a r a l l e l : p r e p a r e " ) r u n _ r a k e _ c o m m a n d _ r a i s e _ i f _ e r r o r ( " p a r a l l e l : r a k e [ d b : g l o b a l s ] " ) r u n _ c o m m a n d _ r a i s e _ i f _ e r r o r ( " a n n o t a t e e \ [ t e s t s \ ] i " ) e n d d e s c " U p d a t e s e e d d a t a i n a l l t e s t / d e v d a t a b a s e s " t a s k s e e d _ a l l : : e n v i r o n m e n t d o | t , a r g s | u n l e s s R a i l s . e n v . d e v e l o p m e n t ? r a i s e " C a n o n l y r u n u n d e r d e v e l o p m e n t e n v i r o n m e n t , b u t s p e c i f i e d e n v w a s # { R a i l s . e n v } " e n d e n v s = % W ( t e s t c i d e v e l o p m e n t ) e n v s . e a c h d o | e n v | r u n _ r a k e _ c o m m a n d _ r a i s e _ i f _ e r r o r ( " R A I L S _ E N V = # { e n v } d b : s e e d " ) e n d r u n _ r a k e _ c o m m a n d _ r a i s e _ i f _ e r r o r ( " p a r a l l e l : r a k e [ d b : s e e d ] " ) e n d e n d
view raw
Comments
2 Comments
Sort by Oldest
Rails On Maui
Share
Login
Favorite
4 days ago
Thanks for all the detail! Great post, would like to see more blog posts like this that go into more detail on developer toolchains.
Reply Share
joneslee85
3 days ago
Great post mate, thanks for pointing out the hover API
Reply Share
WHAT'S THIS?
not yet looked into the issue you mention, but that's a common issue for any
almost all those on a daily basis. My favorites being (CMD + Shft + N) to search for a
conference organization! @maximilien and I might organize a smaller Ruby conf in Maui next
Subscribe
About Me
I'm Justin Gordon. I'm a Ruby on Rails consultant based in Maui. Full stack development is my passion. Feel free to contact me on gmail as j u s t i n . g o r d o n . I'm also on Linked In. Resume.
Follow @railsonmaui 245 followers
Recent Posts
Rocking With Tmux, Tmuxinator, Guard, Zeus, and iTerm2 for Rails Development Capybara PhantomJs Poltergeist Rspec Tips Org-Mode Octopress Setup V2 Simple Form and Disabling Buttons on Submit by Default Using RubyMine/IntelliJ Regexp Search/Replace Migrating From Bash to Zsh GoGaRuCo 2013: Community > Code
GitHub Repos
justin808.github.io Rails On Maui Octopress org-mode
fork of official org-mode repo angularjs-railsonmaui-tutorial Angular spin on EmberJs Tutorial ember-js-guides-railsonmaui-rails4 Ember.js Example with Rails 4 Backend dof Dependent Object Framework JUnit ember-js-guides-railsonmaui-no-rest Completed set of files for the Tom Dale Ember.js Tutorial. ember-js-guides-railsonmaui-start Starter set of files for the Tom Dale Ember.js Tutorial. @justin808 on GitHub
Google+
Copyright 2014 - Justin Gordon - Powered by Octopress