1. Feel-Physics

    No comment

    Feel-Physics
Changes in body
Source | HTML | Preview
@@ -1,174 +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
+
+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/)