linguistics 1.0.8

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,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
+
@@ -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
+