sgf_parser 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.irbrc +3 -0
- data/.rvmrc +4 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +17 -0
- data/LICENSE +20 -0
- data/README.textile +27 -0
- data/Rakefile +20 -0
- data/TODO +0 -0
- data/VERSION +1 -0
- data/bin/sgf +28 -0
- data/bin/stm2dot +18 -0
- data/doc/sgf_state_machine.dot +58 -0
- data/doc/sgf_state_machine.svg +269 -0
- data/lib/sgf.rb +15 -0
- data/lib/sgf/binary_file_error.rb +4 -0
- data/lib/sgf/debugger.rb +15 -0
- data/lib/sgf/default_event_listener.rb +37 -0
- data/lib/sgf/model/constants.rb +19 -0
- data/lib/sgf/model/event_listener.rb +72 -0
- data/lib/sgf/model/game.rb +52 -0
- data/lib/sgf/model/label.rb +12 -0
- data/lib/sgf/model/node.rb +115 -0
- data/lib/sgf/model/property_handler.rb +51 -0
- data/lib/sgf/more/state_machine_presenter.rb +43 -0
- data/lib/sgf/more/stm_dot_converter.rb +139 -0
- data/lib/sgf/parse_error.rb +25 -0
- data/lib/sgf/parser.rb +56 -0
- data/lib/sgf/renderer.rb +25 -0
- data/lib/sgf/sgf_helper.rb +55 -0
- data/lib/sgf/sgf_state_machine.rb +174 -0
- data/lib/sgf/state_machine.rb +76 -0
- data/sgf_parser.gemspec +95 -0
- data/spec/fixtures/2009-11-01-1.sgf +24 -0
- data/spec/fixtures/2009-11-01-2.sgf +23 -0
- data/spec/fixtures/chinese_gb.sgf +9 -0
- data/spec/fixtures/chinese_utf.sgf +9 -0
- data/spec/fixtures/example.sgf +18 -0
- data/spec/fixtures/good.sgf +55 -0
- data/spec/fixtures/good1.sgf +167 -0
- data/spec/fixtures/kgs.sgf +723 -0
- data/spec/fixtures/test.png +0 -0
- data/spec/sgf/model/event_listener_spec.rb +97 -0
- data/spec/sgf/model/game_spec.rb +29 -0
- data/spec/sgf/model/node_spec.rb +84 -0
- data/spec/sgf/more/state_machine_presenter_spec.rb +29 -0
- data/spec/sgf/parse_error_spec.rb +10 -0
- data/spec/sgf/parser_spec.rb +210 -0
- data/spec/sgf/sgf_helper_spec.rb +68 -0
- data/spec/sgf/sgf_state_machine_spec.rb +166 -0
- data/spec/sgf/state_machine_spec.rb +137 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +47 -0
- metadata +150 -0
| @@ -0,0 +1,68 @@ | |
| 1 | 
            +
            require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module SGF
         | 
| 4 | 
            +
              describe SGFHelper do
         | 
| 5 | 
            +
                before :each do
         | 
| 6 | 
            +
                  @helper = Object.new.extend(SGFHelper)
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                describe "xy_to_sgf_pos" do
         | 
| 10 | 
            +
                  it "should convert x,y to sgf position string like ab" do
         | 
| 11 | 
            +
                    @helper.xy_to_sgf_pos(1, 2).should == "bc"
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                describe "move_to_sgf" do
         | 
| 16 | 
            +
                  it "should convert color, x, y to sgf like ;B[ab]" do
         | 
| 17 | 
            +
                    @helper.move_to_sgf(1, 1, 2).should == ";B[bc]"
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
                
         | 
| 21 | 
            +
                describe "to_position_array" do
         | 
| 22 | 
            +
                  
         | 
| 23 | 
            +
                  [nil, "", "  ", "A", "ABC"].each do |bad_argument|
         | 
| 24 | 
            +
                    it "should throw ArgumentError on bad argument(#{bad_argument.inspect})" do
         | 
| 25 | 
            +
                      lambda { @helper.to_position_array(bad_argument) }.should raise_error(ArgumentError)
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  it "should convert AB to [[0, 1]]" do
         | 
| 30 | 
            +
                    @helper.to_position_array("AB").should == [[0, 1]]
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  it "should be case insensitive" do
         | 
| 34 | 
            +
                    @helper.to_position_array("ab").should == [[0, 1]]
         | 
| 35 | 
            +
                    @helper.to_position_array("aB").should == [[0, 1]]
         | 
| 36 | 
            +
                    @helper.to_position_array("Ab").should == [[0, 1]]
         | 
| 37 | 
            +
                    @helper.to_position_array("AB").should == [[0, 1]]
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                  
         | 
| 40 | 
            +
                  it "should ignore leading and trailing spaces" do
         | 
| 41 | 
            +
                    @helper.to_position_array(" AB").should == [[0, 1]]
         | 
| 42 | 
            +
                    @helper.to_position_array("AB ").should == [[0, 1]]
         | 
| 43 | 
            +
                    @helper.to_position_array(" AB ").should == [[0, 1]]
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
                  
         | 
| 46 | 
            +
                  it "should convert AB:BC to [[0,1], [0,2], [1,1], [1,2]]" do
         | 
| 47 | 
            +
                    @helper.to_position_array("AB:BC").should == [[0,1], [0,2], [1,1], [1,2]]
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                    
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
                
         | 
| 52 | 
            +
                describe "to_position" do
         | 
| 53 | 
            +
                  it "should convert AB to [0, 1]" do
         | 
| 54 | 
            +
                    @helper.to_position("AB").should == [0, 1]
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  it "should be case insensitive" do
         | 
| 58 | 
            +
                    @helper.to_position("ab").should == [0, 1]
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
                
         | 
| 62 | 
            +
                describe "to_label" do
         | 
| 63 | 
            +
                  it "should return label" do
         | 
| 64 | 
            +
                    @helper.to_label("AB:C").should == SGF::Model::Label.new(@helper.to_position("AB"), "C")
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
            end
         | 
| @@ -0,0 +1,166 @@ | |
| 1 | 
            +
            require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module SGF
         | 
| 4 | 
            +
              describe SGFStateMachine do
         | 
| 5 | 
            +
                describe "with no context" do
         | 
| 6 | 
            +
                  before :each do
         | 
| 7 | 
            +
                    @stm = SGFStateMachine.new
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  it "should return state machine for sgf" do
         | 
| 11 | 
            +
                    @stm.class.should == SGFStateMachine
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  it "should have start_state of #{SGFStateMachine::STATE_BEGIN}" do
         | 
| 15 | 
            +
                    @stm.start_state.should == SGFStateMachine::STATE_BEGIN
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                
         | 
| 18 | 
            +
                  [
         | 
| 19 | 
            +
                    [SGFStateMachine::STATE_BEGIN,         '(', SGFStateMachine::STATE_GAME_BEGIN],
         | 
| 20 | 
            +
                    [SGFStateMachine::STATE_GAME_BEGIN,    ';', SGFStateMachine::STATE_NODE],
         | 
| 21 | 
            +
                    [SGFStateMachine::STATE_NODE,          'A', SGFStateMachine::STATE_PROP_NAME_BEGIN],
         | 
| 22 | 
            +
                    [SGFStateMachine::STATE_NODE,          ')', SGFStateMachine::STATE_VAR_END],
         | 
| 23 | 
            +
                    [SGFStateMachine::STATE_PROP_NAME,     'A', SGFStateMachine::STATE_PROP_NAME],
         | 
| 24 | 
            +
                    [SGFStateMachine::STATE_PROP_NAME,     '[', SGFStateMachine::STATE_VALUE_BEGIN],
         | 
| 25 | 
            +
                    [SGFStateMachine::STATE_VALUE_BEGIN,   'A', SGFStateMachine::STATE_VALUE],
         | 
| 26 | 
            +
                    [SGFStateMachine::STATE_VALUE_BEGIN,   ']', SGFStateMachine::STATE_VALUE_END],
         | 
| 27 | 
            +
                    [SGFStateMachine::STATE_VALUE,         ']', SGFStateMachine::STATE_VALUE_END],
         | 
| 28 | 
            +
                    [SGFStateMachine::STATE_VALUE,         '\\', SGFStateMachine::STATE_VALUE_ESCAPE],
         | 
| 29 | 
            +
                    [SGFStateMachine::STATE_VALUE_ESCAPE,  ']', SGFStateMachine::STATE_VALUE],
         | 
| 30 | 
            +
                    [SGFStateMachine::STATE_VALUE_END,     ';', SGFStateMachine::STATE_NODE],
         | 
| 31 | 
            +
                    [SGFStateMachine::STATE_VALUE_END,     '(', SGFStateMachine::STATE_VAR_BEGIN],
         | 
| 32 | 
            +
                    [SGFStateMachine::STATE_VALUE_END,     ')', SGFStateMachine::STATE_VAR_END],
         | 
| 33 | 
            +
                    [SGFStateMachine::STATE_VALUE_END,     'A', SGFStateMachine::STATE_PROP_NAME_BEGIN],
         | 
| 34 | 
            +
                    [SGFStateMachine::STATE_VAR_BEGIN,     ';', SGFStateMachine::STATE_NODE],
         | 
| 35 | 
            +
                    [SGFStateMachine::STATE_VAR_END,       ';', SGFStateMachine::STATE_NODE],
         | 
| 36 | 
            +
                    [SGFStateMachine::STATE_VAR_END,       '(', SGFStateMachine::STATE_VAR_BEGIN]
         | 
| 37 | 
            +
                  ].each do |state_before, input, state_after|
         | 
| 38 | 
            +
                    it "should have transition for '#{state_before}' + '#{input}' => '#{state_after}'" do
         | 
| 39 | 
            +
                      @stm.state = state_before
         | 
| 40 | 
            +
                      @stm.event input
         | 
| 41 | 
            +
                      @stm.state.should == state_after
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                  
         | 
| 45 | 
            +
                  it "end should trigger transition to game_end" do
         | 
| 46 | 
            +
                    @stm.state = SGFStateMachine::STATE_VAR_END
         | 
| 47 | 
            +
                    @stm.end
         | 
| 48 | 
            +
                    @stm.state.should == SGFStateMachine::STATE_GAME_END
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                  
         | 
| 51 | 
            +
                  it "should handle escaped characters" do
         | 
| 52 | 
            +
                    @stm.state = SGFStateMachine::STATE_VALUE
         | 
| 53 | 
            +
                    @stm.event '\\'
         | 
| 54 | 
            +
                    @stm.state.should == SGFStateMachine::STATE_VALUE_ESCAPE
         | 
| 55 | 
            +
                    @stm.event ']'
         | 
| 56 | 
            +
                    @stm.state.should == SGFStateMachine::STATE_VALUE
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
                  
         | 
| 59 | 
            +
                  [
         | 
| 60 | 
            +
                    [SGFStateMachine::STATE_BEGIN           , 'A'],
         | 
| 61 | 
            +
                    [SGFStateMachine::STATE_GAME_BEGIN      , '['],
         | 
| 62 | 
            +
                    [SGFStateMachine::STATE_NODE            , '['],
         | 
| 63 | 
            +
                    [SGFStateMachine::STATE_VAR_BEGIN       , '['],
         | 
| 64 | 
            +
                    [SGFStateMachine::STATE_VAR_END         , '['],
         | 
| 65 | 
            +
                    [SGFStateMachine::STATE_PROP_NAME_BEGIN , ']'],
         | 
| 66 | 
            +
                    [SGFStateMachine::STATE_PROP_NAME       , ']'],
         | 
| 67 | 
            +
                    [SGFStateMachine::STATE_VALUE_END       , ']'],
         | 
| 68 | 
            +
                  ].each do |state_before, input|
         | 
| 69 | 
            +
                    it "should raise error for '#{state_before}' + '#{input}'" do
         | 
| 70 | 
            +
                      @stm.state = state_before
         | 
| 71 | 
            +
                      lambda {
         | 
| 72 | 
            +
                        @stm.event input
         | 
| 73 | 
            +
                      }.should raise_error
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
              
         | 
| 78 | 
            +
                describe "with context" do
         | 
| 79 | 
            +
                  before :each do
         | 
| 80 | 
            +
                    @context = Object.new
         | 
| 81 | 
            +
                    @stm = SGFStateMachine.new
         | 
| 82 | 
            +
                    @stm.context = @context
         | 
| 83 | 
            +
                    @stm.reset
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
                  
         | 
| 86 | 
            +
                  it "Transition to game begin should call context.start_game" do
         | 
| 87 | 
            +
                    mock(@context).start_game
         | 
| 88 | 
            +
                    @stm.state = SGFStateMachine::STATE_BEGIN
         | 
| 89 | 
            +
                    @stm.event "("
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
                  
         | 
| 92 | 
            +
                  it "Transition to node should call context.start_node" do
         | 
| 93 | 
            +
                    mock(@context).start_node
         | 
| 94 | 
            +
                    @stm.state = SGFStateMachine::STATE_GAME_BEGIN
         | 
| 95 | 
            +
                    @stm.event ";"
         | 
| 96 | 
            +
                  end
         | 
| 97 | 
            +
                  
         | 
| 98 | 
            +
                  it "Transition to variation begin should call context.start_variation" do
         | 
| 99 | 
            +
                    mock(@context).start_variation
         | 
| 100 | 
            +
                    @stm.state = SGFStateMachine::STATE_NODE
         | 
| 101 | 
            +
                    @stm.event "("
         | 
| 102 | 
            +
                  end
         | 
| 103 | 
            +
                  
         | 
| 104 | 
            +
                  it "Transition to prop name begin should set store input to buffer" do
         | 
| 105 | 
            +
                    @stm.state = SGFStateMachine::STATE_NODE
         | 
| 106 | 
            +
                    @stm.event "A"
         | 
| 107 | 
            +
                    @stm.buffer.should == "A"
         | 
| 108 | 
            +
                  end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                  it "Transition to prop name from prop name begin should append input to buffer" do
         | 
| 111 | 
            +
                    @stm.buffer = "A"
         | 
| 112 | 
            +
                    @stm.state = SGFStateMachine::STATE_PROP_NAME_BEGIN
         | 
| 113 | 
            +
                    @stm.event "B"
         | 
| 114 | 
            +
                    @stm.buffer.should == "AB"
         | 
| 115 | 
            +
                  end
         | 
| 116 | 
            +
                  
         | 
| 117 | 
            +
                  it "Transition to game variation end should call context.end_variation" do
         | 
| 118 | 
            +
                    mock(@context).end_variation
         | 
| 119 | 
            +
                    @stm.state = SGFStateMachine::STATE_VALUE_END
         | 
| 120 | 
            +
                    @stm.event ")"
         | 
| 121 | 
            +
                  end
         | 
| 122 | 
            +
                  
         | 
| 123 | 
            +
                  it "Transition to value begin should call context.property_name= with buffer" do
         | 
| 124 | 
            +
                    mock(@context).property_name = "AB"
         | 
| 125 | 
            +
                    @stm.buffer = "AB"
         | 
| 126 | 
            +
                    @stm.state = SGFStateMachine::STATE_PROP_NAME
         | 
| 127 | 
            +
                    @stm.event "["
         | 
| 128 | 
            +
                  end
         | 
| 129 | 
            +
                  
         | 
| 130 | 
            +
                  it "Transition to value should store input to buffer" do
         | 
| 131 | 
            +
                    @stm.buffer = "AB"
         | 
| 132 | 
            +
                    @stm.state = SGFStateMachine::STATE_VALUE_BEGIN
         | 
| 133 | 
            +
                    @stm.event "V"
         | 
| 134 | 
            +
                    @stm.buffer.should == "V"
         | 
| 135 | 
            +
                  end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                  it "Transition from value escape to value should store input to buffer" do
         | 
| 138 | 
            +
                    @stm.buffer = "AB"
         | 
| 139 | 
            +
                    @stm.state = SGFStateMachine::STATE_VALUE_ESCAPE
         | 
| 140 | 
            +
                    @stm.event "V"
         | 
| 141 | 
            +
                    @stm.buffer.should == "ABV"
         | 
| 142 | 
            +
                  end
         | 
| 143 | 
            +
                  
         | 
| 144 | 
            +
                  it "Transition to value from value should append input to buffer" do
         | 
| 145 | 
            +
                    @stm.buffer = "Valu"
         | 
| 146 | 
            +
                    @stm.state = SGFStateMachine::STATE_VALUE
         | 
| 147 | 
            +
                    @stm.event "e"
         | 
| 148 | 
            +
                    @stm.buffer.should == "Value"
         | 
| 149 | 
            +
                  end
         | 
| 150 | 
            +
                  
         | 
| 151 | 
            +
                  it "Transition to value end should call context.property_value" do
         | 
| 152 | 
            +
                    mock(@context).property_value = "Value"
         | 
| 153 | 
            +
                    @stm.buffer = "Value"
         | 
| 154 | 
            +
                    @stm.state = SGFStateMachine::STATE_VALUE
         | 
| 155 | 
            +
                    @stm.event "]"
         | 
| 156 | 
            +
                  end
         | 
| 157 | 
            +
                  
         | 
| 158 | 
            +
                  it "Transition to node from variation begin should not create node" do
         | 
| 159 | 
            +
                    dont_allow(@context).start_node
         | 
| 160 | 
            +
                    @stm.state = SGFStateMachine::STATE_VAR_BEGIN
         | 
| 161 | 
            +
                    @stm.event ";"
         | 
| 162 | 
            +
                  end
         | 
| 163 | 
            +
                end
         | 
| 164 | 
            +
                
         | 
| 165 | 
            +
              end
         | 
| 166 | 
            +
            end
         | 
| @@ -0,0 +1,137 @@ | |
| 1 | 
            +
            require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module SGF
         | 
| 4 | 
            +
              describe StateMachine do
         | 
| 5 | 
            +
                before :each do
         | 
| 6 | 
            +
                  @stm = StateMachine.new :start
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
                    
         | 
| 9 | 
            +
                it "state should return current state" do
         | 
| 10 | 
            +
                  @stm.state.should == :start
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
                
         | 
| 13 | 
            +
                it "transition should create transition" do
         | 
| 14 | 
            +
                  callback = lambda{}
         | 
| 15 | 
            +
                  @stm.transition :start, /a/, :end, callback
         | 
| 16 | 
            +
                  
         | 
| 17 | 
            +
                  t = @stm.transitions[:start][0]
         | 
| 18 | 
            +
                  t.before_state.should == :start
         | 
| 19 | 
            +
                  t.event_pattern.should == /a/
         | 
| 20 | 
            +
                  t.after_state.should == :end
         | 
| 21 | 
            +
                  t.callback.should == callback
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
                
         | 
| 24 | 
            +
                it "transition should create multiple transitions for multiple start states" do
         | 
| 25 | 
            +
                  @stm.transition [:start, :start2], /a/, :end
         | 
| 26 | 
            +
                  
         | 
| 27 | 
            +
                  t = @stm.transitions[:start][0]
         | 
| 28 | 
            +
                  t.before_state.should == :start
         | 
| 29 | 
            +
                  t.event_pattern.should == /a/
         | 
| 30 | 
            +
                  t.after_state.should == :end
         | 
| 31 | 
            +
                  t2 = @stm.transitions[:start2][0]
         | 
| 32 | 
            +
                  t2.before_state.should == :start2
         | 
| 33 | 
            +
                  t2.event_pattern.should == /a/
         | 
| 34 | 
            +
                  t2.after_state.should == :end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
                
         | 
| 37 | 
            +
                it "transition_if should create transition with condition" do
         | 
| 38 | 
            +
                  condition = lambda{}
         | 
| 39 | 
            +
                  @stm.transition_if condition, :start, /a/, :end
         | 
| 40 | 
            +
                  
         | 
| 41 | 
            +
                  t = @stm.transitions[:start][0]
         | 
| 42 | 
            +
                  t.condition.should == condition
         | 
| 43 | 
            +
                  t.before_state.should == :start
         | 
| 44 | 
            +
                  t.event_pattern.should == /a/
         | 
| 45 | 
            +
                  t.after_state.should == :end
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
                
         | 
| 48 | 
            +
                it "transition_if should create multiple transitions for multiple start states" do
         | 
| 49 | 
            +
                  condition = lambda{}
         | 
| 50 | 
            +
                  @stm.transition_if condition, [:start, :start2], /a/, :end
         | 
| 51 | 
            +
                  
         | 
| 52 | 
            +
                  t = @stm.transitions[:start][0]
         | 
| 53 | 
            +
                  t.condition.should == condition
         | 
| 54 | 
            +
                  t.before_state.should == :start
         | 
| 55 | 
            +
                  t2 = @stm.transitions[:start2][0]
         | 
| 56 | 
            +
                  t2.condition.should == condition
         | 
| 57 | 
            +
                  t2.before_state.should == :start2
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
                
         | 
| 60 | 
            +
                it "desc should set description for next transition" do
         | 
| 61 | 
            +
                  @stm.desc 'conditional transition'
         | 
| 62 | 
            +
                  @stm.transition [:start, :start2], /a/, :end
         | 
| 63 | 
            +
                  
         | 
| 64 | 
            +
                  @stm.transitions[:start][0].description.should == 'conditional transition'
         | 
| 65 | 
            +
                  @stm.transitions[:start2][0].description.should == 'conditional transition'
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
                
         | 
| 68 | 
            +
                it "desc should not description for transition after next transition" do
         | 
| 69 | 
            +
                  @stm.desc 'conditional transition'
         | 
| 70 | 
            +
                  @stm.transition [:start, :start2], /a/, :end
         | 
| 71 | 
            +
                  @stm.transition :start3, /a/, :end
         | 
| 72 | 
            +
                  
         | 
| 73 | 
            +
                  @stm.transitions[:start3][0].description.should be_nil
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
                
         | 
| 76 | 
            +
                it "reset should reset its state to start state" do
         | 
| 77 | 
            +
                  @stm.transition :start, /.*/, :end
         | 
| 78 | 
            +
                  @stm.event('a').should be_true
         | 
| 79 | 
            +
                  @stm.state.should == :end
         | 
| 80 | 
            +
                  
         | 
| 81 | 
            +
                  @stm.reset
         | 
| 82 | 
            +
                  
         | 
| 83 | 
            +
                  @stm.state.should == :start
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
                
         | 
| 86 | 
            +
                it "event should trigger state transition and return true if match the pattern" do
         | 
| 87 | 
            +
                  @stm.transition :start, /.*/, :end
         | 
| 88 | 
            +
                  @stm.event('a').should be_true
         | 
| 89 | 
            +
                  @stm.state.should == :end
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
                
         | 
| 92 | 
            +
                it "event should return false if no transition is defined for state" do
         | 
| 93 | 
            +
                  @stm.event('a').should be_false
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
                
         | 
| 96 | 
            +
                it "event should trigger state transition if current state is any of transition's start states and input match the pattern" do
         | 
| 97 | 
            +
                  @stm.transition [:start, :another], /.*/, :end
         | 
| 98 | 
            +
                  @stm.event 'a'
         | 
| 99 | 
            +
                  @stm.state.should == :end
         | 
| 100 | 
            +
                  @stm.instance_variable_set(:'@state', :another)
         | 
| 101 | 
            +
                  @stm.event 'a'
         | 
| 102 | 
            +
                  @stm.state.should == :end
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
                
         | 
| 105 | 
            +
                it "event should not trigger state transition and return false if it does not match the pattern" do
         | 
| 106 | 
            +
                  @stm.transition :start, /a/, :end
         | 
| 107 | 
            +
                  @stm.event('b').should be_false
         | 
| 108 | 
            +
                  @stm.state.should == :start
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
                
         | 
| 111 | 
            +
                it "event should not trigger state transition and return false if condition is not met" do
         | 
| 112 | 
            +
                  @stm.transition_if lambda{false}, :start, /a/, :end
         | 
| 113 | 
            +
                  @stm.event('a').should be_false
         | 
| 114 | 
            +
                  @stm.state.should == :start
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
                
         | 
| 117 | 
            +
                it "nil means end of input" do
         | 
| 118 | 
            +
                  @stm.transition :start, nil, :end
         | 
| 119 | 
            +
                  @stm.end
         | 
| 120 | 
            +
                  @stm.state.should == :end
         | 
| 121 | 
            +
                end
         | 
| 122 | 
            +
                
         | 
| 123 | 
            +
                it "transition should invoke the lambda if triggered by an event" do
         | 
| 124 | 
            +
                  @stm.buffer = "123"
         | 
| 125 | 
            +
                  @stm.transition :start, /4/, :end, lambda{|stm| @stm.buffer += @stm.input }
         | 
| 126 | 
            +
                  @stm.event '4'
         | 
| 127 | 
            +
                  @stm.buffer.should == "1234"
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
                
         | 
| 130 | 
            +
                it "clear_buffer should clear buffer" do
         | 
| 131 | 
            +
                  @stm.buffer = "abc"
         | 
| 132 | 
            +
                  @stm.clear_buffer
         | 
| 133 | 
            +
                  @stm.buffer.should == ""
         | 
| 134 | 
            +
                end
         | 
| 135 | 
            +
                
         | 
| 136 | 
            +
              end
         | 
| 137 | 
            +
            end
         | 
    
        data/spec/spec.opts
    ADDED
    
    
    
        data/spec/spec_helper.rb
    ADDED
    
    | @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            $:.push(File.dirname(__FILE__) + '/../lib')
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'rubygems'
         | 
| 4 | 
            +
            require 'spec'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Spec::Runner.configure do |config|
         | 
| 7 | 
            +
              # If you're not using ActiveRecord you should remove these
         | 
| 8 | 
            +
              # lines, delete config/database.yml and disable :active_record
         | 
| 9 | 
            +
              # in your config/boot.rb
         | 
| 10 | 
            +
              # config.use_transactional_fixtures = true
         | 
| 11 | 
            +
              # config.use_instantiated_fixtures  = false
         | 
| 12 | 
            +
              # config.fixture_path = RAILS_ROOT + '/../spec/fixtures/'
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              # == Fixtures
         | 
| 15 | 
            +
              #
         | 
| 16 | 
            +
              # You can declare fixtures for each example_group like this:
         | 
| 17 | 
            +
              #   describe "...." do
         | 
| 18 | 
            +
              #     fixtures :table_a, :table_b
         | 
| 19 | 
            +
              #
         | 
| 20 | 
            +
              # Alternatively, if you prefer to declare them only once, you can
         | 
| 21 | 
            +
              # do so right here. Just uncomment the next line and replace the fixture
         | 
| 22 | 
            +
              # names with your fixtures.
         | 
| 23 | 
            +
              #
         | 
| 24 | 
            +
              # config.global_fixtures = :table_a, :table_b
         | 
| 25 | 
            +
              #
         | 
| 26 | 
            +
              # If you declare global fixtures, be aware that they will be declared
         | 
| 27 | 
            +
              # for all of your examples, even those that don't use them.
         | 
| 28 | 
            +
              #
         | 
| 29 | 
            +
              # You can also declare which fixtures to use (for example fixtures for test/fixtures):
         | 
| 30 | 
            +
              #
         | 
| 31 | 
            +
              # config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
         | 
| 32 | 
            +
              #
         | 
| 33 | 
            +
              # == Mock Framework
         | 
| 34 | 
            +
              #
         | 
| 35 | 
            +
              # RSpec uses it's own mocking framework by default. If you prefer to
         | 
| 36 | 
            +
              # use mocha, flexmock or RR, uncomment the appropriate line:
         | 
| 37 | 
            +
              #
         | 
| 38 | 
            +
              # config.mock_with :mocha
         | 
| 39 | 
            +
              # config.mock_with :flexmock
         | 
| 40 | 
            +
              config.mock_with :rr
         | 
| 41 | 
            +
              #
         | 
| 42 | 
            +
              # == Notes
         | 
| 43 | 
            +
              # 
         | 
| 44 | 
            +
              # For more information take a look at Spec::Example::Configuration and Spec::Runner
         | 
| 45 | 
            +
            end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            require 'sgf'
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,150 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification 
         | 
| 2 | 
            +
            name: sgf_parser
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            +
              hash: 27
         | 
| 5 | 
            +
              prerelease: 
         | 
| 6 | 
            +
              segments: 
         | 
| 7 | 
            +
              - 0
         | 
| 8 | 
            +
              - 1
         | 
| 9 | 
            +
              - 0
         | 
| 10 | 
            +
              version: 0.1.0
         | 
| 11 | 
            +
            platform: ruby
         | 
| 12 | 
            +
            authors: 
         | 
| 13 | 
            +
            - Guoliang Cao
         | 
| 14 | 
            +
            autorequire: 
         | 
| 15 | 
            +
            bindir: bin
         | 
| 16 | 
            +
            cert_chain: []
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            date: 2011-11-28 00:00:00 -05:00
         | 
| 19 | 
            +
            default_executable: 
         | 
| 20 | 
            +
            dependencies: 
         | 
| 21 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 22 | 
            +
              prerelease: false
         | 
| 23 | 
            +
              name: jeweler
         | 
| 24 | 
            +
              type: :development
         | 
| 25 | 
            +
              version_requirements: &id001 !ruby/object:Gem::Requirement 
         | 
| 26 | 
            +
                none: false
         | 
| 27 | 
            +
                requirements: 
         | 
| 28 | 
            +
                - - ">="
         | 
| 29 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 30 | 
            +
                    hash: 3
         | 
| 31 | 
            +
                    segments: 
         | 
| 32 | 
            +
                    - 0
         | 
| 33 | 
            +
                    version: "0"
         | 
| 34 | 
            +
              requirement: *id001
         | 
| 35 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 36 | 
            +
              prerelease: false
         | 
| 37 | 
            +
              name: rspec
         | 
| 38 | 
            +
              type: :development
         | 
| 39 | 
            +
              version_requirements: &id002 !ruby/object:Gem::Requirement 
         | 
| 40 | 
            +
                none: false
         | 
| 41 | 
            +
                requirements: 
         | 
| 42 | 
            +
                - - ~>
         | 
| 43 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 44 | 
            +
                    hash: 27
         | 
| 45 | 
            +
                    segments: 
         | 
| 46 | 
            +
                    - 1
         | 
| 47 | 
            +
                    - 3
         | 
| 48 | 
            +
                    - 0
         | 
| 49 | 
            +
                    version: 1.3.0
         | 
| 50 | 
            +
              requirement: *id002
         | 
| 51 | 
            +
            description: A simple SGF parser
         | 
| 52 | 
            +
            email: gcao99@gmail.com
         | 
| 53 | 
            +
            executables: 
         | 
| 54 | 
            +
            - stm2dot
         | 
| 55 | 
            +
            - sgf
         | 
| 56 | 
            +
            extensions: []
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            extra_rdoc_files: 
         | 
| 59 | 
            +
            - LICENSE
         | 
| 60 | 
            +
            - README.textile
         | 
| 61 | 
            +
            - TODO
         | 
| 62 | 
            +
            files: 
         | 
| 63 | 
            +
            - .irbrc
         | 
| 64 | 
            +
            - .rvmrc
         | 
| 65 | 
            +
            - Gemfile
         | 
| 66 | 
            +
            - Gemfile.lock
         | 
| 67 | 
            +
            - LICENSE
         | 
| 68 | 
            +
            - README.textile
         | 
| 69 | 
            +
            - Rakefile
         | 
| 70 | 
            +
            - TODO
         | 
| 71 | 
            +
            - VERSION
         | 
| 72 | 
            +
            - bin/sgf
         | 
| 73 | 
            +
            - bin/stm2dot
         | 
| 74 | 
            +
            - doc/sgf_state_machine.dot
         | 
| 75 | 
            +
            - doc/sgf_state_machine.svg
         | 
| 76 | 
            +
            - lib/sgf.rb
         | 
| 77 | 
            +
            - lib/sgf/binary_file_error.rb
         | 
| 78 | 
            +
            - lib/sgf/debugger.rb
         | 
| 79 | 
            +
            - lib/sgf/default_event_listener.rb
         | 
| 80 | 
            +
            - lib/sgf/model/constants.rb
         | 
| 81 | 
            +
            - lib/sgf/model/event_listener.rb
         | 
| 82 | 
            +
            - lib/sgf/model/game.rb
         | 
| 83 | 
            +
            - lib/sgf/model/label.rb
         | 
| 84 | 
            +
            - lib/sgf/model/node.rb
         | 
| 85 | 
            +
            - lib/sgf/model/property_handler.rb
         | 
| 86 | 
            +
            - lib/sgf/more/state_machine_presenter.rb
         | 
| 87 | 
            +
            - lib/sgf/more/stm_dot_converter.rb
         | 
| 88 | 
            +
            - lib/sgf/parse_error.rb
         | 
| 89 | 
            +
            - lib/sgf/parser.rb
         | 
| 90 | 
            +
            - lib/sgf/renderer.rb
         | 
| 91 | 
            +
            - lib/sgf/sgf_helper.rb
         | 
| 92 | 
            +
            - lib/sgf/sgf_state_machine.rb
         | 
| 93 | 
            +
            - lib/sgf/state_machine.rb
         | 
| 94 | 
            +
            - sgf_parser.gemspec
         | 
| 95 | 
            +
            - spec/fixtures/2009-11-01-1.sgf
         | 
| 96 | 
            +
            - spec/fixtures/2009-11-01-2.sgf
         | 
| 97 | 
            +
            - spec/fixtures/chinese_gb.sgf
         | 
| 98 | 
            +
            - spec/fixtures/chinese_utf.sgf
         | 
| 99 | 
            +
            - spec/fixtures/example.sgf
         | 
| 100 | 
            +
            - spec/fixtures/good.sgf
         | 
| 101 | 
            +
            - spec/fixtures/good1.sgf
         | 
| 102 | 
            +
            - spec/fixtures/kgs.sgf
         | 
| 103 | 
            +
            - spec/fixtures/test.png
         | 
| 104 | 
            +
            - spec/sgf/model/event_listener_spec.rb
         | 
| 105 | 
            +
            - spec/sgf/model/game_spec.rb
         | 
| 106 | 
            +
            - spec/sgf/model/node_spec.rb
         | 
| 107 | 
            +
            - spec/sgf/more/state_machine_presenter_spec.rb
         | 
| 108 | 
            +
            - spec/sgf/parse_error_spec.rb
         | 
| 109 | 
            +
            - spec/sgf/parser_spec.rb
         | 
| 110 | 
            +
            - spec/sgf/sgf_helper_spec.rb
         | 
| 111 | 
            +
            - spec/sgf/sgf_state_machine_spec.rb
         | 
| 112 | 
            +
            - spec/sgf/state_machine_spec.rb
         | 
| 113 | 
            +
            - spec/spec.opts
         | 
| 114 | 
            +
            - spec/spec_helper.rb
         | 
| 115 | 
            +
            has_rdoc: true
         | 
| 116 | 
            +
            homepage: http://github.com/gcao/discuz_robot
         | 
| 117 | 
            +
            licenses: []
         | 
| 118 | 
            +
             | 
| 119 | 
            +
            post_install_message: 
         | 
| 120 | 
            +
            rdoc_options: []
         | 
| 121 | 
            +
             | 
| 122 | 
            +
            require_paths: 
         | 
| 123 | 
            +
            - lib
         | 
| 124 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         | 
| 125 | 
            +
              none: false
         | 
| 126 | 
            +
              requirements: 
         | 
| 127 | 
            +
              - - ">="
         | 
| 128 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 129 | 
            +
                  hash: 3
         | 
| 130 | 
            +
                  segments: 
         | 
| 131 | 
            +
                  - 0
         | 
| 132 | 
            +
                  version: "0"
         | 
| 133 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         | 
| 134 | 
            +
              none: false
         | 
| 135 | 
            +
              requirements: 
         | 
| 136 | 
            +
              - - ">="
         | 
| 137 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 138 | 
            +
                  hash: 3
         | 
| 139 | 
            +
                  segments: 
         | 
| 140 | 
            +
                  - 0
         | 
| 141 | 
            +
                  version: "0"
         | 
| 142 | 
            +
            requirements: []
         | 
| 143 | 
            +
             | 
| 144 | 
            +
            rubyforge_project: 
         | 
| 145 | 
            +
            rubygems_version: 1.4.2
         | 
| 146 | 
            +
            signing_key: 
         | 
| 147 | 
            +
            specification_version: 3
         | 
| 148 | 
            +
            summary: A SGF parser
         | 
| 149 | 
            +
            test_files: []
         | 
| 150 | 
            +
             |