# encoding: UTF-8 require File.expand_path(File.dirname(__FILE__) + '/spec_helper') module ICU class Tournament describe ForeignCSV do def check_player(num, first, last, results, rateable, points, other={}) p = @t.player(num) p.first_name.should == first p.last_name.should == last p.id.should == other[:id] p.fide_rating.should == other[:fide_rating] p.fed.should == other[:fed] p.title.should == other[:title] p.results.size.should == results p.results.select{|r| r.rateable}.size.should == rateable p.points.should == points end context "a typical tournament" do before(:all) do @csv = < 3364) check_player(2, 'April', 'Cronin', 1, 0, 1.0, :fide_rating => 2005, :fed => 'IRL') check_player(3, 'Suzanne', 'Connolly', 1, 0, 0.5, :fide_rating => 1950, :fed => 'IRL') check_player(4, 'Linda', 'Powell', 1, 0, 0.0, :fide_rating => 1850, :fed => 'WLS') end end context "the rdoc example tournament" do before(:all) do @csv = < 3364) check_player(4, 'Mark', 'Orr', 2, 2, 1.5, :id => 1350) check_player(2, 'Gary', 'Kasparov', 1, 0, 0.5, :fide_rating => 2800, :fed => 'RUS', :title => 'GM') check_player(3, 'April', 'Cronin', 2, 0, 1.0, :fide_rating => 2005, :fed => 'IRL') check_player(5, 'Bobby', 'Fischer', 1, 0, 0.0, :fide_rating => 2700, :fed => 'USA', :title => 'GM') end end context "a tournament where someone is both a player and an opponent" do before(:all) do @csv = < 1800, :fed => 'IRL', :id => 3364) check_player(3, 'Mark', 'Orr', 2, 2, 1.0, :fide_rating => 2100, :fed => 'IRL', :id => 1350, :title => 'IM') check_player(2, 'Gary', 'Kasparov', 1, 0, 0.5, :fide_rating => 2800, :fed => 'RUS') check_player(4, 'April', 'Cronin', 1, 0, 0.5, :fide_rating => 2005, :fed => 'IRL') end end context "a file that contains spurious white space and other untidiness" do before(:all) do @csv = < 3364) check_player(2, 'Gary', 'Kasparov', 1, 0, 0.5, :fide_rating => 2800, :fed => 'RUS', :title => 'GM') check_player(3, 'Mark', 'Orr', 1, 0, 0.5, :fide_rating => 2100, :fed => 'IRL', :title => 'IM') end it "should still have original names" do @t.player(1).original_name.should == "ui Laighleis, gearoidin" @t.player(2).original_name.should == "kasparov, gary" @t.player(3).original_name.should == "Orr, Mark" end end context "#parse" do before(:each) do @f = ICU::Tournament::ForeignCSV.new end it "should behave just like #parse! on success" do csv = < 456, :fide_rating => 2100, :fed => 'IRL')) @t.add_player(ICU::Player.new('Peter', 'Cafolla', 2, :id => 159, :fide_rating => 2048, :fed => 'IRL')) @t.add_player(ICU::Player.new('Peter P.', 'Taylor', 3, :fide_rating => 2209, :fed => 'ENG')) @t.add_player(ICU::Player.new('Egozi', 'Nadav', 4, :fide_rating => 2205, :fed => 'ISR')) @t.add_player(ICU::Player.new('Tim R.', 'Spanton', 5, :fide_rating => 1982, :fed => 'ENG')) @t.add_player(ICU::Player.new('Alan', 'Grant', 6, :fide_rating => 2223, :fed => 'SCO')) @t.add_player(ICU::Player.new('Alan J.', 'Walton', 7, :fide_rating => 2223, :fed => 'ENG')) @t.add_player(ICU::Player.new('Bernard', 'Bannink', 8, :fide_rating => 2271, :fed => 'NED', :title => 'FM')) @t.add_player(ICU::Player.new('Roy', 'Phillips', 9, :fide_rating => 2271, :fed => 'MAU')) @t.add_player(ICU::Player.new('Oliver A.', 'Jackson', 10, :fide_rating => 2198, :fed => 'ENG')) @t.add_player(ICU::Player.new('Van Den Berssalaar', 'Jeroen', 11, :fed => 'NED')) @t.add_player(ICU::Player.new('Sam E.', 'Collins', 12, :fide_rating => 2394, :fed => 'IRL', :title => 'IM')) @t.add_player(ICU::Player.new('Doreen', 'Troyke', 13, :fide_rating => 2151, :fed => 'GER', :title => 'WFM')) @t.add_player(ICU::Player.new('Jonathan P.', 'Nelson', 14, :fide_rating => 2282, :fed => 'ENG')) @t.add_player(ICU::Player.new('Nadav', 'Egozi', 15, :fide_rating => 2205, :fed => 'ISR')) @t.add_player(ICU::Player.new('Manuel', 'Weeks', 16, :fide_rating => 2200, :fed => 'AUS', :title => 'FM')) @t.add_player(ICU::Player.new('Alan', 'Grant', 17, :fide_rating => 2223, :fed => 'SCO')) @t.add_result(ICU::Result.new(1, 1, 'L', :opponent => 3, :colour => 'B')) @t.add_result(ICU::Result.new(2, 1, 'D', :opponent => 4, :colour => 'W')) @t.add_result(ICU::Result.new(3, 1, 'D', :opponent => 2, :colour => 'B')) @t.add_result(ICU::Result.new(4, 1, 'W', :opponent => 5, :colour => 'W')) @t.add_result(ICU::Result.new(5, 1, 'W', :opponent => 6, :colour => 'B')) @t.add_result(ICU::Result.new(6, 1, 'L')) @t.add_result(ICU::Result.new(7, 1, 'D', :opponent => 7, :colour => 'W')) @t.add_result(ICU::Result.new(8, 1, 'L', :opponent => 8, :colour => 'B')) @t.add_result(ICU::Result.new(9, 1, 'D', :opponent => 9, :colour => 'W')) @t.add_result(ICU::Result.new(1, 2, 'L', :opponent => 10, :colour => 'W')) @t.add_result(ICU::Result.new(2, 2, 'L', :opponent => 11, :colour => 'B')) @t.add_result(ICU::Result.new(3, 2, 'D', :opponent => 1, :colour => 'W')) @t.add_result(ICU::Result.new(4, 2, 'D', :opponent => 12, :colour => 'B')) @t.add_result(ICU::Result.new(5, 2, 'W', :opponent => 13, :colour => 'W')) @t.add_result(ICU::Result.new(6, 2, 'D', :opponent => 14, :colour => 'B')) @t.add_result(ICU::Result.new(7, 2, 'L', :opponent => 15, :colour => 'W')) @t.add_result(ICU::Result.new(8, 2, 'D', :opponent => 16, :colour => 'B')) @t.add_result(ICU::Result.new(9, 2, 'L', :opponent => 17, :colour => 'W')) end it "should serialize to the expected string" do @t.serialize('ForeignCSV').should == @csv end end context "serialisation of shortened ForeignCSV documentation example" do before(:each) do @csv = < 456, :fide_rating => 2100, :fed => 'IRL')) @t.add_player(ICU::Player.new('Peter P.', 'Taylor', 2, :fide_rating => 2209, :fed => 'ENG')) @t.add_player(ICU::Player.new('Egozi', 'Nadav', 3, :fide_rating => 2205, :fed => 'ISR')) @t.add_player(ICU::Player.new('Peter', 'Cafolla', 4, :fide_rating => 2048, :fed => 'IRL')) @t.add_player(ICU::Player.new('Tim R.', 'Spanton', 5, :fide_rating => 1982, :fed => 'ENG')) @t.add_player(ICU::Player.new('Alan', 'Grant', 6, :fide_rating => 2223, :fed => 'SCO')) @t.add_player(ICU::Player.new('Alan J.', 'Walton', 7, :fide_rating => 2223, :fed => 'ENG')) @t.add_player(ICU::Player.new('Bernard', 'Bannink', 8, :fide_rating => 2271, :fed => 'NED', :title => 'FM')) @t.add_player(ICU::Player.new('Roy', 'Phillips', 9, :fide_rating => 2271, :fed => 'MAU')) @t.add_result(ICU::Result.new(1, 1, 'L', :opponent => 2, :colour => 'B')) @t.add_result(ICU::Result.new(2, 1, 'D', :opponent => 3, :colour => 'W')) @t.add_result(ICU::Result.new(3, 1, 'D', :opponent => 4, :colour => 'B')) @t.add_result(ICU::Result.new(4, 1, 'W', :opponent => 5, :colour => 'W')) @t.add_result(ICU::Result.new(5, 1, 'W', :opponent => 6, :colour => 'B')) @t.add_result(ICU::Result.new(6, 1, 'L')) @t.add_result(ICU::Result.new(7, 1, 'D', :opponent => 7, :colour => 'W')) @t.add_result(ICU::Result.new(8, 1, 'L', :opponent => 8, :colour => 'B')) @t.add_result(ICU::Result.new(9, 1, 'D', :opponent => 9, :colour => 'W')) @t.validate! end it "should serialize to the expected string" do @t.serialize('ForeignCSV').should == @csv end end context "encoding" do before(:each) do @csv = < 3364) check_player(2, 'Gary', 'Kasparov', 1, 0, 0.5, :fide_rating => 2800, :fed => 'RUS', :title => 'GM') check_player(3, 'Mârk', 'Örr', 1, 0, 0.5, :fide_rating => 2100, :fed => 'IRL', :title => 'IM') @t.name.should == "Brätto Open, 2001" end it "should parse Latin-1" do @csv = @csv.encode("ISO-8859-1") lambda { @t = @f.parse!(@csv) }.should_not raise_error check_player(1, 'Gearoìdin', 'Uì Laighlèis', 2, 2, 1.0, :id => 3364) check_player(2, 'Gary', 'Kasparov', 1, 0, 0.5, :fide_rating => 2800, :fed => 'RUS', :title => 'GM') check_player(3, 'Mârk', 'Örr', 1, 0, 0.5, :fide_rating => 2100, :fed => 'IRL', :title => 'IM') @t.name.should == "Brätto Open, 2001" end end context "parsing files" do before(:each) do @p = ICU::Tournament::ForeignCSV.new @s = File.dirname(__FILE__) + '/samples/fcsv' end it "should error on a non-existant valid file" do file = "#{@s}/not_there.csv" lambda { @p.parse_file!(file) }.should raise_error t = @p.parse_file(file) t.should be_nil @p.error.should match(/no such file/i) end it "should error on an invalid file" do file = "#{@s}/invalid.csv" lambda { @p.parse_file!(file) }.should raise_error t = @p.parse_file(file) t.should be_nil @p.error.should match(/expected.*event.*name/i) end it "should parse a valid file" do file = "#{@s}/valid.csv" lambda { @p.parse_file!(file) }.should_not raise_error t = @p.parse_file(file) t.should be_an_instance_of(ICU::Tournament) t.players.size.should == 16 end it "should parse a file encoded in UTF-8" do file = "#{@s}/utf-8.csv" lambda { @t = @p.parse_file!(file) }.should_not raise_error check_player(1, 'Gearoìdin', 'Uì Laighlèis', 2, 2, 1.0, :id => 3364) check_player(2, 'Gary', 'Kasparov', 1, 0, 0.5, :fide_rating => 2800, :fed => 'RUS', :title => 'GM') check_player(3, 'Mârk', 'Örr', 1, 0, 0.5, :fide_rating => 2100, :fed => 'IRL', :title => 'IM') @t.name.should == "Brätto Open, 2001" end it "should parse a file encoded in Latin-1" do file = "#{@s}/latin-1.csv" lambda { @t = @p.parse_file!(file) }.should_not raise_error check_player(1, 'Gearoìdin', 'Uì Laighlèis', 2, 2, 1.0, :id => 3364) check_player(2, 'Gary', 'Kasparov', 1, 0, 0.5, :fide_rating => 2800, :fed => 'RUS', :title => 'GM') check_player(3, 'Mârk', 'Örr', 1, 0, 0.5, :fide_rating => 2100, :fed => 'IRL', :title => 'IM') @t.name.should == "Brätto Open, 2001" end end context "type validation" do before(:each) do @p = ICU::Tournament::ForeignCSV.new @t = ICU::Tournament.new("Isle of Man Masters, 2007", '2007-09-22') @t.site = 'http://www.bcmchess.co.uk/monarch2007/' @t.add_player(ICU::Player.new('Anthony', 'Fox', 1, :id => 456)) @t.add_player(ICU::Player.new('Peter', 'Cafolla', 2, :id => 159)) @t.add_player(ICU::Player.new('Peter P.', 'Taylor', 10, :fide_rating => 2209, :fed => 'ENG')) @t.add_player(ICU::Player.new('Egozi', 'Nadav', 20, :fide_rating => 2205, :fed => 'ISR')) @t.add_player(ICU::Player.new('Tim R.', 'Spanton', 30, :fide_rating => 1982, :fed => 'ENG')) @t.add_player(ICU::Player.new('Alan', 'Grant', 40, :fide_rating => 2223, :fed => 'SCO')) @t.add_result(ICU::Result.new(1, 1, 'W', :opponent => 10, :colour => 'W')) @t.add_result(ICU::Result.new(1, 2, 'L', :opponent => 20, :colour => 'B')) @t.add_result(ICU::Result.new(2, 1, 'D', :opponent => 30, :colour => 'B')) @t.add_result(ICU::Result.new(2, 2, 'L', :opponent => 40, :colour => 'W')) end it "should pass" do @t.invalid.should be_false @t.invalid(:type => @p).should be_false end it "should fail if there's no site" do @t.site = nil; @t.invalid(:type => @p).to_s.should match(/site/) end it "should fail if there are no ICU players" do [1, 2].each { |n| @t.player(n).id = nil } @t.player(2).id = nil; @t.invalid(:type => @p).to_s.should match(/ID/) end it "should fail unless all foreign players have a federation" do @t.player(10).fed = nil; @t.invalid(:type => @p).to_s.should match(/federation/) end it "should fail unless every ICU player has a result in every round" do @t.add_player(ICU::Player.new('Mark', 'Orr', 3, :id => 1350)) @t.add_result(ICU::Result.new(1, 3, 'W', :opponent => 30, :colour => 'B')) @t.invalid(:type => @p).to_s.should match(/result/) @t.add_result(ICU::Result.new(2, 3, 'W', :opponent => 10, :colour => 'W')) @t.invalid(:type => @p).should be_false end it "should fail unless every ICU player's opponents have a federation" do @t.add_player(ICU::Player.new('Mark', 'Orr', 3, :id => 1350)) @t.add_result(ICU::Result.new(1, 3, 'W', :opponent => 30, :colour => 'B')) @t.add_result(ICU::Result.new(2, 3, 'W', :opponent => 10, :colour => 'W')) @t.add_result(ICU::Result.new(3, 1, 'D', :opponent => 40, :colour => 'W')) @t.add_result(ICU::Result.new(3, 2, 'L', :opponent => 3, :colour => 'B')) @t.invalid(:type => @p).to_s.should match(/opponents.*federation/) @t.player(2).fed = 'IRL' @t.invalid(:type => @p).to_s.should match(/opponents.*federation/) @t.player(3).fed = 'IRL' @t.invalid(:type => @p).should be_false end it "should be serializable unless invalid" do lambda { @p.serialize(@t) }.should_not raise_error @t.site = nil; lambda { @p.serialize(@t) }.should raise_error end end end end end