1. Feel-Physics

    No comment

    Feel-Physics
Changes in body
Source | HTML | Preview
@@ -1,272 +1,272 @@
| Component | version |
|:----------------|-------------:|
| RubyMine | 5.0(Windows) |
| Rails | 3.2.12 |
| Rspec | 2.13.0 |
| FactoryGirl | 4.2.0 |
| Faker | 1.1.2 |
| DatabaseCleaner | 0.9.1 |
## Setup
1. コードを書く
```ruby:Gemfile
group :development, :test do
gem "rspec-rails"
gem "factory_girl_rails"
end
group :test do
gem "faker"
gem "capybara"
gem "database_cleaner"
end
```
1. bundle install
1. Tools > Run Rails Script > "rails", "generate rspec:install"
1. Tools > Run Rails Generator > model > Contact firstname:string lastname:string email:string phone:references
1. Tools > Run Rails Generator > model > Phone contact:references phone_type:string phone:string
8. Tools > Run Rake Task > db:migrate
## 1st red
1. テストを書く
```ruby:spec/models/contact_spec.rb
require 'spec_helper'
describe Contact do
it "is valid with a firstname and lastname"
it "is invalid without a firstname"
it "is invalid without a lastname"
it "is invalid with a duplicate email address"
end
```
1. Run > Run > spec
pending
1. Toggle auto-test
1. テストを書く
```ruby:spec/models/contact_spec.rb
require 'spec_helper'
describe Contact do
it "is valid with a firstname and lastname" do
contact = Contact.new(
firstname: 'Tatsuro',
lastname: 'Ueda',
email: 'weed_7777@yahoo.co.jp'
)
expect(contact).to be_valid
end
it "is invalid without a firstname" do
expect(Contact.new(firstname: nil).to have(1).errors_on(:firstname))
end
it "is invalid without a lastname" do
expect(Contact.new(lastname: nil).to have(1).errors_on(:lastname))
end
it "is invalid with a duplicate email address" do
Contact.create(
firstname: 'Tatsuro', lastname: 'Ueda', email: 'weed_7777@yahoo.co.jp'
)
contact = Contact.new(
firstname: 'hoge', lastname: 'fuga', email: 'weed_7777@yahoo.co.jp'
)
expect(contact).to have(1).errors_on(:email)
end
end
```
1. 保存すると自動でテストが走り、こける
1. コードを書く
```ruby:app/models/contact.rb
validates :firstname, presence: true
validates :lastname, presence: true
validates :email, presence: true, uniqueness: true
```
1. 保存すると自動でテストが走り、合格する
## 2nd red
1. テストを書く
```ruby:spec/models/phone_spec.rb
describe Phone do
it "does not allow duplicate phone numbers per contact"
it "allows two contacts to share a phone number"
end
```
1. 保存すると自動でテストが走り、pendingになる
1. テストを書く
```ruby:spec/models/phone_spec.rb
describe Phone do
it "does not allow duplicate phone numbers per contact" do
contact = Contact.create(
firstname: 'Tatsuro', lastname: 'Ueda', email: 'weed_7777@yahoo.co.jp'
)
home_phone = contact.phones.create(
phone_type: 'home',
phone: '01-2345-6789'
)
mobile_phone = contact.phones.create(
phone_type: 'mobile',
phone: '01-2345-6789'
)
expect(mobile_phone).to_not be_valid
end
it "allows two contacts to share a phone number" do
contact = Contact.create(
firstname: 'Tatsuro', lastname: 'Ueda', email: 'weed_7777@yahoo.co.jp'
)
contact.phones.create(
phone_type: 'home',
phone: '01-2345-6789'
)
other_contact = Contact.new
other_phone = other_contact.phones.build(
phone_type: 'home',
phone: '01-2345-6789'
)
expect(other_phone).to be_valid
end
end
```
1. 保存すると自動でテストが走り、こける
1. コードを書く
```ruby:app/models/contact.rb
# belongs_to :phone
has_many :phones
```
```ruby:app/models/phone.rb
attr_accessible :phone, :phone_type
validates :phone, uniqueness: { scope: :contact_id }
```
1. 保存すると自動でテストが走り、合格する
## 3rd red
1. テストを書く
```ruby:spec/models/contact_spec.rb
describe "#name" do
it "returns a contact's full name as a string" do
contact = Contact.new(
firstname: "Tatsuro", lastname: "Ueda", email: "weed_7777@yahoo.co.jp"
)
expect(contact.name).to eq 'Tatsuro Ueda'
end
end
```
1. Run > Run > spec
テストが走り、失敗する
1. Toggle auto-test
1. コードを書く
```ruby:app/models/contact.rb
def name
[firstname, lastname].join " "
end
```
1. 自動的にテストが走り、合格する
-## 2nd red
+## 4th red
1. テストを書く
```ruby:spec/models/contact_spec.rb
describe "#by_letter" do
it "returns a sorted array of results that match" do
smith = Contact.create(
firstname: 'John', lastname: 'Smith', email: 'jsmith@example.com'
)
jones = Contact.create(
firstname: 'Tim', lastname: 'Jones', email: 'tjones@example.com'
)
johnson = Contact.create(
firstname: 'John', lastname: 'Johnson', email: 'jjohnson@example.com'
)
expect(Contact.by_letter("J")).to eq [johnson, jones]
end
end
```
1. 自動的にテストが走り、失敗する
1. コードを書く
```ruby:app/models/contact.rb
def self.by_letter(letter)
where("lastname LIKE ?", "#{letter}%").order(:lastname)
end
```
1. 自動的にテストが走り、合格する
## リファクタリング
`before`と`context`を使ってテストコードを整理する。
```ruby:spec/models/contact_spec.rb
describe "filter last name by letter" do
before :each do
@smith = Contact.create(
firstname: 'John', lastname: 'Smith', email: 'jsmith@example.com'
)
@jones = Contact.create(
firstname: 'Tim', lastname: 'Jones', email: 'tjones@example.com'
)
@johnson = Contact.create(
firstname: 'John', lastname: 'Johnson', email: 'jjohnson@example.com'
)
end
context "matching letters" do
it "returns a sorted array of results that match" do
expect(Contact.by_letter("J")).to eq [@johnson, @jones]
end
end
context "non-matching letters" do
it "returns a sorted array of results that match" do
expect(Contact.by_letter("J")).to_not include smith
end
end
end
```
おしまい。
-----
ブログやってます:[PAPA-tronix !](http://weed.cocolog-nifty.com/wzero3es/)