As Sloth As Possible

��ǽ�ʸ¤�ʥޥ���ΤǤ��ꤿ��

������RSpec

sinatra��ActiveRecord��ERB��BBS��ä��Τǥ�������������Ƥߤ� - ��������˿�ȯ����Ʋ���BBS���äƤߤ褦�ȡ���������Sinatra�򤤤��äƤ�����Sinatra����ϺǶ�С�����󥢥åפ��Ƥ��������뤱�ɡ��ɤ���������Ruby1.9.1�Ǥ�ư���褦������Ũ��

�ǡ���Ĵ�˹Ԥ����Ȼפä�������ɡ��ɤ��ˤ�񤭹��ߤ�spec���̤�ʤ��������ǽ��ơ�POST��GET�ǥѥ�᡼���˥ޥ���Х��Ȥ�ʸ�������äƤ�Ȳ��������������Ȥ˵��դ�����

�ǽ�˽񤤤�spec�ȥ��ץ�¦�Υ����ɤ�ȴ�衣

# coding: utf-8
require 'rubygems'
require 'rack/test'
require 'routes.rb' #sinatra���ץ�

set :environment, :test

include Rack::Test::Methods

def app 
  Sinatra::Application
end

describe '��Ƥ���Ȥ�' do
  it '����Ƥ���������������˥�����쥯�Ȥ��뤳��' do
    @props = { 
      'user'  => '����',
      'body'  => '�١��̤˥��󥿤���ʸ�����ۤʤ󤸤�ʤ�������顪',
    }
    Entry.should_receive(:create).with(@props)
    post '/add', @props
    last_response.status.should be_equal(302)
  end 
end
# coding: utf-8
require 'rubygems'
require 'sinatra'
require 'haml'
require 'sequel'

post '/add' do
  Entry.create(params)
  redirect '/'
end

DB = Sequel.connect('sqlite://db/trabbs.db')
class Entry < Sequel::Model; end

�ºݤˤ�get '/'�Ȥ�Entry�Υ������ޤȤ�index.haml�Ȥ����Ѱդ��Ƥ���ޤ�������Ͽ����ܤ��䴰���Ƥ����졣��ǡ����Ԥ��Ƥ�ΤϤ�����������ĥ�ǥ����Ƥ򤷤Ƥ��줬DB�˵�Ͽ���졢���θ�ȥåפ˥�����쥯�Ȥ���뤳�Ȥʤ�����ɡ����줬�����롣

1)
Spec::Mocks::MockExpectationError in '��Ƥ���Ȥ� �ϡ���Ƥ���������������˥�����쥯�Ȥ��뤳��'
 expected :create with ({"user"=>"����", "body"=>"�١��̤˥��󥿤���ʸ�����ۤʤ󤸤�ʤ�������顪"}) but received it with ({"user"=>"\xE3\x82", "body"=>"\xE3\x81\xB9\xE3\x80\x81\xE5\x88\xA5\xE3\x81\xAB\xE3\x82\xA2\xE3\x83\xB3\xE3\x82\xBF\xE3\x81\xAE"})

����㡣UTF-8��ʸ���󤬤���٤��Ȥ����ˡ�ASCII-8BIT���Ĥޤ�Х����󤬤��Τޤ������äƤ롣��ࡢ�����ȡ��ºݤΥХ�������ѹ������˥��󥳡��ǥ��󥰤����Ѥ���Τ�force_encoding���ä���͡��Ȥ������Ȥ�force_encoding('UTF-8')���Ƥߤ롣

1)
Spec::Mocks::MockExpectationError in '��Ƥ���Ȥ� �ϡ���Ƥ���������������˥�����쥯�Ȥ��뤳��'
 expected :create with ({"user"=>"����", "body"=>"�١��̤˥��󥿤���ʸ�����ۤʤ󤸤�ʤ�������顪"}) but received it with ({"user"=>"\xE3\x82", "body"=>"�١��̤˥��󥿤�"})

�������졩�ʤ�­��ʤ��ʤ�������Ϥɤ��������ȡ�

Rack::Utils#escape

�Ȥ����ǡ���Ǥ�ü�ޤä����ɡ��¤�spec��¹Ԥ���ݤˤ����warning���ФƤ��롣

/usr/local/lib/ruby/gems/1.9.1/gems/rack-1.0.0/lib/rack/utils.rb:13: warning: regexp match /.../n against to UTF-8 string

UTF-8���Ф��ƥ��󥳡��ǥ��󥰤�̵�뤷������ɽ���˥ޥå������Ƥ�Ĥ��󡢤ɤ��⤳�줬�����������Ƥ���Ϥɤ�����ФƤ뤫�Ȥ����ȡ�����ʥ����ɤ���ФƤ��롣

# rack-1.0.0/lib/rack/utils.rb
module Rack
  # Rack::Utils contains a grab-bag of useful methods for writing web

  module Utils
    # Performs URI escaping so that you can construct proper
    # query strings faster.  Use this rather than the cgi.rb
    # version since it's faster.  (Stolen from Camping).
    def escape(s)
      s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
        '%'+$1.unpack('H2'*$1.size).join('%').upcase
      }.tr(' ', '+')
    end
    module_function :escape

    # Unescapes a URI escaped string. (Stolen from Camping).
    def unescape(s)
      s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){
        [$1.delete('%')].pack('H*')
      }
    end
    module_function :unescape

    # �ʲ���ά
  end
end

�ʤ�ۤɤǤ��͡����פ���ˡ�

  1. escape���unpack����Ȥ��ˡ�String#size��ȤäƤ��롣1.8�ޤǤϤ��Υ᥽�åɤϥХ��ȿ����֤��Ƥ����ɡ�1.9�Ǥ�ʸ�������֤��褦�˻��ͤ��ѹ�����Ƥ������ޥ���Х��Ȥ�ʸ������������Х��ȿ���ʸ�����ϰ��פ��ʤ��Τǡ�������ڤ���㤦���Ȥˤʤ롣
  2. pack�����֤äƤ���Τ�ñ�ʤ�Х����󡢤Ĥޤ�ASCII-8BIT��String��
  3. 1.8�ޤǤ�ʸ���󤬤ɤ�ʥ��󥳡��ǥ��󥰤Ǥ��졢unpack����pack����Фޤ�ʸ�����������Ǥ�1.9�Ǥ�unpack����pack�β����Ǹ��Υ��󥳡��ǥ��󥰾���ϼ��ʤ��Ƥ���Τǡ�����Ū�˥��󥳡��ǥ��󥰾�����ղä��Ƥ��ɬ�פ�������

�Ȥ������Ȥ����顣�ޤ�1�˴ؤ��Ƥ�String#size��ȤäƤ�Ȥ�����String#bytesize��Ȥ��褦�˽񤭴�����Ф��������ʤߤ�Rack::Utils�Ǥ�1.8�Ǥ�1.9�Ǥ�ư���褦��Rack::Utils#bytesize�Ȥ����᥽�åɤ��������Ƥ���Τǡ������Ȥ��Ȥ������Ȥ��������ʤ�ǻȤäƤʤ����������ñ��˺��Ƥ��������ʤ��ġ�

module Rack
  module Utils                                                                          
    def escape(s)
      s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/) {                                              
        '%'+$1.unpack('H2'*bytesize($1)).join('%').upcase                               
      }.tr(' ', '+')
    end
  end
end

�����rack��require������˽񤤤�Rack::Utils#escape���񤭤��Ƥ��ȡ�������escape�����褦�ˤʤ롣

����ASCII-8BIT�ˤʤä���äƤ�Τ�force_encoding���ƥ��󥳡��ǥ��󥰤��Ѥ��롣�����������Rack::Utils#unescape���񤭤��ơ�������ǥ��󥳡��ǥ��󥰤��¬����force_encoding���Ƥ����ơ����ץ�¦�Υեå���String#encoding��Ȥä������ǻȤ����󥳡��ǥ��󥰤��Ѵ����Ƥ��Τ��������ʤ��Ȥ��פä�������ɡ�����Ǥ����Τ��ʡ���

��Ǥ�ޤ��������UA�˱�����view�Υ��󥳡��ǥ����Ѥ���ߤ����ʤ��ȤϤ��Ƥʤ�����UTF-8����Ǥ����ɤ���͡��ĤȤ����櫓�ǡ�Sinatra��before����ǡ�RUBY_VERSION��1.9�ʾ���ä��Ȥ���param��ʸ�����force_encoding('UTF-8')����褦�ˤ����ä����ɤ��ҤϤ����Ȥ��Ʋ�������

�Ϥ�������Ǥ�����spec�̤�ޤ������ա���

�Ĥǡ�

�������顢���٤�Rack��fork����ľ����pull request����Ф��������͡�����������ɡ����ʤ���ʡ��Ȥϻפ�������ɡ����ɤ������դΤ���޼����ʤ��Τǡ�ï��1.9�Ǥ������ư���褦��ľ����Rack�γ�ȯ�����åդ˶����Ƥ����Ƥ�館��Ƚ�����ޤ��������ƥ������͡�

��ʬ���֤��Ƥޤ������ɻפ��Ф������Τ褦��³��������º�˺��Ƥ��Τ����ɤ⡣

�Ȥꤢ���������񤤤���Τ�����

spce���ޥ�ɤΥ�åѤ��

����ϼ�ʬ�Υ꥽�������*_spec.rb���ɤ߹���Ǽ�ʬ��main�Х�ɥ�Υ��饹��ƥ��Ȥ��롢�Ȥ���RubyCocoa���ץ���ä��Τ����ɡ�spec�����餻�뤿���������󤽤�ʤ�Τ���Τ����ݤ��������롣�ºݤ�äƤ뤳�Ȥ�Spec::Runner::CommandLine��spec�ե�������Ϥ��Ƥ�����ʤΤǡ��������֥�Х�ɥ��������˼�ä�spec�����餻�롢�Ȥ���spec���ޥ�ɤΥ�åѤ��Ѱդ��롣

#!/usr/bin/env ruby

require 'rubygems'
require 'spec'
require 'osx/cocoa'

spec_opts   = ARGV.reject {|opt| opt =~ /\.bundle\z/}
bundle_path = ARGV.find {|opt| opt =~ /\.bundle\z/}

if bundle_path && bundle = OSX::NSBundle.bundleWithPath(File.expand_path(bundle_path))
  bundle.load
  bundle
  Dir.foreach(bundle.resourcePath) {|file| spec_opts.push(File.join(bundle.resourcePath, file)) if file =~ /.+_spec.rb\z/}
end

::Spec::Runner::CommandLine.run(spec_opts, STDERR, STDOUT, true, true)

���Ƥ��̤ꡢ�Х�ɥ������ɤ���*_spec.rb��ȴ���Ф��������Υѥ��򥳥ޥ�ɥ饤��������դ��ä���Spec�Υ��ʡ����Ϥ��������Х�ɥ�Ϻǽ�ΰ�İʳ�������̵�뤹������ˤʤäƤ뤱�ɡ��������ꤷ�Ƥ������ˡ�ǰ����Х�ɥ�ϰ�Ĥ����ʤΤǤȤꤢ��������ǽ�ʬ��ɬ�פǤ�������������Ĥ��Ƥ⤤�����ɡ�

��ĥ�Ҥ�.bundle�Υե�����ʳ��ΰ���������spec�Υ��ʡ����Ϥ�Τǡ�Ŭ����̾���դ��ƥѥ����̤ä��Ȥ������֤��Ƥ�����spec���ޥ�ɤ�����˻Ȥ��롣-f�Ȥ�-c�Ȥ�-s�Ȥ�������ʤ��Ȥ����ꤹ�롣

������ˡ

�ǡ������Ĥ�ºݤˤɤ��Ȥ����Ȥ����ȡ��㤨��Xcode��ȤäƤ���ʤ餳��ʴ�����

  1. �����������å��ɲä�Cocoa Loadable Bundle�Υ������åȤ��ɲ�
  2. ���Υ������åȤ˼��Υ�����ץȤ�¹Ԥ���ӥ�ɥե��������ɲá�ruby <��Υ�����ץȤΥѥ�> [<spec���ץ����>] $BUILD_DIR/$CONFIGURATION/$EXECUTABLE_NAME.bundle
  3. ���Υ������åȤ�Objective-C�Υ��饹��spec�ե�����������(���κ�spec�ե������ɬ�������ˡ�_spec.rb�פ��դ���ɬ�פ�����)

����ǡ����Υ������åȤ�ӥ�ɤ���ȼ�ưŪ��spec��¹Ԥ��Ƥ����褦�ˤʤ�Ȥ����������䡢�����Ȥʤ�ޤ������ʤ�ޤ����衣���ڥå��������̤�Ȳ�����ʤ��ӥ�ɴ�λ���뤱�ɡ����ڥå����̤�ʤ��ȥӥ�ɤ����Ԥ��ӥ�ɷ�̲��̤�spec���ޥ�ɤη�̤��Ф롣�㤨�Хӥ�ɥ������åȤΰ�¸�ط��ǥ��ץ꥿�����åȤ�spec�������åȤ˰�¸����褦�ˤ��Ƥ����ȡ�spec�������̤�ʤ��¤ꥢ�ץ꤬�ӥ�ɤǤ��ʤ��ʤ�ΤǤ���������

�����������Ĥ�

�ޤ������Τ��Ȥʤ���RubyCocoa�����󥹥ȡ��뤵��Ƥʤ���ư���ʤ���Leopard���Ⱥǽ餫��/System/Library/Frameworks/RubyCocoa.framework�����������ɡ�����Ϥ�Ȥ�����äƤ�ruby(/usr/bin/ruby)���餷���Ȥ��ʤ������ʤ���/usr/bin/ruby��ȤäƤ�ͤ��̤�����ʤ����ɡ�����ʳ�*1��ȤäƤ��硢����Ruby�Ѥ˺���RubyCocoa������뤫��/usr/bin/ruby������RSpec������뤫���Ƥ���ɬ�פ����롣

���ȡ�RSpec�κǿ��Ǥ���spec�μ¹Է�̤�success��failed��¾��pending�ˤ��뤳�Ȥ��Ǥ��뤱�ɡ�pending��success��Ʊ�������ˤʤäƥӥ���������Ƥ��ޤ����Τǡ������դ򡣤ޤ����¹Է�̤ϥӥ�ɥ������Ǥ�������Ƥ�ΤǤ���򸫤뤳�ȤϤǤ��뤱�ɤ⡣

����¾

�Ȥꤢ�������ɽ����ɤ��ˤ���������Growl�������ꤲ���ꤷ�������򤤤��ʤ���

*1��/usr/local/bin/ruby�Ȥ�/opt/local/bin/ruby�Ȥ�

���Ż���Rails���ץꥱ���������Ȥ�Ȥ��ˡ�test/unit����ʤ���RSpec��ȤäƤ롣mock����λȤ����꤬�����Ȥ������ä������ߤ䤹���Ȥ���������̥�Ϥ����������ɡ����Ρֲ������פ��ݤĤˤϤʤ��ʤ����Ĥ�����Ȼפ���

�����ޤǤ�ʤ�RSpec��Ruby�Υ����ɤ�ֱѸ��ɽ���Ȥ��Ƽ����˸�����פ褦�ˤ��뤳�Ȥ�տޤ��Ƹ��ä��������Ƥ��롣����ϱѸ���Υ��󥸥˥��ˤ�������Ũ�ʤ��ȤǤϤ��������ɡ��Ѹ줬���DZѺ�ʸ�ʤ�ƻϤ�ƿ�ʬ�ǵ㤭�����ʤ�褦�ʤؤ��쳰���������ˤȤäƤ���ľ��ä�������������ο�ã����Ⱦ�ϱѸ�˴���Ƥ��ʤ���ã*1���ä��ꤹ��Τǡ����ä������������⤤����ɽ���Ǥ����ष���տޤ����򤹤�˸���ˤʤä��ꤹ�롣���ä��ɥ��ĸ�ǽ񤤤ơ֤��ٶ��פ˳��Ѥ��Ƥ�������Ȥ�����ư�˶��줿���ɤ⡢ï��ͤȤ����ɤ�ʤ���˰콵�ָ�β��Ǥ�������˶줷�ߤ����ʤΤǤ����˽�������ۤ�������ˤ��Ƥ�����

�Ȥ������Ȥǡ���äѤ�Spec��饳���Ȥ��Ȥ��ä���Τϡ��ȤäĤ��䤹�����뤿��ˤ�Ǥ���������ܸ�ǽ񤭤����Ȥ������Ȥ��������Ѹ�θ�������ˤ��Ƥ���ΤǤ���äȹ��פ��ʤ��ȥ����ɤȤ��Ƹ����Ȥ���spec���ޥ�ɤν��Ϥ��ɤä������Լ����ˤʤ�����ʤ���

Lesson1��I study english��

�ޤ���RSpec�ε��ҤϤɤ������դ��˽񤯤��Ȥ����ȡ�

describe ClassName, 'context' do
end

�Ȥʤ롣�ǡ����ξ�ﲼ�ˤ���Ȥ��ε�ư�ˤĤ��ơ�

it 'should ...' do
end

����󤷤Ƥ������㤨�С��Ƕ�����̤�̾����ʹ�����Ȥ�¿�����������λ��ͤ�񤯤ʤ顢

describe Teacher, 'when introduce himself' do

  it 'should tell own name' do
    momoiro = Teacher.new('�忧��˾')
    momoiro.name.should be_eql('�忧˾') #������Ĺ��̾����Ĥʤ��ƽ񤤤������Ǥ��衣
  end

end

����ʴ�����describe����it���⤵�뤳�Ȥʤ��顢���ͳ�ǧ�ν����ε��Ҥ�'momoiro('s) name should be equal "�忧˾".'�Ȥ������ɤ�Ƥ����������ǡ������¹Ԥ���ȡ�

'Teacher when introduce himself should tell his own name' FAILED
expected "�䡡˾", got "�忧��˾"

�Ȥ������Ϥ򤷤Ƥ���롣����'Teacher when introduce himself should tell his own name'������ʸ�ϤˤʤäƤ���*2��RSpec�ϼ����֤�Ƥʤ�����Ũ�פȸ������ߤ����ʤ봶�������䡢���ط��ʤ����ɡ��ͤȤ��ơ��Ǥ⤳��ϱѸ줬'Something when ...'�ǰ�Ĥμ��ˤʤ뤫������'it'�˷Ҥ���ΤǤ��äơ����ܸ��ñ����֤�������Ȥ���ä��Լ����ˤʤ롣

Lesson2�����ͤʤ󤾲վ�񤭤ǽ�ʬ�ʤ�Ǥ���

�ǽ�Ϥ⤦���ä��Ѹ�Ū����ʬ��̵�뤷�ơ�

  • ���������ʾҲ�ò¤¹¤ë¥±ï¿½ï¿½ï¿½ï¿½
    • ��ʬ��̾�������
    • ���ñ¤­¤Ë¤ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½Ë¾ï¿½ï¿½ï¿½ï¿½
    • ̿̾���ˤϿ����ߤ����ɴ�ߡ���ɬ��

�Ȥ����վ�񤭤Υ��᡼���ǡ�context�ˤϾ���'should ...'����ʬ�ˤ�������񤤤Ƥ��ޤ���

describe Teacher, '���������ʾҲ�򤹤륱����' do
  it '��ʬ��̾�������' do
    ...
  end
  it '����ˤ�������˾����' do
    ...
  end
end

�Ƚ񤤤Ƥߤ��Ȥ�����

'Teacher ���������ʾҲ�򤹤륱���� ��ʬ��̾�������' FAILED

�ȤʤäƤ��ޤä����̤��󡣤ʤ󤫡�ʸ�Ϥˤʤ�ʤ��Τ��������������ǽ��Teacher�����äȵ������������ɤ����ʤ顢���Ϥ����ܸ�Ȥ������´�̵���ɤ��ʪ��@IT�ε�������ˤǤ���Ȥ����ʤ��Ȼפ������ʤ���

Lesson3��spec���ޥ�ɤ����ܸ������Ϥ�ޤ�����

���㤢���Ȥ������Ȥǡ����ä��β����ˤʤ�äơ����Ϥ�ʸ�Ϥ��Ҥ���褦�ˤ��Ƥߤ롣

describe Teacher, '���������ʾҲ�򤹤�Ȥ��������Ǥ�' do
  it '�����ϼ�ʬ��̾����������' do
    ...
  end
  it '�����ϲ���ˤ�������˾������' do
    ...
  end
end
'Teacher ���������ʾҲ�򤹤�Ȥ��������Ǥ� �����ϼ�ʬ��̾����������' FAILED

�Ľ��ϤϤ���������ɡ��ο���Spec�ε��ҡ����ܸ줬�⤤����äƤƤʤ�����ʡ�Teacher��it��������̵�뤵��Ƥ�Τ��İ������ޡ��ȤǤʤ���

Lesson4�������Ŷ����ʤ�������

�ǡ���IJ�Τ����ߤˤĤ����褯�ͤ���*3��̡��֤���������Ȥ��פȡ֤ϡ������뤳�ȡפȤ����դ��ˤ�����Լ��������㴳���¤����ʤ��Ȥ����Ȥ����˻�롣

describe Teacher, '�����ʾҲ�򤹤�Ȥ�' do
  it '�ϡ���ʬ��̾�����������' do
    ...
  end
  it '�ϡ�̾���򲣽񤭤ˤ�������˾���뤳��' do
    ...
  end
end
'Teacher �����ʾҲ�򤹤�Ȥ� �ϡ���ʬ��̾�����������' FAILED

��ä�������ʤ�Spec�����Ǥϡ������it�ˤ��������ʤ��ȡפ��ɤ�뤷�����Ϥϡ֡�������Ȥ����������ʤ��ȡפ��ɤ�Ƥɤ���⼫�������äƤм����֤�Ƥʤ�����Ũ���ķ�ɤ��줬����������������

*1����������ͤ�Rails�ν��Ҥξ��󤬼㴳�Ť��ƥϥޤäƤ��Τǡ��֥����ä�Ĵ�٤ơפäƸ��ä��餵��˸Ť��С����������ܸ�API��ե�����ɤ�Ǥơ��ʤ�ǰ켡�������ʤ��Τä��ͤù������ֱѸ������ġפäƸ���줿�Ȥ��ϵ㤱�����������Ϥ狼�뤱�ɡ����ۤ��Ƥ�ġ�

*2���֤ġ�����ʸ�ְ�äƤ뤸��͡������Τ�Ȥ����夬���פäƻפä���㤷����Ŧ���Ƥ����������֤ä�ä����盧�Υ��饺�������󤰤餤�ΤäȤ�襤�����ͥ��˷�ޤäƤ󤸤�����ܥ��������פȴ��դθ��դ�Ҥ٤ʤ���¨�¤˽������ޤ���

*3���ͥ��Ť��ʤ����ʤ�Ǥ���ʤ����ͤ˻פ��Ф����������

���٤�Xcode��ǥ��ץꥱ����������Ȥ��˻Ȥ��뤫��äƤߤ롣

���ץꥱ�������ǻȤ����饹�������ե졼�����Ȥ��ƥӥ�ɤ��ơ�Ruby����OSX#requiew_framework����м����Objective-C���饹��RSpec�ˤ������뤳�Ȥ�����ޤǤǤ狼�ä��Τ����ɡ�ή�Фˤ���ϥ��뤤���ץ������������myclass_spec.rb�äƥե�������֤��Ȥ���Spec�������åȤ�ӥ�ɤ���Ȥ�����ư�Ǹ��ڤ��Ƥ��줿�ꤹ��Τ����ۤʤ櫓�Ǥ���

����ʤ櫓�ǡ������������Ǥ�äƤߤ���

  1. ���̤�Cocoa Application�Υץ��������Ȥ���
  2. �ץ��������Ȥ�RubyCocoa Application����ӥ�ɥ������åȤ��ɲä���
    1. RubyCocoa Application��ư����ȡ�'_spec.rb'�Υե�������ɤ߹����Spec Runner�Ǽ¹Ԥ���褦�ˤ���
  3. xxx_spec.rb���
  4. xxx.m (Objective-C�Υ��饹)���������
  5. RubyCocoa�Υӥ�ɥ������åȤ����ǡ֥ӥ�ɤ��Ƽ¹ԡ�

�ӥ�ɥ������åȤ�ǽ�Shell Tool�Ǻ�����Ȥ���������ɡ�������ȥ꥽�����Ȥ���Ruby������ץȤ�ޤ���ʤ��Τdz��������ɤ߹������Ȥ����������ݤ������������դϤޤ���ǹͤ���Ȥ��ơ��Ȥꤢ����RubyCocoa Application�ˤ���main��ǥ��ץꥱ�������롼�פ򳫻Ϥ��ʤ��ǥ�����ץȤ����¹Ԥ��ƽ�λ����褦�ˤ���������ʤ饯�饹�䥹����ץȤϼ�ư���ɤ߹��ޤ�뤷GUI��ɽ������ʤ���

Spec�������åȤ�����main.m��rb_main.rb�Ϥ���ʴ�����

#import <Cocoa/Cocoa.h>
#import <RubyCocoa/RBRuntime.h>

int main(int argc, const char *argv[])
{
    return RBApplicationMain("rb_main.rb", argc, argv);
}
require 'osx/cocoa'
require 'rubygems'
require 'spec'

def rb_main_init
  path = OSX::NSBundle.mainBundle.resourcePath.fileSystemRepresentation
  specs = []
  rbfiles = Dir.entries(path).select {|x| /?.rb?z/ =? x}
  rbfiles -= [ File.basename(__FILE__) ]
  rbfiles.each do |path|
    if path =? /_spec/
      specs << File.join(File.dirname(__FILE__), File.basename(path))
    else
      require( File.basename(path) )
    end
    ::Spec::Runner::CommandLine.run(specs, STDERR, STDOUT, true, true) unless specs.empty?
  end
end
if $0 == __FILE__ then
  rb_main_init
  #OSX.NSApplicationMain(0, nil)
end

�����Resource���xxx_spec.rb�������ɤ߹����SpecRunner�ˤ����Ƥ���롣��˼������Ƥߤ롣

Namakemono.h

#import <Cocoa/Cocoa.h>

@interface Namakemono : NSObject
{
	NSString * name;
}
- (id)initWithName:(NSString *)aName;
- (NSString *)name;
- (void)setName:(NSString *)aName;
- (NSString *)greetingMessage;
@end

namakemono_spec.rb

include OSX

describe Namakemono do
  before :each do
    @faul = Namakemono.alloc.initWithName(NSString.stringWithString('faultier'))
  end
  
  it 'should be Namakemono' do
    @faul.should be_kind_of(Namakemono)
  end
  
  it 'should have name' do
    @faul.name.to_s.should eql('faultier')
    @faul.greetingMessage.to_s.should match(/Hello, my name is #{@faul.name}/)
  end
end

�֥ӥ�ɤ��Ƽ¹ԡ�

[Session started at 2007-07-23 02:07:18 +0900.]
..

Finished in 0.014898 seconds

2 examples, 0 failures

Spec �ϥ��ơ����� 0 �ǽ�λ���ޤ�����

�Фä������!�������������������Ρ�����˾��Ǥ��Τϡ����Ū�����򤤤��ɤ����ϤȤ⤫��(C#��NUnit�ߤ�����GUI�ġ�����Τ��������ʤ�)��Spec��Ruby�ǽ񤱤�褦�ˤʤä����Ȥ�����Ū�˲������Ƚ��������夬�롣���ȡ��Ŀ�Ū�ʼ�̣�Ȳ�ҤǤ�ȤäƤƴ���Ƥ뤫��RSpec�ˤ������ɡ��̤�Test::Unit��ȤäƤ⤤����ʡ��Ƥ�����Ruby test class�äƥƥ�ץ졼�Ȥ��������ɡ��⤷�����Ƥ⤦����������Ȥ��Ƥ�褦�ʵ�����RubyCocoa���ȹ��ޤ�Ƥ������������Ĥʤ��ʡ����ؤκ�ȯ������ʤ������԰¤ˤʤäƤ�����faul�ä��ϼ����ʡ��Ȼפä���������Ĥä���Dz�������

�ޤ��Ǥ⡢�ޥ���ɥ��åȤȤ��Ƥ�TDD���BDD�������ɤ��Ȼפ������ƥ��ƥ��󥰥ե졼�����Ǥ���Test::Unit�����͵����Ѥ�DSL�äݤ���������Ƥ�RSpec���������������Ϲ⤤�Ȼפ����������鴺���ƻȤ�������ȡ��������Ȥǡ��ȡ��������Ȥǡ�

���Ƥ����ޤ��褿�櫓�����ɤ⡢������٤���٤�ΤϤˤϤޤ��ᤤ�����̵��̣�˥ӥ�ɥ������åȤ�RubyCocoa Application������ư줫���������ΤϤ��ʤ���ʤΤǡ�Spec���ɤ߹���Ǽ¹Ԥ���ġ�������̤˺�äƤ����ơ�RSpec�Υ�����ץȤ�Objective-C�Υ��饹��ޤ���������֥�Х�ɥ��ӥ�ɥ������åȤˤ��ơ������Ĥ�ӥ�ɥե������κǸ�ǥġ�����ɤ߹��ޤ��Ƽ¹Ԥ���褦�ˤ��������Ǥ����unit test bundle�ߤ����˥ƥ�ץ�ˤ��Ƥ��ޤ���Ф���������ɡ�Xcode�Υƥ�ץ�äƼ�ʬ�Ǥ��������͡�¿ʬ���Τ�ʤ����ɡ�

������̲���ʤäƤ����ΤǺ����Ϥ����ޤǡ�

BDD��Cocoa��ȯ�򤹤�Τ�RSpec��ȤäƤߤ���³����

�ʤ�����ճ��ȴ�ñ�˻Ȥ��������ä��ΤǤ���ɤ�Cocoa�ȹ��ߤ���ʤ��ե졼�����ǻ�Ƥߤ褦���Ȥ������Ȥ�OgreKit��������ϻ����˥���ѥ��뤷��/Library/Frameworks�ʲ������ֺѡ��ȡ������Ǥ��⤽��ɤ���äƥե졼������ƤӽФ��Τ��狼��ʤ��ư�װơ��ܲȥ����ȤǤʤ󤫽񤤤Ƥʤ����ʡ���õ���Ƥߤ�⡢�ɤ��˽񤤤Ƥ��������狼���ActiveRecordSupport�Ȥ���̣�������Ȥ��񤤤Ƥ���Τ⸫�Ĥ������ɤȤꤢ������󤷡�

����ץ�Υ������򸫤Ƥ���OSX.require_framework��Ȥ��餷���Ȥ����ΤϤ狼�ä�������ɡ��ɤ߹�����ե졼�����Υ��饹���ɤ��ˤ���Τ��狼�餺���Ф餯Ǻ�����OgreKit::OGRegularExpression�Ȥ���äƤߤƤ���ʤ��̵�����ܤ�줿�ꡣ���Ť˹ͤ���С�Objective-C���ä���Ruby�ߤ����˥⥸�塼�뤬�ͥ��Ȥ��Ƥʤ��Τ�OSX::OGRegularExpression���Ǥ褫�ä�������ɡ�����򸫤Ĥ���ޤ�Google��������乶��ˤ��Ƥ��ޤä������Ƥ���ʤ櫓�ǤǤ����Τ�����ʴ�����

require 'osx/cocoa'
include OSX
require_framework 'OgreKit'

describe OGRegularExpression do
  before :each do
    @match_string   = 'Ich liebe dich, aber du liebst ihn. Ich liebe dich...'
    @unmatch_string = 'Ich mag nicht nur Ruby, sondern Objective-C.'
    @expression     = 'dich'
    @ogregex        = OGRegularExpression.regularExpressionWithString(@expression)
  end
  
  before :all do
    @result         = []
  end
  
  after :all do
    p @result
  end 
  
  it "should replace matches" do
    # Ruby�Υ᥽�åɸƤӽФ��äݤ���������
    replaced = @ogregex.replaceAllMatchesInString_withString(@match_string, 'mich')
    replaced.to_s.should_not include(@expression)
    @result << replaced.to_s 
  end
  
  it 'should replace nothing when no matches in string' do
    # ���ä���Objective-C�Υ�å������ѥå��󥰤äݤ���������
    not_replaced = @ogregex.objc_send(:replaceAllMatchesInString, @unmatch_string, :withString, 'mich')
    not_replaced.to_s.should eql(@unmatch_string)
    @result << not_replaced.to_s
  end
end
$ spec ogrekit_spec.rb
..["Ich liebe mich, aber du liebst ihn. Ich liebe mich...", "Ich mag nicht nur Ruby, sondern Objective-C."]


Finished in 0.018822 seconds

2 examples, 0 failures

�Ǥ����Ǥ������Ѵ�����˻ȤäƤ�ʸ�Ϥ����ʤΤ��ϵ��ˤ��ʤ������ǡ�OgreKit��Spec�ʤΤ�����ɽ���ȤäƤʤ��Τⵤ�ˤ������餱���ʤȻפäƤ롣�ǡ�OgreKit�ϴ���ͭ���ʥ����ɥѥ�����ˤ��ä��Τǥե졼����̾�ǸƤӽФ������ɡ�OSX#require_framework�ϰ����˥ե졼�����Υե�ѥ���Ϳ������Τǡ��ե졼���������Ƥ��ޤ��м�ʬ�Ǻ�ä�Ǥ�դ�Objective-C���饹���ñ�˰����롣�ޤ���Ƥʤ����ɥХ�ɥ������ɤ��뵡ǽ�⤢�롣�פä�������ɡ�gem�Υѥå�������ư���������Ĥߤ�����wiget�Υե����빽���Ȥ��ӥ�ɤ���Rakefile�Ȥ��Υ����ͥ졼�����ä����������⤷��ʤ���wdiget�ʤ饤�󥿡��ե�������Х�ɥ�γ�ȯ��CUI��Ǵ���Ǥ��뤷��RSpec�dz�ǧ���ʤ����륹������ϸ����Ƥ뤫�⡣Dashcode���Ф褦�äƤ������˲�����äƤ������ĤǤ�vim�Τ��ڤʤ�����Xcode�Ǥ�����������ꡣ

���ȡ�����RubyCocoa�򸫤��Ȥ��ˤ�פä�������ɡ�Objective-C�ϥ᥽�å�̾��Ĺ���ʤ���äѤꡣCamelCase��Ruby����ˤ���Ȥɤ����Ƥ���´��������ʤ��������ä���ʤ����ʡ�Objective-C�ǽ񤤤Ƥ�Ȥ���ʤ˵��ˤʤ�ʤ�������ɡ����Ǥ�����

���ơ��ʤ����RubyCocoa�򿨤äƤߤ褦���ʥΥ�ˤʤäƤ������ɡ���Ū��RSpec�Ǥ�RubyCocoa�Ǥ�ʤ��ơ�Cocoa��BDD�ס������ɤ��ˤ�����Cocoa���ץ�γ�ȯ�˼������Ƥߤ����Ȼפ��������������ץ��ե졼���������ƥӥ�ɤ���terminal����spec�¹Ԥ��ơ��Ȥ����Ϥ��᤿������ž�ݡ�Xcode�Ǿ�꤯��ư�¹Ԥ�������ˡ��ͤ��褦���ȡ�

��������Cocoa�dz�ȯ���Ƥ�Ȥ���TDD�����ޤҤȤĤ��ˤ����Τ����ˤʤäƤ���Xcode�ˤ��Ȥ߹��ޤ�Ƥƥǥե����ȤˤʤäƤ�OCUnit�����줬�빽�Ȥ��ˤ�����ñ�˻Ȥ����������򤷤Ƥʤ��������Ȥ������⤹�뤱�ɡ�����򺹤������Ƥ�TDD�Υġ���Ȥ��ƤϤ���ʤ���������Ƥʤ��Ȼפ����¹Է�̤����Ū�����򤯤ʤ���(����ϥ���١�����󲼤�ΤǷ빽����)�����顼�����Τ⤢��ޤ���Ϥ��䤹���ʤ������������Х����������μ��֤�C�Υޥ����ʤΤ�Objective-C��ʸˡ����ʤ��Τⵤ�ˤʤ뤷������ޤ���𤸤�ʤ���¾�ˤ⤤�������ʼ����Ϥ���餷�����ɡ������Ǥ�������ξ��ʤ�Cocoa�Τ����TDD�Τ��������إե졼�����Ȥ�ʤ�ȡ����ܸ���ɤ��ǿ��ξܺ٤ʾ���ʤɳ�̵�������Ǥ̡̤̤̤��Ȥʤ�櫓�Ǥ��衣

�ʤ�����Ȥ�����

�Ȥ������Ȥǡ��ǽ�ϼ�ʬ�Ǻ�뤳�Ȥ��ߤ�����äȤ狼��䤹���Τ������������ä���Objective-C�ߤ�����ưŪ�ʸ���ʤ�������ե쥯�����Ȥ��Ȥäƽ���ˤ�ä��ߤ������������ɤ����ʤ�BDD�äݤ����äǽ񤭤�����ʡ����Ȥ����ۤ��Ĥ�ޤ������᡼���Ȥ��Ƥ�

- (void) before {
  // ������
  faul = [[Namakemono alloc] initWithName:@"faultier"];
}

- (void) after {
  // ����ƨ�����Ƥ��
  [faul release];
}

- (void) whenIntroduce {
  [faul shouldKindOf:Animal];
  [faul shouldKindOf:Namakemono];
  [[faul name] shouldEqual:@"faultier"];
  [[faul capitarizedName] shouldEqual:@"Faultier"];
}

- (void) whenStudy {
  // �轵�ϥƥ��Ȥ�
  id study = [[Task alloc] initWithName:@"English Study"];
  [faul setTask:study key:@"study"];

  [[faul task:@"study"] shuldEqual:study];
  [faul shouldThrow:NullYarukiException message:@selector(reportProgress:) arguments:@"study"];

  // study������������˺���ȥƥ���ľ���˥���꡼�����Ƥ뤳�Ȥ˵��դ���
  [study release];
}

����ʴ��������ȥ�å����ߤ����ʤ���CUI�Ǥ�Xcode�Ȥ߹����Ǥ�Runner�Ϥ��줾�줤���ʤ����Ȥ����äƤ������館�ʤ��ʤäƤ��������ϡ�

���㤢Ruby�ǽ񤱤Ф����󤸤��?

Ruby�ˤ�RSpec�Ȥ�����Ũ����ʪ�����ˤ��롣������ץȤʤ��ĥ���ưפ�����Ruby��ɽ���Ϥʤ鹥������񤱤롣RubyCocoa��Leopard�Ǥ�ɸ�������餷������Ķ��������֤⤤��ʤ����������Ȥ��Х����ä�BDD�Ǥ���󤸤�ʤ�?�Ȼפ�Ω�äƤ�äƤߤ뤳�Ȥˤ�����

�ޤ���Cocoa�Υ��饹��Spec��ɤ�ʤդ��˽񤱤Ф����Τ���Ƥߤ롣

require 'osx/cocoa'
include OSX

describe NSString do
  before :each do
    @expected_string = 'Cocoa BDD with RSpec'
    @str = NSString.stringWithString(@expected_string)
  end

  it 'should be allocated from String' do
    @str.should be_kind_of(NSString)
    @str.to_s.should be_eql(@expected_string)
  end

  it 'should not be editable' do
    @str.to_s.should be_eql(@expected_string)
    lambda { @str << 'append' }.should raise_error(OCException)
  end

  it 'should be editable' do # �虜�ȴְ㤨�Ƥߤ�
   @str << 'append'
   @str.to_s.should be_eql("#{@expected_string}append")
  end
end

�¹Է��

$ spec nsstring_spec.rb
..F

1)
OSX::OCException in 'OSX::NSString should be editable'
NSInvalidArgumentException - Attempt to mutate immutable object with setString:
/Library/Frameworks/RubyCocoa.framework/Versions/A/Resources/ruby/osx/objc/oc_attachments.rb:57:in `setString'
/Library/Frameworks/RubyCocoa.framework/Versions/A/Resources/ruby/osx/objc/oc_attachments.rb:57:in `method_missing'
./nsstring_spec.rb:20:

Finished in 0.013094 seconds

3 examples, 1 failure

���̤����ʤ��ΰ��´���ʤ�������Ϥޤ������Ȥʤ�Ruby������Ũ��Ũ��

���Ȥϼ���Υ��饹�򸡾ڤ����꤫���ȡ�Cocoa���ץ�γ�ȯ��������ˤɤ��ȹ��फ���͡������ȤǤ��ޤ���

�����Υڡ����Υȥåץ�