-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 43f0fc4
Showing
66 changed files
with
1,095 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# See https://help.github.com/articles/ignoring-files for more about ignoring files. | ||
# | ||
# If you find yourself ignoring temporary files generated by your text editor | ||
# or operating system, you probably want to add a global ignore instead: | ||
# git config --global core.excludesfile '~/.gitignore_global' | ||
|
||
# Ignore bundler config. | ||
/.bundle | ||
|
||
# Ignore the default SQLite database. | ||
/db/*.sqlite3 | ||
/db/*.sqlite3-journal | ||
|
||
# Ignore all logfiles and tempfiles. | ||
/log/*.log | ||
/tmp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
source 'https://rubygems.org' | ||
gem 'rails', '4.0.2' | ||
gem 'sqlite3' | ||
gem 'sass-rails', '~> 4.0.0' | ||
gem 'uglifier', '>= 1.3.0' | ||
gem 'coffee-rails', '~> 4.0.0' | ||
gem 'jquery-rails' | ||
gem 'turbolinks' | ||
gem 'jbuilder', '~> 1.2' | ||
|
||
group :doc do | ||
gem 'sdoc', require: false | ||
end | ||
|
||
group :test, :development do | ||
gem 'mocha' | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
GEM | ||
remote: https://rubygems.org/ | ||
specs: | ||
actionmailer (4.0.2) | ||
actionpack (= 4.0.2) | ||
mail (~> 2.5.4) | ||
actionpack (4.0.2) | ||
activesupport (= 4.0.2) | ||
builder (~> 3.1.0) | ||
erubis (~> 2.7.0) | ||
rack (~> 1.5.2) | ||
rack-test (~> 0.6.2) | ||
activemodel (4.0.2) | ||
activesupport (= 4.0.2) | ||
builder (~> 3.1.0) | ||
activerecord (4.0.2) | ||
activemodel (= 4.0.2) | ||
activerecord-deprecated_finders (~> 1.0.2) | ||
activesupport (= 4.0.2) | ||
arel (~> 4.0.0) | ||
activerecord-deprecated_finders (1.0.3) | ||
activesupport (4.0.2) | ||
i18n (~> 0.6, >= 0.6.4) | ||
minitest (~> 4.2) | ||
multi_json (~> 1.3) | ||
thread_safe (~> 0.1) | ||
tzinfo (~> 0.3.37) | ||
arel (4.0.2) | ||
builder (3.1.4) | ||
coffee-rails (4.0.1) | ||
coffee-script (>= 2.2.0) | ||
railties (>= 4.0.0, < 5.0) | ||
coffee-script (2.3.0) | ||
coffee-script-source | ||
execjs | ||
coffee-script-source (1.7.1) | ||
erubis (2.7.0) | ||
execjs (2.2.1) | ||
hike (1.2.3) | ||
i18n (0.6.11) | ||
jbuilder (1.5.3) | ||
activesupport (>= 3.0.0) | ||
multi_json (>= 1.2.0) | ||
jquery-rails (3.1.1) | ||
railties (>= 3.0, < 5.0) | ||
thor (>= 0.14, < 2.0) | ||
json (1.8.1) | ||
mail (2.5.4) | ||
mime-types (~> 1.16) | ||
treetop (~> 1.4.8) | ||
metaclass (0.0.4) | ||
mime-types (1.25.1) | ||
minitest (4.7.5) | ||
mocha (1.1.0) | ||
metaclass (~> 0.0.1) | ||
multi_json (1.10.1) | ||
polyglot (0.3.5) | ||
rack (1.5.2) | ||
rack-test (0.6.2) | ||
rack (>= 1.0) | ||
rails (4.0.2) | ||
actionmailer (= 4.0.2) | ||
actionpack (= 4.0.2) | ||
activerecord (= 4.0.2) | ||
activesupport (= 4.0.2) | ||
bundler (>= 1.3.0, < 2.0) | ||
railties (= 4.0.2) | ||
sprockets-rails (~> 2.0.0) | ||
railties (4.0.2) | ||
actionpack (= 4.0.2) | ||
activesupport (= 4.0.2) | ||
rake (>= 0.8.7) | ||
thor (>= 0.18.1, < 2.0) | ||
rake (10.3.2) | ||
rdoc (4.1.1) | ||
json (~> 1.4) | ||
sass (3.2.19) | ||
sass-rails (4.0.3) | ||
railties (>= 4.0.0, < 5.0) | ||
sass (~> 3.2.0) | ||
sprockets (~> 2.8, <= 2.11.0) | ||
sprockets-rails (~> 2.0) | ||
sdoc (0.4.0) | ||
json (~> 1.8) | ||
rdoc (~> 4.0, < 5.0) | ||
sprockets (2.11.0) | ||
hike (~> 1.2) | ||
multi_json (~> 1.0) | ||
rack (~> 1.0) | ||
tilt (~> 1.1, != 1.3.0) | ||
sprockets-rails (2.0.1) | ||
actionpack (>= 3.0) | ||
activesupport (>= 3.0) | ||
sprockets (~> 2.8) | ||
sqlite3 (1.3.9) | ||
thor (0.19.1) | ||
thread_safe (0.3.4) | ||
tilt (1.4.1) | ||
treetop (1.4.15) | ||
polyglot | ||
polyglot (>= 0.3.1) | ||
turbolinks (2.2.2) | ||
coffee-rails | ||
tzinfo (0.3.40) | ||
uglifier (2.5.3) | ||
execjs (>= 0.3.0) | ||
json (>= 1.8.0) | ||
|
||
PLATFORMS | ||
ruby | ||
|
||
DEPENDENCIES | ||
coffee-rails (~> 4.0.0) | ||
jbuilder (~> 1.2) | ||
jquery-rails | ||
mocha | ||
rails (= 4.0.2) | ||
sass-rails (~> 4.0.0) | ||
sdoc | ||
sqlite3 | ||
turbolinks | ||
uglifier (>= 1.3.0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
Based on Andrzej Krzywda's [post](http://andrzejonsoftware.blogspot.com/2007/05/15-tdd-steps-to-create-rails.html), *"15 TDD steps to create a Rails Application"* which is recommended in the Rails Guide *[A guide to testing rails application](http://guides.rubyonrails.org/testing.html)*. The original post was published in May, 2007 and some codes have since deprecated. I have attempted to update the tutorial here in the hope that it may benefit many people like me. | ||
|
||
This tutorial takes the TDD approach in building a simple word-learning web application, it displays a random word object (with its Polish translation) from the database. Everytime we refresh, we see a different word. Again, for the original post please click [here](http://andrzejonsoftware.blogspot.com/2007/05/15-tdd-steps-to-create-rails.html). | ||
|
||
Let's begin | ||
---------- | ||
### 1. Create a new Rails application | ||
|
||
$ rails new my_app | ||
|
||
$ cd my_app | ||
|
||
Run tests with 'rake test'. It fails due to missing database configuration. | ||
|
||
### 2. Prepare your database | ||
$ rake db:migrate | ||
|
||
$ rake test *~> should now run fine* | ||
|
||
### 3. Create a Word class with corresponding unit test | ||
$ rails g model Word | ||
|
||
### 4. Write a unit test for the Word class. | ||
Edit the test/models/word_test.rb | ||
|
||
``` | ||
test 'word is in both English and Polish' do | ||
word = Word.new eng:'never', pl:'nigdy' | ||
assert_equal 'never', word.eng | ||
assert_equal 'nigdy', word.pl | ||
end | ||
``` | ||
$ rake test *~> should now fail due to missing columns in words table* | ||
|
||
### 5. Add columns to your table | ||
|
||
$ rails g migration add_eng_and_pl_to_words | ||
|
||
From your db/migrate folder open the new migration file you just created and add the following columns like so: | ||
|
||
``` | ||
class AddEngAndPlToWords < ActiveRecord::Migration | ||
def change | ||
add_column :words, :eng, :string | ||
add_column :words, :pl, :string | ||
end | ||
end | ||
``` | ||
$ rake db:migrate *~> to prepare the schema so we can add create some words* | ||
|
||
From your rails console ($ rails console) | ||
|
||
$ Word.create(eng:'yes', pl:'tak') | ||
|
||
$ Word.create(eng:'no', pl:'nie') | ||
|
||
$ Word.create(eng:'everything', pl:'wszystko') | ||
|
||
This will create the three words with its Polish translation. | ||
|
||
$ rake test *~> should now succeed with the following:* | ||
|
||
*'1 tests, 2 assertions, 0 failures, 0 errors'* | ||
|
||
### 6. Fixtures and test for word.random. | ||
|
||
Edit word_test.rb again. The test/models/word_test.rb file should now look like this: | ||
|
||
``` | ||
require 'test_helper' | ||
class WordTest < ActiveSupport::TestCase | ||
fixtures :words | ||
test 'word is in both English and Polish' do | ||
word = Word.new eng:'never', pl:'nigdy' | ||
assert_equal 'never', word.eng | ||
assert_equal 'nigdy', word.pl | ||
end | ||
test 'show random words' do | ||
results = [] | ||
10.times {results << Word.random.eng} | ||
assert results.include?("yes") | ||
end | ||
end | ||
``` | ||
|
||
Edit the words.yml file (in the fixtures folder) to look like this: | ||
|
||
``` | ||
--- | ||
false: | ||
eng: "no" | ||
id: 2 | ||
pl: nie | ||
true: | ||
eng: "yes" | ||
id: 1 | ||
pl: tak | ||
``` | ||
|
||
Be careful with the spacing. YML files are like crazy annoying people, they'll yell at you if you miss a space. Head over to <http://yamllint.com/> and validate your yaml if unsure or learn more here: <http://ess.khhq.net/wiki/YAML_Tutorial> | ||
|
||
In the word_test.rb file, notice the "fixtures :words", the words.yml file will now be loaded to the test database before every run of tests. | ||
|
||
### 7. Implement the Word.random method | ||
In your app/models/word.rb implement the word.random method like so: | ||
|
||
``` | ||
class Word < ActiveRecord::Base | ||
def self.random | ||
all = Word.all | ||
all[rand(all.size)] | ||
end | ||
end | ||
``` | ||
|
||
### 8. Generate the Words controller with a 'learn' action | ||
$ rails g controller Words learn | ||
|
||
### 9. Write a test for the learn method. | ||
Just as there is one-to-one ratio between unit tests and models, so there is between functional tests and controllers. The Controller's responsibility is to retrieve objects from the Model layer and pass them to the View. Let's test the View part first. We use the 'assigns' collection which contains all the objects passed to the View. | ||
|
||
In the test/controllers/words_controller_test.rb | ||
|
||
``` | ||
require 'test_helper' | ||
class WordsControllerTest < ActionController::TestCase | ||
test "learn method passes a random word" do | ||
get 'learn' | ||
assert_kind_of Word, assigns('word') | ||
end | ||
end | ||
``` | ||
$ rake test | ||
|
||
### 10. Make the Test Pass | ||
|
||
In your app/controllers/words_controller.rb | ||
|
||
``` | ||
class WordsController < ApplicationController | ||
def learn | ||
@word = Word.new | ||
end | ||
end | ||
``` | ||
|
||
### 11. Write more tests in the words_controller_test | ||
How can we test that the controller uses the Word.random method? We don't want to duplicate the tests for the Word.random method. Mocks to the rescue! We will only test that the controller calls the Word.random method. The returned value will be faked with a prepared word. Let's install the mocha framework. | ||
|
||
In your Gemfile | ||
|
||
``` | ||
group :test, :development do | ||
gem 'mocha' | ||
end | ||
``` | ||
At bottom of test_helper.rb (or at least after `require 'rails/test_help') add: | ||
|
||
`require 'mocha/mini_test'` | ||
|
||
We can now use 'expects' and 'returns' methods. 'expects' is used for setting an expectation on an object or a class. In this case we expect that the 'random' method will be called. We also set a return value by using 'returns' method. Setting a return value means faking (stubbing) the real method. The real Word.random won't be called. If an expectation isn't met; the test fails. | ||
|
||
``` | ||
require 'test_helper' | ||
class WordsControllerTest < ActionController::TestCase | ||
test "learn method passes a random word" do | ||
random_word = Word.new | ||
Word.expects(:random).returns(random_word) | ||
get 'learn' | ||
assert_equal random_word, assigns('word') | ||
end | ||
end | ||
``` | ||
$ rake test *~> should now fail* | ||
|
||
### 12. Rewrite the implementation | ||
Edit words_controller.rb | ||
|
||
``` | ||
def learn | ||
@word = Word.random | ||
end | ||
``` | ||
|
||
### 13. Test that a word is displayed: Extend the existing test with assert_tag calls. | ||
Edit words_controller_test.rb | ||
|
||
``` | ||
test "learn method passes a random word" do | ||
random_word = Word.new(pl:'czesc', eng:'hello') | ||
Word.expects(:random).returns(random_word) | ||
get 'learn' | ||
assert_equal random_word, assigns('word') | ||
assert_tag tag:'div', child: /czesc/ | ||
assert_tag tag:'div', child: /hello/ | ||
end | ||
``` | ||
|
||
### 14. Implement the view | ||
In app/views/words/learn.html.erb | ||
|
||
```<div> | ||
<%= @word.eng %> | ||
<%= @word.pl %> | ||
</div> | ||
``` | ||
### 15. Manual testing | ||
$ rails server | ||
|
||
Go to http://localhost:3000/words/learn | ||
Refresh several times to see different words. | ||
|
||
Related articles: | ||
[Some more TDD steps with Rails Testing](http://andrzejonsoftware.blogspot.com/2007/05/and-some-more-tdd-steps-with-rails.html), [Rails controllers with mock objects](http://andrzejonsoftware.blogspot.com/2007/06/testing-rails-controllers-with-mock.html) If you want to read more about testing in Rails go to the [Guide To Testing The Rails.](http://manuals.rubyonrails.com/read/book/5) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Add your own tasks in files placed in lib/tasks ending in .rake, | ||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. | ||
|
||
require File.expand_path('../config/application', __FILE__) | ||
|
||
MyApp::Application.load_tasks |
Empty file.
Oops, something went wrong.