<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>Mi smo društvo Ruby programera Srbije (Serbian Ruby user group), i okupljamo ljude koji profesionalno razvijaju softver u programskom jeziku Ruby.
  

  
  Imamo mailing listu i organizujemo povremena druženja na koja su dobrodošli svi zainteresovani. Ovaj blog sadrži beleške sa tih sastanaka, kao i članke o Rubiju i srodnim tehnologijama.
  </description><title>Ruby Srbija</title><generator>Tumblr (3.0; @rubyrs)</generator><link>http://ruby.rs/</link><item><title>Novi Sad, 10. decembar 2011.</title><description>&lt;p&gt;&lt;a href="http://d.pr/kRvB"&gt;&lt;img src="http://d.pr/kRvB+" alt="all"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Novi skup je bio u Novom Sadu pod organizacijom &lt;a href="http://renderedtext.com"&gt;Rendered Text-a&lt;/a&gt;. Obradovao nas je dobar odziv i to što je skoro polovina ljudi došla iz različitih gradova.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://d.pr/aQgP"&gt;&lt;img src="http://d.pr/aQgP+" alt="grupa 1"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Posle uvodnog ćaskanja prešli smo na dvočasovni &lt;em&gt;dojo&lt;/em&gt; gde su 4 grupe radile na zadatku - trebalo je isparsirati poslednje objavljenje gemove sa &lt;a href="http://rubygems.org"&gt;rubygems.org&lt;/a&gt;, ukrstiti one čiji je kod na GitHub-u, i sortirati ih po broju pratilaca koje autor gema ima. Ideja je da su novi gemovi zapaženih developera verovatno vredni pažnje.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://d.pr/IRI8"&gt;&lt;img src="http://d.pr/IRI8+" alt="grupa 2"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na kraju smo zajedno diskutovali šta je koja grupa uradila. Svi smo imali nešto drugačiji pristup - pisanju specova ili organizaciji koda, što je diskusiju učinilo veoma zanimljivom. Vreme je brzo prošlo tako da nam ostaje samo da uskoro ponovimo nešto slično.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://d.pr/Xhv1"&gt;&lt;img src="http://d.pr/Xhv1+" alt="grupa 3"/&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://ruby.rs/post/14457253009</link><guid>http://ruby.rs/post/14457253009</guid><pubDate>Mon, 19 Dec 2011 16:06:00 +0100</pubDate><category>sastanak</category><category>novi sad</category><category>Marko Anastasov</category></item><item><title>Beograd, 25. jun 2011.</title><description>&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_lnlkn1ssNN1qz8riw.jpg"/&gt;&lt;img src="http://media.tumblr.com/tumblr_lnlkprQys41qz8riw.jpg"/&gt;&lt;img src="http://media.tumblr.com/tumblr_lnlkseLAAJ1qz8riw.jpg"/&gt;&lt;/p&gt;
&lt;p&gt;U organizaciji &lt;a href="http://twitter.com/jablanovic"&gt;Jablana&lt;/a&gt; i &lt;a href="http://twitter.com/sale87"&gt;Saleta&lt;/a&gt;, ovaj sastanak se zbio u komfornim prostorijama firme &lt;a href="http://vast.com/"&gt;Vast&lt;/a&gt;. Na zadovoljstvo svih, posećenost je bila najveća do sada (13 ljudi), a recimo i da je &lt;a href="http://twitter.com/blackflasher"&gt;Dalibor&lt;/a&gt; došao čak iz Skoplja.&lt;/p&gt;
&lt;p&gt;Verovatno su zbog toga aktivnosti odstupile od predloženog &lt;a href="http://ruby.rs/post/6382980749/ruby-rs-sastanak-u-bgd"&gt;rasporeda&lt;/a&gt;: glavne teme uvodnog razgovora su bila iskustva sa upotrebom Rubija na poslu i izazovi sa kojima se susreću ljudi čije se firme zasnivaju na drugim tehnologijama, ili gde ne postoji kultura pisanja testova.&lt;/p&gt;
&lt;p&gt;To nas je odvelo u salu za prezentacije, gde je autor prisutnima pokazao primer primene BDD-a na popravljanje baga u real life kodu, što je bilo propraćeno diskusijom o RSpec-u i Cucumber-u, vežbanju, picom i krofnama (što se nastavilo na &lt;a href="http://groups.google.rs/group/rubysrbija"&gt;listi&lt;/a&gt;). Puno smo pričali i o uslovima za poslovanje u Srbiji.&lt;/p&gt;
&lt;p&gt;Par linkova za kraj (Korijeva sabrana dela):&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://vimeo.com/7961506"&gt;StringCalculator kata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://vimeo.com/23061155"&gt;BDD in five minutes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://vimeo.com/3039371"&gt;Razmišljanja o vežbanju&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://ruby.rs/post/7077500073</link><guid>http://ruby.rs/post/7077500073</guid><pubDate>Thu, 30 Jun 2011 11:53:54 +0200</pubDate><category>sastanak</category><category>beograd</category><category>Marko Anastasov</category></item><item><title>Ruby.rs sastanak u Bgd</title><description>&lt;p&gt;Prošlo je već dosta vremena od poslednjeg ruby.rs sastanka i red je da organizujemo sledeći. Firma &lt;a href="http://vast.com"&gt;vast.com&lt;/a&gt;, u kojoj radimo Sale i ja, izašla nam je u susret i obezbediće prostorije i infrastrukturu.&lt;/p&gt;

&lt;p&gt;Dakle, očekujemo sve rubiste u subotu, 25. juna u 16 sati u prostorijama Vasta - &lt;a href="http://maps.google.com/maps/ms?source=s_q&amp;hl=sr&amp;geocode=&amp;aq=1&amp;ie=UTF8&amp;hq=&amp;hnear=%D0%A2%D1%80%D0%B3+%D0%9D%D0%B8%D0%BA%D0%BE%D0%BB%D0%B5+%D0%9F%D0%B0%D1%88%D0%B8%D1%9B%D0%B0,+%D0%A1%D1%82%D0%B0%D1%80%D0%B8+%D0%93%D1%80%D0%B0%D0%B4,+%D0%91%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D0%B4,+%D0%93%D1%80%D0%B0%D0%B4+%D0%91%D0%B5%D0%BE%D0%B3%D1%80%D0%B0%D0%B4,+%D0%A6%D0%B5%D0%BD%D1%82%D1%80%D0%B0%D0%BB%D0%BD%D0%B0+%D0%A1%D1%80%D0%B1%D0%B8%D1%98%D0%B0,+%D0%A1%D1%80%D0%B1%D0%B8%D1%98%D0%B0&amp;msa=0&amp;msid=203070222928589100879.0004a558af333ad3caeea&amp;ll=44.812471,20.463045&amp;spn=0.005001,0.010579&amp;z=17"&gt;Trg Nikole Pašića 9&lt;/a&gt;, ulaz pored Novosti, žuta vrata.&lt;/p&gt;

&lt;p&gt;Program bi bio sličan onom od prošlog sastanka:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;sat-dva TDD coding dojo u parovima (nadam se da MarkoA nema ništa protiv da nam pripremi neki zadatak poput onog od prošlog puta)&lt;/li&gt;
&lt;li&gt;sat-dva neobavezne diskusije ili prezentacije (ako ima interesenata: npr. izveštaj sa neke konferencije, predstavljanje softvera itd)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Molio bih samo da nam, ako ste u mogućnosti, unapred najavite prisustvo na mejl &lt;code&gt;["6a61626c616e40726164696f6e692e6361"].pack('H*')&lt;/code&gt; ili na Google mailing listu.&lt;/p&gt;</description><link>http://ruby.rs/post/6382980749</link><guid>http://ruby.rs/post/6382980749</guid><pubDate>Fri, 10 Jun 2011 14:57:48 +0200</pubDate><category>Mladen Jablanovic</category><category>ruby.rs</category><category>meetup</category><category>beograd</category><category>sastanak</category></item><item><title>16. april 2011., Novi Sad</title><description>&lt;p&gt;&lt;img align="middle" width="474" height="355" src="http://dl.dropbox.com/u/2149954/rubyrs2011-1.jpg"/&gt;&lt;/p&gt;
&lt;p&gt;16. aprila 2011. naša mala družina se ponovo okupila u Novom Sadu, u kancelariji &lt;a href="http://renderedtext.com/"&gt;Rendered Text-a&lt;/a&gt; koja deluje kao poprilično fino mesto za rad. U odnosu na &lt;a href="http://ruby.rs/post/359465117/23-januar-2010-beograd-u-nekada-popularnom"&gt;prethodni zvanični sastanak&lt;/a&gt; (od koga je prošlo dosta vremena), povećao se i broj Ruby programera u Srbiji, no na žalost nisu svi mogli da se pojave na sastanku. Nadamo se da će nas sledeći put biti u većem broju :)&lt;/p&gt;
&lt;p&gt;Glavna aktivnost ovog sastanka je bio &lt;a href="http://codingdojo.org/cgi-bin/wiki.pl?WhatIsCodingDojo"&gt;coding dojo&lt;/a&gt;, gde je zadatak koji smo rešavali bio &lt;a href="http://codingdojo.org/cgi-bin/wiki.pl?KataPacMan"&gt;PacMan&lt;/a&gt;. Ideja je bila da rešimo problem korišćenjem &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD&lt;/a&gt;. Problem smo rešavali tako što smo prvo pisali testove za određene akcije koje Pacman može da radi, a zatim pisali kod koji implementira te akcije. Tu smo se upoznali sa &lt;a href="http://rspec.info/"&gt;RSpecom&lt;/a&gt;. Na žalost ja do sada nisam imao velikog iskustva sa testiranjem (jedino od RSpeca što sam video je u &lt;a href="http://ruby.railstutorial.org/"&gt;RailsTutorialu&lt;/a&gt;), ali mislim da sam u tom nekom kratkom vremenu uz Darka i Marka uspeo da razumem neke nove stvari. TDD je odličan jer čoveka tera da u trenutku misli samo na jednu stvar koju implementira, i da se trudi da tu stvar što elegantnije reši. Ja sam tokom rada imao taj osećaj, jednostavno nisam gledao mnogo napred kao što inače radim, i razmišljao sam samo o malom delu koda koji smo u tom trenutku implementirali. Ako bismo kasnije odlučili da refaktorišemo neki kod, testovi su tu i bićemo sigurni da je sve ok. Naravno, i kada dodajemo nove stvari u kod ovime smo sigurni da se ništa što smo već napisali nije pokvarilo. Može se čoveku učiniti da ovakav razvoj traži više vremena, ali je to što smo sigurni da je sve dobro vredno truda. Pisanjem testova dobijamo praktično i dokumentaciju onoga što pišemo, tako da je to još jedan veliki plus (ko još voli da piše dokumentaciju nakon završenog posla :)).&lt;/p&gt;
&lt;p&gt;Takođe smo bili podeljeni u grupe, i menjali se za računarom na određeno vreme, tako da je još jedna od “tehnika” sa kojom sam se ja prvi put ovde susreo i &lt;a href="http://en.wikipedia.org/wiki/Pair_programming"&gt;programiranje u paru&lt;/a&gt;. Divna tehnika, jer ovako možeš dosta da naučiš od ljudi sa kojima radiš, a i lakše je primetiti greške za vreme pisanja koda (bilo sintaksne ili semantičke prirode). Meni se ovo učinilo kao dobra tehnika da se dobije dobar kod, a i kasnije je neko pomenuo da &lt;a href="http://pivotallabs.com/how/pair_programming"&gt;Pivotal Labs&lt;/a&gt; radi isto tako. Poprilično zanimljiv način rada, koji bih voleo da praktikujem u svom svakodnevnom poslu.&lt;/p&gt;
&lt;p&gt;Da sumiram svoje utiske: super ekipa (&lt;a href="http://twitter.com/darkofabijan"&gt;@darkofabijan&lt;/a&gt;, &lt;a href="http://twitter.com/jablanovic"&gt;@jablanovic&lt;/a&gt;, &lt;a href="http://twitter.com/Lesa_ns"&gt;@Lesa_ns&lt;/a&gt;, &lt;a href="http://twitter.com/marjanpovolni"&gt;@marijanpovolni&lt;/a&gt;, &lt;a href="http://twitter.com/markoa"&gt;@markoa&lt;/a&gt;, &lt;a href="http://twitter.com/sale87"&gt;@sale87&lt;/a&gt;), super tema i poprilično uspešan sastanak. Nadam se da ćemo se uskoro okupiti u Beogradu u još većem broju i nastaviti da upoznajemo nove zanimljive tehnike za razvoj.&lt;/p&gt;</description><link>http://ruby.rs/post/4982448847</link><guid>http://ruby.rs/post/4982448847</guid><pubDate>Wed, 27 Apr 2011 13:41:00 +0200</pubDate><category>sastanak</category><category>Saša Ranisavljević</category></item><item><title>И онда орач рече, "Реци нам о раду."* или .rvmrc</title><description>&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_lk0x7aExhV1qa194t.jpg"/&gt;&lt;/p&gt;



&lt;p&gt;Овај чланак је инспирисан:&lt;/p&gt;



&lt;ul&gt;&lt;li&gt;&#13;
&lt;p&gt;Доктор Никовим &lt;a href="http://thechangelog.com/post/4481277637/codeconf-saturday-summary"&gt;саветом&lt;/a&gt;&lt;/p&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;&#13;
&lt;p&gt;Примером &lt;a href="https://github.com/elabs/front_end_testing"&gt;апликације&lt;/a&gt; о тестирању JavaScripta&lt;/p&gt;&#13;
&lt;/li&gt;&#13;
&lt;li&gt;&#13;
&lt;p&gt;И Срђановим &lt;a href="http://twitter.com/#!/batasrki/status/57616759498350592"&gt;“црвкутом”&lt;/a&gt;&lt;/p&gt;&#13;
&lt;/li&gt;&#13;
&lt;/ul&gt;&lt;p&gt;Често изађу нове алатке и ако нису приказане на повољан начин, могу лако да мимоиђу потенционалне кориснике. Тако сам чуо за &lt;a href="https://rvm.beginrescueend.com/"&gt;RVM&lt;/a&gt; у пролазу и дуго времена нисам обраћао пажњу на њега. Тек касније сам почео да га користим.&lt;/p&gt;



&lt;p&gt;Сада бих да опишем врло сажето корисне делове горе поменуте алатке, јер сматрам да сам сајт то не ради довољно добро, али више то радим из љутње што ја нисам почео да користим све могућности овог пројекта. Па да спречим да се то не деси другима.&lt;/p&gt;



&lt;h2&gt;Увод&lt;/h2&gt;

&lt;p&gt;&#13;&lt;/p&gt;

&lt;p&gt;Шта је &lt;strong&gt;RVM&lt;/strong&gt;? Само име говори шта ради: Ruby Version Manager, омогућава више верзија рубија да функционишу на једној машини. Али не само то, интересантан део је да уз верзије рубија, омогућава и опстанак “џемова” за сваку верзију. Но може још и нешто да омогући: посебну инсталацију “џемова” за сваки пројекат на вашој машини.&lt;/p&gt;



&lt;p&gt;И сада, најбољи део, то све може да се активира аутоматски, за сваки пројекат чим се нађете у самом директоријому пројекта. И за све је заслужан само један фајл: &lt;strong&gt;.rvmrc&lt;/strong&gt;.&lt;/p&gt;



&lt;h2&gt;Како?&lt;/h2&gt;

&lt;p&gt;&#13;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RVM&lt;/strong&gt; је скуп скрипти написаних у bash-у, које створе &lt;strong&gt;.rvm&lt;/strong&gt; у вашем $HOME директоријому, где стави све жељене верзије рубија и њихове “џемове”.&lt;/p&gt;



&lt;p&gt;Ви онда можете да бирате коју верзију рубија желите овако:&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;$ rvm list&#13;
    rvm rubies&#13;
&#13;
   ruby-1.9.2-p136 [ x86_64 ]&#13;
=&gt; ruby-1.8.7-p330 [ x86_64 ]&#13;
&#13;
$rvm use 1.9.2&#13;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#13;&lt;/p&gt;

&lt;p&gt;што ће да пређе са верзије 1.8.7 на верзију 1.9.2.&lt;/p&gt;



&lt;h2&gt;Зимница&lt;/h2&gt;

&lt;p&gt;&#13;&lt;/p&gt;

&lt;p&gt;То је прилично једноставно, али како шта је са “џемовима”? И они могу да се инсталирају исто као и пре:&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;$ gem install bundler&#13;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#13;&lt;/p&gt;

&lt;p&gt;али овако је још и лакше пошто ће све бити инсталирано у вашем радном простору, тј. &lt;strong&gt;$HOME/.rvm&lt;/strong&gt;.&lt;/p&gt;



&lt;p&gt;То је практично, али посебно интересанто је то што можете да правите посебне скупове “џемова” који одговарају само одређеним пројектима. На следећи начин:&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;$ rvm gemset create moj-izbor&#13;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#13;&lt;/p&gt;

&lt;p&gt;Пребаците се у тај нови скуп:&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;$ rvm ruby-1.9.2-p136@moj-izbor&#13;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#13;&lt;/p&gt;

&lt;p&gt;И онда инсталирате пожељне “џемове”.&lt;/p&gt;



&lt;h2&gt;Информације&lt;/h2&gt;

&lt;p&gt;&#13;&lt;/p&gt;

&lt;p&gt;Путем &lt;strong&gt;rvm info&lt;/strong&gt; можете да видите више детаља о тренутном стању вашег RVM окружења. На пример, да видите где су тренутно инсталирани “џемови” које користите:&lt;/p&gt;



&lt;pre&gt;&lt;code&gt;$ rvm info|egrep "GEM_(HOME|PATH)"&#13;
    GEM_HOME:     "/home/taliban/.rvm/gems/ruby-1.9.2-p136"&#13;
    GEM_PATH:     "/home/taliban/.rvm/gems/ruby-1.9.2-p136:/home/taliban/.rvm/gems/ruby-1.9.2-p136@moj-izbor"&#13;
#&#13;
# пази ово ------------------------------------------------------------------------------------^^^^^^^^^&#13;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#13;&lt;/p&gt;

&lt;h2&gt;Аутомата&lt;/h2&gt;



&lt;p&gt;Прилично једноставно, али може бити још и лакше, нарочито ако радите на више пројеката или ако тестирате један пројекат на разне начине. Створите фајл &lt;strong&gt;.rvmrc&lt;/strong&gt; у самом директоријуму пројекта са:&lt;/p&gt;



&lt;pre&gt;&lt;code&gt; rvm ruby-1.9.2&#13;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&#13;&lt;/p&gt;

&lt;p&gt;тако да не морате ручно да мењате ваше окружење, већ ће &lt;strong&gt;RVM&lt;/strong&gt; то радити аутоматски од тада чим уђете у тај пројекат.&lt;/p&gt;



&lt;p&gt;* део из књиге “Пророк” од Халила Џибрана&lt;/p&gt;



&lt;p&gt;(слика преузета са pressonline.rs)&lt;/p&gt;</description><link>http://ruby.rs/post/4817605704</link><guid>http://ruby.rs/post/4817605704</guid><pubDate>Fri, 22 Apr 2011 00:31:00 +0200</pubDate><category>RVM</category><category>Александар Симић</category></item><item><title>Блог у синатри, епизода једанаеста</title><description>&lt;p&gt;Да објасним мало о овом пројекту, да ставим кратак опис о њему:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;emacs README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и додам:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Једноставни блог у Синатри за [http://ruby.rs](&lt;a href="http://ruby.rs"&gt;http://ruby.rs&lt;/a&gt;)

Simple blog in Sinatra for [http://ruby.rs](&lt;a href="http://ruby.rs"&gt;http://ruby.rs&lt;/a&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;па то ставим у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git add README.md 
$ git commit -m "додајем README.md"
[master 67807a9] додајем README.md
 1 files changed, 3 insertions(+), 0 deletions(-)
 create mode 100644 README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Било би добро да када посетим неку страницу која не постоји, да
прикажем грешку, попут: &lt;strong&gt;Nothing to see here, move along&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Отворим нови огранак у гиту:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout -b 404
Switched to a new branch '404'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;У blurgh_spec.rb, додам следећу спецификацију:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe "error page" do
  it "should display a pre defined 404 message" do
    get '/non-existent-page'
    last_response.body.should match("Nothing to see here")
  end
end    
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем тест који наравно не пролази:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Failures:

  1) blurgh routes and content error page should display a pre defined 404 message
     Failure/Error: get '/non-existent-page'
     Errno::ENOENT:
       No such file or directory - spec/fixtures/non-existent-page.md
     # ./blurgh.rb:50:in `readlines'
     # ./blurgh.rb:50:in `get_post'
     # ./blurgh.rb:61:in `block in &lt;top (required)&gt;'
     # ./spec/blurgh_spec.rb:67:in `block (4 levels) in &lt;top (required)&gt;'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Да бих то исправио, морам да променим &lt;strong&gt;get_post&lt;/strong&gt; методу из овога:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def get_post(post)
  header, body = File.readlines(Config.options['store'] + "/" + post + ".md", "")
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;у ово:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def get_post(post)
  begin
    header, body = File.readlines(Config.options['store'] + "/" + post + ".md", "")
  rescue Errno::ENOENT
    not_found
  end
end

not_found do
  "Nothing to see here"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Да објасним шта се овде изменило: &lt;strong&gt;begin&lt;/strong&gt; … &lt;strong&gt;rescue&lt;/strong&gt; омогућава
да се изврши &lt;strong&gt;File.readlines&lt;/strong&gt; метода, али ако се види грешка коју се
приказала предходно: &lt;strong&gt;Errno::ENOENT&lt;/strong&gt; онда да се покрене
&lt;strong&gt;not_found&lt;/strong&gt; метода. &lt;strong&gt;not_found&lt;/strong&gt; метода је специфична, јер је већ
унапред дефинисана у самом &lt;strong&gt;sinatra&lt;/strong&gt; пројекту за употребу у оваквим
случајевима, када се појављује грешка. И уместо да се види грешка,
путем ње, може да се прикаже пожељно упозорење.&lt;/p&gt;

&lt;p&gt;Покренем тестирање и све пролази.&lt;/p&gt;

&lt;p&gt;Па да испробам и саму апликацију, додам:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;store: spec/fixtures
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;у setup.yaml. И покренем:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ shotgun blurgh.rb     
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Видим два чланка који се налазе под &lt;strong&gt;spec/fixtures&lt;/strong&gt;, као што се
видело и пре. И да би испробао нову методу укуцам
&lt;a href="http://localhost:9393/let2"&gt;http://localhost:9393/let2&lt;/a&gt; на којој се
види порука: Nothing to see here.&lt;/p&gt;

&lt;p&gt;Да то сада додам у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
# On branch 404
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   modified:   blurgh.rb
#   modified:   setup.yaml
#   modified:   spec/blurgh_spec.rb
#

$ git add blurgh.rb setup.yaml spec/blurgh_spec.rb

$ git commit -m "приказивање грешке за непостојећу страну"
[404 fb7e5c8] приказивање грешке за непостојећу страну
 3 files changed, 19 insertions(+), 2 deletions(-)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И да додам то у главно стабло гита:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout master
Switched to branch 'master'

$ git merge 404
Updating 67807a9..fb7e5c8
Fast forward
 blurgh.rb           |   11 ++++++++++-
 setup.yaml          |    3 ++-
 spec/blurgh_spec.rb |    7 +++++++
 3 files changed, 19 insertions(+), 2 deletions(-)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Сада има сисем за блоговање, написан у 75 линија рубија. Који је
тестиран. Може још шта да се дода, систем није комплетан. Али има
добру основу.&lt;/p&gt;

&lt;p&gt;Сав овај рад, окачен је &lt;a href="http://github.com/dotemacs/blurgh"&gt;овде&lt;/a&gt;.&lt;/p&gt;</description><link>http://ruby.rs/post/4657428963</link><guid>http://ruby.rs/post/4657428963</guid><pubDate>Sat, 16 Apr 2011 14:21:01 +0200</pubDate></item><item><title>Блог у синатри, епизода десета</title><description>&lt;p&gt;Да би документација тестова била читљивија, преправим&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;context "the view" do
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;у&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;context "the index view" do    
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и додам нови тест:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;context "the post view" do
  it "should show post content" do
    get '/let'
    last_response.body.should match("25. марта 1923. - Слетањем авиона на линији Париз-Цариград на")
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Тај тест наравно не пролази, зато што не постоји ништа што би
приказало садржај фајла. То могу да омогућим тако што створим методу
која ће приказивати индивидалне чланке:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/:post' do
  @config, @content = get_post(:post)
  erb :post
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и додам и &lt;strong&gt;post.erb&lt;/strong&gt; у &lt;strong&gt;views/&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;%= @content %&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;само да би било што једноставније и да би омогућио да тест прође.&lt;/p&gt;

&lt;p&gt;Покренем тест, и он пада са следећом поруком:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1) blurgh routes and content the post view should show post content
     Failure/Error: get '/let'
     TypeError:
       can't convert Symbol into String
     # ./blurgh.rb:46:in `+'
     # ./blurgh.rb:46:in `get_post'
     # ./blurgh.rb:58:in `block in &lt;top (required)&gt;'
     # ./spec/blurgh_spec.rb:44:in `block (4 levels) in &lt;top (required)&gt;'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;што значи да се &lt;strong&gt;get_post&lt;/strong&gt; метода не добија одговарајући
аргумент. Зато преправим:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@config, @content = get_post(:post)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;у&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@config, @content = get_post(params[:post])  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем тестирање поново и све прође.&lt;/p&gt;

&lt;p&gt;Но нисам баш задовољан предходним тестом, он само проверава прву линију чланка&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;last_response.body.should match("25. марта 1923. - Слетањем авиона на линији Париз-Цариград на")
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Било би боље када би учитавао сав фајл. Зато изменим тест у:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;it "should show post content" do
  get '/let'
  article = File.readlines("spec/fixtures/let.md", "")[1]
  last_response.body.should match(article)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;јер ми изгледа читљивије. Па покренем тест… који прође.&lt;/p&gt;

&lt;p&gt;Додам напредак у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
# On branch posts
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   modified:   blurgh.rb
#   modified:   spec/blurgh_spec.rb
#
# Untracked files:
#   (use "git add &lt;file&gt;..." to include in what will be committed)
#
#   views/post.erb
no changes added to commit (use "git add" and/or "git commit -a")
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Овде се види да је &lt;strong&gt;views/post.erb&lt;/strong&gt; нови фајл који још није унет у
гит. Зато требам да га додам са осталим фајловима где је направљена
промена:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git add blurgh.rb spec/blurgh_spec.rb views/post.erb 

$ git commit -m "приказивање чланака"
[posts 5540485] приказивање чланака
 3 files changed, 20 insertions(+), 5 deletions(-)
 create mode 100644 views/post.erb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Било би добро да додам да може да се види наслов када се прикаже
чланак.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;it "should show post title" do
  get '/let'
  config = File.readlines("spec/fixtures/let.md", "")[0]
  post_options = YAML.load(config)
  last_response.body.should match(post_options['title'])
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Покренем тест, и он не пролази, зато што немам начин да прикажем
наслов на страници која приказује чланке.&lt;/p&gt;

&lt;p&gt;Зато преуредим &lt;strong&gt;get ‘/:post’&lt;/strong&gt; у:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/:post' do
  @config, @content = get_post(params[:post])
  @title = YAML.load(@config)['title']
  erb :post
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;подесим &lt;strong&gt;post.erb&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;h2&gt;
  &lt;%= @title %&gt;
&lt;h2&gt;

&lt;%= @content %&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем тест и он прође. Зато да учитам у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
# On branch posts
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   modified:   blurgh.rb
#   modified:   setup.yaml
#   modified:   spec/blurgh_spec.rb
#   modified:   views/post.erb

$ git add blurgh.rb spec/blurgh_spec.rb views/post.erb 
$ git commit -m "приказивање наслова чланака"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Сада да додам датум за чланке. Прво да додам тест:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;it "should show post date" do
  get '/let'
  config = File.readlines("spec/fixtures/let.md", "")[0]
  post_options = YAML.load(config)
  last_response.body.should match("20110325")
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Па да се уверим да тест пада:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rake
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И онда да преправим &lt;strong&gt;get ‘/:post’&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/:post' do
  @config, @content = get_post(params[:post])
  post_options = YAML.load(@config)
  @title = post_options['title']
  @date =  post_options['date']
  erb :post
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и да променим &lt;strong&gt;post.erb&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;h2&gt;
  &lt;%= @title %&gt;
&lt;/h2&gt;

&lt;div&gt;
  &lt;%= @date %&gt;
&lt;/div&gt;

&lt;%= @content %&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Покренем тест и он прође. Па да додам напредак у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
# On branch posts
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   modified:   blurgh.rb
#   modified:   spec/blurgh_spec.rb
#   modified:   views/post.erb
#

$ git add blurgh.rb spec/blurgh_spec.rb views/post.erb

$ git commit -m "приказивање датума чланака"
[posts d005862] приказивање датума чланака
 3 files changed, 14 insertions(+), 1 deletions(-)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Па да додам овај огранак у главни, тако што се прво пребацим у
&lt;strong&gt;master&lt;/strong&gt; огранак:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout master
Switched to branch 'master'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и сада да додам &lt;strong&gt;posts&lt;/strong&gt; огранак у &lt;strong&gt;master&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git merge posts
Auto-merging blurgh.rb
CONFLICT (add/add): Merge conflict in blurgh.rb
Auto-merging spec/blurgh_spec.rb
CONFLICT (add/add): Merge conflict in spec/blurgh_spec.rb
Auto-merging spec/config_spec.rb
CONFLICT (add/add): Merge conflict in spec/config_spec.rb
Auto-merging views/index.erb
CONFLICT (add/add): Merge conflict in views/index.erb
Automatic merge failed; fix conflicts and then commit the result.     
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ово је ново. Порука ми говори да измене које сам направио се не
подударају апсолутно са садржајем &lt;strong&gt;master&lt;/strong&gt; огранку.&lt;/p&gt;

&lt;p&gt;Да би то решио, морам да направим измене ручно. Отворим прво
&lt;strong&gt;blurgh.rb&lt;/strong&gt; и видим следеће:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module Config
&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD:blurgh.rb
  def self.title
    options["title"]
  end

=======
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Да би то поправио, морам сам да коригујем у едитору. Бацим се на
посао, фајл по фајл… То су тестови да ми помогну да ништа није
пропуштено.&lt;/p&gt;

&lt;p&gt;Али ако у међу времену покушам да додам огранак &lt;strong&gt;posts&lt;/strong&gt; поново,
добићу следећу грешку:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git merge posts
fatal: You have not concluded your merge. (MERGE_HEAD exists)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;то је зато што гит није могао аутоматски да дода нови огранак, па је
направио нове фајлове, спајањем постојећих фајлова у &lt;strong&gt;master&lt;/strong&gt;
огранку са фајловима из &lt;strong&gt;posts&lt;/strong&gt; огранка.&lt;/p&gt;

&lt;p&gt;Да би то решио, морам прво да средим све фајлове и да сви тестови
пролазе. Затим да видим статус гита, и тек онда да додам фајлове:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
blurgh.rb: needs merge
spec/blurgh_spec.rb: needs merge
spec/config_spec.rb: needs merge
views/index.erb: needs merge
# On branch master
# Changes to be committed:
#   (use "git reset HEAD &lt;file&gt;..." to unstage)
#
#   new file:   spec/fixtures/let.md
#   new file:   spec/fixtures/o-kapadokiji.md
#   new file:   views/post.erb
#
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   unmerged:   blurgh.rb
#   unmerged:   spec/blurgh_spec.rb
#   unmerged:   spec/config_spec.rb
#   unmerged:   views/index.erb
#

$ git add blurgh.rb spec/config_spec.rb spec/blurgh_spec.rb views/index.erb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;али требам да додам и нове фајлове:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git add spec/fixtures/o-kapadokiji.md spec/fixtures/let.md views/post.erb    
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;На крају учитам све промене у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git commit -m "додајем рад на чланцима"    
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ако погледам лог гита, видим да су то и поруке из &lt;strong&gt;posts&lt;/strong&gt; огранка:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git log --oneline | head -5
88f2449 додајем рад на чланцима
d005862 приказивање датума чланака
4a40483 приказивање наслова чланака
5540485 приказивање чланака
a79f8c8 смршао blurgh_spec.rb    
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Наставља се …&lt;/p&gt;</description><link>http://ruby.rs/post/4269828624</link><guid>http://ruby.rs/post/4269828624</guid><pubDate>Sat, 02 Apr 2011 02:13:48 +0200</pubDate></item><item><title>Блог у синатри, епизода девета</title><description>&lt;p&gt;Резултат тестирања изгледа овако:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rake

Config
  .title
    should return value
  when the title is blank
    should return nothing
  when the title is missing
    should return nil
  .store
    should return value
  .all
    should return all the values

blurgh
  routes and content
    should respond to /
    should have a title
    the view
      should have a body html elements
      the posts URLs should be listed
  get_posts
    should return posts
    on the index page
      the posts URLs should be listed
      the posts titles should be shown
  get_post
    should return a post in two parts

Finished in 0.02477 seconds
13 examples, 0 failures
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;То је зато што сам одредио да формат резултата теста буде: &lt;strong&gt;—format
doc&lt;/strong&gt; у .rspec фајлу.&lt;/p&gt;

&lt;p&gt;Но проблем је што сам ставио:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;on the index page
  the posts URLs should be listed
  the posts titles should be shown
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;да је унутар &lt;strong&gt;get_posts&lt;/strong&gt;. То би приуредим и да наместим да буде читљивије.&lt;/p&gt;

&lt;p&gt;Тренутно &lt;strong&gt;blurgh_spec.rb&lt;/strong&gt; изгледа овако:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# -*- coding: utf-8 -*-
require 'spec_helper'

describe "blurgh" do

  def app
    @app ||= Sinatra::Application
  end

  context "routes and content" do
    before :each do
      YAML.should_receive(:load_file)\
       .with("setup.yaml").and_return({"title" =&gt; "Naslov", "store" =&gt; "posts"})
    end

    it "should respond to /" do
      get '/'
      last_response.should be_ok
    end

    it "should have a title" do
      get '/'
      last_response.body.should match("Naslov")
    end

    context "the view" do
      it "should have a body html elements" do
        get '/'
        last_response.body.should match("&lt;body&gt;")
      end

      it "the posts URLs should be listed" do
        get '/'
        # last_response.body.should match("let")
        last_response.body.should match('&lt;a href="let"&gt;Авионски лет&lt;/a&gt;')
      end
    end
  end

  describe "get_posts" do

    before do
      YAML.should_receive(:load_file).with("setup.yaml")\
        .and_return({"title" =&gt; "Naslov", "store" =&gt; "spec/fixtures"})
    end

    it "should return posts" do
      first_article = File.readlines("spec/fixtures/o-kapadokiji.md", "")[1]
      second_article = File.readlines("spec/fixtures/let.md", "")[1]
      store = Config.all['store']

      get_posts(store).should == \
      [[20110325,  {"url" =&gt; "let", "title" =&gt; "Авионски лет", "body" =&gt; "#{second_article}"}],\
       [20110324, {"url" =&gt; "o-kapadokiji", "title" =&gt; "Кападокија", "body" =&gt; "#{first_article}"}]]
    end

    context "on the index page" do
      it "the posts URLs should be listed" do
        get '/'
        last_response.body.should match("let")
        last_response.body.should match("o-kapadokiji")
      end

      it "the posts titles should be shown" do
        get '/'
        last_response.body.should match('&lt;a href="let"&gt;Авионски лет&lt;/a&gt;')
        last_response.body.should match('&lt;a href="o-kapadokiji"&gt;Кападокија&lt;/a&gt;')
      end

    end

  end

  describe "get_post" do

    before do
      YAML.should_receive(:load_file).with("setup.yaml")\
        .and_return({"title" =&gt; "Naslov", "store" =&gt; "spec/fixtures"})
    end

    it "should return a post in two parts" do
      get_post("o-kapadokiji").should have(2).parts
    end

  end

end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Да би то променио, променим прво:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;context "routes and content" do
  before :each do
    YAML.should_receive(:load_file)\
     .with("setup.yaml").and_return({"title" =&gt; "Naslov", "store" =&gt; "posts"})
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;у&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;context "routes and content" do
  before :each do
    YAML.should_receive(:load_file)\
     .and_return({"title" =&gt; "Naslov", "store" =&gt; "spec/fixtures"})
  end      
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Покренем тестирање и оно прође.&lt;/p&gt;

&lt;p&gt;Али сада се то понавља три пута, што да не ставим то пре почетка свих
тестова:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;before :each do
  YAML.should_receive(:load_file)\
    .and_return({"title" =&gt; "Naslov", "store" =&gt; "spec/fixtures"})
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;а остале избришем. Покренем тест и пролази без жалби.&lt;/p&gt;

&lt;p&gt;Вратим се предходној жељи где би да групишем сродне тестове, тако да
преуредим фајл да изгледа овако:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# -*- coding: utf-8 -*-
require 'spec_helper'

describe "blurgh" do

  before :each do
    YAML.should_receive(:load_file)\
      .and_return({"title" =&gt; "Naslov", "store" =&gt; "spec/fixtures"})
  end

  def app
    @app ||= Sinatra::Application
  end

  context "routes and content" do

    it "should respond to /" do
      get '/'
      last_response.should be_ok
    end

    context "the view" do

      it "should have a title" do
        get '/'
        last_response.body.should match("Naslov")
      end

      it "should have a body html elements" do
        get '/'
        last_response.body.should match("&lt;body&gt;")
      end

      it "the posts titles should be shown" do
        get '/'
        last_response.body.should match('&lt;a href="let"&gt;Авионски лет&lt;/a&gt;')
        last_response.body.should match('&lt;a href="o-kapadokiji"&gt;Кападокија&lt;/a&gt;')
      end

    end
  end

  describe "get_posts" do

    it "should return posts" do
      first_article = File.readlines("spec/fixtures/o-kapadokiji.md", "")[1]
      second_article = File.readlines("spec/fixtures/let.md", "")[1]
      store = Config.all['store']

      get_posts(store).should == \
      [[20110325,  {"url" =&gt; "let", "title" =&gt; "Авионски лет", "body" =&gt; "#{second_article}"}],\
       [20110324, {"url" =&gt; "o-kapadokiji", "title" =&gt; "Кападокија", "body" =&gt; "#{first_article}"}]]
    end

  end

  describe "get_post" do

    it "should return a post in two parts" do
      get_post("o-kapadokiji").should have(2).parts
    end

  end

end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Што је у мом мишљењу, читљивије и логичније. Покренем тест и он
прође. Да додам у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
# On branch posts
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   modified:   spec/blurgh_spec.rb
#

$ git add spec/blurgh_spec.rb 
$ git commit -m "смршао blurgh_spec.rb"
[posts 0e3722c] смршао blurgh_spec.rb
 1 files changed, 18 insertions(+), 34 deletions(-)
&lt;/code&gt;&lt;/pre&gt;</description><link>http://ruby.rs/post/4259011375</link><guid>http://ruby.rs/post/4259011375</guid><pubDate>Fri, 01 Apr 2011 17:07:05 +0200</pubDate></item><item><title>Блог у синатри, епизода осма</title><description>&lt;p&gt;Сада да претворим фајлове у HTML линкове.&lt;/p&gt;

&lt;p&gt;Прво направим тест под &lt;strong&gt;describe “get_posts”&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;it "the posts titles should be shown" do
  get '/'
  last_response.body.should match('&lt;a href="let"&gt;Авионски лет&lt;/a&gt;')
  last_response.body.should match('&lt;a href="o-kapadokiji"&gt;Кападокија&lt;/a&gt;')
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Онда да подесим &lt;strong&gt;index.erb&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;h1&gt;&lt;%= @title %&gt;&lt;/h1&gt;

&lt;% @posts.each do |post| %&gt;
   &lt;a href="&lt;%= post[1]['url'] %&gt;"&gt;&lt;%= post[1]['title'] %&gt;&lt;/a&gt;
&lt;% end %&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем тест, и он успешно прође. Да додам напредак у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
# On branch posts
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   modified:   spec/blurgh_spec.rb
#   modified:   views/index.erb
#

$ git add spec/blurgh_spec.rb views/index.erb

$ git commit -m "омогућено претварање наслова чланака у URL на почетној страници"
[posts b1ad84c] омогућено претварање наслова чланака у URL на почетној страници
 2 files changed, 8 insertions(+), 1 deletions(-)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Било би добро да сада могу да видим и саме чланке. Пошто су они сами
фајлови, треба ми нека метода која ће да их чита. Да кренем са тестом:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe "get_post" do
  pending
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем тестирање:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rspec spec/blurgh_spec.rb 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и оно пада са:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Pending:
  blurgh get_post 
    # Not Yet Implemented
    # ./spec/blurgh_spec.rb:69
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Када размислим мало боље о овоме, како ће се фајлови читати, то ће
бити у суштини овако:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/име-фајла
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Но како они треба да изгледају кад су прочитани. Слично као и када их
&lt;strong&gt;get_posts&lt;/strong&gt; чита, сачињени од два дела. Први део је YAML
конфигурација а други, сам садржај.&lt;/p&gt;

&lt;p&gt;Тако да пишем следећи тест:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe "get_post" do
  it "should return a post in two parts" do
    get_post("o-kapadokiji").should have(2).parts
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Покренем тест, који пада, зато пишем следећу методу:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def get_post(post)
  header, body = File.readlines(Config.options['store'] + "/" + post + ".md", "")
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем тест и он пада:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1) blurgh get_post should return a post in two parts
   Failure/Error: get_post("o-kapadokiji").should have(2).parts
   NoMethodError:
     undefined method `+' for nil:NilClass
   # ./blurgh.rb:46:in `get_post'
   # ./spec/blurgh_spec.rb:76:in `block (3 levels) in &lt;top (required)&gt;'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;46 линија је средина предходне методе и она очекује конфигурацију за
&lt;strong&gt;Config&lt;/strong&gt;. Зато преправим тест да изгледа овако:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe "get_post" do

  before do
    YAML.should_receive(:load_file).with("setup.yaml")\
      .and_return({"title" =&gt; "Naslov", "store" =&gt; "spec/fixtures"})
  end

  it "should return a post in two parts" do
    get_post("o-kapadokiji").should have(2).parts
  end

end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Покренем тест, који успешно прође.&lt;/p&gt;

&lt;p&gt;Па додам то у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
# On branch posts
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   modified:   blurgh.rb
#   modified:   spec/blurgh_spec.rb
no changes added to commit (use "git add" and/or "git commit -a")

$ git add blurgh.rb spec/blurgh_spec.rb

$ git commit -m "учитавање чланка"
[posts b1290dd] учитавање чланка
 2 files changed, 17 insertions(+), 0 deletions(-)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Овде би било добро да обратим пажњу на:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get_post("o-kapadokiji").should have(2).parts     
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;специфично на &lt;strong&gt;have(2).parts&lt;/strong&gt; део. &lt;strong&gt;parts&lt;/strong&gt; је само реч која је ту
додана да би тест био читљивији. Она може бити замењена са неком
другом и тест ће и даље да прође. На пример:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get_post("o-kapadokiji").should have(2).сарма
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;пролази као важећи тест.&lt;/p&gt;

&lt;p&gt;Ако заменим &lt;strong&gt;сарма&lt;/strong&gt; са &lt;strong&gt;class&lt;/strong&gt;, добијам следећу грешку:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1) blurgh get_post should return a post in two parts
     Failure/Error: get_post("o-kapadokiji").should have(2).class
     NoMethodError:
       undefined method `matches?' for RSpec::Matchers::Have:Class
     # ./spec/blurgh_spec.rb:76:in `block (3 levels) in &lt;top (required)&gt;'    
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;што ми указује на то да је &lt;strong&gt;have(2)&lt;/strong&gt; сачињена од &lt;strong&gt;Have&lt;/strong&gt; класе. Ако погледам &lt;a href="https://github.com/rspec/rspec-expectations/blob/master/lib/rspec/matchers/have.rb"&gt;&lt;a href="https://github.com/rspec/rspec-expectations/blob/master/lib/rspec/matchers/have.rb"&gt;https://github.com/rspec/rspec-expectations/blob/master/lib/rspec/matchers/have.rb&lt;/a&gt;&lt;/a&gt; видим следеће под примерима:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#   should have(number).named_collection__or__sugar
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;…&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# If the receiver IS the collection, you can use any name
# you like for &lt;tt&gt;named_collection&lt;/tt&gt;. We'd recommend using
# either "elements", "members", or "items" as these are all
# standard ways of describing the things IN a collection.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;па примери:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Passes if [1,2,3].length == 3
# [1,2,3].should have(3).items #"items" is pure sugar
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Наставак следи…&lt;/p&gt;</description><link>http://ruby.rs/post/4217274993</link><guid>http://ruby.rs/post/4217274993</guid><pubDate>Thu, 31 Mar 2011 00:00:48 +0200</pubDate></item><item><title>Блог у синатри, епизода седма</title><description>&lt;p&gt;Било би пожељно да овај систем може да учита чланке и да их
прикаже. Идеја је да чита чланке из одређеног директоријума који је
наведен у конфигурационом фајлу setup.yaml на следећи начин:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;store: posts
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;За то да направим нови огранак у гиту:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout -b posts
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Прво желим да Config чита и .store врати име директоријума. То означим
у тесту овако:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe ".store" do
  it "should return value" do
    YAML.should_receive(:load_file).with("setup.yaml").and_return({"store" =&gt; "posts"}) 
    Config.store.should match("posts")
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем тест и он не прође:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1) Config.store should return value
   Failure/Error: Config.store.should match("posts")
   NoMethodError:
     undefined method `match' for nil:NilClass
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Онда у Config додам нову методу:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def self.store
  options["store"]
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Поново покренем тест, и овај пут прође. Додам тај рад у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
# On branch posts
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   modified:   blurgh.rb
#   modified:   spec/config_spec.rb
#
no changes added to commit (use "git add" and/or "git commit -a")
$ git add blurgh.rb spec/config_spec.rb
$ git commit -m "додана метода Config.store"
[posts b243446] додана метода Config.store
 2 files changed, 12 insertions(+), 0 deletions(-)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Сада имам тачно одређено место где ће да се држе чланци, али још немам
ништа да их учитам. То желим да ми уради метода get_posts која ће да
врати све фајлове директоријума на који указује store. Тест за ту
методу изгледа овако:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe "get_posts" do
  it "should return posts" do
    Dir.should_receive(:entries).with("posts").and_return(["sample_post.md", "another_sample_post.md"])
    get_posts.should == ["sample_post.md", "another_sample_post.md"]
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И кад покренем тестове, добијем следеће:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; 1) blurgh get_posts should return posts
Failure/Error: get_posts.should == ["sample_post.md", "another_sample_post.md"]
NameError:
  undefined local variable or method `get_posts' for #&lt;RSpec::Core::ExampleGroup::Nested_2::Nested_2:0x00000001f12da8&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Напишем следећу методу у &lt;strong&gt;blurgh.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def get_posts
  Dir.entries(Config.store)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем тестирање поново и тест прође.&lt;/p&gt;

&lt;p&gt;Но то ми није довољно, јер како ћу да организујем чланке, овако су
враћени у “хрпи”. Било би боље када би они могли да буду организовани
по датуму.&lt;/p&gt;

&lt;p&gt;И како ћу за наслов ?&lt;/p&gt;

&lt;p&gt;То би могло да се реши овако: сваки чланак да буде сачињен делимично у
YAML формату, то јест, први параграф, а остатак да буде сам чланак. На
пример да садржај фајла изгледа овако:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;title: Кападокија
date: 20110324

Премало се зна о Кападокији пре него што је постала персијска
сатрапија. Зна се само да је Кападокија била у време Хета веома
значајна земља и да се управо у њој налазила хетска престоница
Хатуша. Иако сатрапија у персијско време, Кападокија је сачувала
известан степен самосталности.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;То би било у реду за један чланак, али шта са get_posts методом ? У
каквом формату да врати чланке ?&lt;/p&gt;

&lt;p&gt;Било би добро да буду враћени у следећем формату:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[[["20110324"], {"title" =&gt; "Кападокија", "body" =&gt; "Премало се зна о Кападокији..."}]]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;На тај начин могу лако да сортирам чланке.&lt;/p&gt;

&lt;p&gt;И шта још би могао да ту додам? Адресу, тј. URL сваког чланка. Намерно
бих да title буде наслов у самој страници а да име фајла буде
URL. Тако да ако предходни пример чланак назовем: o-kapadokji.md,
формат који би &lt;strong&gt;get_posts&lt;/strong&gt; метода враћала би био:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[["20110324", {"url" =&gt; "o-kapadokiji", "title" =&gt; "Кападокија", "body" =&gt; "Премало се зна о Кападокији..."}]]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Да то направим да буде направићу два фајла која ћу да користим за
тестирање:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mkdir spec/fixtures
$ emacs spec/fixtures/o-kapadokiji.md 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И ту ставим горе наведени текст. Онда отворим други фајл:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ emacs spec/fixtures/let.md
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ставим следећи текст:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;title: Авионски лет
date: 20110325

25. марта 1923. - Слетањем авиона на линији Париз-Цариград на аеродром
у Панчеву, Краљевина СХС постала део тада малобројне породице држава
повезаних ваздушним саобраћајем.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Сада да преправим тест:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe "get_posts" do
  it "should return posts" do
    first_article = File.readlines("spec/fixtures/o-kapadokiji.md", "")[1]
    second_article = File.readlines("spec/fixtures/let.md", "")[1]
    YAML.should_receive(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov", "store" =&gt; "spec/fixtures"}) 

    get_posts.should == \
    [[20110325,  {"url" =&gt; "let", "title" =&gt; "Авионски лет", "body" =&gt; "#{second_article}"}],\
     [20110324, {"url" =&gt; "o-kapadokiji", "title" =&gt; "Кападокија", "body" =&gt; "#{first_article}"}]]

  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Да објасним овде да &lt;strong&gt;first_article&lt;/strong&gt; и &lt;strong&gt;second_article&lt;/strong&gt; су само
фајлови учитани, да не бих писао цео њихов садржај. И &lt;strong&gt;store&lt;/strong&gt; сада
чита фајлове из &lt;strong&gt;spec/fixtures&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Покренм тестирање:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rspec spec/blurgh_spec.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;али тест не прође:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1) blurgh get_posts should return posts
     Failure/Error: get_posts.should == \
     Errno::ENOENT:
       No such file or directory - posts
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;То је зато што на самом почетку теста имам:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;before :each do
  YAML.should_receive(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov", "store" =&gt; "posts"}) 
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;који попуњава &lt;strong&gt;store&lt;/strong&gt; са &lt;strong&gt;posts&lt;/strong&gt;. Да би то спречио одвојићу прва
неколико теста у једну целину на следећи начин:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; context "routes and content" do
   before :each do
     YAML.should_receive(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov", "store" =&gt; "posts"}) 
   end

   it "should respond to /" do
     get '/'
     last_response.should be_ok
   end

   it "should have a title" do
     get '/'
     last_response.body.should match("Naslov")
   end

   context "the view" do
     it "should have a body html elements" do
       get '/'
       last_response.body.should match("&lt;body&gt;")
     end
   end
 end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;док је други тест сам за себе.&lt;/p&gt;

&lt;p&gt;Покренем тест и он опет не пролази:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1) blurgh get_posts should return posts
   Failure/Error: [["20110325"], {"url" =&gt; "let", "title" =&gt; "Авионски лет", "body" =&gt; "#{second_article}"}]]
     expected: [[["20110324"], {"url"=&gt;"o-kapadokiji", "title"=&gt;"Кападокија",
     ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;што је и пожељан резултат. Јер ако се анлизира грешка, драгачија је од
предходне: не жали се о томе како не може да прочита неки фајл, већ да
резултат методе није идентичан очекиваном.&lt;/p&gt;

&lt;p&gt;Сада да прилагодим методу, да би прошао тест:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def get_posts

  all_posts = Hash.new {
    |h,k| h[k] = Hash.new(&amp;h.default_proc) 
  }

  post_dir = File.join(Config.store + "/" + "*.md")

  Dir.glob(post_dir).each do |post|
    header, body = File.readlines(post, "")
    data = YAML.load(header)
    all_posts[data['date']]['url']   = post.gsub("\.md", "").gsub(Config.store + "/", "")
    all_posts[data['date']]['title'] = data['title']
    all_posts[data['date']]['body']  = body
  end

  all_posts.sort.reverse

end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;all_posts&lt;/strong&gt; je “хаш хашева” (следи објашњење!). &lt;strong&gt;Dir.glob&lt;/strong&gt; чита
фајлове из &lt;strong&gt;Config.store&lt;/strong&gt; и попуњава &lt;strong&gt;all_posts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Покренем тест и … он падне:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1) blurgh get_posts should return posts
   Failure/Error: YAML.should_receive(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov", "store" =&gt; "spec/fixtures"})
     (Syck).load_file("setup.yaml")
         expected: 1 time
         received: 3 times
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ово ми говори да сам добио жељени резултат, но само је метода позивала
&lt;strong&gt;YAML.load_file&lt;/strong&gt; више него што је означено у тесту. Овде ми тест не
помаже да програм буде коректан, већ и ефикаснији.&lt;/p&gt;

&lt;p&gt;Преправим методу у:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def get_posts

  all_posts = Hash.new {
    |h,k| h[k] = Hash.new(&amp;h.default_proc) 
  }

  store = Config.store
  post_dir = File.join(store + "/" + "*.md")

  Dir.glob(post_dir).each do |post|
    header, body = File.readlines(post, "")
    data = YAML.load(header)
    all_posts[data['date']]['url']   = post.gsub("\.md", "").gsub(store + "/", "")
    all_posts[data['date']]['title'] = data['title']
    all_posts[data['date']]['body']  = body
  end

  all_posts.sort.reverse

end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем тест и сада прође. Што значи да треба да се убаци у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
# On branch posts
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   modified:   blurgh.rb
#   modified:   spec/blurgh_spec.rb
#
# Untracked files:
#   (use "git add &lt;file&gt;..." to include in what will be committed)
#
#   spec/fixtures/
no changes added to commit (use "git add" and/or "git commit -a")
$ git add blurgh.rb spec/blurgh_spec.rb spec/fixtures/
$ git status
# On branch posts
# Changes to be committed:
#   (use "git reset HEAD &lt;file&gt;..." to unstage)
#
#   modified:   blurgh.rb
#   modified:   spec/blurgh_spec.rb
#   new file:   spec/fixtures/let.md
#   new file:   spec/fixtures/o-kapadokiji.md
#
$ git commit -m "урађена метода get_posts"
[posts fba900e] урађена метода get_posts
 4 files changed, 81 insertions(+), 31 deletions(-)
 rewrite spec/blurgh_spec.rb (73%)
 create mode 100644 spec/fixtures/let.md
 create mode 100644 spec/fixtures/o-kapadokiji.md
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Наставља се… (у следећој епизоди RSpec пије пиво и осваја свет)&lt;/p&gt;

&lt;p&gt;Да видим како би то сада могао да организујем да се листа чланака
прикаже на почетној страни.&lt;/p&gt;

&lt;p&gt;Додам следећи тест:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;context "on the index page" do
  it "the posts URLs should be listed" do
    get '/'
    last_response.body.should match("let")
    last_response.body.should match("o-kapadokiji")
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;под **describe “get_posts” **, покренем тестирање и оно пада:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1) blurgh get_posts on the index page the posts URLs should be listed
   Failure/Error: last_response.body.should match("let")
     expected "&lt;html&gt;\n  &lt;body&gt;\n    &lt;h1&gt;Пази сад&lt;/h1&gt;\n\n  &lt;/body&gt;\n&lt;/html&gt;\n" to match "let"
   # ./spec/blurgh_spec.rb:47:in `block (4 levels) in &lt;top (required)&gt;'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;што ми указује да мој тест чита прави setup.yaml, што треба исправити
тако што наместим да се YAML објекат учита пре самог теста. То урадим
на следећи начин, тако што омогућим у &lt;strong&gt;before&lt;/strong&gt; блоку:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe "get_posts" do

  before do
    YAML.should_receive(:load_file).with("setup.yaml")\
      .and_return({"title" =&gt; "Naslov", "store" =&gt; "spec/fixtures"})
  end

  it "should return posts" do
    first_article = File.readlines("spec/fixtures/o-kapadokiji.md", "")[1]
    second_article = File.readlines("spec/fixtures/let.md", "")[1]

    get_posts.should == \
    [[20110325,  {"url" =&gt; "let", "title" =&gt; "Авионски лет", "body" =&gt; "#{second_article}"}],\
     [20110324, {"url" =&gt; "o-kapadokiji", "title" =&gt; "Кападокија", "body" =&gt; "#{first_article}"}]]
  end

  context "on the index page" do
    it "the posts URLs should be listed" do
      get '/'
      last_response.body.should match("let")
      last_response.body.should match("o-kapadokiji")
    end
  end

end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Тест опет пада, али са садржајем који сам ја дефинисао у тесту:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1) blurgh get_posts on the index page the posts URLs should be listed
   Failure/Error: last_response.body.should match("let")
     expected "&lt;html&gt;\n  &lt;body&gt;\n    &lt;h1&gt;Naslov&lt;/h1&gt;\n\n  &lt;/body&gt;\n&lt;/html&gt;\n" to match "let"
   # ./spec/blurgh_spec.rb:53:in `block (4 levels) in &lt;top (required)&gt;'    
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Сада да наместим да index.html добије линкове чланака, преправим
оригинални &lt;strong&gt;get ‘/’&lt;/strong&gt; у:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/' do
  @title = Config.title
  @posts = get_posts
  erb :index 
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и у &lt;strong&gt;index.erb&lt;/strong&gt; додам:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;% @posts.each do |post| %&gt;
   &lt;%= post[1]['url'] %&gt;
&lt;% end %&gt;    
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем тест, али овај пут само одређени, задњи тест на којем радим:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bundle exec rspec -e "blurgh get_posts on the index page" spec/blurgh_spec.rb         
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;резултат је:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Failures:

    1) blurgh get_posts on the index page the posts URLs should be listed
       Failure/Error: YAML.should_receive(:load_file).with("setup.yaml")\
         (Syck).load_file("setup.yaml")
             expected: 1 time
             received: 2 times
       # ./spec/blurgh_spec.rb:36:in `block (3 levels) in &lt;top (required)&gt;'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;што ми говори да очекивани резултат теста је тачан, али да се
конфигурациони фајл чита два пута. Једном се чита:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@title = Config.title
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;а други пут:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@posts = get_posts
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Могао бих да преправим Config модул да чита резултате само једном и да
их све врати. Нешто овако:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;self.all
  options["title"], options["store"]
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Али што се тиче овог чланка, овако је једноставније за сада, ма да
можда није изванредно ефикасно. Но да не заборавим, ставићу белешку да
се овоме вратим и погледам поново:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module Config
  # TODO: moze biti efikasnije
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Сада да подесим тест:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;YAML.should_receive(:load_file).exactly(2).times.with("setup.yaml")\
  .and_return({"title" =&gt; "Naslov", "store" =&gt; "spec/fixtures"})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Додао сам: &lt;strong&gt;.exactly(2).times&lt;/strong&gt; што ће омогућити да тест прође:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rspec -e "blurgh get_posts on the index page" spec/blurgh_spec.rb
Run filtered using {:full_description=&gt;/(?-mix:blurgh get_posts on the index page)/}

blurgh
  routes and content
    the view
  get_posts
    on the index page
      the posts URLs should be listed

Finished in 0.02366 seconds
1 example, 0 failures
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Покренем тест за цео програм и добијам следећу грешку за четири случаја:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;blurgh
  routes and content
    should respond to / (FAILED - 1)
    should have a title (FAILED - 2)
    the view
      should have a body html elements (FAILED - 3)
  get_posts
    should return posts (FAILED - 4)

 ...    

 Failure/Error: YAML.should_receive(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov", "store" =&gt; "posts"})
   (Syck).load_file("setup.yaml")
       expected: 1 time
       received: 2 times    
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И то исто могу да исправим тако што учиним исту измену и за те
тестове, али опет добијам следећу грешку:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1) blurgh get_posts should return posts
   Failure/Error: YAML.should_receive(:load_file).exactly(2).times.with("setup.yaml")\
     (Syck).load_file("setup.yaml")
         expected: 2 times
         received: 1 time
   # ./spec/blurgh_spec.rb:37:in `block (3 levels) in &lt;top (required)&gt;'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Што ми указује да ћу више труда потрошити на измени тестова, него да
применим нову методу &lt;strong&gt;all&lt;/strong&gt; у &lt;strong&gt;Config&lt;/strong&gt; модулу. Зато вратим ове две
задње измене и додам нови тест:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe ".all" do
  it "should return all the values" do
    YAML.should_receive(:load_file).with("setup.yaml")\
      .and_return({"title" =&gt; "Naslov", "store" =&gt; "posts"}) 
    Config.all.should == {"title" =&gt; "Naslov", "store" =&gt; "posts"}
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;са методом:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def self.all
  options
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Покренм тестове за &lt;strong&gt;Config&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rspec spec/config_spec.rb     
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;сви прођу.&lt;/p&gt;

&lt;p&gt;Сада да преправим тестове за blurgh:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;it "should return posts" do
  first_article = File.readlines("spec/fixtures/o-kapadokiji.md", "")[1]
  second_article = File.readlines("spec/fixtures/let.md", "")[1]
  store = Config.all['store']

  get_posts(store).should == \
  [[20110325,  {"url" =&gt; "let", "title" =&gt; "Авионски лет", "body" =&gt; "#{second_article}"}],\
   [20110324, {"url" =&gt; "o-kapadokiji", "title" =&gt; "Кападокија", "body" =&gt; "#{first_article}"}]]
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;тест у овом случају неће да прође јер &lt;strong&gt;get_posts&lt;/strong&gt; метода очекује
аргумент. Њу преправим у:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def get_posts(store)

  all_posts = Hash.new {
    |h,k| h[k] = Hash.new(&amp;h.default_proc) 
  }

  post_dir = File.join(store + "/" + "*.md")

  Dir.glob(post_dir).each do |post|
    header, body = File.readlines(post, "")
    data = YAML.load(header)
    all_posts[data['date']]['url']   = post.gsub("\.md", "").gsub(store + "/", "")
    all_posts[data['date']]['title'] = data['title']
    all_posts[data['date']]['body']  = body
  end

  all_posts.sort.reverse

end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Покренем тест, али он пада:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1) blurgh routes and content should respond to /
   Failure/Error: get '/'
   ArgumentError:
     wrong number of arguments (0 for 1)
   ...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Порука је да у &lt;strong&gt;get ‘/’&lt;/strong&gt; користим нешто са погрешним бројем
аргумената. Изменим блок да сада користи аргумент у позиву у
&lt;strong&gt;get_posts&lt;/strong&gt; методи:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/' do
  blurgh_conf = Config.all
  @title = blurgh_conf['title']
  @posts = get_posts(blurgh_conf['store'])
  erb :index 
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Покренем тестирање и све прође:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rake
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И пре него што убацим то у гит, било би добро да погледам како то
заправо изгледа.&lt;/p&gt;

&lt;p&gt;Отворим setup.yaml и додам:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;store: spec/fixtures
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем апликацију:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ shotgun blurgh.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И погледам &lt;a href="http://localhost:9393/"&gt;http://localhost:9393/&lt;/a&gt; и видим
имена фајлова.&lt;/p&gt;

&lt;p&gt;Вратим измену у setup.yaml и додам рад у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
# On branch posts
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   modified:   blurgh.rb
#   modified:   spec/blurgh_spec.rb
#   modified:   spec/config_spec.rb
#   modified:   views/index.erb
#
# Untracked files:
#   (use "git add &lt;file&gt;..." to include in what will be committed)
#
#   .bundle/
no changes added to commit (use "git add" and/or "git commit -a")
$ git add blurgh.rb spec/ views/
$ git status
# On branch posts
# Changes to be committed:
#   (use "git reset HEAD &lt;file&gt;..." to unstage)
#
#   modified:   blurgh.rb
#   modified:   spec/blurgh_spec.rb
#   modified:   spec/config_spec.rb
#   modified:   views/index.erb
#
# Untracked files:
#   (use "git add &lt;file&gt;..." to include in what will be committed)
#
#   .bundle/
$ git commit -m "приказује листу чланака на index.html"
[posts 21d9938] приказује листу чланака на index.html
 4 files changed, 45 insertions(+), 13 deletions(-)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Једна напомена овде, кад сам урадио &lt;strong&gt;git status&lt;/strong&gt; приказана су четири
фајла. Али ја сам уписао само три аргумента кад сам радио &lt;strong&gt;git add&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git add blurgh.rb spec/ views/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;То је зато што када се гиту дају аргументи са завршном &lt;strong&gt;/&lt;/strong&gt;, он учита
фајлове из тог директоријума.&lt;/p&gt;

&lt;p&gt;У следећој епизоди: претварање фајлова у линкове и можда још нешто…&lt;/p&gt;</description><link>http://ruby.rs/post/4185107487</link><guid>http://ruby.rs/post/4185107487</guid><pubDate>Tue, 29 Mar 2011 17:06:58 +0200</pubDate></item><item><title>Блог у синатри, епизода шеста</title><description>&lt;p&gt;Пошто имам сада основну структуру, мало да “затегнем” тестирање.&lt;/p&gt;

&lt;p&gt;Створим нови огранак у коме ћу да радим:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout -b mocks
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Кад сам намештао YAML објекат да врати садржај фајла:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;YAML.stub!(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov"})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ја сам користио &lt;strong&gt;stub!&lt;/strong&gt;. А описивао сам &lt;strong&gt;stub&lt;/strong&gt;. Иако обе методе
врше исту сврху, &lt;strong&gt;stub!&lt;/strong&gt; (са узвичником) потиче из RSpec верзије 1,
док је &lt;strong&gt;stub&lt;/strong&gt; из RSpec 2. Обе раде у верзији 2.&lt;/p&gt;

&lt;p&gt;То може да се преправи, али би било боље да се пређе на нешто још и
боље: &lt;strong&gt;mocks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Пре него што то урадим да објасним шта је шта.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stub&lt;/strong&gt; је замена за објекат или делове, тј. методе, за објекат.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mock&lt;/strong&gt; је “лажни” објекат.&lt;/p&gt;

&lt;p&gt;Која је разлика ?&lt;/p&gt;

&lt;p&gt;Разлика између &lt;strong&gt;stub&lt;/strong&gt; и &lt;strong&gt;mocks&lt;/strong&gt; је у томе што је &lt;strong&gt;mock&lt;/strong&gt;
“интерактиван”. Шта то тачно значи? У овом случају то значи да
&lt;strong&gt;mock&lt;/strong&gt; јасно дефинише да треба да се назове/користи. Ако није
назван/коришћен током теста, тест је неуспешан. Док &lt;strong&gt;stub&lt;/strong&gt; неће да
се жали ако се не користи у тесту.&lt;/p&gt;

&lt;p&gt;Ево и примера:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe ".title" do
  it "should return value" do
    YAML.stub!(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov"}) 
    Config.title.should match("Naslov")
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ако додам у њега додам YAML.stub(:load):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe ".title" do
  it "should return value" do
    YAML.stub!(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov"}) 
    YAML.stub(:load) # &lt;-- додатак
    Config.title.should match("Naslov")
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Тест ће да успе. Али ако то урадим са &lt;strong&gt;mock&lt;/strong&gt;-ом:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe ".title" do
  it "should return value" do
    YAML.stub!(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov"}) 
    YAML.should_receive(:load)  # &lt;-- додатак
    Config.title.should match("Naslov")
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;тест не пролази:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Failures:

  1) Config.title should return value
     Failure/Error: YAML.should_receive(:load)
       (Syck).load(any args)
           expected: 1 time
           received: 0 times
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Да би направили тест да буде што реалнији, боље би било да се пише овако:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;describe ".title" do
  it "should return value" do
    YAML.should_receive(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov"}) 
    Config.title.should match("Naslov")
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Онда заменим све &lt;strong&gt;stub!&lt;/strong&gt; са &lt;strong&gt;should_receive&lt;/strong&gt; и покренем тестове:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rake 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;сви пролазе. Да видим шта је измењено:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
# On branch mocks
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   modified:   spec/blurgh_spec.rb
#   modified:   spec/config_spec.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Онда да их додам у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git add spec/blurgh_spec.rb spec/config_spec.rb
$ git commit -m "мала измена у тестовима, са stub на mock"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И онда додам нове измене у главно стабло кода:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout master
Switched to branch 'master'
asimic@byzantium:~/dev/blurgh2$ git merge mocks
Updating 4f37cd4..c13635d
Fast-forward
 spec/blurgh_spec.rb |    2 +-
 spec/config_spec.rb |    6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

$ git merge mocks
Updating 4f37cd4..c13635d
Fast-forward
 spec/blurgh_spec.rb |    2 +-
 spec/config_spec.rb |    6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)
&lt;/code&gt;&lt;/pre&gt;</description><link>http://ruby.rs/post/4185100407</link><guid>http://ruby.rs/post/4185100407</guid><pubDate>Tue, 29 Mar 2011 17:06:26 +0200</pubDate></item><item><title>Блог у синатри, епизода пета</title><description>&lt;p&gt;До сада, радио сам само са тестовима, нисам заиста пробао
апликацију. Најлакши начин да се покрене синатра апликација је
користећи shotgun. Дакле:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout -b proba
$ emacs Gemfile
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И у њу додам:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem 'shotgun'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Па
    $ bundle install&lt;/p&gt;

&lt;p&gt;Да би покренуо апликацију:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ shotgun blurgh.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И отворим http://localhost:9393/, али ту је грешка, јер нема setup.yaml фајла.&lt;/p&gt;

&lt;p&gt;Направим setup.yaml са следећим садржајем:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;title: Пази сад
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Поново отворим страницу, и видим “Пази сад” у &lt;strong&gt;h1&lt;/strong&gt; таговима као што
очекујем.&lt;/p&gt;

&lt;p&gt;Да убацим садржај у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git add Gemfile setup.yaml
$ git commit -m "апликација приказује странице"
$ git checkout master
$ git merge proba
&lt;/code&gt;&lt;/pre&gt;</description><link>http://ruby.rs/post/4185094807</link><guid>http://ruby.rs/post/4185094807</guid><pubDate>Tue, 29 Mar 2011 17:06:01 +0200</pubDate></item><item><title>Блог у синатри, епизода четврта</title><description>&lt;p&gt;Пошто је ово систем за блог, било би пожељно да има начин како ће моћи
да прикаже садржај.&lt;/p&gt;

&lt;p&gt;Правим нови огранак:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout -b views
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Напишем следећи тест у &lt;strong&gt;blurgh_spec.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;context "the view" do
  it "should have a body html elements" do
    get '/'
    last_response.body.should match("&lt;body&gt;")
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;следеће:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mkdir views
$ emacs views/layout.erb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;у који додам:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;html&gt;
  &lt;body&gt;
    &lt;%= yield %&gt;
  &lt;/body&gt;
&lt;/html&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;у фајл views/index.erb ставим:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&lt;h1&gt;&lt;%= @title %&gt;&lt;/h1&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;У главном програму додам следеће:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;get '/' do
  @title = Config.title
  erb :index 
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем тест и он прође.&lt;/p&gt;

&lt;p&gt;Онда рад додам у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
# On branch master
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   modified:   blurgh.rb
#   modified:   spec/blurgh_spec.rb
#
# Untracked files:
#   (use "git add &lt;file&gt;..." to include in what will be committed)
#
#   views/
no changes added to commit (use "git add" and/or "git commit -a")
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;То ми говори да су измењена два фајла: blurgh.rb и spec/blurgh_spec.rb и додан views.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git add blurgh.rb spec/blurgh_spec.rb
asimic@byzantium:~/dev/blurgh2$ git add views/
asimic@byzantium:~/dev/blurgh2$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD &lt;file&gt;..." to unstage)
#
#   modified:   blurgh.rb
#   modified:   spec/blurgh_spec.rb
#   new file:   views/index.erb
#   new file:   views/layout.erb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Друго додавање у гиту: &lt;strong&gt;git add views/&lt;/strong&gt;, намерно сам користио &lt;strong&gt;/&lt;/strong&gt;
на самом крају јер то онда дода гиту све фајлове у том директоријому.&lt;/p&gt;

&lt;p&gt;И за крај:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git commit -m "додани views"
$ git checkout master
$ git merge views
&lt;/code&gt;&lt;/pre&gt;</description><link>http://ruby.rs/post/4185088725</link><guid>http://ruby.rs/post/4185088725</guid><pubDate>Tue, 29 Mar 2011 17:05:33 +0200</pubDate></item><item><title>Блог у синатри, епизода трећа</title><description>&lt;p&gt;А шта ако setup.yaml нема title дефинисан? Или ако нема setup.yaml
ништа у себи?&lt;/p&gt;

&lt;p&gt;Отворим нови огранак:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout -b extra_checks
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и ту почнем да пишем тестове у spec/config_spec.rb:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;context "when the title is blank" do
  it "should return nothing" do
    YAML.stub!(:load_file).with("setup.yaml").and_return({"title" =&gt; ""}) 
    Config.title.should match("")
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Пробам:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rspec spec/config_spec.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Тест прође. Онда додам други:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;context "when the title is missing" do
  it "should return nil" do
    YAML.stub!(:load_file).with("setup.yaml").and_return({}) 
    Config.title.should be_nil
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И он прође. Онда пробам све тестове заједно:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rake

Config
  .title
    should return value
  when the title is blank
    should return nothing
  when the title is missing
    should return nil

blurgh
  should respond to /
  should have a title

Finished in 0.01154 seconds
5 examples, 0 failures
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Сви пролазе. Онда додам напредак у гит и све ставим у главно стабло:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git add spec/config_spec.rb
$ git commit -m "још тестова за Config.title" 
$ git checkout master
$ git merge extra_checks
&lt;/code&gt;&lt;/pre&gt;</description><link>http://ruby.rs/post/4106221743</link><guid>http://ruby.rs/post/4106221743</guid><pubDate>Sat, 26 Mar 2011 13:56:00 +0100</pubDate><category>Александар Симић</category><category>RSpec</category><category>sinatra</category></item><item><title>Блог у синатри, епизода друга</title><description>&lt;p&gt;Да би додали нешто ново, пожељно је да се направи нови огранак (branch) у гиту:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout -b config_file    
$ git branch
* config_file
  master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Са задњом сам направио нови огранак и наместио њега као тренутно место
у гиту где ће ићи сав нов рад.&lt;/p&gt;

&lt;p&gt;Овај систем ће читати своју конфигурацију из setup.yaml фајла, чији формат ће изгледати овако:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;title: Име мог блога
store: posts
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Title ће бити сам наслов, suffix је завршни део назива фајлова, у овом
случају у Markdown формату и store означава где ће се фајлови стављати.&lt;/p&gt;

&lt;p&gt;Тако да када будем отишао на почетну страну ја требам да видим наслов
или назив. То треба да се подеси у тесту:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;it "should have a title" do
  get '/'
  last_response.body.should match("Naslov")
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И ако покренем тестирање:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rake
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;следећа грешка се појављује:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Failures:

  1) blurgh should have a title
     Failure/Error: last_response.body.should match("Naslov")
       expected "" to match "Naslov"
     # ./spec/blurgh_spec.rb:16:in `block (2 levels) in &lt;top (required)&gt;'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Да би то решио, ‘/’ адреса треба да испише наслов који ће да добије из фајла у YAML формату.&lt;/p&gt;

&lt;p&gt;Пошто ништа не чита тај фајл, направићу модул који га чита. Али прво да кренем са тестом:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;emacs spec/config_spec.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И ту опишем како би да се понаша тај модул:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'spec_helper'

describe "Config" do

  describe ".title" do
    it "should return value" do
      Config.title.should match("Naslov")
    end
  end

end  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ту означим да метода title ће вратити вредност дефинисану у фајлу, у
овом случају то ће бити “Naslov”.&lt;/p&gt;

&lt;p&gt;Онда напишем Config модул у &lt;strong&gt;blurgh.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module Config
  def self.title
    options["title"]
  end

  private
  def self.options
    YAML.load_file("setup.yaml")
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;где приватна метода options чита YAML конфигурацију. Модул се&lt;/p&gt;

&lt;p&gt;Да би могао да читам YAML формат, додам:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'yaml'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Вратим се тесту, покренем га, он не ради:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; Failure/Error: Config.title.should match("Naslov")
 Errno::ENOENT:
   No such file or directory - setup.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;То је зато што тај фајл и не постоји. Зато требa да се створи “лажни” фајл:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;YAML.stub!(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov"})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;stub&lt;/strong&gt; је део RSpec-а и он намести да метода врати пожељне
резултате. У овом случају намести да YAML врати учитан фајл setup.yaml
са садржајем “title: Naslov”.&lt;/p&gt;

&lt;p&gt;Ако погледате пажљиво, видећете да он у ствари не вараћа&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;"title: Naslov" 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;већ Hash са садржајем:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;"title" =&gt; "Naslov"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;То је зато што у овом случају ја желим да YAML објекат врати што
“реалнији” резултат. Шта то значи? Када YAML учита неки фајл, он учита
вредности из њега и стави их у Hash. А пошто ја овде хоћу да наместим
YAML да ми врати пожељне вредности, ја их сам попуним.&lt;/p&gt;

&lt;p&gt;Сада да пробам само задњи тест:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rspec spec/config_spec.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Он прође.&lt;/p&gt;

&lt;p&gt;Сада се вратим на првобитни тест у spec/blurgh_spec.rb и додам у &lt;strong&gt;it
“should have a title” do&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;YAML.stub!(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov"}) 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rake
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и опет тест за наслов пада. То је зато што ништа се не враћа из главне
синатрине методе. Да би то исправио додам следеће:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Config.title
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;покренем&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rake
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И уместо да сви тестови прођу, први пада. То је првобитни тест, зато
што он не може да нађе setup.yaml фајл. Да би то исправио, убацим
следећи блок:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;before :all do
  YAML.stub!(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov"})     
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Али тада само први тест прође, други пада. Ако изменим блок у &lt;strong&gt;before
:each&lt;/strong&gt;, онда сваки тест у blurgh_spec добије “лажни” фајл, то јест
stub setup.yaml фајла:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'spec_helper'

describe "blurgh" do

  before :each do
    YAML.stub!(:load_file).with("setup.yaml").and_return({"title" =&gt; "Naslov"})     
  end

  def app
    @app ||= Sinatra::Application
  end

  it "should respond to /" do
    get '/'
    last_response.should be_ok
  end

  it "should have a title" do
    get '/'
    last_response.body.should match("Naslov")
  end

end


$ bundle exec rake

Config
  .title
    should return value

blurgh
  should respond to /
  should have a title

Finished in 0.01046 seconds
3 examples, 0 failures
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;После овог напредка, додам то у гит. Прво да видим статус:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
# On branch config_file
# Changed but not updated:
#   (use "git add &lt;file&gt;..." to update what will be committed)
#   (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
#
#   modified:   blurgh.rb
#   modified:   spec/blurgh_spec.rb
#
# Untracked files:
#   (use "git add &lt;file&gt;..." to include in what will be committed)
#
#   spec/config_spec.rb
no changes added to commit (use "git add" and/or "git commit -a")
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Што значи да blurgh.rb и spec/blurgh_spec.rb су измењене а
spec/config_spec.rb је нови фајл.&lt;/p&gt;

&lt;p&gt;Све промене додам гит (у два корака):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git add blurgh.rb spec/blurgh_spec.rb spec/config_spec.rb
$ git status
# On branch config_file
# Changes to be committed:
#   (use "git reset HEAD &lt;file&gt;..." to unstage)
#
#   modified:   blurgh.rb
#   modified:   spec/blurgh_spec.rb
#   new file:   spec/config_spec.rb
$ git commit -m "додан нови модул Config"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Погледао сам статус гита, чисто да видим да ли је све тачно унешено.&lt;/p&gt;

&lt;p&gt;Тренутно сам и даље на огранку config_file, да потврдим:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git branch
\* config_file
  master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Да би унео нови део напредка у главно стабло гита, требам да се
пребацим у њега и да упишем нове рад. То радим овако:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout master
Switched to branch 'master'

$ git merge config_file
Updating b740f6e..b95240c
Fast-forward
 blurgh.rb           |   13 +++++++++++++
 spec/blurgh_spec.rb |   12 +++++++++++-
 spec/config_spec.rb |   12 ++++++++++++
 3 files changed, 36 insertions(+), 1 deletions(-)
 create mode 100644 spec/config_spec.rb
&lt;/code&gt;&lt;/pre&gt;</description><link>http://ruby.rs/post/4086480346</link><guid>http://ruby.rs/post/4086480346</guid><pubDate>Fri, 25 Mar 2011 17:54:00 +0100</pubDate></item><item><title>Блог систем у синатри, епизода прва</title><description>&lt;p&gt;Идеја овог чланка је писање апликације у синатри, са тестирањем и
гитом. Предходно знање ових технологија/апликација није потребно.&lt;/p&gt;

&lt;p&gt;Блог систем треба да има YAML фајл у коме се убаци наслов, и место где
ће да се држе чланци.&lt;/p&gt;

&lt;p&gt;Од самог почетка користићу тестирање:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mkdir blurgh
$ cd blurgh 
$ emacs Gemfile
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и додам:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;source 'http://rubygems.org'

gem 'sinatra'
gem 'rack-test'
gem 'rspec'
gem 'rake'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;онда инсталирам:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ gem install -r bundle 
$ bundle install    
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Да би омогућио да RSpec функционше, требам да направим следеће фајлове:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ mkdir spec
$ emacs spec/spec_helper.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;И додам следеће:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require File.join(File.dirname(__FILE__), '..', 'blurgh')

require 'sinatra'
require 'rack/test'
require 'rspec'


# set test environment
set :environment, :test
set :run, false
set :raise_errors, true
set :logging, false


RSpec.configure do |c|
  c.include Rack::Test::Methods
end    
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Кључни део овде је додавање: Rack::Test::Methods. То омогућава
тестирање уз помоћ &lt;a href="http://rack.rubyforge.org/"&gt;&lt;strong&gt;rack&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Онда направим први тест:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ emacs spec/blurgh_spec.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и напишем први тест:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'spec_helper'

describe "blurgh" do

  def app
    @app ||= Sinatra::Application
  end

  it "should respond to /" do
    get '/'
    last_response.should be_ok
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;да покренем тај тест:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rspec spec/blurgh_spec.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;он наравно неће да прође јер још увек нема главне апликације, зато&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ emacs blurgh.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и додам следеће:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/env ruby

require 'sinatra'

get '/' do
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;поново покренем тестирање:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rspec spec/blurgh_spec.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и избаци следеће резултате:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rspec spec/blurgh_spec.rb 
.

Finished in 0.01479 seconds
1 example, 0 failures
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;да би то било мало разговетније, покренем тестирање са “документационом” опцијом и бојом, овако:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rspec -f doc --colour spec/blurgh_spec.rb 

blurgh
  should respond to /

Finished in 0.01517 seconds
1 example, 0 failures
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;То је добар почетак, и то ћу да убацим у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git init
$ emacs .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;и ту ставим следеће:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Gemfile.lock

## Mac OS
.DS_Store

## Textmate
*.tmproj
tmtags

## Emacs
*~
\#*
.\#*

## Vim
*.swp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;додам фајлове у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git add .
$ git status
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;који врати следеће:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached &lt;file&gt;..." to unstage)
#
#   new file:   .gitignore
#   new file:   Gemfile
#   new file:   blurgh.rb
#   new file:   spec/blurgh_spec.rb
#   new file:   spec/spec_helper.rb
#
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;онда упишем те промене фајлове:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git commit -m "сам почетак"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;што испише следеће резултате&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[master (root-commit) ea5dd64] сам почетак
 5 files changed, 58 insertions(+), 0 deletions(-)
 create mode 100644 .gitignore
 create mode 100644 Gemfile
 create mode 100755 blurgh.rb
 create mode 100644 spec/blurgh_spec.rb
 create mode 100644 spec/spec_helper.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Али пошто је то досадно да се стално куца, користићу rake да то аутоматизујем:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ emacs Rakefile
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;у коју додам ово:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new do |t|
  t.rspec_opts = ["-r ./spec/spec_helper.rb"]
  t.pattern = 'spec/**/*_spec.rb'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;то омогућује RSpec да покреће тестове када се укуца:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rake spec 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Али пошто ће то бити честа радња, да омогућим да куцам што мање,
додајем и ово:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;task :default =&gt; "spec"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Тако да могу да укуцам само:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rake 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Да би имао боју и опис тестова, отворим нови фајл &lt;strong&gt;.rspec&lt;/strong&gt; и у њега убацим:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;--colour --format doc
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Сада резултат изгледа боље:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle exec rake 

blurgh
  should respond to /

Finished in 0.0092 seconds
1 example, 0 failures
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;То сада може да се дода у гит:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git status
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;ми покаже који су нови фајлови које могу да додам:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git add Rakefile .rspec
$ git commit -m "додајем Rakefile и .rspec"
&lt;/code&gt;&lt;/pre&gt;</description><link>http://ruby.rs/post/4044498226</link><guid>http://ruby.rs/post/4044498226</guid><pubDate>Wed, 23 Mar 2011 15:27:00 +0100</pubDate><category>Александар Симић</category><category>sinatra</category><category>RSpec</category></item><item><title>Опис књиге: Rails 3 in Action</title><description>&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_libwu9iOow1qa194t.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;Књиге које описују неку тренутну технологију или “алат” брзо остаре и њихов значај губи смисао, зато што касни за технологијом коју описује. Није много другачије што се тиче “Шина” (или ти Rails). Штавише, мислим да су књиге које описују Rails, кад се издају, већ “бајате” и говоре о томе како се радило јуче.&lt;/p&gt;

&lt;p&gt;“Rails 3 in Action” покушава да то мало измени, тако што почиње да учи читаоца како се ради са Rails-ом почевши са методологијама где се пишу тестови прво, па тек онда сам програм. За то је аутор књиге изабрао &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt; и &lt;a href="http://relishapp.com/rspec"&gt;RSpec&lt;/a&gt;. Све то је праћено коришћењем &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt; система за одржавање кода.&lt;/p&gt;

&lt;p&gt;Аутор то ради тако што да мали увод у све технологије, али да би то најбоље дочарао прави апликацију и објашњава кораке. На тај начин доступа читаоцу не само да види како се тренутно пишу апликације са тестирањем, него како и он сам ради.&lt;/p&gt;

&lt;p&gt;Моје разумевање “краставца” је да он треба да опише систем. Технологија коју он тестира може да се замени а да &lt;strong&gt;features&lt;/strong&gt; и &lt;strong&gt;steps&lt;/strong&gt; (делови који сачињавају краставац) могу да остану идентични. Начин на који аутор то приказује, није могуће. Модели скоро да нису тестирани, али зато контролери јесу.&lt;/p&gt;

&lt;p&gt;Књига наводи два аутора: Јехуду Кетца и Рајана А. Бига. Али заправо Рајан је &lt;a href="http://twitter.com/#!/ryanbigg/status/57022545865605120"&gt;пише сам&lt;/a&gt;. Но то не значи ништа негативно, књига служи као добра референца.&lt;/p&gt;

&lt;p&gt;Други разлог зашто наводим ауторе је JavaScript, и баш специфично &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;. Иако је Јехуда један од главних програмера на Rails и jQuery пројектима (или барем је био до издања Rails верзије 3), jQuery се и не помиње. Има један део где се говори о Prototype, али то је само мали пример.&lt;/p&gt;

&lt;p&gt;Да ли бих препоручио ову књигу? Моје мишљење је да не постоји један извор информација, без обзира на област. Тако да сматрам да је књига само још један начин на који можете видети нови приступ. Ја сам купио ову књигу, у MEAP&lt;strong&gt;*&lt;/strong&gt; издању, и неки пут погледам како је аутор радио или применио нешто. Али читање блогова и праћење пројекта, не само Rails, већ Cucumber, RSpec и других је потребно. Али ако нисте пре користили Rails, и желите да научите како да развијате пројекат тако што пишете прво тестове па програм, књига је добар увод.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.manning.com/katz/"&gt;Rails 3 In Action - издавачева страница&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Пројекат коришћен у књизи се налази &lt;a href="https://github.com/rails3book/ticketee"&gt;овде&lt;/a&gt; на github-у.&lt;/p&gt;

&lt;p&gt;* MEAP - електронско издање, где се добија приступ књизи док се још пише, поглавље по поглавље (Manning Early Access Program)&lt;/p&gt;

&lt;p&gt;(текст је преправљан 13. априла 2011)&lt;/p&gt;</description><link>http://ruby.rs/post/3970346427</link><guid>http://ruby.rs/post/3970346427</guid><pubDate>Sun, 20 Mar 2011 01:05:00 +0100</pubDate><category>rails</category><category>Александар Симић</category></item><item><title>Tri saveta Rubi početniku</title><description>&lt;p&gt;Pratim prilično redovno &lt;a href="http://stackoverflow.com/questions/tagged/ruby"&gt;pitanja sa Ruby tagom&lt;/a&gt; na &lt;a href="http://stackoverflow.com"&gt;StackOverflow&lt;/a&gt;, i primetio sam da se dobar deo pitanja vezanih za Ruby kao jezik vrti oko načina za manipulaciju podacima smeštenim u osnovne Rubi strukture podataka - često postavljač pitanja okači svoje “naivno” parče koda i pita kako bi izgledalo “elegantnije” ili “rubističkije” rešenje.&lt;/p&gt;

&lt;p&gt;S tim u vezi, evo par saveta za Rubi početnika koji želi da što pre prevaziđe ovakva pitanja, koja se zapravo svode na pisanje Java ili PHP koda u Rubiju:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Naučite jako dobro čemu služe i kako rade metode &lt;a href="http://apidock.com/ruby/Enumerable/map"&gt;&lt;code&gt;Enumerable#map&lt;/code&gt;&lt;/a&gt; i &lt;a href="http://apidock.com/ruby/Enumerable/inject"&gt;&lt;code&gt;Enumerable#inject&lt;/code&gt;&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;Prođite nekoliko puta kroz dokumentaciju za &lt;a href="http://apidock.com/ruby/Enumerable"&gt;&lt;code&gt;Enumerable&lt;/code&gt;&lt;/a&gt;, &lt;a href="http://apidock.com/ruby/Array"&gt;&lt;code&gt;Array&lt;/code&gt;&lt;/a&gt; i &lt;a href="http://apidock.com/ruby/Hash"&gt;&lt;code&gt;Hash&lt;/code&gt;&lt;/a&gt;, pažljivo pročitajte koje metode nude i koje sve oblike te metode mogu da uzmu (neke primaju opcioni blok itd).&lt;/li&gt;
&lt;li&gt;Naučite šta su blokovi. Naučite u čemu se razlikuju od funkcija, kako se prosleđuju i pozivaju iz metoda. Naučite pojam &lt;a href="http://en.wikipedia.org/wiki/Closure_(computer_science)"&gt;&lt;em&gt;closures&lt;/em&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Postoji još nekoliko “alata” koje Rubiju daju prednost nad “običnim” jezicima, ali se za početak zadržite na ove tri stavke, dok ih ne usvojite u potpunosti.&lt;/p&gt;</description><link>http://ruby.rs/post/518514689</link><guid>http://ruby.rs/post/518514689</guid><pubDate>Tue, 13 Apr 2010 17:55:33 +0200</pubDate><category>ruby 101</category><category>Mladen Jablanović</category></item><item><title>Hacking a subselect in ActiveRecord </title><description>&lt;a href="http://pivotallabs.com/users/jsusser/blog/articles/567-hacking-a-subselect-in-activerecord"&gt;Hacking a subselect in ActiveRecord &lt;/a&gt;: &lt;p&gt;U našoj Rails aplikaciji imamo jedan prilično nezgodan problem, o kome sam &lt;a href="http://www.devprotalk.com/showthread.php?t=7913"&gt;već pisao na DPT-u&lt;/a&gt;. Ukratko, treba mi broj slogova koji vraća SQL upit grupisan po nekoliko polja (videti primer na DPT-u). S obzirom da se ovo koristi iz Rails aplikacije korišćenjem ActiveRecord-a, nije moguće (barem u to doba nije bilo) izvršiti upit korišćenjem podupita, tj. nije moguće izvesti nešto ovako:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;SELECT COUNT(*) FROM
(SELECT 1 FROM tabela GROUP BY a, b) t
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pomoću uputstva na linkovanom članku ovo je ipak moguće izvesti, doduše malim hakovanjem pozivanjem privatne metode na ActiveRecord::Base klasi. Ona generiše SQL string koji posle koristimo kao vrednost parametra :from u upitu koji vraća COUNT, nešto ovako:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;count_sql = Model.send(:construct_finder_sql, :select =&gt; 1, :group =&gt; 'a, b')
Model.count(:from =&gt; "(#{count_sql}) a")
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Izgleda da radi. ;)&lt;/p&gt;</description><link>http://ruby.rs/post/435438557</link><guid>http://ruby.rs/post/435438557</guid><pubDate>Mon, 08 Mar 2010 23:57:35 +0100</pubDate><category>Mladen Jablanović</category><category>ActiveRecord</category><category>Rails</category><category>SQL</category></item><item><title>Je li f()==5 i 5==f() isto?</title><description>&lt;p&gt;Vi koji ste radili sa C-olikim jezicima setićete se jedne od konvencija pri pisanju if-uslova, da se vrednost sa kojom se promenljiva poredi piše sa leve strane znaka jednakosti, a promenljiva s desne (&lt;code&gt;if 5 == i&lt;/code&gt; naspram uobičajenog &lt;code&gt;if i == 5&lt;/code&gt;), zbog česte greške da se umesto dvostrukog znaka jednakosti stavi jednostruki, i odradi dodela vrednosti promenljivoj s leve strane, za šta se neki kompajleri ne bi bunili.&lt;/p&gt;

&lt;p&gt;Samo naoko sličan problem javlja se ponekad i u Rubiju, ali ne zbog moguće greške u kucanju, već zbog prirode znaka jednakosti.&lt;/p&gt;

&lt;p&gt;Analizirajući performanse jedne skripte profajlerom, primetio sam da se u listi pozivanih metoda neočekivano javlja metoda &lt;a href="http://apidock.com/ruby/Time/&lt;%3D&gt;"&gt;&lt;code&gt;Time#&lt;=&gt;&lt;/code&gt;&lt;/a&gt; (koja opet, iz ko zna kog razloga, zove &lt;code&gt;BasicObject#method_missing&lt;/code&gt;), iako sam bio prilično siguran da u kodu nemam poređenje objekata klase Time. Detaljnijim pregledom shvatio sam da se poziv te metode javlja pri proveri rezultata jedne metode, tj. u otprilike ovakvom koodu:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;return if m() == false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(Pre nego što počnete prozivku zbog onog &lt;code&gt;== false&lt;/code&gt;, reći ću da mi je bila potrebna eksplicitna provera za &lt;code&gt;false&lt;/code&gt;, tj. nisam hteo da mi se uslov ispuni ako je rezultat metode &lt;code&gt;nil&lt;/code&gt;, već samo &lt;code&gt;false&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;Ispostavilo se da metoda &lt;code&gt;m&lt;/code&gt; u nekim slučajevima vraća objekat klase &lt;code&gt;Time&lt;/code&gt;. (Ok, još malo pravdanja: metoda &lt;code&gt;m&lt;/code&gt; je zapravo metoda &lt;code&gt;send&lt;/code&gt; na jednom objektu, i može zapravo pozivati različite metode, otud nije baš uvek izvesno šta će se naći kao vraćena klasa.) S obzirom da je u Rubiju manje-više sve ili objekat ili poziv metode nekog objekta, ono &lt;code&gt;==&lt;/code&gt; je takođe poziv metode. U slučaju klase Time, ovaj operator ne vrši jednostavno poređenje referenci, pa se usled toga &lt;code&gt;==&lt;/code&gt; kome je poziv metode sa leve strane različito ponaša od onog gde je sa leve strane  npr. &lt;code&gt;false&lt;/code&gt;. Ok, da ne grešim dušu, kood se ponaša isto, ali se izvršava različitom brzinom, što opet nekad može da bude bitno.&lt;/p&gt;

&lt;p&gt;Da bi se izbegla nepotrebna logika vezana za konkretnu implementaciju metode &lt;code&gt;==&lt;/code&gt; levog objekta, dovoljno je promeniti redosled:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;return if false == m()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;false&lt;/code&gt; je u Rubiju instanca klase &lt;code&gt;FalseClass&lt;/code&gt;, i njeno &lt;code&gt;==&lt;/code&gt; je isto što i obično &lt;a href="http://apidock.com/ruby/Object/%3D%3D"&gt;&lt;code&gt;Object#==&lt;/code&gt;&lt;/a&gt;, odnosno jednostavna provera  jesu li u pitanju isti objekti.&lt;/p&gt;</description><link>http://ruby.rs/post/376838758</link><guid>http://ruby.rs/post/376838758</guid><pubDate>Sun, 07 Feb 2010 23:41:47 +0100</pubDate><category>Mladen Jablanović</category><category>ruby 101</category></item></channel></rss>

