linguistics 1.0.8
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/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
|
+
|