linkparser 1.1.3 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.md +68 -3
- data/README.md +66 -47
- data/ext/{dictionary.c → linkparser_ext/dictionary.c} +61 -66
- data/ext/{extconf.rb → linkparser_ext/extconf.rb} +10 -3
- data/ext/{linkage.c → linkparser_ext/linkage.c} +121 -358
- data/ext/{linkparser.c → linkparser_ext/linkparser.c} +79 -28
- data/ext/{linkparser.h → linkparser_ext/linkparser.h} +14 -16
- data/ext/linkparser_ext/parseoptions.c +776 -0
- data/ext/{sentence.c → linkparser_ext/sentence.c} +65 -151
- data/lib/linkparser.rb +14 -6
- data/lib/linkparser/dictionary.rb +13 -0
- data/lib/linkparser/linkage.rb +271 -166
- data/lib/linkparser/mixins.rb +2 -3
- data/lib/linkparser/parseoptions.rb +58 -0
- data/lib/linkparser/sentence.rb +21 -38
- data/spec/bugfixes_spec.rb +23 -36
- data/spec/helpers.rb +39 -0
- data/spec/linkparser/dictionary_spec.rb +29 -48
- data/spec/linkparser/linkage_spec.rb +212 -276
- data/spec/linkparser/mixins_spec.rb +9 -24
- data/spec/linkparser/parseoptions_spec.rb +47 -59
- data/spec/linkparser/sentence_spec.rb +36 -56
- data/spec/linkparser_spec.rb +11 -25
- metadata +134 -174
- metadata.gz.sig +0 -0
- data/.gemtest +0 -0
- data/ChangeLog +0 -670
- data/LICENSE +0 -27
- data/Rakefile +0 -91
- data/ext/parseoptions.c +0 -1236
data/lib/linkparser/mixins.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
|
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
|
data/lib/linkparser/sentence.rb
CHANGED
@@ -1,28 +1,16 @@
|
|
1
|
-
|
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
|
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
|
-
|
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
|
-
|
79
|
-
|
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
|
data/spec/bugfixes_spec.rb
CHANGED
@@ -1,48 +1,35 @@
|
|
1
|
-
|
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
|
-
|
4
|
+
require_relative 'helpers'
|
22
5
|
|
6
|
+
require 'rspec'
|
23
7
|
require 'linkparser'
|
24
8
|
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
13
|
+
@dict = LinkParser::Dictionary.new('en', verbosity: 0)
|
31
14
|
end
|
32
15
|
|
33
|
-
|
34
|
-
|
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
|
-
|
41
|
-
|
42
|
-
|
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
|
data/spec/helpers.rb
ADDED
@@ -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
|
-
|
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
|
-
|
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
|
-
###
|
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.
|
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 )
|
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
|
-
|
35
|
+
expect {
|
50
36
|
LinkParser::Dictionary.new( "foo", "bar", "baz" )
|
51
|
-
}.
|
37
|
+
}.to raise_error( ArgumentError )
|
52
38
|
end
|
53
39
|
|
54
40
|
it "can be instantiated with a language argument" do
|
55
|
-
|
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)
|
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
|
63
|
-
|
64
|
-
LinkParser::Dictionary.new(
|
65
|
-
}.
|
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
|
-
|
57
|
+
expect {
|
70
58
|
LinkParser::Dictionary.new('zz')
|
71
|
-
}.
|
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( :
|
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
|
-
|
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.
|
99
|
-
sentence.options.verbosity.
|
100
|
-
sentence.options.
|
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
|
-
|
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
|
-
|
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', :
|
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
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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 "
|
81
|
-
|
82
|
-
|
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
|
87
|
-
|
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 "
|
98
|
-
|
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 "
|
103
|
-
|
104
|
-
|
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
|
-
|
110
|
-
|
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
|
-
|
116
|
-
|
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
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
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
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
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
|
-
|
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
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
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
|
-
|
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
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
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
|
-
|
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
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
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
|
-
|
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
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
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
|
-
|
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
|
-
|
207
|
-
|
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
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
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
|
-
|
215
|
-
|
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
|
-
|
218
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
234
|
-
|
235
|
-
|
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
|
-
|
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
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
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
|
-
|
259
|
-
|
246
|
+
expect( linkage.links ).to be_an_instance_of( Array )
|
247
|
+
expect( linkage.links.length ).to eq( 7 )
|
260
248
|
|
261
|
-
|
262
|
-
link.
|
249
|
+
linkage.links.each do |link|
|
250
|
+
expect( link ).to be_a_kind_of( Struct )
|
263
251
|
end
|
264
252
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
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
|
-
|
264
|
+
expect( linkage.verb ).to eq( "was" )
|
277
265
|
end
|
278
266
|
|
279
267
|
|
280
|
-
it "
|
281
|
-
|
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
|
286
|
-
|
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 "
|
291
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
306
|
-
|
307
|
-
|
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
|
-
|
319
|
-
|
320
|
-
|
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 "
|
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
|
-
|
341
|
-
|
342
|
-
|
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
|
-
|
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
|
-
|
370
|
-
|
371
|
-
end
|
318
|
+
let( :text ) { "The dog fetches the ball." }
|
372
319
|
|
373
320
|
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
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
|
-
|
336
|
+
expect( linkage.imperative? ).to be_falsey()
|
406
337
|
end
|
407
338
|
|
408
339
|
|
409
340
|
context "from an imperative sentence" do
|
410
|
-
|
411
|
-
|
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
|
-
|
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 =
|
428
|
-
sent.subject.
|
429
|
-
sent.object.
|
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
|