zenlish 0.2.05 → 0.2.07
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +228 -0
- data/CHANGELOG.md +19 -0
- data/Gemfile +5 -3
- data/LICENSE.txt +1 -1
- data/Rakefile +5 -3
- data/lib/zenlish/feature/boolean_domain.rb +6 -4
- data/lib/zenlish/feature/boolean_value.rb +3 -2
- data/lib/zenlish/feature/enumeration_domain.rb +5 -2
- data/lib/zenlish/feature/feature.rb +9 -7
- data/lib/zenlish/feature/feature_def.rb +9 -6
- data/lib/zenlish/feature/feature_domain.rb +4 -2
- data/lib/zenlish/feature/feature_struct.rb +3 -1
- data/lib/zenlish/feature/feature_struct_def.rb +5 -3
- data/lib/zenlish/feature/feature_struct_def_bearer.rb +6 -4
- data/lib/zenlish/feature/feature_value.rb +4 -2
- data/lib/zenlish/feature/identifier_domain.rb +5 -3
- data/lib/zenlish/feature/identifier_value.rb +3 -2
- data/lib/zenlish/feature/symbol_value.rb +3 -1
- data/lib/zenlish/inflect/atomic_o_expression.rb +2 -1
- data/lib/zenlish/inflect/composite_o_expression.rb +3 -1
- data/lib/zenlish/inflect/concatenation.rb +3 -2
- data/lib/zenlish/inflect/equals_literal.rb +3 -1
- data/lib/zenlish/inflect/feature_heading.rb +2 -5
- data/lib/zenlish/inflect/formal_argument.rb +3 -1
- data/lib/zenlish/inflect/function_call.rb +4 -1
- data/lib/zenlish/inflect/heading.rb +2 -0
- data/lib/zenlish/inflect/inflection_rule.rb +2 -0
- data/lib/zenlish/inflect/inflection_table.rb +6 -4
- data/lib/zenlish/inflect/inflection_table_builder.rb +21 -18
- data/lib/zenlish/inflect/input_asis.rb +3 -0
- data/lib/zenlish/inflect/input_expression.rb +4 -2
- data/lib/zenlish/inflect/literal_asis.rb +4 -1
- data/lib/zenlish/inflect/matches_pattern.rb +2 -0
- data/lib/zenlish/inflect/membership.rb +2 -0
- data/lib/zenlish/inflect/method_heading.rb +3 -6
- data/lib/zenlish/inflect/not_equals_literal.rb +2 -0
- data/lib/zenlish/inflect/nullary_input_expression.rb +3 -1
- data/lib/zenlish/inflect/output_expression.rb +6 -0
- data/lib/zenlish/inflect/substitution.rb +3 -1
- data/lib/zenlish/inflect/unary_input_expression.rb +4 -1
- data/lib/zenlish/inflect/unconditionally_true.rb +4 -2
- data/lib/zenlish/lang/dictionary.rb +19 -16
- data/lib/zenlish/lang/lemmatizer.rb +40 -0
- data/lib/zenlish/lang/zenlish_grammar.rb +6 -4
- data/lib/zenlish/lex/empty_lexicon_factory.rb +3 -2
- data/lib/zenlish/lex/lexeme.rb +6 -4
- data/lib/zenlish/lex/lexical_entry.rb +6 -4
- data/lib/zenlish/lex/lexicon.rb +4 -3
- data/lib/zenlish/lex/literal.rb +3 -1
- data/lib/zenlish/lexer/lexer.rb +144 -0
- data/lib/zenlish/trie/base_trie_node.rb +27 -0
- data/lib/zenlish/trie/trie.rb +132 -0
- data/lib/zenlish/trie/trie_node.rb +21 -0
- data/lib/zenlish/trie/trie_root.rb +10 -0
- data/lib/zenlish/version.rb +3 -1
- data/lib/zenlish/wclasses/adjective.rb +4 -2
- data/lib/zenlish/wclasses/adverb.rb +3 -1
- data/lib/zenlish/wclasses/adverb_maybe.rb +3 -1
- data/lib/zenlish/wclasses/adverb_not.rb +2 -0
- data/lib/zenlish/wclasses/all_word_classes.rb +3 -1
- data/lib/zenlish/wclasses/article.rb +2 -0
- data/lib/zenlish/wclasses/auxiliary.rb +2 -0
- data/lib/zenlish/wclasses/auxiliary_be.rb +7 -6
- data/lib/zenlish/wclasses/auxiliary_do.rb +6 -5
- data/lib/zenlish/wclasses/cardinal.rb +3 -1
- data/lib/zenlish/wclasses/common_noun.rb +2 -0
- data/lib/zenlish/wclasses/comparative_particle.rb +5 -3
- data/lib/zenlish/wclasses/conjunction.rb +2 -0
- data/lib/zenlish/wclasses/conjunctive_pronoun.rb +2 -0
- data/lib/zenlish/wclasses/coordinator.rb +4 -2
- data/lib/zenlish/wclasses/definite_article.rb +2 -0
- data/lib/zenlish/wclasses/degree_adverb.rb +2 -0
- data/lib/zenlish/wclasses/demonstrative_determiner.rb +6 -4
- data/lib/zenlish/wclasses/demonstrative_pronoun.rb +2 -0
- data/lib/zenlish/wclasses/determiner.rb +3 -1
- data/lib/zenlish/wclasses/distributive_determiner.rb +2 -0
- data/lib/zenlish/wclasses/existential_there.rb +2 -0
- data/lib/zenlish/wclasses/fronting_quantifier.rb +3 -1
- data/lib/zenlish/wclasses/indefinite_article.rb +2 -0
- data/lib/zenlish/wclasses/indefinite_pronoun.rb +3 -1
- data/lib/zenlish/wclasses/irregular_linking_verb.rb +3 -1
- data/lib/zenlish/wclasses/irregular_verb.rb +13 -15
- data/lib/zenlish/wclasses/irregular_verb_be.rb +8 -7
- data/lib/zenlish/wclasses/irregular_verb_can.rb +8 -7
- data/lib/zenlish/wclasses/irregular_verb_do.rb +7 -6
- data/lib/zenlish/wclasses/irregular_verb_extension.rb +8 -7
- data/lib/zenlish/wclasses/irregular_verb_have.rb +12 -11
- data/lib/zenlish/wclasses/irregular_verb_know.rb +3 -1
- data/lib/zenlish/wclasses/irregular_verb_say.rb +3 -1
- data/lib/zenlish/wclasses/irregular_verb_think.rb +3 -1
- data/lib/zenlish/wclasses/lexical_verb.rb +3 -4
- data/lib/zenlish/wclasses/linking_adverb.rb +2 -0
- data/lib/zenlish/wclasses/modal_verb_can.rb +7 -5
- data/lib/zenlish/wclasses/noun.rb +4 -2
- data/lib/zenlish/wclasses/numeral.rb +2 -0
- data/lib/zenlish/wclasses/personal_pronoun.rb +8 -6
- data/lib/zenlish/wclasses/possessive_determiner.rb +13 -12
- data/lib/zenlish/wclasses/preposition.rb +3 -1
- data/lib/zenlish/wclasses/preposition_of.rb +2 -0
- data/lib/zenlish/wclasses/preposition_than.rb +2 -0
- data/lib/zenlish/wclasses/pronoun.rb +3 -1
- data/lib/zenlish/wclasses/proper_noun.rb +10 -8
- data/lib/zenlish/wclasses/quantifier.rb +3 -1
- data/lib/zenlish/wclasses/regular_verb.rb +9 -9
- data/lib/zenlish/wclasses/regular_verb_want.rb +4 -2
- data/lib/zenlish/wclasses/relative_pronoun.rb +4 -2
- data/lib/zenlish/wclasses/subordinating_conjunction.rb +7 -5
- data/lib/zenlish/wclasses/verb.rb +5 -3
- data/lib/zenlish/wclasses/word_class.rb +7 -5
- data/lib/zenlish.rb +3 -3
- data/spec/spec_helper.rb +3 -1
- data/spec/zenlish/feature/boolean_domain_spec.rb +16 -16
- data/spec/zenlish/feature/boolean_value_spec.rb +7 -6
- data/spec/zenlish/feature/enumeration_domain_spec.rb +21 -21
- data/spec/zenlish/feature/feature_def_spec.rb +15 -14
- data/spec/zenlish/feature/feature_spec.rb +17 -17
- data/spec/zenlish/feature/feature_struct_def_bearer_spec.rb +23 -21
- data/spec/zenlish/feature/feature_struct_def_spec.rb +26 -25
- data/spec/zenlish/feature/identifier_domain_spec.rb +15 -15
- data/spec/zenlish/feature/identifier_value_spec.rb +10 -9
- data/spec/zenlish/feature/symbol_value_spec.rb +9 -8
- data/spec/zenlish/inflect/concatenation_spec.rb +14 -14
- data/spec/zenlish/inflect/equals_literal_spec.rb +17 -16
- data/spec/zenlish/inflect/feature_heading_spec.rb +22 -21
- data/spec/zenlish/inflect/formal_argument_spec.rb +7 -7
- data/spec/zenlish/inflect/function_call_spec.rb +11 -12
- data/spec/zenlish/inflect/inflection_rule_spec.rb +28 -24
- data/spec/zenlish/inflect/inflection_table_builder_spec.rb +62 -57
- data/spec/zenlish/inflect/inflection_table_spec.rb +49 -46
- data/spec/zenlish/inflect/input_asis_spec.rb +12 -15
- data/spec/zenlish/inflect/literal_asis_spec.rb +10 -10
- data/spec/zenlish/inflect/matches_pattern_spec.rb +16 -15
- data/spec/zenlish/inflect/membership_spec.rb +17 -16
- data/spec/zenlish/inflect/method_heading_spec.rb +15 -14
- data/spec/zenlish/inflect/not_equals_literal_spec.rb +17 -16
- data/spec/zenlish/inflect/substitution_spec.rb +10 -11
- data/spec/zenlish/inflect/unconditionally_true_spec.rb +8 -6
- data/spec/zenlish/lang/dictionary_spec.rb +28 -31
- data/spec/zenlish/lang/lemmatizer_spec.rb +43 -0
- data/spec/zenlish/lang/zenlish_grammar_spec.rb +5 -5
- data/spec/zenlish/lex/empty_lexicon_factory_spec.rb +8 -8
- data/spec/zenlish/lex/lexeme_spec.rb +27 -28
- data/spec/zenlish/lex/lexical_entry_spec.rb +15 -15
- data/spec/zenlish/lex/lexicon_spec.rb +52 -50
- data/spec/zenlish/lex/literal_spec.rb +8 -8
- data/spec/zenlish/lexer/lexer_spec.rb +52 -0
- data/spec/zenlish/parser/lesson1_spec.rb +81 -81
- data/spec/zenlish/parser/lesson2_spec.rb +133 -138
- data/spec/zenlish/parser/lesson3_spec.rb +186 -226
- data/spec/zenlish/parser/zparser_spec.rb +8 -7
- data/spec/zenlish/support/minimal_lexicon.rb +2 -0
- data/spec/zenlish/support/var2word.rb +16 -9
- data/spec/zenlish/trie/base_trie_node_spec.rb +33 -0
- data/spec/zenlish/trie/trie_spec.rb +108 -0
- data/spec/zenlish/wclasses/common_noun_spec.rb +15 -19
- data/spec/zenlish/wclasses/demonstrative_determiner_spec.rb +12 -12
- data/spec/zenlish/wclasses/irregular_verb_can_spec.rb +18 -18
- data/spec/zenlish/wclasses/irregular_verb_extension_spec.rb +10 -10
- data/spec/zenlish/wclasses/irregular_verb_spec.rb +28 -28
- data/spec/zenlish/wclasses/lexical_verb_spec.rb +9 -9
- data/spec/zenlish/wclasses/modal_verb_can_spec.rb +12 -12
- data/spec/zenlish/wclasses/noun_spec.rb +7 -7
- data/spec/zenlish/wclasses/personal_pronoun_spec.rb +20 -23
- data/spec/zenlish/wclasses/possessive_determiner_spec.rb +28 -31
- data/spec/zenlish/wclasses/preposition_spec.rb +5 -5
- data/spec/zenlish/wclasses/proper_noun_spec.rb +3 -3
- data/spec/zenlish/wclasses/regular_verb_spec.rb +30 -30
- data/spec/zenlish/wclasses/regular_verb_want_spec.rb +30 -0
- data/spec/zenlish/wclasses/verb_spec.rb +9 -9
- data/spec/zenlish_spec.rb +4 -2
- data/zenlish.gemspec +18 -14
- metadata +49 -16
@@ -2,22 +2,23 @@
|
|
2
2
|
|
3
3
|
require_relative '../../../lib/zenlish/feature/enumeration_domain'
|
4
4
|
# Load the class under test
|
5
|
-
require_relative '../../../lib/zenlish/feature/symbol_value'
|
5
|
+
require_relative '../../../lib/zenlish/feature/symbol_value'
|
6
6
|
|
7
7
|
module Zenlish
|
8
8
|
module Feature
|
9
9
|
describe SymbolValue do
|
10
10
|
let(:its_value) { :plural }
|
11
|
-
|
11
|
+
|
12
|
+
subject(:symbolic) { described_class.new(its_value) }
|
12
13
|
|
13
14
|
context 'Initialization:' do
|
14
|
-
it '
|
15
|
-
expect {
|
15
|
+
it 'is initialized with a value argument' do
|
16
|
+
expect { described_class.new(its_value) }.not_to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'knows its internal value' do
|
20
|
+
expect(symbolic.val).to eq(its_value)
|
16
21
|
end
|
17
|
-
|
18
|
-
it 'should know its internal value' do
|
19
|
-
expect(subject.val).to eq(its_value)
|
20
|
-
end
|
21
22
|
end # context
|
22
23
|
|
23
24
|
context 'Provided services:' do
|
@@ -11,30 +11,30 @@ module Zenlish
|
|
11
11
|
let(:suffix) { LiteralAsIs.new('s') }
|
12
12
|
let(:sample_argument) { FormalArgument.new(2) }
|
13
13
|
let(:base_form) { InputAsIs.new(sample_argument) }
|
14
|
-
|
15
|
-
subject {
|
14
|
+
|
15
|
+
subject(:concatenation) { described_class.new(base_form, suffix) }
|
16
16
|
|
17
17
|
context 'Initialization:' do
|
18
|
-
it '
|
19
|
-
expect {
|
18
|
+
it 'is initialized with two arguments' do
|
19
|
+
expect { described_class.new(base_form, suffix) }.not_to raise_error
|
20
20
|
end
|
21
|
-
|
22
|
-
it '
|
23
|
-
expect(
|
24
|
-
expect(
|
21
|
+
|
22
|
+
it 'knows its arguments' do
|
23
|
+
expect(concatenation.children.first).to eq(base_form)
|
24
|
+
expect(concatenation.children.last).to eq(suffix)
|
25
25
|
end
|
26
26
|
end # context
|
27
27
|
|
28
28
|
context 'Provided services:' do
|
29
|
-
let(:sample_values) { [nil, nil, 'place', nil] }
|
30
|
-
|
31
|
-
it '
|
29
|
+
let(:sample_values) { [nil, nil, 'place', nil] }
|
30
|
+
|
31
|
+
it 'concatenates children results' do
|
32
32
|
headings = double('fake-headings')
|
33
33
|
lexeme = double('fake-lexeme')
|
34
|
-
|
35
|
-
expect(
|
34
|
+
|
35
|
+
expect(concatenation.generate(headings, lexeme, sample_values)).to eq('places')
|
36
36
|
end
|
37
37
|
end # context
|
38
38
|
end # describe
|
39
39
|
end # module
|
40
|
-
end # module
|
40
|
+
end # module
|
@@ -13,44 +13,45 @@ module Zenlish
|
|
13
13
|
describe EqualsLiteral do
|
14
14
|
let(:an_argument) { FormalArgument.new(1) }
|
15
15
|
let(:feat_val) { :plural }
|
16
|
-
|
16
|
+
|
17
|
+
subject(:literal) { described_class.new(an_argument, feat_val) }
|
17
18
|
|
18
19
|
context 'Initialization:' do
|
19
|
-
it '
|
20
|
-
expect {
|
20
|
+
it 'is initialized with a formal argument and a literal' do
|
21
|
+
expect { described_class.new(an_argument, feat_val) }.not_to raise_error
|
21
22
|
end
|
22
23
|
|
23
|
-
it '
|
24
|
-
expect(
|
24
|
+
it 'knows its argument' do
|
25
|
+
expect(literal.argument).to eq(an_argument)
|
25
26
|
end
|
26
27
|
|
27
|
-
it '
|
28
|
-
expect(
|
28
|
+
it 'knows the literal' do
|
29
|
+
expect(literal.literal).to eq(feat_val)
|
29
30
|
end
|
30
31
|
end # context
|
31
32
|
|
32
33
|
context 'Provided services:' do
|
33
|
-
it '
|
34
|
+
it 'tests the actual argument' do
|
34
35
|
lexeme = double('dummy-lexeme')
|
35
36
|
headings = double('fake-headings')
|
36
37
|
actual_args = [nil, :plural, nil]
|
37
|
-
expect(
|
38
|
+
expect(literal).to be_success(headings, lexeme, actual_args)
|
38
39
|
actual_args[1] = :singular
|
39
|
-
expect(
|
40
|
+
expect(literal).not_to be_success(headings, lexeme, actual_args)
|
40
41
|
end
|
41
42
|
|
42
|
-
it '
|
43
|
+
it 'tests the lexeme' do
|
43
44
|
c_noun = WClasses::CommonNoun.new
|
44
45
|
entry = Lex::LexicalEntry.new('animal')
|
45
46
|
lexeme = Lex::Lexeme.new(c_noun, entry)
|
46
47
|
headings = [nil, FeatureHeading.new('NUMBER'), nil]
|
47
|
-
expect(
|
48
|
+
expect(literal).to be_success(headings, lexeme, [])
|
48
49
|
|
49
|
-
instance =
|
50
|
-
expect(instance.
|
50
|
+
instance = described_class.new(an_argument, :singular)
|
51
|
+
expect(instance).to be_success(headings, lexeme, [])
|
51
52
|
|
52
|
-
instance =
|
53
|
-
expect(instance.
|
53
|
+
instance = described_class.new(an_argument, :irregular)
|
54
|
+
expect(instance).not_to be_success(headings, lexeme, [])
|
54
55
|
end
|
55
56
|
end # context
|
56
57
|
end # describe
|
@@ -6,45 +6,46 @@ require_relative '../../../lib/zenlish/inflect/feature_heading'
|
|
6
6
|
module Zenlish
|
7
7
|
module Inflect
|
8
8
|
describe FeatureHeading do
|
9
|
-
let(:feature_name) { 'NUMBER' }
|
10
|
-
|
9
|
+
let(:feature_name) { 'NUMBER' }
|
10
|
+
|
11
|
+
subject(:ft_heading) { described_class.new(feature_name) }
|
11
12
|
|
12
13
|
context 'Initialization:' do
|
13
|
-
it '
|
14
|
-
expect {
|
14
|
+
it 'is initialized with a feature name' do
|
15
|
+
expect { described_class.new(feature_name) }.not_to raise_error
|
15
16
|
end
|
16
|
-
|
17
|
-
it '
|
18
|
-
expect(
|
17
|
+
|
18
|
+
it 'knows its label' do
|
19
|
+
expect(ft_heading.label).to eq(feature_name)
|
19
20
|
end
|
20
21
|
end # context
|
21
22
|
|
22
23
|
context 'Provided services:' do
|
23
24
|
let(:a_domain) { Feature::EnumerationDomain.new(:singular, :plural) }
|
24
25
|
let(:enum_def) { Feature::FeatureDef.new(feature_name, a_domain) }
|
25
|
-
let(:b_domain) { Feature::BooleanDomain.instance }
|
26
|
+
let(:b_domain) { Feature::BooleanDomain.instance }
|
26
27
|
let(:bool_def) { Feature::FeatureDef.new(feature_name, b_domain) }
|
27
|
-
|
28
|
-
it '
|
28
|
+
|
29
|
+
it 'obtains the value of a feature' do
|
29
30
|
mocked = { 'NUMBER' => :plural }
|
30
|
-
expect(
|
31
|
+
expect(ft_heading.evaluate_for(mocked)).to eq(:plural)
|
31
32
|
end
|
32
|
-
|
33
|
-
it '
|
33
|
+
|
34
|
+
it 'obtains all possible values of a feature' do
|
34
35
|
mocked = { 'NUMBER' => :plural }
|
35
|
-
expect(
|
36
|
+
expect(ft_heading.all_matches(mocked)).to eq([:plural])
|
36
37
|
end
|
37
38
|
|
38
|
-
it '
|
39
|
+
it 'obtains all possible values of a enumeration domain' do
|
39
40
|
mocked = { 'NUMBER' => enum_def }
|
40
|
-
expect(
|
41
|
-
end
|
41
|
+
expect(ft_heading.all_matches(mocked)).to eq(%i[singular plural])
|
42
|
+
end
|
42
43
|
|
43
|
-
it '
|
44
|
+
it 'obtains all possible values of a enumeration domain' do
|
44
45
|
mocked = { 'NUMBER' => bool_def }
|
45
|
-
expect(
|
46
|
-
end
|
46
|
+
expect(ft_heading.all_matches(mocked)).to eq([false, true])
|
47
|
+
end
|
47
48
|
end # context
|
48
49
|
end # describe
|
49
50
|
end # module
|
50
|
-
end # module
|
51
|
+
end # module
|
@@ -6,15 +6,15 @@ require_relative '../../../lib/zenlish/inflect/formal_argument'
|
|
6
6
|
module Zenlish
|
7
7
|
module Inflect
|
8
8
|
describe FormalArgument do
|
9
|
-
subject {
|
9
|
+
subject(:arg) { described_class.new(3) }
|
10
10
|
|
11
11
|
context 'Initialization:' do
|
12
|
-
it '
|
13
|
-
expect {
|
12
|
+
it 'is initialized with a text literal' do
|
13
|
+
expect { described_class.new(1) }.not_to raise_error
|
14
14
|
end
|
15
|
-
|
16
|
-
it '
|
17
|
-
expect(
|
15
|
+
|
16
|
+
it 'knows its index value' do
|
17
|
+
expect(arg.index).to eq(3)
|
18
18
|
end
|
19
19
|
end # context
|
20
20
|
|
@@ -22,4 +22,4 @@ module Zenlish
|
|
22
22
|
end # context
|
23
23
|
end # describe
|
24
24
|
end # module
|
25
|
-
end # module
|
25
|
+
end # module
|
@@ -1,32 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'ostruct'
|
4
3
|
# Load the class under test
|
5
4
|
require_relative '../../../lib/zenlish/inflect/function_call'
|
6
5
|
|
7
6
|
module Zenlish
|
8
7
|
module Inflect
|
9
8
|
describe FunctionCall do
|
10
|
-
subject {
|
9
|
+
subject(:func_call) { described_class.new('greet') }
|
11
10
|
|
12
11
|
context 'Initialization:' do
|
13
|
-
it '
|
14
|
-
expect {
|
12
|
+
it 'is initialized with a text literal' do
|
13
|
+
expect { described_class.new('greet') }.not_to raise_error
|
15
14
|
end
|
16
|
-
|
17
|
-
it '
|
18
|
-
expect(
|
15
|
+
|
16
|
+
it 'knows its method name' do
|
17
|
+
expect(func_call.mth_name).to eq('greet')
|
19
18
|
end
|
20
19
|
end # context
|
21
20
|
|
22
21
|
context 'Provided services:' do
|
23
|
-
it '
|
24
|
-
headings = double('fake-headings')
|
25
|
-
lexeme =
|
22
|
+
it 'returns the affix during word form generation' do
|
23
|
+
headings = double('fake-headings')
|
24
|
+
lexeme = double('fake-lexeme', greet: 'Hello, world')
|
26
25
|
values = double('fake-values')
|
27
|
-
expect(
|
26
|
+
expect(func_call.generate(headings, lexeme, values)).to eq('Hello, world')
|
28
27
|
end
|
29
28
|
end # context
|
30
29
|
end # describe
|
31
30
|
end # module
|
32
|
-
end # module
|
31
|
+
end # module
|
@@ -17,6 +17,8 @@ require_relative '../../../lib/zenlish/inflect/inflection_rule'
|
|
17
17
|
|
18
18
|
module Zenlish
|
19
19
|
module Inflect
|
20
|
+
# rubocop: disable Naming/VariableNumber
|
21
|
+
|
20
22
|
describe InflectionRule do
|
21
23
|
# One rule in row representation:
|
22
24
|
# | plural | ~ /[^aeiouy]y$/ | sub(base_form, /y$/, "ies")|
|
@@ -26,7 +28,7 @@ module Zenlish
|
|
26
28
|
let(:method_name) { 'base_form' }
|
27
29
|
let(:heading1) { MethodHeading.new(method_name) }
|
28
30
|
let(:headings) { [heading0, heading1] }
|
29
|
-
|
31
|
+
|
30
32
|
# Condition part
|
31
33
|
let(:feature_value) { :plural }
|
32
34
|
let(:arg_0) { FormalArgument.new(0) }
|
@@ -42,20 +44,21 @@ module Zenlish
|
|
42
44
|
let(:pattern) { /y$/ }
|
43
45
|
let(:consequent) { Substitution.new(base, pattern, suffix) }
|
44
46
|
|
45
|
-
subject {
|
47
|
+
subject(:i_rule) { described_class.new(conditions, consequent) }
|
46
48
|
|
47
49
|
context 'Initialization:' do
|
48
|
-
it '
|
49
|
-
expect
|
50
|
-
|
50
|
+
it 'is initialized with condition and consequent parts' do
|
51
|
+
expect do
|
52
|
+
described_class.new(conditions, consequent)
|
53
|
+
end.not_to raise_error
|
51
54
|
end
|
52
55
|
|
53
|
-
it '
|
54
|
-
expect(
|
56
|
+
it 'knows its condition part' do
|
57
|
+
expect(i_rule.conditions).to eq(conditions)
|
55
58
|
end
|
56
59
|
|
57
|
-
it '
|
58
|
-
expect(
|
60
|
+
it 'knows its consequent part' do
|
61
|
+
expect(i_rule.consequent).to eq(consequent)
|
59
62
|
end
|
60
63
|
end # context
|
61
64
|
|
@@ -65,38 +68,39 @@ module Zenlish
|
|
65
68
|
let(:an_entry) { Lex::LexicalEntry.new('cherry') }
|
66
69
|
let(:lexeme) { Lex::Lexeme.new(c_noun, an_entry) }
|
67
70
|
|
68
|
-
it '
|
71
|
+
it 'succeeds when all conditions succeed with actuals' do
|
69
72
|
actuals = [:plural, 'cherry']
|
70
|
-
expect(
|
73
|
+
expect(i_rule).to be_success(headings, fake_lexeme, actuals)
|
71
74
|
end
|
72
75
|
|
73
|
-
it '
|
76
|
+
it 'fails when one condition fails with actuals' do
|
74
77
|
actuals = [:singular, 'cherry']
|
75
|
-
expect(
|
78
|
+
expect(i_rule).not_to be_success(headings, fake_lexeme, actuals)
|
76
79
|
|
77
80
|
actuals = [:plural, 'girl']
|
78
|
-
expect(
|
81
|
+
expect(i_rule).not_to be_success(headings, fake_lexeme, actuals)
|
79
82
|
end
|
80
83
|
|
81
|
-
it '
|
84
|
+
it 'generates inflected form when rule iworks for actuals' do
|
82
85
|
actuals = [:plural, 'cherry']
|
83
|
-
expect(
|
86
|
+
expect(i_rule.apply(headings, fake_lexeme, actuals)).to eq('cherries')
|
84
87
|
end
|
85
|
-
|
86
|
-
it '
|
87
|
-
expect(
|
88
|
+
|
89
|
+
it 'succeeds when all conditions succeed for given lexeme' do
|
90
|
+
expect(i_rule).to be_success(headings, lexeme, [])
|
88
91
|
end
|
89
92
|
|
90
|
-
it '
|
93
|
+
it 'fails when one condition fails with given lexeme' do
|
91
94
|
entry_2 = Lex::LexicalEntry.new('animal')
|
92
95
|
lex_m2 = Lex::Lexeme.new(c_noun, entry_2)
|
93
|
-
expect(
|
96
|
+
expect(i_rule).not_to be_success(headings, lex_m2, [])
|
94
97
|
end
|
95
98
|
|
96
|
-
it '
|
97
|
-
expect(
|
98
|
-
end
|
99
|
+
it 'generates inflected form when rule works for given lexeme' do
|
100
|
+
expect(i_rule.apply(headings, lexeme, [])).to eq('cherries')
|
101
|
+
end
|
99
102
|
end # context
|
100
103
|
end # describe
|
104
|
+
# rubocop: enable Naming/VariableNumber
|
101
105
|
end # module
|
102
106
|
end # module
|
@@ -5,36 +5,39 @@ require_relative '../../../lib/zenlish/inflect/inflection_table_builder'
|
|
5
5
|
|
6
6
|
module Zenlish
|
7
7
|
module Inflect
|
8
|
+
# rubocop: disable Layout/SpaceInsideParens
|
9
|
+
# rubocop: disable Naming/VariableNumber
|
10
|
+
|
8
11
|
describe InflectionTableBuilder do
|
9
|
-
subject {
|
12
|
+
subject(:builder) { described_class.new }
|
10
13
|
|
11
14
|
context 'Initialization:' do
|
12
|
-
it '
|
13
|
-
expect {
|
15
|
+
it 'is initialized without argument' do
|
16
|
+
expect { described_class.new }.not_to raise_error
|
14
17
|
end
|
15
18
|
|
16
|
-
it '
|
17
|
-
expect(
|
19
|
+
it "doesn't not have headings after initialization" do
|
20
|
+
expect(builder.headings).to be_empty
|
18
21
|
end
|
19
22
|
end # context
|
20
23
|
|
21
24
|
context 'Basic services:' do
|
22
|
-
it '
|
23
|
-
|
24
|
-
expect(
|
25
|
+
it 'retains the table name' do
|
26
|
+
builder.build('Common_form')
|
27
|
+
expect(builder.table.name).to eq('Common_form')
|
25
28
|
end
|
26
29
|
|
27
|
-
it '
|
30
|
+
it 'accepts heading creation' do
|
28
31
|
# First way
|
29
|
-
|
30
|
-
expect(
|
31
|
-
expect(
|
32
|
-
|
33
|
-
expect(
|
34
|
-
expect(
|
32
|
+
builder.feature_heading 'NUMBER'
|
33
|
+
expect(builder.headings.size).to eq(1)
|
34
|
+
expect(builder.headings.last.label).to eq('NUMBER')
|
35
|
+
builder.method_heading 'base_form'
|
36
|
+
expect(builder.headings.last).to be_a(MethodHeading)
|
37
|
+
expect(builder.headings.last.label).to eq('base_form')
|
35
38
|
|
36
39
|
# Second way
|
37
|
-
table =
|
40
|
+
table = builder.build('Common_form') do
|
38
41
|
feature_heading 'NUMBER'
|
39
42
|
method_heading 'base_form'
|
40
43
|
end
|
@@ -44,8 +47,10 @@ module Zenlish
|
|
44
47
|
end # context
|
45
48
|
|
46
49
|
context 'Table building:' do
|
47
|
-
|
48
|
-
|
50
|
+
let(:mock_feature_bearer) { Struct.new(:NUMBER, :base_form) }
|
51
|
+
|
52
|
+
it 'is able to build consequents' do
|
53
|
+
table = builder.build('Common_form') do
|
49
54
|
feature_heading 'NUMBER'
|
50
55
|
method_heading 'base_form'
|
51
56
|
rule([], col('base_form'))
|
@@ -54,23 +59,23 @@ module Zenlish
|
|
54
59
|
end
|
55
60
|
expect(table.rules).not_to be_empty
|
56
61
|
consequent_0 = table.rules[0].consequent
|
57
|
-
expect(consequent_0).to
|
62
|
+
expect(consequent_0).to be_a(InputAsIs)
|
58
63
|
expect(consequent_0.formal.index).to eq(1)
|
59
64
|
|
60
65
|
consequent_1 = table.rules[1].consequent
|
61
|
-
expect(consequent_1).to
|
66
|
+
expect(consequent_1).to be_a(Substitution)
|
62
67
|
expect(consequent_1.children[0].formal.index).to eq(1)
|
63
68
|
expect(consequent_1.pattern).to eq(/y$/)
|
64
69
|
expect(consequent_1.children[-1].text).to eq('ies')
|
65
70
|
|
66
71
|
consequent_2 = table.rules[2].consequent
|
67
72
|
expect(consequent_2.children[0].formal.index).to eq(1)
|
68
|
-
expect(consequent_2).to
|
73
|
+
expect(consequent_2).to be_a(Concatenation)
|
69
74
|
expect(consequent_2.children[-1].text).to eq('s')
|
70
75
|
end
|
71
76
|
|
72
|
-
it '
|
73
|
-
table =
|
77
|
+
it 'is able to build conditions' do
|
78
|
+
table = builder.build('Common_form') do
|
74
79
|
feature_heading 'NUMBER'
|
75
80
|
method_heading 'base_form'
|
76
81
|
rule([equals(:singular), dont_care], col('base_form'))
|
@@ -79,26 +84,24 @@ module Zenlish
|
|
79
84
|
end
|
80
85
|
|
81
86
|
conds_0 = table.rules[0].conditions
|
82
|
-
expect(conds_0[0]).to
|
87
|
+
expect(conds_0[0]).to be_a(EqualsLiteral)
|
83
88
|
expect(conds_0[0].literal).to eq(:singular)
|
84
|
-
expect(conds_0[1]).to
|
89
|
+
expect(conds_0[1]).to be_a(UnconditionallyTrue)
|
85
90
|
|
86
91
|
conds_1 = table.rules[1].conditions
|
87
|
-
expect(conds_1[0]).to
|
92
|
+
expect(conds_1[0]).to be_a(EqualsLiteral)
|
88
93
|
expect(conds_1[0].literal).to eq(:plural)
|
89
|
-
expect(conds_1[1]).to
|
94
|
+
expect(conds_1[1]).to be_a(MatchesPattern)
|
90
95
|
expect(conds_1[1].pattern).to eq(/[^aeiouy]y$/)
|
91
96
|
|
92
97
|
conds_2 = table.rules[2].conditions
|
93
|
-
expect(conds_2[0]).to
|
98
|
+
expect(conds_2[0]).to be_a(EqualsLiteral)
|
94
99
|
expect(conds_2[0].literal).to eq(:plural)
|
95
|
-
expect(conds_2[1]).to
|
100
|
+
expect(conds_2[1]).to be_a(UnconditionallyTrue)
|
96
101
|
end
|
97
102
|
|
98
|
-
|
99
|
-
|
100
|
-
it 'should build default paradigm for common nouns' do
|
101
|
-
table = subject.build('Common_form') do
|
103
|
+
it 'builds default paradigm for common nouns' do
|
104
|
+
table = builder.build('Common_form') do
|
102
105
|
feature_heading 'NUMBER'
|
103
106
|
method_heading 'base_form'
|
104
107
|
rule([equals(:singular), dont_care], col('base_form'))
|
@@ -106,25 +109,25 @@ module Zenlish
|
|
106
109
|
rule([equals(:plural), dont_care], concat(col('base_form'), 's'))
|
107
110
|
end
|
108
111
|
|
109
|
-
mck_1 =
|
112
|
+
mck_1 = mock_feature_bearer.new(:singular, 'animal')
|
110
113
|
expect(table.inflect(mck_1, [nil, nil])).to eq('animal')
|
111
114
|
mck_1['NUMBER'] = :plural
|
112
115
|
expect(table.inflect(mck_1, [nil, nil])).to eq('animals')
|
113
116
|
|
114
|
-
mck_2 =
|
117
|
+
mck_2 = mock_feature_bearer.new(:singular, 'boy')
|
115
118
|
expect(table.inflect(mck_2, [nil, nil])).to eq('boy')
|
116
119
|
mck_2['NUMBER'] = :plural
|
117
120
|
expect(table.inflect(mck_2, [nil, nil])).to eq('boys')
|
118
121
|
|
119
|
-
mck_3 =
|
122
|
+
mck_3 = mock_feature_bearer.new(:singular, 'body')
|
120
123
|
expect(table.inflect(mck_3, [nil, nil])).to eq('body')
|
121
124
|
mck_3['NUMBER'] = :plural
|
122
125
|
expect(table.inflect(mck_3, [nil, nil])).to eq('bodies')
|
123
126
|
end
|
124
|
-
|
127
|
+
|
125
128
|
MockRegularVerb = Struct.new(:base_form, :PERSON, :NUMBER, :TIME)
|
126
|
-
it '
|
127
|
-
table =
|
129
|
+
it 'builds default paradigm for regular verbs' do
|
130
|
+
table = builder.build('Regular_form') do
|
128
131
|
feature_heading 'PERSON'
|
129
132
|
feature_heading 'NUMBER'
|
130
133
|
feature_heading 'TIME'
|
@@ -132,15 +135,15 @@ module Zenlish
|
|
132
135
|
# PERSON NUMBER TIME base_form
|
133
136
|
rule([not_equal(:third), dont_care, equals(:present), dont_care], col('base_form'))
|
134
137
|
rule([equals(:third), equals(:singular), equals(:present), matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ies'))
|
135
|
-
rule([equals(:third), equals(:singular), equals(:present), matches(/(?:[osxz]|ch|sh)$/)], concat(col('base_form'), 'es'))
|
136
|
-
rule([equals(:third), equals(:singular), equals(:present), dont_care], concat(col('base_form'), 's'))
|
137
|
-
rule([dont_care, dont_care, equals(:progressive), matches(/e$/)], sub(col('base_form'), /e$/, 'ing'))
|
138
|
+
rule([equals(:third), equals(:singular), equals(:present), matches(/(?:[osxz]|ch|sh)$/)], concat(col('base_form'), 'es'))
|
139
|
+
rule([equals(:third), equals(:singular), equals(:present), dont_care], concat(col('base_form'), 's'))
|
140
|
+
rule([dont_care, dont_care, equals(:progressive), matches(/e$/)], sub(col('base_form'), /e$/, 'ing'))
|
138
141
|
rule([dont_care, dont_care, equals(:progressive), dont_care], concat(col('base_form'), 'ing'))
|
139
|
-
rule([dont_care, dont_care, in?(:past_simple, :past_participle), matches(/e$/)], concat(col('base_form'), 'd'))
|
140
|
-
rule([dont_care, dont_care, in?(:past_simple, :past_participle), matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ied'))
|
142
|
+
rule([dont_care, dont_care, in?(:past_simple, :past_participle), matches(/e$/)], concat(col('base_form'), 'd'))
|
143
|
+
rule([dont_care, dont_care, in?(:past_simple, :past_participle), matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ied'))
|
141
144
|
rule([dont_care, dont_care, in?(:past_simple, :past_participle), dont_care], concat(col('base_form'), 'ed'))
|
142
145
|
end
|
143
|
-
|
146
|
+
|
144
147
|
verb_1 = MockRegularVerb.new('belong', :first, :singular, :present)
|
145
148
|
expect(table.inflect(verb_1, [nil, nil, nil, nil] )).to eq('belong')
|
146
149
|
expect(table.inflect(verb_1, [:third, nil, nil, nil] )).to eq('belongs')
|
@@ -148,7 +151,7 @@ module Zenlish
|
|
148
151
|
expect(table.inflect(verb_1, [nil, nil, :progressive, nil] )).to eq('belonging')
|
149
152
|
expect(table.inflect(verb_1, [nil, nil, :past_simple, nil] )).to eq('belonged')
|
150
153
|
expect(table.inflect(verb_1, [nil, nil, :past_participle, nil])).to eq('belonged')
|
151
|
-
|
154
|
+
|
152
155
|
verb_2 = MockRegularVerb.new('try', :first, :singular, :present)
|
153
156
|
expect(table.inflect(verb_2, [nil, nil, nil, nil] )).to eq('try')
|
154
157
|
expect(table.inflect(verb_2, [:third, nil, nil, nil] )).to eq('tries')
|
@@ -158,7 +161,7 @@ module Zenlish
|
|
158
161
|
expect(table.inflect(verb_2, [nil, nil, :past_participle, nil])).to eq('tried')
|
159
162
|
|
160
163
|
verb_3 = MockRegularVerb.new('touch', :first, :singular, :present)
|
161
|
-
expect(table.inflect(verb_3, [:second,nil,
|
164
|
+
expect(table.inflect(verb_3, [:second, nil, nil, nil] )).to eq('touch')
|
162
165
|
expect(table.inflect(verb_3, [:third, nil, nil, nil] )).to eq('touches')
|
163
166
|
expect(table.inflect(verb_3, [nil, :plural, nil, nil] )).to eq('touch')
|
164
167
|
expect(table.inflect(verb_3, [nil, nil, :progressive, nil] )).to eq('touching')
|
@@ -171,12 +174,12 @@ module Zenlish
|
|
171
174
|
expect(table.inflect(verb_4, [nil, :plural, nil, nil] )).to eq('cause')
|
172
175
|
expect(table.inflect(verb_4, [nil, nil, :progressive, nil] )).to eq('causing')
|
173
176
|
expect(table.inflect(verb_4, [nil, nil, :past_simple, nil] )).to eq('caused')
|
174
|
-
expect(table.inflect(verb_4, [nil, nil, :past_participle, nil])).to eq('caused')
|
177
|
+
expect(table.inflect(verb_4, [nil, nil, :past_participle, nil])).to eq('caused')
|
175
178
|
end
|
176
|
-
|
179
|
+
|
177
180
|
MockIrregularVerb = Struct.new(:base_form, :PERSON, :NUMBER, :TIME, :past_simple, :past_participle)
|
178
|
-
it '
|
179
|
-
table =
|
181
|
+
it 'builds default paradigm for irregular verbs' do
|
182
|
+
table = builder.build('Irregular_inflection') do
|
180
183
|
feature_heading 'PERSON'
|
181
184
|
feature_heading 'NUMBER'
|
182
185
|
feature_heading 'TIME'
|
@@ -184,12 +187,12 @@ module Zenlish
|
|
184
187
|
# PERSON NUMBER TIME base_form
|
185
188
|
rule([not_equal(:third), dont_care, equals(:present), dont_care], col('base_form'))
|
186
189
|
rule([equals(:third), equals(:singular), equals(:present), matches(/[^aeiouy]y$/)], sub(col('base_form'), /y$/, 'ies'))
|
187
|
-
rule([equals(:third), equals(:singular), equals(:present), matches(/(?:[osxz]|ch|sh)$/)], concat(col('base_form'), 'es'))
|
188
|
-
rule([equals(:third), equals(:singular), equals(:present), dont_care], concat(col('base_form'), 's'))
|
189
|
-
rule([dont_care, dont_care, equals(:progressive), matches(/e$/)], sub(col('base_form'), /e$/, 'ing'))
|
190
|
+
rule([equals(:third), equals(:singular), equals(:present), matches(/(?:[osxz]|ch|sh)$/)], concat(col('base_form'), 'es'))
|
191
|
+
rule([equals(:third), equals(:singular), equals(:present), dont_care], concat(col('base_form'), 's'))
|
192
|
+
rule([dont_care, dont_care, equals(:progressive), matches(/e$/)], sub(col('base_form'), /e$/, 'ing'))
|
190
193
|
rule([dont_care, dont_care, equals(:progressive), dont_care], concat(col('base_form'), 'ing'))
|
191
|
-
rule([dont_care, dont_care, equals(:past_simple), dont_care], func('past_simple'))
|
192
|
-
rule([dont_care, dont_care, equals(:past_participle), dont_care], func('past_participle'))
|
194
|
+
rule([dont_care, dont_care, equals(:past_simple), dont_care], func('past_simple'))
|
195
|
+
rule([dont_care, dont_care, equals(:past_participle), dont_care], func('past_participle'))
|
193
196
|
end
|
194
197
|
|
195
198
|
verb_1 = MockIrregularVerb.new('choose', :first, :singular, :present, 'chose', 'chosen')
|
@@ -202,5 +205,7 @@ module Zenlish
|
|
202
205
|
end
|
203
206
|
end # context
|
204
207
|
end # describe
|
208
|
+
# rubocop: enable Naming/VariableNumber
|
209
|
+
# rubocop: enable Layout/SpaceInsideParens
|
205
210
|
end # module
|
206
|
-
end # module
|
211
|
+
end # module
|