Skip to content

Instantly share code, notes, and snippets.

@pochi
Last active December 16, 2015 18:09
Show Gist options
  • Save pochi/5475961 to your computer and use it in GitHub Desktop.
Save pochi/5475961 to your computer and use it in GitHub Desktop.
# coding: utf-8
require 'rspec'
describe Array do
describe '初期化' do
describe '初期値を引数で渡した場合' do
let(:current) { Array.new(2,'hoge') }
context 'Array.new(2, "hoge")' do
it '配列の要素がhogeになっていること' do
expect(current).to eq(['hoge', 'hoge'])
end
end
context '要素を直接書き換えた場合' do
it '全体が書きかわらないこと' do
replace = current.dup
replace[0] = 'moge'
expect(replace).to eq(['moge', 'hoge'])
end
end
context '要素への変更操作をした場合' do
it '全体が書きかわること' do
replace = current.dup
replace[0].replace('moge')
expect(replace).to eq(['moge', 'moge'])
end
end
end
describe '引数をブロックで渡した場合' do
let(:current) { Array.new(2) {|_| 'hoge' } }
context 'Array.new(2) {|_| "hoge" }' do
it '配列の要素がhogeになっていること' do
expect(current).to eq(['hoge', 'hoge'])
end
end
context '要素への変更操作をした場合' do
it '全体が書きかわらないこと' do
replace = current.dup
replace[0].replace('moge')
expect(replace).to eq(['moge', 'hoge'])
end
end
end
describe '他の初期化方法' do
it 'Array [1]で作成できること' do
expect(Array [1]).to eq([1])
end
end
end
describe '代入' do
let(:current) { (0..10).map {|i| i} }
context '複数要素を置き換えした場合' do
it '指定した要素に切り替わること' do
current[3,3] = 5
expect(current).to eq([0,1,2,5,6,7,8,9,10])
end
end
context '配列要素より大きい要素を指定した場合' do
it '指定した要素に切り替わること' do
current[12,3] = 5,6,7
expect(current).to eq([0,1,2,3,4,5,6,7,8,9,10,nil,5,6,7])
end
end
context 'fill' do
it '対象の要素が変更されること' do
expect([1,2,3].fill('a', 1..2)).to eq([1,'a','a'])
end
end
context 'replace' do
it 'オブジェクトIDが変更されないこと' do
hoge = [1,2,3]
object_id = hoge.object_id
hoge.replace([2,3,4])
expect(hoge.object_id).to eq(object_id)
end
end
end
describe '多重代入' do
context 'a,b,c=[1,2],3' do
it 'a=[1,2],b=3,c=nil' do
a,b,c=[1,2],3
expect(a).to eq([1,2])
expect(b).to eq(3)
expect(c).to eq(nil)
end
end
context '(a,b),c=[1,2],3' do
it 'a=1,b=2,c=3' do
(a,b),c=[1,2],3
expect(a).to eq(1)
expect(b).to eq(2)
expect(c).to eq(3)
end
end
context 'a,*b=1,2,3' do
it 'a=1,b=[2,3]' do
a,*b=1,2,3
expect(a).to eq(1)
expect(b).to eq([2,3])
end
end
context 'a,b=1,2,3' do
it 'a=1,b=2' do
a,b=1,2,3
expect(a).to eq(1)
expect(b).to eq(2)
end
end
end
describe '可変長引数' do
context 'メソッドの引数を*で渡した場合' do
it '引数を配列として扱うこと' do
def hoge(a,*b); moge(*b); end
def moge(c,*d); d; end
expect(hoge(1,2,3)).to eq([3])
end
end
context 'メソッドの引数をそのまま渡した場合' do
it '普通の値として扱うこと' do
def hoge(a,*b); moge(*b); end
def moge(c,d); d; end
expect(hoge(1,2,3)).to eq(3)
end
end
end
describe '配列演算子' do
context '&' do
it '共通の値をuniqすること' do
expect([4,4,5,5]&[5,6,7]).to eq([5])
end
end
context '|' do
it '和の値をuniqすること' do
expect([4,4,5,5]|[5,6,7]).to eq([4,5,6,7])
end
end
context '+' do
it '連結すること' do
expect([4,4,5,5]+[5,6,7]).to eq([4,4,5,5,5,6,7])
end
end
context '-' do
it '左辺にないもののみ残ること' do
expect([4,4,5,5]-[5,6,7]).to eq([4,4])
end
end
end
describe '要素への追加' do
it '追加できること' do
expect([1]<<2).to eq([1,2])
expect([1].concat([2])).to eq([1,2])
expect([1].insert(1,2)).to eq([1,2])
expect([1]+[2]).to eq([1,2])
expect([1].unshift(2)).to eq([2,1])
end
end
describe '要素の参照' do
it 'rangeで取得できること' do
expect([1,2,3][1..2]).to eq([2,3])
expect([1,2,3][1..3]).to eq([2,3])
end
it 'atは値を返すこと' do
expect([1,2,3].at(1)).to eq(2)
end
it 'values_atは配列で返すこと' do
expect([1,2,3].values_at(1)).to eq([2])
expect([1,2,3].values_at(5)).to eq([nil])
end
it 'fetchは対象要素がなかった場合IndexErrorが発生すること' do
expect{[1,2,3].fetch(4)}.to raise_exception(IndexError)
expect([1,2,3].fetch(4,'ERROR')).to eq('ERROR')
expect([1,2,3].fetch(4) {|n| "ERROR #{n}"}).to eq('ERROR 4')
end
it 'firstでは引数分の配列が取得できること' do
expect([1,2,3].first(2)).to eq([1,2])
end
it 'lastでは引数分の配列が取得できること' do
expect([1,2,3].last(2)).to eq([2,3])
end
end
describe '要素の探索' do
it 'indexで要素を探索できること' do
expect([1,2,3,3].index(3)).to eq(2)
end
it 'rindexで要素を末尾から探索できること' do
expect([1,2,3,3].rindex(3)).to eq(3)
end
it 'assocでは配列の配列を探索できること' do
expect([[1],[2]].assoc(2)).to eq([2])
end
it 'rassocでは配列の配列の最後の要素を探索できること' do
expect([[1,2],[2,3]].rassoc(2)).to eq([1,2])
end
end
describe '要素の削除' do
it 'delete_atは指定の要素を削除できること' do
expect([1,2,3].tap {|a| a.delete_at(2) }).to eq([1,2])
end
it 'deleteは引数の要素を==で比べて削除できること' do
expect([1,2,2,3].tap {|a| a.delete(2) }).to eq([1,3])
end
it 'delete_ifはブロックに条件を渡せること' do
expect([1,2,2,3].tap {|a| a.delete_if{|n| n%2==0} }).to eq([1,3])
end
it 'slice!は指定の要素を削除できること' do
expect([1,2,2,3].tap {|a| a.slice!(2,3) }).to eq([1,2])
end
it 'shiftは先頭の要素から引数で指定した分削除できること' do
expect([1,2,2,3].tap {|a| a.shift(2) }).to eq([2,3])
end
it 'popは先頭の末尾から引数で指定した分削除できること' do
expect([1,2,2,3].tap {|a| a.pop(2) }).to eq([1,2])
end
it '-は元の配列からマッチした分削除できること' do
expect([1,2,2,3]-[1,2]).to eq([3])
end
end
context '比較' do
it 'UFO演算子が使えること' do
expect([2,1,2]<=>[1,3,5]).to eq(1)
end
end
context '配列内の繰り返し' do
it 'reverse_eachが使えること' do
expect([].tap {|a| [1,2,3].reverse_each {|i| a << i}} ).to eq [3,2,1]
end
it 'cycleが使えること' do
hoge = []
[1,2,3].cycle do |i|
hoge << i
break if i == 3
end
expect(hoge).to eq [1,2,3]
end
end
context '配列の長さ' do
it 'nitemsはnilではない要素数が取得できること' do
# Ruby1.9では廃止
if RUBY_VERSION < '1.9'
expect([1,2,3,nil,5].ntimes).to ex 4
end
end
end
context 'ソート' do
it 'ブロックを渡せること' do
expect([1,3,2].sort{|a,b| b<=>a}).to eq [3,2,1]
end
end
context '配列変換' do
it 'flattenには引数が設定できること(引数の階層まで許す)' do
expect([[[1,2],3],4,5].flatten(1)).to eq [[1,2],3,4,5]
expect([[[1,2],3],4,5].flatten(0)).to eq [[[1,2],3],4,5]
expect([[[1,2],3],4,5].flatten(2)).to eq [1,2,3,4,5]
end
it 'shuffleメソッドがあること' do
hoge = [1,2,3]
hoge.stub!(:shuffle).and_return([2,1,3])
expect(hoge.shuffle).to eq [2,1,3]
end
end
context '配列の組み合わせ生成' do
it 'productメソッドですべての組み合わせが実現できること' do
expect([1,2].product(['a','b'])).to eq [[1,'a'],[1,'b'],[2,'a'],[2,'b']]
end
it 'zipメソッドで各要素をあわせた配列ができること' do
expect([1,2].zip([3,4])).to eq [[1,3],[2,4]]
expect([1,2].zip([3])).to eq [[1,3],[2,nil]]
expect([1,2].zip([3],[6,7])).to eq [[1,3,6],[2,nil,7]]
end
end
end
# coding: utf-8
require 'rspec'
require 'complex'
describe Complex do
context '初期化' do
it '第一引数に実数、第二引数に虚数をとること' do
expect(Complex(1,1)+0.5).to eq(Complex(1.5,1))
end
it 'realで実数部分をとれること' do
expect(Complex(1,1).real).to eq(1)
end
it 'imageで虚数部分をとれること' do
# 1 + 0.5i
expect(Complex(1,0.5).image).to eq(0.5)
end
end
context 'ガウス平面' do
it 'absで複素数の絶対値が取得できること' do
# ルート(実数の2乗+虚数の2乗)
expect(Complex(0,2).abs).to eq(2)
end
it 'argで偏角を取得できること' do
expect(Complex(0,2).arg).to eq(1.5707963267948966)
end
it 'polarで絶対値と偏角の配列を取得できること' do
expect(Complex(0,2).polar).to eq([2,1.5707963267948966])
end
end
end
# coding: utf-8
require 'rspec'
require 'csv'
describe CSV do
before do
File.open('pochi.csv', 'w+') {|f| f.print "1,2,3\n4,5,6\n7,8,9"}
end
context 'データの読み込み' do
it 'loadで取得できること' do
elements = []
CSV.open('pochi.csv').each {|row| elements << row }
expect(elements).to eq([['1','2','3'],['4','5','6'],['7','8','9']])
end
it 'readで取得できること' do
expect(CSV.read('pochi.csv')).to eq([['1','2','3'],['4','5','6'],['7','8','9']])
end
it 'foreachで取得できること' do
elements = []
CSV.foreach('pochi.csv') {|row| elements << row }
expect(elements).to eq([['1','2','3'],['4','5','6'],['7','8','9']])
end
end
context 'データの書き込み' do
it 'openのモードによって書き込みができること' do
CSV.open('pochi_write.csv','w+') {|csv| csv << [1,2,3] << [4,5,6]}
expect(CSV.read('pochi_write.csv')).to eq([['1','2','3'],['4','5','6']])
end
end
end
__END__
ファイルの読み込みモード
r
w
rb
rw
# coding: utf-8
require 'rspec'
def capture(stream)
begin
stream = stream.to_s
eval "$#{stream} = StringIO.new"
yield
result = eval("$#{stream}").string
ensure
eval("$#{stream} = #{stream.upcase}")
end
result
end
describe 'Dir,File' do
context 'Dir' do
it 'pathでディレクトリを取得できること' do
expect(Dir.open('/usr'){|dir| dir.path}).to eq('/usr')
end
it 'pwd,getwdで現在のディレクトリを取得できること' do
Dir.chdir('/usr') do
expect(Dir.pwd).to eq('/usr')
end
end
it 'chdirでブロックを渡すと1時的に移動できること' do
Dir.chdir('/usr') do
expect(Dir.pwd).to eq('/usr')
end
end
it 'Dir.mkdir,rmdir,unlink,deleteが利用できること' do
%w(mkdir rmdir unlink delete).map{|m| m.to_sym }.each do |m|
expect(Dir.methods).to be_include(m)
end
end
end
context 'File' do
before do
File.open('pochi.txt', 'w+') {|f| f.write 'pochi' }
end
it 'basenameでファイル名を取得できること' do
expect(File.basename('/usr/pochi.txt')).to eq('pochi.txt')
end
it 'dirnameでディレクトリ名を取得できること' do
expect(File.dirname('/usr/pochi.txt')).to eq('/usr')
end
it 'extnameで拡張子を取得できること' do
expect(File.extname('/usr/pochi.txt')).to eq('.txt')
end
it 'splitでディレクトリ名とファイル名の配列を取得できること' do
expect(File.split('/usr/pochi.txt')).to eq(['/usr','pochi.txt'])
end
it 'executable?で実行可能か調べられること' do
expect(File.executable?('pochi.txt')).to be_false
end
it 'readable?で読み込み狩野か調べられること' do
expect(File.readable?('pochi.txt')).to be_true
end
it 'writable?で読み込み狩野か調べられること' do
expect(File.writable?('pochi.txt')).to be_true
end
it 'utimeで最終アクセス時間、更新時間を設定できること(戻り値はLinuxのといっしょ(1))' do
expect(File.utime(Time.now, Time.now, "pochi.txt")).to eq(1)
end
it 'expand_pathでファイルの絶対パスが取得できること' do
expect(File.expand_path('pochi.txt')).to eq('/opt/local/repos/ruby/gold/pochi.txt')
end
it 'deleteでファイルを削除できること' do
expect(File.delete('pochi.txt')).to eq(1)
expect(File.exists?('pochi.txt')).to be_false
end
it 'truncateでし指定したバイトに切り詰められること' do
File.truncate('pochi.txt',3)
expect(File.read('pochi.txt')).to eq('poc')
end
it 'renameでファイル名を変更できること' do
expect(File.rename('pochi.txt','pochi.txt.txt')).to eq(0)
end
it 'open(file,a+)でファイルの末尾に追記できること' do
File.open('pochi.txt', 'a+') {|f| f.write 'cute' }
expect(File.read('pochi.txt')).to eq('pochicute')
end
it 'open(file,w+)でファイルを上書きできること' do
File.open('pochi.txt', 'w+') {|f| f.write 'cute' }
expect(File.read('pochi.txt')).to eq('cute')
end
it 'open(file,r+)でファイルの先頭に追記できること' do
File.open('pochi.txt', 'r+') {|f| f.write 'cute' }
expect(File.read('pochi.txt')).to eq('cutei')
end
it 'flockでファイルをロックできること' do
File.open('pochi.txt', 'w') {|f| f.flock(File::LOCK_EX) }
end
end
describe IO do
context 'open' do
it "| commandで標準出力を取得できること" do
expect(open('| pwd').read.chomp).to eq('/opt/local/repos/ruby/gold')
end
end
context 'STDOUT.write(puts)' do
it '標準出力で書き込めること' do
STDOUT = StringIO.new
STDOUT.puts('pochi','cute')
STDOUT.write('hoge')
expect(STDOUT.string).to eq("pochi\ncute\nhoge")
end
end
context 'STDOUT.print' do
it '$,で指定した値が各引数ごとの間にjoinされ、$\に設定されている文字列が最後に入ること' do
$, = "\t"
$\ = 'cute'
STDOUT = StringIO.new
STDOUT.print('hoge', ['pochi'])
expect(STDOUT.string).to eq("hoge\t[\"pochi\"]cute")
end
end
context 'その他の標準出力' do
it 'printfを使ってフォーマット付き出力ができること' do
STDOUT = StringIO.new
STDOUT.printf('%05d', 123)
expect(STDOUT.string).to eq('00123')
end
it 'putcで一文字出力できること' do
STDOUT = StringIO.new
STDOUT.putc('a')
expect(STDOUT.string).to eq('a')
end
it '<<で出力できること' do
STDOUT = StringIO.new
STDOUT << 'pochi' << ' is ' << 'cute'
expect(STDOUT.string).to eq('pochi is cute')
end
end
context 'flush' do
it '内部バッファをフラッシュできること' do
io = open('pochi.txt', 'w+')
io.write('pochi')
expect(File.read('pochi.txt')).to eq('')
io.flush
expect(File.read('pochi.txt')).to eq('pochi')
end
end
context 'stat' do
it 'ファイルの状態を調べられること' do
io = open('pochi.txt', 'w+')
expect(io.stat).to be_a(File::Stat)
end
end
context 'closed?' do
it 'ioオブジェクトが閉じられたかどうか確認できること' do
io = open('pochi.txt', 'w+')
expect(io.closed?).to be_false
io.close
expect(io.closed?).to be_true
end
end
context 'eof?' do
before { open('pochi.txt', 'w') {|f| f.puts 'pochi' }}
it 'ファイルの終端か調べられること' do
io = open('pochi.txt','r')
expect(io.eof?).to be_false
io.read
expect(io.eof?).to be_true
io.close
end
end
context 'lineno' do
before { open('pochi.txt', 'w') {|f| f.puts "pochi\nis\ncute" }}
it 'ファイルの行数を知れること' do
io = open('pochi.txt', 'r')
expect(io.lineno).to eq(0)
io.gets
expect(io.lineno).to eq(1)
io.close
end
end
context 'ポインタの移動' do
before { open('pochi.txt', 'w') {|f| f.puts 'pochi' }}
it 'rewindで先頭に戻れること' do
io = open('pochi.txt', 'r')
expect(io.read).to eq("pochi\n")
expect(io.read).to eq('')
io.rewind
expect(io.read).to eq("pochi\n")
end
it 'posで移動できること' do
io = open('pochi.txt', 'r')
expect(io.read).to eq("pochi\n")
expect(io.read).to eq('')
io.pos = 0
expect(io.read).to eq("pochi\n")
end
it 'seekでポインタを移動できること' do
io = open('pochi.txt', 'r')
io.seek(2)
expect(io.read.chomp).to eq('chi')
io.seek(2)
io.seek(-1, IO::SEEK_CUR) # SEEK_CUR => 現在のカーソル
expect(io.read.chomp).to eq('ochi')
io.seek(-2, IO::SEEK_END)
expect(io.read.chomp).to eq('i')
end
end
context 'IO.popen' do
it 'パイプを開いて入出力を扱うことができること' do
out = nil
IO.popen('grep -i pochi', 'w+') do |io|
io.write('pochipochi')
io.close_write
out = io.read.chomp
end
expect(out).to eq('pochipochi')
end
end
context 'IO.read' do
before do
File.open('pochi.txt', 'w+') {|f| f.write "pochi\nhogehoge" }
end
it '指定したファイルを読み取れること' do
expect(IO.read('pochi.txt')).to eq("pochi\nhogehoge")
expect(IO.read('pochi.txt',3)).to eq('poc')
expect(IO.read('| pwd').chomp).to eq('/opt/local/repos/ruby/gold')
end
it 'foreachでファイルを読み取れること' do
expect([].tap {|a| IO.foreach('pochi.txt') {|l| a << l} }).to eq(["pochi\n", 'hogehoge'])
end
it 'readlinesでファイルを読み取れること(全部読んで配列で返す)' do
expect(open('pochi.txt').readlines).to eq(["pochi\n", 'hogehoge'])
end
it 'getbyte,readchar,getcで一文字ずつ取得できること(iterationの場合each_char, chars)' do
io = open('pochi.txt')
expect(io.getbyte.chr).to eq('p')
expect(io.getbyte.chr).to eq('o')
expect(io.readchar).to eq('c')
expect(io.getc).to eq('h')
end
end
end
end
__END__
File.mode
r: 読み込みモード
w: 書き込みモード
a: 追記モード
r+: 読み書きモード。ファイルの先頭にセットされる。
w+: 読み書きモード。ファイルが空になる。
a+: 読み書きモード。ファイルの末尾にセットされる。
File.updatetime
atime: 最終アクセス時間
ctime: 状態が変更された時間
mtime: 最終更新時間
# coding: utf-8
require 'rspec'
describe Enumerable do
context 'map' do
it '評価した値の配列がかえってくること' do
expect([1,2,3].map{|i|i**2}).to eq([1,4,9])
end
end
context 'inject' do
it '加算できること' do
expect([1,2,3].inject(0) {|r,v| r+=v}).to eq(6)
end
end
context 'each_cons' do
it '配列の組み合わせが順番によばれること' do
expect([].tap {|a| [1,2,3,4].each_cons(2) {|i| a << i} }).to eq([[1,2],[2,3],[3,4]])
end
end
context 'all?,any?,one?,none?' do
it '結果がかえってくること' do
expect([1,2,3]).to be_all
expect([1,nil,nil]).to be_any
expect([1,nil,nil]).to be_one
expect([nil,nil,nil]).to be_none
end
end
context 'find(select), find_index' do
it 'findはブロックで評価した値がかえってくること' do
expect([1,2,3,4].find{|i| i%2==0}).to eq(2)
end
it 'find_indexはブロックで評価したindexがかえってくること' do
expect([1,2,3,4].find_index{|i| i%2==0}).to eq(1)
end
end
context 'sorb_by' do
it 'ブロックの評価結果を<=>で比較して昇順ソートしてくれること' do
expect([4,3,1,2].sort_by{|i| i}).to eq([1,2,3,4])
end
end
context 'group_by' do
it 'ブロックの評価結果をkey、要素を配列としたHashを返すこと' do
expect([1,2,3,4].group_by{|i| i%2==0}).to eq({true=>[2,4],false=>[1,3]})
end
end
end
# coding: utf-8
require 'rspec'
describe Exception do
before do
class HogeError < RuntimeError; end
end
context '自作クラスが作れること' do
it '例外が投げれること' do
expect { raise HogeError }.to raise_exception(HogeError)
end
it 'エラーメッセージが投げれること' do
expect(
begin
raise HogeError.exception('pochi')
rescue => e
e.message
end
).to eq('pochi')
end
end
context 'set_backtrace' do
it 'backtraceの情報を上書きできること' do
expect(
begin
raise HogeError.exception('pochi')
rescue => e
e.set_backtrace('pochi')
e.backtrace
end
).to eq(['pochi'])
end
end
context '除算で0でわったとき' do
it 'ZeroDivisionErrorが発生すること' do
expect { 1/0 }.to raise_exception(ZeroDivisionError)
end
end
context 'throw-catchのテスト' do
it ':hogeがthrowされること' do
def hoge(); throw :hoge; end
catch(:hoge) {}
expect { hoge }.to throw_symbol(:hoge)
end
end
end
# coding: utf-8
require 'rspec'
require 'fileutils'
def capture(stream)
begin
stream = stream.to_s
eval "$#{stream} = StringIO.new"
yield
result = eval("$#{stream}").string
ensure
eval("$#{stream} = #{stream.upcase}")
end
result
end
describe FileUtils do
before do
module FileUtils
# ソース見る限りstderrで出そうとしてるのだけどキャッチできなかったから上書きした
def fu_output_message(msg)
$stdout.puts msg
end
private_module_function :fu_output_message
end
class Pochi; include FileUtils; end
end
let(:options) do
{ :verbose => true, :noop => true }
end
it 'includeできること' do
class Hoge; include FileUtils; end
expect(Hoge.ancestors).to be_include(FileUtils)
end
context 'mkdir,mkdir_p' do
it 'ディレクトリが作成できること' do
expect(capture(:stdout) do
FileUtils.mkdir('hoge', options)
end).to eq("mkdir hoge\n")
expect(capture(:stdout) do
FileUtils.mkdir_p('hoge', options)
end).to eq("mkdir -p hoge\n")
end
end
context 'cp,copy' do
it 'コピーできること' do
expect(capture(:stdout) do
FileUtils.cp('hoge', 'moge', options)
end).to eq("cp hoge moge\n")
expect(capture(:stdout) do
FileUtils.copy('hoge', 'moge', options)
end).to eq("cp hoge moge\n")
end
end
context 'cp_r' do
it 'ディレクトリコピーができること' do
expect(capture(:stdout) do
FileUtils.cp_r('hoge', 'moge', options)
end).to eq("cp -r hoge moge\n")
end
end
context 'mv,move' do
it 'ファイルを変更できること' do
expect(capture(:stdout) do
FileUtils.mv('hoge', 'moge', options)
end).to eq("mv hoge moge\n")
expect(capture(:stdout) do
FileUtils.move('hoge', 'moge', options)
end).to eq("mv hoge moge\n")
end
end
context 'rm,remove' do
it 'ファイルを削除できること' do
expect(capture(:stdout) do
FileUtils.rm('hoge', options)
end).to eq("rm hoge\n")
expect(capture(:stdout) do
FileUtils.remove('hoge', options)
end).to eq("rm hoge\n")
end
end
context 'rmdir, rm_r, rm_rf' do
it 'ファイルを削除できること' do
expect(capture(:stdout) do
FileUtils.rmdir('hoge', options)
end).to eq("rmdir hoge\n")
expect(capture(:stdout) do
FileUtils.rm_r('hoge', options)
end).to eq("rm -r hoge\n")
expect(capture(:stdout) do
FileUtils.rm_rf('hoge', options)
end).to eq("rm -rf hoge\n")
end
end
context 'touch' do
it 'ファイルを更新できること' do
expect(capture(:stdout) do
FileUtils.touch('hoge', options)
end).to eq("touch hoge\n")
end
end
context 'chown,chmod' do
it '所有権の変更ができること' do
expect(capture(:stdout) do
FileUtils.chown('user', 'group', 'hoge', options)
end).to eq("chown user:group hoge\n")
expect(capture(:stdout) do
# modeは8進数で指定
FileUtils.chmod(0755, 'hoge', options)
end).to eq("chmod 755 hoge\n")
end
end
context 'ln_s,symlink' do
it 'シンボリックリンクがはれること' do
expect(capture(:stdout) do
FileUtils.ln_s('hoge', 'moge', options)
end).to eq("ln -s hoge moge\n")
expect(capture(:stdout) do
FileUtils.symlink('hoge', 'moge', options)
end).to eq("ln -s hoge moge\n")
end
end
end
__END__
:verbose(詳細出力)と:noop(実際にコマンドを実行しない)を利用してテストできる
:forceで上書きできるメソッドは有効かできる。
preserve: 真を指定すると更新時刻と、可能なら所有ユーザ・所有グループもコピーします。
# coding: utf-8
require 'rspec'
describe Hash do
context '初期化' do
it 'Hash[:hoge,1,:moge,2]で初期化できること' do
current = Hash[:hoge,1,:moge,2]
expect(current[:hoge]).to eq(1)
expect(current[:fuga]).to eq(nil)
end
it '引数を渡すと初期値が設定できること' do
h = Hash.new('pochi')
expect(h['hoge']).to eq('pochi')
end
it 'defaultメソッドで初期値を変更できること' do
h = {}
h.default = 'pochi'
expect(h['hoge']).to eq('pochi')
end
end
context '値の取得' do
let(:h) {{name: 'pochi',age: 23}}
it 'values_atで特定のキーの値を配列で返すこと' do
expect(h.values_at(:name, :age)).to eq ['pochi', 23]
end
it 'fetchで値を取得できること' do
expect(h.fetch(:name)).to eq 'pochi'
expect(h.fetch(:hoge, 'ERROR')).to eq 'ERROR'
end
it 'selectで値を取得できること' do
if RUBY_VERSION < '1.9'
expect(h.select{|k,v| k==:name }).to eq([[:name, 'pochi']])
end
end
end
context '変更' do
let(:h) {{name: 'pochi',age: 23}}
it 'deleteで削除できること' do
expect(h.dup.tap {|h| h.delete(:name)}).to eq({:age => 23})
expect(h.tap {|h| h.delete(:hoge)}).to eq({:name => 'pochi',:age => 23})
end
it 'rejectで取り除けること(元のオブジェクトは変更されない)' do
expect(h.reject{|k,v| v=='pochi'}).to eq({:age => 23})
expect(h).to eq({name: 'pochi',age: 23})
end
it 'reject!で取り除けること' do
expect(h.tap {|h| h.reject!{|k,v| v=='pochi'}}).to eq({age: 23})
end
it 'replaceで変更できること(object_idはかわらない)' do
_id = h.object_id
h.replace(:hoge => 'moge')
expect(_id).to eq(h.object_id)
end
it 'shiftで不定のkeyとvalueが取得できること' do
hoge = {:hoge => :moge}
expect(hoge.shift).to eq [:hoge,:moge]
expect(hoge).to be_empty
end
it 'mergeで新しいhashを作れること(そのものを変更したいときはmerge!を使う)' do
expect(h.merge(:hoge => :moge, :age => 25)).to eq({name: 'pochi',age: 25, hoge: :moge})
end
it 'mergeでブロックを渡せること' do
expect(h.merge(:hoge => :moge, :age => 25) {|k,old,new| old}).to eq({name: 'pochi',age: 23, hoge: :moge})
end
it 'invertでkeyとvalueを逆にできること' do
expect(h.invert).to eq({23 => :age,'pochi' => :name})
end
it 'to_aで配列に変換できること' do
expect(h.to_a).to eq([[:name, 'pochi'], [:age, 23]])
end
end
context '値の調査' do
it 'has_key?,include?,key?,member?でkeyがあるかきけること' do
expect({:name=>'pochi'}.member?(:name)).to be_true
end
end
context 'sort' do
it 'keyとvalueの配列でsortされること' do
expect({name: 'pochi',age: 23}.sort).to eq [[:age, 23],[:name, 'pochi']]
end
it 'ブロックで渡せること' do
if RUBY_VERSION < '1.9'
expect({name: 'pochi',age: 23}.sort{|a,b| a[1]<=>b[1]}).to eq([[:age, 23],[:name, 'pochi']])
end
end
end
end
# coding: utf-8
require 'rspec'
def capture(stream)
begin
stream = stream.to_s
eval "$#{stream} = StringIO.new"
yield
result = eval("$#{stream}").string
ensure
eval("$#{stream} = #{stream.upcase}")
end
result
end
describe 'Klass' do
before do
Hoge = Class.new
end
context '定義したクラスを上書きした場合' do
it 'warningが出力されること' do
expect(capture(:stderr) { Hoge=2 }).to be_include('warning')
expect(Hoge).to eq(2)
end
end
describe 'instance_methods(false)' do
it 'クラスで定義したインスタンスメソッドが取得できること' do
class Hoge; def moge; end; end
# 1.9からはsymbolでかえってくるようになった。1.8では文字列
expect(Hoge.instance_methods(false)).to eq([:moge])
end
it 'aliasとundefを利用するとその分が適用されること' do
class Hoge
def moge; end
alias moge1 moge
def fuga; end
undef fuga
end
expect(Hoge.instance_methods(false)).to eq([:moge, :moge1])
end
end
describe 'instance_variables' do
it '代入したときに初めて有効化されること' do
class Hoge; attr_accessor :moge; end
expect(Hoge.new.instance_variables).to be_empty
m = Hoge.new; m.moge = 111
# 1.9からはsymbolでかえってくるようになった。1.8では文字列
expect(m.instance_variables).to eq([:@moge])
end
end
context '定義したクラスにsuperclassを設定しようとした場合' do
it 'TypeErrorが発生すること' do
class Moge; end
expect { class Hoge < Moge; end }.to raise_exception(TypeError)
end
end
context '複数モジュールが同じメソッドを持っていた場合' do
before do
module M1; def hoge; 3; end; end
module M2; def hoge; 4; end; end
end
it '最後に適用したメソッドが有効化されること' do
class Hoge
include M1
include M2
end
expect(Hoge.new.hoge).to eq(4)
end
it 'includeで複数モジュールを適用した場合最初に定義したものが有効かされること' do
class Hoge
include M1, M2
end
expect(Hoge.new.hoge).to eq(3)
end
it 'moduleで定義しているメソッドは上書きできること' do
class Hoge
include M1
def hoge; 1; end
end
expect(Hoge.new.hoge).to eq(1)
end
end
context '特異クラスの取得' do
it '無名クラスが取得できること' do
hoge = Hoge.new
klass = class << hoge; self; end
expect(klass).to be_a(Class)
end
end
context 'def式の中で再度def式を定義する' do
before do
class Hoge
def moge; self; def fuga; self; end; end
end
end
it 'def式がよばれないと中のメソッドは定義されないこと' do
expect(Hoge.instance_methods(false)).to eq([:moge])
end
it '一度メソッドをよぶと中のメソッドも定義されること' do
hoge = Hoge.new
hoge.moge
expect(Hoge.instance_methods(false)).to eq([:moge,:fuga])
end
end
context 'インスタンス変数はクラスまで探索しない' do
it 'クラスに定義されたインスタンス変数の値はインスタンスに影響しないこと' do
class Hoge
@name = 'pochi'
def name; @name; end
end
expect(Hoge.new.name).to be_nil
end
it 'クラス変数は共有されること' do
class Hoge
@@name = 'pochi'
def name; @@name; end
end
expect(Hoge.new.name).to eq('pochi')
end
end
end
# coding: utf-8
require 'rspec'
describe Marshal do
context 'dump' do
it 'オブジェクトを書き出せること' do
expect(Marshal.dump('abc')).to eq("\x04\bI\"\babc\x06:\x06ET")
end
it 'ファイルに書き出せること' do
File.open('pochi.dump', 'w+') {|f| Marshal.dump('abc', f) }
expect(File.read('pochi.dump')).to eq("\x04\bI\"\babc\x06:\x06ET")
end
end
context 'load' do
it 'Rubyオブジェクトを取得できること' do
File.open('pochi.dump', 'w+') {|f| Marshal.dump('abc', f) }
expect(Marshal.load(File.read('pochi.dump'))).to eq('abc')
end
end
context '例外' do
it 'オブジェクトの状態を示すものはいれられないこと(Dir,IO,File,MatchData,Proc,Thread)' do
# 後はクラスをさしているオブジェクト(クラスメソッドを持っているオブジェクト、クラスを間接的にさしているオブジェクト)
expect { Marshal.dump(Dir.new) }.to raise_exception(ArgumentError)
end
end
end
# coding: utf-8
require 'rspec'
describe Module do
it 'contantsで定数一覧が取得できること' do
expect(Regexp.constants).to eq([:IGNORECASE, :EXTENDED, :MULTILINE, :FIXEDENCODING, :NOENCODING])
end
it 'const_defined?で定数が定義されているか調べられること' do
expect(Regexp.const_defined?(:IGNORECASE)).to be_true
expect(Regexp.const_defined?(:POCHI)).to be_false
end
it 'const_getで定数の値を取り出せること' do
expect(Regexp.const_get(:IGNORECASE)).to eq(1)
end
it 'const_setで定数を設定できること' do
Regexp.const_set(:POCHI, 'pochi')
expect(Regexp.const_get(:POCHI)).to eq('pochi')
end
it 'remove_constで定数を削除できること' do
Regexp.__send__(:remove_const, :IGNORECASE)
expect { Regexp.const_get(:IGNORECASE) }.to raise_exception(NameError)
end
it 'ancestorsで祖先クラスを取得できること' do
if RUBY_VERSION < '1.9'
expect(Array.ancestors).to eq([Array, Enumerable, Object, Kernel])
end
end
it 'alias_methodで別名を取得できること' do
class Hoge
def hoge; 'hoge'; end
alias_method 'another_hoge', 'hoge'
def hoge
'moge ' + another_hoge
end
end
expect(Hoge.new.hoge).to eq('moge hoge')
end
it 'class_execでクラスの内部構造を利用できること' do
expect(Regexp.class_exec(1) {|i| i + self::EXTENDED }).to eq(3)
end
it 'class_variablesでクラス変数が取得できること' do
# ATTENTION: @@hogeに何か代入しないと宣言されない
class Hoge; @@hoge=2; end
expect(Hoge.class_variables).to eq([:@@hoge])
end
it 'class_variables_defined?で宣言されているか調べられること' do
expect(Hoge.class_variable_defined?(:@@hoge)).to be_true
end
it 'class_variable_setで設定できること' do
Hoge.class_variable_set(:@@hoge, 5)
expect(Hoge.class_variable_get(:@@hoge)).to eq(5)
end
it 'remove_class_bariableでクラス変数をけせること' do
Hoge.remove_class_variable(:@@hoge)
expect(Hoge.class_variables).to eq([])
end
it 'klass.include?でモジュールがロードされているか調べる' do
module Moge; end
class Hoge; include Moge; end
expect(Hoge.include?(Moge)).to be_true
end
it 'module_functionを利用してモジュールからメソッドをよべるようになること' do
module Moge; def moge; 'moge'; end; module_function :moge; def fuga; 'fuga'; end; end;
expect(Moge.moge).to eq('moge')
expect { Moge.fuga }.to raise_exception(NoMethodError)
end
end
# coding: utf-8
require 'rspec'
require 'net/http'
describe Net::HTTP do
context 'GET' do
it 'インスタンスに対してgetメソッドでデータ取得できること' do
n = Net::HTTP.new('www.google.com')
n.start
r = n.get("/")
n.finish
expect(r.body).to be_include('google')
end
it 'ブロックで渡せること' do
Net::HTTP.new('www.google.com') do |h|
r = h.get("/")
expect(r.body).to be_include('google')
end
end
it 'クラスメソッドでも取得できること' do
# getした時点でbodyがかえってくる
expect(Net::HTTP.get('www.google.com', '/')).to be_include('google')
end
it 'requestメソッドを使って取得できること' do
n = Net::HTTP.new('www.google.com')
r = Net::HTTP::Get.new('/') # Post,Head,Putもあり
r = n.request(r)
expect(r.body).to be_include('google')
end
it 'basic_authを設定できること' do
r = Net::HTTP::Get.new('/') # Post,Head,Putもあり
r.basic_auth('pochi', 'cute')
expect(r['authorization']).to eq('Basic cG9jaGk6Y3V0ZQ==')
end
end
context 'HTTPResponse' do
it 'レスポンスの状態を取得できること' do
Net::HTTP.new('www.google.com') do |h|
r = h.get("/")
expect(r.body).to be_include('google')
expect(r.code).to eq('302')
expect(r['location']).to eq('http://www.google.co.jp')
end
end
end
end
# coding: utf-8
require 'rspec'
describe Numeric do
describe '小数値の切り上げ、切り捨て' do
describe '1.7の場合' do
let(:current) {1.7}
context 'ceil' do
it '大きい整数を返す(2)' do
expect(current.ceil).to be(2)
end
end
context 'floor' do
it '小さい整数を返す(1)' do
expect(current.floor).to be(1)
end
end
context 'round' do
it '最も近い整数を返す(2)' do
expect(current.round).to be(2)
end
end
context 'truncate' do
it 'その数字と0の間で一番近い整数を返す(1)' do
expect(current.truncate).to be(1)
end
end
end
describe '-1.7の場合' do
let(:current) {-1.7}
context 'ceil' do
it '大きい整数を返す(-1)' do
expect(current.ceil).to be(-1)
end
end
context 'floor' do
it '小さい整数を返す(-2)' do
expect(current.floor).to be(-2)
end
end
context 'round' do
it '最も近い整数を返す(-2)' do
expect(current.round).to be(-2)
end
end
context 'truncate' do
it 'その数字と0の間で一番近い整数を返す(-1)' do
expect(current.truncate).to be(-1)
end
end
end
end
describe '除算' do
it '10/3の場合整数を返す(3)' do
expect(10/3).to be(3)
end
it '10/3.0の場合Floatを返す(3.333)' do
expect(10/3).to be(3)
end
end
describe '剰余' do
it '10.modulo(3)は1を返す' do
expect(10.modulo(3)).to be(1)
end
it '10 % 3 は1を返す' do
expect(10%3).to be(1)
end
end
describe '整数に対する文字(chr)' do
context '正の数値の場合(65)' do
let(:current) {65}
it 'Aがかえること' do
expect(current.chr).to eq('A')
end
end
context '負の数値の場合' do
let(:current) {-1}
it 'RangeErrorが発生すること' do
expect{current.chr}.to raise_exception(RangeError)
end
end
end
describe 'ビット演算子' do
let(:left) {10}
let(:right) {3}
context '論理和(|)' do
it '10(0b1010)と3(0b0011)で計算すると11(0b1011)がかえること' do
expect(left|right).to eq(11)
end
end
context '論理積(&)' do
it '10(0b1010)と3(0b0011)で計算すると2(0b0010)がかえること' do
expect(left&right).to eq(2)
end
end
context '排他的論理和(^)' do
it '10(0b1010)と3(0b0011)で計算すると9(0b1001)がかえること' do
expect(left^right).to eq(9)
end
end
context '否定(~)' do
it '10(0b1010)を否定すると-11(0b10101)がかえること' do
expect(~left).to eq(-11)
end
end
context '左シフト演算(<<)' do
it '10(0b1010)で1ビットシフトすると20(0b10100)がかえること' do
expect(left<<1).to eq(20)
end
end
context '右シフト演算(>>)' do
it '10(0b1010)で1ビットシフトすると20(0b0101)がかえること' do
expect(left>>1).to eq(5)
end
end
end
describe "小数の繰り返し" do
context '10.step(11,0.5)' do
it "10,10.5,11がよばれること" do
counts = []
10.step(11,0.5) {|f| counts << f}
expect(counts).to eq([10,10.5,11])
end
end
end
end
# coding: utf-8
require 'rspec'
describe Object do
context 'equal?' do
it 'object_idで判断すること' do
expect('hoge'.equal?('hoge')).to be_false
end
end
context 'eql?' do
it 'hashで判断すること' do
expect('hoge'.eql?('hoge')).to be_true
expect('hoge'.hash == 'hoge'.hash).to be_true
end
end
end
# coding: utf-8
require 'rspec'
describe Proc do
context '手続きオブジェクト' do
it '作れること' do
expect((Proc.new {'pochi'}).call).to eq('pochi')
end
it 'arityで引数をとれること' do
expect((Proc.new {|x,y,z|}).arity).to eq(3)
end
it 'nextで中断できること' do
p = Proc.new do
next 'next'
'done'
end
expect(p.call).to eq('next')
end
end
describe 'break' do
context 'callで呼び出すとき' do
it 'Procの場合LocalJumpErrorが発生すること' do
p = Proc.new {break}
expect { p.call }.to raise_exception(LocalJumpError)
end
it 'lambdaのときエラーが発生しないこと' do
l = lambda {break}
expect { l.call }.to_not raise_exception(LocalJumpError)
end
end
context '手続きオブジェクトで呼び出すとき' do
it 'Procの場合LocalJumpErrorが発生すること' do
p = Proc.new {break}
expect { 10.times(&p) }.to raise_exception(LocalJumpError)
end
it 'lambdaの場合LocalJumpErrorが発生すること' do
l = lambda {break}
if RUBY_VERSION < '1.9'
expect { 10.times(&l) }.to raise_exception(LocalJumpError)
end
end
end
end
context 'return' do
it 'Procの場合LocalJumpErrorが発生すること' do
p = Proc.new {return}
expect { p.call }.to raise_exception(LocalJumpError)
end
it 'lambdaの場合LocalJumpErrorが発生すること' do
l = lambda {return}
expect { l.call }.to_not raise_exception(LocalJumpError)
end
end
context 'yield' do
it '渡した変数が実際に更新されること' do
def hoge(a); a + yield; end
x = 5
r = hoge(x) {x+=5}
expect(r).to eq(15)
expect(x).to eq(10)
end
it 'yieldに計算式を渡すと計算してくれること' do
def hoge(a); yield(a,3); end
expect(hoge(2) {|x,y| x+y}).to eq(5)
end
it 'Procインスタンスを渡せること' do
def hoge(a); a + yield; end
moge = Proc.new {3+3}
expect(hoge(2, &moge)).to eq(8)
end
it 'メソッドに引数でProcを渡せること' do
def hoge(a,&moge); a+moge.call; end
expect(hoge(2){3}).to eq(5)
end
end
context 'Procとlambdaの違い' do
it 'Procは引数制限が甘いこと' do
expect((Proc.new {|x,y|y}).call(2)).to eq(nil)
end
it 'lambdaの場合ArgumentErrorが発生すること' do
expect{(lambda {|x,y|y}).call(2)}.to raise_exception(ArgumentError)
end
end
end
# coding: utf-8
require 'rspec'
describe Range do
describe 'include?' do
context '範囲に入っている場合' do
it 'trueがかえること' do
expect('a'..'z').to include('d')
end
end
context '範囲に入っていない場合' do
it 'falseがかえること' do
expect(('a'..'z').include?(3)).to be_false
end
end
end
describe '==' do
context '範囲に入っている場合' do
it 'falseがかえること' do
expect(('a'..'z') == 'a' ).to be_false
end
end
end
describe '===' do
context '範囲に入っている場合' do
it 'trueがかえること' do
expect(('a'..'z') === 'a' ).to be_true
end
end
end
end
# coding: utf-8
require 'rspec'
require 'rational'
# 有理数の計算(1/3とか)
describe Rational do
context '生成' do
it 'Rationalで生成できること(newでは生成できない)' do
expect(Rational(1,3)).to be_a(Rational)
expect(Rational(2)).to eq(2)
end
end
context '演算' do
it 'Rational同士で演算できること' do
expect(Rational(1,3)+Rational(1,2)).to eq(Rational(5,6))
expect(Rational(1,3)+Rational(2,3)).to eq(Rational(1,1))
end
it 'RationalとIntegerで演算するとRationalクラスになること' do
expect(Rational(1,3)+1).to eq(Rational(4,3))
end
it 'RationalとFloatで演算するとFloatクラスになること' do
expect(Rational(1,2)+0.25).to eq(0.75)
end
end
context '分子(numerator),分母(denominator)' do
it 'それぞれ取得できること' do
expect(Rational(1,3).numerator).to eq(1)
expect(Rational(1,3).denominator).to eq(3)
end
end
context '除算' do
it 'divmodを利用すると除算した結果とあまりが配列でかえってくること' do
expect(Rational(4,3).divmod(2)).to eq([0,Rational(4,3)])
expect(Rational(8,3).divmod(2)).to eq([1,Rational(2,3)])
end
end
end
__END__
floor,ceil,truncate,roundが使える
# coding: utf-8
require 'rspec'
describe Regexp do
context '生成' do
let(:regexp) {Regexp.new('abc', Regexp::IGNORECASE | Regexp::MULTILINE | Regexp::EXTENDED, 'u')}
it '第一引数に対象文字列、第二引数にオプション、第三引数に文字コードを指定できること' do
expect(regexp).to be_a(Regexp)
expect(Regexp.compile('abc', Regexp::IGNORECASE | Regexp::MULTILINE | Regexp::EXTENDED, 'u')).to be_a(Regexp)
end
it 'optionsでオプションが取得できること' do
expect(regexp.options).to eq(7)
expect(regexp.options & Regexp::IGNORECASE).to be_true
expect(regexp.options & Regexp::MULTILINE).to be_true
expect(regexp.options & Regexp::EXTENDED).to be_true
end
it 'casefold?で大文字小文字のオプションを設定しているかわかること' do
expect(regexp).to be_casefold
end
it 'kcodeで文字コードを取得できること' do
if RUBY_VERSION < '1.9'
expect(regexp.kcode).to eq('utf8')
end
end
it 'sourceで文字列を取得できること' do
expect(regexp.source).to eq('abc')
end
end
context 'マッチ' do
it 'matchメソッドが使えること' do
expect(/abc/imx.match('ABC')).to be_a(MatchData)
expect(/abc/imx.match('hoge')).to be_nil
end
it '=~メソッドが使えること' do
if RUBY_VERSION < '1.9'
expect(/abc/imx =~ 'aapABC').to be(3)
end
expect(/abc/imx =~ 'hoge').to be_nil
end
it '===メソッドでtrue or falseを返すこと' do
expect(/abc/imx === 'aapABC').to be_true
expect(/abc/imx === 'hoge').to be_false
end
it '~メソッドで$_とマッチングすること' do
$_ = 'abcABC'
expect(~ /abc/imx).to be_zero
end
it 'unionが使えること' do
hoge = Regexp.new('(abc)')
moge = Regexp.new('(def)')
fuga = Regexp.union(hoge, moge)
puts fuga.inspect
expect(fuga === 'abcdef').to be_true
expect($~.to_a).to eq(['abc','abc',nil])
end
end
context '特殊文字のエスケープ' do
it 'escape,quoteでできること' do
expect(Regexp.escape('.([])')).to eq("\\.\\(\\[\\]\\)")
expect(Regexp.quote('.([])')).to eq("\\.\\(\\[\\]\\)")
end
end
context '正規表現にマッチした場合' do
before do
/(bb)/ =~ 'aabbcc'
end
it '$~,Regexp.last_matchでデータを取得できること' do
expect($~).to be_a(MatchData)
expect(Regexp.last_match).to be_a(MatchData)
end
it '$`にマッチした前の文字列がセットされていること' do
expect($`).to eq('aa')
end
it '$&にマッチした文字列がセットされていること' do
expect(Regexp.last_match(0)).to eq('bb')
expect(Regexp.last_match(1)).to eq('bb')
expect($&).to eq('bb')
end
it "$'にマッチした後の文字列がセットされていること" do
expect($').to eq('cc')
end
end
context '{}' do
context '正確な回数を指定した場合' do
it 'マッチすること' do
expect(/aab{3}c/).to match('aabbbc')
end
end
context '正確な回数より少ない場合' do
it 'マッチしないこと' do
expect(/aab{3}c/).to_not match('aabbc')
end
end
context '最低回数を指定した場合' do
it 'マッチすること' do
expect(/aab{3,}c/).to match('aabbbbbbbbbbbbc')
end
end
context '最低回数及び最高回数を指定し、かつ最高回数を最低回数を下回るものを指定した場合' do
it 'SyntaxErrorが発生すること' do
expect { eval('/aab{3,2}c/') }.to raise_exception(SyntaxError)
end
end
end
end
__END__
生成時のオプション
IGNORECASE(i): 大文字と小文字の区別をしない
MULTILINE(m): .が改行にマッチするようにする
EXTENDED(x): 空白と#から改行までを無視する
. 改行をのぞく任意の1文字。ただしmオプションが指定された場合は改行も。
\d 数字
\D 数字以外
\w 英数字とアンダースコア
\W 英数字とアンダースコア以外
\s 空白文字(\t,\n,\r,\f)
\S 空白以外の文字
\A 先頭文字
\z 末尾文字
\Z 末尾文字で改行出終わっていればその前にマッチ
i 大文字と小文字の区別をしない
o 一度だけ式展開する
x パターン中の空白と改行を無視する
m .を改行にもマッチさせる
# coding: utf-8
require 'rspec'
require 'socket'
require 'fileutils'
describe 'Socket' do
context 'TCPServer' do
it 'サーバが作れてacceptでリクエストを受け付けれてputsでレスポンスを作れること' do
f = Fiber.new do
s = TCPServer.new 8081 # openでもいい
loop do
Fiber.yield
client = s.accept
client.puts 'Pochi'
client.close
end
end
f.resume
client = TCPSocket.new 'localhost', 8081
f.resume
expect(client.gets).to eq("Pochi\n")
end
end
context 'UDPSocket' do
it 'サーバが作れてリクエストを受け付けれること(recvでデータを受け取る)' do
s = UDPSocket.new
s.bind('0.0.0.0', 8082)
c = UDPSocket.new
w = Socket.pack_sockaddr_in(8082,'0.0.0.0')
c.send('Pochi',0,w)
c.close
expect(s.recv(5)).to eq('Pochi')
end
end
context 'UNIXSocket' do
before { FileUtils.rm('pochi_socket') if File.exists?('pochi_socket') }
it 'サーバが作れてacceptでリクエストを受け付けれてputsでレスポンスを作れること' do
socket_name = 'pochi_socket'
s = UNIXServer.new socket_name # openでもいい
c = UNIXSocket.new socket_name
a = s.accept
a.puts 'Pochi'
expect(c.gets).to eq("Pochi\n")
end
end
end
# coding: utf-8
require 'rspec'
def capture(stream)
begin
stream = stream.to_s
eval "$#{stream} = StringIO.new"
yield
result = eval("$#{stream}").string
ensure
eval("$#{stream} = #{stream.upcase}")
end
result
end
describe String do
it '%で文字列が作成できること' do
expect(%[hoge]).to eq('hoge')
end
context '文字列の結合' do
it 'スペースで文字列が結合できること' do
expect('hoge' 'moge').to eq('hogemoge')
end
end
context '数値への変換' do
it '数値に変換できない部分は切り捨てられること' do
expect('123abc3'.to_i).to eq(123)
end
end
context 'length' do
it '英数字は1byteとして計算されること' do
expect('a12s'.length).to eq(4)
end
it '日本語は1byteとして計算されること' do
# 1.9.2だと7文字と計算される
if RUBY_VERSION >= '1.9'
expect('ほげ111ほげ'.length).to eq(7)
else
expect('ほげ111ほげ'.length).to eq(15)
end
end
end
context '比較' do
it '==は違う型のオブジェクトと比較できること' do
expect('100'==100).to be_false
end
it 'それ以外の比較演算子はArgumentErrorを返すこと' do
expect{'100'>=100}.to raise_exception(ArgumentError)
end
end
context '文字列の分割' do
let(:current) {'abcdefg'}
it 'sliceには正規表現が使えること' do
expect(current.split(/d/)).to eq(['abc', 'efg'])
end
it 'slice!を利用すると取り除いた文字列が取得できること' do
current.slice!(4)
expect(current).to eq('abcdfg')
end
it 'slice!にはRangeオブジェクトがつかえること' do
current.slice!(1..3)
expect(current).to eq('aefg')
end
it '範囲指定が第一引数:開始位置,第二引数:文字個数で指定できること' do
current.slice!(1,3)
expect(current).to eq('aefg')
end
it '文字列で指定できること' do
expect(current['bc']).to eq('bc')
expect(current['hoge']).to be_nil
current.slice!('bcdefg')
expect(current).to eq('a')
end
it '文字列の変更ができること([]=, insert)' do
current[0..2]='a'
expect(current).to eq('adefg')
current.insert(2, 'bbb')
expect(current).to eq('adbbbefg')
end
end
context 'sub, gsub' do
let(:current) {'abcdefg'}
it 'ブロックがとれること' do
expect(current.sub(/abc/) {|s| 'xxx'}).to eq('xxxdefg')
end
end
context 'tr, tr_s' do
it '文字列を検索して置換できること' do
expect('aabbccdd'.tr('a-d', 'A-D')).to eq('AABBCCDD')
expect('aabbccddaa'.tr('aa', 'AA')).to eq('AAbbccddAA')
end
it 'tr_sは重複文字列を圧縮すること' do
expect('aabbccdd'.tr_s('a-d', 'a-d')).to eq('abcd')
expect('aabbccddaa'.tr_s('a-d', 'a-d')).to eq('abcda')
end
end
context 'delete' do
it '引数に複数パターンを指定できること' do
expect('aaabbbcccddd'.delete('a-d','c-e','d-z')).to eq('aaabbbccc')
expect('aaabbbcccddd'.delete('a')).to eq('bbbcccddd')
end
end
context 'squeeze' do
it '複数並んでいる文字を圧縮できること' do
expect('aaabbb'.squeeze).to eq('ab')
expect('aaabbb'.squeeze('a')).to eq('abbb')
expect('aaabbb'.squeeze('a-b', 'b-c')).to eq('aaab')
end
end
context 'replace' do
it '自身を書き換えること' do
expect('aaa'.replace('bbb')).to eq('bbb')
hoge = 'hoge'
hoge.freeze
expect{hoge.replace('hoge')}.to raise_exception(RuntimeError)
end
end
context '+,<<,concat,*' do
it '文字列を追加できること(オブジェクトIDはかわる)' do
expect('a'+'b').to eq('ab')
expect('a'<<'b').to eq('ab')
expect('a'.concat('b')).to eq('ab')
expect('a'*2).to eq('aa')
hoge = 'a'
hoge_id = hoge.object_id
hoge += 'bbb'
expect(hoge_id).to_not eq(hoge.object_id)
end
end
context '大文字小文字への変換(capitalize, upcase, downcase, swapcase)' do
it '変換できること' do
expect('aaaBBB'.capitalize).to eq('Aaabbb')
expect('aaaBBB'.swapcase).to eq('AAAbbb')
end
end
context '先頭及び末尾にある空白と改行を削除(chomp,strip,lstrip,rstrip,chop)' do
it '取り除けること' do
expect("aaa\n".chomp).to eq('aaa')
expect(" aaa\n".strip).to eq('aaa')
expect(" aaa\n".lstrip).to eq("aaa\n")
expect(" aaa\n".rstrip).to eq(" aaa")
expect("aaa".chop).to eq('aa')
end
end
context '文字列の長さ' do
it 'countを使うとパターン別の文字数をカウントできること' do
expect('aabbcc'.count('a')).to eq(2)
expect('aabbcc'.count('a-c')).to eq(6)
end
end
context '文字列の割当(center, ljust, rjust)' do
it 'センター、左よせ、右よせがそれぞれできること' do
expect('aaa'.center(10,'-')).to eq('---aaa----')
expect(' aaa '.ljust(10,'-')).to eq(' aaa --')
expect(' aaa '.rjust(10,'-')).to eq('-- aaa ')
end
end
context '文字列をそのまま表示' do
it 'dumpを使うこと' do
expect(capture(:stdout) {puts "aa\tbb".dump}).to eq("\"aa\\tbb\"\n")
end
end
context '文字列の検索(include,index,match,scan)' do
it '検索できること' do
expect('aaa'.include?('aa')).to be_true
expect('aabbcc'.index('bb')).to eq(2)
expect('aabbcc'.match('bb')).to be_a(MatchData)
expect('aabbcc'.scan(/[a-c]/)).to eq(['a','a','b','b','c','c'])
end
end
context '次の文字列' do
it 'それっぽくやってくれること' do
expect('aaa'.next).to eq('aab')
expect('zzz'.succ).to eq('aaaa')
expect('xyz'.next).to eq('xza')
end
end
context '他のクラスへの置換' do
it 'hexは16真数として数値に変換すること' do
expect('0010'.hex).to eq(16)
end
it 'octは8真数として数値に変換すること' do
expect('0010aaa'.oct).to eq(8)
end
it 'to_iは10真数として数値に変換すること(それ以外は無視する)' do
expect('10hoge0010'.to_i).to eq(10)
expect('aaa10hoge0010'.to_i).to eq(0)
end
it 'intern(to_sym)メソッドでシンボルにできること' do
expect('10'.intern).to eq(:'10')
end
end
end
# coding: utf-8
require 'rspec'
require 'stringio'
describe StringIO do
let(:io) {StringIO.new}
context '初期化' do
it '生成できること' do
expect(io).to be_a(StringIO)
end
it '文字列を読み込めること' do
expect(StringIO.open('pochi') {|io| io.read}).to eq('pochi')
end
end
context '文字列の書き込み' do
it 'putcで書き込めること' do
io.putc 'a'
expect(io.string).to eq('a')
io.putc 'bcd' # putcは一文字だけ
expect(io.string).to eq('ab')
io.string = '' # 初期化
expect(io.string).to be_empty
end
it 'putsで書き込めること' do
io.puts ['pochi','cute']
expect(io.string).to eq("pochi\ncute\n")
io.string = ''
if RUBY_VERSION < '1.9'
io.puts nil
# nilを入れると文字列が入る
expect(io.string).to eq("nil\n")
end
end
it 'printで書き込めること' do
io.print 'pochi', ' is ', 'cute'
expect(io.string).to eq("pochi is cute")
end
it 'printfで書き込めること' do
io.printf("%05d", 10)
expect(io.string).to eq("00010")
end
end
context '文字列の読み込み' do
it 'readでポインタ分読み込めること' do
io.string = 'pochi is cute.'
expect(io.read(5)).to eq('pochi')
expect(io.read).to eq(' is cute.')
expect(io.read).to eq('')
expect(io.read(3)).to be_nil
end
it 'getcで一文字読み込めること' do
io.string = 'pochi is cute.'
expect(io.getc).to eq('p')
io.pos = io.string.length
expect(io.getc).to be_nil
end
it 'readcharで一文字読み込めること' do
io.string = 'pochi is cute.'
expect(io.readchar).to eq('p')
io.pos = io.string.length
expect{io.readchar}.to raise_exception(EOFError)
end
it 'getsで一行読み込めること' do
io.string = 'pochi is cute.'
expect(io.gets).to eq('pochi is cute.')
expect(io.gets).to be_nil
end
it 'readlineで一行読み込めること' do
io.string = 'pochi is cute.'
expect(io.readline).to eq('pochi is cute.')
expect{io.readline}.to raise_exception(EOFError)
end
it 'seekで移動できること' do
io.string = 'pochi is cute.'
io.seek(3)
expect(io.getc).to eq('h')
io.seek(-2, IO::SEEK_CUR)
expect(io.getc).to eq('c')
io.seek(-1, IO::SEEK_END)
expect(io.getc).to eq('.')
end
end
end
# coding: utf-8
require 'rspec'
describe Symbol do
context '生成' do
it 'テンプレート文字列を利用できること' do
hoge = 'hoge'
expect(:"#{hoge}moge").to eq(:hogemoge)
end
it '%s記法で作成できること' do
expect(%s?hoge?).to eq(:hoge)
end
it '何度作ってもidが同じなこと' do
expect(:hoge.object_id).to eq(:hoge.object_id)
end
end
context '取得' do
it 'all_symbolsで取得できること' do
expect(Symbol.all_symbols).to be_a(Array)
end
it 'to_s, id2nameで文字列を取得できること' do
expect(:hoge.id2name).to eq('hoge')
end
end
end
# coding: utf-8
require 'rspec'
def capture(stream)
begin
stream = stream.to_s
eval "$#{stream} = StringIO.new"
yield
result = eval("$#{stream}").string
ensure
eval("$#{stream} = #{stream.upcase}")
end
result
end
describe Thread do
context '初期化' do
it '引数にブロックを渡せること' do
expect(Thread.new(3) { |t| t }).to be_a(Thread)
end
end
context '状態' do
it 'statusで調べられること' do
if RUBY_VERSION < '1.9'
t = Thread.new { sleep 100 }
expect(t.status).to eq('sleep')
expect(t).to be_alive
t = Thread.new { Thread.stop }
expect(t.status).to eq('sleep')
expect(t).to_not be_alive
end
end
end
context '実行' do
it 'Threadが実行できること' do
t = Thread.new { puts 'pochi' }
expect(capture(:stdout) {t.run}).to eq("pochi\n")
end
end
context '終了' do
it 'exitで終了できること' do
t = Thread.new { Thread.exit; expect(t.status).to eq('dead') }
t.join
end
it 'ensureが実行されること' do
t = Thread.new do
begin
'hoge'
ensure
print 'pochi'
end
end
expect(capture(:stdout) {t.join}).to eq('pochi')
end
end
context 'list' do
it 'リストが取得できること' do
expect(Thread.list).to eq([Thread.main])
end
end
context 'pass' do
it '他のThreadに実行権を渡せること' do
end
end
context 'priority' do
it '優先度を設定できること' do
t = Thread.new {}
t.priority = 1000
if RUBY_VERSION < '1.9'
expect(t.priority).to eq(1000)
end
end
end
context '固有のデータ' do
it 'Hash形式でセットできること' do
t = Thread.current
t[:hoge] = 'moge'
expect(t[:hoge]).to eq('moge')
expect(t.key?(:hoge)).to be_true
end
it 'keysで一覧を取得できること' do
t = Thread.current
expect(t.keys).to eq([:__recursive_key__, :hoge])
end
end
context '排他制御' do
it 'Thread.exclusiveを利用して排他制御できること' do
t1 = Thread.new do
Thread.exclusive do
3.times {|_| print '1' }
end
end
t2 = Thread.new do
Thread.exclusive do
3.times {|_| print '2' }
end
end
expect(capture(:stdout) { t1.join; t2.join }).to eq('111222')
end
# try_lockはロックされていると例外がおこる
it 'Mutex.lockを使って排他制御できること' do
m = Mutex.new
t1 = Thread.new do
m.synchronize do
3.times do |_|
print '1'
end
end
end
t2 = Thread.new do
m.synchronize do
3.times do |_|
print '2'
end
end
end
expect(capture(:stdout) { t1.join; t2.join }).to eq('111222')
end
it 'Mutex.try_lockはロックされているとfalseがかえること' do
m = Mutex.new
t1 = Thread.new { m.try_lock; sleep 1 }
t2 = Thread.new { puts m.try_lock }
expect(capture(:stdout) {t1.join; t2.join}).to eq("false\n")
end
it 'Mutex.locked?で確認できること' do
m = Mutex.new
t1 = Thread.new { puts m.locked?; m.try_lock; sleep 1 }
t2 = Thread.new { puts m.locked? }
expect(capture(:stdout) {t1.join; t2.join}).to eq("false\ntrue\n")
end
end
end
__END__
スレッド中例外が発生したときにプログラムを終了させるには以下の条件のいずれかを設定する
1. Thread.abort_on_exceptionをtrueにする
2. 特定のスレッドのabort_on_exceptionメソッドにtrueをセットする
3. グローバル変数$DEBUGをtrueにしてプログラムを-dで実行する
# coding: utf-8
require 'rspec'
require 'date'
describe Date do
context 'Timeで扱えない範囲を扱えること' do
it '' do
if RUBY_VERSION < '1.9'
expect{ Time.now + 30 * 365 * 24 * 3600 }.to raise_exception(RangeError)
expect{ Date.now + 30 * 365 * 24 * 3600 }.to_not raise_exception
end
end
end
context '演算' do
it 'Rationalクラスで返却されること' do
expect( Date.parse('2013-01-03') - Date.parse('2013-01-01')).to be_a(Rational)
end
end
context '生成' do
it 'civil(year,month,day),newで生成できること' do
expect(Date.civil(2013,1,1)).to be_a(Date)
expect(Date.new(2013,1,1)).to be_a(Date)
end
it 'parse,strptimeで生成できること' do
expect(Date.parse('2011-01-01').year).to eq(2011)
expect(Date.strptime('11-01-01').year).to eq(11)
end
it 'parseで年を二桁でいれて第二引数をtrueにするとそれっぽく補完してくれる' do
expect(Date.parse('11-01-01',true).year).to eq(2011) # 第二引数にtrueを入れると年が2桁でもそれっぽく補完してくれる。strptimeではできない
expect(Date.parse('69-01-01',true).year).to eq(1969) # 第二引数にtrueを入れると年が2桁でもそれっぽく補完してくれる。strptimeではできない
expect(Date.parse('68-01-01',true).year).to eq(2068) # 第二引数にtrueを入れると年が2桁でもそれっぽく補完してくれる。strptimeではできない
end
it 'strptimeは第二引数にフォーマットを指定できること' do
expect(Date.strptime('2011/01/01', "%Y/%m/%d").year).to eq(2011)
end
it 'todayで本日を取得できること' do
expect(Date.today).to be_a(Date)
end
it 'to_s,strftimeで文字列として取得できること' do
expect(Date.parse('2011-01-01').to_s).to eq('2011-01-01')
end
end
context '日付の移動' do
it 'next,succで次の日に移動できること' do
expect(Date.today.succ - Date.today).to eq(Rational(1,1))
expect(Date.today.next - Date.today).to eq(Rational(1,1))
end
it 'step(limit, step)でイテレートできること' do
s = Date.civil(2013,1,1)
e = Date.civil(2013,1,4)
i = []
s.step(e,1) {|e| i << e}
expect(i).to eq([Date.parse('2013-01-01'),Date.parse('2013-01-02'),Date.parse('2013-01-03'),Date.parse('2013-01-04')])
end
it 'downto(min)でイテレートできること' do
s = Date.civil(2013,1,1)
e = Date.civil(2013,1,4)
i = []
e.downto(s) {|e| i << e}
expect(i).to eq([Date.parse('2013-01-01'),Date.parse('2013-01-02'),Date.parse('2013-01-03'),Date.parse('2013-01-04')].reverse)
end
it 'upto(max)でイテレートできること' do
s = Date.civil(2013,1,1)
e = Date.civil(2013,1,4)
i = []
s.upto(e) {|e| i << e}
expect(i).to eq([Date.parse('2013-01-01'),Date.parse('2013-01-02'),Date.parse('2013-01-03'),Date.parse('2013-01-04')])
end
end
context '日付チェック' do
it 'leap?で閏年かどうかチェックできること' do
expect(Date.civil(2013,1,1)).to_not be_leap
end
end
end
describe DateTime do
context '生成' do
it 'civil,newで生成できること' do
expect(DateTime.civil).to be_a(DateTime)
expect(DateTime.new).to be_a(DateTime)
end
it 'DateTime.nowで現在時刻を作れること' do
expect(DateTime.now).to be_a(DateTime)
end
end
context 'zoneとoffsetの違い' do
it 'zoneは文字列' do
expect(DateTime.now.zone).to eq('+09:00')
end
it 'offsetはRational' do
expect(DateTime.now.offset).to eq(Rational(3,8))
end
end
end
# coding: utf-8
require 'rspec'
require 'uri'
describe URI do
context 'URI, parse' do
it '解析できること' do
uri = URI("https://gist.github.com/pochi/5475961")
expect(uri.scheme).to eq('https')
expect(uri.host).to eq('gist.github.com')
expect(uri.port).to eq(443)
expect(uri.path).to eq('/pochi/5475961')
end
it '解析できない場合URI::InvalidURIErrorが発生すること' do
expect { URI("https://gist.___github.com/pochi/5475961") }.to raise_exception(URI::InvalidURIError)
end
end
context 'split' do
it 'URIを配列に分割できること[scheme,userinfo,host,port,registory,path,opaque,query,fragment]' do
expect(URI.split("https://gist.github.com/pochi/5475961")).to eq(['https',nil,'gist.github.com', nil, nil, "/pochi/5475961", nil, nil, nil])
end
end
context 'escape,encode' do
it 'デフォルト文字コードでエスケープされること' do
expect(URI.escape("https://gist.github.com/ぽち/5475961")).to eq('https://gist.github.com/%E3%81%BD%E3%81%A1/5475961')
expect(URI.encode("https://gist.github.com/ぽち/5475961")).to eq('https://gist.github.com/%E3%81%BD%E3%81%A1/5475961')
end
end
context 'unescape,decode' do
it 'デコードできること' do
escapse_uri = 'https://gist.github.com/%E3%81%BD%E3%81%A1/5475961'
expect(URI.decode(escapse_uri)).to eq('https://gist.github.com/ぽち/5475961')
expect(URI.unescape(escapse_uri)).to eq('https://gist.github.com/ぽち/5475961')
end
end
end
__END__
http
https
ftp
ldap
ldaps
mailto
に対応しており、プロトコルを見て勝手に判断してくれる
# coding: utf-8
require 'rspec'
describe 'while' do
it 'begin endで後置whileが実現できること' do
i = 0
begin
i = i.next
end while i != 3
expect(i).to eq(3)
end
end
# coding: utf-8
require 'rspec'
require 'yaml'
describe YAML do
before do
File.open('pochi.yaml', 'w+') {|f| f.puts data}
end
let(:data) do
<<-YAML
- Dog
- Cat
---
- Pochi
YAML
end
context 'データの読み込み' do
it 'loadでデータを読み込めること' do
expect(YAML.load(data)).to eq(['Dog','Cat'])
end
it 'load_fileからデータを読み込めること' do
expect(YAML.load_file('pochi.yaml')).to eq(['Dog','Cat'])
end
it 'load_streamからデータを読み込めること' do
expect(YAML.load_stream(File.open 'pochi.yaml')).to eq([['Dog','Cat'], ['Pochi']])
end
it 'load_documentsからデータを読み込めること' do
expect(YAML.load_documents(File.open 'pochi.yaml') {|y| y} ).to eq([['Dog','Cat'], ['Pochi']])
end
end
context 'データの書き込み' do
it 'dumpで出力できること' do
expect(YAML.dump(YAML.load(data))).to eq("---\n- Dog\n- Cat\n")
end
it 'dumpの第二引数にioオブジェクトを渡せること' do
if RUBY_VERSION < '1.9'
YAML.dump(YAML.load(data), File.open('pochi.yaml', 'w+'))
puts File.open('pochi.yaml').read
expect(File.open('pochi.yaml').read).to eq("---\n- Dog\n- Cat\n")
end
end
it 'dump_streamで複数オブジェクトを指定できること' do
expect(YAML.dump_stream(['pochi'],['cute'])).to eq("---\n- pochi\n---\n- cute\n")
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment