linguistics 1.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +640 -0
- data/LICENSE +27 -0
- data/README +166 -0
- data/README.english +245 -0
- data/Rakefile +338 -0
- data/examples/generalize_sentence.rb +46 -0
- data/lib/linguistics.rb +366 -0
- data/lib/linguistics/en.rb +1728 -0
- data/lib/linguistics/en/infinitive.rb +1145 -0
- data/lib/linguistics/en/linkparser.rb +109 -0
- data/lib/linguistics/en/wordnet.rb +257 -0
- data/lib/linguistics/iso639.rb +461 -0
- data/rake/191_compat.rb +26 -0
- data/rake/dependencies.rb +76 -0
- data/rake/helpers.rb +434 -0
- data/rake/hg.rb +261 -0
- data/rake/manual.rb +782 -0
- data/rake/packaging.rb +144 -0
- data/rake/publishing.rb +318 -0
- data/rake/rdoc.rb +30 -0
- data/rake/style.rb +62 -0
- data/rake/svn.rb +668 -0
- data/rake/testing.rb +187 -0
- data/rake/verifytask.rb +64 -0
- data/rake/win32.rb +190 -0
- data/spec/linguistics/en_spec.rb +215 -0
- data/spec/linguistics/iso639_spec.rb +72 -0
- data/spec/linguistics_spec.rb +107 -0
- data/tests/en/infinitive.tests.rb +207 -0
- data/tests/en/inflect.tests.rb +1389 -0
- data/tests/en/lafcadio.tests.rb +77 -0
- data/tests/en/linkparser.tests.rb +42 -0
- data/tests/en/lprintf.tests.rb +77 -0
- data/tests/en/titlecase.tests.rb +73 -0
- data/tests/en/wordnet.tests.rb +95 -0
- metadata +107 -0
data/rake/testing.rb
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
#
|
2
|
+
# Rake tasklib for testing tasks
|
3
|
+
|
4
|
+
#
|
5
|
+
# Authors:
|
6
|
+
# * Michael Granger <ged@FaerieMUD.org>
|
7
|
+
#
|
8
|
+
|
9
|
+
unless defined?( COVERAGE_MINIMUM )
|
10
|
+
if ENV['COVVERAGE_MINIMUM']
|
11
|
+
COVERAGE_MINIMUM = Float( ENV['COVERAGE_MINIMUM'] )
|
12
|
+
else
|
13
|
+
COVERAGE_MINIMUM = 85.0
|
14
|
+
end
|
15
|
+
end
|
16
|
+
SPEC_FILES = [] unless defined?( SPEC_FILES )
|
17
|
+
TEST_FILES = [] unless defined?( TEST_FILES )
|
18
|
+
|
19
|
+
COMMON_SPEC_OPTS = ['-Du'] unless defined?( COMMON_SPEC_OPTS )
|
20
|
+
|
21
|
+
COVERAGE_TARGETDIR = BASEDIR + 'coverage' unless defined?( COVERAGE_TARGETDIR )
|
22
|
+
RCOV_EXCLUDES = 'spec,tests,/Library/Ruby,/var/lib,/usr/local/lib' unless
|
23
|
+
defined?( RCOV_EXCLUDES )
|
24
|
+
|
25
|
+
|
26
|
+
desc "Run all defined tests"
|
27
|
+
task :test do
|
28
|
+
unless SPEC_FILES.empty?
|
29
|
+
log "Running specs"
|
30
|
+
Rake::Task['spec:quiet'].invoke
|
31
|
+
end
|
32
|
+
|
33
|
+
unless TEST_FILES.empty?
|
34
|
+
log "Running unit tests"
|
35
|
+
Rake::Task[:unittests].invoke
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
### RSpec specifications
|
41
|
+
begin
|
42
|
+
gem 'rspec', '>= 1.1.3'
|
43
|
+
|
44
|
+
require 'spec'
|
45
|
+
require 'spec/rake/spectask'
|
46
|
+
|
47
|
+
### Task: spec
|
48
|
+
desc "Run specs"
|
49
|
+
task :spec => 'spec:doc'
|
50
|
+
|
51
|
+
namespace :spec do
|
52
|
+
desc "Run rspec every time there's a change to one of the files"
|
53
|
+
task :autotest do
|
54
|
+
require 'autotest/rspec'
|
55
|
+
|
56
|
+
autotester = Autotest::Rspec.new
|
57
|
+
autotester.run
|
58
|
+
end
|
59
|
+
|
60
|
+
desc "Generate regular color 'doc' spec output"
|
61
|
+
Spec::Rake::SpecTask.new( :doc ) do |task|
|
62
|
+
task.spec_files = SPEC_FILES
|
63
|
+
task.spec_opts = COMMON_SPEC_OPTS + ['-f', 's', '-c']
|
64
|
+
end
|
65
|
+
|
66
|
+
desc "Generate spec output with profiling"
|
67
|
+
Spec::Rake::SpecTask.new( :profile ) do |task|
|
68
|
+
task.spec_files = SPEC_FILES
|
69
|
+
task.spec_opts = COMMON_SPEC_OPTS + ['-f', 'o']
|
70
|
+
end
|
71
|
+
|
72
|
+
desc "Generate quiet non-colored plain-text output"
|
73
|
+
Spec::Rake::SpecTask.new( :quiet ) do |task|
|
74
|
+
task.spec_files = SPEC_FILES
|
75
|
+
task.spec_opts = COMMON_SPEC_OPTS + ['-f', 'p']
|
76
|
+
end
|
77
|
+
|
78
|
+
desc "Generate HTML output"
|
79
|
+
Spec::Rake::SpecTask.new( :html ) do |task|
|
80
|
+
task.spec_files = SPEC_FILES
|
81
|
+
task.spec_opts = COMMON_SPEC_OPTS + ['-f', 'h']
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
rescue LoadError => err
|
86
|
+
task :no_rspec do
|
87
|
+
$stderr.puts "Specification tasks not defined: %s" % [ err.message ]
|
88
|
+
end
|
89
|
+
|
90
|
+
task :spec => :no_rspec
|
91
|
+
namespace :spec do
|
92
|
+
task :autotest => :no_rspec
|
93
|
+
task :doc => :no_rspec
|
94
|
+
task :profile => :no_rspec
|
95
|
+
task :quiet => :no_rspec
|
96
|
+
task :html => :no_rspec
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
### Test::Unit tests
|
102
|
+
begin
|
103
|
+
require 'rake/testtask'
|
104
|
+
|
105
|
+
Rake::TestTask.new( :unittests ) do |task|
|
106
|
+
task.libs += [LIBDIR]
|
107
|
+
task.test_files = TEST_FILES
|
108
|
+
task.verbose = true
|
109
|
+
end
|
110
|
+
|
111
|
+
rescue LoadError => err
|
112
|
+
task :no_test do
|
113
|
+
$stderr.puts "Test tasks not defined: %s" % [ err.message ]
|
114
|
+
end
|
115
|
+
|
116
|
+
task :unittests => :no_rspec
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
### RCov (via RSpec) tasks
|
121
|
+
begin
|
122
|
+
gem 'rcov'
|
123
|
+
gem 'rspec', '>= 1.1.3'
|
124
|
+
|
125
|
+
require 'spec'
|
126
|
+
require 'rcov'
|
127
|
+
|
128
|
+
### Task: coverage (via RCov)
|
129
|
+
desc "Build test coverage reports"
|
130
|
+
unless SPEC_FILES.empty?
|
131
|
+
Spec::Rake::SpecTask.new( :coverage ) do |task|
|
132
|
+
task.spec_files = SPEC_FILES
|
133
|
+
task.libs += [LIBDIR]
|
134
|
+
task.spec_opts = ['-f', 'p', '-b']
|
135
|
+
task.rcov_opts = RCOV_OPTS
|
136
|
+
task.rcov = true
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
### Task: rcov
|
142
|
+
task :rcov => :coverage
|
143
|
+
|
144
|
+
### Other coverage tasks
|
145
|
+
namespace :coverage do
|
146
|
+
desc "Generate a detailed text coverage report"
|
147
|
+
Spec::Rake::SpecTask.new( :text ) do |task|
|
148
|
+
task.spec_files = SPEC_FILES
|
149
|
+
task.rcov_opts = RCOV_OPTS + ['--text-report']
|
150
|
+
task.rcov = true
|
151
|
+
end
|
152
|
+
|
153
|
+
desc "Show differences in coverage from last run"
|
154
|
+
Spec::Rake::SpecTask.new( :diff ) do |task|
|
155
|
+
task.spec_files = SPEC_FILES
|
156
|
+
task.spec_opts = ['-f', 'p', '-b']
|
157
|
+
task.rcov_opts = RCOV_OPTS - ['--save'] + ['--text-coverage-diff']
|
158
|
+
task.rcov = true
|
159
|
+
end
|
160
|
+
|
161
|
+
desc "Run RCov in 'spec-only' mode to check coverage from specs"
|
162
|
+
Spec::Rake::SpecTask.new( :speconly ) do |task|
|
163
|
+
task.spec_files = SPEC_FILES
|
164
|
+
task.rcov_opts = ['--exclude', RCOV_EXCLUDES, '--text-report', '--save']
|
165
|
+
task.rcov = true
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
CLOBBER.include( COVERAGE_TARGETDIR )
|
170
|
+
|
171
|
+
rescue LoadError => err
|
172
|
+
task :no_rcov do
|
173
|
+
$stderr.puts "Coverage tasks not defined: RSpec+RCov tasklib not available: %s" %
|
174
|
+
[ err.message ]
|
175
|
+
end
|
176
|
+
|
177
|
+
task :coverage => :no_rcov
|
178
|
+
task :clobber_coverage
|
179
|
+
task :rcov => :no_rcov
|
180
|
+
namespace :coverage do
|
181
|
+
task :text => :no_rcov
|
182
|
+
task :diff => :no_rcov
|
183
|
+
end
|
184
|
+
task :verify => :no_rcov
|
185
|
+
end
|
186
|
+
|
187
|
+
|
data/rake/verifytask.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#####################################################################
|
2
|
+
### S U B V E R S I O N T A S K S A N D H E L P E R S
|
3
|
+
#####################################################################
|
4
|
+
|
5
|
+
require 'rake/tasklib'
|
6
|
+
|
7
|
+
#
|
8
|
+
# Work around the inexplicable behaviour of the original RDoc::VerifyTask, which
|
9
|
+
# errors if your coverage isn't *exactly* the threshold.
|
10
|
+
#
|
11
|
+
|
12
|
+
# A task that can verify that the RCov coverage doesn't
|
13
|
+
# drop below a certain threshold. It should be run after
|
14
|
+
# running Spec::Rake::SpecTask.
|
15
|
+
class VerifyTask < Rake::TaskLib
|
16
|
+
|
17
|
+
COVERAGE_PERCENTAGE_PATTERN =
|
18
|
+
%r{<tt class='coverage_code'>(\d+\.\d+)%</tt>}
|
19
|
+
|
20
|
+
# Name of the task. Defaults to :verify_rcov
|
21
|
+
attr_accessor :name
|
22
|
+
|
23
|
+
# Path to the index.html file generated by RCov, which
|
24
|
+
# is the file containing the total coverage.
|
25
|
+
# Defaults to 'coverage/index.html'
|
26
|
+
attr_accessor :index_html
|
27
|
+
|
28
|
+
# Whether or not to output details. Defaults to true.
|
29
|
+
attr_accessor :verbose
|
30
|
+
|
31
|
+
# The threshold value (in percent) for coverage. If the
|
32
|
+
# actual coverage is not equal to this value, the task will raise an
|
33
|
+
# exception.
|
34
|
+
attr_accessor :threshold
|
35
|
+
|
36
|
+
def initialize( name=:verify )
|
37
|
+
@name = name
|
38
|
+
@index_html = 'coverage/index.html'
|
39
|
+
@verbose = true
|
40
|
+
yield self if block_given?
|
41
|
+
raise "Threshold must be set" if @threshold.nil?
|
42
|
+
define
|
43
|
+
end
|
44
|
+
|
45
|
+
def define
|
46
|
+
desc "Verify that rcov coverage is at least #{threshold}%"
|
47
|
+
|
48
|
+
task @name do
|
49
|
+
total_coverage = nil
|
50
|
+
if match = File.read( index_html ).match( COVERAGE_PERCENTAGE_PATTERN )
|
51
|
+
total_coverage = Float( match[1] )
|
52
|
+
else
|
53
|
+
raise "Couldn't find the coverage percentage in #{index_html}"
|
54
|
+
end
|
55
|
+
|
56
|
+
puts "Coverage: #{total_coverage}% (threshold: #{threshold}%)" if verbose
|
57
|
+
if total_coverage < threshold
|
58
|
+
raise "Coverage must be at least #{threshold}% but was #{total_coverage}%"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# vim: set nosta noet ts=4 sw=4:
|
data/rake/win32.rb
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
#
|
2
|
+
# Win32-specific tasks (cross-compiling, etc.)
|
3
|
+
#
|
4
|
+
# Thanks to some people that understand this stuff better than me for
|
5
|
+
# posting helpful blog posts. This stuff is an amalgam of stuff they did:
|
6
|
+
#
|
7
|
+
# * Mauricio Fernandez
|
8
|
+
# http://eigenclass.org/hiki/cross+compiling+rcovrt
|
9
|
+
#
|
10
|
+
# * Jeremy Hinegardner
|
11
|
+
# http://www.copiousfreetime.org/articles/2008/10/12/building-gems-for-windows.html
|
12
|
+
#
|
13
|
+
# * Aaron Patterson
|
14
|
+
# http://tenderlovemaking.com/2008/11/21/cross-compiling-ruby-gems-for-win32/
|
15
|
+
|
16
|
+
require 'rubygems'
|
17
|
+
require 'rake'
|
18
|
+
require 'pathname'
|
19
|
+
require 'rubygems/platform'
|
20
|
+
require 'rbconfig'
|
21
|
+
require 'uri'
|
22
|
+
require 'net/ftp'
|
23
|
+
|
24
|
+
HOMEDIR = Pathname( '~' ).expand_path
|
25
|
+
RUBYVERSION = '1.8.6-p287'
|
26
|
+
RUBYVERSION_MAJORMINOR = RUBYVERSION[/^\d+\.\d+/]
|
27
|
+
|
28
|
+
RUBY_DL_BASE = "ftp://ftp.ruby-lang.org/pub/ruby/#{RUBYVERSION_MAJORMINOR}/"
|
29
|
+
RUBY_DL_URI = URI( RUBY_DL_BASE + "ruby-#{RUBYVERSION}.tar.gz" )
|
30
|
+
|
31
|
+
XCOMPILER_DIR = HOMEDIR + '.ruby_mingw32'
|
32
|
+
|
33
|
+
XCOMPILER_DL = XCOMPILER_DIR + "ruby-#{RUBYVERSION}.tar.gz"
|
34
|
+
XCOMPILER_SRC = XCOMPILER_DIR + "ruby-#{RUBYVERSION}"
|
35
|
+
|
36
|
+
XCOMPILER_BIN = XCOMPILER_DIR + 'bin'
|
37
|
+
XCOMPILER_LIB = XCOMPILER_DIR + 'lib'
|
38
|
+
XCOMPILER_RUBY = XCOMPILER_BIN + 'ruby.exe'
|
39
|
+
|
40
|
+
XCOMPILER_LOAD_PATH = XCOMPILER_LIB + "ruby/#{RUBYVERSION_MAJORMINOR}/i386-mingw32"
|
41
|
+
|
42
|
+
TAR_OPTS = { :compression => :gzip }
|
43
|
+
|
44
|
+
WIN32_GEMSPEC = GEMSPEC.dup
|
45
|
+
WIN32_GEMSPEC.files += FileList[ EXTDIR + '**.{dll,so}' ]
|
46
|
+
WIN32_GEMSPEC.platform = Gem::Platform.new( 'i386-mingw32' )
|
47
|
+
WIN32_GEMSPEC.extensions = []
|
48
|
+
|
49
|
+
|
50
|
+
CONFIGURE_CMD = %W[
|
51
|
+
env
|
52
|
+
ac_cv_func_getpgrp_void=no
|
53
|
+
ac_cv_func_setpgrp_void=yes
|
54
|
+
rb_cv_negative_time_t=no
|
55
|
+
ac_cv_func_memcmp_working=yes
|
56
|
+
rb_cv_binary_elf=no
|
57
|
+
./configure
|
58
|
+
--host=i386-mingw32
|
59
|
+
--target=i386-mingw32
|
60
|
+
--build=#{Config::CONFIG['build']}
|
61
|
+
--prefix=#{XCOMPILER_DIR}
|
62
|
+
]
|
63
|
+
|
64
|
+
### Archive::Tar::Reader#extract (as of 0.9.0) is broken w.r.t.
|
65
|
+
### permissions, so we have to do this ourselves.
|
66
|
+
def untar( tarfile, targetdir )
|
67
|
+
targetdir = Pathname( targetdir )
|
68
|
+
raise "No such directory: #{targetdir}" unless targetdir.directory?
|
69
|
+
|
70
|
+
reader = Archive::Tar::Reader.new( tarfile.to_s, TAR_OPTS )
|
71
|
+
|
72
|
+
mkdir_p( targetdir )
|
73
|
+
reader.each( true ) do |header, body|
|
74
|
+
path = targetdir + header[:path]
|
75
|
+
# trace "Header is: %p" % [ header ]
|
76
|
+
|
77
|
+
case header[:type]
|
78
|
+
when :file
|
79
|
+
trace " #{path}"
|
80
|
+
path.open( File::WRONLY|File::EXCL|File::CREAT|File::TRUNC, header[:mode] ) do |fio|
|
81
|
+
bytesize = header[:size]
|
82
|
+
fio.write( body[0,bytesize] )
|
83
|
+
end
|
84
|
+
|
85
|
+
when :directory
|
86
|
+
trace " #{path}"
|
87
|
+
path.mkpath
|
88
|
+
|
89
|
+
when :link
|
90
|
+
linktarget = targetdir + header[:dest]
|
91
|
+
trace " #{path} => #{linktarget}"
|
92
|
+
path.make_link( linktarget.to_s )
|
93
|
+
|
94
|
+
when :symlink
|
95
|
+
linktarget = targetdir + header[:dest]
|
96
|
+
trace " #{path} -> #{linktarget}"
|
97
|
+
path.make_symlink( linktarget )
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
begin
|
105
|
+
require 'archive/tar'
|
106
|
+
|
107
|
+
namespace :win32 do
|
108
|
+
directory XCOMPILER_DIR.to_s
|
109
|
+
|
110
|
+
file XCOMPILER_DL => XCOMPILER_DIR do
|
111
|
+
# openuri can't handle this -- passive ftp required?
|
112
|
+
# run 'wget', '-O', XCOMPILER_DL, RUBY_DL_URI
|
113
|
+
log "Downloading ruby distro from %s" % [ RUBY_DL_URI ]
|
114
|
+
ftp = Net::FTP.new( RUBY_DL_URI.host )
|
115
|
+
ftp.login
|
116
|
+
ftp.getbinaryfile( RUBY_DL_URI.path, XCOMPILER_DL, 4096 )
|
117
|
+
ftp.close
|
118
|
+
end
|
119
|
+
|
120
|
+
directory XCOMPILER_SRC.to_s
|
121
|
+
task XCOMPILER_SRC => [ XCOMPILER_DIR, XCOMPILER_DL ] do
|
122
|
+
if XCOMPILER_SRC.exist?
|
123
|
+
trace "Rake fails. #{XCOMPILER_SRC} already exists."
|
124
|
+
else
|
125
|
+
untar( XCOMPILER_DL, XCOMPILER_DIR )
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
file XCOMPILER_RUBY => XCOMPILER_SRC do
|
130
|
+
Dir.chdir( XCOMPILER_SRC ) do
|
131
|
+
unless File.exist?( 'Makefile.in.orig' )
|
132
|
+
File.open( 'Makefile.in.new', IO::CREAT|IO::WRONLY|IO::EXCL ) do |ofh|
|
133
|
+
IO.readlines( 'Makefile.in' ).each do |line|
|
134
|
+
next if line.include?( 0.chr )
|
135
|
+
trace " copying line: %p" % [ line ]
|
136
|
+
line.sub!( /ALT_SEPARATOR = ".*?"/, "ALT_SEPARATOR = 92.chr" )
|
137
|
+
ofh.write( line )
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
mv 'Makefile.in', 'Makefile.in.orig'
|
142
|
+
mv 'Makefile.in.new', 'Makefile.in'
|
143
|
+
end
|
144
|
+
|
145
|
+
run *CONFIGURE_CMD
|
146
|
+
run 'make', 'ruby'
|
147
|
+
run 'make', 'rubyw.exe'
|
148
|
+
run 'make', 'install'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
file XCOMPILER_LOAD_PATH => XCOMPILER_RUBY
|
153
|
+
|
154
|
+
desc "Cross-compile the library for Win32 systems, installing a cross-" +
|
155
|
+
"compiled Ruby if necessary"
|
156
|
+
task :build => [ EXTDIR, XCOMPILER_LOAD_PATH.to_s ] do
|
157
|
+
in_subdirectory( EXTDIR ) do
|
158
|
+
ruby "-I#{XCOMPILER_LOAD_PATH}", 'extconf.rb'
|
159
|
+
sh 'make'
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
desc "Build a binary gem for win32 systems"
|
164
|
+
task :gem => ['win32:build', PKGDIR.to_s] + WIN32_GEMSPEC.files do
|
165
|
+
when_writing( "Creating win32 GEM" ) do
|
166
|
+
pkgname = WIN32_GEMSPEC.file_name
|
167
|
+
builder = Gem::Builder.new( WIN32_GEMSPEC )
|
168
|
+
builder.build
|
169
|
+
mv pkgname, PKGDIR + pkgname, :verbose => $trace
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
rescue LoadError => err
|
175
|
+
trace "Couldn't load the win32 tasks: %s: %s" % [ err.class.name, err.message ]
|
176
|
+
|
177
|
+
task :no_win32_build do
|
178
|
+
abort "No win32 build: %s: %s" % [ err.class.name, err.message ]
|
179
|
+
end
|
180
|
+
|
181
|
+
namespace :win32 do
|
182
|
+
desc "Build a binary Gem for Win32 systems, installing a cross " +
|
183
|
+
"compiled Ruby if necessary"
|
184
|
+
task :gem => :no_win32_build
|
185
|
+
task :build => :no_win32_build
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
|
@@ -0,0 +1,215 @@
|
|
1
|
+
#!/usr/bin/env spec -cfs
|
2
|
+
|
3
|
+
BEGIN {
|
4
|
+
require 'pathname'
|
5
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent.parent
|
6
|
+
|
7
|
+
libdir = basedir + "lib"
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
|
10
|
+
}
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'spec/runner'
|
14
|
+
require 'linguistics'
|
15
|
+
require 'linguistics/en'
|
16
|
+
rescue LoadError
|
17
|
+
unless Object.const_defined?( :Gem )
|
18
|
+
require 'rubygems'
|
19
|
+
retry
|
20
|
+
end
|
21
|
+
raise
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
describe Linguistics::EN do
|
26
|
+
|
27
|
+
before( :all ) do
|
28
|
+
Linguistics::use( :en )
|
29
|
+
include Linguistics::EN
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
describe "conjunctions with an Array of a single element" do
|
34
|
+
|
35
|
+
before( :each ) do
|
36
|
+
@array = ['cat']
|
37
|
+
end
|
38
|
+
|
39
|
+
it "results in a phrase with indefinite article" do
|
40
|
+
@array.en.conjunction.should == "a cat"
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
describe "conjunction with an Array of two different words" do
|
47
|
+
|
48
|
+
before( :each ) do
|
49
|
+
@array = ['cat', 'dog']
|
50
|
+
end
|
51
|
+
|
52
|
+
it "results in a phrase joined with 'and' with default options" do
|
53
|
+
@array.en.conjunction.should == "a cat and a dog"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "results in a phrase joined with 'plus' if 'plus' is set as the conjunctive" do
|
57
|
+
@array.en.conjunction(:conjunctive => 'plus').should == "a cat plus a dog"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "results in a phrase joined with a space if an empty string is set as the conjunctive" do
|
61
|
+
@array.en.conjunction(:conjunctive => '').should == "a cat a dog"
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
describe "conjunction with an Array of two words that differ only in case" do
|
68
|
+
|
69
|
+
before( :each ) do
|
70
|
+
@array = ['cat', 'Cat']
|
71
|
+
end
|
72
|
+
|
73
|
+
it "combines them into their downcased equivalents with default options" do
|
74
|
+
@array.en.conjunction.should == "two cats"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "lists them separately if :combine is set to false" do
|
78
|
+
@array.en.conjunction(:combine => false).should == "a cat and a Cat"
|
79
|
+
end
|
80
|
+
|
81
|
+
it "doesn't combine them if :casefold is turned off" do
|
82
|
+
@array.en.conjunction(:casefold => false).should == "a cat and a Cat"
|
83
|
+
end
|
84
|
+
|
85
|
+
it "combines and lists them with a non-specific count if :generalize is set" do
|
86
|
+
@array.en.conjunction(:generalize => true).should == "several cats"
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
describe "conjunction with an Array of many (more than two) words of varying cases" do
|
93
|
+
|
94
|
+
before( :each ) do
|
95
|
+
@array = %w{cat dog fox dog chicken chicken Fox chicken goose Dog goose}
|
96
|
+
end
|
97
|
+
|
98
|
+
it "combines them into their downcased equivalents and lists them in order of amount " +
|
99
|
+
"with default options" do
|
100
|
+
@array.en.conjunction.should ==
|
101
|
+
'three dogs, three chickens, two foxes, two geese, and a cat'
|
102
|
+
end
|
103
|
+
|
104
|
+
it "lists them separately if :combine is set to false" do
|
105
|
+
@array.en.conjunction(:combine => false).should ==
|
106
|
+
'a cat, a dog, a fox, a dog, a chicken, a chicken, a Fox, a '\
|
107
|
+
'chicken, a goose, a Dog, and a goose'
|
108
|
+
end
|
109
|
+
|
110
|
+
it "doesn't combine the differently-cased ones if :casefold is turned off" do
|
111
|
+
@array.en.conjunction(:casefold => false).should ==
|
112
|
+
'three chickens, two dogs, two geese, a cat, a fox, a Fox, '\
|
113
|
+
'and a Dog'
|
114
|
+
end
|
115
|
+
|
116
|
+
it "combines and lists them with a non-specific count if :generalize is set" do
|
117
|
+
@array.en.conjunction(:generalize => true).should ==
|
118
|
+
'several dogs, several chickens, several foxes, several '\
|
119
|
+
'geese, and a cat'
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
describe "conjunction with an object-transform block" do
|
126
|
+
|
127
|
+
it "doesn't still have #6: #conjunction doesn't invoke supplied block under some conditions"
|
128
|
+
before( :each ) do
|
129
|
+
# Create a new class, as we need to guarantee that this will be the
|
130
|
+
# first #conjunction call to it.
|
131
|
+
@collection = Class::new {
|
132
|
+
include Enumerable, Linguistics
|
133
|
+
def initialize( *ary )
|
134
|
+
@ary = ary.flatten
|
135
|
+
end
|
136
|
+
|
137
|
+
# Delegate #each to the contained Array
|
138
|
+
def each( &block )
|
139
|
+
@ary.each( &block )
|
140
|
+
end
|
141
|
+
}
|
142
|
+
|
143
|
+
@obj = @collection.new( 'foo', 'bar', 'baz', 'tree', 'node', 'sonogram' )
|
144
|
+
end
|
145
|
+
|
146
|
+
it "uses supplied block for object transform on first invocation" do
|
147
|
+
@obj.en.conjunction {|word| "%s-letter word" % word.length.en.numwords }.should ==
|
148
|
+
"three three-letter words, two four-letter words, and an eight-letter word"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
def test_conjunction_should_use_supplied_block_for_object_transform
|
155
|
+
rval = nil
|
156
|
+
|
157
|
+
assert_nothing_raised do
|
158
|
+
rval = Items.en.conjunction {|word| "%s-word" % word[0,1]}
|
159
|
+
end
|
160
|
+
|
161
|
+
assert_equal "three c-words and a b-word", rval
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
def test_conjunction_should_use_supplied_block_for_object_transform_through_autoproxy
|
166
|
+
rval = nil
|
167
|
+
|
168
|
+
assert_nothing_raised do
|
169
|
+
rval = Items.conjunction {|word| "%s-word" % word[0,1]}
|
170
|
+
end
|
171
|
+
|
172
|
+
assert_equal "three c-words and a b-word", rval
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_conjunction_with_penultimate_separator_turned_off_should_not_use_one
|
176
|
+
rval = nil
|
177
|
+
|
178
|
+
assert_nothing_raised do
|
179
|
+
rval = Items.en.conjunction( :penultimate => false )
|
180
|
+
end
|
181
|
+
|
182
|
+
assert_equal "a cow, a chicken, a blancmange and a cyclist", rval
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_three_item_conjunction_should_honor_penultimate_setting
|
186
|
+
rval = nil
|
187
|
+
|
188
|
+
assert_nothing_raised do
|
189
|
+
rval = %w{duck cow dog}.en.conjunction( :penultimate => false )
|
190
|
+
end
|
191
|
+
|
192
|
+
assert_equal "a duck, a cow and a dog", rval
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_conjunction_uses_alt_separator_if_phrases_include_the_primary_one
|
196
|
+
rval = nil
|
197
|
+
scene_items = [
|
198
|
+
"desk with stamps, paper, and envelopes on it",
|
199
|
+
"basket containing milk, eggs, and broccoli",
|
200
|
+
"chair",
|
201
|
+
"wooden chest",
|
202
|
+
"hat rack",
|
203
|
+
]
|
204
|
+
|
205
|
+
assert_nothing_raised do
|
206
|
+
rval = scene_items.conjunction
|
207
|
+
end
|
208
|
+
|
209
|
+
assert_equal "a desk with stamps, paper, and envelopes on it; " +
|
210
|
+
"a basket containing milk, eggs, and broccoli; " +
|
211
|
+
"a chair; a wooden chest; and a hat rack", rval
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|