linkparser 1.1.3 → 2.2.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.
@@ -1,5 +1,5 @@
1
- #!/usr/bin/env ruby
2
-
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
3
 
4
4
  module LinkParser
5
5
 
@@ -11,7 +11,6 @@ module LinkParser
11
11
 
12
12
  ### Make a wrapper for a deprecated method. The wrapper will print a deprecation warning
13
13
  ### to STDERR, and then call the method with the same name prefixed with an underscore.
14
- ### @param [Symbol, #to_sym] name the name of the method to deprecate.
15
14
  def deprecated_method( *names )
16
15
  names.each do |name|
17
16
  method_body = lambda do |*args|
@@ -0,0 +1,58 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ require 'linkparser' unless defined?( LinkParser )
5
+
6
+
7
+ # LinkParser parse options class. Instances of this class are used to specify the different
8
+ # parameters that are used to parse sentences. Examples of the kinds of things that are
9
+ # controlled by ParseOptions include maximum parsing time and memory, whether to use
10
+ # null-links, and whether or not to use "panic" mode. This data structure is passed in to
11
+ # the various parsing and printing routines along with the sentence.
12
+ class LinkParser::ParseOptions
13
+ extend Loggability,
14
+ LinkParser::DeprecationUtilities
15
+
16
+ # Use LinkParser's logger
17
+ log_to :linkparser
18
+
19
+
20
+ ### Return an Array of valid option names as Symbols.
21
+ def self::option_names
22
+ return @option_names ||= instance_methods( false ).
23
+ grep( /^[a-z].*=$/ ).map {|sym| sym.to_s.chomp('=').to_sym }
24
+ end
25
+
26
+
27
+ ### Return a new LinkParser::ParseOptions with the values of the receiver merged with
28
+ ### those from the +other+ object.
29
+ def merge( other )
30
+ new_options = self.dup
31
+ new_options.merge!( other )
32
+ return new_options
33
+ end
34
+
35
+
36
+ ### Overwrite the option settings on the receiver with those from the +other+
37
+ ### object.
38
+ def merge!( other )
39
+ other.to_hash.each do |key, val|
40
+ self.send( "#{key}=", val )
41
+ end
42
+ end
43
+
44
+
45
+ ### Return the options as a Hash.
46
+ def to_hash
47
+ return self.class.option_names.each_with_object( {} ) do |optname, accum|
48
+ val = if self.respond_to?( "#{optname}?" )
49
+ self.send( "#{optname}?" )
50
+ else
51
+ self.send( optname )
52
+ end
53
+
54
+ accum[ optname ] = val
55
+ end
56
+ end
57
+
58
+ end # class LinkParser::ParseOptions
@@ -1,28 +1,16 @@
1
- #!/usr/bin/ruby
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'linkparser' unless defined?( LinkParser )
4
5
 
5
- #
6
- # A Sentence is the API's representation of an input string, tokenized
7
- # and interpreted according to a specific Dictionary. After a Sentence
8
- # is created and parsed, various attributes of the resulting set of
9
- # linkages can be obtained.
10
- #
11
- # == Authors
12
- #
13
- # * Michael Granger <ged@FaerieMUD.org>
14
- #
15
- # == Version
16
- #
17
- # $Id: sentence.rb,v 23a39531870a 2011/01/11 18:18:12 ged $
18
- #
19
- # == License
20
- #
21
- # :include: LICENSE
22
- #--
23
- #
24
- # See the LICENSE file for copyright/licensing information.
25
6
  class LinkParser::Sentence
7
+ extend Loggability,
8
+ LinkParser::DeprecationUtilities
9
+
10
+
11
+ # Use LinkParser's logger
12
+ log_to :linkparser
13
+
26
14
 
27
15
  ######
28
16
  public
@@ -41,7 +29,7 @@ class LinkParser::Sentence
41
29
  contents = "(unparsed)"
42
30
  end
43
31
 
44
- return "#<%s:0x%x %s>" % [
32
+ return "#<%s:%#x %s>" % [
45
33
  self.class.name,
46
34
  self.object_id / 2,
47
35
  contents,
@@ -59,26 +47,21 @@ class LinkParser::Sentence
59
47
  protected
60
48
  #########
61
49
 
62
- ### Return the singleton class for this object
63
- def singleton_class
64
- class << self; self; end
65
- end
66
-
67
-
68
50
  ### Proxy method -- auto-delegate calls to the first linkage.
69
- def method_missing( sym, *args )
70
-
71
- # Check both symbol and string for forward-compatibility with 1.9.x
72
- return super unless
73
- LinkParser::Linkage.instance_methods.include?( sym.to_s ) ||
74
- LinkParser::Linkage.instance_methods.include?( sym )
51
+ def method_missing( sym, *args, &block )
52
+ return super unless LinkParser::Linkage.instance_methods.include?( sym )
75
53
 
76
- linkage = self.linkages.first or raise LinkParser::Error, "sentence has no linkages"
54
+ linkage_method = LinkParser::Linkage.instance_method( sym )
55
+ meth = lambda do |*args, &block|
56
+ linkage = self.linkages.first or raise LinkParser::Error, "sentence has no linkages"
57
+ linkage_method.bind( linkage ).call( *args, &block )
58
+ end
77
59
 
78
- meth = linkage.method( sym )
79
- self.singleton_class.send( :define_method, sym, &meth )
60
+ self.singleton_class.instance_exec( sym, meth ) do |name, new_method|
61
+ define_method( name, &new_method )
62
+ end
80
63
 
81
- meth.call( *args )
64
+ meth.call( *args, &block )
82
65
  rescue => err
83
66
  raise err, err.message, err.backtrace[ 0..-2 ]
84
67
  end
@@ -1,48 +1,35 @@
1
- #!/usr/bin/ruby -w
2
- #
3
- # Specification for various bugfixes to the LinkParser binding
4
- # $Id: bugfixes_spec.rb,v 1eddd00723e6 2010/11/22 15:59:36 ged $
5
- #
6
- # See the LICENSE file in the distribution for information about copyright and licensing.
7
- #
8
-
9
- BEGIN {
10
- require 'pathname'
11
- basedir = Pathname.new( __FILE__ ).dirname.parent
12
-
13
- libdir = basedir + 'lib'
14
- extdir = basedir + 'ext'
15
-
16
- $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
17
- $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
18
- $LOAD_PATH.unshift( extdir.to_s ) unless $LOAD_PATH.include?( extdir.to_s )
19
- }
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
20
3
 
21
- require 'rspec'
4
+ require_relative 'helpers'
22
5
 
6
+ require 'rspec'
23
7
  require 'linkparser'
24
8
 
25
- # @dict = LinkParser::Dictionary.new( :verbosity => 0 )
26
- # s = LinkParser::Sentence.new('The cat runs.',@dict)
27
- # puts s.linkages.first.verb # "cat.n" !?!?!
28
- describe %{bugfix for #3: The first linkage for "The cat runs."} do
9
+
10
+ describe LinkParser do
11
+
29
12
  before( :all ) do
30
- $DEBUG = true if ENV['DEBUG']
13
+ @dict = LinkParser::Dictionary.new('en', verbosity: 0)
31
14
  end
32
15
 
33
- before( :each ) do
34
- @dict = LinkParser::Dictionary.new( 'en', :verbosity => 0 )
35
- @sentence = @dict.parse( "The cat runs." )
36
- @linkage = @sentence.linkages.first
37
- end
16
+ let( :sentence ) { @dict.parse( text ) }
17
+ let( :linkage ) { sentence.linkages.first }
38
18
 
39
19
 
40
- it "thinks cat is the subject" do
41
- @linkage.subject.should == "cat"
42
- end
20
+ describe 'bugfix for #3: The first linkage for "The cat runs."' do
21
+
22
+ let( :text ) { "The cat runs." }
23
+
24
+
25
+ it "selects cat as the subject" do
26
+ expect( linkage.subject ).to eq( "cat" )
27
+ end
28
+
29
+ it "selects runs as the verb" do
30
+ expect( linkage.verb ).to eq( "runs" )
31
+ end
43
32
 
44
- it "thinks runs is the verb" do
45
- @linkage.verb.should == "runs"
46
33
  end
47
- end
48
34
 
35
+ end
@@ -0,0 +1,39 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ # SimpleCov test coverage reporting; enable this using the :coverage rake task
5
+ require 'simplecov' if ENV['COVERAGE']
6
+ require 'rspec'
7
+
8
+ require 'loggability/spechelpers'
9
+
10
+ require 'linkparser'
11
+
12
+
13
+ $DEBUG = true if ENV['DEBUG']
14
+
15
+
16
+ ### RSpec helper functions.
17
+ module LinkParser::SpecHelpers
18
+ end
19
+
20
+
21
+ ### Mock with RSpec
22
+ RSpec.configure do |config|
23
+ config.run_all_when_everything_filtered = true
24
+ config.filter_run :focus
25
+ config.order = 'random'
26
+ config.mock_with( :rspec ) do |mock|
27
+ mock.syntax = :expect
28
+ end
29
+
30
+ lg_version = LinkParser.link_grammar_version[ /(\d+(\.\d+)+)$/, 1 ]
31
+ config.filter_run_excluding( skip_version: lg_version )
32
+ config.filter_run_including( only_version: lg_version )
33
+
34
+ config.include( Loggability::SpecHelpers )
35
+ config.include( LinkParser::SpecHelpers )
36
+ end
37
+
38
+ # vim: set nosta noet ts=4 sw=4:
39
+
@@ -1,31 +1,15 @@
1
- #!/usr/bin/ruby -w
2
- #
3
- # Specification for the LinkParser::Dictionary class
4
- # $Id: dictionary_spec.rb,v 54e4e2ff8899 2010/11/25 00:50:55 ged $
5
- #
6
- # See the LICENSE file in the distribution for information about copyright and licensing.
7
- #
8
-
9
- BEGIN {
10
- require 'pathname'
11
- basedir = Pathname.new( __FILE__ ).dirname.parent.parent
12
-
13
- libdir = basedir + 'lib'
14
- extdir = basedir + 'ext'
15
-
16
- $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
17
- $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
18
- $LOAD_PATH.unshift( extdir.to_s ) unless $LOAD_PATH.include?( extdir.to_s )
19
- }
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
20
3
 
21
- require 'rspec'
4
+ require_relative '../helpers'
22
5
 
6
+ require 'rspec'
23
7
  require 'linkparser'
24
8
 
25
9
 
26
10
  describe LinkParser::Dictionary do
27
11
 
28
- ### Work around current system's locale
12
+ ### Tests expect English locale
29
13
  before( :all ) do
30
14
  $LANG = ENV['LANG']
31
15
  ENV['LANG'] = 'en_US.UTF-8'
@@ -38,66 +22,63 @@ describe LinkParser::Dictionary do
38
22
 
39
23
 
40
24
  it "can be instantiated using all default values" do
41
- LinkParser::Dictionary.new.should be_an_instance_of( LinkParser::Dictionary )
25
+ expect( LinkParser::Dictionary.new ).to be_an_instance_of( LinkParser::Dictionary )
42
26
  end
43
27
 
44
28
  it "can be instantiated with an options hash" do
45
- LinkParser::Dictionary.new( :verbosity => 2 ).options[:verbosity].should == 2
29
+ dict = LinkParser::Dictionary.new( :verbosity => 2 )
30
+ expect( dict ).to be_a( LinkParser::Dictionary )
31
+ expect( dict.options[:verbosity] ).to eq( 2 )
46
32
  end
47
33
 
48
34
  it "raises an error when created with an bad number of arguments" do
49
- lambda {
35
+ expect {
50
36
  LinkParser::Dictionary.new( "foo", "bar", "baz" )
51
- }.should raise_error(ArgumentError)
37
+ }.to raise_error( ArgumentError )
52
38
  end
53
39
 
54
40
  it "can be instantiated with a language argument" do
55
- lambda {LinkParser::Dictionary.new( 'en' )}.should_not raise_error()
41
+ dict = LinkParser::Dictionary.new( 'en' )
42
+ expect( dict ).to be_a( LinkParser::Dictionary )
56
43
  end
57
44
 
58
45
  it "can be instantiated with both a language and an options hash" do
59
- LinkParser::Dictionary.new('en', :verbosity => 2).options[:verbosity].should == 2
46
+ dict = LinkParser::Dictionary.new( 'en', :verbosity => 2 )
47
+ expect( dict.options[:verbosity] ).to eq( 2 )
60
48
  end
61
49
 
62
- it "raises an exception if created with unknown dictionaries" do
63
- lambda {
64
- LinkParser::Dictionary.new('foo', 'bar', 'baz', 'bim')
65
- }.should raise_error( LinkParser::Error )
50
+ it "raises an exception if created with an unknown language" do
51
+ expect {
52
+ LinkParser::Dictionary.new( 'ie' )
53
+ }.to raise_error( LinkParser::Error )
66
54
  end
67
55
 
68
56
  it "raises an exception if created with an unknown language" do
69
- lambda {
57
+ expect {
70
58
  LinkParser::Dictionary.new('zz')
71
- }.should raise_error( LinkParser::Error )
59
+ }.to raise_error( LinkParser::Error )
72
60
  end
73
61
 
62
+
74
63
  context "instance" do
75
64
 
76
65
  TEST_SENTENCE = "The dog plays with the ball."
77
66
 
78
- before( :each ) do
79
- @dict = LinkParser::Dictionary.new(
80
- :verbosity => 0,
81
- :max_null_count => 18,
82
- :echo_on => true
83
- )
67
+ before( :all ) do
68
+ @dict = LinkParser::Dictionary.new( verbosity: 0, max_null_count: 18, islands_ok: true )
84
69
  end
85
70
 
86
71
 
87
- it "knows what the total cost of its linkages are" do
88
- @dict.max_cost.should be_an_instance_of(Fixnum)
89
- end
90
-
91
72
  it "can parse a sentence" do
92
- @dict.parse( TEST_SENTENCE ).
93
- should be_an_instance_of( LinkParser::Sentence )
73
+ sentence = @dict.parse( TEST_SENTENCE )
74
+ expect( sentence ).to be_an_instance_of( LinkParser::Sentence )
94
75
  end
95
76
 
96
77
  it "passes on its options to the sentences it parses" do
97
78
  sentence = @dict.parse( TEST_SENTENCE )
98
- sentence.options.max_null_count.should == 18
99
- sentence.options.verbosity.should == 0
100
- sentence.options.echo_on?.should == true
79
+ expect( sentence.options.max_null_count ).to eq( 18 )
80
+ expect( sentence.options.verbosity ).to eq( 0 )
81
+ expect( sentence.options.islands_ok? ).to eq( true )
101
82
  end
102
83
  end
103
84
 
@@ -1,420 +1,349 @@
1
- #!/usr/bin/ruby -w
2
- #
3
- # Specification for the LinkParser::Linkage class
4
- # $Id: linkage_spec.rb,v 7af8c401b107 2010/12/30 18:00:05 ged $
5
- #
6
- # See the LICENSE file in the distribution for information about copyright and licensing.
7
- #
8
-
9
- BEGIN {
10
- require 'pathname'
11
- basedir = Pathname.new( __FILE__ ).dirname.parent.parent
12
-
13
- libdir = basedir + 'lib'
14
- extdir = basedir + 'ext'
15
-
16
- $LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
17
- $LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
18
- $LOAD_PATH.unshift( extdir.to_s ) unless $LOAD_PATH.include?( extdir.to_s )
19
- }
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
20
3
 
21
- require 'rspec'
4
+ require_relative '../helpers'
22
5
 
6
+ require 'rspec'
23
7
  require 'linkparser'
24
8
 
25
9
 
26
10
  describe LinkParser::Linkage do
27
11
 
28
12
  before( :all ) do
29
- @dict = LinkParser::Dictionary.new( 'en', :verbosity => 0 )
30
- $DEBUG = true if ENV['DEBUG']
13
+ @dict = LinkParser::Dictionary.new( 'en', verbosity: 0 )
31
14
  end
32
15
 
33
- before( :each ) do
34
- @sentence = @dict.parse( "The flag was wet." )
35
- @linkage = @sentence.linkages.first
36
- end
37
16
 
17
+ let( :dict ) { @dict }
38
18
 
39
- # +-------------Xp-------------+
40
- # +-----Wd-----+ |
41
- # | +--Ds-+--Ss-+--Pa-+ |
42
- # | | | | | |
43
- # LEFT-WALL the flag.n was.v wet.a .
44
- it "can build a diagram string for a sentence" do
45
- @linkage.diagram.should =~ /LEFT-WALL/
46
- @linkage.diagram.should =~ /the/
47
- @linkage.diagram.should =~ /flag\.n/
48
- @linkage.diagram.should =~ /was\.v/
49
- @linkage.diagram.should =~ /wet\.a/
50
-
51
- @linkage.diagram.should =~ /-Xp-/
52
- @linkage.diagram.should =~ /-Wd-/
53
- @linkage.diagram.should =~ /-Ds-/
54
- @linkage.diagram.should =~ /-Ss-/
55
- @linkage.diagram.should =~ /-Pa-/
56
- end
57
-
58
-
59
- # LEFT-WALL Xp <---Xp----> Xp .
60
- # (m) LEFT-WALL Wd <---Wd----> Wd flag.n
61
- # (m) the D <---Ds----> Ds flag.n
62
- # (m) flag.n Ss <---Ss----> Ss was.v
63
- # (m) was.v Pa <---Pa----> Pa wet.a
64
- # . RW <---RW----> RW RIGHT-WALL
65
- it "can build a 'links and domains' diagram" do
66
- @linkage.links_and_domains.should =~ /LEFT-WALL/
67
- @linkage.links_and_domains.should =~ /the/
68
- @linkage.links_and_domains.should =~ /flag\.n/
69
- @linkage.links_and_domains.should =~ /was\.v/
70
- @linkage.links_and_domains.should =~ /wet\.a/
19
+ let( :text ) { "The flag was wet." }
20
+ let( :sentence ) { @dict.parse(text) }
21
+ let( :linkage ) { sentence.linkages.first }
71
22
 
72
- @linkage.links_and_domains.should =~ /-Xp-/
73
- @linkage.links_and_domains.should =~ /-Wd-/
74
- @linkage.links_and_domains.should =~ /-Ds-/
75
- @linkage.links_and_domains.should =~ /-Ss-/
76
- @linkage.links_and_domains.should =~ /-Pa-/
23
+
24
+ it "can build a diagram string for a sentence" do
25
+ expect( linkage.diagram.each_line.to_a ).to include(
26
+ " +--------------Xp--------------+\n",
27
+ " +-------->WV------->+ |\n",
28
+ " +---->Wd-----+ | |\n",
29
+ " | +Ds**c+-Ss*s-+--Pa--+ +--RW--+\n",
30
+ " | | | | | | |\n",
31
+ "LEFT-WALL the flag.n was.v-d wet.a . RIGHT-WALL\n",
32
+ )
77
33
  end
78
34
 
79
35
 
80
- it "knows how many words are in the sentence" do
81
- # LEFT-WALL + words + '.' + RIGHT-WALL = 7
82
- @linkage.num_words.should == 7
36
+ it "can build a diagram string for a sentence wrapped to a screen width" do
37
+ diagram = linkage.diagram( max_width: 20 )
38
+ expect( diagram.each_line.map(&:strip).map(&:length) ).to all( be <= 20 )
83
39
  end
84
40
 
85
41
 
86
- it "can return a list of the tokenized words" do
87
- @linkage.words.should include("LEFT-WALL")
88
- @linkage.words.should include("the")
89
- @linkage.words.should include("flag.n")
90
- @linkage.words.should include("was.v-d")
91
- @linkage.words.should include("wet.a")
92
- @linkage.words.should include(".")
93
- @linkage.words.should include("RIGHT-WALL")
42
+ it "can build a diagram string without wall-words" do
43
+ expect( linkage.diagram(display_walls: false) ).to_not include( 'RIGHT-WALL' )
94
44
  end
95
45
 
96
46
 
97
- it "knows how many links are in the sentence" do
98
- @linkage.num_links.should == 6
47
+ it "can build a 'links and domains' diagram" do
48
+ expect( linkage.links_and_domains.each_line.to_a ).to include(
49
+ " LEFT-WALL Xp ----Xp----- Xp .\n",
50
+ " (m) LEFT-WALL hWV >---WV----> dWV was.v-d\n",
51
+ " (m) LEFT-WALL hWd >---Wd----- Wd flag.n\n",
52
+ " (m) flag.n Ss*s ----Ss*s--- Ss was.v-d\n",
53
+ " (m) the D ----Ds**c-- Ds**c flag.n\n",
54
+ " (m) was.v-d Pa ----Pa----- Pa wet.a\n",
55
+ " . RW ----RW----- RW RIGHT-WALL\n",
56
+ "\n"
57
+ )
99
58
  end
100
59
 
101
60
 
102
- it "can return the left word for any of its links" do
103
- # LEFT-WALL Xp <---Xp----> Xp .
104
- @linkage.link_lword( 0 ).should == @linkage.words.index('LEFT-WALL')
61
+ it "knows how many words are in the sentence" do
62
+ # LEFT-WALL + words + '.' + RIGHT-WALL = 7
63
+ expect( linkage.num_words ).to eq( 7 )
64
+ end
105
65
 
106
- # (m) LEFT-WALL Wd <---Wd----> Wd flag.n
107
- @linkage.link_lword( 1 ).should == @linkage.words.index('LEFT-WALL')
108
66
 
109
- # (m) the D <---Ds----> Ds flag.n
110
- @linkage.link_lword( 2 ).should == @linkage.words.index('the')
67
+ it "can return a list of the tokenized words" do
68
+ expect( linkage.words ).to include("LEFT-WALL")
69
+ expect( linkage.words ).to include("the")
70
+ expect( linkage.words ).to include("flag.n")
71
+ expect( linkage.words ).to include("was.v-d")
72
+ expect( linkage.words ).to include("wet.a")
73
+ expect( linkage.words ).to include(".")
74
+ expect( linkage.words ).to include("RIGHT-WALL")
75
+ end
111
76
 
112
- # (m) flag.n Ss <---Ss----> Ss was.v
113
- @linkage.link_lword( 3 ).should == @linkage.words.index('flag.n')
114
77
 
115
- # (m) was.v Pa <---Pa----> Pa wet.a
116
- @linkage.link_lword( 4 ).should == @linkage.words.index('was.v-d')
78
+ it "knows how many links are in the sentence" do
79
+ expect( linkage.num_links ).to eq( 7 )
80
+ end
117
81
 
118
- # . RW <---RW----> RW RIGHT-WALL
119
- @linkage.link_lword( 5 ).should == @linkage.words.index('.')
120
82
 
83
+ it "can return the left word for any of its links" do
84
+ # LEFT-WALL Xp <---Xp----> Xp .
85
+ expect( linkage.link_lword(0) ).to eq( linkage.words.index('LEFT-WALL') )
86
+ # (m) LEFT-WALL WV <---WV----> WV was.v-d
87
+ expect( linkage.link_lword(1) ).to eq( linkage.words.index('LEFT-WALL') )
88
+ # (m) LEFT-WALL Wd <---Wd----> Wd flag.n
89
+ expect( linkage.link_lword(2) ).to eq( linkage.words.index('LEFT-WALL') )
90
+ # (m) flag.n Ss <---Ss----> Ss was.v-d
91
+ expect( linkage.link_lword(3) ).to eq( linkage.words.index('flag.n') )
92
+ # (m) the D <---Ds----> Ds flag.n
93
+ expect( linkage.link_lword(4) ).to eq( linkage.words.index('the') )
94
+ # (m) was.v-d Pa <---Pa----> Pa wet.a
95
+ expect( linkage.link_lword(5) ).to eq( linkage.words.index('was.v-d') )
96
+ # . RW <---RW----> RW RIGHT-WALL
97
+ expect( linkage.link_lword(6) ).to eq( linkage.words.index('.') )
121
98
  end
122
99
 
123
100
  it "can return the right word for any of its links" do
124
- # LEFT-WALL Xp <---Xp----> Xp .
125
- @linkage.link_rword( 0 ).should == @linkage.words.index('.')
126
-
127
- # (m) LEFT-WALL Wd <---Wd----> Wd flag.n
128
- @linkage.link_rword( 1 ).should == @linkage.words.index('flag.n')
129
-
130
- # (m) the D <---Ds----> Ds flag.n
131
- @linkage.link_rword( 2 ).should == @linkage.words.index('flag.n')
132
-
133
- # (m) flag.n Ss <---Ss----> Ss was.v
134
- @linkage.link_rword( 3 ).should == @linkage.words.index('was.v-d')
135
-
136
- # (m) was.v Pa <---Pa----> Pa wet.a
137
- @linkage.link_rword( 4 ).should == @linkage.words.index('wet.a')
138
-
139
- # . RW <---RW----> RW RIGHT-WALL
140
- @linkage.link_rword( 5 ).should == @linkage.words.index('RIGHT-WALL')
141
-
101
+ # LEFT-WALL Xp <---Xp----> Xp .
102
+ expect( linkage.link_rword(0) ).to eq( linkage.words.index('.') )
103
+ # (m) LEFT-WALL WV <---WV----> WV was.v-d
104
+ expect( linkage.link_rword(1) ).to eq( linkage.words.index('was.v-d') )
105
+ # (m) LEFT-WALL Wd <---Wd----> Wd flag.n
106
+ expect( linkage.link_rword(2) ).to eq( linkage.words.index('flag.n') )
107
+ # (m) flag.n Ss <---Ss----> Ss was.v-d
108
+ expect( linkage.link_rword(3) ).to eq( linkage.words.index('was.v-d') )
109
+ # (m) the D <---Ds----> Ds flag.n
110
+ expect( linkage.link_rword(4) ).to eq( linkage.words.index('flag.n') )
111
+ # (m) was.v-d Pa <---Pa----> Pa wet.a
112
+ expect( linkage.link_rword(5) ).to eq( linkage.words.index('wet.a') )
113
+ # . RW <---RW----> RW RIGHT-WALL
114
+ expect( linkage.link_rword(6) ).to eq( linkage.words.index('RIGHT-WALL') )
142
115
  end
143
116
 
144
117
 
145
118
  it "can return the length of any of its links" do
146
- @linkage.link_length( 0 ).should == 5
147
- @linkage.link_length( 1 ).should == 2
148
- @linkage.link_length( 2 ).should == 1
149
- @linkage.link_length( 3 ).should == 1
150
- @linkage.link_length( 4 ).should == 1
151
- @linkage.link_length( 5 ).should == 1
119
+ expect( linkage.link_length(0) ).to eq( 5 )
120
+ expect( linkage.link_length(1) ).to eq( 3 )
121
+ expect( linkage.link_length(2) ).to eq( 2 )
122
+ expect( linkage.link_length(3) ).to eq( 1 )
123
+ expect( linkage.link_length(4) ).to eq( 1 )
124
+ expect( linkage.link_length(5) ).to eq( 1 )
125
+ expect( linkage.link_length(6) ).to eq( 1 )
152
126
 
153
127
  # Out-of-bounds just returns -1
154
- @linkage.link_length( 7 ).should == -1
128
+ expect( linkage.link_length(11) ).to eq( -1 )
155
129
  end
156
130
 
157
131
 
158
132
  it "can return labels for any of its links" do
159
- @linkage.link_label( 0 ).should == "Xp"
160
- @linkage.link_label( 1 ).should == "Wd"
161
- @linkage.link_label( 2 ).should == "Ds"
162
- @linkage.link_label( 3 ).should == "Ss"
163
- @linkage.link_label( 4 ).should == "Pa"
164
- @linkage.link_label( 5 ).should == "RW"
133
+ expect( linkage.link_label(0) ).to eq( "Xp" )
134
+ expect( linkage.link_label(1) ).to eq( "WV" )
135
+ expect( linkage.link_label(2) ).to eq( "Wd" )
136
+ expect( linkage.link_label(3) ).to eq( "Ss*s" )
137
+ expect( linkage.link_label(4) ).to eq( "Ds**c" )
138
+ expect( linkage.link_label(5) ).to eq( "Pa" )
139
+ expect( linkage.link_label(6) ).to eq( "RW" )
165
140
 
166
- @linkage.link_label( 7 ).should be_nil
141
+ expect( linkage.link_label(7) ).to be_nil
167
142
  end
168
143
 
169
144
 
170
145
  it "can return left labels for any of its links" do
171
- @linkage.link_llabel( 0 ).should == "Xp"
172
- @linkage.link_llabel( 1 ).should == "Wd"
173
- @linkage.link_llabel( 2 ).should == "D"
174
- @linkage.link_llabel( 3 ).should == "Ss"
175
- @linkage.link_llabel( 4 ).should == "Pa"
176
- @linkage.link_llabel( 5 ).should == "RW"
146
+ expect( linkage.link_llabel(0) ).to eq( "Xp" )
147
+ expect( linkage.link_llabel(1) ).to eq( "hWV" )
148
+ expect( linkage.link_llabel(2) ).to eq( "hWd" )
149
+ expect( linkage.link_llabel(3) ).to eq( "Ss*s" )
150
+ expect( linkage.link_llabel(4) ).to eq( "D" )
151
+ expect( linkage.link_llabel(5) ).to eq( "Pa" )
152
+ expect( linkage.link_llabel(6) ).to eq( "RW" )
177
153
 
178
- @linkage.link_llabel( 7 ).should be_nil
154
+ expect( linkage.link_llabel(7) ).to be_nil
179
155
  end
180
156
 
181
157
 
182
158
  it "can return labels for any of its links" do
183
- @linkage.link_rlabel( 0 ).should == "Xp"
184
- @linkage.link_rlabel( 1 ).should == "Wd"
185
- @linkage.link_rlabel( 2 ).should == "Ds"
186
- @linkage.link_rlabel( 3 ).should == "Ss"
187
- @linkage.link_rlabel( 4 ).should == "Pa"
188
- @linkage.link_rlabel( 5 ).should == "RW"
159
+ expect( linkage.link_rlabel(0) ).to eq( "Xp" )
160
+ expect( linkage.link_rlabel(1) ).to eq( "dWV" )
161
+ expect( linkage.link_rlabel(2) ).to eq( "Wd" )
162
+ expect( linkage.link_rlabel(3) ).to eq( "Ss" )
163
+ expect( linkage.link_rlabel(4) ).to eq( "Ds**c" )
164
+ expect( linkage.link_rlabel(5) ).to eq( "Pa" )
165
+ expect( linkage.link_rlabel(6) ).to eq( "RW" )
189
166
 
190
- @linkage.link_rlabel( 7 ).should be_nil
167
+ expect( linkage.link_rlabel(7) ).to be_nil
191
168
  end
192
169
 
193
170
 
194
171
  it "can return the number of domains for any link" do
195
- @linkage.link_num_domains( 0 ).should == 0
196
- 1.upto(4) do |i|
197
- @linkage.link_num_domains( i ).should == 1
198
- end
199
- @linkage.link_num_domains( 5 ).should == 0
172
+ pending "are domains deprecated or something?"
173
+ expect( linkage.link_num_domains(0) ).to eq( -1 )
174
+ expect( linkage.link_num_domains(1) ).to eq( 1 )
175
+ expect( linkage.link_num_domains(2) ).to eq( 1 )
176
+ expect( linkage.link_num_domains(3) ).to eq( 1 )
177
+ expect( linkage.link_num_domains(4) ).to eq( 1 )
178
+ expect( linkage.link_num_domains(5) ).to eq( 1 )
179
+ expect( linkage.link_num_domains(6) ).to eq( 0 )
200
180
 
201
- @linkage.link_num_domains( 112 ).should == -1
181
+ expect( linkage.link_num_domains(112) ).to eq( -1 )
202
182
  end
203
183
 
204
184
 
205
185
  it "can return the names of the domains of any of its links" do
206
- @linkage.link_domain_names( 0 ).should be_an_instance_of( Array )
207
- @linkage.link_domain_names( 0 ).should be_empty
186
+ pending "are domains deprecated or something?"
187
+ expect( linkage.link_domain_names(0) ).to be_an_instance_of( Array )
188
+ expect( linkage.link_domain_names(0) ).to be_empty
208
189
 
209
- 1.upto(4) do |i|
210
- @linkage.link_domain_names( i ).should be_an_instance_of( Array )
211
- @linkage.link_domain_names( i ).should == ["m"]
212
- end
190
+ expect( linkage.link_domain_names(1) ).to be_an_instance_of( Array )
191
+ expect( linkage.link_domain_names(1) ).to eq( ['m'] )
192
+
193
+ expect( linkage.link_domain_names(2) ).to be_an_instance_of( Array )
194
+ expect( linkage.link_domain_names(2) ).to eq( ['m'] )
195
+
196
+ expect( linkage.link_domain_names(3) ).to be_an_instance_of( Array )
197
+ expect( linkage.link_domain_names(3) ).to eq( ["m"] )
213
198
 
214
- @linkage.link_domain_names( 5 ).should be_an_instance_of( Array )
215
- @linkage.link_domain_names( 5 ).should be_empty
199
+ expect( linkage.link_domain_names(4) ).to be_an_instance_of( Array )
200
+ expect( linkage.link_domain_names(4) ).to eq( ['m'] )
216
201
 
217
- @linkage.link_domain_names( 12 ).should be_an_instance_of( Array )
218
- @linkage.link_domain_names( 12 ).should be_empty
202
+ expect( linkage.link_domain_names(5) ).to be_an_instance_of( Array )
203
+ expect( linkage.link_domain_names(5) ).to eq( ['m'] )
204
+
205
+ expect( linkage.link_domain_names(6) ).to be_an_instance_of( Array )
206
+ expect( linkage.link_domain_names(6) ).to be_empty
207
+
208
+ expect( linkage.link_domain_names(12) ).to be_an_instance_of( Array )
209
+ expect( linkage.link_domain_names(12) ).to be_empty
219
210
  end
220
211
 
221
212
 
222
213
  it "can return the disjunct strings for any of its words" do
223
- @linkage.disjunct_strings.should have( @linkage.num_words ).members
214
+ expect( linkage.disjunct_strings.length ).to eq( linkage.num_words )
224
215
  end
225
216
 
226
217
 
227
218
  it "can return parsed disjuncts for any of its words" do
228
- @linkage.disjuncts.should have( @linkage.num_words ).members
219
+ expect( linkage.disjuncts.length ).to eq( linkage.num_words )
229
220
  end
230
221
 
231
222
 
232
223
  it "can report on the various cost metrics of the parse" do
233
- @linkage.unused_word_cost.should be_an_instance_of( Fixnum )
234
- @linkage.disjunct_cost.should be_an_instance_of( Fixnum )
235
- @linkage.and_cost.should be_an_instance_of( Fixnum )
236
- @linkage.link_cost.should be_an_instance_of( Fixnum )
224
+ expect( linkage.unused_word_cost ).to be_an_instance_of( Integer )
225
+ expect( linkage.disjunct_cost ).to be_an_instance_of( Integer )
226
+ expect( linkage.link_cost ).to be_an_instance_of( Integer )
237
227
  end
238
228
 
239
229
 
240
- ### :FIXME: I don't know what these do/mean yet, so for now just test to
230
+ ### :FIXME: I don't know what these do/mean yet, so for now just test to
241
231
  ### make sure they're implemented. They should really be tested with
242
232
  ### sentences that have predictable results.
243
233
  it "implements Link Grammar predicate methods" do
244
- @linkage.should respond_to( :canonical? )
245
- @linkage.should respond_to( :improper? )
246
- @linkage.should respond_to( :has_inconsistent_domains? )
247
- @linkage.should respond_to( :violation_name )
234
+ expect( linkage ).to respond_to( :violation_name )
248
235
  end
249
236
 
250
237
 
251
- # LEFT-WALL Xp <---Xp----> Xp .
252
- # (m) LEFT-WALL Wd <---Wd----> Wd flag.n
253
- # (m) the D <---Ds----> Ds flag.n
254
- # (m) flag.n Ss <---Ss----> Ss was.v
255
- # (m) was.v Pa <---Pa----> Pa wet.a
256
- # . RW <---RW----> RW RIGHT-WALL
238
+ # LEFT-WALL Xp ----Xp----- Xp .
239
+ # (m) LEFT-WALL hWV >---WV----> dWV was.v-d
240
+ # (m) LEFT-WALL hWd >---Wd----- Wd flag.n
241
+ # (m) flag.n Ss*s ----Ss*s--- Ss was.v-d
242
+ # (m) the D ----Ds**c-- Ds**c flag.n
243
+ # (m) was.v-d Pa ----Pa----- Pa wet.a
244
+ # . RW ----RW----- RW RIGHT-WALL
257
245
  it "contains link structs describing the linkage" do
258
- @linkage.should have(6).links
259
- @linkage.links.should be_an_instance_of( Array )
246
+ expect( linkage.links ).to be_an_instance_of( Array )
247
+ expect( linkage.links.length ).to eq( 7 )
260
248
 
261
- @linkage.links.each do |link|
262
- link.should be_a_kind_of( Struct )
249
+ linkage.links.each do |link|
250
+ expect( link ).to be_a_kind_of( Struct )
263
251
  end
264
252
 
265
- @linkage.links.first.lword.should == 'LEFT-WALL'
266
- @linkage.links.first.label.should == 'Xp'
267
- @linkage.links.last.rword.should == 'RIGHT-WALL'
268
- @linkage.links.last.label.should == 'RW'
269
- @linkage.links[3].lword.should == 'flag.n'
270
- @linkage.links[3].rword.should == 'was.v-d'
271
- @linkage.links[3].label.should == 'Ss'
253
+ expect( linkage.links.first.lword ).to eq( 'LEFT-WALL' )
254
+ expect( linkage.links.first.label ).to eq( 'Xp' )
255
+ expect( linkage.links.last.rword ).to eq( 'RIGHT-WALL' )
256
+ expect( linkage.links.last.label ).to eq( 'RW' )
257
+ expect( linkage.links[3].lword ).to eq( 'flag.n' )
258
+ expect( linkage.links[3].rword ).to eq( 'was.v-d' )
259
+ expect( linkage.links[3].label ).to eq( 'Ss*s' )
272
260
  end
273
261
 
274
262
 
275
263
  it "knows what word is the verb in the sentence" do
276
- @linkage.verb.should == "was"
264
+ expect( linkage.verb ).to eq( "was" )
277
265
  end
278
266
 
279
267
 
280
- it "knows what word is the subject of the sentence" do
281
- @linkage.subject.should == "flag"
268
+ it "can return the verb without stripping the subscript" do
269
+ expect( linkage.verb(keep_subscript: true) ).to eq( "was.v-d" )
282
270
  end
283
271
 
284
272
 
285
- it "knows when the sentence doesn't have a direct object" do
286
- @linkage.object.should be_nil()
273
+ it "knows what word is the subject of the sentence" do
274
+ expect( linkage.subject ).to eq( "flag" )
287
275
  end
288
276
 
289
277
 
290
- it "knows which of its words are nouns" do
291
- @linkage.nouns.should have(1).member
292
- @linkage.nouns.should include( "flag" )
278
+ it "can return the subject without stripping the subscript" do
279
+ expect( linkage.subject(keep_subscript: true) ).to eq( "flag.n" )
293
280
  end
294
281
 
295
282
 
296
- MODE1_C_TREE_STRING = "(S (NP The flag)\n (VP was\n (ADJP wet))\n .)\n"
297
- MODE2_C_TREE_STRING = "[S [NP The flag NP] [VP was [ADJP wet ADJP] VP] . S] \n"
298
- MODE3_C_TREE_STRING = "(S (NP The flag) (VP was (ADJP wet)) .)\n"
283
+ context "for sentences with a direct object" do
299
284
 
300
- it "returns an indented sexps for the constituent tree string by default (mode 1)" do
301
- @linkage.constituent_tree_string.should == MODE1_C_TREE_STRING
302
- end
285
+ let( :text ) { "The dog fetches the ball." }
303
286
 
304
287
 
305
- it "returns indented sexps for the constituent tree string if fetched with explicit mode '1'" do
306
- @linkage.constituent_tree_string( 1 ).should == MODE1_C_TREE_STRING
307
- end
308
-
309
- it "returns bracketed constituents if constituent tree string is fetched in mode 2" do
310
- @linkage.constituent_tree_string( 2 ).should == MODE2_C_TREE_STRING
311
- end
288
+ it "knows what word is the object of the sentence" do
289
+ expect( linkage.object ).to eq( "ball" )
290
+ end
312
291
 
313
- it "returns unindented sexps for the constituent tree string if constituent tree string " +
314
- "is fetched in mode 3" do
315
- @linkage.constituent_tree_string( 3 ).should == MODE3_C_TREE_STRING
316
- end
317
292
 
318
- it "raises an exception for any numeric constituent tree string mode greater than 3" do
319
- expect {
320
- @linkage.constituent_tree_string( 4 )
321
- }.to raise_error( ArgumentError, /illegal mode 4/i )
322
- end
293
+ it "can return the object without stripping the subscript" do
294
+ expect( linkage.object(keep_subscript: true) ).to eq( linkage.words[5] )
295
+ end
323
296
 
324
- it "raises an exception for any numeric constituent tree string mode less than 1" do
325
- expect {
326
- @linkage.constituent_tree_string( 0 )
327
- }.to raise_error( ArgumentError, /illegal mode 0/i )
328
297
  end
329
298
 
330
299
 
331
- it "raises an exception when a non-numeric constituent tree string mode is given" do
332
- expect {
333
- @linkage.constituent_tree_string( 'glarg' )
334
- }.to raise_error( TypeError )
300
+ it "knows when the sentence doesn't have a direct object" do
301
+ expect( linkage.object ).to be_nil()
335
302
  end
336
303
 
337
- it "returns an Array of CTree structs for its constituent tree" do
338
- rval = @linkage.constituent_tree
339
304
 
340
- rval.should be_an_instance_of( Array )
341
- rval.should have(1).members
342
- rval.first.should be_a_kind_of( Struct )
343
- rval.first.label.should == 'S'
344
- rval.first.children.should have(3).members
345
- rval.first.children.collect {|n| n.label }.should include( 'NP', 'VP', '.' )
305
+ it "knows which of its words are nouns" do
306
+ expect( linkage.nouns.size ).to eq( 1 )
307
+ expect( linkage.nouns ).to include( "flag" )
346
308
  end
347
309
 
310
+
348
311
  it "returns an informational string when inspected" do
349
- @linkage.inspect.should =~ /Linkage:0x[[:xdigit:]]+: \[\d+ links\]/
312
+ expect( linkage.inspect ).to match( /Linkage:0x[[:xdigit:]]+: \[\d+ links\]/ )
350
313
  end
351
314
 
352
315
 
353
316
  context "from a simple sentence with a direct object" do
354
- before( :each ) do
355
- @sentence = @dict.parse( "The dog ran home." )
356
- @linkage = @sentence.linkages.first
357
- end
358
-
359
-
360
- it "knows what word is the object in the sentence" do
361
- # This depends on the linkage:
362
- # +---------------Xp---------------+
363
- # +-----Wd----+ |
364
- # | +-Ds-+--Ss--+---Ou---+ |
365
- # | | | | | |
366
- # LEFT-WALL the dog.n ran.v-d home.n-u .
367
- @sentence.object.should == 'home'
368
317
 
369
- end
370
-
371
- end
318
+ let( :text ) { "The dog fetches the ball." }
372
319
 
373
320
 
374
- context "deprecated sublinkage API" do
375
-
376
- before( :each ) do
377
- @sentence = @dict.parse( "The ball rolled down the hill and bumped the curb." )
378
- @linkage = @sentence.linkages.first
379
- end
380
-
381
- it "warns about deprecation if #num_sublinkages is called" do
382
- @linkage.should_receive( :warn ).with( /deprecated/i )
383
- @linkage.num_sublinkages
384
- end
385
-
386
- it "warns about deprecation if #compute_union is called" do
387
- @linkage.should_receive( :warn ).with( /deprecated/i )
388
- @linkage.compute_union
389
- end
390
-
391
- it "warn about deprecation if #current_sublinkage= is called" do
392
- @linkage.should_receive( :warn ).with( /deprecated/i )
393
- @linkage.current_sublinkage = 1
394
- end
321
+ it "knows what word is the object in the sentence" do
322
+ # +------------------Xp------------------+
323
+ # +-------->WV------->+ |
324
+ # +-----Wd----+ +------Ou-----+ |
325
+ # | +Ds**+---Ss--+ +--Dmu-+ +--RW--+
326
+ # | | | | | | | |
327
+ # LEFT-WALL the dog.n fetches.v the ball.n-u . RIGHT-WALL
328
+ expect( sentence.object ).to eq( 'ball' )
395
329
 
396
- it "warn about deprecation if #current_sublinkage is called" do
397
- @linkage.should_receive( :warn ).with( /deprecated/i )
398
- @linkage.current_sublinkage
399
330
  end
400
331
 
401
332
  end
402
333
 
403
334
 
404
335
  it "should know that it's not an imperative sentence" do
405
- @linkage.imperative?.should be_false()
336
+ expect( linkage.imperative? ).to be_falsey()
406
337
  end
407
338
 
408
339
 
409
340
  context "from an imperative sentence" do
410
- before( :each ) do
411
- @sentence = @dict.parse( "Go to the store!" )
412
- @linkage = @sentence.linkages.first
413
- end
341
+
342
+ let( :text ) { "Go to the store!" }
414
343
 
415
344
 
416
345
  it "knows that it's an imperative sentence" do
417
- @linkage.imperative?.should be_true()
346
+ expect( linkage.imperative? ).to be_truthy()
418
347
  end
419
348
 
420
349
 
@@ -424,9 +353,16 @@ describe LinkParser::Linkage do
424
353
  context "bugfixes" do
425
354
 
426
355
  it "also strips off the '.p' from the subject and object when they are plural" do
427
- sent = @dict.parse( 'People like goats.' )
428
- sent.subject.should_not =~ /people\.p/i
429
- sent.object.should_not =~ /goats\.p/i
356
+ sent = dict.parse( 'People like goats.' )
357
+ expect( sent.subject ).to_not match( /people\.p/i )
358
+ expect( sent.object ).to_not match( /goats\.p/i )
359
+ end
360
+
361
+
362
+ it "raises an exception if the diagram screen_width is too small", skip_version: '5.4.2' do
363
+ expect {
364
+ linkage.diagram( max_width: 2 )
365
+ }.to raise_error( /can't create a diagram/i )
430
366
  end
431
367
 
432
368
  end