activefacts 0.8.10 → 0.8.12
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/Rakefile +3 -2
- data/bin/afgen +25 -23
- data/bin/cql +9 -8
- data/css/orm2.css +23 -3
- data/examples/CQL/CompanyDirectorEmployee.cql +1 -1
- data/examples/CQL/Diplomacy.cql +3 -3
- data/examples/CQL/Insurance.cql +27 -21
- data/examples/CQL/Metamodel.cql +12 -8
- data/examples/CQL/MetamodelNext.cql +172 -149
- data/examples/CQL/ServiceDirector.cql +17 -17
- data/examples/CQL/Supervision.cql +3 -5
- data/examples/CQL/WaiterTips.cql +1 -1
- data/examples/CQL/unit.cql +1 -1
- data/index.html +0 -0
- data/lib/activefacts/cql/FactTypes.treetop +41 -8
- data/lib/activefacts/cql/Language/English.treetop +10 -0
- data/lib/activefacts/cql/ObjectTypes.treetop +3 -1
- data/lib/activefacts/cql/Terms.treetop +34 -53
- data/lib/activefacts/cql/compiler.rb +1 -1
- data/lib/activefacts/cql/compiler/clause.rb +21 -8
- data/lib/activefacts/cql/compiler/constraint.rb +3 -1
- data/lib/activefacts/cql/compiler/entity_type.rb +1 -1
- data/lib/activefacts/cql/compiler/fact_type.rb +9 -3
- data/lib/activefacts/cql/compiler/join.rb +3 -0
- data/lib/activefacts/cql/compiler/value_type.rb +9 -4
- data/lib/activefacts/cql/parser.rb +11 -3
- data/lib/activefacts/generate/oo.rb +3 -3
- data/lib/activefacts/generate/ordered.rb +0 -4
- data/lib/activefacts/input/orm.rb +305 -250
- data/lib/activefacts/persistence/tables.rb +6 -0
- data/lib/activefacts/support.rb +18 -0
- data/lib/activefacts/version.rb +1 -1
- data/lib/activefacts/vocabulary/extensions.rb +59 -20
- data/lib/activefacts/vocabulary/metamodel.rb +23 -13
- data/lib/activefacts/vocabulary/verbaliser.rb +5 -3
- data/spec/absorption_spec.rb +3 -2
- data/spec/cql/comparison_spec.rb +1 -3
- data/spec/cql/context_spec.rb +1 -1
- data/spec/cql/entity_type_spec.rb +2 -2
- data/spec/cql/expressions_spec.rb +2 -4
- data/spec/cql/fact_type_matching_spec.rb +55 -3
- data/spec/cql/parser/fact_types_spec.rb +3 -0
- data/spec/cql/role_matching_spec.rb +8 -7
- data/spec/cql/samples_spec.rb +10 -2
- data/spec/cql_dm_spec.rb +2 -1
- data/spec/helpers/array_matcher.rb +18 -35
- data/spec/helpers/diff_matcher.rb +34 -13
- data/spec/helpers/file_matcher.rb +27 -43
- data/spec/helpers/string_matcher.rb +23 -33
- data/spec/norma_cql_spec.rb +1 -0
- data/spec/norma_tables_spec.rb +1 -2
- metadata +95 -102
@@ -237,6 +237,12 @@ module ActiveFacts
|
|
237
237
|
}
|
238
238
|
debug :absorption, "#{object_type.name} has #{non_identifying_refs_from.size} non-identifying functional roles"
|
239
239
|
|
240
|
+
# If all non-identifying functional roles are one-to-ones that can be flipped, do that:
|
241
|
+
if non_identifying_refs_from.all? { |ref| ref.role_type == :one_one && (ref.to.is_table || ref.to.tentative) }
|
242
|
+
non_identifying_refs_from.each { |ref| ref.flip }
|
243
|
+
non_identifying_refs_from = []
|
244
|
+
end
|
245
|
+
|
240
246
|
if object_type.references_to.size > 1 and
|
241
247
|
non_identifying_refs_from.size > 0
|
242
248
|
debug :absorption, "#{object_type.name} has non-identifying functional dependencies so 3NF requires it be a table"
|
data/lib/activefacts/support.rb
CHANGED
@@ -150,3 +150,21 @@ class Array
|
|
150
150
|
self
|
151
151
|
end
|
152
152
|
end
|
153
|
+
|
154
|
+
# Load the ruby debugger before everything else, if requested
|
155
|
+
if debug :debug
|
156
|
+
begin
|
157
|
+
require 'ruby-debug'
|
158
|
+
Debugger.start # (:post_mortem => true) # Some Ruby versions crash on post-mortem debugging
|
159
|
+
rescue LoadError
|
160
|
+
# Ok, no debugger, tough luck.
|
161
|
+
end
|
162
|
+
|
163
|
+
if debug :trap
|
164
|
+
trap('SIGINT') do
|
165
|
+
puts "Stopped at:\n\t"+caller*"\n\t"
|
166
|
+
debugger
|
167
|
+
true
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
data/lib/activefacts/version.rb
CHANGED
@@ -53,6 +53,10 @@ module ActiveFacts
|
|
53
53
|
reading.text =~ /\{\d\}/ and reading.role_sequence.all_role_ref_in_order[$1.to_i].role == role
|
54
54
|
end || preferred_reading
|
55
55
|
end
|
56
|
+
|
57
|
+
def all_role_in_order
|
58
|
+
all_role.sort_by{|r| r.ordinal}
|
59
|
+
end
|
56
60
|
end
|
57
61
|
|
58
62
|
class Role
|
@@ -179,7 +183,7 @@ module ActiveFacts
|
|
179
183
|
|
180
184
|
class EntityType
|
181
185
|
def preferred_identifier
|
182
|
-
|
186
|
+
return @preferred_identifier if @preferred_identifier
|
183
187
|
if fact_type
|
184
188
|
|
185
189
|
# For a nested fact type, the PI is a unique constraint over N or N-1 roles
|
@@ -390,39 +394,43 @@ module ActiveFacts
|
|
390
394
|
(0...role_refs.size).each{|i|
|
391
395
|
role_ref = role_refs[i]
|
392
396
|
role = role_ref.role
|
393
|
-
|
394
|
-
|
397
|
+
l_adj = "#{role_ref.leading_adjective}".sub(/(\b-\b|.\b|.\Z)/, '\1-').sub(/\b--\b/,'-- ').sub(/- /,'- ')
|
398
|
+
l_adj = nil if l_adj == ""
|
395
399
|
# Double the space to compensate for space removed below
|
396
|
-
|
397
|
-
|
400
|
+
# REVISIT: hyphenated trailing adjectives are not correctly represented here
|
401
|
+
t_adj = "#{role_ref.trailing_adjective}".sub(/(\b.|\A.)/, '-\1').sub(/ -/,' -')
|
402
|
+
t_adj = nil if t_adj == ""
|
398
403
|
|
399
|
-
expanded.gsub!(/\{#{i}\}/)
|
404
|
+
expanded.gsub!(/\{#{i}\}/) do
|
400
405
|
role_ref = role_refs[i]
|
401
406
|
player = role_ref.role.object_type
|
402
407
|
role_name = role.role_name
|
403
408
|
role_name = nil if role_name == ""
|
404
409
|
if role_name && define_role_names == false
|
405
|
-
|
410
|
+
l_adj = t_adj = nil # When using role names, don't add adjectives
|
406
411
|
end
|
407
|
-
|
408
|
-
|
409
|
-
if
|
410
|
-
|
412
|
+
freq_con = frequency_constraints[i]
|
413
|
+
freq_con = freq_con.frequency if freq_con && freq_con.is_a?(ActiveFacts::Metamodel::PresenceConstraint)
|
414
|
+
if freq_con.is_a?(Array)
|
415
|
+
freq_con, player_name = *freq_con
|
411
416
|
else
|
412
417
|
player_name = player.name
|
413
418
|
end
|
414
419
|
literal = literals[i]
|
415
|
-
[
|
416
|
-
|
417
|
-
|
420
|
+
words = [
|
421
|
+
freq_con ? freq_con : nil,
|
422
|
+
l_adj,
|
418
423
|
define_role_names == false && role_name ? role_name : player_name,
|
419
|
-
|
424
|
+
t_adj,
|
420
425
|
define_role_names && role_name && player.name != role_name ? "(as #{role_name})" : nil,
|
421
426
|
# Can't have both a literal and a value constraint, but we don't enforce that here:
|
422
427
|
literal ? literal : nil
|
423
|
-
]
|
424
|
-
|
425
|
-
|
428
|
+
]
|
429
|
+
if (subscript_block)
|
430
|
+
words = subscript_block.call(role_ref, *words)
|
431
|
+
end
|
432
|
+
words.compact*" "
|
433
|
+
end
|
426
434
|
}
|
427
435
|
expanded.gsub!(/ ?- ?/, '-') # Remove single spaces around adjectives
|
428
436
|
#debug "Expanded '#{expanded}' using #{frequency_constraints.inspect}"
|
@@ -441,6 +449,37 @@ module ActiveFacts
|
|
441
449
|
end
|
442
450
|
end
|
443
451
|
end
|
452
|
+
|
453
|
+
# Return the array of the numbers of the RoleRefs inserted into this reading from the role_sequence
|
454
|
+
def role_numbers
|
455
|
+
text.scan(/\{(\d)\}/).flatten.map{|m| Integer(m) }
|
456
|
+
end
|
457
|
+
|
458
|
+
def expand_with_final_presence_constraint &b
|
459
|
+
# Arrange the roles in order they occur in this reading:
|
460
|
+
role_refs = role_sequence.all_role_ref_in_order
|
461
|
+
role_numbers = text.scan(/\{(\d)\}/).flatten.map{|m| Integer(m) }
|
462
|
+
roles = role_numbers.map{|m| role_refs[m].role }
|
463
|
+
fact_constraints = fact_type.internal_presence_constraints
|
464
|
+
|
465
|
+
# Find the constraints that constrain frequency over each role we can verbalise:
|
466
|
+
frequency_constraints = []
|
467
|
+
roles.each do |role|
|
468
|
+
frequency_constraints <<
|
469
|
+
if (role == roles.last) # On the last role of the reading, emit any presence constraint
|
470
|
+
constraint = fact_constraints.
|
471
|
+
detect do |c| # Find a UC that spans all other Roles
|
472
|
+
c.is_a?(ActiveFacts::Metamodel::PresenceConstraint) &&
|
473
|
+
roles-c.role_sequence.all_role_ref.map(&:role) == [role]
|
474
|
+
end
|
475
|
+
constraint && constraint.frequency
|
476
|
+
else
|
477
|
+
nil
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
expand(frequency_constraints) { |*a| b && b.call(*a) }
|
482
|
+
end
|
444
483
|
end
|
445
484
|
|
446
485
|
class ValueConstraint
|
@@ -482,7 +521,7 @@ module ActiveFacts
|
|
482
521
|
min_literal = min.literal
|
483
522
|
end
|
484
523
|
else
|
485
|
-
min_literal = infinity ? "
|
524
|
+
min_literal = infinity ? "-Infinity" : ""
|
486
525
|
end
|
487
526
|
if max = value_range.maximum_bound
|
488
527
|
max = max.value
|
@@ -492,7 +531,7 @@ module ActiveFacts
|
|
492
531
|
max_literal = max.literal
|
493
532
|
end
|
494
533
|
else
|
495
|
-
max_literal = infinity ? "
|
534
|
+
max_literal = infinity ? "Infinity" : ""
|
496
535
|
end
|
497
536
|
|
498
537
|
min_literal +
|
@@ -41,6 +41,10 @@ module ActiveFacts
|
|
41
41
|
value_type
|
42
42
|
end
|
43
43
|
|
44
|
+
class DisjunctionId < AutoCounter
|
45
|
+
value_type
|
46
|
+
end
|
47
|
+
|
44
48
|
class DisplayRoleNamesSetting < String
|
45
49
|
value_type
|
46
50
|
restrict 'false', 'true'
|
@@ -182,6 +186,11 @@ module ActiveFacts
|
|
182
186
|
has_one :object_type # See ObjectType.all_context_note
|
183
187
|
end
|
184
188
|
|
189
|
+
class Disjunction
|
190
|
+
identified_by :disjunction_id
|
191
|
+
one_to_one :disjunction_id, :mandatory => true # See DisjunctionId.disjunction
|
192
|
+
end
|
193
|
+
|
185
194
|
class Enforcement
|
186
195
|
identified_by :constraint
|
187
196
|
has_one :agent # See Agent.all_enforcement
|
@@ -300,9 +309,9 @@ module ActiveFacts
|
|
300
309
|
has_one :coefficient # See Coefficient.all_unit
|
301
310
|
has_one :ephemera_url, :class => EphemeraURL # See EphemeraURL.all_unit
|
302
311
|
maybe :is_fundamental
|
303
|
-
|
312
|
+
one_to_one :name, :mandatory => true # See Name.unit
|
304
313
|
has_one :offset # See Offset.all_unit
|
305
|
-
|
314
|
+
one_to_one :plural_name, :class => Name # See Name.unit_as_plural_name
|
306
315
|
one_to_one :unit_id, :mandatory => true # See UnitId.unit
|
307
316
|
has_one :vocabulary, :mandatory => true # See Vocabulary.all_unit
|
308
317
|
end
|
@@ -380,6 +389,7 @@ module ActiveFacts
|
|
380
389
|
|
381
390
|
class JoinStep
|
382
391
|
identified_by :input_join_role, :output_join_role
|
392
|
+
has_one :disjunction # See Disjunction.all_join_step
|
383
393
|
has_one :fact_type, :mandatory => true # See FactType.all_join_step
|
384
394
|
has_one :input_join_role, :class => JoinRole, :mandatory => true # See JoinRole.all_join_step_as_input_join_role
|
385
395
|
maybe :is_anti
|
@@ -400,7 +410,6 @@ module ActiveFacts
|
|
400
410
|
end
|
401
411
|
|
402
412
|
class ObjectTypeShape < Shape
|
403
|
-
maybe :has_expanded_reference_mode
|
404
413
|
has_one :object_type, :mandatory => true # See ObjectType.all_object_type_shape
|
405
414
|
end
|
406
415
|
|
@@ -491,9 +500,7 @@ module ActiveFacts
|
|
491
500
|
|
492
501
|
class EntityType < ObjectType
|
493
502
|
one_to_one :fact_type # See FactType.entity_type
|
494
|
-
|
495
|
-
|
496
|
-
class ImplicitBooleanValueType < ValueType
|
503
|
+
maybe :is_implied_by_objectification
|
497
504
|
end
|
498
505
|
|
499
506
|
class Facet
|
@@ -502,6 +509,16 @@ module ActiveFacts
|
|
502
509
|
has_one :value_type, :mandatory => true # See ValueType.all_facet
|
503
510
|
end
|
504
511
|
|
512
|
+
class FacetValue
|
513
|
+
identified_by :value_type, :facet
|
514
|
+
has_one :facet, :mandatory => true # See Facet.all_facet_value
|
515
|
+
has_one :value, :mandatory => true # See Value.all_facet_value
|
516
|
+
has_one :value_type, :mandatory => true # See ValueType.all_facet_value
|
517
|
+
end
|
518
|
+
|
519
|
+
class ImplicitBooleanValueType < ValueType
|
520
|
+
end
|
521
|
+
|
505
522
|
class TypeInheritance < FactType
|
506
523
|
identified_by :subtype, :supertype
|
507
524
|
has_one :subtype, :class => EntityType, :mandatory => true # See EntityType.all_type_inheritance_as_subtype
|
@@ -510,12 +527,5 @@ module ActiveFacts
|
|
510
527
|
maybe :provides_identification
|
511
528
|
end
|
512
529
|
|
513
|
-
class FacetValue
|
514
|
-
identified_by :value_type, :facet
|
515
|
-
has_one :facet, :mandatory => true # See Facet.all_facet_value
|
516
|
-
has_one :value, :mandatory => true # See Value.all_facet_value
|
517
|
-
has_one :value_type, :mandatory => true # See ValueType.all_facet_value
|
518
|
-
end
|
519
|
-
|
520
530
|
end
|
521
531
|
end
|
@@ -305,8 +305,10 @@ module ActiveFacts
|
|
305
305
|
# these expansions include frequency constraints, role names and value constraints as passed-in,
|
306
306
|
# and also define adjectives by using the hyphenated form (on at least the first occurrence).
|
307
307
|
def expand_reading(reading, frequency_constraints = [], define_role_names = nil, value_constraints = [], &subscript_block)
|
308
|
-
reading.expand(frequency_constraints, define_role_names, value_constraints) do |role_ref|
|
309
|
-
|
308
|
+
reading.expand(frequency_constraints, define_role_names, value_constraints) do |role_ref, *parts|
|
309
|
+
parts + [
|
310
|
+
(!(role_ref.role.role_name and define_role_names != nil) and p = player(role_ref) and p.subscript) ? "(#{p.subscript})" : nil
|
311
|
+
]
|
310
312
|
end
|
311
313
|
end
|
312
314
|
|
@@ -626,7 +628,7 @@ module ActiveFacts
|
|
626
628
|
# role_refs = steps.map{|step| [step.input_join_role.join_node, step.output_join_role.join_node].map{|jn| jn.all_role_ref.detect{|rr| rr.role.fact_type == object_type.fact_type}}}.flatten.compact.uniq
|
627
629
|
|
628
630
|
reading = object_type.fact_type.preferred_reading
|
629
|
-
" (
|
631
|
+
" (in which #{expand_reading_text(objectification_step, reading.text, reading.role_sequence, player_by_role)})"
|
630
632
|
end
|
631
633
|
|
632
634
|
def elided_objectification(next_step, fact_type, last_is_contractable, next_node)
|
data/spec/absorption_spec.rb
CHANGED
@@ -21,6 +21,7 @@ describe "Absorption" do
|
|
21
21
|
Claim is identified by ClaimID where
|
22
22
|
Claim has exactly one ClaimID,
|
23
23
|
ClaimID is of at most one Claim;
|
24
|
+
Claim was reported on one DateTime;
|
24
25
|
}
|
25
26
|
AT_Incident = %Q{
|
26
27
|
Incident is identified by Claim where
|
@@ -50,7 +51,7 @@ describe "Absorption" do
|
|
50
51
|
#{AT_Prologue} #{AT_Claim} #{AT_Incident}
|
51
52
|
Incident relates to loss on exactly one DateTime;
|
52
53
|
},
|
53
|
-
:tables => { "Claim" => [%w{Claim ID}, %w{Incident Date Time}]}
|
54
|
+
:tables => { "Claim" => [%w{Claim ID}, %w{Date Time}, %w{Incident Date Time}]}
|
54
55
|
},
|
55
56
|
|
56
57
|
{ :should => "absorb an objectified binary with single-role UC",
|
@@ -62,7 +63,7 @@ describe "Absorption" do
|
|
62
63
|
Person has exactly one birth-DateTime;
|
63
64
|
},
|
64
65
|
:tables => {
|
65
|
-
"Claim" => [%w{Claim ID}, %w{Lodgement Date Time}, %w{Lodgement Person ID}],
|
66
|
+
"Claim" => [%w{Claim ID}, %w{Date Time}, %w{Lodgement Date Time}, %w{Lodgement Person ID}],
|
66
67
|
"Party" => [%w{Party ID}, %w{Person Birth Date Time}]
|
67
68
|
}
|
68
69
|
},
|
data/spec/cql/comparison_spec.rb
CHANGED
@@ -8,9 +8,7 @@ require 'rspec/expectations'
|
|
8
8
|
require 'activefacts/support'
|
9
9
|
require 'activefacts/api/support'
|
10
10
|
require 'activefacts/cql/compiler'
|
11
|
-
require '
|
12
|
-
|
13
|
-
require 'ruby-debug'; Debugger.start
|
11
|
+
require File.dirname(__FILE__) + '/../helpers/compile_helpers'
|
14
12
|
|
15
13
|
describe "When matching a reading with an existing fact type" do
|
16
14
|
before :each do
|
data/spec/cql/context_spec.rb
CHANGED
@@ -41,7 +41,7 @@ describe "Business Context Notes" do
|
|
41
41
|
],
|
42
42
|
# Entity and Fact types
|
43
43
|
# Entity and Fact types
|
44
|
-
[ 'Foo is identified by Bar [independent] where Foo has one Bar (so that we have an id);',
|
44
|
+
[ 'Foo is identified by Bar [independent] where Foo has one(to avoid fuckups) Bar (so that we have an id);',
|
45
45
|
1, 'so_that'
|
46
46
|
],
|
47
47
|
[ 'Baz has one Bar (so that we have an id), Bar is of one Baz (because we need that);',
|
@@ -137,7 +137,7 @@ describe "When compiling an entity type, " do
|
|
137
137
|
eval(lambda { example.call(*c) }, BlackHole.new)
|
138
138
|
rescue => raised
|
139
139
|
end
|
140
|
-
raise RSpec::Core::PendingExampleFixedError.new(msg) unless raised
|
140
|
+
raise RSpec::Core::Pending::PendingExampleFixedError.new(msg) unless raised
|
141
141
|
throw :pending_declared_in_example, msg
|
142
142
|
}
|
143
143
|
end
|
@@ -306,7 +306,7 @@ describe "When compiling an entity type, " do
|
|
306
306
|
test.call(@compiler.vocabulary.constellation)
|
307
307
|
rescue RSpec::Expectations::ExpectationNotMetError
|
308
308
|
raise
|
309
|
-
rescue RSpec::Core::
|
309
|
+
rescue RSpec::Core::Pending::PendingDeclaredInExample.new
|
310
310
|
raise
|
311
311
|
rescue => e
|
312
312
|
puts "Failed on\n\t"+tests.select{|t| t.is_a?(String)}*" "
|
@@ -8,9 +8,7 @@ require 'rspec/expectations'
|
|
8
8
|
require 'activefacts/support'
|
9
9
|
require 'activefacts/api/support'
|
10
10
|
require 'activefacts/cql/compiler'
|
11
|
-
require '
|
12
|
-
|
13
|
-
require 'ruby-debug'; Debugger.start
|
11
|
+
require File.dirname(__FILE__) + '/../helpers/compile_helpers'
|
14
12
|
|
15
13
|
describe "When compiling expressions" do
|
16
14
|
before :each do
|
@@ -55,7 +53,7 @@ describe "When compiling expressions" do
|
|
55
53
|
(is_old_ft.all_reading.map{ |r| r.expand }*', ').should == "Person is old"
|
56
54
|
|
57
55
|
comparison_ft = (new_fact_types - [is_old_ft])[0]
|
58
|
-
(comparison_ft.all_reading.map{ |r| r.expand }*', ').should == "Age >= product(Integer, sum(Integer, Integer))"
|
56
|
+
(comparison_ft.all_reading.map{ |r| r.expand }*', ').should == "Boolean = Age >= product(Integer, sum(Integer, Integer))"
|
59
57
|
|
60
58
|
# one_join_with_value 60, 'year'
|
61
59
|
end
|
@@ -2,15 +2,14 @@
|
|
2
2
|
# ActiveFacts CQL Fact Type matching tests
|
3
3
|
# Copyright (c) 2009 Clifford Heath. Read the LICENSE file.
|
4
4
|
#
|
5
|
+
$: << Dir::getwd
|
5
6
|
|
6
7
|
require 'rspec/expectations'
|
7
8
|
|
8
9
|
require 'activefacts/support'
|
9
10
|
require 'activefacts/api/support'
|
10
11
|
require 'activefacts/cql/compiler'
|
11
|
-
require '
|
12
|
-
|
13
|
-
require 'ruby-debug'; Debugger.start
|
12
|
+
require File.dirname(__FILE__) + '/../helpers/compile_helpers'
|
14
13
|
|
15
14
|
describe "When matching a reading" do
|
16
15
|
before :each do
|
@@ -279,5 +278,58 @@ describe "When matching a reading" do
|
|
279
278
|
(pcs = fact_pcs(fact_type)).size.should == 1
|
280
279
|
end
|
281
280
|
end
|
281
|
+
|
282
|
+
describe "with hyphenated adjectives" do
|
283
|
+
before :each do
|
284
|
+
compile %q{Girl is going out with at most one butt-- ugly Boy;}
|
285
|
+
# baseline
|
286
|
+
end
|
287
|
+
|
288
|
+
it "should compile them correctly" do
|
289
|
+
(new_fact_types = fact_types).size.should == 1
|
290
|
+
(readings = new_fact_types[0].all_reading).size.should == 1
|
291
|
+
(role_refs = readings.single.role_sequence.all_role_ref).size.should == 2
|
292
|
+
(boy_role_ref = role_refs.sort_by{|rr| rr.ordinal}[1])
|
293
|
+
boy_role_ref.leading_adjective.should == 'butt-ugly'
|
294
|
+
end
|
295
|
+
|
296
|
+
it "should match using explicit adjectives" do
|
297
|
+
compile %q{
|
298
|
+
Girl is going out with butt-- ugly Boy,
|
299
|
+
butt-ugly Boy is going out with Girl;
|
300
|
+
}
|
301
|
+
(new_fact_types = fact_types).size.should == 1
|
302
|
+
(fact_type = new_fact_types[0]).all_reading.size.should == 2
|
303
|
+
(pcs = fact_pcs(fact_type)).size.should == 1
|
304
|
+
# REVISIT: Check new and existing reading
|
305
|
+
end
|
306
|
+
|
307
|
+
it "should match using implicit adjectives" do
|
308
|
+
compile %q{
|
309
|
+
Girl is going out with butt-- ugly Boy,
|
310
|
+
butt-ugly Boy is going out with Girl;
|
311
|
+
}
|
312
|
+
(new_fact_types = fact_types).size.should == 1
|
313
|
+
(fact_type = new_fact_types[0]).all_reading.size.should == 2
|
314
|
+
(pcs = fact_pcs(fact_type)).size.should == 1
|
315
|
+
# REVISIT: Check new and existing reading
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
describe "with hyphenated trailing adjectives" do
|
320
|
+
before :each do
|
321
|
+
compile %q{Girl is going out with at most one Boy tres --gross;}
|
322
|
+
# baseline
|
323
|
+
end
|
324
|
+
|
325
|
+
it "should compile them correctly" do
|
326
|
+
(new_fact_types = fact_types).size.should == 1
|
327
|
+
(readings = new_fact_types[0].all_reading).size.should == 1
|
328
|
+
(role_refs = readings.single.role_sequence.all_role_ref).size.should == 2
|
329
|
+
(boy_role_ref = role_refs.sort_by{|rr| rr.ordinal}[1])
|
330
|
+
boy_role_ref.trailing_adjective.should == 'tres-gross'
|
331
|
+
end
|
332
|
+
|
333
|
+
end
|
282
334
|
end
|
283
335
|
end
|