| 36 | | Accessors = [ |
| 37 | | :part_of_speech, |
| 38 | | :offset, |
| 39 | | :filenum, |
| 40 | | :wordlist, |
| 41 | | :pointerlist, |
| 42 | | :frameslist, |
| 43 | | :gloss, |
| 44 | | ] |
| 45 | | |
| 46 | | RelationMethods = [ |
| | 36 | TEST_SYNSET_OFFSET = 6172789 |
| | 37 | |
| | 38 | TEST_SYNSET_POS = :noun |
| | 39 | |
| | 40 | TEST_SYNSET_DATA = "09||linguistics%0||@ 05999797%n 0000|#p 06142861%n 0000|+ " + |
| | 41 | "02843218%a 0101|+ 10264437%n 0101|-c 00111415%a 0000|-c 00111856%a 0000|-c 00120252%a " + |
| | 42 | "0000|-c 00120411%a 0000|-c 00201802%a 0000|-c 00699651%a 0000|-c 00699876%a 0000|-c " + |
| | 43 | "00819852%a 0000|-c 00820219%a 0000|-c 00820458%a 0000|-c 00820721%a 0000|-c 00820975%a " + |
| | 44 | "0000|-c 00821208%a 0000|-c 01973823%a 0000|-c 02297664%a 0000|-c 02297966%a 0000|-c " + |
| | 45 | "02298285%a 0000|-c 02298642%a 0000|-c 02298766%a 0000|-c 02478052%a 0000|-c 02482790%a " + |
| | 46 | "0000|-c 02593124%a 0000|-c 02593578%a 0000|-c 02836479%a 0000|-c 02856124%a 0000|-c " + |
| | 47 | "02993853%a 0000|-c 03041636%a 0000|-c 03045196%a 0000|-c 03102278%a 0000|-c 03129490%a " + |
| | 48 | "0000|-c 00098051%n 0000|-c 04986883%n 0000|-c 05087664%n 0000|-c 05153897%n 0000|-c " + |
| | 49 | "05850212%n 0000|~ 06168552%n 0000|~ 06168703%n 0000|~ 06168855%n 0000|~ 06169050%n 0000|-c " + |
| | 50 | "06174404%n 0000|-c 06175829%n 0000|-c 06175967%n 0000|-c 06176107%n 0000|-c 06176322%n " + |
| | 51 | "0000|-c 06176519%n 0000|-c 06177450%n 0000|~ 06179290%n 0000|~ 06179492%n 0000|~ 06179792%n " + |
| | 52 | "0000|~ 06181123%n 0000|~ 06181284%n 0000|~ 06181448%n 0000|~ 06181584%n 0000|~ 06181893%n " + |
| | 53 | "0000|-c 06249910%n 0000|-c 06250444%n 0000|-c 06290051%n 0000|-c 06290637%n 0000|-c " + |
| | 54 | "06300193%n 0000|-c 06331803%n 0000|-c 06483702%n 0000|-c 06483992%n 0000|-c 06484279%n " + |
| | 55 | "0000|-c 07111510%n 0000|-c 07111711%n 0000|-c 07111933%n 0000|-c 07259772%n 0000|-c " + |
| | 56 | "07259984%n 0000|-c 07276018%n 0000|-c 08103635%n 0000|-c 13433061%n 0000|-c 13508333%n " + |
| | 57 | "0000|-c 13802920%n 0000|-c 00587390%v 0000|-c 00587522%v 0000|-c 00634286%v 0000|-c " + |
| | 58 | "01013856%v 0000|-c 01735556%v 0000||||the scientific study of language" |
| | 59 | |
| | 60 | RELATION_METHODS = [ |
| 103 | | |
| 104 | | ################################################################# |
| 105 | | ### T E S T S |
| 106 | | ################################################################# |
| 107 | | |
| 108 | | ### Accessors |
| 109 | | def test_accessors |
| 110 | | printTestHeader "Synset: Accessors" |
| 111 | | rval = nil |
| 112 | | |
| 113 | | assert_respond_to @blankSyn, :lexicon |
| 114 | | |
| 115 | | Accessors.each do |meth| |
| 116 | | assert_respond_to @blankSyn, meth |
| 117 | | assert_respond_to @blankSyn, "#{meth}=" |
| 118 | | |
| 119 | | assert_nothing_raised do |
| 120 | | rval = @blankSyn.send( meth ) |
| | 121 | it "has (generated) methods for each type of WordNet relation" do |
| | 122 | RELATION_METHODS.each do |relation| |
| | 123 | WordNet::Synset.instance_method( relation ).should be_an_instance_of( UnboundMethod ) |
| | 124 | end |
| | 125 | end |
| | 126 | |
| | 127 | |
| | 128 | describe "instance created from synset data" do |
| | 129 | |
| | 130 | before( :each ) do |
| | 131 | @lexicon = mock( "lexicon" ) |
| | 132 | @synset = WordNet::Synset.new( @lexicon, |
| | 133 | TEST_SYNSET_OFFSET, TEST_SYNSET_POS, 'linguistics', TEST_SYNSET_DATA ) |
| | 134 | end |
| | 135 | |
| | 136 | |
| | 137 | it "knows what part_of_speech it is" do |
| | 138 | @synset.part_of_speech.should == TEST_SYNSET_POS |
| | 139 | end |
| | 140 | |
| | 141 | it "knows what offset it is" do |
| | 142 | @synset.offset.should == TEST_SYNSET_OFFSET |
| | 143 | end |
| | 144 | |
| | 145 | it "knows what filenum it is" do |
| | 146 | @synset.filenum.should == '09' |
| | 147 | end |
| | 148 | |
| | 149 | it "knows what its wordlist is" do |
| | 150 | @synset.wordlist.should == 'linguistics%0' |
| | 151 | end |
| | 152 | |
| | 153 | POINTER_PATTERN = /(\S{2} \d+%[nvars] \d{4})/ |
| | 154 | LIST_OF_POINTERS = /#{POINTER_PATTERN}(\|#{POINTER_PATTERN})*/ |
| | 155 | it "knows what its pointerlist is" do |
| | 156 | @synset.pointerlist.should =~ LIST_OF_POINTERS |
| | 157 | end |
| | 158 | |
| | 159 | it "knows what frameslist it is" do |
| | 160 | @synset.frameslist.should == '' |
| | 161 | end |
| | 162 | |
| | 163 | it "knows what its gloss is" do |
| | 164 | @synset.gloss.should =~ /study of language/i |
| | 165 | end |
| | 166 | |
| | 167 | |
| | 168 | ### :TODO: Test traversal, content, storing, higher-order functions |
| | 169 | describe "traversal" do |
| | 170 | |
| | 171 | it "can traverse its relationships and return the resulting synsets" do |
| | 172 | hypernym1 = mock( "hypernym of linguistics" ) |
| | 173 | hypernym2 = mock( "super-hypernym of linguistics" ) |
| | 174 | |
| | 175 | @lexicon.should_receive( :lookup_synsets_by_key ).with( /\d+%[nvars]/ ). |
| | 176 | and_return( hypernym1 ) |
| | 177 | hypernym1.should_receive( :hypernyms ).and_return([ hypernym2 ]) |
| | 178 | hypernym2.should_receive( :hypernyms ).and_return([]) |
| | 179 | |
| | 180 | synsets = @synset.traverse( :hypernyms ) |
| | 181 | |
| | 182 | synsets.should have(3).members |
| | 183 | synsets.should include( @synset, hypernym1, hypernym2 ) |
| 122 | | end |
| 123 | | end |
| 124 | | |
| 125 | | ### Relations |
| 126 | | def test_relations |
| 127 | | printTestHeader "Synset: Relation methods" |
| 128 | | rval = nil |
| 129 | | |
| 130 | | RelationMethods.each do |meth| |
| 131 | | casemeth = meth.to_s.sub( /^(\w)/ ) {|char| char.upcase }.intern |
| 132 | | |
| 133 | | assert_respond_to @blankSyn, meth |
| 134 | | assert_respond_to @blankSyn, "#{meth}=" |
| 135 | | |
| 136 | | assert_nothing_raised { |
| 137 | | rval = @blankSyn.send( meth ) |
| 138 | | } |
| 139 | | |
| 140 | | assert_instance_of Array, rval |
| 141 | | end |
| 142 | | end |
| 143 | | |
| 144 | | ### Aggregate relation methods |
| 145 | | def test_aggregate_relations |
| 146 | | printTestHeader "Synset: Aggregate relations" |
| 147 | | rval = nil |
| 148 | | |
| 149 | | AggregateRelationMethods.each {|meth| |
| 150 | | assert_respond_to @blankSyn, meth |
| 151 | | |
| 152 | | assert_nothing_raised { |
| 153 | | rval = @blankSyn.send( meth ) |
| 154 | | } |
| 155 | | |
| 156 | | assert_instance_of Array, rval |
| 157 | | } |
| 158 | | end |
| 159 | | |
| 160 | | ### Traversal method |
| 161 | | def test_synset_should_respond_to_traverse_method |
| 162 | | printTestHeader "Synset: Traversal method" |
| 163 | | assert_respond_to @traversalSyn, :traverse |
| 164 | | end |
| 165 | | |
| 166 | | ### :TODO: This should really be split into two tests. |
| 167 | | ### Traversal: include origin, break loop |
| 168 | | def test_traversal_with_true_second_arg_should_include_origin |
| 169 | | printTestHeader "Synset: Traversal, including origin, break" |
| 170 | | rval = nil |
| 171 | | count = depth = 0 |
| 172 | | sets = [] |
| 173 | | |
| 174 | | assert_nothing_raised { |
| 175 | | rval = @traversalSyn.traverse( :hyponyms, true ) {|tsyn,tdepth| |
| 176 | | sets << tsyn |
| 177 | | depth = tdepth |
| 178 | | count += 1 |
| 179 | | return true |
| 180 | | } |
| 181 | | } |
| 182 | | assert_equal true, rval |
| 183 | | assert_equal 1, sets.length |
| 184 | | assert_equal @traversalSyn, sets[0] |
| 185 | | assert_equal 0, depth |
| 186 | | assert_equal 1, count |
| 187 | | end |
| 188 | | |
| 189 | | ### :TODO: This should really be split into two tests. |
| 190 | | ### Traversal: exclude origin, break loop |
| 191 | | def test_traversal_with_false_second_arg_should_not_include_origin |
| 192 | | printTestHeader "Synset: Traversal, excluding origin, break" |
| 193 | | rval = nil |
| 194 | | count = depth = 0 |
| 195 | | sets = [] |
| 196 | | |
| 197 | | assert_nothing_raised { |
| 198 | | rval = @traversalSyn.traverse( :hyponyms, false ) {|tsyn,tdepth| |
| 199 | | sets << tsyn |
| 200 | | depth = tdepth |
| 201 | | count += 1 |
| 202 | | return true |
| 203 | | } |
| 204 | | } |
| 205 | | assert_equal true, rval |
| 206 | | assert_equal 1, sets.length |
| 207 | | assert_not_equal @traversalSyn, sets[0] |
| 208 | | assert_equal 1, depth |
| 209 | | assert_equal 1, count |
| 210 | | end |
| 211 | | |
| 212 | | ### Traversal: include origin, nobreak, noblock |
| 213 | | def test_hyponym_traversal_with_no_block_should_return_appropriate_hyponyms |
| 214 | | printTestHeader "Synset: Traversal, include origin, nobreak, noblock" |
| 215 | | sets = [] |
| 216 | | |
| 217 | | assert_nothing_raised { |
| 218 | | sets = @traversalSyn.traverse( :hyponyms ) |
| 219 | | } |
| 220 | | assert_block { sets.length > 1 } |
| 221 | | assert_equal @traversalSyn, sets[0] |
| 222 | | assert_block { sets.find {|hsyn| hsyn.words.include?( "grammar" )} } |
| 223 | | assert_block { sets.find {|hsyn| hsyn.words.include?( "syntax" )} } |
| 224 | | assert_block { sets.find {|hsyn| hsyn.words.include?( "computational linguistics" )} } |
| 225 | | end |
| 226 | | |
| 227 | | |
| 228 | | ### Traversal: exclude origin, nobreak, noblock |
| 229 | | def test_hyponym_traversal_with_no_block_and_false_second_arg_should_return_holonyms_but_not_the_origin |
| 230 | | printTestHeader "Synset: Traversal, exclude origin, nobreak, noblock" |
| 231 | | sets = [] |
| 232 | | |
| 233 | | assert_nothing_raised { |
| 234 | | sets = @traversalSyn.traverse( :hyponyms, false ) |
| 235 | | } |
| 236 | | assert_block { sets.length > 1 } |
| 237 | | assert_not_equal @traversalSyn, sets[0] |
| 238 | | assert_block { sets.find {|hsyn| hsyn.words.include?( "grammar" )} } |
| 239 | | assert_block { sets.find {|hsyn| hsyn.words.include?( "syntax" )} } |
| 240 | | assert_block { sets.find {|hsyn| hsyn.words.include?( "computational linguistics" )} } |
| 241 | | end |
| 242 | | |
| 243 | | |
| 244 | | ### Traversal: include origin, nobreak, noblock |
| 245 | | def test_traversal_break_after_3_should_include_three_sets_plus_origin |
| 246 | | printTestHeader "Synset: Traversal, break after 3" |
| 247 | | rval = nil |
| 248 | | sets = Hash::new {|hsh,key| hsh[key] = []} |
| 249 | | |
| 250 | | assert_nothing_raised { |
| 251 | | rval = @traversalSyn.traverse( :hyponyms ) {|tsyn,tdepth| |
| 252 | | sets[tdepth] << tsyn |
| 253 | | tdepth == 3 |
| 254 | | } |
| 255 | | } |
| 256 | | assert_equal 4, sets.keys.length |
| 257 | | assert_equal [0,1,2,3], sets.keys.sort |
| 258 | | assert_equal 1, sets[3].length |
| 259 | | assert rval, "Break early flag expected to be set" |
| 260 | | end |
| 261 | | |
| 262 | | |
| 263 | | ### Part of speech: part_of_speech |
| 264 | | def test_part_of_speech_should_return_the_symbol_part_of_speech |
| 265 | | printTestHeader "Synset: part_of_speech" |
| 266 | | rval = nil |
| 267 | | |
| 268 | | assert_nothing_raised { rval = @traversalSyn.part_of_speech } |
| 269 | | assert_equal :noun, rval |
| 270 | | end |
| 271 | | |
| 272 | | |
| 273 | | ### Part of speech: pos |
| 274 | | def test_pos_should_return_the_synsets_singlechar_part_of_speech |
| 275 | | printTestHeader "Synset: pos" |
| 276 | | rval = nil |
| 277 | | |
| 278 | | assert_nothing_raised { rval = @traversalSyn.pos } |
| 279 | | assert_equal "n", rval |
| 280 | | end |
| 281 | | |
| 282 | | |
| 283 | | ### :TODO: Test traversal, content, storing, higher-order functions |
| 284 | | |
| | 185 | |
| | 186 | |
| | 187 | it "can exclude its origin term from a traversal set" do |
| | 188 | hypernym1 = mock( "hypernym of linguistics" ) |
| | 189 | hypernym2 = mock( "super-hypernym of linguistics" ) |
| | 190 | |
| | 191 | @lexicon.should_receive( :lookup_synsets_by_key ).with( /\d+%[nvars]/ ). |
| | 192 | and_return( hypernym1 ) |
| | 193 | hypernym1.should_receive( :hypernyms ).and_return([ hypernym2 ]) |
| | 194 | hypernym2.should_receive( :hypernyms ).and_return([]) |
| | 195 | |
| | 196 | synsets = @synset.traverse( :hypernyms, false ) |
| | 197 | |
| | 198 | synsets.should have(2).members |
| | 199 | synsets.should include( hypernym1, hypernym2 ) |
| | 200 | end |
| | 201 | |
| | 202 | end # "traversal" |
| | 203 | |
| | 204 | end # "instance" |