Archive for the ‘Uncategorized’ Category

Making Technorati Happy

Tuesday, June 2nd, 2009

My Technorati Profile. I’m taking it back.

Listing of cucumber's out-of-the-box webrat steps

Sunday, April 19th, 2009

Commonly used webrat steps found in cucumber

(replace words in [brackets] with the approprate word.)

Given

Given I am on [page_name]

When

When I go to [page_name]
When I press "[button]"
When I follow "[link]"
When I fill in "[field]" with "[value]"
When I select "[value]" from "[field]"
When I select "[time]" as the date and time				#datetime_select
When I select "[datetime]" as the "[datetime_label]" date and time	#specific datetime_select
When I select "[time]" as the time			#time select
When I select "[time]" as the "[time_label]" time	#specific time select
When I select "[date]" as the date			#date_select
When I select "[date]" as the "[date_label]" date	#specific date_select
When I check "[field]"
When I uncheck "[field]"
When I choose "[field]"
When I attach the file at "[path]" to "[field]"

Then

Then I should see "[text]"
Then I should not see "[text]"
Then the "[field]" field should contain "[value]"
Then the "[field]" field should not contain "[value]"
Then the "[label]" checkbox should be checked
Then I should be on [page_name]

Rubyyot.com is dead; Long live Rubyyot.com

Tuesday, March 31st, 2009

I have pulled the plug on Rubyyot.com, the task management site. It was an enjoyable learning experience, but I was no longer using it and I don’t think anyone else was either. I’ve removed it to make way for new development projects. That is if I can ever concentrate enough on any one of my projects to actually complete it.

Chores: a test driven website – Part 8 (this time it's personal)

Saturday, January 31st, 2009

This is part of the Chores series of posts.

I’m now attacking the Idenitity model. My idea for this is a model that contains a single field. That field is a valid, properly formatted, immutable OpenID. Because I’m going to need to validate OpenIDs I’m going to install the Open ID Plugin as follows.

$ ruby script/plugin install git://github.com/rails/open_id_authentication.git
Initialized empty Git repository in c:/rails/chores/vendor/plugins/open_id_authentication/.git/
remote: Counting objects: 35, done.←[K
remote: Compressing objects: 100% (31/31), done.←[K
remote: Total 35 (delta 4), reused 21 (delta 2)[K
Unpacking objects: 100% (35/35), done.
From git://github.com/rails/open_id_authentication
 * branch            HEAD       -> FETCH_HEAD
$ rake open_id_authentication:db:create
(in c:/rails/chores)
      exists  db/migrate
      create  db/migrate/20090125184610_add_open_id_authentication_tables.rb
$ rake db:migrate
(in c:/rails/chores)
==  AddOpenIdAuthenticationTables: migrating ==================================
-- create_table(:open_id_authentication_associations, {:force=>true})
   -> 0.0310s
-- create_table(:open_id_authentication_nonces, {:force=>true})
   -> 0.0160s
==  AddOpenIdAuthenticationTables: migrated (0.0470s) =========================

Here is my test for the Identity model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
require 'test_helper'
 
class IdentityShouldBeValidatedTest < ActiveSupport::TestCase
  specify "that an open ID is required on create" do
    identity = Identity.new
    invalid identity
    identity.open_id = "test.example.com"
    valid identity
  end
 
  specify "message for an overly long identifier" do
    identity = Identity.new :identifier => hundred_and_one_character_identifier
    validation_message_for identity, :identifier, "is too long."
  end
 
  specify "message for a null identifier" do
    identity = Identity.new
    validation_message_for identity, :identifier, "can not be blank."
  end
 
  specify "message for a poorly formatted" do
    identity = Identity.new :identifier => invalid_open_id
    validation_message_for identity, :identifier, "is not a valid Open ID."
  end
 
  specify "message for a duplicate identifier" do
    Identity.make :identifier => valid_identifier
    identity = Identity.new :identifier => valid_identifier
    validation_message_for identity, :identifier, "is already in use, please use another."
  end
 
  specify "that 100 character identifier is valid" do
    identity = Identity.new :identifier => hundred_character_identifier
    valid identity
  end
 
  specify "that identifier is unique" do
    Identity.make :identifier => valid_identifier
    identity = Identity.new :identifier =>  valid_identifier
    invalid identity
  end
 
  specify "that open_id must have the correct format" do
    identity = Identity.new
    identity.open_id = invalid_open_id
    invalid identity
  end
 
  specify "that open_id uniqueness extends to identifier when validated" do
    Identity.make  :identifier => valid_identifier
    identity = Identity.new :open_id => "test.example.com"
    invalid identity
  end
 
  protected
    def hundred_character_identifier
      "http://This.is.a.hundred.character.description.one.hundred.chatacters.is.not.too.long.but.it.of.com/"
    end
 
    def hundred_and_one_character_identifier
      "http://This.is.a.hundred1.character.description.one.hundred.chatacters.is.not.too.long.but.it.of.com/"
    end
 
    def invalid_open_id
      "bad_id"
    end
 
end
 
class IdentityOpenIdShouldSetIdentifierTest < ActiveSupport::TestCase
  specify "that open_id sets identifier" do
    identity = Identity.new
    assert_nil identity.identifier
    identity.open_id = "test.example.com"
    assert_not_nil identity.identifier
  end
 
  specify "that identifier sets open_id" do
    identity = Identity.new
    assert_nil identity.open_id
    identity.identifier = "http://test.example.com/"
    assert_not_nil identity.open_id
  end
 
  specify "that open_id is nicely formatted for display" do
    identity = Identity.new :identifier => "http://test.example.com/"
    assert_equal valid_open_id, identity.open_id
  end
end
 
class IdentityShouldBeImmutableTest < ActiveSupport::TestCase
  specify "that open_id is immutable" do
    identity = Identity.make
    assert_raise RuntimeError do
      identity.open_id = "monkey.example.com"
    end
  end
 
  specify "that identifier is immutable" do
    identity = Identity.make
    assert_raise RuntimeError do
      identity.identifier = "http://monkey.example.com/"
    end
  end
end
 
class IdentityShouldBeFoundByOpenID < ActiveSupport::TestCase
  specify "that open_id can be used to find a record" do
    identity = Identity.make :identifier => valid_identifier
    identity_from_db = Identity.find_by_open_id valid_open_id
    assert_equal identity.identifier, identity.identifier
  end
 
  specify "that display formatted open_id can be used to find a record" do
    identity = Identity.make :identifier => valid_identifier
    identity_from_db = Identity.find_by_open_id valid_identifier
    assert_equal identity.identifier, identity.identifier
  end
end

Here is the code that passes the test
./test/test_helper.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
ENV["RAILS_ENV"] = "test"
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
require File.expand_path(File.dirname(__FILE__) + "/blueprints")
require 'test_help'
require 'faker'
 
class ActiveSupport::TestCase
  self.use_transactional_fixtures = true
  self.use_instantiated_fixtures  = false
 
  def invalid model
    assert !model.valid?
  end
 
  def valid model
    assert model.valid?
  end
 
  def validation_message_for model, column, message
    invalid model
    assert_equal message, model.errors.on(column)
  end
 
  def valid_identifier
    "http://test.example.com/"
  end
 
  def valid_open_id
    "test.example.com"
  end
end
 
def specify *args, &block
  test(*args, &block)
end

./app/models/identity.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class Identity < ActiveRecord::Base
  include OpenIdAuthentication
 
  validates_presence_of :identifier,        :message => "can not be blank."
 
  validates_uniqueness_of :identifier,      :message => "is already in use, please use another."
 
  validates_length_of :identifier,          :maximum => 100,
                                            :allow_nil => true,
                                            :message => "is too long."
 
  validate_on_create :valid_id
 
  def open_id
    return nil if self.identifier.nil?
    self.identifier[7..-2]
  end
 
  def identifier= identifier
    raise "Cannot update identifier." unless new_record?
    set_identifier identifier
  end
 
  def open_id= open_id
    raise "Cannot update open_id." unless new_record?
    set_identifier open_id
  end
 
  def valid_id
    errors.add(:identifier, "is not a valid Open ID.") if @invalid_id
  end
 
  def self.find_by_open_id open_id
    id = OpenIdAuthentication::normalize_identifier(open_id)
    find_by_identifier open_id
  end
 
  protected
  def normalize_id id
    begin
      identifier = normalize_identifier(id)
    rescue OpenIdAuthentication::InvalidOpenId
      identifier = id
      @invalid_id = true
    end
    identifier
  end
 
  def set_identifier id
    write_attribute(:identifier, normalize_id(id))
  end
end

./test/blueprints.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
require 'machinist'  # if you installed machinist from gem
 
Chore.blueprint do
  description "Put the dirty clothes in the hamper"
end
 
Identity.blueprint do
  identifier "http://#{Faker::Name.first_name}.#{Faker::Internet.domain_name}/"
end
 
Child.blueprint do
  child { Identity.make }
  parent { Identity.make }
end

This one took a little work to do and I’m going to revisit it in a little while to see if it needs any refactoring.

The end of a butt sucking era

Friday, January 16th, 2009

I quit smoking yesterday. I had my last cigarette yesterday at aroung 4:00 pm. It’s been over 24 hours now. I’ve managed to keep myself distracted for the most part. I find that makes it easier.