wordnet 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/rake/testing.rb ADDED
@@ -0,0 +1,192 @@
1
+ #
2
+ # Rake tasklib for testing tasks
3
+ # $Id: testing.rb 39 2008-08-22 01:27:56Z deveiant $
4
+ #
5
+ # Authors:
6
+ # * Michael Granger <ged@FaerieMUD.org>
7
+ #
8
+
9
+ COVERAGE_MINIMUM = 85.0 unless defined?( COVERAGE_MINIMUM )
10
+ SPEC_FILES = [] unless defined?( SPEC_FILES )
11
+ TEST_FILES = [] unless defined?( TEST_FILES )
12
+
13
+ COMMON_SPEC_OPTS = ['-c', '-f', 's'] unless defined?( COMMON_SPEC_OPTS )
14
+
15
+ COVERAGE_TARGETDIR = BASEDIR + 'coverage' unless defined?( COVERAGE_TARGETDIR )
16
+ RCOV_EXCLUDES = 'spec,tests,/Library/Ruby,/var/lib,/usr/local/lib' unless
17
+ defined?( RCOV_EXCLUDES )
18
+
19
+
20
+ desc "Run all defined tests"
21
+ task :test do
22
+ unless SPEC_FILES.empty?
23
+ log "Running specs"
24
+ Rake::Task['spec:quiet'].invoke
25
+ end
26
+
27
+ unless TEST_FILES.empty?
28
+ log "Running unit tests"
29
+ Rake::Task[:unittests].invoke
30
+ end
31
+ end
32
+
33
+
34
+ ### RSpec specifications
35
+ begin
36
+ gem 'rspec', '>= 1.1.3'
37
+ require 'spec/rake/spectask'
38
+
39
+ ### Task: spec
40
+ Spec::Rake::SpecTask.new( :spec ) do |task|
41
+ task.spec_files = SPEC_FILES
42
+ task.libs += [LIBDIR]
43
+ task.spec_opts = COMMON_SPEC_OPTS
44
+ end
45
+
46
+
47
+ namespace :spec do
48
+ desc "Run rspec every time there's a change to one of the files"
49
+ task :autotest do
50
+ require 'autotest/rspec'
51
+
52
+ autotester = Autotest::Rspec.new
53
+ autotester.exceptions = %r{\.svn|\.skel}
54
+ autotester.run
55
+ end
56
+
57
+
58
+ desc "Generate quiet output"
59
+ Spec::Rake::SpecTask.new( :quiet ) do |task|
60
+ task.spec_files = SPEC_FILES
61
+ task.spec_opts = ['-f', 'p', '-D']
62
+ end
63
+
64
+ desc "Generate HTML output for a spec run"
65
+ Spec::Rake::SpecTask.new( :html ) do |task|
66
+ task.spec_files = SPEC_FILES
67
+ task.spec_opts = ['-f','h', '-D']
68
+ end
69
+
70
+ desc "Generate plain-text output for a CruiseControl.rb build"
71
+ Spec::Rake::SpecTask.new( :text ) do |task|
72
+ task.spec_files = SPEC_FILES
73
+ task.spec_opts = ['-f','p']
74
+ end
75
+ end
76
+ rescue LoadError => err
77
+ task :no_rspec do
78
+ $stderr.puts "Specification tasks not defined: %s" % [ err.message ]
79
+ end
80
+
81
+ task :spec => :no_rspec
82
+ namespace :spec do
83
+ task :autotest => :no_rspec
84
+ task :quiet => :no_rspec
85
+ task :html => :no_rspec
86
+ task :text => :no_rspec
87
+ end
88
+ end
89
+
90
+
91
+ ### Test::Unit tests
92
+ begin
93
+ require 'rake/testtask'
94
+
95
+ Rake::TestTask.new( :unittests ) do |task|
96
+ task.libs += [LIBDIR]
97
+ task.test_files = TEST_FILES
98
+ task.verbose = true
99
+ end
100
+
101
+ rescue LoadError => err
102
+ task :no_test do
103
+ $stderr.puts "Test tasks not defined: %s" % [ err.message ]
104
+ end
105
+
106
+ task :unittests => :no_rspec
107
+ end
108
+
109
+
110
+ ### RCov (via RSpec) tasks
111
+ begin
112
+ gem 'rcov'
113
+ gem 'rspec', '>= 1.1.3'
114
+
115
+ ### Task: coverage (via RCov)
116
+ ### Task: rcov
117
+ desc "Build test coverage reports"
118
+ unless SPEC_FILES.empty?
119
+ Spec::Rake::SpecTask.new( :coverage ) do |task|
120
+ task.spec_files = SPEC_FILES
121
+ task.libs += [LIBDIR]
122
+ task.spec_opts = ['-f', 'p', '-b']
123
+ task.rcov_opts = RCOV_OPTS
124
+ task.rcov = true
125
+ end
126
+ end
127
+ unless TEST_FILES.empty?
128
+ require 'rcov/rcovtask'
129
+
130
+ Rcov::RcovTask.new do |task|
131
+ task.libs += [LIBDIR]
132
+ task.test_files = TEST_FILES
133
+ task.verbose = true
134
+ task.rcov_opts = RCOV_OPTS
135
+ end
136
+ end
137
+
138
+
139
+ task :rcov => [:coverage] do; end
140
+
141
+ ### Other coverage tasks
142
+ namespace :coverage do
143
+ desc "Generate a detailed text coverage report"
144
+ Spec::Rake::SpecTask.new( :text ) do |task|
145
+ task.spec_files = SPEC_FILES
146
+ task.rcov_opts = RCOV_OPTS + ['--text-report']
147
+ task.rcov = true
148
+ end
149
+
150
+ desc "Show differences in coverage from last run"
151
+ Spec::Rake::SpecTask.new( :diff ) do |task|
152
+ task.spec_files = SPEC_FILES
153
+ task.spec_opts = ['-f', 'p', '-b']
154
+ task.rcov_opts = RCOV_OPTS - ['--save'] + ['--text-coverage-diff']
155
+ task.rcov = true
156
+ end
157
+
158
+ ### Task: verify coverage
159
+ desc "Build coverage statistics"
160
+ VerifyTask.new( :verify => :rcov ) do |task|
161
+ task.threshold = COVERAGE_MINIMUM
162
+ end
163
+
164
+ desc "Run RCov in 'spec-only' mode to check coverage from specs"
165
+ Spec::Rake::SpecTask.new( :speconly ) do |task|
166
+ task.spec_files = SPEC_FILES
167
+ task.rcov_opts = ['--exclude', RCOV_EXCLUDES, '--text-report', '--save']
168
+ task.rcov = true
169
+ end
170
+ end
171
+
172
+ task :clobber_coverage do
173
+ rmtree( COVERAGE_TARGETDIR )
174
+ end
175
+
176
+ rescue LoadError => err
177
+ task :no_rcov do
178
+ $stderr.puts "Coverage tasks not defined: RSpec+RCov tasklib not available: %s" %
179
+ [ err.message ]
180
+ end
181
+
182
+ task :coverage => :no_rcov
183
+ task :clobber_coverage
184
+ task :rcov => :no_rcov
185
+ namespace :coverage do
186
+ task :text => :no_rcov
187
+ task :diff => :no_rcov
188
+ end
189
+ task :verify => :no_rcov
190
+ end
191
+
192
+
@@ -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:
@@ -0,0 +1,155 @@
1
+ #!/usr/bin/ruby
2
+
3
+ begin
4
+ require 'wordnet'
5
+ rescue LoadError
6
+ unless Object.const_defined?( :Gem )
7
+ require 'rubygems'
8
+ retry
9
+ end
10
+ raise
11
+ end
12
+
13
+ module WordNet::SpecHelpers
14
+
15
+ ###############
16
+ module_function
17
+ ###############
18
+
19
+ ### Create a temporary working directory and return
20
+ ### a Pathname object for it.
21
+ def make_tempdir
22
+ dirname = "%s.%d.%0.4f" % [
23
+ 'wordnet_spec',
24
+ Process.pid,
25
+ (Time.now.to_f % 3600),
26
+ ]
27
+ tempdir = Pathname.new( Dir.tmpdir ) + dirname
28
+ tempdir.mkpath
29
+
30
+ return tempdir
31
+ end
32
+
33
+ end
34
+
35
+ # Override the badly-formatted output of the RSpec HTML formatter
36
+ require 'spec/runner/formatter/html_formatter'
37
+
38
+ class Spec::Runner::Formatter::HtmlFormatter
39
+ def example_failed( example, counter, failure )
40
+ failure_style = failure.pending_fixed? ? 'pending_fixed' : 'failed'
41
+
42
+ unless @header_red
43
+ @output.puts " <script type=\"text/javascript\">makeRed('rspec-header');</script>"
44
+ @header_red = true
45
+ end
46
+
47
+ unless @example_group_red
48
+ css_class = 'example_group_%d' % [current_example_group_number]
49
+ @output.puts " <script type=\"text/javascript\">makeRed('#{css_class}');</script>"
50
+ @example_group_red = true
51
+ end
52
+
53
+ move_progress()
54
+
55
+ @output.puts " <dd class=\"spec #{failure_style}\">",
56
+ " <span class=\"failed_spec_name\">#{h(example.description)}</span>",
57
+ " <div class=\"failure\" id=\"failure_#{counter}\">"
58
+ if failure.exception
59
+ backtrace = format_backtrace( failure.exception.backtrace )
60
+ message = failure.exception.message
61
+
62
+ @output.puts " <div class=\"message\"><code>#{h message}</code></div>",
63
+ " <div class=\"backtrace\"><pre>#{backtrace}</pre></div>"
64
+ end
65
+
66
+ if extra = extra_failure_content( failure )
67
+ @output.puts( extra )
68
+ end
69
+
70
+ @output.puts " </div>",
71
+ " </dd>"
72
+ @output.flush
73
+ end
74
+
75
+
76
+ alias_method :default_global_styles, :global_styles
77
+
78
+ def global_styles
79
+ css = default_global_styles()
80
+ css << %Q{
81
+ /* Stuff added by #{__FILE__} */
82
+
83
+ /* Overrides */
84
+ #rspec-header {
85
+ -webkit-box-shadow: #333 0 2px 5px;
86
+ margin-bottom: 1em;
87
+ }
88
+
89
+ .example_group dt {
90
+ -webkit-box-shadow: #333 0 2px 3px;
91
+ }
92
+
93
+ /* Style for log output */
94
+ dd.log-message {
95
+ background: #eee;
96
+ padding: 0 2em;
97
+ margin: 0.2em 1em;
98
+ border-bottom: 1px dotted #999;
99
+ border-top: 1px dotted #999;
100
+ text-indent: -1em;
101
+ }
102
+
103
+ /* Parts of the message */
104
+ dd.log-message .log-time {
105
+ font-weight: bold;
106
+ }
107
+ dd.log-message .log-time:after {
108
+ content: ": ";
109
+ }
110
+ dd.log-message .log-level {
111
+ font-variant: small-caps;
112
+ border: 1px solid #ccc;
113
+ padding: 1px 2px;
114
+ }
115
+ dd.log-message .log-name {
116
+ font-size: 1.2em;
117
+ color: #1e51b2;
118
+ }
119
+ dd.log-message .log-name:before { content: "«"; }
120
+ dd.log-message .log-name:after { content: "»"; }
121
+
122
+ dd.log-message .log-message-text {
123
+ padding-left: 4px;
124
+ font-family: Monaco, "Andale Mono", "Vera Sans Mono", mono;
125
+ }
126
+
127
+
128
+ /* Distinguish levels */
129
+ dd.log-message.debug { color: #666; }
130
+ dd.log-message.info {}
131
+
132
+ dd.log-message.warn,
133
+ dd.log-message.error {
134
+ background: #ff9;
135
+ }
136
+ dd.log-message.error .log-level,
137
+ dd.log-message.error .log-message-text {
138
+ color: #900;
139
+ }
140
+ dd.log-message.fatal {
141
+ background: #900;
142
+ color: white;
143
+ font-weight: bold;
144
+ border: 0;
145
+ }
146
+ dd.log-message.fatal .log-name {
147
+ color: white;
148
+ }
149
+ }
150
+
151
+ return css
152
+ end
153
+ end
154
+
155
+
@@ -0,0 +1,248 @@
1
+ #!/usr/bin/env ruby
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 'fileutils'
14
+ require 'tmpdir'
15
+ require 'bdb'
16
+ require 'spec/runner'
17
+ require 'spec/lib/helpers'
18
+
19
+ require 'wordnet/lexicon'
20
+ rescue LoadError
21
+ unless Object.const_defined?( :Gem )
22
+ require 'rubygems'
23
+ retry
24
+ end
25
+ raise
26
+ end
27
+
28
+
29
+
30
+ #####################################################################
31
+ ### C O N T E X T S
32
+ #####################################################################
33
+
34
+ describe WordNet::Lexicon do
35
+ include WordNet::SpecHelpers
36
+
37
+ TEST_WORDS = {
38
+ 'activity' => WordNet::Noun,
39
+ 'sword' => WordNet::Noun,
40
+ 'density' => WordNet::Noun,
41
+ 'burly' => WordNet::Adjective,
42
+ 'wispy' => WordNet::Adjective,
43
+ 'traditional' => WordNet::Adjective,
44
+ 'sit' => WordNet::Verb,
45
+ 'take' => WordNet::Verb,
46
+ 'joust' => WordNet::Verb,
47
+ }
48
+
49
+
50
+ before( :each ) do
51
+ @path = make_tempdir()
52
+ end
53
+
54
+
55
+ after( :each ) do
56
+ FileUtils.rm_rf @path, :verbose => $DEBUG
57
+ end
58
+
59
+
60
+
61
+ #################################################################
62
+ ### T E S T S
63
+ #################################################################
64
+
65
+ it "defaults to being in :readonly mode" do
66
+ env = stub( "bdb environment handle", :open_db => nil )
67
+ BDB::Env.should_receive( :new ).
68
+ with( @path.to_s, WordNet::Lexicon::ENV_FLAGS_RO, WordNet::Lexicon::ENV_OPTIONS ).
69
+ and_return( env )
70
+
71
+ lex = WordNet::Lexicon.new( @path.to_s )
72
+
73
+ lex.should be_readonly()
74
+ lex.should_not be_readwrite()
75
+ end
76
+
77
+ it "can be created in :writable mode" do
78
+ env = stub( "bdb environment handle", :open_db => nil )
79
+ BDB::Env.should_receive( :new ).
80
+ with( @path.to_s, WordNet::Lexicon::ENV_FLAGS_RW, WordNet::Lexicon::ENV_OPTIONS ).
81
+ and_return( env )
82
+
83
+ lex = WordNet::Lexicon.new( @path.to_s, :writable )
84
+
85
+ lex.should_not be_readonly()
86
+ lex.should be_readwrite()
87
+ end
88
+
89
+ it "passes a read/write flagset to BDB when created in :readwrite mode" do
90
+ env = stub( "bdb environment handle", :open_db => nil )
91
+ BDB::Env.should_receive( :new ).
92
+ with( @path.to_s, WordNet::Lexicon::ENV_FLAGS_RW, WordNet::Lexicon::ENV_OPTIONS ).
93
+ and_return( env )
94
+
95
+ lex = WordNet::Lexicon.new( @path.to_s, :readwrite )
96
+
97
+ lex.should_not be_readonly()
98
+ lex.should be_readwrite()
99
+ end
100
+
101
+
102
+ describe "created in readonly mode" do
103
+
104
+ before( :each ) do
105
+ @env = mock( "bdb environment handle" )
106
+ BDB::Env.stub!( :new ).and_return( @env )
107
+ @env.stub!( :open_db )
108
+
109
+ @lexicon = WordNet::Lexicon.new( @path.to_s, :readonly )
110
+ end
111
+
112
+
113
+ it "doesn't try to remove logs" do
114
+ @env.should_not_receive( :log_archive )
115
+ @lexicon.clean_logs
116
+ end
117
+
118
+
119
+ end
120
+
121
+
122
+ describe "created in readwrite mode" do
123
+
124
+ before( :each ) do
125
+ @env = mock( "bdb environment handle" )
126
+ BDB::Env.stub!( :new ).and_return( @env )
127
+ @env.stub!( :open_db )
128
+
129
+ @lexicon = WordNet::Lexicon.new( @path.to_s, :readwrite )
130
+ end
131
+
132
+
133
+ it "can be closed" do
134
+ @env.should_receive( :close )
135
+ @lexicon.close
136
+ end
137
+
138
+ it "provides a delegator for the checkpoint method of the underlying database" do
139
+ @env.should_receive( :checkpoint )
140
+ @lexicon.checkpoint
141
+ end
142
+
143
+ it "provides an interface to clean up database transaction logs" do
144
+ @env.should_receive( :log_archive ).with( BDB::ARCH_ABS ).
145
+ and_return([ :log1, :log2 ])
146
+ File.should_receive( :chmod ).with( 0777, :log1 )
147
+ File.should_receive( :delete ).with( :log1 )
148
+ File.should_receive( :chmod ).with( 0777, :log2 )
149
+ File.should_receive( :delete ).with( :log2 )
150
+
151
+ @lexicon.clean_logs
152
+ end
153
+
154
+
155
+ end
156
+
157
+
158
+ describe "with a converted WordNet database" do
159
+
160
+ before( :all ) do
161
+ @basedir = Pathname.new( __FILE__ ).dirname.parent.parent
162
+ @datadir = @basedir + 'ruby-wordnet'
163
+ end
164
+
165
+ before( :each ) do
166
+ pending "you haven't converted the WordNet datafiles yet -- try 'rake convert'" unless
167
+ @datadir.directory?
168
+
169
+ @lexicon = WordNet::Lexicon.new( @datadir.to_s )
170
+ end
171
+
172
+
173
+ TEST_WORDS.each do |word, pos|
174
+ it "returns a Fixnum value for the familiarity of #{word}(#{pos})" do
175
+ @lexicon.familiarity( word, pos ).should be_an_instance_of( Fixnum )
176
+ end
177
+ end
178
+
179
+
180
+ it "returns the root word as the morphological conversion of a dictionary word it knows about" do
181
+ @lexicon.morph( "angriest", WordNet::Adjective ).should == 'angry'
182
+ end
183
+
184
+
185
+ it "returns nil as the morphological conversion of a dictionary word it doesn't know about" do
186
+ @lexicon.morph( "Passomoquoddy", WordNet::Noun ).should be_nil()
187
+ end
188
+
189
+
190
+ it "returns the 'reverse morph' of dictionary words it knows about" do
191
+ @lexicon.reverse_morph( "angry" ).should == 'angriest%a'
192
+ end
193
+
194
+
195
+ it "tries looking up a failing via its morphological conversion if the original fails" do
196
+ synsets = @lexicon.lookup_synsets( 'angriest', WordNet::Adjective )
197
+
198
+ synsets.should_not be_nil()
199
+ synsets.first.should be_an_instance_of( WordNet::Synset )
200
+ synsets.first.words.should include( 'angry' )
201
+ end
202
+
203
+
204
+ it "returns only the requested sense if a sense is specified" do
205
+ synset = @lexicon.lookup_synsets( 'run', WordNet::Verb, 4 )
206
+ synset.should be_an_instance_of( WordNet::Synset )
207
+ synset.words.first.should =~ /operate/i
208
+ end
209
+
210
+
211
+ it "can find every compound sense of a word in its dictionary" do
212
+ words = @lexicon.grep( 'thing' )
213
+
214
+ words.should have(10).members
215
+ words.should include( 'thing%n' )
216
+ words.should include( 'thing-in-itself%n' )
217
+ words.should include( 'thingamabob%n' )
218
+ words.should include( 'thingamajig%n' )
219
+ words.should include( 'thingmabob%n' )
220
+ words.should include( 'thingmajig%n' )
221
+ words.should include( 'things%n' )
222
+ words.should include( 'thingumabob%n' )
223
+ words.should include( 'thingumajig%n' )
224
+ words.should include( 'thingummy%n' )
225
+ end
226
+
227
+
228
+ TEST_WORDS.each do |word, pos|
229
+ it "can look up the synset #{word}(#{pos}) by word and part-of-speech" do
230
+ synsets = @lexicon.lookup_synsets( word, pos )
231
+
232
+ synsets.should have_at_least(1).members
233
+ synsets.each do |ss|
234
+ ss.should be_an_instance_of( WordNet::Synset )
235
+ end
236
+ end
237
+ end
238
+
239
+
240
+ it "can act as a factory for new synsets" do
241
+ @lexicon.create_synset( "Ruby", WordNet::Noun ).
242
+ should be_an_instance_of( WordNet::Synset )
243
+ end
244
+
245
+ end
246
+
247
+ end
248
+