summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-03-31 23:56:09 -0500
committerLuke Kanies <luke@madstop.com>2008-03-31 23:56:09 -0500
commit88dc49cb7b0efe757c92ce28c807b91335acb07a (patch)
tree13fe4561f1f524f97a8bb2c1ff84c1ef981d0241
parent4165edaeb71ee2883b1bb85ff39a52d5628b259f (diff)
parenta8592f1009040ebf30a98268610915cc33bb3f63 (diff)
downloadpuppet-88dc49cb7b0efe757c92ce28c807b91335acb07a.tar.gz
puppet-88dc49cb7b0efe757c92ce28c807b91335acb07a.tar.xz
puppet-88dc49cb7b0efe757c92ce28c807b91335acb07a.zip
Merge branch 'master' into master_no_global_resources
Conflicts: lib/puppet/node/catalog.rb lib/puppet/type/pfile.rb lib/puppet/type/pfilebucket.rb lib/puppet/util/filetype.rb spec/unit/node/catalog.rb spec/unit/other/transbucket.rb spec/unit/ral/provider/mount/parsed.rb spec/unit/ral/types/file.rb spec/unit/ral/types/interface.rb spec/unit/ral/types/mount.rb spec/unit/ral/types/package.rb spec/unit/ral/types/schedule.rb spec/unit/ral/types/service.rb test/language/compile.rb test/language/lexer.rb test/language/snippets.rb test/lib/puppettest.rb test/ral/types/basic.rb test/ral/types/cron.rb test/ral/types/exec.rb test/ral/types/file.rb test/ral/types/file/target.rb test/ral/types/filebucket.rb test/ral/types/fileignoresource.rb test/ral/types/filesources.rb test/ral/types/group.rb test/ral/types/host.rb test/ral/types/parameter.rb test/ral/types/sshkey.rb test/ral/types/tidy.rb test/ral/types/user.rb test/ral/types/yumrepo.rb
-rw-r--r--CHANGELOG196
-rw-r--r--Rakefile15
-rw-r--r--autotest/discover.rb (renamed from spec/lib/autotest/discover.rb)0
-rw-r--r--autotest/puppet_rspec.rb60
-rw-r--r--autotest/rspec.rb74
-rwxr-xr-xbin/puppet28
-rwxr-xr-xbin/puppetd32
-rwxr-xr-xbin/puppetdoc18
-rwxr-xr-xbin/puppetmasterd5
-rwxr-xr-xbin/puppetrun11
-rwxr-xr-xbin/ralsh23
-rw-r--r--conf/freebsd/puppetd2
-rw-r--r--conf/freebsd/puppetmasterd2
-rw-r--r--[-rwxr-xr-x]conf/gentoo/puppet/puppet.conf (renamed from conf/gentoo/puppet/puppetca.conf)2
-rw-r--r--conf/gentoo/puppet/puppetd.conf29
-rwxr-xr-xconf/gentoo/puppet/puppetmasterd.conf29
-rw-r--r--conf/namespaceauth.conf20
-rw-r--r--conf/redhat/puppet.spec2
-rw-r--r--conf/solaris/smf/puppetd.xml2
-rw-r--r--conf/solaris/smf/puppetmasterd.xml2
-rw-r--r--conf/suse/puppet.spec18
-rw-r--r--debian/README.source11
-rw-r--r--debian/changelog111
-rw-r--r--debian/control4
-rw-r--r--debian/puppet.conf1
-rw-r--r--debian/puppet.dirs3
-rw-r--r--debian/puppet.init13
-rwxr-xr-x[-rw-r--r--]debian/rules11
-rw-r--r--examples/root/etc/puppet/puppet.conf (renamed from examples/root/etc/puppet/puppetmasterd.conf)9
-rw-r--r--examples/root/etc/puppet/puppetd.conf4
-rw-r--r--ext/emacs/puppet-mode.el202
-rw-r--r--ext/ldap/puppet.schema7
-rw-r--r--ext/logcheck/puppet5
-rwxr-xr-xext/puppet-test76
-rwxr-xr-xinstall.rb80
-rw-r--r--lib/puppet.rb14
-rw-r--r--lib/puppet/defaults.rb25
-rw-r--r--lib/puppet/dsl.rb88
-rw-r--r--lib/puppet/file_serving/configuration/parser.rb6
-rw-r--r--lib/puppet/file_serving/file_base.rb19
-rw-r--r--lib/puppet/file_serving/metadata.rb40
-rw-r--r--lib/puppet/indirector/facts/facter.rb3
-rw-r--r--lib/puppet/indirector/indirection.rb2
-rw-r--r--lib/puppet/indirector/node/exec.rb9
-rw-r--r--lib/puppet/indirector/node/ldap.rb12
-rw-r--r--lib/puppet/indirector/node/plain.rb7
-rw-r--r--lib/puppet/indirector/report/processor.rb3
-rw-r--r--lib/puppet/indirector/terminus.rb1
-rw-r--r--lib/puppet/indirector/yaml.rb10
-rw-r--r--lib/puppet/metatype/closure.rb4
-rw-r--r--lib/puppet/metatype/evaluation.rb41
-rw-r--r--lib/puppet/metatype/metaparams.rb8
-rw-r--r--lib/puppet/metatype/providers.rb11
-rw-r--r--lib/puppet/network.rb3
-rwxr-xr-xlib/puppet/network/authstore.rb3
-rw-r--r--lib/puppet/network/client.rb12
-rw-r--r--lib/puppet/network/client/master.rb37
-rwxr-xr-xlib/puppet/network/handler/fileserver.rb116
-rw-r--r--lib/puppet/network/handler/master.rb2
-rwxr-xr-xlib/puppet/network/handler/report.rb3
-rw-r--r--lib/puppet/network/http/mongrel/rest.rb6
-rw-r--r--lib/puppet/network/http/webrick/rest.rb8
-rw-r--r--lib/puppet/network/http_pool.rb26
-rw-r--r--lib/puppet/network/http_server/mongrel.rb8
-rw-r--r--lib/puppet/network/http_server/webrick.rb7
-rw-r--r--lib/puppet/network/server.rb2
-rw-r--r--lib/puppet/network/xmlrpc/client.rb13
-rw-r--r--lib/puppet/node.rb2
-rw-r--r--lib/puppet/node/catalog.rb93
-rw-r--r--lib/puppet/node/environment.rb3
-rw-r--r--lib/puppet/parser/ast.rb76
-rw-r--r--lib/puppet/parser/ast/astarray.rb29
-rw-r--r--lib/puppet/parser/ast/caseopt.rb8
-rw-r--r--lib/puppet/parser/ast/casestatement.rb9
-rw-r--r--lib/puppet/parser/ast/collection.rb8
-rw-r--r--lib/puppet/parser/ast/collexpr.rb8
-rw-r--r--lib/puppet/parser/ast/definition.rb307
-rw-r--r--lib/puppet/parser/ast/else.rb5
-rw-r--r--lib/puppet/parser/ast/function.rb13
-rw-r--r--lib/puppet/parser/ast/hostclass.rb125
-rw-r--r--lib/puppet/parser/ast/ifstatement.rb9
-rw-r--r--lib/puppet/parser/ast/leaf.rb12
-rw-r--r--lib/puppet/parser/ast/node.rb84
-rw-r--r--lib/puppet/parser/ast/resource.rb12
-rw-r--r--lib/puppet/parser/ast/resource_defaults.rb6
-rw-r--r--lib/puppet/parser/ast/resource_override.rb10
-rw-r--r--lib/puppet/parser/ast/resource_reference.rb6
-rw-r--r--lib/puppet/parser/ast/resourceparam.rb6
-rw-r--r--lib/puppet/parser/ast/selector.rb11
-rw-r--r--lib/puppet/parser/ast/tag.rb6
-rw-r--r--lib/puppet/parser/ast/vardef.rb7
-rw-r--r--lib/puppet/parser/collector.rb10
-rw-r--r--lib/puppet/parser/compiler.rb (renamed from lib/puppet/parser/compile.rb)168
-rw-r--r--lib/puppet/parser/functions.rb6
-rw-r--r--lib/puppet/parser/grammar.ra4
-rw-r--r--lib/puppet/parser/interpreter.rb55
-rw-r--r--lib/puppet/parser/lexer.rb673
-rw-r--r--lib/puppet/parser/parser.rb9
-rw-r--r--lib/puppet/parser/parser_support.rb30
-rw-r--r--lib/puppet/parser/resource.rb89
-rw-r--r--lib/puppet/parser/resource/param.rb2
-rw-r--r--lib/puppet/parser/resource/reference.rb10
-rw-r--r--lib/puppet/parser/scope.rb19
-rw-r--r--lib/puppet/parser/templatewrapper.rb2
-rw-r--r--lib/puppet/pgraph.rb43
-rw-r--r--lib/puppet/provider/interface/redhat.rb130
-rwxr-xr-xlib/puppet/provider/mailalias/aliases.rb5
-rw-r--r--lib/puppet/provider/nameservice/directoryservice.rb13
-rwxr-xr-xlib/puppet/provider/package/fink.rb2
-rwxr-xr-xlib/puppet/provider/package/gem.rb14
-rwxr-xr-xlib/puppet/provider/package/openbsd.rb14
-rw-r--r--lib/puppet/provider/package/pkgdmg.rb7
-rw-r--r--lib/puppet/provider/package/portage.rb16
-rwxr-xr-xlib/puppet/provider/package/ports.rb3
-rw-r--r--lib/puppet/provider/package/yumhelper.py14
-rwxr-xr-xlib/puppet/provider/service/debian.rb3
-rw-r--r--lib/puppet/provider/service/gentoo.rb4
-rwxr-xr-xlib/puppet/provider/service/init.rb2
-rwxr-xr-xlib/puppet/provider/sshkey/parsed.rb2
-rw-r--r--lib/puppet/provider/user/useradd.rb4
-rw-r--r--lib/puppet/provider/zone/solaris.rb3
-rw-r--r--lib/puppet/rails.rb4
-rw-r--r--lib/puppet/rails/database/001_add_created_at_to_all_tables.rb17
-rw-r--r--lib/puppet/rails/external/tagging/README4
-rw-r--r--lib/puppet/rails/external/tagging/acts_as_taggable.rb62
-rw-r--r--lib/puppet/rails/external/tagging/init.rb5
-rw-r--r--lib/puppet/rails/external/tagging/tag.rb50
-rw-r--r--lib/puppet/rails/external/tagging/tagging.rb12
-rw-r--r--lib/puppet/rails/fact_value.rb4
-rw-r--r--lib/puppet/rails/host.rb3
-rw-r--r--lib/puppet/rails/param_value.rb4
-rw-r--r--lib/puppet/rails/puppet_class.rb6
-rw-r--r--lib/puppet/rails/resource_tag.rb4
-rw-r--r--lib/puppet/rails/source_file.rb5
-rw-r--r--lib/puppet/reference/node_source.rb9
-rw-r--r--lib/puppet/reference/report.rb21
-rw-r--r--lib/puppet/reports/tagmail.rb15
-rw-r--r--lib/puppet/resource_reference.rb5
-rw-r--r--lib/puppet/simple_graph.rb23
-rwxr-xr-xlib/puppet/sslcertificates.rb2
-rw-r--r--lib/puppet/sslcertificates/ca.rb36
-rw-r--r--lib/puppet/transaction.rb11
-rw-r--r--lib/puppet/transportable.rb48
-rw-r--r--lib/puppet/type.rb15
-rwxr-xr-xlib/puppet/type/cron.rb18
-rwxr-xr-xlib/puppet/type/exec.rb35
-rw-r--r--lib/puppet/type/file.rb (renamed from lib/puppet/type/pfile.rb)146
-rwxr-xr-xlib/puppet/type/file/checksum.rb274
-rwxr-xr-xlib/puppet/type/file/content.rb (renamed from lib/puppet/type/pfile/content.rb)25
-rwxr-xr-xlib/puppet/type/file/ensure.rb (renamed from lib/puppet/type/pfile/ensure.rb)23
-rwxr-xr-xlib/puppet/type/file/group.rb (renamed from lib/puppet/type/pfile/group.rb)0
-rwxr-xr-xlib/puppet/type/file/mode.rb (renamed from lib/puppet/type/pfile/mode.rb)0
-rwxr-xr-xlib/puppet/type/file/owner.rb (renamed from lib/puppet/type/pfile/owner.rb)0
-rwxr-xr-xlib/puppet/type/file/source.rb (renamed from lib/puppet/type/pfile/source.rb)82
-rw-r--r--lib/puppet/type/file/target.rb (renamed from lib/puppet/type/pfile/target.rb)0
-rwxr-xr-xlib/puppet/type/file/type.rb (renamed from lib/puppet/type/pfile/type.rb)0
-rwxr-xr-xlib/puppet/type/filebucket.rb (renamed from lib/puppet/type/pfilebucket.rb)0
-rwxr-xr-xlib/puppet/type/host.rb16
-rwxr-xr-xlib/puppet/type/mailalias.rb2
-rw-r--r--lib/puppet/type/package.rb14
-rwxr-xr-xlib/puppet/type/pfile/checksum.rb326
-rw-r--r--lib/puppet/type/service.rb13
-rwxr-xr-xlib/puppet/type/sshkey.rb6
-rwxr-xr-xlib/puppet/type/tidy.rb2
-rw-r--r--lib/puppet/util.rb3
-rw-r--r--lib/puppet/util/autoload.rb10
-rw-r--r--lib/puppet/util/checksums.rb64
-rw-r--r--lib/puppet/util/constant_inflector.rb15
-rw-r--r--lib/puppet/util/diff.rb4
-rw-r--r--lib/puppet/util/fileparsing.rb3
-rwxr-xr-xlib/puppet/util/filetype.rb10
-rw-r--r--lib/puppet/util/graph.rb2
-rw-r--r--lib/puppet/util/settings.rb268
-rw-r--r--lib/puppet/util/tagging.rb40
-rw-r--r--man/man8/filebucket.8116
-rw-r--r--man/man8/pi.834
-rw-r--r--man/man8/puppet.8575
-rw-r--r--man/man8/puppet.conf.81747
-rw-r--r--man/man8/puppetca.8116
-rw-r--r--man/man8/puppetd.8184
-rw-r--r--man/man8/puppetdoc.862
-rw-r--r--man/man8/puppetmasterd.887
-rw-r--r--man/man8/puppetrun.8151
-rw-r--r--man/man8/ralsh.8148
-rw-r--r--spec/Rakefile12
-rwxr-xr-xspec/integration/file_serving/configuration.rb4
-rwxr-xr-xspec/integration/node.rb8
-rw-r--r--spec/lib/autotest/puppet_rspec.rb46
-rw-r--r--spec/lib/autotest/rspec.rb95
-rw-r--r--spec/lib/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb31
-rw-r--r--spec/lib/spec.rb13
-rw-r--r--spec/lib/spec/dsl.rb11
-rw-r--r--spec/lib/spec/dsl/behaviour.rb221
-rw-r--r--spec/lib/spec/dsl/behaviour_callbacks.rb82
-rw-r--r--spec/lib/spec/dsl/behaviour_eval.rb231
-rwxr-xr-xspec/lib/spec/dsl/behaviour_factory.rb42
-rw-r--r--spec/lib/spec/dsl/composite_proc_builder.rb33
-rwxr-xr-xspec/lib/spec/dsl/description.rb76
-rw-r--r--spec/lib/spec/dsl/example.rb135
-rwxr-xr-xspec/lib/spec/dsl/example_matcher.rb40
-rw-r--r--spec/lib/spec/dsl/example_should_raise_handler.rb74
-rw-r--r--spec/lib/spec/expectations/errors.rb6
-rwxr-xr-xspec/lib/spec/extensions.rb1
-rw-r--r--spec/lib/spec/mocks/mock.rb29
-rw-r--r--spec/lib/spec/mocks/spec_methods.rb30
-rw-r--r--spec/lib/spec/runner/behaviour_runner.rb123
-rw-r--r--spec/lib/spec/runner/command_line.rb22
-rw-r--r--spec/lib/spec/runner/extensions/kernel.rb50
-rw-r--r--spec/lib/spec/runner/extensions/object.rb32
-rw-r--r--spec/lib/spec/runner/formatter.rb9
-rw-r--r--spec/lib/spec/runner/formatter/failing_behaviours_formatter.rb29
-rw-r--r--spec/lib/spec/runner/formatter/rdoc_formatter.rb24
-rw-r--r--spec/lib/spec/runner/formatter/specdoc_formatter.rb29
-rw-r--r--spec/lib/spec/runner/option_parser.rb227
-rw-r--r--spec/lib/spec/runner/options.rb175
-rw-r--r--spec/lib/spec/runner/reporter.rb125
-rw-r--r--spec/lib/spec/runner/spec_parser.rb50
-rwxr-xr-xspec/lib/spec/test_case_adapter.rb10
-rw-r--r--spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb43
-rw-r--r--spec/shared_behaviours/file_server_terminus.rb (renamed from spec/lib/shared_behaviours/file_server_terminus.rb)0
-rw-r--r--spec/shared_behaviours/file_serving.rb (renamed from spec/lib/shared_behaviours/file_serving.rb)0
-rw-r--r--spec/spec.opts4
-rw-r--r--spec/spec_helper.rb32
-rwxr-xr-xspec/unit/file_serving/configuration.rb389
-rwxr-xr-xspec/unit/file_serving/configuration/parser.rb175
-rwxr-xr-xspec/unit/file_serving/file_base.rb125
-rwxr-xr-xspec/unit/file_serving/metadata.rb74
-rwxr-xr-xspec/unit/indirector/catalog/compiler.rb6
-rwxr-xr-xspec/unit/indirector/checksum/file.rb176
-rwxr-xr-xspec/unit/indirector/direct_file_server.rb107
-rwxr-xr-xspec/unit/indirector/facts/facter.rb55
-rwxr-xr-xspec/unit/indirector/file.rb200
-rwxr-xr-xspec/unit/indirector/file_server.rb223
-rwxr-xr-xspec/unit/indirector/indirection.rb459
-rwxr-xr-xspec/unit/indirector/module_files.rb376
-rwxr-xr-xspec/unit/indirector/node/exec.rb89
-rwxr-xr-xspec/unit/indirector/node/ldap.rb292
-rwxr-xr-xspec/unit/indirector/node/plain.rb6
-rwxr-xr-xspec/unit/indirector/rest.rb2
-rwxr-xr-xspec/unit/indirector/terminus.rb255
-rwxr-xr-xspec/unit/indirector/yaml.rb124
-rw-r--r--spec/unit/network/client.rb43
-rwxr-xr-xspec/unit/network/http_pool.rb257
-rw-r--r--spec/unit/network/server.rb8
-rwxr-xr-xspec/unit/node.rb20
-rwxr-xr-xspec/unit/node/catalog.rb271
-rwxr-xr-xspec/unit/other/pgraph.rb35
-rwxr-xr-xspec/unit/other/transaction.rb7
-rwxr-xr-xspec/unit/other/transbucket.rb30
-rwxr-xr-xspec/unit/parser/ast/definition.rb158
-rwxr-xr-xspec/unit/parser/ast/hostclass.rb135
-rwxr-xr-xspec/unit/parser/ast/node.rb125
-rwxr-xr-xspec/unit/parser/collector.rb60
-rwxr-xr-xspec/unit/parser/compile.rb281
-rwxr-xr-xspec/unit/parser/compiler.rb532
-rwxr-xr-xspec/unit/parser/interpreter.rb285
-rwxr-xr-xspec/unit/parser/lexer.rb465
-rwxr-xr-xspec/unit/parser/resource.rb332
-rwxr-xr-xspec/unit/parser/resource/reference.rb8
-rwxr-xr-xspec/unit/ral/provider/interface/redhat.rb3
-rwxr-xr-xspec/unit/ral/provider/mount.rb172
-rwxr-xr-xspec/unit/ral/provider/mount/parsed.rb151
-rwxr-xr-xspec/unit/ral/type.rb4
-rwxr-xr-xspec/unit/ral/type/exec.rb (renamed from spec/unit/ral/types/exec.rb)0
-rwxr-xr-xspec/unit/ral/type/file.rb96
-rwxr-xr-xspec/unit/ral/type/interface.rb (renamed from spec/unit/ral/types/interface.rb)0
-rwxr-xr-xspec/unit/ral/type/mount.rb184
-rwxr-xr-xspec/unit/ral/type/nagios.rb (renamed from spec/unit/ral/types/nagios.rb)0
-rwxr-xr-xspec/unit/ral/type/noop_metaparam.rb38
-rwxr-xr-xspec/unit/ral/type/package.rb (renamed from spec/unit/ral/types/package.rb)186
-rwxr-xr-xspec/unit/ral/type/schedule.rb335
-rwxr-xr-xspec/unit/ral/type/service.rb (renamed from spec/unit/ral/types/service.rb)15
-rwxr-xr-xspec/unit/ral/type/user.rb (renamed from spec/unit/ral/types/user.rb)0
-rwxr-xr-xspec/unit/ral/types/file.rb28
-rwxr-xr-xspec/unit/ral/types/mount.rb187
-rwxr-xr-xspec/unit/ral/types/schedule.rb370
-rwxr-xr-xspec/unit/resource_reference.rb6
-rwxr-xr-xspec/unit/simple_graph.rb75
-rwxr-xr-xspec/unit/util/checksums.rb99
-rwxr-xr-xspec/unit/util/constant_inflector.rb70
-rwxr-xr-xspec/unit/util/settings.rb75
-rwxr-xr-xspec/unit/util/tagging.rb92
-rw-r--r--test/data/snippets/collection_within_virtual_definitions.pp20
-rw-r--r--test/data/snippets/realize_defined_types.pp13
-rwxr-xr-xtest/executables/puppetbin.rb17
-rwxr-xr-xtest/language/ast.rb66
-rwxr-xr-xtest/language/ast/casestatement.rb6
-rwxr-xr-xtest/language/ast/definition.rb166
-rwxr-xr-xtest/language/ast/hostclass.rb184
-rwxr-xr-xtest/language/ast/resource.rb13
-rwxr-xr-xtest/language/ast/resource_reference.rb24
-rwxr-xr-xtest/language/ast/selector.rb4
-rwxr-xr-xtest/language/ast/variable.rb4
-rwxr-xr-xtest/language/compile.rb569
-rwxr-xr-xtest/language/functions.rb48
-rwxr-xr-xtest/language/lexer.rb275
-rwxr-xr-xtest/language/parser.rb29
-rwxr-xr-xtest/language/resource.rb202
-rwxr-xr-xtest/language/scope.rb58
-rwxr-xr-xtest/language/snippets.rb6
-rw-r--r--test/lib/mocha/expectation_error.rb6
-rw-r--r--test/lib/mocha/missing_expectation.rb27
-rw-r--r--test/lib/mocha/parameter_matchers.rb9
-rwxr-xr-xtest/lib/puppettest.rb49
-rw-r--r--test/lib/puppettest/parsertesting.rb20
-rwxr-xr-xtest/lib/puppettest/support/resources.rb2
-rwxr-xr-xtest/network/client/client.rb29
-rwxr-xr-xtest/network/client/master.rb41
-rwxr-xr-xtest/network/handler/fileserver.rb100
-rwxr-xr-xtest/network/handler/master.rb15
-rwxr-xr-xtest/network/server/webrick.rb2
-rwxr-xr-xtest/other/dsl.rb7
-rwxr-xr-xtest/other/transactions.rb8
-rwxr-xr-xtest/rails/ast.rb4
-rwxr-xr-xtest/rails/configuration.rb2
-rwxr-xr-xtest/rails/railsparameter.rb2
-rwxr-xr-xtest/rails/railsresource.rb1
-rwxr-xr-xtest/ral/manager/provider.rb26
-rwxr-xr-xtest/ral/manager/type.rb24
-rwxr-xr-xtest/ral/providers/cron/crontab.rb5
-rwxr-xr-xtest/ral/providers/mailalias/aliases.rb1
-rwxr-xr-xtest/ral/providers/sshkey/parsed.rb1
-rwxr-xr-xtest/ral/type/basic.rb (renamed from test/ral/types/basic.rb)16
-rwxr-xr-xtest/ral/type/cron.rb (renamed from test/ral/types/cron.rb)0
-rwxr-xr-xtest/ral/type/exec.rb (renamed from test/ral/types/exec.rb)51
-rwxr-xr-xtest/ral/type/file.rb (renamed from test/ral/types/file.rb)108
-rwxr-xr-xtest/ral/type/file/target.rb (renamed from test/ral/types/file/target.rb)0
-rwxr-xr-xtest/ral/type/filebucket.rb (renamed from test/ral/types/filebucket.rb)0
-rwxr-xr-xtest/ral/type/fileignoresource.rb (renamed from test/ral/types/fileignoresource.rb)0
-rwxr-xr-xtest/ral/type/filesources.rb (renamed from test/ral/types/filesources.rb)0
-rwxr-xr-xtest/ral/type/group.rb (renamed from test/ral/types/group.rb)0
-rwxr-xr-xtest/ral/type/host.rb (renamed from test/ral/types/host.rb)73
-rwxr-xr-xtest/ral/type/mailalias.rb (renamed from test/ral/types/mailalias.rb)0
-rwxr-xr-xtest/ral/type/parameter.rb (renamed from test/ral/types/parameter.rb)0
-rwxr-xr-xtest/ral/type/port.rb (renamed from test/ral/types/port.rb)0
-rwxr-xr-xtest/ral/type/property.rb (renamed from test/ral/types/property.rb)0
-rwxr-xr-xtest/ral/type/resources.rb (renamed from test/ral/types/resources.rb)0
-rwxr-xr-xtest/ral/type/service.rb (renamed from test/ral/types/service.rb)0
-rwxr-xr-xtest/ral/type/sshkey.rb (renamed from test/ral/types/sshkey.rb)0
-rwxr-xr-xtest/ral/type/tidy.rb (renamed from test/ral/types/tidy.rb)12
-rwxr-xr-xtest/ral/type/user.rb (renamed from test/ral/types/user.rb)0
-rwxr-xr-xtest/ral/type/yumrepo.rb (renamed from test/ral/types/yumrepo.rb)4
-rwxr-xr-xtest/ral/type/zone.rb (renamed from test/ral/types/zone.rb)0
-rwxr-xr-xtest/util/autoload.rb29
-rwxr-xr-xtest/util/settings.rb63
-rw-r--r--vendor/gems/mocha-0.5.6/._RELEASEbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/._Rakefilebin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/COPYING3
-rw-r--r--vendor/gems/mocha-0.5.6/MIT-LICENSE7
-rw-r--r--vendor/gems/mocha-0.5.6/README35
-rw-r--r--vendor/gems/mocha-0.5.6/RELEASE188
-rw-r--r--vendor/gems/mocha-0.5.6/Rakefile149
-rw-r--r--vendor/gems/mocha-0.5.6/examples/._misc.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/examples/._mocha.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/examples/._stubba.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/examples/misc.rb44
-rw-r--r--vendor/gems/mocha-0.5.6/examples/mocha.rb26
-rw-r--r--vendor/gems/mocha-0.5.6/examples/stubba.rb65
-rw-r--r--vendor/gems/mocha-0.5.6/lib/._mocha.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha.rb (renamed from test/lib/mocha.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._any_instance_method.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._auto_verify.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._central.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._class_method.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._deprecation.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._expectation.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._expectation_error.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._expectation_list.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._infinite_range.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._inspect.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._instance_method.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._metaclass.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._method_matcher.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._missing_expectation.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._mock.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._object.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._parameter_matchers.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._parameters_matcher.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._pretty_parameters.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._return_values.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._sequence.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._setup_and_teardown.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._single_return_value.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._standalone.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._test_case_adapter.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/._yield_parameters.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/any_instance_method.rb (renamed from test/lib/mocha/any_instance_method.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/auto_verify.rb (renamed from test/lib/mocha/auto_verify.rb)75
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/central.rb (renamed from test/lib/mocha/central.rb)2
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/class_method.rb (renamed from test/lib/mocha/class_method.rb)6
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/deprecation.rb (renamed from test/lib/mocha/deprecation.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/exception_raiser.rb (renamed from test/lib/mocha/exception_raiser.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/expectation.rb (renamed from test/lib/mocha/expectation.rb)120
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/expectation_error.rb15
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/expectation_list.rb46
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/infinite_range.rb (renamed from test/lib/mocha/infinite_range.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/inspect.rb (renamed from test/lib/mocha/inspect.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/instance_method.rb (renamed from test/lib/mocha/instance_method.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/is_a.rb (renamed from test/lib/mocha/is_a.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/metaclass.rb (renamed from test/lib/mocha/metaclass.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/method_matcher.rb21
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/missing_expectation.rb17
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/mock.rb (renamed from test/lib/mocha/mock.rb)95
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/multiple_yields.rb (renamed from test/lib/mocha/multiple_yields.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/no_yields.rb (renamed from test/lib/mocha/no_yields.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/object.rb (renamed from test/lib/mocha/object.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers.rb25
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._all_of.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._any_of.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._any_parameters.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._anything.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._base.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._equals.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_entries.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_entry.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_key.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_value.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._includes.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._instance_of.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._is_a.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._kind_of.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._not.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._object.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._optionally.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._regexp_matches.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/all_of.rb (renamed from test/lib/mocha/parameter_matchers/all_of.rb)9
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/any_of.rb (renamed from test/lib/mocha/parameter_matchers/any_of.rb)9
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/any_parameters.rb40
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/anything.rb (renamed from test/lib/mocha/parameter_matchers/anything.rb)7
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/base.rb15
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/equals.rb42
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/has_entries.rb42
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/has_entry.rb (renamed from test/lib/mocha/parameter_matchers/has_entry.rb)24
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/has_key.rb (renamed from test/lib/mocha/parameter_matchers/has_key.rb)7
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/has_value.rb (renamed from test/lib/mocha/parameter_matchers/has_value.rb)7
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/includes.rb (renamed from test/lib/mocha/parameter_matchers/includes.rb)7
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/instance_of.rb42
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/is_a.rb42
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/kind_of.rb42
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/not.rb42
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/object.rb9
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/optionally.rb33
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/regexp_matches.rb43
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/parameters_matcher.rb37
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/pretty_parameters.rb (renamed from test/lib/mocha/pretty_parameters.rb)2
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/return_values.rb (renamed from test/lib/mocha/return_values.rb)11
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/sequence.rb42
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/setup_and_teardown.rb (renamed from test/lib/mocha/setup_and_teardown.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/single_return_value.rb (renamed from test/lib/mocha/single_return_value.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/single_yield.rb (renamed from test/lib/mocha/single_yield.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/standalone.rb (renamed from test/lib/mocha/standalone.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/stub.rb (renamed from test/lib/mocha/stub.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/test_case_adapter.rb (renamed from test/lib/mocha/test_case_adapter.rb)0
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha/yield_parameters.rb (renamed from test/lib/mocha/yield_parameters.rb)6
-rw-r--r--vendor/gems/mocha-0.5.6/lib/mocha_standalone.rb2
-rw-r--r--vendor/gems/mocha-0.5.6/lib/stubba.rb2
-rw-r--r--vendor/gems/mocha-0.5.6/test/._deprecation_disabler.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/._execution_point.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/._method_definer.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/._test_helper.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/._test_runner.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/._expected_invocation_count_acceptance_test.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/._mocha_acceptance_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/._mock_with_initializer_block_acceptance_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/._mocked_methods_dispatch_acceptance_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/._optional_parameters_acceptance_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/._parameter_matcher_acceptance_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/._partial_mocks_acceptance_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/._sequence_acceptance_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/._standalone_acceptance_test.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/._stubba_acceptance_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/expected_invocation_count_acceptance_test.rb187
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/mocha_acceptance_test.rb98
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/mock_with_initializer_block_acceptance_test.rb44
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/mocked_methods_dispatch_acceptance_test.rb71
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/optional_parameters_acceptance_test.rb63
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/parameter_matcher_acceptance_test.rb117
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/partial_mocks_acceptance_test.rb40
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/sequence_acceptance_test.rb179
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/standalone_acceptance_test.rb131
-rw-r--r--vendor/gems/mocha-0.5.6/test/acceptance/stubba_acceptance_test.rb102
-rw-r--r--vendor/gems/mocha-0.5.6/test/active_record_test_case.rb36
-rw-r--r--vendor/gems/mocha-0.5.6/test/deprecation_disabler.rb15
-rw-r--r--vendor/gems/mocha-0.5.6/test/execution_point.rb34
-rw-r--r--vendor/gems/mocha-0.5.6/test/integration/._mocha_test_result_integration_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/integration/._stubba_integration_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/integration/._stubba_test_result_integration_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/integration/mocha_test_result_integration_test.rb105
-rw-r--r--vendor/gems/mocha-0.5.6/test/integration/stubba_integration_test.rb89
-rw-r--r--vendor/gems/mocha-0.5.6/test/integration/stubba_test_result_integration_test.rb85
-rw-r--r--vendor/gems/mocha-0.5.6/test/method_definer.rb18
-rw-r--r--vendor/gems/mocha-0.5.6/test/test_helper.rb12
-rw-r--r--vendor/gems/mocha-0.5.6/test/test_runner.rb31
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._any_instance_method_test.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._auto_verify_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._central_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._class_method_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._expectation_error_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._expectation_list_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._expectation_test.rbbin0 -> 179 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._hash_inspect_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._method_matcher_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._missing_expectation_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._mock_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._object_inspect_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._parameters_matcher_test.rbbin0 -> 176 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/._sequence_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/any_instance_method_test.rb126
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/array_inspect_test.rb16
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/auto_verify_test.rb129
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/central_test.rb124
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/class_method_test.rb200
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/date_time_inspect_test.rb21
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/expectation_error_test.rb24
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/expectation_list_test.rb75
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/expectation_raiser_test.rb28
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/expectation_test.rb483
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/hash_inspect_test.rb16
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/infinite_range_test.rb53
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/metaclass_test.rb22
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/method_matcher_test.rb23
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/missing_expectation_test.rb42
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/mock_test.rb323
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/multiple_yields_test.rb18
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/no_yield_test.rb18
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/object_inspect_test.rb37
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/object_test.rb165
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._all_of_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._any_of_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._anything_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_entries_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_entry_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_key_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_value_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._includes_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._instance_of_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._is_a_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._kind_of_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._not_test.rbbin0 -> 177 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._regexp_matches_test.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._stub_matcher.rbbin0 -> 178 bytes
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/all_of_test.rb26
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/any_of_test.rb26
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/anything_test.rb21
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_entries_test.rb30
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_entry_test.rb40
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_key_test.rb25
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_value_test.rb25
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/includes_test.rb25
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/instance_of_test.rb25
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/is_a_test.rb25
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/kind_of_test.rb25
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/not_test.rb26
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/regexp_matches_test.rb25
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/stub_matcher.rb23
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/parameters_matcher_test.rb121
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/return_values_test.rb63
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/sequence_test.rb104
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/setup_and_teardown_test.rb76
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/single_return_value_test.rb33
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/single_yield_test.rb18
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/string_inspect_test.rb11
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/stub_test.rb24
-rw-r--r--vendor/gems/mocha-0.5.6/test/unit/yield_parameters_test.rb93
-rw-r--r--vendor/gems/rspec/CHANGES1045
-rw-r--r--vendor/gems/rspec/MIT-LICENSE20
-rw-r--r--vendor/gems/rspec/README71
-rw-r--r--vendor/gems/rspec/Rakefile279
-rw-r--r--vendor/gems/rspec/TODO2
-rw-r--r--vendor/gems/rspec/UPGRADE31
-rwxr-xr-xvendor/gems/rspec/bin/spec (renamed from spec/bin/spec)2
-rwxr-xr-xvendor/gems/rspec/bin/spec_translator8
-rw-r--r--vendor/gems/rspec/examples/pure/autogenerated_docstrings_example.rb19
-rw-r--r--vendor/gems/rspec/examples/pure/before_and_after_example.rb40
-rwxr-xr-xvendor/gems/rspec/examples/pure/behave_as_example.rb45
-rw-r--r--vendor/gems/rspec/examples/pure/custom_expectation_matchers.rb54
-rw-r--r--vendor/gems/rspec/examples/pure/custom_formatter.rb12
-rw-r--r--vendor/gems/rspec/examples/pure/dynamic_spec.rb9
-rw-r--r--vendor/gems/rspec/examples/pure/file_accessor.rb19
-rw-r--r--vendor/gems/rspec/examples/pure/file_accessor_spec.rb38
-rw-r--r--vendor/gems/rspec/examples/pure/greeter_spec.rb31
-rw-r--r--vendor/gems/rspec/examples/pure/helper_method_example.rb14
-rw-r--r--vendor/gems/rspec/examples/pure/io_processor.rb8
-rw-r--r--vendor/gems/rspec/examples/pure/io_processor_spec.rb21
-rw-r--r--vendor/gems/rspec/examples/pure/legacy_spec.rb11
-rw-r--r--vendor/gems/rspec/examples/pure/mocking_example.rb27
-rw-r--r--vendor/gems/rspec/examples/pure/multi_threaded_behaviour_runner.rb28
-rw-r--r--vendor/gems/rspec/examples/pure/nested_classes_example.rb36
-rw-r--r--vendor/gems/rspec/examples/pure/partial_mock_example.rb28
-rw-r--r--vendor/gems/rspec/examples/pure/pending_example.rb20
-rw-r--r--vendor/gems/rspec/examples/pure/predicate_example.rb27
-rw-r--r--vendor/gems/rspec/examples/pure/priority.txt1
-rw-r--r--vendor/gems/rspec/examples/pure/shared_example_group_example.rb81
-rw-r--r--vendor/gems/rspec/examples/pure/shared_stack_examples.rb38
-rw-r--r--vendor/gems/rspec/examples/pure/spec_helper.rb3
-rw-r--r--vendor/gems/rspec/examples/pure/stack.rb36
-rw-r--r--vendor/gems/rspec/examples/pure/stack_spec.rb63
-rw-r--r--vendor/gems/rspec/examples/pure/stack_spec_with_nested_example_groups.rb67
-rw-r--r--vendor/gems/rspec/examples/pure/stubbing_example.rb69
-rw-r--r--vendor/gems/rspec/examples/stories/adder.rb13
-rw-r--r--vendor/gems/rspec/examples/stories/addition34
-rw-r--r--vendor/gems/rspec/examples/stories/addition.rb9
-rw-r--r--vendor/gems/rspec/examples/stories/calculator.rb65
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/README.txt21
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/everything.rb6
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/examples/examples.rb3
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/examples/game_behaviour.rb35
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/examples/grid_behaviour.rb66
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/CellsWithLessThanTwoNeighboursDie.story21
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/CellsWithMoreThanThreeNeighboursDie.story21
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/EmptySpacesWithThreeNeighboursCreateACell.story42
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/ICanCreateACell.story42
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/ICanKillACell.story17
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/TheGridWraps.story53
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/create_a_cell.rb52
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/helper.rb6
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/kill_a_cell.rb26
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/steps.rb5
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/stories.rb3
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/stories.txt22
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/life.rb3
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/life/game.rb23
-rw-r--r--vendor/gems/rspec/examples/stories/game-of-life/life/grid.rb43
-rw-r--r--vendor/gems/rspec/examples/stories/helper.rb9
-rw-r--r--vendor/gems/rspec/examples/stories/steps/addition_steps.rb18
-rw-r--r--vendor/gems/rspec/failing_examples/README.txt7
-rw-r--r--vendor/gems/rspec/failing_examples/diffing_spec.rb36
-rw-r--r--vendor/gems/rspec/failing_examples/failing_autogenerated_docstrings_example.rb19
-rw-r--r--vendor/gems/rspec/failing_examples/failure_in_setup.rb10
-rw-r--r--vendor/gems/rspec/failing_examples/failure_in_teardown.rb10
-rw-r--r--vendor/gems/rspec/failing_examples/mocking_example.rb40
-rw-r--r--vendor/gems/rspec/failing_examples/mocking_with_flexmock.rb26
-rw-r--r--vendor/gems/rspec/failing_examples/mocking_with_mocha.rb25
-rw-r--r--vendor/gems/rspec/failing_examples/mocking_with_rr.rb27
-rw-r--r--vendor/gems/rspec/failing_examples/partial_mock_example.rb20
-rw-r--r--vendor/gems/rspec/failing_examples/predicate_example.rb29
-rw-r--r--vendor/gems/rspec/failing_examples/raising_example.rb47
-rw-r--r--vendor/gems/rspec/failing_examples/spec_helper.rb3
-rw-r--r--vendor/gems/rspec/failing_examples/syntax_error_example.rb7
-rw-r--r--vendor/gems/rspec/failing_examples/team_spec.rb44
-rw-r--r--vendor/gems/rspec/failing_examples/timeout_behaviour.rb7
-rw-r--r--vendor/gems/rspec/lib/autotest/discover.rb3
-rw-r--r--vendor/gems/rspec/lib/autotest/rspec.rb74
-rw-r--r--vendor/gems/rspec/lib/spec.rb30
-rw-r--r--vendor/gems/rspec/lib/spec/example.rb12
-rwxr-xr-xvendor/gems/rspec/lib/spec/example/configuration.rb (renamed from spec/lib/spec/dsl/configuration.rb)87
-rw-r--r--vendor/gems/rspec/lib/spec/example/errors.rb (renamed from spec/lib/spec/dsl/errors.rb)4
-rw-r--r--vendor/gems/rspec/lib/spec/example/example_group.rb16
-rwxr-xr-xvendor/gems/rspec/lib/spec/example/example_group_factory.rb62
-rw-r--r--vendor/gems/rspec/lib/spec/example/example_group_methods.rb424
-rwxr-xr-xvendor/gems/rspec/lib/spec/example/example_matcher.rb42
-rw-r--r--vendor/gems/rspec/lib/spec/example/example_methods.rb106
-rw-r--r--vendor/gems/rspec/lib/spec/example/module_reopening_fix.rb21
-rw-r--r--vendor/gems/rspec/lib/spec/example/pending.rb18
-rw-r--r--vendor/gems/rspec/lib/spec/example/shared_example_group.rb58
-rw-r--r--vendor/gems/rspec/lib/spec/expectations.rb (renamed from spec/lib/spec/expectations.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/expectations/differs/default.rb (renamed from spec/lib/spec/expectations/differs/default.rb)25
-rw-r--r--vendor/gems/rspec/lib/spec/expectations/errors.rb12
-rw-r--r--vendor/gems/rspec/lib/spec/expectations/extensions.rb (renamed from spec/lib/spec/expectations/extensions.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/expectations/extensions/object.rb (renamed from spec/lib/spec/expectations/extensions/object.rb)19
-rw-r--r--vendor/gems/rspec/lib/spec/expectations/extensions/string_and_symbol.rb (renamed from spec/lib/spec/expectations/extensions/string_and_symbol.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/expectations/handler.rb (renamed from spec/lib/spec/expectations/handler.rb)17
-rwxr-xr-xvendor/gems/rspec/lib/spec/extensions.rb3
-rw-r--r--vendor/gems/rspec/lib/spec/extensions/class.rb24
-rw-r--r--vendor/gems/rspec/lib/spec/extensions/main.rb102
-rwxr-xr-xvendor/gems/rspec/lib/spec/extensions/object.rb (renamed from spec/lib/spec/extensions/object.rb)6
-rw-r--r--vendor/gems/rspec/lib/spec/interop/test.rb12
-rw-r--r--vendor/gems/rspec/lib/spec/interop/test/unit/autorunner.rb6
-rw-r--r--vendor/gems/rspec/lib/spec/interop/test/unit/testcase.rb61
-rw-r--r--vendor/gems/rspec/lib/spec/interop/test/unit/testresult.rb6
-rw-r--r--vendor/gems/rspec/lib/spec/interop/test/unit/testsuite_adapter.rb34
-rw-r--r--vendor/gems/rspec/lib/spec/interop/test/unit/ui/console/testrunner.rb61
-rw-r--r--vendor/gems/rspec/lib/spec/matchers.rb (renamed from spec/lib/spec/matchers.rb)24
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/be.rb (renamed from spec/lib/spec/matchers/be.rb)32
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/be_close.rb (renamed from spec/lib/spec/matchers/be_close.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/change.rb (renamed from spec/lib/spec/matchers/change.rb)26
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/eql.rb (renamed from spec/lib/spec/matchers/eql.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/equal.rb (renamed from spec/lib/spec/matchers/equal.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/exist.rb17
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/has.rb (renamed from spec/lib/spec/matchers/has.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/have.rb (renamed from spec/lib/spec/matchers/have.rb)3
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/include.rb (renamed from spec/lib/spec/matchers/include.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/match.rb (renamed from spec/lib/spec/matchers/match.rb)0
-rwxr-xr-xvendor/gems/rspec/lib/spec/matchers/operator_matcher.rb (renamed from spec/lib/spec/matchers/operator_matcher.rb)1
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/raise_error.rb (renamed from spec/lib/spec/matchers/raise_error.rb)34
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/respond_to.rb (renamed from spec/lib/spec/matchers/respond_to.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/satisfy.rb (renamed from spec/lib/spec/matchers/satisfy.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/simple_matcher.rb29
-rw-r--r--vendor/gems/rspec/lib/spec/matchers/throw_symbol.rb (renamed from spec/lib/spec/matchers/throw_symbol.rb)2
-rw-r--r--vendor/gems/rspec/lib/spec/mocks.rb (renamed from spec/lib/spec/mocks.rb)7
-rw-r--r--vendor/gems/rspec/lib/spec/mocks/argument_constraint_matchers.rb (renamed from spec/lib/spec/mocks/argument_constraint_matchers.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/mocks/argument_expectation.rb (renamed from spec/lib/spec/mocks/argument_expectation.rb)2
-rw-r--r--vendor/gems/rspec/lib/spec/mocks/error_generator.rb (renamed from spec/lib/spec/mocks/error_generator.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/mocks/errors.rb (renamed from spec/lib/spec/mocks/errors.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/mocks/extensions/object.rb (renamed from spec/lib/spec/mocks/extensions/object.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/mocks/message_expectation.rb (renamed from spec/lib/spec/mocks/message_expectation.rb)119
-rw-r--r--vendor/gems/rspec/lib/spec/mocks/methods.rb (renamed from spec/lib/spec/mocks/methods.rb)4
-rw-r--r--vendor/gems/rspec/lib/spec/mocks/mock.rb50
-rw-r--r--vendor/gems/rspec/lib/spec/mocks/order_group.rb (renamed from spec/lib/spec/mocks/order_group.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/mocks/proxy.rb (renamed from spec/lib/spec/mocks/proxy.rb)49
-rw-r--r--vendor/gems/rspec/lib/spec/mocks/space.rb (renamed from spec/lib/spec/mocks/space.rb)2
-rw-r--r--vendor/gems/rspec/lib/spec/mocks/spec_methods.rb38
-rw-r--r--vendor/gems/rspec/lib/spec/rake/spectask.rb (renamed from spec/lib/spec/rake/spectask.rb)22
-rw-r--r--vendor/gems/rspec/lib/spec/rake/verify_rcov.rb (renamed from spec/lib/spec/rake/verify_rcov.rb)2
-rw-r--r--vendor/gems/rspec/lib/spec/runner.rb (renamed from spec/lib/spec/runner.rb)69
-rw-r--r--vendor/gems/rspec/lib/spec/runner/backtrace_tweaker.rb (renamed from spec/lib/spec/runner/backtrace_tweaker.rb)6
-rw-r--r--vendor/gems/rspec/lib/spec/runner/class_and_arguments_parser.rb16
-rw-r--r--vendor/gems/rspec/lib/spec/runner/command_line.rb28
-rw-r--r--vendor/gems/rspec/lib/spec/runner/drb_command_line.rb (renamed from spec/lib/spec/runner/drb_command_line.rb)9
-rw-r--r--vendor/gems/rspec/lib/spec/runner/example_group_runner.rb59
-rw-r--r--vendor/gems/rspec/lib/spec/runner/formatter/base_formatter.rb (renamed from spec/lib/spec/runner/formatter/base_formatter.rb)18
-rw-r--r--vendor/gems/rspec/lib/spec/runner/formatter/base_text_formatter.rb (renamed from spec/lib/spec/runner/formatter/base_text_formatter.rb)36
-rw-r--r--vendor/gems/rspec/lib/spec/runner/formatter/failing_example_groups_formatter.rb31
-rw-r--r--vendor/gems/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb (renamed from spec/lib/spec/runner/formatter/failing_examples_formatter.rb)8
-rw-r--r--vendor/gems/rspec/lib/spec/runner/formatter/html_formatter.rb (renamed from spec/lib/spec/runner/formatter/html_formatter.rb)64
-rw-r--r--vendor/gems/rspec/lib/spec/runner/formatter/profile_formatter.rb47
-rw-r--r--vendor/gems/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb (renamed from spec/lib/spec/runner/formatter/progress_bar_formatter.rb)7
-rw-r--r--vendor/gems/rspec/lib/spec/runner/formatter/snippet_extractor.rb (renamed from spec/lib/spec/runner/formatter/snippet_extractor.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/runner/formatter/specdoc_formatter.rb39
-rw-r--r--vendor/gems/rspec/lib/spec/runner/formatter/story/html_formatter.rb128
-rw-r--r--vendor/gems/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb131
-rw-r--r--vendor/gems/rspec/lib/spec/runner/formatter/text_mate_formatter.rb16
-rw-r--r--vendor/gems/rspec/lib/spec/runner/heckle_runner.rb (renamed from spec/lib/spec/runner/heckle_runner.rb)18
-rw-r--r--vendor/gems/rspec/lib/spec/runner/heckle_runner_unsupported.rb (renamed from spec/lib/spec/runner/heckle_runner_unsupported.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/runner/option_parser.rb201
-rw-r--r--vendor/gems/rspec/lib/spec/runner/options.rb286
-rw-r--r--vendor/gems/rspec/lib/spec/runner/reporter.rb143
-rw-r--r--vendor/gems/rspec/lib/spec/runner/spec_parser.rb71
-rw-r--r--vendor/gems/rspec/lib/spec/story.rb10
-rw-r--r--vendor/gems/rspec/lib/spec/story/extensions.rb3
-rw-r--r--vendor/gems/rspec/lib/spec/story/extensions/main.rb86
-rw-r--r--vendor/gems/rspec/lib/spec/story/extensions/regexp.rb9
-rw-r--r--vendor/gems/rspec/lib/spec/story/extensions/string.rb9
-rw-r--r--vendor/gems/rspec/lib/spec/story/given_scenario.rb14
-rw-r--r--vendor/gems/rspec/lib/spec/story/runner.rb56
-rw-r--r--vendor/gems/rspec/lib/spec/story/runner/plain_text_story_runner.rb48
-rw-r--r--vendor/gems/rspec/lib/spec/story/runner/scenario_collector.rb18
-rw-r--r--vendor/gems/rspec/lib/spec/story/runner/scenario_runner.rb46
-rw-r--r--vendor/gems/rspec/lib/spec/story/runner/story_mediator.rb123
-rw-r--r--vendor/gems/rspec/lib/spec/story/runner/story_parser.rb227
-rw-r--r--vendor/gems/rspec/lib/spec/story/runner/story_runner.rb68
-rw-r--r--vendor/gems/rspec/lib/spec/story/scenario.rb14
-rw-r--r--vendor/gems/rspec/lib/spec/story/step.rb58
-rw-r--r--vendor/gems/rspec/lib/spec/story/step_group.rb89
-rw-r--r--vendor/gems/rspec/lib/spec/story/step_mother.rb37
-rw-r--r--vendor/gems/rspec/lib/spec/story/story.rb42
-rw-r--r--vendor/gems/rspec/lib/spec/story/world.rb125
-rw-r--r--vendor/gems/rspec/lib/spec/translator.rb (renamed from spec/lib/spec/translator.rb)0
-rw-r--r--vendor/gems/rspec/lib/spec/version.rb (renamed from spec/lib/spec/version.rb)45
-rw-r--r--vendor/gems/rspec/plugins/mock_frameworks/flexmock.rb (renamed from spec/plugins/mock_frameworks/flexmock.rb)0
-rw-r--r--vendor/gems/rspec/plugins/mock_frameworks/mocha.rb (renamed from spec/plugins/mock_frameworks/mocha.rb)0
-rw-r--r--vendor/gems/rspec/plugins/mock_frameworks/rr.rb (renamed from spec/plugins/mock_frameworks/rr.rb)0
-rw-r--r--vendor/gems/rspec/plugins/mock_frameworks/rspec.rb (renamed from spec/plugins/mock_frameworks/rspec.rb)2
-rw-r--r--vendor/gems/rspec/pre_commit/lib/pre_commit.rb4
-rw-r--r--vendor/gems/rspec/pre_commit/lib/pre_commit/core.rb50
-rw-r--r--vendor/gems/rspec/pre_commit/lib/pre_commit/pre_commit.rb54
-rw-r--r--vendor/gems/rspec/pre_commit/lib/pre_commit/rspec.rb111
-rw-r--r--vendor/gems/rspec/pre_commit/lib/pre_commit/rspec_on_rails.rb313
-rw-r--r--vendor/gems/rspec/pre_commit/spec/pre_commit/pre_commit_spec.rb15
-rw-r--r--vendor/gems/rspec/pre_commit/spec/pre_commit/rspec_on_rails_spec.rb36
-rw-r--r--vendor/gems/rspec/pre_commit/spec/spec_helper.rb3
-rw-r--r--vendor/gems/rspec/pre_commit/spec/spec_suite.rb11
-rw-r--r--vendor/gems/rspec/rake_tasks/examples.rake7
-rw-r--r--vendor/gems/rspec/rake_tasks/examples_with_rcov.rake9
-rw-r--r--vendor/gems/rspec/rake_tasks/failing_examples_with_html.rake9
-rw-r--r--vendor/gems/rspec/rake_tasks/verify_rcov.rake7
-rw-r--r--vendor/gems/rspec/spec/README.jruby15
-rw-r--r--vendor/gems/rspec/spec/autotest/discover_spec.rb19
-rw-r--r--vendor/gems/rspec/spec/autotest/rspec_spec.rb195
-rw-r--r--vendor/gems/rspec/spec/autotest_helper.rb6
-rw-r--r--vendor/gems/rspec/spec/autotest_matchers.rb47
-rw-r--r--vendor/gems/rspec/spec/rspec_suite.rb7
-rw-r--r--vendor/gems/rspec/spec/ruby_forker.rb13
-rw-r--r--vendor/gems/rspec/spec/spec.opts6
-rwxr-xr-xvendor/gems/rspec/spec/spec/example/configuration_spec.rb282
-rw-r--r--vendor/gems/rspec/spec/spec/example/example_group_class_definition_spec.rb48
-rw-r--r--vendor/gems/rspec/spec/spec/example/example_group_factory_spec.rb129
-rw-r--r--vendor/gems/rspec/spec/spec/example/example_group_methods_spec.rb489
-rw-r--r--vendor/gems/rspec/spec/spec/example/example_group_spec.rb711
-rw-r--r--vendor/gems/rspec/spec/spec/example/example_matcher_spec.rb96
-rw-r--r--vendor/gems/rspec/spec/spec/example/example_methods_spec.rb104
-rw-r--r--vendor/gems/rspec/spec/spec/example/example_runner_spec.rb194
-rw-r--r--vendor/gems/rspec/spec/spec/example/example_spec.rb53
-rw-r--r--vendor/gems/rspec/spec/spec/example/nested_example_group_spec.rb59
-rw-r--r--vendor/gems/rspec/spec/spec/example/pending_module_spec.rb31
-rwxr-xr-xvendor/gems/rspec/spec/spec/example/predicate_matcher_spec.rb21
-rw-r--r--vendor/gems/rspec/spec/spec/example/shared_example_group_spec.rb265
-rw-r--r--vendor/gems/rspec/spec/spec/example/subclassing_example_group_spec.rb25
-rw-r--r--vendor/gems/rspec/spec/spec/expectations/differs/default_spec.rb109
-rw-r--r--vendor/gems/rspec/spec/spec/expectations/extensions/object_spec.rb107
-rw-r--r--vendor/gems/rspec/spec/spec/expectations/fail_with_spec.rb71
-rw-r--r--vendor/gems/rspec/spec/spec/extensions/main_spec.rb76
-rw-r--r--vendor/gems/rspec/spec/spec/interop/test/unit/resources/spec_that_fails.rb10
-rw-r--r--vendor/gems/rspec/spec/spec/interop/test/unit/resources/spec_that_passes.rb10
-rw-r--r--vendor/gems/rspec/spec/spec/interop/test/unit/resources/spec_with_errors.rb10
-rw-r--r--vendor/gems/rspec/spec/spec/interop/test/unit/resources/test_case_that_fails.rb10
-rw-r--r--vendor/gems/rspec/spec/spec/interop/test/unit/resources/test_case_that_passes.rb10
-rw-r--r--vendor/gems/rspec/spec/spec/interop/test/unit/resources/test_case_with_errors.rb10
-rw-r--r--vendor/gems/rspec/spec/spec/interop/test/unit/resources/testsuite_adapter_spec_with_test_unit.rb38
-rw-r--r--vendor/gems/rspec/spec/spec/interop/test/unit/spec_spec.rb45
-rw-r--r--vendor/gems/rspec/spec/spec/interop/test/unit/test_unit_spec_helper.rb14
-rw-r--r--vendor/gems/rspec/spec/spec/interop/test/unit/testcase_spec.rb45
-rw-r--r--vendor/gems/rspec/spec/spec/interop/test/unit/testsuite_adapter_spec.rb9
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/be_close_spec.rb39
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/be_spec.rb224
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/change_spec.rb319
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/description_generation_spec.rb153
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/eql_spec.rb28
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/equal_spec.rb28
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/exist_spec.rb57
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/handler_spec.rb129
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/has_spec.rb37
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/have_spec.rb291
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/include_spec.rb45
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/match_spec.rb37
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/matcher_methods_spec.rb78
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/mock_constraint_matchers_spec.rb24
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/operator_matcher_spec.rb158
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/raise_error_spec.rb191
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/respond_to_spec.rb54
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/satisfy_spec.rb36
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/simple_matcher_spec.rb31
-rw-r--r--vendor/gems/rspec/spec/spec/matchers/throw_symbol_spec.rb54
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/any_number_of_times_spec.rb29
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/argument_expectation_spec.rb23
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/at_least_spec.rb97
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/at_most_spec.rb93
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/bug_report_10260_spec.rb8
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/bug_report_10263.rb24
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/bug_report_11545_spec.rb31
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/bug_report_15719_spec.rb30
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/bug_report_7611_spec.rb19
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/bug_report_7805_spec.rb22
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/bug_report_8165_spec.rb31
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/bug_report_8302_spec.rb26
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/failing_mock_argument_constraints_spec.rb115
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/mock_ordering_spec.rb84
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/mock_space_spec.rb54
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/mock_spec.rb475
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/multiple_return_value_spec.rb113
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/null_object_mock_spec.rb40
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/once_counts_spec.rb53
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/options_hash_spec.rb45
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/partial_mock_spec.rb106
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb66
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/passing_mock_argument_constraints_spec.rb154
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/precise_counts_spec.rb52
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/record_messages_spec.rb26
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/stub_spec.rb181
-rw-r--r--vendor/gems/rspec/spec/spec/mocks/twice_counts_spec.rb67
-rw-r--r--vendor/gems/rspec/spec/spec/package/bin_spec_spec.rb14
-rw-r--r--vendor/gems/rspec/spec/spec/runner/class_and_argument_parser_spec.rb23
-rw-r--r--vendor/gems/rspec/spec/spec/runner/command_line_spec.rb147
-rw-r--r--vendor/gems/rspec/spec/spec/runner/drb_command_line_spec.rb92
-rw-r--r--vendor/gems/rspec/spec/spec/runner/empty_file.txt0
-rw-r--r--vendor/gems/rspec/spec/spec/runner/examples.txt2
-rw-r--r--vendor/gems/rspec/spec/spec/runner/execution_context_spec.rb31
-rw-r--r--vendor/gems/rspec/spec/spec/runner/failed.txt3
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb44
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/failing_examples_formatter_spec.rb33
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.4.html365
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html387
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.5.html371
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.6-jruby.html381
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.6.html365
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/html_formatter_spec.rb66
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/profile_formatter_spec.rb65
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/progress_bar_formatter_spec.rb127
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/snippet_extractor_spec.rb18
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb103
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/specdoc_formatter_spec.rb126
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/story/html_formatter_spec.rb61
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb335
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.4.html365
-rw-r--r--vendor/gems/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html365
-rw-r--r--vendor/gems/rspec/spec/spec/runner/heckle_runner_spec.rb78
-rw-r--r--vendor/gems/rspec/spec/spec/runner/heckler_spec.rb13
-rw-r--r--vendor/gems/rspec/spec/spec/runner/noisy_backtrace_tweaker_spec.rb45
-rw-r--r--vendor/gems/rspec/spec/spec/runner/option_parser_spec.rb378
-rw-r--r--vendor/gems/rspec/spec/spec/runner/options_spec.rb364
-rw-r--r--vendor/gems/rspec/spec/spec/runner/output_one_time_fixture.rb7
-rw-r--r--vendor/gems/rspec/spec/spec/runner/output_one_time_fixture_runner.rb8
-rw-r--r--vendor/gems/rspec/spec/spec/runner/output_one_time_spec.rb16
-rw-r--r--vendor/gems/rspec/spec/spec/runner/quiet_backtrace_tweaker_spec.rb56
-rw-r--r--vendor/gems/rspec/spec/spec/runner/reporter_spec.rb189
-rw-r--r--vendor/gems/rspec/spec/spec/runner/resources/a_bar.rb0
-rw-r--r--vendor/gems/rspec/spec/spec/runner/resources/a_foo.rb0
-rw-r--r--vendor/gems/rspec/spec/spec/runner/resources/a_spec.rb1
-rw-r--r--vendor/gems/rspec/spec/spec/runner/spec.opts2
-rw-r--r--vendor/gems/rspec/spec/spec/runner/spec_parser/spec_parser_fixture.rb70
-rw-r--r--vendor/gems/rspec/spec/spec/runner/spec_parser_spec.rb79
-rw-r--r--vendor/gems/rspec/spec/spec/runner/spec_spaced.opts2
-rw-r--r--vendor/gems/rspec/spec/spec/runner_spec.rb11
-rw-r--r--vendor/gems/rspec/spec/spec/spec_classes.rb133
-rw-r--r--vendor/gems/rspec/spec/spec/story/builders.rb46
-rw-r--r--vendor/gems/rspec/spec/spec/story/extensions/main_spec.rb161
-rw-r--r--vendor/gems/rspec/spec/spec/story/extensions_spec.rb14
-rw-r--r--vendor/gems/rspec/spec/spec/story/given_scenario_spec.rb27
-rw-r--r--vendor/gems/rspec/spec/spec/story/runner/plain_text_story_runner_spec.rb92
-rw-r--r--vendor/gems/rspec/spec/spec/story/runner/scenario_collector_spec.rb27
-rw-r--r--vendor/gems/rspec/spec/spec/story/runner/scenario_runner_spec.rb142
-rw-r--r--vendor/gems/rspec/spec/spec/story/runner/story_mediator_spec.rb133
-rw-r--r--vendor/gems/rspec/spec/spec/story/runner/story_parser_spec.rb384
-rw-r--r--vendor/gems/rspec/spec/spec/story/runner/story_runner_spec.rb256
-rw-r--r--vendor/gems/rspec/spec/spec/story/runner_spec.rb106
-rw-r--r--vendor/gems/rspec/spec/spec/story/scenario_spec.rb20
-rw-r--r--vendor/gems/rspec/spec/spec/story/step_group_spec.rb157
-rw-r--r--vendor/gems/rspec/spec/spec/story/step_mother_spec.rb72
-rw-r--r--vendor/gems/rspec/spec/spec/story/step_spec.rb200
-rw-r--r--vendor/gems/rspec/spec/spec/story/story_helper.rb2
-rw-r--r--vendor/gems/rspec/spec/spec/story/story_spec.rb86
-rw-r--r--vendor/gems/rspec/spec/spec/story/world_spec.rb423
-rw-r--r--vendor/gems/rspec/spec/spec/translator_spec.rb265
-rw-r--r--vendor/gems/rspec/spec/spec_helper.rb103
-rw-r--r--vendor/gems/rspec/stories/all.rb5
-rw-r--r--vendor/gems/rspec/stories/example_groups/autogenerated_docstrings45
-rw-r--r--vendor/gems/rspec/stories/example_groups/example_group_with_should_methods17
-rw-r--r--vendor/gems/rspec/stories/example_groups/nested_groups17
-rw-r--r--vendor/gems/rspec/stories/example_groups/output25
-rw-r--r--vendor/gems/rspec/stories/example_groups/stories.rb7
-rw-r--r--vendor/gems/rspec/stories/helper.rb6
-rw-r--r--vendor/gems/rspec/stories/interop/examples_and_tests_together30
-rw-r--r--vendor/gems/rspec/stories/interop/stories.rb7
-rw-r--r--vendor/gems/rspec/stories/interop/test_case_with_should_methods17
-rw-r--r--vendor/gems/rspec/stories/pending_stories/README3
-rw-r--r--vendor/gems/rspec/stories/resources/helpers/cmdline.rb9
-rw-r--r--vendor/gems/rspec/stories/resources/helpers/story_helper.rb16
-rw-r--r--vendor/gems/rspec/stories/resources/matchers/smart_match.rb37
-rw-r--r--vendor/gems/rspec/stories/resources/spec/example_group_with_should_methods.rb12
-rw-r--r--vendor/gems/rspec/stories/resources/spec/simple_spec.rb8
-rw-r--r--vendor/gems/rspec/stories/resources/steps/running_rspec.rb50
-rw-r--r--vendor/gems/rspec/stories/resources/stories/failing_story.rb15
-rw-r--r--vendor/gems/rspec/stories/resources/test/spec_and_test_together.rb57
-rw-r--r--vendor/gems/rspec/stories/resources/test/test_case_with_should_methods.rb30
934 files changed, 41151 insertions, 10782 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 0908aeaa5..2bd81df45 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,199 @@
+ Pass source to pkg_add via the PKG_PATH environment variable if
+ it ends in a '/' indicating it is a directory. Allows pkg_add
+ to resolve dependancies, and make it possible to specify packages
+ without version numbers.
+
+ Fixing #571 -- provider suitability is now checked at resource
+ evaluation time, rather than resource instantiation time. This
+ means that you don't catch your "errors" as early, but it also
+ means you should be able to realistically configure a whole host
+ in one run.
+
+ Moved the configuration of the Node cache to the puppetmasterd
+ executable, since it otherwise causes caches to be used in all
+ cases, which we don't want (e.g., bin/puppet was using them).
+
+ Ported #198 man page creation functionality to 0.24.x branch and
+ added man pages and man page creation logic to install.rb. The
+ man pages are stored in man/man8 and will install to config::CONFIG
+ mandir/man8.
+
+ Fixing #1138 -- the yamldir is automatically created by the
+ server now that it's in the :puppetmasterd section rather than
+ a separate :yaml section.
+
+ Disabling http keep-alive as a means of preventing #1010.
+ There is now a constant in Puppet::Network::HttpPool that will
+ disable or enable this feature, but note that we determined
+ that it can cause corruption, especially in file serving (but
+ it's client-side corruption).
+
+ Applying patch by Ryan McBride to fix OpenBSD package
+ matching. The actual problem was caused by the fix to #1001.
+
+ Found all instances of methods where split() is used without
+ any local variables and added a local variable -- see
+ http://snurl.com/21zf8. My own testing showed that this
+ caused memory growth to level off at a reasonable level.
+ Note that the link above says the problem is only with class
+ methods, but my own testing showed that it's any method that
+ meets these criteria. This is not a functional change, but
+ should hopefully be the last nail in the coffin of #1131.
+
+ Found an array that leaked pretty quickly between reparsing
+ files, thanks to work by Adam Jacob and Arjuna Christenson
+ (the finding, not the leak). I'm going to act like this
+ fixes #1131, at least for now, but I doubt it does,
+ since that shows general memory growth over time, whereas
+ the leak here should go away as soon as files are reparsed
+ (because the parser is holding the reference to the leaking
+ array).
+
+ Fixed #1147: Cached nodes are correctly considered out of
+ date if the node facts have been updated (thus causing
+ node facts to again be available in manifests, for those
+ cases where they were not).
+
+ Fixed #1137: The certificate name is correctly being added
+ to the facts hash.
+
+ Fixed #1136: Verbose and Debug no longer clobber each other.
+
+ Hopefully *finally* fixed the "already being managed" problem
+ (#1036). The problem only cropped up if there was a failure
+ when trying to manage the system -- this would cause the
+ setting-based resources not to get cleaned up.
+
+0.24.3
+ Modified the ldap node terminus to also use the facts version
+ as the version for a node, which should similarly encourage the
+ use of the yaml cache. (Related to #1130)
+
+ Caching node information in yaml (I figured caching in memory will
+ cause ever-larger memory growth), and changing the external node
+ terminus to use the version of the facts as their version. This
+ will usually result in the cached node information being used,
+ instead of always hitting the external node app during file
+ serving. Note that if the facts aren't changed by the client,
+ then this will result in the cached node being used, but at this
+ point, the client always updates its facts. (#1130)
+
+ Fixing #1132 -- host names can now have dashes anywhere.
+ (Patch by freiheit.)
+
+ Fixing #1118 -- downloading plugins and facts now ignores noop.
+ Note that this changes the behaviour a bit -- the resource's
+ noop setting always beats the global setting (previously,
+ whichever was true would win).
+
+ The change in checksums from 'timestamp' to 'mtime' no longer
+ result in updates on every run (#1116).
+
+ Aliases again work in relationships (#1094).
+
+ The CA serial file will no longer ever be owned by
+ root (#1041).
+
+ Fixing the rest of #1113: External node commands can specify
+ an environment and Puppet will now use it.
+
+ Partially fixing #1113: LDAP nodes now support environments,
+ and the schema has been updated accordingly.
+
+ Always duplicating resource defaults in the parser, so that
+ stacked metaparameter values do not result in all resources
+ that receive a given default also getting those stacked
+ values.
+
+0.24.2
+ Fixing #1062 by moving the yamldir setting to its own yaml
+ section. This should keep the yamldir from being created
+ on clients.
+
+ Fixed #1047 -- Puppet's parser no longer changes the order
+ in which statements are evaluated, which means that case
+ statements can now set variables that are used by other
+ variables.
+
+ Fixed #1063 -- the master correctly logs syntax errors when
+ reparsing during a single run.
+
+ Removed the loglevels from the valid values for `logoutput`
+ in the Exec resource type -- the log levels are specified
+ using the `loglevel` parameter, not `logoutput`. This never
+ worked, or at least hasn`t for ages, and now the docs are
+ just correct.
+
+ Somewhat refactored fileserving so that it no longer caches
+ any objects, nor does it use Puppet's RAL resources. In the
+ process, I fixed #894 (you can now copy links) and refactored
+ other classes as necessary. Mostly it was fixing tests.
+
+ Hopefully partially fixed #1010 -- clients should now fail
+ to install files whose checksums do not match the checksum
+ from the server.
+
+ Fixed #1018 -- resources now have their namevars added as
+ aliases in the resource catalog, just like they were added
+ in the resource classes.
+
+ Fixed #1037 -- remote unreadable files no longer have the
+ permission denied exceptions caught, thus forbidding them
+ from being replaced with 'nil'.
+
+ The environment is now available as a variable in the manifests.
+
+ Fixed #1043 -- autoloading now searches the plugins directory
+ in each module, in addition to the lib directory. The 'lib'
+ directory is also deprecated, but supported for now to give
+ people a chance to convert.
+
+ Fixed #1003 -- Applying DavidS's patch to fix searching for
+ tags in sql.
+
+ Fixed #992 -- Puppet is now compatible with gems 1.0.1.
+
+ Fixed #968 again, this time with tests -- parseonly works,
+ including not compiling the configurations, and also storeconfigs
+ is no longer required during parse-testing.
+
+ Fixed #1021 -- the problem was that my method of determining
+ the in-degree sometimes resulted in a lower number than the
+ number of in-edges.
+
+ Fixed #997 -- virtual defined types are no longer evaluated.
+ NOTE: This introduces a behaviour change, in that you previously
+ could realize a resource within a virtual defined resource, and now
+ you must realize the entire defined resource, rather than just
+ the contained resource.
+
+ Fixed #1030 - class and definition evaluation has been significantly
+ refactored, fixing this problem and making the whole interplay
+ between the classes, definitions, and nodes, and the Compile class much
+ cleaner.
+
+ Exec resources must now have unique names, although the commands can still
+ be duplicated. This is easily accomplished by just specifying a unique
+ name with whatever (unique or otherwise) command you need.
+
+ Fixed #989 -- missing CRL files are correctly ignored, and the
+ value should be set to 'false' to explicitly not look for these
+ files.
+
+ Fixed #1017 -- environment-specific modulepath is no longer ignored.
+
+ Fixing #794 -- consolidating the gentoo configuration files.
+
+ Fixing #976 -- both the full name of qualified classes and
+ the class parts are now added as tags. I've also
+ created a Tagging module that we should push throughout
+ the rest of the system that uses tags.
+
+ Fixing #995 -- puppetd no longer dies at startup if the server
+ is not running.
+
+ Fixing #977 -- the rundir is again set to 1777.
+
Fixed #971 -- classes can once again be included multiple
times.
diff --git a/Rakefile b/Rakefile
index d5b65e49a..1a3faad09 100644
--- a/Rakefile
+++ b/Rakefile
@@ -27,7 +27,8 @@ project = Rake::RedLabProject.new("puppet") do |p|
'bin/**/*',
'ext/**/*',
'examples/**/*',
- 'conf/**/*'
+ 'conf/**/*',
+ 'man/**/*'
]
p.filelist.exclude("bin/pi")
@@ -83,10 +84,6 @@ rule(/_is_runnable$/) do |t|
end
end
-file "debian" => :bzr_is_runnable do
- system("bzr get http://www.hezmatt.org/~mpalmer/bzr/puppet.debian.svn debian") || exit(1)
-end
-
task :check_build_deps => 'dpkg-checkbuilddeps_is_runnable' do
system("dpkg-checkbuilddeps") || exit(1)
end
@@ -138,3 +135,11 @@ task :dailyclean do
File.unlink(file)
end
end
+
+task :tracdocs do
+ require 'puppet'
+ require 'puppet/util/reference'
+ Puppet::Util::Reference.references.each do |ref|
+ sh "puppetdoc -m trac -r #{ref.to_s}"
+ end
+end
diff --git a/spec/lib/autotest/discover.rb b/autotest/discover.rb
index 0ac563724..0ac563724 100644
--- a/spec/lib/autotest/discover.rb
+++ b/autotest/discover.rb
diff --git a/autotest/puppet_rspec.rb b/autotest/puppet_rspec.rb
new file mode 100644
index 000000000..5ff794e9d
--- /dev/null
+++ b/autotest/puppet_rspec.rb
@@ -0,0 +1,60 @@
+require 'autotest'
+require 'autotest/rspec'
+
+Autotest.add_hook :initialize do |at|
+ at.clear_mappings
+
+ # the libraries under lib/puppet
+ at.add_mapping(%r%^lib/puppet/(.*)\.rb$%) { |filename, m|
+ at.files_matching %r!spec/(unit|integration)/#{m[1]}.rb!
+ }
+
+ # the actual spec files themselves
+ at.add_mapping(%r%^spec/(unit|integration)/.*\.rb$%) { |filename, _|
+ filename
+ }
+
+ # force a complete re-run for all of these:
+
+ # main puppet lib
+ at.add_mapping(%r!^lib/puppet\.rb$!) { |filename, _|
+ at.files_matching %r!spec/(unit|integration)/.*\.rb!
+ }
+
+ # the spec_helper
+ at.add_mapping(%r!^spec/spec_helper\.rb$!) { |filename, _|
+ at.files_matching %r!spec/(unit|integration)/.*\.rb!
+ }
+
+ # the puppet test libraries
+ at.add_mapping(%r!^test/lib/puppettest/.*!) { |filename, _|
+ at.files_matching %r!spec/(unit|integration)/.*\.rb!
+ }
+
+ # the puppet spec libraries
+ at.add_mapping(%r!^spec/lib/spec.*!) { |filename, _|
+ at.files_matching %r!spec/(unit|integration)/.*\.rb!
+ }
+
+ # the monkey patches for rspec
+ at.add_mapping(%r!^spec/lib/monkey_patches/.*!) { |filename, _|
+ at.files_matching %r!spec/(unit|integration)/.*\.rb!
+ }
+end
+
+class Autotest::PuppetRspec < Autotest::Rspec
+ # Autotest will look for spec commands in the following
+ # locations, in this order:
+ #
+ # * bin/spec
+ # * default spec bin/loader installed in Rubygems
+ # * our local vendor/gems/rspec/bin/spec
+ def spec_commands
+ [
+ File.join('vendor', 'gems', 'rspec', 'bin', 'spec') ,
+ File.join('bin', 'spec'),
+ File.join(Config::CONFIG['bindir'], 'spec')
+ ]
+ end
+
+end
diff --git a/autotest/rspec.rb b/autotest/rspec.rb
new file mode 100644
index 000000000..ebafbfe91
--- /dev/null
+++ b/autotest/rspec.rb
@@ -0,0 +1,74 @@
+require 'autotest'
+
+Autotest.add_hook :initialize do |at|
+ at.clear_mappings
+ # watch out: Ruby bug (1.8.6):
+ # %r(/) != /\//
+ at.add_mapping(%r%^spec/.*\.rb$%) { |filename, _|
+ filename
+ }
+ at.add_mapping(%r%^lib/(.*)\.rb$%) { |_, m|
+ ["spec/#{m[1]}_spec.rb"]
+ }
+ at.add_mapping(%r%^spec/(spec_helper|shared/.*)\.rb$%) {
+ at.files_matching %r{^spec/.*_spec\.rb$}
+ }
+end
+
+class RspecCommandError < StandardError; end
+
+class Autotest::Rspec < Autotest
+
+ def initialize
+ super
+
+ self.failed_results_re = /^\d+\)\n(?:\e\[\d*m)?(?:.*?Error in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n(.*?)\n\n/m
+ self.completed_re = /\Z/ # FIX: some sort of summary line at the end?
+ end
+
+ def consolidate_failures(failed)
+ filters = Hash.new { |h,k| h[k] = [] }
+ failed.each do |spec, failed_trace|
+ if f = test_files_for(failed).find { |f| failed_trace =~ Regexp.new(f) } then
+ filters[f] << spec
+ break
+ end
+ end
+ return filters
+ end
+
+ def make_test_cmd(files_to_test)
+ return "#{ruby} -S #{spec_command} #{add_options_if_present} #{files_to_test.keys.flatten.join(' ')}"
+ end
+
+ def add_options_if_present
+ File.exist?("spec/spec.opts") ? "-O spec/spec.opts " : ""
+ end
+
+ # Finds the proper spec command to use. Precendence is set in the
+ # lazily-evaluated method spec_commands. Alias + Override that in
+ # ~/.autotest to provide a different spec command then the default
+ # paths provided.
+ def spec_command(separator=File::ALT_SEPARATOR)
+ unless defined? @spec_command then
+ @spec_command = spec_commands.find { |cmd| File.exists? cmd }
+
+ raise RspecCommandError, "No spec command could be found!" unless @spec_command
+
+ @spec_command.gsub! File::SEPARATOR, separator if separator
+ end
+ @spec_command
+ end
+
+ # Autotest will look for spec commands in the following
+ # locations, in this order:
+ #
+ # * bin/spec
+ # * default spec bin/loader installed in Rubygems
+ def spec_commands
+ [
+ File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'spec')),
+ File.join(Config::CONFIG['bindir'], 'spec')
+ ]
+ end
+end
diff --git a/bin/puppet b/bin/puppet
index f5d230a7a..9e1102a3d 100755
--- a/bin/puppet
+++ b/bin/puppet
@@ -136,6 +136,14 @@ end
Puppet.parse_config
+# Now parse the config
+if Puppet[:config] and File.exists? Puppet[:config]
+ Puppet.settings.parse(Puppet[:config])
+end
+
+Puppet.genconfig
+Puppet.genmanifest
+
# If noop is set, then also enable diffs
if Puppet[:noop]
Puppet[:show_diff] = true
@@ -156,14 +164,6 @@ elsif options[:verbose]
Puppet::Util::Log.level = :info
end
-# Now parse the config
-if Puppet[:config] and File.exists? Puppet[:config]
- Puppet.settings.parse(Puppet[:config])
-end
-
-Puppet.genconfig
-Puppet.genmanifest
-
# Set our code or file to use.
if options[:code] or ARGV.length == 0
Puppet[:code] = options[:code] || STDIN.read
@@ -171,6 +171,16 @@ else
Puppet[:manifest] = ARGV.shift
end
+if Puppet[:parseonly]
+ begin
+ Puppet::Parser::Interpreter.new.parser(Puppet[:environment])
+ rescue => detail
+ Puppet.err detail
+ exit 1
+ end
+ exit 0
+end
+
# Collect our facts.
facts = Puppet::Node::Facts.find("me")
facts.name = facts.values["hostname"]
@@ -198,8 +208,6 @@ begin
# Compile our catalog
catalog = Puppet::Node::Catalog.find(node)
- exit(0) if Puppet[:parseonly]
-
# Translate it to a RAL catalog
catalog = catalog.to_ral
diff --git a/bin/puppetd b/bin/puppetd
index 297d4876d..f652e6b08 100755
--- a/bin/puppetd
+++ b/bin/puppetd
@@ -188,6 +188,8 @@ args = {}
options = {
:waitforcert => 120, # Default to checking for certs every 5 minutes
:onetime => false,
+ :verbose => false,
+ :debug => false,
:centrallogs => false,
:setdest => false,
:enable => false,
@@ -228,11 +230,9 @@ begin
puts "%s" % Puppet.version
exit
when "--verbose"
- Puppet::Util::Log.level = :info
- Puppet::Util::Log.newdestination(:console)
+ options[:verbose] = true
when "--debug"
- Puppet::Util::Log.level = :debug
- Puppet::Util::Log.newdestination(:console)
+ options[:debug] = true
when "--fqdn"
options[:fqdn] = arg
when "--no-client"
@@ -247,6 +247,9 @@ begin
Puppet::Util::Log.newdestination(arg)
options[:setdest] = true
rescue => detail
+ if Puppet[:debug]
+ puts detail.backtrace
+ end
$stderr.puts detail.to_s
end
when "--waitforcert"
@@ -272,12 +275,23 @@ if options[:test]
Puppet.settings.handlearg("--no-splay")
Puppet.settings.handlearg("--show_diff")
Puppet.settings.handlearg("--no-daemonize")
+ options[:verbose] = true
options[:onetime] = true
options[:waitforcert] = 0
- unless Puppet::Util::Log.level == :debug
+end
+
+# Handle the logging settings.
+if options[:debug] or options[:verbose]
+ Puppet::Util::Log.newdestination(:console)
+ if options[:debug]
+ Puppet::Util::Log.level = :debug
+ else
Puppet::Util::Log.level = :info
end
- Puppet::Util::Log.newdestination(:console)
+end
+
+unless options[:setdest]
+ Puppet::Util::Log.newdestination(:syslog)
end
Puppet.genconfig
@@ -288,10 +302,6 @@ if Puppet[:noop]
Puppet[:show_diff] = true
end
-unless options[:setdest]
- Puppet::Util::Log.newdestination(:syslog)
-end
-
args[:Server] = Puppet[:server]
if options[:fqdn]
args[:FQDN] = options[:fqdn]
@@ -374,7 +384,7 @@ if Puppet[:listen] and ! options[:onetime]
# to clients. In the meantime, we just disable CRL checking if
# the CRL file doesn't exist
unless File::exist?(Puppet[:cacrl])
- Puppet[:cacrl] = 'none'
+ Puppet[:cacrl] = 'false'
end
handlers = nil
diff --git a/bin/puppetdoc b/bin/puppetdoc
index be86cc618..82e4c076b 100755
--- a/bin/puppetdoc
+++ b/bin/puppetdoc
@@ -128,11 +128,19 @@ else
else
with_contents = true
end
+ exit_code = 0
options[:references].sort { |a,b| a.to_s <=> b.to_s }.each do |name|
- section = Puppet::Util::Reference.reference(name)
-
- # Add the per-section text, but with no ToC
- text += section.send(options[:format], with_contents)
+ raise "Could not find reference %s" % name unless section = Puppet::Util::Reference.reference(name)
+
+ begin
+ # Add the per-section text, but with no ToC
+ text += section.send(options[:format], with_contents)
+ rescue => detail
+ puts detail.backtrace
+ $stderr.puts "Could not generate reference %s: %s" % [name, detail]
+ exit_code = 1
+ next
+ end
end
unless with_contents # We've only got one reference
@@ -147,6 +155,8 @@ else
else
puts text
end
+
+ exit exit_code
end
diff --git a/bin/puppetmasterd b/bin/puppetmasterd
index bae11c831..b4733e604 100755
--- a/bin/puppetmasterd
+++ b/bin/puppetmasterd
@@ -81,13 +81,13 @@ end
require 'getoptlong'
require 'puppet'
+require 'puppet/network/handler'
require 'puppet/sslcertificates'
options = [
[ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
[ "--help", "-h", GetoptLong::NO_ARGUMENT ],
[ "--logdest", "-l", GetoptLong::REQUIRED_ARGUMENT ],
- [ "--noca", GetoptLong::NO_ARGUMENT ],
[ "--nobucket", GetoptLong::NO_ARGUMENT ],
[ "--noreports", GetoptLong::NO_ARGUMENT ],
[ "--nonodes", GetoptLong::NO_ARGUMENT ],
@@ -188,6 +188,9 @@ Puppet.genmanifest
# A temporary solution, to at least make the master work for now.
Puppet::Node::Facts.terminus_class = :yaml
+# Cache our nodes in yaml. Currently not configurable.
+Puppet::Node.cache_class = :yaml
+
require 'etc'
handlers = {
diff --git a/bin/puppetrun b/bin/puppetrun
index cc78f81a8..d0823b9c5 100755
--- a/bin/puppetrun
+++ b/bin/puppetrun
@@ -40,7 +40,7 @@
# you want any Puppet daemon to allow -- it is currently global to all Puppet
# daemons.
#
-# An example file looks like this:
+# An example file looks like this::
#
# [fileserver]
# allow *.madstop.com
@@ -274,14 +274,9 @@ else
end
# Now parse the config
-config = File.join(Puppet[:confdir], "puppetmasterd.conf")
-Puppet.parse_config(config)
+Puppet.parse_config
-if File.exists? config
- Puppet.settings.parse(config)
-end
-
-if Puppet[:ldapnodes]
+if Puppet[:node_terminus] = "ldap"
if options[:all]
hosts = ldapnodes(:all, options[:fqdn])
puts "all: %s" % hosts.join(", ")
diff --git a/bin/ralsh b/bin/ralsh
index e43177d35..fdf64916f 100755
--- a/bin/ralsh
+++ b/bin/ralsh
@@ -63,17 +63,18 @@
#
# = Example
#
-# $ ralsh user luke
-# user { 'luke':
-# home => '/home/luke',
-# uid => '100',
-# ensure => 'present',
-# comment => 'Luke Kanies,,,',
-# gid => '1000',
-# shell => '/bin/bash',
-# groups => ['sysadmin','audio','video','puppet']
-# }
-# $
+# This example uses ``ralsh`` to return Puppet configuration for the user ``luke``::
+#
+# $ ralsh user luke
+# user { 'luke':
+# home => '/home/luke',
+# uid => '100',
+# ensure => 'present',
+# comment => 'Luke Kanies,,,',
+# gid => '1000',
+# shell => '/bin/bash',
+# groups => ['sysadmin','audio','video','puppet']
+# }
#
# = Author
#
diff --git a/conf/freebsd/puppetd b/conf/freebsd/puppetd
index bf718a027..4a5ae59ca 100644
--- a/conf/freebsd/puppetd
+++ b/conf/freebsd/puppetd
@@ -18,7 +18,7 @@ pidfile="/var/run/$name.pid"
# read configuration and set defaults
load_rc_config "$name"
: ${puppetd_enable="NO"}
-: ${puppetd_config="/usr/local/etc/puppetd.conf"}
+: ${puppetd_config="/usr/local/etc/puppet.conf"}
: ${puppetd_flags=""}
command_args="--config $puppetd_config $puppetd_flags"
diff --git a/conf/freebsd/puppetmasterd b/conf/freebsd/puppetmasterd
index 6f217dc8c..d41e0031b 100644
--- a/conf/freebsd/puppetmasterd
+++ b/conf/freebsd/puppetmasterd
@@ -18,7 +18,7 @@ pidfile="/var/run/$name.pid"
# read configuration and set defaults
load_rc_config "$name"
: ${puppetmasterd_enable="NO"}
-: ${puppetmasterd_config="/usr/local/etc/puppetmasterd.conf"}
+: ${puppetmasterd_config="/usr/local/etc/puppet.conf"}
: ${puppetmasterd_flags=""}
command_args="--config $puppetmasterd_config $puppetmasterd_flags"
diff --git a/conf/gentoo/puppet/puppetca.conf b/conf/gentoo/puppet/puppet.conf
index 35f4abf1a..70dcb02da 100755..100644
--- a/conf/gentoo/puppet/puppetca.conf
+++ b/conf/gentoo/puppet/puppet.conf
@@ -1,4 +1,4 @@
-[puppet]
+[main]
# Where Puppet stores dynamic and growing data.
# The default value is '/var/puppet'.
vardir = /var/lib/puppet
diff --git a/conf/gentoo/puppet/puppetd.conf b/conf/gentoo/puppet/puppetd.conf
deleted file mode 100644
index 35f4abf1a..000000000
--- a/conf/gentoo/puppet/puppetd.conf
+++ /dev/null
@@ -1,29 +0,0 @@
-[puppet]
- # Where Puppet stores dynamic and growing data.
- # The default value is '/var/puppet'.
- vardir = /var/lib/puppet
-
- # The Puppet log directory.
- # The default value is '$vardir/log'.
- logdir = /var/log/puppet
-
- # Where Puppet PID files are kept.
- # The default value is '$vardir/run'.
- rundir = /var/run/puppet
-
- # Where SSL certificates are kept.
- # The default value is '$confdir/ssl'.
- ssldir = $vardir/ssl
-
-[puppetd]
- # The file in which puppetd stores a list of the classes
- # associated with the retrieved configuratiion. Can be loaded in
- # the separate ``puppet`` executable using the ``--loadclasses``
- # option.
- # The default value is '$confdir/classes.txt'.
- classfile = $vardir/classes.txt
-
- # Where puppetd caches the local configuration. An
- # extension indicating the cache format is added automatically.
- # The default value is '$confdir/localconfig'.
- localconfig = $vardir/localconfig
diff --git a/conf/gentoo/puppet/puppetmasterd.conf b/conf/gentoo/puppet/puppetmasterd.conf
deleted file mode 100755
index 35f4abf1a..000000000
--- a/conf/gentoo/puppet/puppetmasterd.conf
+++ /dev/null
@@ -1,29 +0,0 @@
-[puppet]
- # Where Puppet stores dynamic and growing data.
- # The default value is '/var/puppet'.
- vardir = /var/lib/puppet
-
- # The Puppet log directory.
- # The default value is '$vardir/log'.
- logdir = /var/log/puppet
-
- # Where Puppet PID files are kept.
- # The default value is '$vardir/run'.
- rundir = /var/run/puppet
-
- # Where SSL certificates are kept.
- # The default value is '$confdir/ssl'.
- ssldir = $vardir/ssl
-
-[puppetd]
- # The file in which puppetd stores a list of the classes
- # associated with the retrieved configuratiion. Can be loaded in
- # the separate ``puppet`` executable using the ``--loadclasses``
- # option.
- # The default value is '$confdir/classes.txt'.
- classfile = $vardir/classes.txt
-
- # Where puppetd caches the local configuration. An
- # extension indicating the cache format is added automatically.
- # The default value is '$confdir/localconfig'.
- localconfig = $vardir/localconfig
diff --git a/conf/namespaceauth.conf b/conf/namespaceauth.conf
new file mode 100644
index 000000000..837235769
--- /dev/null
+++ b/conf/namespaceauth.conf
@@ -0,0 +1,20 @@
+# This is an example namespaceauth.conf file,
+# which you'll need if you want to start a client
+# in --listen mode.
+[fileserver]
+ allow *.domain.com
+
+[puppetmaster]
+ allow *.domain.com
+
+[puppetrunner]
+ allow culain.domain.com
+
+[puppetbucket]
+ allow *.domain.com
+
+[puppetreports]
+ allow *.domain.com
+
+[resource]
+ allow server.domain.com
diff --git a/conf/redhat/puppet.spec b/conf/redhat/puppet.spec
index 9811e3492..65cb4939c 100644
--- a/conf/redhat/puppet.spec
+++ b/conf/redhat/puppet.spec
@@ -7,7 +7,7 @@
Summary: A network tool for managing many disparate systems
Name: puppet
-Version: 0.24.1
+Version: 0.24.4
Release: 1%{?dist}
License: GPLv2+
Group: System Environment/Base
diff --git a/conf/solaris/smf/puppetd.xml b/conf/solaris/smf/puppetd.xml
index e2a1d89e9..ad1b45231 100644
--- a/conf/solaris/smf/puppetd.xml
+++ b/conf/solaris/smf/puppetd.xml
@@ -18,7 +18,7 @@
grouping='require_all'
restart_on='none'
type='path'>
- <service_fmri value='file:///etc/puppet/puppetd.conf'/>
+ <service_fmri value='file:///etc/puppet/puppet.conf'/>
</dependency>
<dependency name='loopback'
diff --git a/conf/solaris/smf/puppetmasterd.xml b/conf/solaris/smf/puppetmasterd.xml
index e89e832fc..17c52916f 100644
--- a/conf/solaris/smf/puppetmasterd.xml
+++ b/conf/solaris/smf/puppetmasterd.xml
@@ -18,7 +18,7 @@
grouping='require_all'
restart_on='none'
type='path'>
- <service_fmri value='file:///etc/puppet/puppetmasterd.conf'/>
+ <service_fmri value='file:///etc/puppet/puppet.conf'/>
</dependency>
<dependency name='loopback'
diff --git a/conf/suse/puppet.spec b/conf/suse/puppet.spec
index 6d4e9f538..f1fa0ba2d 100644
--- a/conf/suse/puppet.spec
+++ b/conf/suse/puppet.spec
@@ -5,7 +5,7 @@
Summary: A network tool for managing many disparate systems
Name: puppet
-Version: 0.18.4
+Version: 0.24.1
Release: 3%{?dist}
License: GPL
Group: System Environment/Base
@@ -15,11 +15,11 @@ Source: http://reductivelabs.com/downloads/puppet/%{name}-%{version}.tgz
Patch0: puppet.suse.patch
Patch1: puppet.service.patch
-Requires: ruby >= 1.8.1
-Requires: facter >= 1.1.4
+Requires: ruby >= 1.8.6
+Requires: facter >= 1.3.7
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildArchitectures: noarch
-BuildRequires: ruby >= 1.8.1
+BuildRequires: ruby >= 1.8.6
%description
Puppet lets you centrally manage every important aspect of your system using a
@@ -67,9 +67,7 @@ find %{buildroot}%{ruby_sitelibdir} -type f -perm +ugo+x -print0 | xargs -0 -r %
%{__install} -Dp -m0644 %{confdir}/server.sysconfig %{buildroot}%{_sysconfdir}/sysconfig/puppetmaster
%{__install} -Dp -m0755 %{suseconfdir}/server.init %{buildroot}%{_initrddir}/puppetmaster
%{__install} -Dp -m0644 %{confdir}/fileserver.conf %{buildroot}%{_sysconfdir}/puppet/fileserver.conf
-%{__install} -Dp -m0644 %{confdir}/puppetd.conf %{buildroot}%{_sysconfdir}/puppet/puppetd.conf
-%{__ln_s} puppetd.conf %{buildroot}%{_sysconfdir}/puppet/puppetmasterd.conf
-%{__ln_s} puppetd.conf %{buildroot}%{_sysconfdir}/puppet/puppetca.conf
+%{__install} -Dp -m0644 %{confdir}/puppet.conf %{buildroot}%{_sysconfdir}/puppet/puppet.conf
%{__install} -Dp -m0644 %{confdir}/logrotate %{buildroot}%{_sysconfdir}/logrotate.d/puppet
%files
@@ -79,7 +77,7 @@ find %{buildroot}%{ruby_sitelibdir} -type f -perm +ugo+x -print0 | xargs -0 -r %
%{ruby_sitelibdir}/*
%{_initrddir}/puppet
%config(noreplace) %{_sysconfdir}/sysconfig/puppet
-%config(noreplace) %{_sysconfdir}/puppet/puppetd.conf
+%config(noreplace) %{_sysconfdir}/puppet/puppet.conf
%doc CHANGELOG COPYING LICENSE README TODO examples
%exclude %{_sbindir}/puppetdoc
%config(noreplace) %{_sysconfdir}/logrotate.d/puppet
@@ -131,6 +129,10 @@ fi
%{__rm} -rf %{buildroot}
%changelog
+* Sat Feb 16 2008 James Turnbull <james@lovedthanlost.net> - 0.24.1-1
+- Fixed puppet configuation file references to match single puppet.conf file
+- Update versions for 0.24.1 release
+
* Tue Aug 3 2006 Martin Vuk <martin.vuk@fri.uni-lj.si> - 0.18.4-3
- Replaced puppet-bin.patch with %build section from David's spec
diff --git a/debian/README.source b/debian/README.source
index 49b373b40..fd9155241 100644
--- a/debian/README.source
+++ b/debian/README.source
@@ -1,9 +1,2 @@
-The debian/ directory for this package is maintained in bzr. There are two
-primary branches, kept by each maintainer:
-
-http://www.hezmatt.org/~mpalmer/bzr/puppet.debian (mpalmer)
-http://repo.spacepants.org/puppet/puppet.debian (jaq)
-
-Typically all the changes will be in one (or both) of these branches. They
-merge from each other on a regular basis, and the canonical version for a
-release just depends on who actually made the upload.
+The debian directory is now maintained on Alioth in git.
+See http://pkg-puppet.alioth.debian.org/ for more information.
diff --git a/debian/changelog b/debian/changelog
index 1a33e55c3..69984d622 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,114 @@
+puppet (0.24.1-2) unstable; urgency=low
+
+ * Set rundir correctly (Closes: #460203, #459579)
+ * Apply patch for puppet#1003 to enable collection of tagged resources
+
+ -- Thom May <thom@debian.org> Wed, 16 Jan 2008 11:08:55 +0100
+
+puppet (0.24.1-1) unstable; urgency=low
+
+ * New upstream release (Closes: #445626)
+ * Set maintainer to pkg-puppet-devel
+
+ -- Thom May <thom@debian.org> Sun, 30 Dec 2007 19:13:47 +0100
+
+puppet (0.24.0-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Thom May <thom@debian.org> Wed, 19 Dec 2007 16:00:34 +0100
+
+puppet (0.23.2-15) unstable; urgency=low
+
+ * No change upload setting maintainer to me whilst waiting for an alioth
+ project.
+
+ -- Thom May <thom@debian.org> Thu, 29 Nov 2007 10:44:50 +0100
+
+puppet (0.23.2-14) unstable; urgency=low
+
+ * Orphaning.
+ * Create /var/lib/puppet in the puppet package. Closes: #452506.
+ * Start the puppet init script after puppetmaster, to silence whiny bug
+ reports. Closes: #452064.
+ * Add a reload command to the Puppet init script. Closes: #452060.
+
+ -- Matthew Palmer <mpalmer@debian.org> Thu, 29 Nov 2007 10:48:21 +1100
+
+puppet (0.23.2-13) unstable; urgency=low
+
+ * Drop quotes from an already-quoted value in a query. Closes: #448179.
+ * Remove excessive quoting from puppet/network/handler/master.rb.
+ Closes: #448221.
+ * Force removal of directories during pluginsync. Closes: #448180.
+
+ -- Matthew Palmer <mpalmer@debian.org> Tue, 30 Oct 2007 14:55:19 +1100
+
+puppet (0.23.2-12) unstable; urgency=low
+
+ * Create /var/run/puppet and set the perms in the various initscripts, as
+ well as hardcoding the rundir better in configuration.rb and removing
+ the explicit rundir setting from puppet.conf. Closes: #447314.
+ * Apply additional patch given (backwards) to fix export/collect on some
+ database backends. Closes: #445591 (again!)
+
+ -- Matthew Palmer <mpalmer@debian.org> Sat, 20 Oct 2007 11:28:50 +1000
+
+puppet (0.23.2-11) unstable; urgency=low
+
+ * Apply patch from puppet#786 to fix a problem with exported resources not
+ being properly detected as needing a rerun. Closes: #445591.
+ * Fix ignore handling for the plugins mount. Closes: #446390.
+
+ -- Matthew Palmer <mpalmer@debian.org> Mon, 15 Oct 2007 09:11:25 +1000
+
+puppet (0.23.2-10) unstable; urgency=low
+
+ * Recycle connections when we change (or get) certs.
+ * Catch and retry more transient errors in the XMLRPC wrapper.
+
+ -- Matthew Palmer <mpalmer@debian.org> Thu, 27 Sep 2007 15:06:11 +1000
+
+puppet (0.23.2-9) unstable; urgency=low
+
+ * Recycle the HTTP connection if we get an EPIPE during a request.
+ Closes: #444177. Thanks to Jos Backus for helping with testing.
+
+ -- Matthew Palmer <mpalmer@debian.org> Thu, 27 Sep 2007 09:55:34 +1000
+
+puppet (0.23.2-8) unstable; urgency=low
+
+ * Remove extraneous debugging output accidentally left behind in the last
+ release.
+ * Fix spelling mistakes in debian/control and debian/puppet.preinst.
+ Closes: #444158.
+
+ -- Matthew Palmer <mpalmer@debian.org> Thu, 27 Sep 2007 07:45:07 +1000
+
+puppet (0.23.2-7) unstable; urgency=low
+
+ * Ignore ENOENT errors in the module plugin syncing code, since they're
+ innocuous and expected.
+ * Allow facts that are downloaded through pluginsync to be used like any
+ other fact.
+ * Allow users to still have an old-style plugins mount if they want, by
+ specifying a path for the mount. Also track down a fault in old-style
+ fileserving which did strange slash-stripping. Closes: #443932.
+
+ -- Matthew Palmer <mpalmer@debian.org> Tue, 25 Sep 2007 16:41:32 +1000
+
+puppet (0.23.2-6) unstable; urgency=low
+
+ * Patch rails/param_name.rb to stop query failures, as per puppet#784.
+ * Actually honour namevar.
+ * Only set dbuser if explicitly asked for.
+ * Fix annoying database deletion error for ParamValue objects.
+ * Add an accessor for ca_file, since older openssl-ruby only had a writer.
+ * Fix the fileserver to honour ignore. Thanks to Nathan Ward for the
+ bug report on IRC.
+
+ -- Matthew Palmer <mpalmer@debian.org> Thu, 20 Sep 2007 16:10:41 +1000
+
puppet (0.23.2-5) unstable; urgency=low
* Add some NEWS for the ssldir transition. Should have done that earlier.
diff --git a/debian/control b/debian/control
index 879c9770c..8b0e92e7e 100644
--- a/debian/control
+++ b/debian/control
@@ -1,8 +1,8 @@
Source: puppet
Section: admin
Priority: optional
-Maintainer: Matthew Palmer <mpalmer@debian.org>
-Uploaders: Jamie Wilkinson <jaq@debian.org>, Matthew Palmer <mpalmer@debian.org>
+Maintainer: Puppet Package Maintainers <pkg-puppet-devel@lists.alioth.debian.org>
+Uploaders: Thom May <thom@debian.org>
Build-Depends-Indep: debhelper (>= 4.0.0), ruby (>= 1.8.1)
Standards-Version: 3.6.2
diff --git a/debian/puppet.conf b/debian/puppet.conf
index e17d039bb..c541c748a 100644
--- a/debian/puppet.conf
+++ b/debian/puppet.conf
@@ -2,6 +2,7 @@
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
+rundir=/var/run/puppet
[puppetmasterd]
templatedir=/var/lib/puppet/templates
diff --git a/debian/puppet.dirs b/debian/puppet.dirs
index 95ccc1e1b..9ce18f88e 100644
--- a/debian/puppet.dirs
+++ b/debian/puppet.dirs
@@ -3,4 +3,5 @@ usr/lib/ruby/1.8
var/log/puppet
etc/puppet/files
usr/share/vim/addons/ftdetect
-usr/share/vim/vim70/syntax
+usr/share/vim/vim71/syntax
+var/lib/puppet
diff --git a/debian/puppet.init b/debian/puppet.init
index da9f548cb..063f9273f 100644
--- a/debian/puppet.init
+++ b/debian/puppet.init
@@ -12,6 +12,10 @@ test -x $DAEMON || exit 0
. /lib/lsb/init-functions
+reload_puppet() {
+ start-stop-daemon --stop --quiet --signal HUP --pidfile /var/run/puppet/$NAME.pid
+}
+
start_puppet() {
start-stop-daemon --start --quiet --pidfile /var/run/puppet/$NAME.pid \
--startas $DAEMON -- $DAEMON_OPTS
@@ -39,7 +43,12 @@ case "$1" in
stop_puppet
log_end_msg 0
;;
- restart|force-reload)
+ reload)
+ log_begin_msg "Reloading $DESC"
+ reload_puppet
+ log_end_msg 0
+ ;;
+ restart|force-reload)
log_begin_msg "Restarting $DESC"
stop_puppet
sleep 1
@@ -47,7 +56,7 @@ case "$1" in
log_end_msg 0
;;
*)
- echo "Usage: $0 {start|stop|restart|force-reload}" >&2
+ echo "Usage: $0 {start|stop|restart|force-reload|reload}" >&2
exit 1
;;
esac
diff --git a/debian/rules b/debian/rules
index 69bf3a4af..ecabcbad0 100644..100755
--- a/debian/rules
+++ b/debian/rules
@@ -66,10 +66,10 @@ install: build
$(INSTALL) -m0644 debian/puppet.conf $(pkgconfdir)/puppet.conf
# Vim auto-syntax-highlighting stuff
- $(INSTALL) -m0644 ext/vim/puppet.vim \
- $(CURDIR)/debian/puppet/usr/share/vim/vim70/syntax/puppet.vim
- $(INSTALL) -m0644 ext/vim/filetype.vim \
- $(CURDIR)/debian/puppet/usr/share/vim/addons/ftdetect/puppet.vim
+ $(INSTALL) -m0644 ext/vim/syntax/puppet.vim \
+ $(CURDIR)/debian/puppet/usr/share/vim/vim71/syntax/
+ $(INSTALL) -m0644 ext/vim/ftdetect/puppet.vim \
+ $(CURDIR)/debian/puppet/usr/share/vim/addons/ftdetect/
# Emacs keeping up with the Joneses
$(INSTALL) -m0644 ext/emacs/puppet-mode-init.el \
@@ -100,7 +100,8 @@ binary-indep: build install
dh_movefiles -i
dh_installchangelogs -i CHANGELOG
dh_installdocs -i
- dh_installinit -i
+ dh_installinit -ppuppetmaster
+ dh_installinit -ppuppet -- defaults 21
dh_installlogrotate -i
dh_compress -i
dh_fixperms -i
diff --git a/examples/root/etc/puppet/puppetmasterd.conf b/examples/root/etc/puppet/puppet.conf
index b3182075c..151364ebd 100644
--- a/examples/root/etc/puppet/puppetmasterd.conf
+++ b/examples/root/etc/puppet/puppet.conf
@@ -1,7 +1,10 @@
+[puppetd]
+report = true
+factsync = true
+pluginsync = true
+
[puppetmasterd]
reports = store,rrdgraph,tagmail,log
-
-[ldap]
-ldapnodes = true
+node_terminus = ldap
ldapserver = culain.madstop.com
ldapbase = dc=madstop,dc=com
diff --git a/examples/root/etc/puppet/puppetd.conf b/examples/root/etc/puppet/puppetd.conf
deleted file mode 100644
index ce988cfa1..000000000
--- a/examples/root/etc/puppet/puppetd.conf
+++ /dev/null
@@ -1,4 +0,0 @@
-[puppet]
-report = true
-factsync = true
-pluginsync = true
diff --git a/ext/emacs/puppet-mode.el b/ext/emacs/puppet-mode.el
index 2cf5dcfe9..f331474a9 100644
--- a/ext/emacs/puppet-mode.el
+++ b/ext/emacs/puppet-mode.el
@@ -89,46 +89,108 @@
(make-local-variable 'paragraph-ignore-fill-prefix)
(setq paragraph-ignore-fill-prefix t))
+(defun puppet-comment-line-p ()
+ "Return non-nil iff this line is a comment."
+ (save-excursion
+ (beginning-of-line)
+ (looking-at (format "\\s-*%s" comment-start))))
+
+(defun puppet-in-array ()
+ "If point is in an array, return the position of the opening '[' of
+that array, else return nil."
+ (save-excursion
+ (save-match-data
+ (let ((opoint (point))
+ (apoint (search-backward "[" nil t)))
+ (when apoint
+ ;; An array opens before point. If it doesn't close before
+ ;; point, then point must be in it.
+ ;; ### TODO: of course, the '[' could be in a string literal,
+ ;; ### in which case this whole idea is bogus. But baby
+ ;; ### steps, baby steps. A more robust strategy might be
+ ;; ### to walk backwards by sexps, until hit a wall, then
+ ;; ### inspect the nature of that wall.
+ (if (= (count-matches "\\]" apoint opoint) 0)
+ apoint))))))
+
(defun puppet-indent-line ()
"Indent current line as puppet code."
(interactive)
(beginning-of-line)
(if (bobp)
(indent-line-to 0) ; First line is always non-indented
- (let ((not-indented t) cur-indent)
- (if (looking-at "^.*}") ; If the line we are looking at is the end of
- ; a block, then decrease the indentation
- (progn
- (save-excursion
- (forward-line -1)
-
- (if (looking-at "^.*}")
- (progn
- (setq cur-indent (- (current-indentation) 2))
- (setq not-indented nil))
- (setq cur-indent (- (current-indentation) 2))))
- (if (< cur-indent 0) ; We can't indent past the left margin
- (setq cur-indent 0)))
- (save-excursion
- (while not-indented ; Iterate backwards until we find an
- ; indentation hint
- (forward-line -1)
- (if (looking-at "^.*}") ; This hint indicates that we need to
- ; indent at the level of the END_ token
- (progn
- (setq cur-indent (current-indentation))
- (setq not-indented nil))
- (if (looking-at "^.*{") ; This hint indicates that we need to
- ; indent an extra level
- (progn
- ; Do the actual indenting
- (setq cur-indent (+ (current-indentation) 2))
- (setq not-indented nil))
- (if (bobp)
- (setq not-indented nil)))))))
+ (let ((not-indented t)
+ (array-start (puppet-in-array))
+ cur-indent)
+ (cond
+ (array-start
+ ;; This line probably starts with an element from an array.
+ ;; Indent the line to the same indentation as the first
+ ;; element in that array. That is, this...
+ ;;
+ ;; exec {
+ ;; "add_puppetmaster_mongrel_startup_links":
+ ;; command => "string1",
+ ;; creates => [ "string2", "string3",
+ ;; "string4", "string5",
+ ;; "string6", "string7",
+ ;; "string3" ],
+ ;; refreshonly => true,
+ ;; }
+ ;;
+ ;; ...should instead look like this:
+ ;;
+ ;; exec {
+ ;; "add_puppetmaster_mongrel_startup_links":
+ ;; command => "string1",
+ ;; creates => [ "string2", "string3",
+ ;; "string4", "string5",
+ ;; "string6", "string7",
+ ;; "string8" ],
+ ;; refreshonly => true,
+ ;; }
+ (save-excursion
+ (goto-char array-start)
+ (forward-char 1)
+ (re-search-forward "\\S-")
+ (forward-char -1)
+ (setq cur-indent (current-column))))
+ ((looking-at "^[^{\n]*}")
+ ;; This line contains the end of a block, but the block does
+ ;; not also begin on this line, so decrease the indentation.
+ (save-excursion
+ (forward-line -1)
+ (if (looking-at "^.*}")
+ (progn
+ (setq cur-indent (- (current-indentation) 2))
+ (setq not-indented nil))
+ (setq cur-indent (- (current-indentation) 2))))
+ (if (< cur-indent 0) ; We can't indent past the left margin
+ (setq cur-indent 0)))
+ (t
+ ;; Otherwise, we did not start on a block-ending-only line.
+ (save-excursion
+ ;; Iterate backwards until we find an indentation hint
+ (while not-indented
+ (forward-line -1)
+ (cond
+ ((puppet-comment-line-p)
+ (if (bobp)
+ (setq not-indented nil)
+ ;; else ignore the line and continue iterating backwards
+ ))
+ ((looking-at "^.*}") ; indent at the level of the END_ token
+ (setq cur-indent (current-indentation))
+ (setq not-indented nil))
+ ((looking-at "^.*{") ; indent an extra level
+ (setq cur-indent (+ (current-indentation) 2))
+ (setq not-indented nil))
+ ((bobp)
+ (setq not-indented nil))
+ )))))
(if cur-indent
- (indent-line-to cur-indent)
- (indent-line-to 0)))))
+ (indent-line-to cur-indent)
+ (indent-line-to 0)))))
;;;###autoload
@@ -155,31 +217,31 @@ The variable puppet-indent-level controls the amount of indentation.
(setq font-lock-variable-name-face font-lock-type-face))
(setq puppet-font-lock-syntactic-keywords
- '(
- ("\\(^\\|[=(,~?:;]\\|\\(^\\|\\s \\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&&\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)"
- (4 (7 . ?/))
- (6 (7 . ?/)))
- ("^\\(=\\)begin\\(\\s \\|$\\)" 1 (7 . nil))
- ("^\\(=\\)end\\(\\s \\|$\\)" 1 (7 . nil))))
+ '(
+ ("\\(^\\|[=(,~?:;]\\|\\(^\\|\\s \\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&&\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)"
+ (4 (7 . ?/))
+ (6 (7 . ?/)))
+ ("^\\(=\\)begin\\(\\s \\|$\\)" 1 (7 . nil))
+ ("^\\(=\\)end\\(\\s \\|$\\)" 1 (7 . nil))))
(cond ((featurep 'xemacs)
- (put 'puppet-mode 'font-lock-defaults
- '((puppet-font-lock-keywords)
- nil nil nil
- beginning-of-line
- (font-lock-syntactic-keywords
- . puppet-font-lock-syntactic-keywords))))
- (t
- (add-hook 'puppet-mode-hook
- '(lambda ()
- (make-local-variable 'font-lock-defaults)
- (make-local-variable 'font-lock-keywords)
- (make-local-variable 'font-lock-syntax-table)
- (make-local-variable 'font-lock-syntactic-keywords)
- (setq font-lock-defaults '((puppet-font-lock-keywords) nil nil))
- (setq font-lock-keywords puppet-font-lock-keywords)
- (setq font-lock-syntax-table puppet-font-lock-syntax-table)
- (setq font-lock-syntactic-keywords puppet-font-lock-syntactic-keywords)))))
+ (put 'puppet-mode 'font-lock-defaults
+ '((puppet-font-lock-keywords)
+ nil nil nil
+ beginning-of-line
+ (font-lock-syntactic-keywords
+ . puppet-font-lock-syntactic-keywords))))
+ (t
+ (add-hook 'puppet-mode-hook
+ '(lambda ()
+ (make-local-variable 'font-lock-defaults)
+ (make-local-variable 'font-lock-keywords)
+ (make-local-variable 'font-lock-syntax-table)
+ (make-local-variable 'font-lock-syntactic-keywords)
+ (setq font-lock-defaults '((puppet-font-lock-keywords) nil nil))
+ (setq font-lock-keywords puppet-font-lock-keywords)
+ (setq font-lock-syntax-table puppet-font-lock-syntax-table)
+ (setq font-lock-syntactic-keywords puppet-font-lock-syntactic-keywords)))))
(defvar puppet-font-lock-syntax-table
(let* ((tbl (copy-syntax-table puppet-mode-syntax-table)))
@@ -196,23 +258,23 @@ The variable puppet-indent-level controls the amount of indentation.
1 font-lock-reference-face)
;; keywords
(cons (concat
- "\\b\\(\\("
- (mapconcat
- 'identity
- '("case"
+ "\\b\\(\\("
+ (mapconcat
+ 'identity
+ '("case"
"class"
"default"
"define"
- "false"
- "import"
- "include"
- "inherits"
- "node"
- "true"
- )
- "\\|")
- "\\)\\>\\)")
- 1)
+ "false"
+ "import"
+ "include"
+ "inherits"
+ "node"
+ "true"
+ )
+ "\\|")
+ "\\)\\>\\)")
+ 1)
;; variables
'("\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(nil\\|self\\|true\\|false\\)\\>"
2 font-lock-variable-name-face)
diff --git a/ext/ldap/puppet.schema b/ext/ldap/puppet.schema
index b7c715ec2..bbad23eab 100644
--- a/ext/ldap/puppet.schema
+++ b/ext/ldap/puppet.schema
@@ -12,6 +12,11 @@ attributetype ( 1.1.3.9 NAME 'parentnode'
EQUALITY caseIgnoreIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+attributetype ( 1.1.3.9 NAME 'environment'
+ DESC 'Puppet Node Environment'
+ EQUALITY caseIgnoreIA5Match
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
objectclass ( 1.1.1.2 NAME 'puppetClient' SUP top AUXILIARY
DESC 'Puppet Client objectclass'
- MAY ( puppetclass $ parentnode ))
+ MAY ( puppetclass $ parentnode $ environment ))
diff --git a/ext/logcheck/puppet b/ext/logcheck/puppet
index 8b854dc48..449ec70f5 100644
--- a/ext/logcheck/puppet
+++ b/ext/logcheck/puppet
@@ -15,3 +15,8 @@
^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Restarting with .*$
^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Starting catalog run$
^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Finished catalog run in [.0-9]+ seconds$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Loading fact .*$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Ignoring cache$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Ignoring --listen on onetime run$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ puppetd\[[0-9]+\]: Retrieving plugins$
+
diff --git a/ext/puppet-test b/ext/puppet-test
index 362a43996..dc0aeca92 100755
--- a/ext/puppet-test
+++ b/ext/puppet-test
@@ -53,6 +53,9 @@
# list::
# List all available tests.
#
+# pause::
+# Pause before starting test (useful for testing with dtrace).
+#
# repeat::
# How many times to perform the test.
#
@@ -88,7 +91,7 @@
# Do an initial trap, so that cancels don't get a stack trace.
trap(:INT) do
$stderr.puts "Cancelling startup"
- exit(0)
+ exit(1)
end
require 'puppet'
@@ -140,10 +143,6 @@ class Suite
instance_eval(&block)
end
- def prepare
- raise "Test %s did not override 'prepare'" % @name
- end
-
# Define a new type of test on this suite.
def newtest(name, doc, &block)
@tests[name] = doc
@@ -163,7 +162,14 @@ class Suite
raise "Suite %s only supports tests %s; not %s" % [@name, @tests.keys.collect { |k| k.to_s }.join(","), test]
end
puts "Running %s %s test" % [@name, test]
- prepare()
+
+ prepare() if respond_to?(:prepare)
+
+ if $options[:pause]
+ puts "Hit any key to continue"
+ $stdin.readline
+ puts "Continuing with test"
+ end
if $options[:fork] > 0
@forking = true
@@ -200,7 +206,25 @@ class Suite
end
end
-Suite.new :catalog, "Catalog handling" do
+Suite.new :parser, "Manifest parsing" do
+ newtest :parse, "Parsed files" do
+ @parser = Puppet::Parser::Parser.new(:environment => Puppet[:environment])
+ @parser.file = Puppet[:manifest]
+ @parser.parse
+ end
+end
+
+Suite.new :local_catalog, "Local catalog handling" do
+ def prepare
+ @node = Puppet::Node.find(Puppet[:certname])
+ end
+
+ newtest :compile, "Compiled catalog" do
+ Puppet::Node::Catalog.find(@node)
+ end
+end
+
+Suite.new :remote_catalog, "Remote catalog handling" do
def prepare
$args[:cache] = false
# Create a config client and pull the config down
@@ -212,10 +236,12 @@ Suite.new :catalog, "Catalog handling" do
# Use the facts from the cache, to skip the time it takes
# to load them.
@client.dostorage
- @facts = Puppet::Util::Storage.cache(:configuration)[:facts]
+ @facts = Puppet::Util::Storage.cache(:configuration)[:facts] || {}
if @facts.empty?
- @facts = @client.master.getfacts
+ if tmp = Puppet::Node::Facts.find("me")
+ @facts = tmp.values
+ end
end
if host = $options[:fqdn]
@@ -227,7 +253,7 @@ Suite.new :catalog, "Catalog handling" do
@facts = YAML.dump(@facts)
end
- newtest :compile, "Compiled catalog" do
+ newtest :getconfig, "Compiled catalog" do
@client.driver.getconfig(@facts, "yaml")
end
@@ -257,6 +283,21 @@ Suite.new :file, "File interactions" do
end
end
+Suite.new :filebucket, "Filebucket interactions" do
+ def prepare
+ require 'tempfile'
+ @client = Puppet::Network::Client.dipper.new($args)
+ end
+
+ newtest :backup, "Backed up file" do
+ Tempfile.open("bucket_testing") do |f|
+ f.print rand(1024)
+ f.close
+ @client.backup(f.path)
+ end
+ end
+end
+
# Note that this uses an env variable to determine how many resources per
# host to create (with a default of 10). 'repeat' determines how
# many hosts to create. You probably will get mad failures if you
@@ -325,12 +366,13 @@ end
$cmdargs = [
[ "--compile", "-c", GetoptLong::NO_ARGUMENT ],
- [ "--describe", "-D", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--describe", GetoptLong::REQUIRED_ARGUMENT ],
[ "--retrieve", "-R", GetoptLong::REQUIRED_ARGUMENT ],
[ "--fork", GetoptLong::REQUIRED_ARGUMENT ],
[ "--fqdn", "-F", GetoptLong::REQUIRED_ARGUMENT ],
[ "--suite", "-s", GetoptLong::REQUIRED_ARGUMENT ],
[ "--test", "-t", GetoptLong::REQUIRED_ARGUMENT ],
+ [ "--pause", "-p", GetoptLong::NO_ARGUMENT ],
[ "--repeat", "-r", GetoptLong::REQUIRED_ARGUMENT ],
[ "--debug", "-d", GetoptLong::NO_ARGUMENT ],
[ "--help", "-h", GetoptLong::NO_ARGUMENT ],
@@ -340,14 +382,14 @@ $cmdargs = [
]
# Add all of the config parameters as valid $options.
-Puppet.config.addargs($cmdargs)
+Puppet.settings.addargs($cmdargs)
Puppet::Util::Log.newdestination(:console)
result = GetoptLong.new(*$cmdargs)
$args = {}
-$options = {:repeat => 1, :fork => 0}
+$options = {:repeat => 1, :fork => 0, :pause => false}
begin
explicit_waitforcert = false
@@ -399,6 +441,8 @@ begin
$options[:test] = arg.intern
when "--file"
$options[:file] = arg
+ when "--pause"
+ $options[:pause] = true
when "--list"
Suite.suites.sort { |a,b| a.to_s <=> b.to_s }.each do |suite_name|
suite = Suite[suite_name]
@@ -407,7 +451,7 @@ begin
end
exit(0)
else
- Puppet.config.handlearg(opt, arg)
+ Puppet.settings.handlearg(opt, arg)
end
}
rescue GetoptLong::InvalidOption => detail
@@ -422,8 +466,8 @@ Puppet.parse_config
$args[:Server] = Puppet[:server]
unless $options[:test]
- $options[:suite] = :configuration
- $options[:test] = :compile
+ $options[:suite] = :remote_catalog
+ $options[:test] = :getconfig
end
unless $options[:test]
diff --git a/install.rb b/install.rb
index 6c418119b..d744f2d2d 100755
--- a/install.rb
+++ b/install.rb
@@ -47,6 +47,18 @@ rescue LoadError
$haverdoc = false
end
+begin
+ if $haverdoc
+ rst2man = %x{which rst2man.py}
+ $haveman = true
+ else
+ $haveman = false
+ end
+rescue
+ puts "Missing rst2man; skipping man page creation"
+ $haveman = false
+end
+
PREREQS = %w{openssl facter xmlrpc/client xmlrpc/server cgi}
InstallOptions = OpenStruct.new
@@ -64,6 +76,7 @@ sbins = glob(%w{sbin/*})
bins = glob(%w{bin/*})
rdoc = glob(%w{bin/* sbin/* lib/**/*.rb README README-library CHANGELOG TODO Install}).reject { |e| e=~ /\.(bat|cmd)$/ }
ri = glob(%w(bin/*.rb sbin/* lib/**/*.rb)).reject { |e| e=~ /\.(bat|cmd)$/ }
+man = glob(%w{man/man8/*})
libs = glob(%w{lib/**/*.rb lib/**/*.py})
tests = glob(%w{tests/**/*.rb})
@@ -84,6 +97,19 @@ def do_libs(libs, strip = 'lib/')
end
end
+def do_man(man, strip = 'man/')
+ man.each do |mf|
+ omf = File.join(InstallOptions.man_dir, mf.gsub(/#{strip}/, ''))
+ om = File.dirname(omf)
+ File.makedirs(om, true)
+ File.chmod(0644, om)
+ File.install(mf, omf, 0644, true)
+ gzip = %x{which gzip}
+ gzip.chomp!
+ %x{#{gzip} #{omf}}
+ end
+end
+
# Verify that all of the prereqs are installed
def check_prereqs
PREREQS.each { |pre|
@@ -112,8 +138,28 @@ def prepare_installation
InstallOptions.rdoc = false
InstallOptions.ri = false
end
+
+
+ if $haveman
+ InstallOptions.man = true
+ if RUBY_PLATFORM == "i386-mswin32"
+ InstallOptions.man = false
+ end
+ else
+ InstallOptions.man = false
+ end
+
InstallOptions.tests = true
+ if $haveman
+ InstallOptions.man = true
+ if RUBY_PLATFORM == "i386-mswin32"
+ InstallOptions.man = false
+ end
+ else
+ InstallOptions.man = false
+ end
+
ARGV.options do |opts|
opts.banner = "Usage: #{File.basename($0)} [options]"
opts.separator ""
@@ -123,6 +169,9 @@ def prepare_installation
opts.on('--[no-]ri', 'Prevents the creation of RI output.', 'Default off on mswin32.') do |onri|
InstallOptions.ri = onri
end
+ opts.on('--[no-]man', 'Presents the creation of man pages.', 'Default on.') do |onman|
+ InstallOptions.man = onman
+ end
opts.on('--[no-]tests', 'Prevents the execution of unit tests.', 'Default on.') do |ontest|
InstallOptions.tests = ontest
end
@@ -133,6 +182,7 @@ def prepare_installation
end
opts.on('--full', 'Performs a full installation. All', 'optional installation steps are run.') do |full|
InstallOptions.rdoc = true
+ InstallOptions.man = true
InstallOptions.ri = true
InstallOptions.tests = true
end
@@ -163,15 +213,18 @@ def prepare_installation
if (destdir = ENV['DESTDIR'])
bindir = "#{destdir}#{Config::CONFIG['bindir']}"
sbindir = "#{destdir}#{Config::CONFIG['sbindir']}"
+ mandir = "#{destdir}#{Config::CONFIG['mandir']}"
sitelibdir = "#{destdir}#{sitelibdir}"
tmpdirs << bindir
FileUtils.makedirs(bindir)
FileUtils.makedirs(sbindir)
+ FileUtils.makedirs(mandir)
FileUtils.makedirs(sitelibdir)
else
bindir = Config::CONFIG['bindir']
sbindir = Config::CONFIG['sbindir']
+ mandir = Config::CONFIG['mandir']
tmpdirs << Config::CONFIG['bindir']
end
@@ -180,6 +233,7 @@ def prepare_installation
InstallOptions.bin_dir = bindir
InstallOptions.sbin_dir = sbindir
InstallOptions.lib_dir = libdir
+ InstallOptions.man_dir = mandir
end
##
@@ -212,6 +266,30 @@ def build_ri(files)
end
end
+def build_man(bins)
+ return unless $haveman
+ begin
+ # Locate rst2man
+ rst2man = %x{which rst2man.py}
+ rst2man.chomp!
+ # Create puppet.conf.8 man page
+ %x{bin/puppetdoc --reference configuration > ./puppet.conf.rst}
+ %x{#{rst2man} ./puppet.conf.rst ./man/man8/puppet.conf.8}
+ File.unlink("./puppet.conf.rst")
+
+ # Create binary man pages
+ bins.each do |bin|
+ b = bin.gsub( "bin/", "")
+ %x{#{bin} --help > ./#{b}.rst}
+ %x{#{rst2man} ./#{b}.rst ./man/man8/#{b}.8}
+ File.unlink("./#{b}.rst")
+ end
+ rescue SystemCallError
+ $stderr.puts "Couldn't build man pages: " + $!
+ $stderr.puts "Continuing with install..."
+ end
+end
+
def run_tests(test_list)
begin
require 'test/unit/ui/console/testrunner'
@@ -309,6 +387,8 @@ prepare_installation
run_tests(tests) if InstallOptions.tests
#build_rdoc(rdoc) if InstallOptions.rdoc
#build_ri(ri) if InstallOptions.ri
+#build_man(bins) if InstallOptions.man
do_bins(sbins, InstallOptions.sbin_dir)
do_bins(bins, InstallOptions.bin_dir)
do_libs(libs)
+do_man(man)
diff --git a/lib/puppet.rb b/lib/puppet.rb
index 18037cdc1..cde25721e 100644
--- a/lib/puppet.rb
+++ b/lib/puppet.rb
@@ -25,7 +25,7 @@ require 'puppet/util/suidmanager'
# it's also a place to find top-level commands like 'debug'
module Puppet
- PUPPETVERSION = '0.24.1'
+ PUPPETVERSION = '0.24.4'
def Puppet.version
return PUPPETVERSION
@@ -205,16 +205,7 @@ module Puppet
end
# Parse the config file for this process.
- def self.parse_config(oldconfig = nil)
- # First look for the old configuration file.
- oldconfig ||= File.join(Puppet[:confdir], Puppet[:name].to_s + ".conf")
- if FileTest.exists?(oldconfig) and Puppet[:name] != "puppet"
- Puppet.warning "Individual config files are deprecated; remove %s and use puppet.conf" % oldconfig
- Puppet.settings.old_parse(oldconfig)
- return
- end
-
- # Now check for the normal config.
+ def self.parse_config
if Puppet[:config] and File.exists? Puppet[:config]
Puppet.debug "Parsing %s" % Puppet[:config]
Puppet.settings.parse(Puppet[:config])
@@ -423,6 +414,7 @@ module Puppet
end
require 'puppet/type'
+require 'puppet/network'
require 'puppet/module'
require 'puppet/util/storage'
require 'puppet/parser/interpreter'
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb
index a95023895..0f01c2ee2 100644
--- a/lib/puppet/defaults.rb
+++ b/lib/puppet/defaults.rb
@@ -66,7 +66,11 @@ module Puppet
:owner => "root",
:desc => "Where SSL certificates are kept."
},
- :rundir => { :default => rundir,
+ :rundir => {
+ :default => rundir,
+ :mode => 01777,
+ :owner => "$user",
+ :group => "$group",
:desc => "Where Puppet PID files are kept."
},
:genconfig => [false,
@@ -136,8 +140,6 @@ module Puppet
:show_diff => [false, "Whether to print a contextual diff when files are being replaced. The diff
is printed on stdout, so this option is meaningless unless you are running Puppet interactively.
This feature currently requires the ``diff/lcs`` Ruby library."],
- :yamldir => {:default => "$vardir/yaml", :owner => "$user", :group => "$user", :mode => "750",
- :desc => "The directory in which YAML data is stored, usually in a subdirectory."},
:daemonize => { :default => true,
:desc => "Send the process into the background. This is the default.",
:short => "D"
@@ -228,7 +230,7 @@ module Puppet
:owner => "$user",
:group => "$group",
:mode => 0664,
- :desc => "The certificate revocation list (CRL) for the CA. Set this to 'none' if you do not want to use a CRL."
+ :desc => "The certificate revocation list (CRL) for the CA. Set this to 'false' if you do not want to use a CRL."
},
:caprivatedir => { :default => "$cadir/private",
:owner => "$user",
@@ -256,6 +258,7 @@ module Puppet
:serial => { :default => "$cadir/serial",
:owner => "$user",
:group => "$group",
+ :mode => 0600,
:desc => "Where the serial number for certificates is stored."
},
:autosign => { :default => "$confdir/autosign.conf",
@@ -324,8 +327,8 @@ module Puppet
:masterport => [8140, "Which port puppetmasterd listens on."],
:parseonly => [false, "Just check the syntax of the manifests."],
:node_name => ["cert", "How the puppetmaster determines the client's identity
- and sets the 'hostname' fact for use in the manifest, in particular
- for determining which 'node' statement applies to the client.
+ and sets the 'hostname', 'fqdn' and 'domain' facts for use in the manifest,
+ in particular for determining which 'node' statement applies to the client.
Possible values are 'cert' (use the subject's CN in the client's
certificate) and 'facter' (use the hostname that the client
reported in its facts)"],
@@ -343,11 +346,15 @@ module Puppet
:ssl_client_header => ["HTTP_X_CLIENT_DN", "The header containing an authenticated
client's SSL DN. Only used with Mongrel. This header must be set by the proxy
to the authenticated client's SSL DN (e.g., ``/CN=puppet.reductivelabs.com``).
- See the `UsingMongrel`:trac: wiki page for more information."],
+ See http://reductivelabs.com/puppet/trac/wiki/UsingMongrel for more information."],
:ssl_client_verify_header => ["HTTP_X_CLIENT_VERIFY", "The header containing the status
message of the client verification. Only used with Mongrel. This header must be set by the proxy
to 'SUCCESS' if the client successfully authenticated, and anything else otherwise.
- See the `UsingMongrel`:trac: wiki page for more information."]
+ See http://reductivelabs.com/puppet/trac/wiki/UsingMongrel for more information."],
+ # To make sure this directory is created before we try to use it on the server, we need
+ # it to be in the server section (#1138).
+ :yamldir => {:default => "$vardir/yaml", :owner => "$user", :group => "$user", :mode => "750",
+ :desc => "The directory in which YAML data is stored, usually in a subdirectory."}
)
self.setdefaults(:puppetd,
@@ -597,7 +604,7 @@ module Puppet
setdefaults(:ldap,
:ldapnodes => [false,
"Whether to search for node configurations in LDAP. See
- `LdapNodes`:trac: for more information."],
+ http://reductivelabs.com/puppet/trac/wiki/LdapNodes/ for more information."],
:ldapssl => [false,
"Whether SSL should be used when searching for nodes.
Defaults to false because SSL usually requires certificates
diff --git a/lib/puppet/dsl.rb b/lib/puppet/dsl.rb
index 4fbce556c..966feaf9b 100644
--- a/lib/puppet/dsl.rb
+++ b/lib/puppet/dsl.rb
@@ -46,58 +46,56 @@
#
# apply
-module Puppet
- # Provide the actual commands for acting like a language.
- module DSL
- def aspect(name, options = {}, &block)
- Puppet::Aspect.new(name, options, &block)
- end
+require 'puppet'
- def acquire(*names)
- names.each do |name|
- if aspect = Puppet::Aspect[name]
- unless aspect.evaluated?
- aspect.evaluate
- end
- else
- raise "Could not find aspect %s" % name
+# Provide the actual commands for acting like a language.
+module Puppet::DSL
+ def aspect(name, options = {}, &block)
+ Puppet::DSL::Aspect.new(name, options, &block)
+ end
+
+ def acquire(*names)
+ names.each do |name|
+ if aspect = Puppet::DSL::Aspect[name]
+ unless aspect.evaluated?
+ aspect.evaluate
end
+ else
+ raise "Could not find aspect %s" % name
end
end
+ end
- def apply
- bucket = export()
- catalog = bucket.to_catalog
- catalog.apply
- end
+ def apply
+ bucket = export()
+ catalog = bucket.to_catalog
+ catalog.apply
+ end
- def export
- objects = Puppet::Aspect.collect do |name, aspect|
- if aspect.evaluated?
- aspect.export
- end
- end.reject { |a| a.nil? }.flatten.collect do |obj|
- obj.to_trans
+ def export
+ objects = Puppet::DSL::Aspect.collect do |name, aspect|
+ if aspect.evaluated?
+ aspect.export
end
- bucket = Puppet::TransBucket.new(objects)
- bucket.name = "top"
- bucket.type = "class"
-
- return bucket
+ end.reject { |a| a.nil? }.flatten.collect do |obj|
+ obj.to_trans
end
+ bucket = Puppet::TransBucket.new(objects)
+ bucket.name = "top"
+ bucket.type = "class"
- def init
- unless Process.uid == 0
- Puppet[:confdir] = File.expand_path("~/.puppet")
- Puppet[:vardir] = File.expand_path("~/.puppet/var")
- end
- Puppet[:user] = Process.uid
- Puppet[:group] = Process.gid
- Puppet::Util::Log.newdestination(:console)
- Puppet::Util::Log.level = :info
- end
+ return bucket
+ end
- private
+ def init
+ unless Process.uid == 0
+ Puppet[:confdir] = File.expand_path("~/.puppet")
+ Puppet[:vardir] = File.expand_path("~/.puppet/var")
+ end
+ Puppet[:user] = Process.uid
+ Puppet[:group] = Process.gid
+ Puppet::Util::Log.newdestination(:console)
+ Puppet::Util::Log.level = :info
end
class Aspect
@@ -224,10 +222,10 @@ module Puppet
end
def newresource(type, name, params = {})
- if self.is_a?(Puppet::Aspect)
+ if self.is_a?(Puppet::DSL::Aspect)
source = self
else
- source = Puppet::Aspect[:main]
+ source = Puppet::DSL::Aspect[:main]
end
unless obj = @@objects[type][name]
obj = Resource.new :title => name, :type => type.name,
@@ -262,7 +260,7 @@ module Puppet
env = nil
end
@node.parameters = Facter.to_hash
- @compile = Puppet::Parser::Compile.new(@node, @interp.send(:parser, env))
+ @compile = Puppet::Parser::Compiler.new(@node, @interp.send(:parser, env))
@scope = @compile.topscope
end
@scope
diff --git a/lib/puppet/file_serving/configuration/parser.rb b/lib/puppet/file_serving/configuration/parser.rb
index 707c3f9b1..cda6889d4 100644
--- a/lib/puppet/file_serving/configuration/parser.rb
+++ b/lib/puppet/file_serving/configuration/parser.rb
@@ -62,7 +62,8 @@ class Puppet::FileServing::Configuration::Parser < Puppet::Util::LoadedFile
# Allow a given pattern access to a mount.
def allow(mount, value)
- value.split(/\s*,\s*/).each { |val|
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = value.split(/\s*,\s*/).each { |val|
begin
mount.info "allowing %s access" % val
mount.allow(val)
@@ -75,7 +76,8 @@ class Puppet::FileServing::Configuration::Parser < Puppet::Util::LoadedFile
# Deny a given pattern access to a mount.
def deny(mount, value)
- value.split(/\s*,\s*/).each { |val|
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = value.split(/\s*,\s*/).each { |val|
begin
mount.info "denying %s access" % val
mount.deny(val)
diff --git a/lib/puppet/file_serving/file_base.rb b/lib/puppet/file_serving/file_base.rb
index 7f169d1ea..e87d683aa 100644
--- a/lib/puppet/file_serving/file_base.rb
+++ b/lib/puppet/file_serving/file_base.rb
@@ -9,16 +9,28 @@ require 'puppet/file_serving'
class Puppet::FileServing::FileBase
attr_accessor :key
+ # Does our file exist?
+ def exist?
+ begin
+ stat
+ return true
+ rescue => detail
+ return false
+ end
+ end
+
# Return the full path to our file. Fails if there's no path set.
def full_path
raise(ArgumentError, "You must set a path to get a file's path") unless self.path
- relative_path ? File.join(path, relative_path) : path
+ if relative_path.nil? or relative_path == ""
+ path
+ else
+ File.join(path, relative_path)
+ end
end
def initialize(key, options = {})
- raise ArgumentError.new("Files must not be fully qualified") if path =~ /^#{::File::SEPARATOR}/
-
@key = key
@links = :manage
@@ -34,6 +46,7 @@ class Puppet::FileServing::FileBase
# Determine how we deal with links.
attr_reader :links
def links=(value)
+ value = :manage if value == :ignore
raise(ArgumentError, ":links can only be set to :manage or :follow") unless [:manage, :follow].include?(value)
@links = value
end
diff --git a/lib/puppet/file_serving/metadata.rb b/lib/puppet/file_serving/metadata.rb
index e26e75844..56712122c 100644
--- a/lib/puppet/file_serving/metadata.rb
+++ b/lib/puppet/file_serving/metadata.rb
@@ -28,6 +28,25 @@ class Puppet::FileServing::Metadata < Puppet::FileServing::FileBase
attr_reader :path, :owner, :group, :mode, :checksum_type, :checksum, :ftype, :destination
+ PARAM_ORDER = [:mode, :ftype, :owner, :group]
+
+ def attributes_with_tabs
+ desc = []
+ PARAM_ORDER.each { |check|
+ check = :ftype if check == :type
+ desc << send(check)
+ }
+
+ case ftype
+ when "file", "directory": desc << checksum
+ when "link": desc << @destination
+ else
+ raise ArgumentError, "Cannot manage files of type %s" % ftype
+ end
+
+ return desc.join("\t")
+ end
+
def checksum_type=(type)
raise(ArgumentError, "Unsupported checksum type %s" % type) unless respond_to?("%s_file" % type)
@@ -45,13 +64,19 @@ class Puppet::FileServing::Metadata < Puppet::FileServing::FileBase
@ftype = stat.ftype
- # Set the octal mode, but as a string.
- @mode = "%o" % (stat.mode & 007777)
+ # We have to mask the mode, yay.
+ @mode = stat.mode & 007777
- if stat.ftype == "symlink"
+ case stat.ftype
+ when "file":
+ @checksum = ("{%s}" % @checksum_type) + send("%s_file" % @checksum_type, real_path)
+ when "directory": # Always just timestamp the directory.
+ sumtype = @checksum_type.to_s =~ /time/ ? @checksum_type : "ctime"
+ @checksum = ("{%s}" % sumtype) + send("%s_file" % sumtype, path).to_s
+ when "link":
@destination = File.readlink(real_path)
else
- @checksum = get_checksum(real_path)
+ raise ArgumentError, "Cannot manage files of type %s" % stat.ftype
end
end
@@ -59,11 +84,4 @@ class Puppet::FileServing::Metadata < Puppet::FileServing::FileBase
@checksum_type = "md5"
super
end
-
- private
-
- # Retrieve our checksum.
- def get_checksum(path)
- ("{%s}" % @checksum_type) + send("%s_file" % @checksum_type, path)
- end
end
diff --git a/lib/puppet/indirector/facts/facter.rb b/lib/puppet/indirector/facts/facter.rb
index 5b9a7b3c0..a8c47e3bf 100644
--- a/lib/puppet/indirector/facts/facter.rb
+++ b/lib/puppet/indirector/facts/facter.rb
@@ -23,7 +23,8 @@ class Puppet::Node::Facts::Facter < Puppet::Indirector::Code
end
def self.loadfacts
- Puppet[:factpath].split(":").each do |dir|
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = Puppet[:factpath].split(":").each do |dir|
loaddir(dir, "fact")
end
end
diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb
index 129676e9c..d47433c60 100644
--- a/lib/puppet/indirector/indirection.rb
+++ b/lib/puppet/indirector/indirection.rb
@@ -162,7 +162,7 @@ class Puppet::Indirector::Indirection
# See if our instance is in the cache and up to date.
if cache? and cache.has_most_recent?(key, terminus(terminus_name).version(key))
- Puppet.info "Using cached %s %s" % [self.name, key]
+ Puppet.debug "Using cached %s %s" % [self.name, key]
return cache.find(key, *args)
end
diff --git a/lib/puppet/indirector/node/exec.rb b/lib/puppet/indirector/node/exec.rb
index ed76bce94..dcfc625b2 100644
--- a/lib/puppet/indirector/node/exec.rb
+++ b/lib/puppet/indirector/node/exec.rb
@@ -24,13 +24,20 @@ class Puppet::Node::Exec < Puppet::Indirector::Exec
return create_node(name, result)
end
+ # Use the version of the facts, since we assume that's the main thing
+ # that changes. If someone wants their own way of defining version,
+ # they can easily provide their own, um, version of this class.
+ def version(name)
+ Puppet::Node::Facts.version(name)
+ end
+
private
# Turn our outputted objects into a Puppet::Node instance.
def create_node(name, result)
node = Puppet::Node.new(name)
set = false
- [:parameters, :classes].each do |param|
+ [:parameters, :classes, :environment].each do |param|
if value = result[param]
node.send(param.to_s + "=", value)
set = true
diff --git a/lib/puppet/indirector/node/ldap.rb b/lib/puppet/indirector/node/ldap.rb
index dd11f4e9b..73b5cdd70 100644
--- a/lib/puppet/indirector/node/ldap.rb
+++ b/lib/puppet/indirector/node/ldap.rb
@@ -7,7 +7,8 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
# The attributes that Puppet class information is stored in.
def class_attributes
- Puppet[:ldapclassattrs].split(/\s*,\s*/)
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = Puppet[:ldapclassattrs].split(/\s*,\s*/)
end
# Look for our node in ldap.
@@ -36,11 +37,14 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
information[:parameters][param] = value unless information[:parameters].include?(param)
end
+ information[:environment] ||= parent_info[:environment]
+
parent = parent_info[:parent]
end
node.classes = information[:classes].uniq unless information[:classes].empty?
node.parameters = information[:parameters] unless information[:parameters].empty?
+ node.environment = information[:environment] if information[:environment]
node.fact_merge
return node
@@ -87,6 +91,8 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
hash
end
+ result[:environment] = result[:parameters]["environment"] if result[:parameters]["environment"]
+
return result
end
@@ -117,4 +123,8 @@ class Puppet::Node::Ldap < Puppet::Indirector::Ldap
end
filter
end
+
+ def version(name)
+ Puppet::Node::Facts.version(name)
+ end
end
diff --git a/lib/puppet/indirector/node/plain.rb b/lib/puppet/indirector/node/plain.rb
index d60cc3aa5..8058563e6 100644
--- a/lib/puppet/indirector/node/plain.rb
+++ b/lib/puppet/indirector/node/plain.rb
@@ -16,4 +16,11 @@ class Puppet::Node::Plain < Puppet::Indirector::Plain
node.fact_merge
node
end
+
+ # Use the version of the facts, since we assume that's the main thing
+ # that changes. If someone wants their own way of defining version,
+ # they can easily provide their own, um, version of this class.
+ def version(name)
+ Puppet::Node::Facts.version(name)
+ end
end
diff --git a/lib/puppet/indirector/report/processor.rb b/lib/puppet/indirector/report/processor.rb
index fd1bc413a..fa2b7f36b 100644
--- a/lib/puppet/indirector/report/processor.rb
+++ b/lib/puppet/indirector/report/processor.rb
@@ -45,6 +45,7 @@ class Puppet::Transaction::Report::Processor < Puppet::Indirector::Code
# Handle the parsing of the reports attribute.
def reports
- Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
end
end
diff --git a/lib/puppet/indirector/terminus.rb b/lib/puppet/indirector/terminus.rb
index a0623b284..3015c8a37 100644
--- a/lib/puppet/indirector/terminus.rb
+++ b/lib/puppet/indirector/terminus.rb
@@ -66,6 +66,7 @@ class Puppet::Indirector::Terminus
subclass.terminus_type = self.name
# Our subclass is specifically associated with an indirection.
+ raise("Invalid name %s" % longname) unless names.length > 0
indirection_name = names.pop.sub(/^[A-Z]/) { |i| i.downcase }.gsub(/[A-Z]/) { |i| "_" + i.downcase }.intern
if indirection_name == "" or indirection_name.nil?
diff --git a/lib/puppet/indirector/yaml.rb b/lib/puppet/indirector/yaml.rb
index 16816d941..4dd29159e 100644
--- a/lib/puppet/indirector/yaml.rb
+++ b/lib/puppet/indirector/yaml.rb
@@ -2,11 +2,6 @@ require 'puppet/indirector/terminus'
# The base class for YAML indirection termini.
class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
- def initialize
- # Make sure our base directory exists.
- Puppet.settings.use(:yaml)
- end
-
# Read a given name's file in and convert it from YAML.
def find(name)
raise ArgumentError.new("You must specify the name of the object to retrieve") unless name
@@ -40,6 +35,11 @@ class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
end
end
+ def version(name)
+ return nil unless FileTest.exist?(path(name))
+ return File.stat(path(name)).mtime
+ end
+
private
def from_yaml(text)
diff --git a/lib/puppet/metatype/closure.rb b/lib/puppet/metatype/closure.rb
index 259854411..673a2359d 100644
--- a/lib/puppet/metatype/closure.rb
+++ b/lib/puppet/metatype/closure.rb
@@ -20,6 +20,10 @@ class Puppet::Type
end
end
+ def isomorphic?
+ self.class.isomorphic?
+ end
+
# is the instance a managed instance? A 'yes' here means that
# the instance was created from the language, vs. being created
# in order resolve other questions, such as finding a package
diff --git a/lib/puppet/metatype/evaluation.rb b/lib/puppet/metatype/evaluation.rb
index b3b6570b2..ff1eddb55 100644
--- a/lib/puppet/metatype/evaluation.rb
+++ b/lib/puppet/metatype/evaluation.rb
@@ -4,6 +4,11 @@ class Puppet::Type
# This returns any changes resulting from testing, thus 'collect' rather
# than 'each'.
def evaluate
+ if self.provider.is_a?(Puppet::Provider)
+ unless provider.class.suitable?
+ raise Puppet::Error, "Provider %s is not functional on this platform" % provider.class.name
+ end
+ end
#Puppet.err "Evaluating %s" % self.path.join(":")
unless defined? @evalcount
self.err "No evalcount defined on '%s' of type '%s'" %
@@ -108,7 +113,11 @@ class Puppet::Type
# Are we running in noop mode?
def noop?
- @noop || Puppet[:noop]
+ if defined?(@noop)
+ @noop
+ else
+ Puppet[:noop]
+ end
end
def noop
@@ -121,30 +130,23 @@ class Puppet::Type
# the other properties matter.
changes = []
ensureparam = @parameters[:ensure]
- if @parameters.include?(:ensure) && !currentvalues.include?(ensureparam)
+
+ # This allows resource types to have 'ensure' be a parameter, which allows them to
+ # just pass the parameter on to other generated resources.
+ ensureparam = nil unless ensureparam.is_a?(Puppet::Property)
+ if ensureparam && !currentvalues.include?(ensureparam)
raise Puppet::DevError, "Parameter ensure defined but missing from current values"
end
- if @parameters.include?(:ensure) and ! ensureparam.insync?(currentvalues[ensureparam])
-# self.info "ensuring %s from %s" %
-# [@parameters[:ensure].should, @parameters[:ensure].is]
+
+ if ensureparam and ! ensureparam.insync?(currentvalues[ensureparam])
changes << Puppet::PropertyChange.new(ensureparam, currentvalues[ensureparam])
# Else, if the 'ensure' property is correctly absent, then do
# nothing
- elsif @parameters.include?(:ensure) and currentvalues[ensureparam] == :absent
- # self.info "Object is correctly absent"
+ elsif ensureparam and currentvalues[ensureparam] == :absent
return []
else
-# if @parameters.include?(:ensure)
-# self.info "ensure: Is: %s, Should: %s" %
-# [@parameters[:ensure].is, @parameters[:ensure].should]
-# else
-# self.info "no ensure property"
-# end
changes = properties().find_all { |property|
- unless currentvalues.include?(property)
- raise Puppet::DevError, "Property %s does not have a current value",
- [property.name]
- end
+ currentvalues[property] ||= :absent
! property.insync?(currentvalues[property])
}.collect { |property|
Puppet::PropertyChange.new(property, currentvalues[property])
@@ -152,10 +154,7 @@ class Puppet::Type
end
if Puppet[:debug] and changes.length > 0
- self.debug("Changing " + changes.collect { |ch|
- ch.property.name
- }.join(",")
- )
+ self.debug("Changing " + changes.collect { |ch| ch.property.name }.join(","))
end
changes
diff --git a/lib/puppet/metatype/metaparams.rb b/lib/puppet/metatype/metaparams.rb
index 9e4cb089c..bf64d3a93 100644
--- a/lib/puppet/metatype/metaparams.rb
+++ b/lib/puppet/metatype/metaparams.rb
@@ -255,7 +255,7 @@ class Puppet::Type
@value.each do |value|
unless @resource.catalog.resource(*value)
description = self.class.direction == :in ? "dependency" : "dependent"
- raise Puppet::Error, "Could not find #{description} %s[%s]" % [value[0].to_s.capitalize, value[1]]
+ fail Puppet::Error, "Could not find #{description} %s[%s] for %s" % [value[0].to_s.capitalize, value[1], resource.ref]
end
end
end
@@ -373,7 +373,7 @@ class Puppet::Type
}
service { nagios:
running => true,
- subscribe => file[nagconf]
+ subscribe => File[nagconf]
}
}
@@ -390,7 +390,7 @@ class Puppet::Type
file { "/var/nagios/configuration":
source => "...",
recurse => true,
- before => exec["nagios-rebuid"]
+ before => Exec["nagios-rebuid"]
}
exec { "nagios-rebuild":
@@ -408,7 +408,7 @@ class Puppet::Type
file { "/etc/sshd_config":
source => "....",
- notify => service[sshd]
+ notify => Service[sshd]
}
service { sshd:
diff --git a/lib/puppet/metatype/providers.rb b/lib/puppet/metatype/providers.rb
index c302d9928..6308f7e54 100644
--- a/lib/puppet/metatype/providers.rb
+++ b/lib/puppet/metatype/providers.rb
@@ -188,15 +188,8 @@ class Puppet::Type
provider_class = provider_class.class.name
end
- if provider = @resource.class.provider(provider_class)
- unless provider.suitable?
- raise ArgumentError,
- "Provider '%s' is not functional on this platform" %
- [provider_class]
- end
- else
- raise ArgumentError, "Invalid %s provider '%s'" %
- [@resource.class.name, provider_class]
+ unless provider = @resource.class.provider(provider_class)
+ raise ArgumentError, "Invalid %s provider '%s'" % [@resource.class.name, provider_class]
end
end
diff --git a/lib/puppet/network.rb b/lib/puppet/network.rb
new file mode 100644
index 000000000..8993b8869
--- /dev/null
+++ b/lib/puppet/network.rb
@@ -0,0 +1,3 @@
+# Just a stub, so we can correctly scope other classes.
+module Puppet::Network # :nodoc:
+end
diff --git a/lib/puppet/network/authstore.rb b/lib/puppet/network/authstore.rb
index c16bef32f..cb1fdc57d 100755
--- a/lib/puppet/network/authstore.rb
+++ b/lib/puppet/network/authstore.rb
@@ -235,7 +235,8 @@ module Puppet
# Convert the name to a common pattern.
def munge_name(name)
- name.downcase.split(".").reverse
+ # LAK:NOTE http://snurl.com/21zf8 [groups_google_com]
+ x = name.downcase.split(".").reverse
end
# Parse our input pattern and figure out what kind of allowal
diff --git a/lib/puppet/network/client.rb b/lib/puppet/network/client.rb
index 283436e95..478883959 100644
--- a/lib/puppet/network/client.rb
+++ b/lib/puppet/network/client.rb
@@ -7,6 +7,8 @@ require 'puppet/util/subclass_loader'
require 'puppet/util/methodhelper'
require 'puppet/sslcertificates/support'
+require 'puppet/network/handler'
+
require 'net/http'
# Some versions of ruby don't have this method defined, which basically causes
@@ -94,10 +96,9 @@ class Puppet::Network::Client
self.read_cert
# We have to start the HTTP connection manually before we start
- # sending it requests or keep-alive won't work.
- if @driver.respond_to? :start
- @driver.start
- end
+ # sending it requests or keep-alive won't work. Note that with #1010,
+ # we don't currently actually want keep-alive.
+ @driver.start if @driver.respond_to? :start and Puppet::Network::HttpPool.keep_alive?
@local = false
elsif hash.include?(driverparam)
@@ -107,8 +108,7 @@ class Puppet::Network::Client
end
@local = true
else
- raise Puppet::Network::ClientError, "%s must be passed a Server or %s" %
- [self.class, driverparam]
+ raise Puppet::Network::ClientError, "%s must be passed a Server or %s" % [self.class, driverparam]
end
end
diff --git a/lib/puppet/network/client/master.rb b/lib/puppet/network/client/master.rb
index a920afec6..4c7fa5f5b 100644
--- a/lib/puppet/network/client/master.rb
+++ b/lib/puppet/network/client/master.rb
@@ -26,28 +26,32 @@ class Puppet::Network::Client::Master < Puppet::Network::Client
down = Puppet[:downcasefacts]
- facts = {}
- Facter.each { |name,fact|
+ facts = Facter.to_hash.inject({}) do |newhash, array|
+ name, fact = array
if down
- facts[name] = fact.to_s.downcase
+ newhash[name] = fact.to_s.downcase
else
- facts[name] = fact.to_s
+ newhash[name] = fact.to_s
end
- }
+ newhash
+ end
# Add our client version to the list of facts, so people can use it
# in their manifests
facts["clientversion"] = Puppet.version.to_s
# And add our environment as a fact.
- facts["environment"] = Puppet[:environment]
-
+ unless facts.include?("environment")
+ facts["environment"] = Puppet[:environment]
+ end
+
facts
end
# Return the list of dynamic facts as an array of symbols
def self.dynamic_facts
- Puppet.settings[:dynamicfacts].split(/\s*,\s*/).collect { |fact| fact.downcase }
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = Puppet.settings[:dynamicfacts].split(/\s*,\s*/).collect { |fact| fact.downcase }
end
# Cache the config
@@ -316,7 +320,8 @@ class Puppet::Network::Client::Master < Puppet::Network::Client
:group => Process.gid,
:purge => true,
:force => true,
- :backup => false
+ :backup => false,
+ :noop => false
}
if args[:ignore]
@@ -327,9 +332,6 @@ class Puppet::Network::Client::Master < Puppet::Network::Client
Puppet.info "Retrieving #{args[:name]}s"
- noop = Puppet[:noop]
- Puppet[:noop] = false
-
files = []
begin
Timeout::timeout(self.timeout) do
@@ -351,14 +353,6 @@ class Puppet::Network::Client::Master < Puppet::Network::Client
downconfig.clear
return files
- ensure
- # I can't imagine why this is necessary, but apparently at last one person has had problems with noop
- # being nil here.
- if noop.nil?
- Puppet[:noop] = false
- else
- Puppet[:noop] = noop
- end
end
# Retrieve facts from the central server.
@@ -431,7 +425,8 @@ class Puppet::Network::Client::Master < Puppet::Network::Client
end
def self.loadfacts
- Puppet[:factpath].split(":").each do |dir|
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = Puppet[:factpath].split(":").each do |dir|
loaddir(dir, "fact")
end
end
diff --git a/lib/puppet/network/handler/fileserver.rb b/lib/puppet/network/handler/fileserver.rb
index 3ee4721f3..183979429 100755
--- a/lib/puppet/network/handler/fileserver.rb
+++ b/lib/puppet/network/handler/fileserver.rb
@@ -5,6 +5,9 @@ require 'cgi'
require 'delegate'
require 'sync'
+require 'puppet/file_serving'
+require 'puppet/file_serving/metadata'
+
class Puppet::Network::Handler
AuthStoreError = Puppet::AuthStoreError
class FileServerError < Puppet::Error; end
@@ -59,40 +62,27 @@ class Puppet::Network::Handler
# Describe a given file. This returns all of the manageable aspects
# of that file.
- def describe(url, links = :ignore, client = nil, clientip = nil)
+ def describe(url, links = :follow, client = nil, clientip = nil)
links = links.intern if links.is_a? String
- if links == :manage
- raise Puppet::Network::Handler::FileServerError, "Cannot currently copy links"
- end
-
mount, path = convert(url, client, clientip)
- if client
- mount.debug "Describing %s for %s" % [url, client]
- end
+ mount.debug("Describing %s for %s" % [url, client]) if client
- obj = nil
- unless obj = mount.getfileobject(path, links, client)
+ # use the mount to resolve the path for us.
+ metadata = Puppet::FileServing::Metadata.new(url, :path => mount.file_path(path, client), :links => links)
+
+ return "" unless metadata.exist?
+
+ begin
+ metadata.collect_attributes
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err detail
return ""
end
- currentvalues = mount.check(obj)
-
- desc = []
- CHECKPARAMS.each { |check|
- if value = currentvalues[check]
- desc << value
- else
- if check == "checksum" and currentvalues[:type] == "file"
- mount.notice "File %s does not have data for %s" %
- [obj.name, check]
- end
- desc << nil
- end
- }
-
- return desc.join("\t")
+ return metadata.attributes_with_tabs
end
# Create a new fileserving module.
@@ -140,26 +130,18 @@ class Puppet::Network::Handler
def list(url, links = :ignore, recurse = false, ignore = false, client = nil, clientip = nil)
mount, path = convert(url, client, clientip)
- if client
- mount.debug "Listing %s for %s" % [url, client]
- end
+ mount.debug "Listing %s for %s" % [url, client] if client
- obj = nil
- unless mount.path_exists?(path, client)
- return ""
- end
+ return "" unless mount.path_exists?(path, client)
desc = mount.list(path, recurse, ignore, client)
if desc.length == 0
- mount.notice "Got no information on //%s/%s" %
- [mount, path]
+ mount.notice "Got no information on //%s/%s" % [mount, path]
return ""
end
-
- desc.collect { |sub|
- sub.join("\t")
- }.join("\n")
+
+ desc.collect { |sub| sub.join("\t") }.join("\n")
end
def local?
@@ -213,12 +195,7 @@ class Puppet::Network::Handler
return ""
end
- str = nil
- if links == :manage
- raise Puppet::Error, "Cannot copy links yet."
- else
- str = mount.read_file(path, client)
- end
+ str = mount.read_file(path, client)
if @local
return str
@@ -452,55 +429,6 @@ class Puppet::Network::Handler
Puppet::Util.logmethods(self, true)
- def getfileobject(dir, links, client = nil)
- unless path_exists?(dir, client)
- self.debug "File source %s does not exist" % dir
- return nil
- end
-
- return fileobj(dir, links, client)
- end
-
- # Run 'retrieve' on a file. This gets the actual parameters, so
- # we can pass them to the client.
- def check(obj)
- # Retrieval is enough here, because we don't want to cache
- # any information in the state file, and we don't want to generate
- # any state changes or anything. We don't even need to sync
- # the checksum, because we're always going to hit the disk
- # directly.
-
- # We're now caching file data, using the LoadedFile to check the
- # disk no more frequently than the :filetimeout.
- path = obj[:path]
- sync = sync(path)
- unless data = @@files[path]
- data = {}
- sync.synchronize(Sync::EX) do
- @@files[path] = data
- data[:loaded_obj] = Puppet::Util::LoadedFile.new(path)
- data[:values] = properties(obj)
- return data[:values]
- end
- end
-
- changed = nil
- sync.synchronize(Sync::SH) do
- changed = data[:loaded_obj].changed?
- end
-
- if changed
- sync.synchronize(Sync::EX) do
- data[:values] = properties(obj)
- return data[:values]
- end
- else
- sync.synchronize(Sync::SH) do
- return data[:values]
- end
- end
- end
-
# Create a map for a specific client.
def clientmap(client)
{
diff --git a/lib/puppet/network/handler/master.rb b/lib/puppet/network/handler/master.rb
index 8d84fe8b8..dabfaca50 100644
--- a/lib/puppet/network/handler/master.rb
+++ b/lib/puppet/network/handler/master.rb
@@ -82,6 +82,8 @@ class Puppet::Network::Handler
if Puppet[:node_name] == 'cert'
if name
client = name
+ facts["fqdn"] = client
+ facts["hostname"], facts["domain"] = client.split('.', 2)
end
if ip
clientip = ip
diff --git a/lib/puppet/network/handler/report.rb b/lib/puppet/network/handler/report.rb
index 8ddeed9f6..b92b77ea5 100755
--- a/lib/puppet/network/handler/report.rb
+++ b/lib/puppet/network/handler/report.rb
@@ -79,7 +79,8 @@ class Puppet::Network::Handler
# Handle the parsing of the reports attribute.
def reports
- Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = Puppet[:reports].gsub(/(^\s+)|(\s+$)/, '').split(/\s*,\s*/)
end
end
end
diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb
index db63613ab..6c24e360c 100644
--- a/lib/puppet/network/http/mongrel/rest.rb
+++ b/lib/puppet/network/http/mongrel/rest.rb
@@ -14,11 +14,13 @@ class Puppet::Network::HTTP::MongrelREST < Puppet::Network::HTTP::Handler
end
def path(request)
- '/' + request.params[Mongrel::Const::REQUEST_PATH].split('/')[1]
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = '/' + request.params[Mongrel::Const::REQUEST_PATH].split('/')[1]
end
def request_key(request)
- request.params[Mongrel::Const::REQUEST_PATH].split('/')[2]
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = request.params[Mongrel::Const::REQUEST_PATH].split('/')[2]
end
def body(request)
diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb
index dd0c84d61..8cda079e2 100644
--- a/lib/puppet/network/http/webrick/rest.rb
+++ b/lib/puppet/network/http/webrick/rest.rb
@@ -19,11 +19,13 @@ class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler
end
def path(request)
- '/' + request.path.split('/')[1]
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = '/' + request.path.split('/')[1]
end
def request_key(request)
- request.path.split('/')[2]
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = request.path.split('/')[2]
end
def body(request)
@@ -38,4 +40,4 @@ class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler
response.status = status
response.body = result
end
-end \ No newline at end of file
+end
diff --git a/lib/puppet/network/http_pool.rb b/lib/puppet/network/http_pool.rb
index 99f09a90c..9d37f2eeb 100644
--- a/lib/puppet/network/http_pool.rb
+++ b/lib/puppet/network/http_pool.rb
@@ -1,8 +1,20 @@
require 'puppet/sslcertificates/support'
require 'net/https'
+module Puppet::Network
+end
+
# Manage Net::HTTP instances for keep-alive.
module Puppet::Network::HttpPool
+ # 2008/03/23
+ # LAK:WARNING: Enabling this has a high propability of
+ # causing corrupt files and who knows what else. See #1010.
+ HTTP_KEEP_ALIVE = false
+
+ def self.keep_alive?
+ HTTP_KEEP_ALIVE
+ end
+
# This handles reading in the key and such-like.
extend Puppet::SSLCertificates::Support
@http_cache = {}
@@ -53,12 +65,14 @@ module Puppet::Network::HttpPool
# Return our cached instance if we've got a cache, as long as we're not
# resetting the instance.
- return @http_cache[key] if ! reset and @http_cache[key]
+ if keep_alive?
+ return @http_cache[key] if ! reset and @http_cache[key]
- # Clean up old connections if we have them.
- if http = @http_cache[key]
- @http_cache.delete(key)
- http.finish if http.started?
+ # Clean up old connections if we have them.
+ if http = @http_cache[key]
+ @http_cache.delete(key)
+ http.finish if http.started?
+ end
end
args = [host, port]
@@ -85,7 +99,7 @@ module Puppet::Network::HttpPool
cert_setup(http)
- @http_cache[key] = http
+ @http_cache[key] = http if keep_alive?
return http
end
diff --git a/lib/puppet/network/http_server/mongrel.rb b/lib/puppet/network/http_server/mongrel.rb
index d6e21b189..6b2325d29 100644
--- a/lib/puppet/network/http_server/mongrel.rb
+++ b/lib/puppet/network/http_server/mongrel.rb
@@ -33,6 +33,7 @@ require 'xmlrpc/server'
require 'puppet/network/xmlrpc/server'
require 'puppet/network/http_server'
require 'puppet/network/client_request'
+require 'puppet/network/handler'
require 'puppet/daemon'
require 'resolv'
@@ -127,7 +128,12 @@ module Puppet::Network
client = dn_matchdata[1].to_str
valid = (params[Puppet[:ssl_client_verify_header]] == 'SUCCESS')
else
- client = Resolv.getname(ip)
+ begin
+ client = Resolv.getname(ip)
+ rescue => detail
+ Puppet.err "Could not resolve %s: %s" % [ip, detail]
+ client = "unknown"
+ end
valid = false
end
diff --git a/lib/puppet/network/http_server/webrick.rb b/lib/puppet/network/http_server/webrick.rb
index 3c9f72e17..568b4e798 100644
--- a/lib/puppet/network/http_server/webrick.rb
+++ b/lib/puppet/network/http_server/webrick.rb
@@ -8,6 +8,7 @@ require 'puppet/sslcertificates/support'
require 'puppet/network/xmlrpc/webrick_servlet'
require 'puppet/network/http_server'
require 'puppet/network/client'
+require 'puppet/network/handler'
module Puppet
class ServerError < RuntimeError; end
@@ -22,12 +23,12 @@ module Puppet
# with them, with flags appropriate for checking client
# certificates for revocation
def x509store
- if Puppet[:cacrl] == 'none'
+ if Puppet[:cacrl] == 'false'
# No CRL, no store needed
return nil
end
unless File.exist?(Puppet[:cacrl])
- raise Puppet::Error, "Could not find CRL; set 'cacrl' to 'none' to disable CRL usage"
+ raise Puppet::Error, "Could not find CRL; set 'cacrl' to 'false' to disable CRL usage"
end
crl = OpenSSL::X509::CRL.new(File.read(Puppet[:cacrl]))
store = OpenSSL::X509::Store.new
@@ -133,7 +134,7 @@ module Puppet
handlers.collect { |handler, args|
hclass = nil
- unless hclass = Handler.handler(handler)
+ unless hclass = Puppet::Network::Handler.handler(handler)
raise ServerError, "Invalid handler %s" % handler
end
hclass.new(args)
diff --git a/lib/puppet/network/server.rb b/lib/puppet/network/server.rb
index 50e3bd686..f2c8dc18c 100644
--- a/lib/puppet/network/server.rb
+++ b/lib/puppet/network/server.rb
@@ -1,3 +1,5 @@
+require 'puppet/network/http'
+
class Puppet::Network::Server
attr_reader :server_type, :protocols, :address, :port
diff --git a/lib/puppet/network/xmlrpc/client.rb b/lib/puppet/network/xmlrpc/client.rb
index 27bb3dc5e..f6a5e8db6 100644
--- a/lib/puppet/network/xmlrpc/client.rb
+++ b/lib/puppet/network/xmlrpc/client.rb
@@ -90,6 +90,13 @@ module Puppet::Network
@clients[handler] || self.mkclient(handler)
end
+ def http
+ unless @http
+ @http = Puppet::Network::HttpPool.http_instance(@host, @port, true)
+ end
+ @http
+ end
+
def initialize(hash = {})
hash[:Path] ||= "/RPC2"
hash[:Server] ||= Puppet[:server]
@@ -125,7 +132,11 @@ module Puppet::Network
end
def start
- @http.start unless @http.started?
+ begin
+ @http.start unless @http.started?
+ rescue => detail
+ Puppet.err "Could not connect to server: %s" % detail
+ end
end
def local
diff --git a/lib/puppet/node.rb b/lib/puppet/node.rb
index c0628ecdc..252ab961e 100644
--- a/lib/puppet/node.rb
+++ b/lib/puppet/node.rb
@@ -161,5 +161,7 @@ class Puppet::Node
params.each do |name, value|
@parameters[name] = value unless @parameters.include?(name)
end
+
+ @parameters["environment"] ||= self.environment if self.environment
end
end
diff --git a/lib/puppet/node/catalog.rb b/lib/puppet/node/catalog.rb
index ff41031e1..77e845368 100644
--- a/lib/puppet/node/catalog.rb
+++ b/lib/puppet/node/catalog.rb
@@ -1,4 +1,8 @@
require 'puppet/indirector'
+require 'puppet/pgraph'
+require 'puppet/transaction'
+
+require 'puppet/util/tagging'
# This class models a node catalog. It is the thing
# meant to be passed from server to client, and it contains all
@@ -8,6 +12,8 @@ class Puppet::Node::Catalog < Puppet::PGraph
extend Puppet::Indirector
indirects :catalog, :terminus_class => :compiler
+ include Puppet::Util::Tagging
+
# The host name this is a catalog for.
attr_accessor :name
@@ -58,28 +64,32 @@ class Puppet::Node::Catalog < Puppet::PGraph
raise ArgumentError, "Can only add objects that respond to :ref"
end
+ fail_unless_unique(resource)
+
ref = resource.ref
- if @resource_table.include?(ref)
- raise ArgumentError, "Resource %s is already defined" % ref
- else
- @resource_table[ref] = resource
- end
- if resource.is_a?(Puppet::Type) and resource.class.isomorphic? and resource.title != resource.ref and resource.title != resource[:name]
- self.alias(resource, resource[:name])
+ @resource_table[ref] = resource
+
+ # If the name and title differ, set up an alias
+ #self.alias(resource, resource.name) if resource.respond_to?(:name) and resource.respond_to?(:title) and resource.name != resource.title
+ if resource.respond_to?(:name) and resource.respond_to?(:title) and resource.name != resource.title
+ self.alias(resource, resource.name) if resource.isomorphic?
end
- resource.catalog = self unless is_relationship_graph
- add_vertex!(resource)
+
+ resource.catalog = self if resource.respond_to?(:catalog=) and ! is_relationship_graph
+
+ add_vertex(resource)
end
end
# Create an alias for a resource.
def alias(resource, name)
+ #set $1
resource.ref =~ /^(.+)\[/
newref = "%s[%s]" % [$1 || resource.class.name, name]
- if res = @resource_table[newref]
- return if res == resource
+ if existing = @resource_table[newref]
+ return if existing == resource
raise(ArgumentError, "Cannot alias %s to %s; resource %s already exists" % [resource.ref, name, newref])
end
@resource_table[newref] = resource
@@ -275,7 +285,6 @@ class Puppet::Node::Catalog < Puppet::PGraph
super()
@name = name if name
@extraction_format ||= :transportable
- @tags = []
@classes = []
@resource_table = {}
@transient_resources = []
@@ -320,9 +329,9 @@ class Puppet::Node::Catalog < Puppet::PGraph
# First create the dependency graph
self.vertices.each do |vertex|
- @relationship_graph.add_vertex! vertex
+ @relationship_graph.add_vertex vertex
vertex.builddepends.each do |edge|
- @relationship_graph.add_edge!(edge)
+ @relationship_graph.add_edge(edge)
end
end
@@ -332,7 +341,7 @@ class Puppet::Node::Catalog < Puppet::PGraph
unless @relationship_graph.edge?(edge.source, edge.target) # don't let automatic relationships conflict with manual ones.
unless @relationship_graph.edge?(edge.target, edge.source)
vertex.debug "Autorequiring %s" % [edge.source]
- @relationship_graph.add_edge!(edge)
+ @relationship_graph.add_edge(edge)
else
vertex.debug "Skipping automatic relationship with %s" % (edge.source == vertex ? edge.target : edge.source)
end
@@ -388,25 +397,6 @@ class Puppet::Node::Catalog < Puppet::PGraph
@resource_table.keys
end
- # Add a tag.
- def tag(*names)
- names.each do |name|
- name = name.to_s
- @tags << name unless @tags.include?(name)
- if name.include?("::")
- name.split("::").each do |sub|
- @tags << sub unless @tags.include?(sub)
- end
- end
- end
- nil
- end
-
- # Return the list of tags.
- def tags
- @tags.dup
- end
-
# Convert our catalog into a RAL catalog.
def to_ral
to_catalog :to_type
@@ -454,6 +444,28 @@ class Puppet::Node::Catalog < Puppet::PGraph
end
end
+ # Verify that the given resource isn't defined elsewhere.
+ def fail_unless_unique(resource)
+ # Short-curcuit the common case,
+ return unless existing_resource = @resource_table[resource.ref]
+
+ # Either it's a defined type, which are never
+ # isomorphic, or it's a non-isomorphic type, so
+ # we should throw an exception.
+ msg = "Duplicate definition: %s is already defined" % resource.ref
+
+ if existing_resource.file and existing_resource.line
+ msg << " in file %s at line %s" %
+ [existing_resource.file, existing_resource.line]
+ end
+
+ if resource.line or resource.file
+ msg << "; cannot redefine"
+ end
+
+ raise ArgumentError.new(msg)
+ end
+
# An abstracted method for converting one catalog into another type of catalog.
# This pretty much just converts all of the resources from one class to another, using
# a conversion method.
@@ -464,6 +476,15 @@ class Puppet::Node::Catalog < Puppet::PGraph
vertices.each do |resource|
next if resource.respond_to?(:virtual?) and resource.virtual?
+ #This is hackity hack for 1094
+ #Aliases aren't working in the ral catalog because the current instance of the resource
+ #has a reference to the catalog being converted. . . So, give it a reference to the new one
+ #problem solved. . .
+ if resource.is_a?(Puppet::TransObject)
+ resource = resource.dup
+ resource.catalog = result
+ end
+
newres = resource.send(convert)
# We can't guarantee that resources don't munge their names
@@ -488,12 +509,12 @@ class Puppet::Node::Catalog < Puppet::PGraph
raise Puppet::DevError, "Could not find resource %s when converting %s resources" % [edge.target.ref, message]
end
- result.add_edge!(source, target, edge.label)
+ result.add_edge(source, target, edge.label)
end
map.clear
- result.add_class *self.classes
+ result.add_class(*self.classes)
result.tag(*self.tags)
return result
diff --git a/lib/puppet/node/environment.rb b/lib/puppet/node/environment.rb
index 2a314803f..343720a62 100644
--- a/lib/puppet/node/environment.rb
+++ b/lib/puppet/node/environment.rb
@@ -4,7 +4,8 @@ class Puppet::Node::Environment
# Return the list of valid environments. Just looks them up in
# the settings.
def self.valid
- Puppet.settings.value(:environments).split(",").collect { |e| e.to_sym }
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = Puppet.settings.value(:environments).split(",").collect { |e| e.to_sym }
end
# Is the provided environment valid?
diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb
index 14b686e2f..c9bd7c9e8 100644
--- a/lib/puppet/parser/ast.rb
+++ b/lib/puppet/parser/ast.rb
@@ -14,30 +14,6 @@ class Puppet::Parser::AST
include Puppet::Util::MethodHelper
attr_accessor :line, :file, :parent, :scope
- # Just used for 'tree', which is only used in debugging.
- @@pink = ""
- @@green = ""
- @@yellow = ""
- @@slate = ""
- @@reset = ""
-
- # Just used for 'tree', which is only used in debugging.
- @@indent = " " * 4
- @@indline = @@pink + ("-" * 4) + @@reset
- @@midline = @@slate + ("-" * 4) + @@reset
-
- @@settypes = {}
-
- # Just used for 'tree', which is only used in debugging.
- def AST.indention
- return @@indent * @@indention
- end
-
- # Just used for 'tree', which is only used in debugging.
- def AST.midline
- return @@midline
- end
-
# Does this ast object set something? If so, it gets evaluated first.
def self.settor?
if defined? @settor
@@ -47,16 +23,12 @@ class Puppet::Parser::AST
end
end
- # Evaluate the current object. Basically just iterates across all
+ # Evaluate the current object. Just a stub method, since the subclass
+ # should override this method.
# of the contained children and evaluates them in turn, returning a
# list of all of the collected values, rejecting nil values
- def evaluate(args)
- #Puppet.debug("Evaluating ast %s" % @name)
- value = self.collect { |obj|
- obj.safeevaluate(args)
- }.reject { |obj|
- obj.nil?
- }
+ def evaluate(*options)
+ raise Puppet::DevError, "Did not override #evaluate in %s" % self.class
end
# Throw a parse error.
@@ -75,11 +47,11 @@ class Puppet::Parser::AST
# correctly handles errors. It is critical to use this method because
# it can enable you to catch the error where it happens, rather than
# much higher up the stack.
- def safeevaluate(options)
+ def safeevaluate(*options)
# We duplicate code here, rather than using exceptwrap, because this
# is called so many times during parsing.
begin
- return self.evaluate(options)
+ return self.evaluate(*options)
rescue Puppet::Error => detail
raise adderrorcontext(detail)
rescue => detail
@@ -90,14 +62,6 @@ class Puppet::Parser::AST
end
end
- # Again, just used for printing out the parse tree.
- def typewrap(string)
- #return self.class.to_s.sub(/.+::/,'') +
- #"(" + @@green + string.to_s + @@reset + ")"
- return @@green + string.to_s + @@reset +
- "(" + self.class.to_s.sub(/.+::/,'') + ")"
- end
-
# Initialize the object. Requires a hash as the argument, and
# takes each of the parameters of the hash and calls the settor
# method for them. This is probably pretty inefficient and should
@@ -107,13 +71,27 @@ class Puppet::Parser::AST
@line = nil
set_options(args)
end
- #---------------------------------------------------------------
- # Now autoload everything.
- @autoloader = Puppet::Util::Autoload.new(self,
- "puppet/parser/ast"
- )
- @autoloader.loadall
end
+# And include all of the AST subclasses.
+require 'puppet/parser/ast/astarray'
+require 'puppet/parser/ast/branch'
+require 'puppet/parser/ast/caseopt'
+require 'puppet/parser/ast/casestatement'
+require 'puppet/parser/ast/collection'
+require 'puppet/parser/ast/collexpr'
+require 'puppet/parser/ast/definition'
+require 'puppet/parser/ast/else'
+require 'puppet/parser/ast/function'
+require 'puppet/parser/ast/hostclass'
+require 'puppet/parser/ast/ifstatement'
require 'puppet/parser/ast/leaf'
-
+require 'puppet/parser/ast/node'
+require 'puppet/parser/ast/resource'
+require 'puppet/parser/ast/resource_defaults'
+require 'puppet/parser/ast/resource_override'
+require 'puppet/parser/ast/resource_reference'
+require 'puppet/parser/ast/resourceparam'
+require 'puppet/parser/ast/selector'
+require 'puppet/parser/ast/tag'
+require 'puppet/parser/ast/vardef'
diff --git a/lib/puppet/parser/ast/astarray.rb b/lib/puppet/parser/ast/astarray.rb
index 5f1e838d0..8f09aa922 100644
--- a/lib/puppet/parser/ast/astarray.rb
+++ b/lib/puppet/parser/ast/astarray.rb
@@ -15,18 +15,7 @@ class Puppet::Parser::AST
end
# Evaluate our children.
- def evaluate(hash)
- scope = hash[:scope]
- rets = nil
- # We basically always operate declaratively, and when we
- # do we need to evaluate the settor-like statements first. This
- # is basically variable and type-default declarations.
- # This is such a stupid hack. I've no real idea how to make a
- # "real" declarative language, so I hack it so it looks like
- # one, yay.
- settors = []
- others = []
-
+ def evaluate(scope)
# Make a new array, so we don't have to deal with the details of
# flattening and such
items = []
@@ -35,23 +24,15 @@ class Puppet::Parser::AST
@children.each { |child|
if child.instance_of?(AST::ASTArray)
child.each do |ac|
- if ac.class.settor?
- settors << ac
- else
- others << ac
- end
+ items << ac
end
else
- if child.class.settor?
- settors << child
- else
- others << child
- end
+ items << child
end
}
- rets = [settors, others].flatten.collect { |child|
- child.safeevaluate(:scope => scope)
+ rets = items.flatten.collect { |child|
+ child.safeevaluate(scope)
}
return rets.reject { |o| o.nil? }
end
diff --git a/lib/puppet/parser/ast/caseopt.rb b/lib/puppet/parser/ast/caseopt.rb
index d1d9d0e9c..824bde853 100644
--- a/lib/puppet/parser/ast/caseopt.rb
+++ b/lib/puppet/parser/ast/caseopt.rb
@@ -44,17 +44,17 @@ class Puppet::Parser::AST
def eachvalue(scope)
if @value.is_a?(AST::ASTArray)
@value.each { |subval|
- yield subval.evaluate(:scope => scope)
+ yield subval.safeevaluate(scope)
}
else
- yield @value.evaluate(:scope => scope)
+ yield @value.safeevaluate(scope)
end
end
# Evaluate the actual statements; this only gets called if
# our option matched.
- def evaluate(hash)
- return @statements.safeevaluate(hash)
+ def evaluate(scope)
+ return @statements.safeevaluate(scope)
end
end
end
diff --git a/lib/puppet/parser/ast/casestatement.rb b/lib/puppet/parser/ast/casestatement.rb
index 3c6f9c7e2..aa03090de 100644
--- a/lib/puppet/parser/ast/casestatement.rb
+++ b/lib/puppet/parser/ast/casestatement.rb
@@ -8,9 +8,8 @@ class Puppet::Parser::AST
# Short-curcuit evaluation. Return the value of the statements for
# the first option that matches.
- def evaluate(hash)
- scope = hash[:scope]
- value = @test.safeevaluate(:scope => scope)
+ def evaluate(scope)
+ value = @test.safeevaluate(scope)
sensitive = Puppet[:casesensitive]
value = value.downcase if ! sensitive and value.respond_to?(:downcase)
@@ -30,7 +29,7 @@ class Puppet::Parser::AST
if found
# we found a matching option
- retvalue = option.safeevaluate(:scope => scope)
+ retvalue = option.safeevaluate(scope)
break
end
@@ -42,7 +41,7 @@ class Puppet::Parser::AST
# Unless we found something, look for the default.
unless found
if default
- retvalue = default.safeevaluate(:scope => scope)
+ retvalue = default.safeevaluate(scope)
else
Puppet.debug "No true answers and no default"
retvalue = nil
diff --git a/lib/puppet/parser/ast/collection.rb b/lib/puppet/parser/ast/collection.rb
index e05977a47..9e795a33c 100644
--- a/lib/puppet/parser/ast/collection.rb
+++ b/lib/puppet/parser/ast/collection.rb
@@ -9,18 +9,16 @@ class Collection < AST::Branch
attr_accessor :type, :query, :form
# We return an object that does a late-binding evaluation.
- def evaluate(hash)
- scope = hash[:scope]
-
+ def evaluate(scope)
if self.query
- str, code = self.query.safeevaluate :scope => scope
+ str, code = self.query.safeevaluate scope
else
str = code = nil
end
newcoll = Puppet::Parser::Collector.new(scope, @type, str, code, self.form)
- scope.compile.add_collection(newcoll)
+ scope.compiler.add_collection(newcoll)
newcoll
end
diff --git a/lib/puppet/parser/ast/collexpr.rb b/lib/puppet/parser/ast/collexpr.rb
index 4a96d9c61..3e13d9400 100644
--- a/lib/puppet/parser/ast/collexpr.rb
+++ b/lib/puppet/parser/ast/collexpr.rb
@@ -9,9 +9,7 @@ class CollExpr < AST::Branch
attr_accessor :test1, :test2, :oper, :form, :type, :parens
# We return an object that does a late-binding evaluation.
- def evaluate(hash)
- scope = hash[:scope]
-
+ def evaluate(scope)
# Make sure our contained expressions have all the info they need.
[@test1, @test2].each do |t|
if t.is_a?(self.class)
@@ -21,8 +19,8 @@ class CollExpr < AST::Branch
end
# The code is only used for virtual lookups
- str1, code1 = @test1.safeevaluate :scope => scope
- str2, code2 = @test2.safeevaluate :scope => scope
+ str1, code1 = @test1.safeevaluate scope
+ str2, code2 = @test2.safeevaluate scope
# First build up the virtual code.
# If we're a conjunction operator, then we're calling code. I did
diff --git a/lib/puppet/parser/ast/definition.rb b/lib/puppet/parser/ast/definition.rb
index 3d6d6188c..0c65c702c 100644
--- a/lib/puppet/parser/ast/definition.rb
+++ b/lib/puppet/parser/ast/definition.rb
@@ -1,155 +1,145 @@
require 'puppet/parser/ast/branch'
-class Puppet::Parser::AST
- # Evaluate the stored parse tree for a given component. This will
- # receive the arguments passed to the component and also the type and
- # name of the component.
- class Definition < AST::Branch
- include Puppet::Util
- include Puppet::Util::Warnings
- include Puppet::Util::MethodHelper
- class << self
- attr_accessor :name
- end
+require 'puppet/util/warnings'
- # The class name
- @name = :definition
+# The AST class for defined types, which is also the base class
+# nodes and classes.
+class Puppet::Parser::AST::Definition < Puppet::Parser::AST::Branch
+ include Puppet::Util::Warnings
+ class << self
+ attr_accessor :name
+ end
- attr_accessor :classname, :arguments, :code, :scope, :keyword
- attr_accessor :exported, :namespace, :parser, :virtual
+ # The class name
+ @name = :definition
- # These are retrieved when looking up the superclass
- attr_accessor :name
+ attr_accessor :classname, :arguments, :code, :scope, :keyword
+ attr_accessor :exported, :namespace, :parser, :virtual, :name
- attr_reader :parentclass
+ attr_reader :parentclass
- def child_of?(klass)
- false
- end
+ def child_of?(klass)
+ false
+ end
- def evaluate(options)
- origscope = options[:scope]
- resource = options[:resource]
+ # Create a resource that knows how to evaluate our actual code.
+ def evaluate(scope)
+ resource = Puppet::Parser::Resource.new(:type => self.class.name, :title => self.classname, :scope => scope, :source => scope.source)
- # Create a new scope.
- scope = subscope(origscope, resource)
+ scope.catalog.tag(*resource.tags)
- # Additionally, add a tag for whatever kind of class
- # we are
- if @classname != "" and ! @classname.nil?
- @classname.split(/::/).each { |tag| scope.resource.tag(tag) }
- end
+ scope.compiler.add_resource(scope, resource)
- [resource.name, resource.title].each do |str|
- unless str.nil? or str =~ /[^\w]/ or str == ""
- scope.resource.tag(str)
- end
- end
+ return resource
+ end
- set_resource_parameters(scope, resource)
+ # Now evaluate the code associated with this class or definition.
+ def evaluate_code(resource)
+ # Create a new scope.
+ scope = subscope(resource.scope, resource)
- if self.code
- return self.code.safeevaluate(:scope => scope)
- else
- return nil
- end
+ set_resource_parameters(scope, resource)
+
+ if self.code
+ return self.code.safeevaluate(scope)
+ else
+ return nil
end
+ end
- def initialize(hash = {})
- @arguments = nil
- @parentclass = nil
- super
+ def initialize(hash = {})
+ @arguments = nil
+ @parentclass = nil
+ super
- # Convert the arguments to a hash for ease of later use.
- if @arguments
- unless @arguments.is_a? Array
- @arguments = [@arguments]
- end
- oldargs = @arguments
- @arguments = {}
- oldargs.each do |arg, val|
- @arguments[arg] = val
- end
- else
- @arguments = {}
+ # Convert the arguments to a hash for ease of later use.
+ if @arguments
+ unless @arguments.is_a? Array
+ @arguments = [@arguments]
end
-
- # Deal with metaparams in the argument list.
- @arguments.each do |arg, defvalue|
- next unless Puppet::Type.metaparamclass(arg)
- if defvalue
- warnonce "%s is a metaparam; this value will inherit to all contained resources" % arg
- else
- raise Puppet::ParseError, "%s is a metaparameter; please choose another parameter name in the %s definition" % [arg, self.classname]
- end
+ oldargs = @arguments
+ @arguments = {}
+ oldargs.each do |arg, val|
+ @arguments[arg] = val
end
+ else
+ @arguments = {}
end
- def find_parentclass
- @parser.findclass(namespace, parentclass)
+ # Deal with metaparams in the argument list.
+ @arguments.each do |arg, defvalue|
+ next unless Puppet::Type.metaparamclass(arg)
+ if defvalue
+ warnonce "%s is a metaparam; this value will inherit to all contained resources" % arg
+ else
+ raise Puppet::ParseError, "%s is a metaparameter; please choose another parameter name in the %s definition" % [arg, self.classname]
+ end
end
+ end
- # Set our parent class, with a little check to avoid some potential
- # weirdness.
- def parentclass=(name)
- if name == self.classname
- parsefail "Parent classes must have dissimilar names"
- end
+ def find_parentclass
+ @parser.findclass(namespace, parentclass)
+ end
- @parentclass = name
+ # Set our parent class, with a little check to avoid some potential
+ # weirdness.
+ def parentclass=(name)
+ if name == self.classname
+ parsefail "Parent classes must have dissimilar names"
end
- # Hunt down our class object.
- def parentobj
- if @parentclass
- # Cache our result, since it should never change.
- unless defined?(@parentobj)
- unless tmp = find_parentclass
- parsefail "Could not find %s %s" % [self.class.name, @parentclass]
- end
+ @parentclass = name
+ end
- if tmp == self
- parsefail "Parent classes must have dissimilar names"
- end
+ # Hunt down our class object.
+ def parentobj
+ return nil unless @parentclass
- @parentobj = tmp
- end
- @parentobj
- else
- nil
+ # Cache our result, since it should never change.
+ unless defined?(@parentobj)
+ unless tmp = find_parentclass
+ parsefail "Could not find %s parent %s" % [self.class.name, @parentclass]
end
+
+ if tmp == self
+ parsefail "Parent classes must have dissimilar names"
+ end
+
+ @parentobj = tmp
end
+ @parentobj
+ end
- # Create a new subscope in which to evaluate our code.
- def subscope(scope, resource)
- args = {
- :resource => resource,
- :keyword => self.keyword,
- :namespace => self.namespace,
- :source => self
- }
+ # Create a new subscope in which to evaluate our code.
+ def subscope(scope, resource)
+ args = {
+ :resource => resource,
+ :keyword => self.keyword,
+ :namespace => self.namespace,
+ :source => self
+ }
- oldscope = scope
- scope = scope.newscope(args)
- scope.source = self
+ oldscope = scope
+ scope = scope.newscope(args)
+ scope.source = self
- return scope
- end
+ return scope
+ end
- def to_s
- classname
- end
+ def to_s
+ classname
+ end
- # Check whether a given argument is valid. Searches up through
- # any parent classes that might exist.
- def validattr?(param)
- param = param.to_s
+ # Check whether a given argument is valid. Searches up through
+ # any parent classes that might exist.
+ def validattr?(param)
+ param = param.to_s
- if @arguments.include?(param)
- # It's a valid arg for us
- return true
- elsif param == "name"
- return true
+ if @arguments.include?(param)
+ # It's a valid arg for us
+ return true
+ elsif param == "name"
+ return true
# elsif defined? @parentclass and @parentclass
# # Else, check any existing parent
# if parent = @scope.lookuptype(@parentclass) and parent != []
@@ -160,53 +150,52 @@ class Puppet::Parser::AST
# raise Puppet::Error, "Could not find parent class %s" %
# @parentclass
# end
- elsif Puppet::Type.metaparam?(param)
- return true
- else
- # Or just return false
- return false
- end
+ elsif Puppet::Type.metaparam?(param)
+ return true
+ else
+ # Or just return false
+ return false
end
+ end
- private
-
- # Set any arguments passed by the resource as variables in the scope.
- def set_resource_parameters(scope, resource)
- args = symbolize_options(resource.to_hash || {})
-
- # Verify that all required arguments are either present or
- # have been provided with defaults.
- if self.arguments
- self.arguments.each { |arg, default|
- arg = symbolize(arg)
- unless args.include?(arg)
- if defined? default and ! default.nil?
- default = default.safeevaluate :scope => scope
- args[arg] = default
- #Puppet.debug "Got default %s for %s in %s" %
- # [default.inspect, arg.inspect, @name.inspect]
- else
- parsefail "Must pass %s to %s of type %s" %
- [arg, resource.title, @classname]
- end
+ private
+
+ # Set any arguments passed by the resource as variables in the scope.
+ def set_resource_parameters(scope, resource)
+ args = symbolize_options(resource.to_hash || {})
+
+ # Verify that all required arguments are either present or
+ # have been provided with defaults.
+ if self.arguments
+ self.arguments.each { |arg, default|
+ arg = arg.to_sym
+ unless args.include?(arg)
+ if defined? default and ! default.nil?
+ default = default.safeevaluate scope
+ args[arg] = default
+ #Puppet.debug "Got default %s for %s in %s" %
+ # [default.inspect, arg.inspect, @name.inspect]
+ else
+ parsefail "Must pass %s to %s of type %s" %
+ [arg, resource.title, @classname]
end
- }
- end
-
- # Set each of the provided arguments as variables in the
- # definition's scope.
- args.each { |arg,value|
- unless validattr?(arg)
- parsefail "%s does not accept attribute %s" % [@classname, arg]
- end
-
- exceptwrap do
- scope.setvar(arg.to_s, args[arg])
end
}
-
- scope.setvar("title", resource.title) unless args.include? :title
- scope.setvar("name", resource.name) unless args.include? :name
end
+
+ # Set each of the provided arguments as variables in the
+ # definition's scope.
+ args.each { |arg,value|
+ unless validattr?(arg)
+ parsefail "%s does not accept attribute %s" % [@classname, arg]
+ end
+
+ exceptwrap do
+ scope.setvar(arg.to_s, args[arg])
+ end
+ }
+
+ scope.setvar("title", resource.title) unless args.include? :title
+ scope.setvar("name", resource.name) unless args.include? :name
end
end
diff --git a/lib/puppet/parser/ast/else.rb b/lib/puppet/parser/ast/else.rb
index e76051372..affac625d 100644
--- a/lib/puppet/parser/ast/else.rb
+++ b/lib/puppet/parser/ast/else.rb
@@ -12,9 +12,8 @@ class Puppet::Parser::AST
# Evaluate the actual statements; this only gets called if
# our test was true matched.
- def evaluate(hash)
- scope = hash[:scope]
- return @statements.safeevaluate(:scope => scope)
+ def evaluate(scope)
+ return @statements.safeevaluate(scope)
end
end
end
diff --git a/lib/puppet/parser/ast/function.rb b/lib/puppet/parser/ast/function.rb
index 0cd1fff62..63d7c7abf 100644
--- a/lib/puppet/parser/ast/function.rb
+++ b/lib/puppet/parser/ast/function.rb
@@ -7,18 +7,11 @@ class Puppet::Parser::AST
@settor = true
- def evaluate(hash)
+ def evaluate(scope)
# We don't need to evaluate the name, because it's plaintext
+ args = @arguments.safeevaluate(scope)
- # Just evaluate the arguments
- scope = hash[:scope]
-
- args = @arguments.safeevaluate(:scope => scope)
-
- #exceptwrap :message => "Failed to execute %s" % @name,
- # :type => Puppet::ParseError do
- return scope.send("function_" + @name, args)
- #end
+ return scope.send("function_" + @name, args)
end
def initialize(hash)
diff --git a/lib/puppet/parser/ast/hostclass.rb b/lib/puppet/parser/ast/hostclass.rb
index 63900d0e3..7f89f8151 100644
--- a/lib/puppet/parser/ast/hostclass.rb
+++ b/lib/puppet/parser/ast/hostclass.rb
@@ -1,80 +1,87 @@
require 'puppet/parser/ast/definition'
-class Puppet::Parser::AST
- # The code associated with a class. This is different from definitions
- # in that each class is a singleton -- only one will exist for a given
- # node.
- class HostClass < AST::Definition
- @name = :class
+# The code associated with a class. This is different from definitions
+# in that each class is a singleton -- only one will exist for a given
+# node.
+class Puppet::Parser::AST::HostClass < Puppet::Parser::AST::Definition
+ @name = :class
- # Are we a child of the passed class? Do a recursive search up our
- # parentage tree to figure it out.
- def child_of?(klass)
- return false unless self.parentclass
+ # Are we a child of the passed class? Do a recursive search up our
+ # parentage tree to figure it out.
+ def child_of?(klass)
+ return false unless self.parentclass
- if klass == self.parentobj
- return true
- else
- return self.parentobj.child_of?(klass)
- end
+ if klass == self.parentobj
+ return true
+ else
+ return self.parentobj.child_of?(klass)
end
+ end
- # Evaluate the code associated with this class.
- def evaluate(options)
- scope = options[:scope]
- raise(ArgumentError, "Classes require resources") unless options[:resource]
- # Verify that we haven't already been evaluated. This is
- # what provides the singleton aspect.
- if existing_scope = scope.compile.class_scope(self)
- Puppet.debug "Class '%s' already evaluated; not evaluating again" % (classname == "" ? "main" : classname)
- return nil
- end
+ # Make sure our parent class has been evaluated, if we have one.
+ def evaluate(scope)
+ if parentclass and ! scope.catalog.resource(self.class.name, parentclass)
+ parent_resource = parentobj.evaluate(scope)
+ end
- scope.compile.catalog.tag(self.classname)
+ # Do nothing if the resource already exists; this makes sure we don't
+ # get multiple copies of the class resource, which helps provide the
+ # singleton nature of classes.
+ if resource = scope.catalog.resource(self.class.name, self.classname)
+ return resource
+ end
- pnames = nil
- if pklass = self.parentobj
- pklass.safeevaluate :scope => scope, :resource => options[:resource]
+ super
+ end
- scope = parent_scope(scope, pklass)
- pnames = scope.namespaces
- end
+ # Evaluate the code associated with this class.
+ def evaluate_code(resource)
+ scope = resource.scope
+ # Verify that we haven't already been evaluated. This is
+ # what provides the singleton aspect.
+ if existing_scope = scope.compiler.class_scope(self)
+ Puppet.debug "Class '%s' already evaluated; not evaluating again" % (classname == "" ? "main" : classname)
+ return nil
+ end
- # Don't create a subscope for the top-level class, since it already
- # has its own scope.
- unless options[:resource].title == :main
- scope = subscope(scope, options[:resource])
- end
+ pnames = nil
+ if pklass = self.parentobj
+ parent_resource = resource.scope.compiler.catalog.resource(self.class.name, pklass.classname)
+ # This shouldn't evaluate if the class has already been evaluated.
+ pklass.evaluate_code(parent_resource)
- if pnames
- pnames.each do |ns|
- scope.add_namespace(ns)
- end
- end
+ scope = parent_scope(scope, pklass)
+ pnames = scope.namespaces
+ end
- # Set the class before we do anything else, so that it's set
- # during the evaluation and can be inspected.
- scope.compile.class_set(self.classname, scope)
+ # Don't create a subscope for the top-level class, since it already
+ # has its own scope.
+ scope = subscope(scope, resource) unless resource.title == :main
- # Now evaluate our code, yo.
- if self.code
- return self.code.evaluate(:scope => scope)
- else
- return nil
+ # Add the parent scope namespaces to our own.
+ if pnames
+ pnames.each do |ns|
+ scope.add_namespace(ns)
end
end
- def initialize(options)
- @parentclass = nil
- super
+ # Set the class before we evaluate the code, so that it's set during
+ # the evaluation and can be inspected.
+ scope.compiler.class_set(self.classname, scope)
+
+ # Now evaluate our code, yo.
+ if self.code
+ return self.code.safeevaluate(scope)
+ else
+ return nil
end
+ end
- def parent_scope(scope, klass)
- if s = scope.compile.class_scope(klass)
- return s
- else
- raise Puppet::DevError, "Could not find scope for %s" % klass.classname
- end
+ def parent_scope(scope, klass)
+ if s = scope.compiler.class_scope(klass)
+ return s
+ else
+ raise Puppet::DevError, "Could not find scope for %s" % klass.classname
end
end
end
diff --git a/lib/puppet/parser/ast/ifstatement.rb b/lib/puppet/parser/ast/ifstatement.rb
index 66a07b01f..afa2cd572 100644
--- a/lib/puppet/parser/ast/ifstatement.rb
+++ b/lib/puppet/parser/ast/ifstatement.rb
@@ -12,15 +12,14 @@ class Puppet::Parser::AST
# Short-curcuit evaluation. If we're true, evaluate our statements,
# else if there's an 'else' setting, evaluate it.
# the first option that matches.
- def evaluate(hash)
- scope = hash[:scope]
- value = @test.safeevaluate(:scope => scope)
+ def evaluate(scope)
+ value = @test.safeevaluate(scope)
if Puppet::Parser::Scope.true?(value)
- return @statements.safeevaluate(:scope => scope)
+ return @statements.safeevaluate(scope)
else
if defined? @else
- return @else.safeevaluate(:scope => scope)
+ return @else.safeevaluate(scope)
else
return nil
end
diff --git a/lib/puppet/parser/ast/leaf.rb b/lib/puppet/parser/ast/leaf.rb
index 225253061..c545c1e47 100644
--- a/lib/puppet/parser/ast/leaf.rb
+++ b/lib/puppet/parser/ast/leaf.rb
@@ -6,7 +6,7 @@ class Puppet::Parser::AST
attr_accessor :value, :type
# Return our value.
- def evaluate(hash)
+ def evaluate(scope)
return @value
end
@@ -35,14 +35,14 @@ class Puppet::Parser::AST
class String < AST::Leaf
# Interpolate the string looking for variables, and then return
# the result.
- def evaluate(hash)
- return hash[:scope].strinterp(@value, @file, @line)
+ def evaluate(scope)
+ return scope.strinterp(@value, @file, @line)
end
end
# An uninterpreted string.
class FlatString < AST::Leaf
- def evaluate(hash)
+ def evaluate(scope)
return @value
end
end
@@ -81,9 +81,9 @@ class Puppet::Parser::AST
class Variable < Name
# Looks up the value of the object in the scope tree (does
# not include syntactical constructs, like '$' and '{}').
- def evaluate(hash)
+ def evaluate(scope)
parsewrap do
- return hash[:scope].lookupvar(@value)
+ return scope.lookupvar(@value)
end
end
end
diff --git a/lib/puppet/parser/ast/node.rb b/lib/puppet/parser/ast/node.rb
index a296e43ba..2bf6c1882 100644
--- a/lib/puppet/parser/ast/node.rb
+++ b/lib/puppet/parser/ast/node.rb
@@ -1,67 +1,35 @@
require 'puppet/parser/ast/hostclass'
-class Puppet::Parser::AST
- # The specific code associated with a host. Nodes are annoyingly unlike
- # other objects. That's just the way it is, at least for now.
- class Node < AST::HostClass
- @name = :node
- attr_accessor :name
-
- def evaluate(options)
- scope = options[:scope]
-
- #pscope = if ! Puppet[:lexical] or options[:asparent]
- # @scope
- #else
- # origscope
- #end
-
- # We don't have to worry about the declarativeness of node parentage,
- # because the entry point is always a single node definition.
- if parent = self.parentobj
- scope = parent.safeevaluate :scope => scope, :resource => options[:resource]
- end
-
- scope = scope.newscope(
- :resource => options[:resource],
- :keyword => @keyword,
- :source => self,
- :namespace => "" # nodes are always in ""
- )
-
- # Mark our node name as a class, too, but strip it of the domain
- # name. Make the mark before we evaluate the code, so that it is
- # marked within the code itself.
- scope.compile.class_set(self.classname, scope)
-
- # And then evaluate our code if we have any
- if self.code
- @code.safeevaluate(:scope => scope)
- end
-
- return scope
+# The specific code associated with a host. Nodes are annoyingly unlike
+# other objects. That's just the way it is, at least for now.
+class Puppet::Parser::AST::Node < Puppet::Parser::AST::HostClass
+ @name = :node
+
+ def initialize(options)
+ @parentclass = nil
+ super
+
+ # Do some validation on the node name
+ if @name =~ /[^-\w.]/
+ raise Puppet::ParseError, "Invalid node name %s" % @name
end
+ end
- def initialize(options)
- @parentclass = nil
- super
+ def namespace
+ ""
+ end
- # Do some validation on the node name
- if @name =~ /[^-\w.]/
- raise Puppet::ParseError, "Invalid node name %s" % @name
- end
- end
+ # Make sure node scopes are marked as such.
+ def subscope(*args)
+ scope = super
+ scope.nodescope = true
+ scope
+ end
- # Make sure node scopes are marked as such.
- def subscope(*args)
- scope = super
- scope.nodescope = true
- end
+ private
- private
- # Search for the object matching our parent class.
- def find_parentclass
- @parser.findnode(parentclass)
- end
+ # Search for the object matching our parent class.
+ def find_parentclass
+ @parser.findnode(parentclass)
end
end
diff --git a/lib/puppet/parser/ast/resource.rb b/lib/puppet/parser/ast/resource.rb
index c53ab0a68..8a60522a3 100644
--- a/lib/puppet/parser/ast/resource.rb
+++ b/lib/puppet/parser/ast/resource.rb
@@ -9,15 +9,13 @@ class Resource < AST::ResourceReference
# Does not actually return an object; instead sets an object
# in the current scope.
- def evaluate(options)
- scope = options[:scope]
-
+ def evaluate(scope)
# Evaluate all of the specified params.
paramobjects = @params.collect { |param|
- param.safeevaluate(:scope => scope)
+ param.safeevaluate(scope)
}
- objtitles = @title.safeevaluate(:scope => scope)
+ objtitles = @title.safeevaluate(scope)
# it's easier to always use an array, even for only one name
unless objtitles.is_a?(Array)
@@ -50,10 +48,10 @@ class Resource < AST::ResourceReference
:scope => scope
)
- # And then store the resource in the compile.
+ # And then store the resource in the compiler.
# At some point, we need to switch all of this to return
# objects instead of storing them like this.
- scope.compile.store_resource(scope, obj)
+ scope.compiler.add_resource(scope, obj)
obj
end
}.reject { |obj| obj.nil? }
diff --git a/lib/puppet/parser/ast/resource_defaults.rb b/lib/puppet/parser/ast/resource_defaults.rb
index 8f9c1b8df..4856f0594 100644
--- a/lib/puppet/parser/ast/resource_defaults.rb
+++ b/lib/puppet/parser/ast/resource_defaults.rb
@@ -8,13 +8,11 @@ class Puppet::Parser::AST
# As opposed to ResourceDef, this stores each default for the given
# object type.
- def evaluate(hash)
- scope = hash[:scope]
-
+ def evaluate(scope)
# Use a resource reference to canonize the type
ref = Puppet::ResourceReference.new(@type, "whatever")
type = ref.type
- params = @params.safeevaluate(:scope => scope)
+ params = @params.safeevaluate(scope)
parsewrap do
scope.setdefaults(type, params)
diff --git a/lib/puppet/parser/ast/resource_override.rb b/lib/puppet/parser/ast/resource_override.rb
index 46c930902..f9464acda 100644
--- a/lib/puppet/parser/ast/resource_override.rb
+++ b/lib/puppet/parser/ast/resource_override.rb
@@ -17,17 +17,15 @@ class Puppet::Parser::AST
# Does not actually return an object; instead sets an object
# in the current scope.
- def evaluate(hash)
- scope = hash[:scope]
-
+ def evaluate(scope)
# Get our object reference.
- object = @object.safeevaluate(:scope => scope)
+ object = @object.safeevaluate(scope)
hash = {}
# Evaluate all of the specified params.
params = @params.collect { |param|
- param.safeevaluate(:scope => scope)
+ param.safeevaluate(scope)
}
# Now we just create a normal resource, but we call a very different
@@ -44,7 +42,7 @@ class Puppet::Parser::AST
# Now we tell the scope that it's an override, and it behaves as
# necessary.
- scope.compile.store_override(obj)
+ scope.compiler.add_override(obj)
obj
end
diff --git a/lib/puppet/parser/ast/resource_reference.rb b/lib/puppet/parser/ast/resource_reference.rb
index b06ea17be..4bb41165a 100644
--- a/lib/puppet/parser/ast/resource_reference.rb
+++ b/lib/puppet/parser/ast/resource_reference.rb
@@ -22,10 +22,8 @@ class Puppet::Parser::AST
# Evaluate our object, but just return a simple array of the type
# and name.
- def evaluate(hash)
- scope = hash[:scope]
-
- title = @title.safeevaluate(:scope => scope)
+ def evaluate(scope)
+ title = @title.safeevaluate(scope)
if @type.to_s.downcase == "class"
objtype = "class"
title = qualified_class(scope, title)
diff --git a/lib/puppet/parser/ast/resourceparam.rb b/lib/puppet/parser/ast/resourceparam.rb
index 8b1e7b367..c552a7ee5 100644
--- a/lib/puppet/parser/ast/resourceparam.rb
+++ b/lib/puppet/parser/ast/resourceparam.rb
@@ -10,12 +10,10 @@ class Puppet::Parser::AST
end
# Return the parameter and the value.
- def evaluate(hash)
- scope = hash[:scope]
-
+ def evaluate(scope)
return Puppet::Parser::Resource::Param.new(
:name => @param,
- :value => @value.safeevaluate(:scope => scope),
+ :value => @value.safeevaluate(scope),
:source => scope.source, :line => self.line, :file => self.file,
:add => self.add
)
diff --git a/lib/puppet/parser/ast/selector.rb b/lib/puppet/parser/ast/selector.rb
index d363ab7e4..399d405a3 100644
--- a/lib/puppet/parser/ast/selector.rb
+++ b/lib/puppet/parser/ast/selector.rb
@@ -11,13 +11,12 @@ class Puppet::Parser::AST
end
# Find the value that corresponds with the test.
- def evaluate(hash)
- scope = hash[:scope]
+ def evaluate(scope)
retvalue = nil
found = nil
# Get our parameter.
- paramvalue = @param.safeevaluate(:scope => scope)
+ paramvalue = @param.safeevaluate(scope)
sensitive = Puppet[:casesensitive]
@@ -33,13 +32,13 @@ class Puppet::Parser::AST
# Then look for a match in the options.
@values.each { |obj|
- param = obj.param.safeevaluate(:scope => scope)
+ param = obj.param.safeevaluate(scope)
if ! sensitive && param.respond_to?(:downcase)
param = param.downcase
end
if param == paramvalue
# we found a matching option
- retvalue = obj.value.safeevaluate(:scope => scope)
+ retvalue = obj.value.safeevaluate(scope)
found = true
break
elsif obj.param.is_a?(Default)
@@ -51,7 +50,7 @@ class Puppet::Parser::AST
# Unless we found something, look for the default.
unless found
if default
- retvalue = default.value.safeevaluate(:scope => scope)
+ retvalue = default.value.safeevaluate(scope)
else
self.fail Puppet::ParseError,
"No matching value for selector param '%s'" % paramvalue
diff --git a/lib/puppet/parser/ast/tag.rb b/lib/puppet/parser/ast/tag.rb
index e2882d2f0..2909504a7 100644
--- a/lib/puppet/parser/ast/tag.rb
+++ b/lib/puppet/parser/ast/tag.rb
@@ -8,10 +8,8 @@ class Puppet::Parser::AST
@name = :class
attr_accessor :type
- def evaluate(hash)
- scope = hash[:scope]
-
- types = @type.safeevaluate(:scope => scope)
+ def evaluate(scope)
+ types = @type.safeevaluate(scope)
types = [types] unless types.is_a? Array
diff --git a/lib/puppet/parser/ast/vardef.rb b/lib/puppet/parser/ast/vardef.rb
index 1e7f874bc..ee79159d7 100644
--- a/lib/puppet/parser/ast/vardef.rb
+++ b/lib/puppet/parser/ast/vardef.rb
@@ -9,10 +9,9 @@ class Puppet::Parser::AST
# Look up our name and value, and store them appropriately. The
# lexer strips off the syntax stuff like '$'.
- def evaluate(hash)
- scope = hash[:scope]
- name = @name.safeevaluate(:scope => scope)
- value = @value.safeevaluate(:scope => scope)
+ def evaluate(scope)
+ name = @name.safeevaluate(scope)
+ value = @value.safeevaluate(scope)
parsewrap do
scope.setvar(name,value, @file, @line)
diff --git a/lib/puppet/parser/collector.rb b/lib/puppet/parser/collector.rb
index b8165a84f..2699dc6e1 100644
--- a/lib/puppet/parser/collector.rb
+++ b/lib/puppet/parser/collector.rb
@@ -51,7 +51,7 @@ class Puppet::Parser::Collector
search = "(exported=? AND restype=?)"
values = [true, @type]
- search += " AND (?)" and values << @equery if @equery
+ search += " AND (%s)" % @equery if @equery
# We're going to collect objects from rails, but we don't want any
# objects from this host.
@@ -118,20 +118,20 @@ class Puppet::Parser::Collector
# If there are no more resources to find, delete this from the list
# of collections.
if @resources.empty?
- @scope.compile.delete_collection(self)
+ @scope.compiler.delete_collection(self)
end
return result
end
- # Collect just virtual objects, from our local compile.
+ # Collect just virtual objects, from our local compiler.
def collect_virtual(exported = false)
if exported
method = :exported?
else
method = :virtual?
end
- scope.compile.resources.find_all do |resource|
+ scope.compiler.resources.find_all do |resource|
resource.type == @type and resource.send(method) and match?(resource)
end
end
@@ -150,7 +150,7 @@ class Puppet::Parser::Collector
resource.exported = false
- scope.compile.store_resource(scope, resource)
+ scope.compiler.add_resource(scope, resource)
return resource
end
diff --git a/lib/puppet/parser/compile.rb b/lib/puppet/parser/compiler.rb
index f76103a28..8fba41121 100644
--- a/lib/puppet/parser/compile.rb
+++ b/lib/puppet/parser/compiler.rb
@@ -7,7 +7,7 @@ require 'puppet/util/errors'
# Maintain a graph of scopes, along with a bunch of data
# about the individual catalog we're compiling.
-class Puppet::Parser::Compile
+class Puppet::Parser::Compiler
include Puppet::Util
include Puppet::Util::Errors
attr_reader :parser, :node, :facts, :collections, :catalog, :node_scope
@@ -17,6 +17,29 @@ class Puppet::Parser::Compile
@collections << coll
end
+ # Store a resource override.
+ def add_override(override)
+ # If possible, merge the override in immediately.
+ if resource = @catalog.resource(override.ref)
+ resource.merge(override)
+ else
+ # Otherwise, store the override for later; these
+ # get evaluated in Resource#finish.
+ @resource_overrides[override.ref] << override
+ end
+ end
+
+ # Store a resource in our resource table.
+ def add_resource(scope, resource)
+ # Note that this will fail if the resource is not unique.
+ @catalog.add_resource(resource)
+
+ # And in the resource graph. At some point, this might supercede
+ # the global resource table, but the table is a lot faster
+ # so it makes sense to maintain for now.
+ @catalog.add_edge(scope.resource, resource)
+ end
+
# Do we use nodes found in the code, vs. the external node sources?
def ast_nodes?
parser.nodes.length > 0
@@ -26,10 +49,10 @@ class Puppet::Parser::Compile
# the scope in which it was evaluated, so that we can look it up later.
def class_set(name, scope)
if existing = @class_scopes[name]
- if existing.nodescope? or scope.nodescope?
+ if existing.nodescope? != scope.nodescope?
raise Puppet::ParseError, "Cannot have classes, nodes, or definitions with the same name"
else
- raise Puppet::DevError, "Somehow evaluated the same class twice"
+ raise Puppet::DevError, "Somehow evaluated %s %s twice" % [ existing.nodescope? ? "node" : "class", name]
end
end
@class_scopes[name] = scope
@@ -54,7 +77,7 @@ class Puppet::Parser::Compile
return @catalog.classes
end
- # Compile our catalog. This mostly revolves around finding and evaluating classes.
+ # Compiler our catalog. This mostly revolves around finding and evaluating classes.
# This is the main entry into our catalog.
def compile
# Set the client's parameters into the top scope.
@@ -68,10 +91,10 @@ class Puppet::Parser::Compile
evaluate_generators()
- fail_on_unevaluated()
-
finish()
+ fail_on_unevaluated()
+
if Puppet[:storeconfigs]
store()
end
@@ -84,11 +107,6 @@ class Puppet::Parser::Compile
@collections.delete(coll) if @collections.include?(coll)
end
- # LAK:FIXME There are no tests for this.
- def delete_resource(resource)
- @resource_table.delete(resource.ref) if @resource_table.include?(resource.ref)
- end
-
# Return the node's environment.
def environment
unless defined? @environment
@@ -120,16 +138,11 @@ class Puppet::Parser::Compile
if klass = scope.findclass(name)
found << name and next if class_scope(klass)
- # Create a resource to model this class, and then add it to the list
- # of resources.
- resource = Puppet::Parser::Resource.new(:type => "class", :title => klass.classname, :scope => scope, :source => scope.source)
-
- store_resource(scope, resource)
+ resource = klass.evaluate(scope)
# If they've disabled lazy evaluation (which the :include function does),
# then evaluate our resource immediately.
resource.evaluate unless lazy_evaluate
- @catalog.tag(klass.classname)
found << name
else
Puppet.info "Could not find class %s for %s" % [name, node.name]
@@ -140,10 +153,8 @@ class Puppet::Parser::Compile
end
# Return a resource by either its ref or its type and title.
- def findresource(string, name = nil)
- string = "%s[%s]" % [string.capitalize, name] if name
-
- @resource_table[string]
+ def findresource(*args)
+ @catalog.resource(*args)
end
# Set up our compile. We require a parser
@@ -158,7 +169,7 @@ class Puppet::Parser::Compile
begin
send(param.to_s + "=", value)
rescue NoMethodError
- raise ArgumentError, "Compile objects do not accept %s" % param
+ raise ArgumentError, "Compiler objects do not accept %s" % param
end
end
@@ -171,10 +182,10 @@ class Puppet::Parser::Compile
# its parent to the graph.
def newscope(parent, options = {})
parent ||= topscope
- options[:compile] = self
+ options[:compiler] = self
options[:parser] ||= self.parser
scope = Puppet::Parser::Scope.new(options)
- @scope_graph.add_edge!(parent, scope)
+ @scope_graph.add_edge(parent, scope)
scope
end
@@ -195,35 +206,7 @@ class Puppet::Parser::Compile
# Return a list of all resources.
def resources
- @resource_table.values
- end
-
- # Store a resource override.
- def store_override(override)
- override.override = true
-
- # If possible, merge the override in immediately.
- if resource = @resource_table[override.ref]
- resource.merge(override)
- else
- # Otherwise, store the override for later; these
- # get evaluated in Resource#finish.
- @resource_overrides[override.ref] << override
- end
- end
-
- # Store a resource in our resource table.
- def store_resource(scope, resource)
- # This might throw an exception
- verify_uniqueness(resource)
-
- # Store it in the global table.
- @resource_table[resource.ref] = resource
-
- # And in the resource graph. At some point, this might supercede
- # the global resource table, but the table is a lot faster
- # so it makes sense to maintain for now.
- @catalog.add_edge!(scope.resource, resource)
+ @catalog.vertices
end
# The top scope is usually the top-level scope, but if we're using AST nodes,
@@ -250,9 +233,7 @@ class Puppet::Parser::Compile
# Create a resource to model this node, and then add it to the list
# of resources.
- resource = Puppet::Parser::Resource.new(:type => "node", :title => astnode.classname, :scope => topscope, :source => topscope.source)
- store_resource(topscope, resource)
- @catalog.tag(astnode.classname)
+ resource = astnode.evaluate(topscope)
resource.evaluate
@@ -285,11 +266,15 @@ class Puppet::Parser::Compile
def evaluate_definitions
exceptwrap do
if ary = unevaluated_resources
+ evaluated = false
ary.each do |resource|
- resource.evaluate
+ if not resource.virtual?
+ resource.evaluate
+ evaluated = true
+ end
end
# If we evaluated, let the loop know.
- return true
+ return evaluated
else
return false
end
@@ -309,6 +294,9 @@ class Puppet::Parser::Compile
done = false if evaluate_collections
done = false if evaluate_definitions
break if done
+
+ count += 1
+
if count > 1000
raise Puppet::ParseError, "Somehow looped more than 1000 times while evaluating host catalog"
end
@@ -322,9 +310,7 @@ class Puppet::Parser::Compile
@main_resource = Puppet::Parser::Resource.new(:type => "class", :title => :main, :scope => @topscope, :source => @main)
@topscope.resource = @main_resource
- @catalog.add_vertex!(@main_resource)
-
- @resource_table["Class[main]"] = @main_resource
+ @catalog.add_resource(@main_resource)
@main_resource.evaluate
end
@@ -380,14 +366,27 @@ class Puppet::Parser::Compile
# Make sure all of our resources and such have done any last work
# necessary.
def finish
- @resource_table.each { |name, resource| resource.finish if resource.respond_to?(:finish) }
+ @catalog.vertices.each do |resource|
+ # Add in any resource overrides.
+ if overrides = resource_overrides(resource)
+ overrides.each do |over|
+ resource.merge(over)
+ end
+
+ # Remove the overrides, so that the configuration knows there
+ # are none left.
+ overrides.clear
+ end
+
+ resource.finish if resource.respond_to?(:finish)
+ end
end
# Initialize the top-level scope, class, and resource.
def init_main
# Create our initial scope and a resource that will evaluate main.
- @topscope = Puppet::Parser::Scope.new(:compile => self, :parser => self.parser)
- @scope_graph.add_vertex!(@topscope)
+ @topscope = Puppet::Parser::Scope.new(:compiler => self, :parser => self.parser)
+ @scope_graph.add_vertex(@topscope)
end
# Set up all of our internal variables.
@@ -396,9 +395,6 @@ class Puppet::Parser::Compile
# be used by top scopes and node scopes.
@class_scopes = {}
- # The table for all defined resources.
- @resource_table = {}
-
# The list of objects that will available for export.
@exported_resources = {}
@@ -412,9 +408,6 @@ class Puppet::Parser::Compile
# but they each refer back to the scope that created them.
@collections = []
- # A list of tags we've generated; most class names.
- @tags = []
-
# A graph for maintaining scope relationships.
@scope_graph = Puppet::SimpleGraph.new
@@ -443,7 +436,7 @@ class Puppet::Parser::Compile
# We used to have hooks here for forking and saving, but I don't
# think it's worth retaining at this point.
- store_to_active_record(@node, @resource_table.values)
+ store_to_active_record(@node, @catalog.vertices)
end
# Do the actual storage.
@@ -466,9 +459,7 @@ class Puppet::Parser::Compile
# Return an array of all of the unevaluated resources. These will be definitions,
# which need to get evaluated into native resources.
def unevaluated_resources
- ary = @resource_table.find_all do |name, object|
- ! object.builtin? and ! object.evaluated?
- end.collect { |name, object| object }
+ ary = @catalog.vertices.reject { |resource| resource.builtin? or resource.evaluated? }
if ary.empty?
return nil
@@ -476,33 +467,4 @@ class Puppet::Parser::Compile
return ary
end
end
-
- # Verify that the given resource isn't defined elsewhere.
- def verify_uniqueness(resource)
- # Short-curcuit the common case,
- unless existing_resource = @resource_table[resource.ref]
- return true
- end
-
- if typeclass = Puppet::Type.type(resource.type) and ! typeclass.isomorphic?
- Puppet.info "Allowing duplicate %s" % typeclass.name
- return true
- end
-
- # Either it's a defined type, which are never
- # isomorphic, or it's a non-isomorphic type, so
- # we should throw an exception.
- msg = "Duplicate definition: %s is already defined" % resource.ref
-
- if existing_resource.file and existing_resource.line
- msg << " in file %s at line %s" %
- [existing_resource.file, existing_resource.line]
- end
-
- if resource.line or resource.file
- msg << "; cannot redefine"
- end
-
- raise Puppet::ParseError.new(msg)
- end
end
diff --git a/lib/puppet/parser/functions.rb b/lib/puppet/parser/functions.rb
index 34b38b809..e0b60e161 100644
--- a/lib/puppet/parser/functions.rb
+++ b/lib/puppet/parser/functions.rb
@@ -111,7 +111,7 @@ module Functions
vals = [vals] unless vals.is_a?(Array)
# The 'false' disables lazy evaluation.
- klasses = compile.evaluate_classes(vals, self, false)
+ klasses = compiler.evaluate_classes(vals, self, false)
missing = vals.find_all do |klass|
! klasses.include?(klass)
@@ -146,7 +146,7 @@ module Functions
tells you whether the current container is tagged with the specified tags.
The tags are ANDed, so that all of the specified tags must be included for
the function to return true.") do |vals|
- configtags = compile.catalog.tags
+ configtags = compiler.catalog.tags
resourcetags = resource.tags
retval = true
@@ -235,7 +235,7 @@ module Functions
vals = [vals] unless vals.is_a?(Array)
coll.resources = vals
- compile.add_collection(coll)
+ compiler.add_collection(coll)
end
newfunction(:search, :doc => "Add another namespace for this class to search.
diff --git a/lib/puppet/parser/grammar.ra b/lib/puppet/parser/grammar.ra
index 0fd644b3a..484efe83c 100644
--- a/lib/puppet/parser/grammar.ra
+++ b/lib/puppet/parser/grammar.ra
@@ -151,7 +151,7 @@ resourceoverride: resourceref LBRACE anyparams endcomma RBRACE {
virtualresource: at resource {
type = val[0]
- if type == :exported and ! Puppet[:storeconfigs]
+ if (type == :exported and ! Puppet[:storeconfigs]) and ! Puppet[:parseonly]
error "You cannot collect without storeconfigs being set"
end
@@ -192,7 +192,7 @@ collection: classref collectrhand {
else
args[:form] = val[1]
end
- if args[:form] == :exported and ! Puppet[:storeconfigs]
+ if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
error "You cannot collect exported resources without storeconfigs being set"
end
result = ast AST::Collection, args
diff --git a/lib/puppet/parser/interpreter.rb b/lib/puppet/parser/interpreter.rb
index e29e19944..f27c1c5c8 100644
--- a/lib/puppet/parser/interpreter.rb
+++ b/lib/puppet/parser/interpreter.rb
@@ -3,7 +3,7 @@ require 'timeout'
require 'puppet/rails'
require 'puppet/util/methodhelper'
require 'puppet/parser/parser'
-require 'puppet/parser/compile'
+require 'puppet/parser/compiler'
require 'puppet/parser/scope'
# The interpreter is a very simple entry-point class that
@@ -24,8 +24,13 @@ class Puppet::Parser::Interpreter
# evaluate our whole tree
def compile(node)
- raise Puppet::ParseError, "Could not parse configuration; cannot compile" unless env_parser = parser(node.environment)
- return Puppet::Parser::Compile.new(node, env_parser).compile
+ raise Puppet::ParseError, "Could not parse configuration; cannot compile on node %s" % node.name unless env_parser = parser(node.environment)
+ begin
+ return Puppet::Parser::Compiler.new(node, env_parser).compile
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error, detail.to_s + " on node %s" % node.name
+ end
end
# create our interpreter
@@ -42,6 +47,30 @@ class Puppet::Parser::Interpreter
@parsers = {}
end
+ # Return the parser for a specific environment.
+ def parser(environment)
+ if ! @parsers[environment] or @parsers[environment].reparse?
+ # This will throw an exception if it does not succeed. We only
+ # want to get rid of the old parser if we successfully create a new
+ # one.
+ begin
+ tmp = create_parser(environment)
+ @parsers[environment].clear if @parsers[environment]
+ @parsers[environment] = tmp
+ rescue => detail
+ # If a parser already exists, than assume that we logged the
+ # exception elsewhere and reuse the parser. If one doesn't
+ # exist, then reraise.
+ if @parsers[environment]
+ Puppet.err detail
+ else
+ raise detail
+ end
+ end
+ end
+ @parsers[environment]
+ end
+
private
# Create a new parser object and pre-parse the configuration.
@@ -67,24 +96,4 @@ class Puppet::Parser::Interpreter
raise error
end
end
-
- # Return the parser for a specific environment.
- def parser(environment)
- if ! @parsers[environment] or @parsers[environment].reparse?
- # This will throw an exception if it does not succeed. We only
- # want to get rid of the old parser if we successfully create a new
- # one.
- begin
- tmp = create_parser(environment)
- @parsers[environment].clear if @parsers[environment]
- @parsers[environment] = tmp
- rescue => detail
- # If a parser already exists, than assume that we logged the
- # exception elsewhere and reuse the parser. If one doesn't
- # exist, then reraise.
- raise detail unless @parsers[environment]
- end
- end
- @parsers[environment]
- end
end
diff --git a/lib/puppet/parser/lexer.rb b/lib/puppet/parser/lexer.rb
index 086d82c09..51026ea1b 100644
--- a/lib/puppet/parser/lexer.rb
+++ b/lib/puppet/parser/lexer.rb
@@ -1,4 +1,3 @@
-
# the scanner/lexer
require 'strscan'
@@ -7,326 +6,436 @@ require 'puppet'
module Puppet
class LexError < RuntimeError; end
- module Parser
- #---------------------------------------------------------------
- class Lexer
- attr_reader :line, :last, :file
-
- attr_accessor :indefine
-
- #%r{\w+} => :WORD,
- @@tokens = {
- %r{#.*} => :COMMENT,
- %r{\[} => :LBRACK,
- %r{\]} => :RBRACK,
- %r{\{} => :LBRACE,
- %r{\}} => :RBRACE,
- %r{\(} => :LPAREN,
- %r{\)} => :RPAREN,
- %r{\"} => :DQUOTE,
- %r{\n} => :RETURN,
- %r{\'} => :SQUOTE,
- %r{=} => :EQUALS,
- %r{==} => :ISEQUAL,
- %r{>=} => :GREATEREQUAL,
- %r{>} => :GREATERTHAN,
- %r{<} => :LESSTHAN,
- %r{<=} => :LESSEQUAL,
- %r{!=} => :NOTEQUAL,
- %r{!} => :NOT,
- %r{,} => :COMMA,
- %r{\.} => :DOT,
- %r{:} => :COLON,
- %r{@} => :AT,
- %r{<<\|} => :LLCOLLECT,
- %r{\|>>} => :RRCOLLECT,
- %r{<\|} => :LCOLLECT,
- %r{\|>} => :RCOLLECT,
- %r{;} => :SEMIC,
- %r{\?} => :QMARK,
- %r{\\} => :BACKSLASH,
- %r{=>} => :FARROW,
- %r{\+>} => :PARROW,
- %r{[a-z][-\w]*} => :NAME,
- %r{([a-z][-\w]*::)+[a-z][-\w]*} => :CLASSNAME,
- %r{((::){0,1}[A-Z][-\w]*)+} => :CLASSREF,
- %r{[0-9]+} => :NUMBER,
- %r{\$(\w*::)*\w+} => :VARIABLE
- }
-
- @@pairs = {
- "{" => "}",
- "(" => ")",
- "[" => "]",
- "<|" => "|>",
- "<<|" => "|>>"
- }
-
- @@reverse_pairs = @@pairs.inject({}) { |hash, pair| hash[pair[1]] = pair[0]; hash }
-
- @@keywords = {
- "case" => :CASE,
- "class" => :CLASS,
- "default" => :DEFAULT,
- "define" => :DEFINE,
- "false" => :BOOLEAN,
- "import" => :IMPORT,
- "if" => :IF,
- "elsif" => :ELSIF,
- "else" => :ELSE,
- "inherits" => :INHERITS,
- "node" => :NODE,
- "true" => :BOOLEAN,
- "and" => :AND,
- "or" => :OR,
- "undef" => :UNDEF
- }
-
- def clear
- initvars
- end
+end
- def expected
- if @expected.empty?
- nil
- else
- token = @expected[-1]
- @@tokens.each do |value, name|
- if token == name
- return value
- end
- end
- return token
- end
- end
+module Puppet::Parser; end
- # scan the whole file
- # basically just used for testing
- def fullscan
- array = []
-
- self.scan { |token,str|
- # Ignore any definition nesting problems
- @indefine = false
- #Puppet.debug("got token '%s' => '%s'" % [token,str])
- if token.nil?
- return array
- else
- array.push([token,str])
- end
- }
- return array
+class Puppet::Parser::Lexer
+ attr_reader :last, :file
+
+ attr_accessor :line, :indefine
+
+ # Our base token class.
+ class Token
+ attr_accessor :regex, :name, :string, :skip, :incr_line, :skip_text
+
+ def initialize(regex, name)
+ if regex.is_a?(String)
+ @name, @string = name, regex
+ @regex = Regexp.new(Regexp.escape(@string))
+ else
+ @name, @regex = name, regex
end
+ end
- # this is probably pretty damned inefficient...
- # it'd be nice not to have to load the whole file first...
- def file=(file)
- @file = file
- @line = 1
- File.open(file) { |of|
- str = ""
- of.each { |line| str += line }
- @scanner = StringScanner.new(str)
- }
+ def skip?
+ self.skip
+ end
+
+ def to_s
+ if self.string
+ @string
+ else
+ @name.to_s
end
+ end
+ end
- def indefine?
- if defined? @indefine
- @indefine
- else
- false
- end
+ # Maintain a list of tokens.
+ class TokenList
+ attr_reader :regex_tokens, :string_tokens
+
+ def [](name)
+ @tokens[name]
+ end
+
+ # Create a new token.
+ def add_token(name, regex, options = {}, &block)
+ token = Token.new(regex, name)
+ raise(ArgumentError, "Token %s already exists" % name) if @tokens.include?(name)
+ @tokens[token.name] = token
+ if token.string
+ @string_tokens << token
+ @tokens_by_string[token.string] = token
+ else
+ @regex_tokens << token
end
- def initialize
- initvars()
+ options.each do |name, option|
+ token.send(name.to_s + "=", option)
end
- def initvars
- @line = 1
- @last = ""
- @lasttoken = nil
- @scanner = nil
- @file = nil
- # AAARRGGGG! okay, regexes in ruby are bloody annoying
- # no one else has "\n" =~ /\s/
- @skip = %r{[ \t]+}
+ token.meta_def(:convert, &block) if block_given?
+
+ token
+ end
- @namestack = []
- @indefine = false
+ def initialize
+ @tokens = {}
+ @regex_tokens = []
+ @string_tokens = []
+ @tokens_by_string = {}
+ end
- @expected = []
- end
+ # Look up a token by its value, rather than name.
+ def lookup(string)
+ @tokens_by_string[string]
+ end
- # Go up one in the namespace.
- def namepop
- @namestack.pop
+ # Define more tokens.
+ def add_tokens(hash)
+ hash.each do |regex, name|
+ add_token(name, regex)
end
+ end
- # Collect the current namespace.
- def namespace
- @namestack.join("::")
+ # Sort our tokens by length, so we know once we match, we're done.
+ # This helps us avoid the O(n^2) nature of token matching.
+ def sort_tokens
+ @string_tokens.sort! { |a, b| b.string.length <=> a.string.length }
+ end
+ end
+
+ TOKENS = TokenList.new
+ TOKENS.add_tokens(
+ '[' => :LBRACK,
+ ']' => :RBRACK,
+ '{' => :LBRACE,
+ '}' => :RBRACE,
+ '(' => :LPAREN,
+ ')' => :RPAREN,
+ '=' => :EQUALS,
+ '==' => :ISEQUAL,
+ '>=' => :GREATEREQUAL,
+ '>' => :GREATERTHAN,
+ '<' => :LESSTHAN,
+ '<=' => :LESSEQUAL,
+ '!=' => :NOTEQUAL,
+ '!' => :NOT,
+ ',' => :COMMA,
+ '.' => :DOT,
+ ':' => :COLON,
+ '@' => :AT,
+ '<<|' => :LLCOLLECT,
+ '|>>' => :RRCOLLECT,
+ '<|' => :LCOLLECT,
+ '|>' => :RCOLLECT,
+ ';' => :SEMIC,
+ '?' => :QMARK,
+ '\\' => :BACKSLASH,
+ '=>' => :FARROW,
+ '+>' => :PARROW,
+ %r{([a-z][-\w]*::)+[a-z][-\w]*} => :CLASSNAME,
+ %r{((::){0,1}[A-Z][-\w]*)+} => :CLASSREF
+ )
+
+ TOKENS.add_tokens "Whatever" => :DQTEXT, "Nomatter" => :SQTEXT, "alsonomatter" => :BOOLEAN
+
+ TOKENS.add_token :NAME, %r{[a-z][-\w]*} do |lexer, value|
+ string_token = self
+ # we're looking for keywords here
+ if tmp = KEYWORDS.lookup(value)
+ string_token = tmp
+ if [:TRUE, :FALSE].include?(string_token.name)
+ value = eval(value)
+ string_token = TOKENS[:BOOLEAN]
end
+ end
+ [string_token, value]
+ end
+
+ TOKENS.add_token :NUMBER, %r{[0-9]+} do |lexer, value|
+ [TOKENS[:NAME], value]
+ end
+
+ TOKENS.add_token :COMMENT, %r{#.*}, :skip => true
+
+ TOKENS.add_token :RETURN, "\n", :skip => true, :incr_line => true, :skip_text => true
+
+ TOKENS.add_token :SQUOTE, "'" do |lexer, value|
+ value = lexer.slurpstring(value)
+ [TOKENS[:SQTEXT], value]
+ end
+
+ TOKENS.add_token :DQUOTE, '"' do |lexer, value|
+ value = lexer.slurpstring(value)
+ [TOKENS[:DQTEXT], value]
+ end
+
+ TOKENS.add_token :VARIABLE, %r{\$(\w*::)*\w+} do |lexer, value|
+ value = value.sub(/^\$/, '')
+ [self, value]
+ end
+
+ TOKENS.sort_tokens
+
+ @@pairs = {
+ "{" => "}",
+ "(" => ")",
+ "[" => "]",
+ "<|" => "|>",
+ "<<|" => "|>>"
+ }
+
+ KEYWORDS = TokenList.new
+
+ KEYWORDS.add_tokens(
+ "case" => :CASE,
+ "class" => :CLASS,
+ "default" => :DEFAULT,
+ "define" => :DEFINE,
+ "import" => :IMPORT,
+ "if" => :IF,
+ "elsif" => :ELSIF,
+ "else" => :ELSE,
+ "inherits" => :INHERITS,
+ "node" => :NODE,
+ "and" => :AND,
+ "or" => :OR,
+ "undef" => :UNDEF,
+ "false" => :FALSE,
+ "true" => :TRUE
+ )
+
+ def clear
+ initvars
+ end
+
+ def expected
+ return nil if @expected.empty?
+ name = @expected[-1]
+ raise "Could not find expected token %s" % name unless token = TOKENS.lookup(name)
+
+ return token
+ end
+
+ # scan the whole file
+ # basically just used for testing
+ def fullscan
+ array = []
+
+ self.scan { |token, str|
+ # Ignore any definition nesting problems
+ @indefine = false
+ array.push([token,str])
+ }
+ return array
+ end
+
+ # this is probably pretty damned inefficient...
+ # it'd be nice not to have to load the whole file first...
+ def file=(file)
+ @file = file
+ @line = 1
+ File.open(file) { |of|
+ str = ""
+ of.each { |line| str += line }
+ @scanner = StringScanner.new(str)
+ }
+ end
- # This value might have :: in it, but we don't care -- it'll be
- # handled normally when joining, and when popping we want to pop
- # this full value, however long the namespace is.
- def namestack(value)
- @namestack << value
+ def find_string_token
+ matched_token = value = nil
+
+ # We know our longest string token is three chars, so try each size in turn
+ # until we either match or run out of chars. This way our worst-case is three
+ # tries, where it is otherwise the number of string chars we have. Also,
+ # the lookups are optimized hash lookups, instead of regex scans.
+ [3, 2, 1].each do |i|
+ str = @scanner.peek(i)
+ if matched_token = TOKENS.lookup(str)
+ value = @scanner.scan(matched_token.regex)
+ break
end
+ end
+
+ return matched_token, value
+ end
- def rest
- @scanner.rest
+ # Find the next token that matches a regex. We look for these first.
+ def find_regex_token
+ @regex += 1
+ matched_token = nil
+ value = ""
+ length = 0
+
+ # I tried optimizing based on the first char, but it had
+ # a slightly negative affect and was a good bit more complicated.
+ TOKENS.regex_tokens.each do |token|
+ next unless match_length = @scanner.match?(token.regex)
+
+ # We've found a longer match
+ if match_length > length
+ value = @scanner.scan(token.regex)
+ length = value.length
+ matched_token = token
end
+ end
- # this is the heart of the lexer
- def scan
- #Puppet.debug("entering scan")
- if @scanner.nil?
- raise TypeError.new("Invalid or empty string")
- end
+ return matched_token, value
+ end
- @scanner.skip(@skip)
- until @scanner.eos? do
- yielded = false
- sendbreak = false # gah, this is a nasty hack
- stoken = nil
- sregex = nil
- value = ""
-
- # first find out which type of token we've got
- @@tokens.each { |regex,token|
- # we're just checking, which doesn't advance the scan
- # pointer
- tmp = @scanner.check(regex)
- if tmp.nil?
- #puppet.debug("did not match %s to '%s'" %
- # [regex,@scanner.rest])
- next
- end
-
- # find the longest match
- if tmp.length > value.length
- value = tmp
- stoken = token
- sregex = regex
- else
- # we've already got a longer match
- next
- end
- }
-
- # error out if we didn't match anything at all
- if stoken.nil?
- nword = nil
- if @scanner.rest =~ /^(\S+)/
- nword = $1
- elsif@scanner.rest =~ /^(\s+)/
- nword = $1
- else
- nword = @scanner.rest
- end
- raise "Could not match '%s'" % nword
- end
+ # Find the next token, returning the string and the token.
+ def find_token
+ @find += 1
+ matched_token, value = find_regex_token
- value = @scanner.scan(sregex)
+ unless matched_token
+ matched_token, value = find_string_token
+ end
- if value == ""
- raise "Didn't match regex on token %s" % stoken
- end
+ return matched_token, value
+ end
- # token-specific operations
- # if this gets much more complicated, it should
- # be moved up to where the tokens themselves are defined
- # which will get me about 75% of the way to a lexer generator
- ptoken = stoken
- case stoken
- when :NAME then
- wtoken = stoken
- # we're looking for keywords here
- if @@keywords.include?(value)
- wtoken = @@keywords[value]
- #Puppet.debug("token '%s'" % wtoken)
- if wtoken == :BOOLEAN
- value = eval(value)
- end
- end
- ptoken = wtoken
- when :NUMBER then
- ptoken = :NAME
- when :COMMENT then
- # just throw comments away
- next
- when :RETURN then
- @line += 1
- @scanner.skip(@skip)
- next
- when :SQUOTE then
- #Puppet.debug("searching '%s' after '%s'" % [self.rest,value])
- value = self.slurpstring(value)
- ptoken = :SQTEXT
- #Puppet.debug("got string '%s' => '%s'" % [:DQTEXT,value])
- when :DQUOTE then
- value = self.slurpstring(value)
- ptoken = :DQTEXT
- when :VARIABLE then
- value = value.sub(/^\$/, '')
- end
+ def indefine?
+ if defined? @indefine
+ @indefine
+ else
+ false
+ end
+ end
- if match = @@pairs[value] and ptoken != :DQUOTE and ptoken != :SQUOTE
- @expected << match
- elsif exp = @expected[-1] and exp == value and ptoken != :DQUOTE and ptoken != :SQUOTE
- @expected.pop
- end
+ def initialize
+ @find = 0
+ @regex = 0
+ initvars()
+ end
- yield [ptoken, value]
+ def initvars
+ @line = 1
+ @previous_token = nil
+ @scanner = nil
+ @file = nil
+ # AAARRGGGG! okay, regexes in ruby are bloody annoying
+ # no one else has "\n" =~ /\s/
+ @skip = %r{[ \t]+}
+
+ @namestack = []
+ @indefine = false
+ @expected = []
+ end
- if @lasttoken == :CLASS
- namestack(value)
- end
+ # Make any necessary changes to the token and/or value.
+ def munge_token(token, value)
+ @line += 1 if token.incr_line
- if @lasttoken == :DEFINE
- if indefine?
- msg = "Cannot nest definition %s inside %s" % [value, @indefine]
- self.indefine = false
- raise Puppet::ParseError, msg
- end
+ skip() if token.skip_text
- @indefine = value
- end
+ return if token.skip
- @last = value
- @lasttoken = ptoken
+ token, value = token.convert(self, value) if token.respond_to?(:convert)
- @scanner.skip(@skip)
- end
- @scanner = nil
- yield [false,false]
- end
+ return unless token
+
+ return token, value
+ end
+
+ # Go up one in the namespace.
+ def namepop
+ @namestack.pop
+ end
- # we've encountered an opening quote...
- # slurp in the rest of the string and return it
- def slurpstring(quote)
- # we search for the next quote that isn't preceded by a
- # backslash; the caret is there to match empty strings
- str = @scanner.scan_until(/([^\\]|^)#{quote}/)
- if str.nil?
- raise Puppet::LexError.new("Unclosed quote after '%s' in '%s'" %
- [self.last,self.rest])
+ # Collect the current namespace.
+ def namespace
+ @namestack.join("::")
+ end
+
+ # This value might have :: in it, but we don't care -- it'll be
+ # handled normally when joining, and when popping we want to pop
+ # this full value, however long the namespace is.
+ def namestack(value)
+ @namestack << value
+ end
+
+ def rest
+ @scanner.rest
+ end
+
+ # this is the heart of the lexer
+ def scan
+ #Puppet.debug("entering scan")
+ raise Puppet::LexError.new("Invalid or empty string") unless @scanner
+
+ # Skip any initial whitespace.
+ skip()
+
+ until @scanner.eos? do
+ yielded = false
+ matched_token, value = find_token
+
+ # error out if we didn't match anything at all
+ if matched_token.nil?
+ nword = nil
+ # Try to pull a 'word' out of the remaining string.
+ if @scanner.rest =~ /^(\S+)/
+ nword = $1
+ elsif @scanner.rest =~ /^(\s+)/
+ nword = $1
else
- str.sub!(/#{quote}\Z/,"")
- str.gsub!(/\\#{quote}/,quote)
+ nword = @scanner.rest
end
+ raise "Could not match '%s'" % nword
+ end
- return str
+ final_token, value = munge_token(matched_token, value)
+
+ next unless final_token
+
+ if match = @@pairs[value] and final_token.name != :DQUOTE and final_token.name != :SQUOTE
+ @expected << match
+ elsif exp = @expected[-1] and exp == value and final_token.name != :DQUOTE and final_token.name != :SQUOTE
+ @expected.pop
end
- # just parse a string, not a whole file
- def string=(string)
- @scanner = StringScanner.new(string)
+ yield [final_token.name, value]
+
+ if @previous_token
+ namestack(value) if @previous_token.name == :CLASS
+
+ if @previous_token.name == :DEFINE
+ if indefine?
+ msg = "Cannot nest definition %s inside %s" % [value, @indefine]
+ self.indefine = false
+ raise Puppet::ParseError, msg
+ end
+
+ @indefine = value
+ end
end
+
+ @previous_token = final_token
+ skip()
end
- #---------------------------------------------------------------
+ @scanner = nil
+
+ # This indicates that we're done parsing.
+ yield [false,false]
+ end
+
+ # Skip any skipchars in our remaining string.
+ def skip
+ @scanner.skip(@skip)
end
-end
+ # we've encountered an opening quote...
+ # slurp in the rest of the string and return it
+ def slurpstring(quote)
+ # we search for the next quote that isn't preceded by a
+ # backslash; the caret is there to match empty strings
+ str = @scanner.scan_until(/([^\\]|^)#{quote}/)
+ if str.nil?
+ raise Puppet::LexError.new("Unclosed quote after '%s' in '%s'" %
+ [self.last,self.rest])
+ else
+ str.sub!(/#{quote}\Z/,"")
+ str.gsub!(/\\#{quote}/,quote)
+ end
+
+ return str
+ end
+
+ # just parse a string, not a whole file
+ def string=(string)
+ @scanner = StringScanner.new(string)
+ end
+end
diff --git a/lib/puppet/parser/parser.rb b/lib/puppet/parser/parser.rb
index c3279d4e7..e27a209fc 100644
--- a/lib/puppet/parser/parser.rb
+++ b/lib/puppet/parser/parser.rb
@@ -29,7 +29,7 @@ module Puppet
class Parser < Racc::Parser
-module_eval <<'..end grammar.ra modeval..id9134b179f4', 'grammar.ra', 638
+module_eval <<'..end grammar.ra modeval..idfef5d70c9f', 'grammar.ra', 638
# It got too annoying having code in a file that needs to be compiled.
require 'puppet/parser/parser_support'
@@ -39,8 +39,9 @@ require 'puppet/parser/parser_support'
# mode: ruby
# End:
+# $Id$
-..end grammar.ra modeval..id9134b179f4
+..end grammar.ra modeval..idfef5d70c9f
##### racc 1.4.5 generates ###
@@ -956,7 +957,7 @@ module_eval <<'.,.,', 'grammar.ra', 174
def _reduce_38( val, _values, result )
type = val[0]
- if type == :exported and ! Puppet[:storeconfigs]
+ if (type == :exported and ! Puppet[:storeconfigs]) and ! Puppet[:parseonly]
error "You cannot collect without storeconfigs being set"
end
@@ -1009,7 +1010,7 @@ module_eval <<'.,.,', 'grammar.ra', 199
else
args[:form] = val[1]
end
- if args[:form] == :exported and ! Puppet[:storeconfigs]
+ if args[:form] == :exported and ! Puppet[:storeconfigs] and ! Puppet[:parseonly]
error "You cannot collect exported resources without storeconfigs being set"
end
result = ast AST::Collection, args
diff --git a/lib/puppet/parser/parser_support.rb b/lib/puppet/parser/parser_support.rb
index acf3c9f7c..b86a4792b 100644
--- a/lib/puppet/parser/parser_support.rb
+++ b/lib/puppet/parser/parser_support.rb
@@ -47,11 +47,8 @@ class Puppet::Parser::Parser
# Create an AST object, and automatically add the file and line information if
# available.
- def ast(klass, hash = nil)
- hash ||= {}
- unless hash.include?(:line)
- hash[:line] = @lexer.line
- end
+ def ast(klass, hash = {})
+ hash[:line] = @lexer.line unless hash.include?(:line)
unless hash.include?(:file)
if file = @lexer.file
@@ -126,13 +123,17 @@ class Puppet::Parser::Parser
def fqfind(namespace, name, table)
namespace = namespace.downcase
name = name.to_s.downcase
+
+ # If our classname is fully qualified or we have no namespace,
+ # just try directly for the class, and return either way.
if name =~ /^::/ or namespace == ""
classname = name.sub(/^::/, '')
- unless table[classname]
- self.load(classname)
- end
+ self.load(classname) unless table[classname]
return table[classname]
end
+
+ # Else, build our namespace up piece by piece, checking
+ # for the class in each namespace.
ary = namespace.split("::")
while ary.length > 0
@@ -180,7 +181,7 @@ class Puppet::Parser::Parser
"in file #{@lexer.file} at line #{@lexer.line}"
)
end
- files = Puppet::Module::find_manifests(pat, :cwd => dir)
+ files = Puppet::Module::find_manifests(pat, :cwd => dir, :environment => @environment)
if files.size == 0
raise Puppet::ImportError.new("No file(s) found for import " +
"of '#{pat}'")
@@ -224,7 +225,6 @@ class Puppet::Parser::Parser
return false if classname == ""
filename = classname.gsub("::", File::SEPARATOR)
- loaded = false
# First try to load the top-level module
mod = filename.scan(/^[\w-]+/).shift
unless @loaded.include?(mod)
@@ -232,24 +232,24 @@ class Puppet::Parser::Parser
begin
import(mod)
Puppet.info "Autoloaded module %s" % mod
- loaded = true
rescue Puppet::ImportError => detail
# We couldn't load the module
end
end
- unless filename == mod and ! @loaded.include?(mod)
- @loaded << mod
+ return true if classes.include?(classname)
+
+ unless @loaded.include?(filename)
+ @loaded << filename
# Then the individual file
begin
import(filename)
Puppet.info "Autoloaded file %s from module %s" % [filename, mod]
- loaded = true
rescue Puppet::ImportError => detail
# We couldn't load the file
end
end
- return loaded
+ return classes.include?(classname)
end
# Split an fq name into a namespace and name
diff --git a/lib/puppet/parser/resource.rb b/lib/puppet/parser/resource.rb
index 3f346166e..4b48ff6cf 100644
--- a/lib/puppet/parser/resource.rb
+++ b/lib/puppet/parser/resource.rb
@@ -3,18 +3,18 @@
class Puppet::Parser::Resource
require 'puppet/parser/resource/param'
require 'puppet/parser/resource/reference'
+ require 'puppet/util/tagging'
include Puppet::Util
include Puppet::Util::MethodHelper
include Puppet::Util::Errors
include Puppet::Util::Logging
+ include Puppet::Util::Tagging
attr_accessor :source, :line, :file, :scope, :rails_id
attr_accessor :virtual, :override, :translated
attr_reader :exported, :evaluated, :params
- attr_writer :tags
-
# Determine whether the provided parameter name is a relationship parameter.
def self.relationship_parameter?(name)
unless defined?(@relationship_names)
@@ -58,8 +58,7 @@ class Puppet::Parser::Resource
def evaluate
if klass = @ref.definedtype
finish()
- scope.compile.delete_resource(self)
- return klass.evaluate(:scope => scope, :resource => self)
+ return klass.evaluate_code(self)
elsif builtin?
devfail "Cannot evaluate a builtin type"
else
@@ -83,12 +82,19 @@ class Puppet::Parser::Resource
# Do any finishing work on this object, called before evaluation or
# before storage/translation.
def finish
- add_overrides()
+ return if finished?
+ @finished = true
add_defaults()
add_metaparams()
+ add_scope_tags()
validate()
end
+ # Has this resource already been finished?
+ def finished?
+ defined?(@finished) and @finished
+ end
+
def initialize(options)
# Set all of the options we can.
options.each do |option, value|
@@ -130,12 +136,16 @@ class Puppet::Parser::Resource
raise ArgumentError, "Resources do not accept %s" % options.keys.collect { |k| k.to_s }.join(", ")
end
- @tags = []
tag(@ref.type)
- tag(@ref.title) if @ref.title.to_s =~ /^[-\w]+$/
+ tag(@ref.title) if valid_tag?(@ref.title.to_s)
+ end
- if scope.resource
- @tags += scope.resource.tags
+ # Is this resource modeling an isomorphic resource type?
+ def isomorphic?
+ if builtin?
+ return @ref.builtintype.isomorphic?
+ else
+ return true
end
end
@@ -223,21 +233,18 @@ class Puppet::Parser::Resource
@ref.to_s
end
- # Add a tag to our current list. These tags will be added to all
- # of the objects contained in this scope.
- def tag(*ary)
- ary.collect { |tag| tag.to_s.downcase }.collect { |tag| tag.split("::") }.flatten.each do |tag|
- unless tag =~ /^\w[-\w]*$/
- fail Puppet::ParseError, "Invalid tag %s" % tag.inspect
- end
- unless @tags.include?(tag)
- @tags << tag
- end
+ # Define a parameter in our resource.
+ def set_parameter(param, value = nil)
+ if value
+ param = Puppet::Parser::Resource::Param.new(
+ :name => param, :value => value, :source => self.source
+ )
+ elsif ! param.is_a?(Puppet::Parser::Resource::Param)
+ raise ArgumentError, "Must pass a parameter or all necessary values"
end
- end
- def tags
- @tags.dup
+ # And store it in our parameter hash.
+ @params[param.name] = param
end
def to_hash
@@ -260,6 +267,8 @@ class Puppet::Parser::Resource
# Handle file specially
db_resource.file = self.file
+ db_resource.save
+
@params.each { |name, param|
param.to_rails(db_resource)
}
@@ -336,7 +345,7 @@ class Puppet::Parser::Resource
unless @params.include?(name)
self.debug "Adding default for %s" % name
- @params[name] = param
+ @params[name] = param.dup
end
end
end
@@ -361,16 +370,9 @@ class Puppet::Parser::Resource
end
end
- # Add any overrides for this object.
- def add_overrides
- if overrides = scope.compile.resource_overrides(self)
- overrides.each do |over|
- self.merge(over)
- end
-
- # Remove the overrides, so that the configuration knows there
- # are none left.
- overrides.clear
+ def add_scope_tags
+ if scope_resource = scope.resource
+ tag(*scope_resource.tags)
end
end
@@ -382,11 +384,8 @@ class Puppet::Parser::Resource
# The parameter is already set. Fail if they're not allowed to override it.
unless param.source.child_of?(current.source)
- if Puppet[:trace]
- puts caller
- end
- msg = "Parameter '%s' is already set on %s" %
- [param.name, self.to_s]
+ puts caller if Puppet[:trace]
+ msg = "Parameter '%s' is already set on %s" % [param.name, self.to_s]
if current.source.to_s != ""
msg += " by %s" % current.source
end
@@ -438,20 +437,6 @@ class Puppet::Parser::Resource
end
end
- # Define a parameter in our resource.
- def set_parameter(param, value = nil)
- if value
- param = Puppet::Parser::Resource::Param.new(
- :name => param, :value => value, :source => self.source
- )
- elsif ! param.is_a?(Puppet::Parser::Resource::Param)
- raise ArgumentError, "Must pass a parameter or all necessary values"
- end
-
- # And store it in our parameter hash.
- @params[param.name] = param
- end
-
# Make sure the resource's parameters are all valid for the type.
def validate
@params.each do |name, param|
diff --git a/lib/puppet/parser/resource/param.rb b/lib/puppet/parser/resource/param.rb
index 9352311d6..9dd3f26d2 100644
--- a/lib/puppet/parser/resource/param.rb
+++ b/lib/puppet/parser/resource/param.rb
@@ -12,7 +12,7 @@ class Puppet::Parser::Resource::Param
end
def inspect
- "#<#{self.class} @name => #{self.name}, @value => #{self.value}, @source => #{self.source.name}>"
+ "#<#{self.class} @name => #{name}, @value => #{value}, @source => #{source.name}>"
end
def line_to_i
diff --git a/lib/puppet/parser/resource/reference.rb b/lib/puppet/parser/resource/reference.rb
index 6e70d23b7..c59748049 100644
--- a/lib/puppet/parser/resource/reference.rb
+++ b/lib/puppet/parser/resource/reference.rb
@@ -37,10 +37,14 @@ class Puppet::Parser::Resource::Reference < Puppet::ResourceReference
if self.title == :main
tmp = @scope.findclass("")
else
- tmp = @scope.findclass(self.title)
+ unless tmp = @scope.findclass(self.title)
+ fail Puppet::ParseError, "Could not find class '%s'" % self.title
+ end
end
when "Node": # look for node definitions
- tmp = @scope.parser.nodes[self.title]
+ unless tmp = @scope.parser.nodes[self.title]
+ fail Puppet::ParseError, "Could not find node '%s'" % self.title
+ end
else # normal definitions
# We have to swap these variables around so the errors are right.
tmp = @scope.finddefine(self.type)
@@ -49,7 +53,7 @@ class Puppet::Parser::Resource::Reference < Puppet::ResourceReference
if tmp
@definedtype = tmp
else
- fail Puppet::ParseError, "Could not find resource '%s'" % self
+ fail Puppet::ParseError, "Could not find resource type '%s'" % self.type
end
end
diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
index 028414cc0..a6e43e7b3 100644
--- a/lib/puppet/parser/scope.rb
+++ b/lib/puppet/parser/scope.rb
@@ -17,15 +17,20 @@ class Puppet::Parser::Scope
include Puppet::Util::Errors
attr_accessor :parent, :level, :parser, :source, :resource
attr_accessor :base, :keyword, :nodescope
- attr_accessor :top, :translated, :compile
+ attr_accessor :top, :translated, :compiler
+
+ # A demeterific shortcut to the catalog.
+ def catalog
+ compiler.catalog
+ end
# Proxy accessors
def host
- @compile.node.name
+ @compiler.node.name
end
def interpreter
- @compile.interpreter
+ @compiler.interpreter
end
# Is the value true? This allows us to control the definition of truth
@@ -72,7 +77,7 @@ class Puppet::Parser::Scope
end
def findresource(string, name = nil)
- compile.findresource(string, name)
+ compiler.findresource(string, name)
end
# Initialize our new scope. Defaults to having no parent.
@@ -147,7 +152,7 @@ class Puppet::Parser::Scope
unless klass
raise Puppet::ParseError, "Could not find class %s" % klassname
end
- unless kscope = compile.class_scope(klass)
+ unless kscope = compiler.class_scope(klass)
raise Puppet::ParseError, "Class %s has not been evaluated so its variables cannot be referenced" % klass.classname
end
return kscope.lookupvar(shortname, usestring)
@@ -184,7 +189,7 @@ class Puppet::Parser::Scope
# Create a new scope and set these options.
def newscope(options = {})
- compile.newscope(self, options)
+ compiler.newscope(self, options)
end
# Is this class for a node? This is used to make sure that
@@ -199,7 +204,7 @@ class Puppet::Parser::Scope
# than doing lots of queries.
def parent
unless defined?(@parent)
- @parent = compile.parent(self)
+ @parent = compiler.parent(self)
end
@parent
end
diff --git a/lib/puppet/parser/templatewrapper.rb b/lib/puppet/parser/templatewrapper.rb
index 13823d483..7a8f74156 100644
--- a/lib/puppet/parser/templatewrapper.rb
+++ b/lib/puppet/parser/templatewrapper.rb
@@ -7,7 +7,7 @@ class Puppet::Parser::TemplateWrapper
def initialize(scope, file)
@scope = scope
- @file = Puppet::Module::find_template(file, @scope.compile.environment)
+ @file = Puppet::Module::find_template(file, @scope.compiler.environment)
unless FileTest.exists?(@file)
raise Puppet::ParseError,
diff --git a/lib/puppet/pgraph.rb b/lib/puppet/pgraph.rb
index 54b815b45..3bcc2ced0 100644
--- a/lib/puppet/pgraph.rb
+++ b/lib/puppet/pgraph.rb
@@ -7,38 +7,18 @@ require 'puppet/simple_graph'
# This class subclasses a graph class in order to handle relationships
# among resources.
class Puppet::PGraph < Puppet::SimpleGraph
- # This is the type used for splicing.
- attr_accessor :container_type
-
include Puppet::Util
- def add_edge!(*args)
+ def add_edge(*args)
@reversal = nil
super
end
- def add_vertex!(*args)
+ def add_vertex(*args)
@reversal = nil
super
end
- # Make sure whichever edge has a label keeps the label
- def copy_label(source, target, label)
- # 'require' relationships will not have a label,
- # and all 'subscribe' relationships have the same
- # label, at least for now.
-
- # Labels default to {}, so we can't just test for nil.
- newlabel = label || {}
- oldlabel = edge_label(source, target) || {}
- if ! newlabel.empty? and oldlabel.empty?
- edge_label_set(source, target, label)
- # We should probably check to see if the labels both exist
- # and don't match, but we'd just throw an error which the user
- # couldn't do anyting about.
- end
- end
-
# Which resources a given resource depends upon.
def dependents(resource)
tree_from_vertex(resource).keys
@@ -57,11 +37,6 @@ class Puppet::PGraph < Puppet::SimpleGraph
@reversal.tree_from_vertex(resource, :out).keys
end
- # Override this method to use our class instead.
- def edge_class()
- Puppet::Relationship
- end
-
# Determine all of the leaf nodes below a given vertex.
def leaves(vertex, direction = :out)
tree = tree_from_vertex(vertex, direction)
@@ -123,23 +98,11 @@ class Puppet::PGraph < Puppet::SimpleGraph
t = edge.target
end
- # We don't want to add multiple copies of the
- # same edge, but we *do* want to make sure we
- # keep labels around.
- # XXX This will *not* work when we support multiple
- # types of labels, and only works now because
- # you can only do simple subscriptions.
- if edge?(s, t)
- copy_label(s, t, edge.label)
- next
- end
- add_edge!(s, t, edge.label)
+ add_edge(s, t, edge.label)
end
# Now get rid of the edge, so remove_vertex! works correctly.
remove_edge!(edge)
- Puppet.debug "%s: %s => %s: %s" % [container,
- edge.source, edge.target, edge?(edge.source, edge.target)]
end
end
remove_vertex!(container)
diff --git a/lib/puppet/provider/interface/redhat.rb b/lib/puppet/provider/interface/redhat.rb
index aa217620e..4a9fcb491 100644
--- a/lib/puppet/provider/interface/redhat.rb
+++ b/lib/puppet/provider/interface/redhat.rb
@@ -5,7 +5,7 @@ Puppet::Type.type(:interface).provide(:redhat) do
desc "Manage network interfaces on Red Hat operating systems. This provider
parses and generates configuration files in ``/etc/sysconfig/network-scripts``."
- INTERFACE_DIR = "/etc/sysconfig/network-scripts"
+ INTERFACE_DIR = "/etc/sysconfig/network-scripts"
confine :exists => INTERFACE_DIR
defaultfor :operatingsystem => [:fedora, :centos, :redhat]
@@ -43,52 +43,52 @@ NETMASK=<%= self.netmask %>
BROADCAST=
LOOPBACKDUMMY
- # maximum number of dummy interfaces
- @max_dummies = 10
+ # maximum number of dummy interfaces
+ @max_dummies = 10
- # maximum number of aliases per interface
- @max_aliases_per_iface = 10
+ # maximum number of aliases per interface
+ @max_aliases_per_iface = 10
- @@dummies = []
- @@aliases = Hash.new { |hash, key| hash[key] = [] }
+ @@dummies = []
+ @@aliases = Hash.new { |hash, key| hash[key] = [] }
- # calculate which dummy interfaces are currently already in
- # use prior to needing to call self.next_dummy later on.
- def self.instances
- # parse all of the config files at once
- Dir.glob("%s/ifcfg-*" % INTERFACE_DIR).collect do |file|
- record = parse(file)
+ # calculate which dummy interfaces are currently already in
+ # use prior to needing to call self.next_dummy later on.
+ def self.instances
+ # parse all of the config files at once
+ Dir.glob("%s/ifcfg-*" % INTERFACE_DIR).collect do |file|
+ record = parse(file)
- # store the existing dummy interfaces
+ # store the existing dummy interfaces
@@dummies << record[:ifnum] if (record[:interface_type] == :dummy and ! @@dummies.include?(record[:ifnum]))
@@aliases[record[:interface]] << record[:ifnum] if record[:interface_type] == :alias
new(record)
- end
- end
-
- # return the next avaliable dummy interface number, in the case where
- # ifnum is not manually specified
- def self.next_dummy
- @max_dummies.times do |i|
- unless @@dummies.include?(i.to_s)
- @@dummies << i.to_s
- return i.to_s
- end
- end
- end
-
- # return the next available alias on a given interface, in the case
- # where ifnum if not manually specified
- def self.next_alias(interface)
- @max_aliases_per_iface.times do |i|
- unless @@aliases[interface].include?(i.to_s)
- @@aliases[interface] << i.to_s
- return i.to_s
- end
- end
- end
+ end
+ end
+
+ # return the next avaliable dummy interface number, in the case where
+ # ifnum is not manually specified
+ def self.next_dummy
+ @max_dummies.times do |i|
+ unless @@dummies.include?(i.to_s)
+ @@dummies << i.to_s
+ return i.to_s
+ end
+ end
+ end
+
+ # return the next available alias on a given interface, in the case
+ # where ifnum if not manually specified
+ def self.next_alias(interface)
+ @max_aliases_per_iface.times do |i|
+ unless @@aliases[interface].include?(i.to_s)
+ @@aliases[interface] << i.to_s
+ return i.to_s
+ end
+ end
+ end
# base the ifnum, for dummy / loopback interface in linux
# on the last octect of the IP address
@@ -139,14 +139,14 @@ LOOPBACKDUMMY
# on whether we are adding an alias to a real interface, or a loopback
# address (also dummy) on linux. For linux it's quite involved, and we
# will use an ERB template
- def generate
+ def generate
itype = self.interface_type == :alias ? :alias : :normal
self.class.template(itype).result(binding)
- end
+ end
# Where should the file be written out?
- # This defaults to INTERFACE_DIR/ifcfg-<namevar>, but can have a
- # more symbolic name by setting interface_desc in the type.
+ # This defaults to INTERFACE_DIR/ifcfg-<namevar>, but can have a
+ # more symbolic name by setting interface_desc in the type.
def file_path
if resource and val = resource[:interface_desc]
desc = val
@@ -185,16 +185,16 @@ LOOPBACKDUMMY
end
end
- # create the device name, so this based on the IP, and interface + type
- def device
- case @resource.should(:interface_type)
- when :loopback
- @property_hash[:ifnum] ||= self.class.next_dummy
- return "dummy" + @property_hash[:ifnum]
- when :alias
- @property_hash[:ifnum] ||= self.class.next_alias(@resource[:interface])
- return @resource[:interface] + ":" + @property_hash[:ifnum]
- end
+ # create the device name, so this based on the IP, and interface + type
+ def device
+ case @resource.should(:interface_type)
+ when :loopback
+ @property_hash[:ifnum] ||= self.class.next_dummy
+ return "dummy" + @property_hash[:ifnum]
+ when :alias
+ @property_hash[:ifnum] ||= self.class.next_alias(@resource[:interface])
+ return @resource[:interface] + ":" + @property_hash[:ifnum]
+ end
end
# Set the name to our ip address.
@@ -202,19 +202,19 @@ LOOPBACKDUMMY
@property_hash[:name] = value
end
- # whether the device is to be brought up on boot or not. converts
- # the true / false of the type, into yes / no values respectively
- # writing out the ifcfg-* files
- def on_boot
- case @property_hash[:onboot].to_s
- when "true"
- return "yes"
- when "false"
- return "no"
- else
- return "neither"
- end
- end
+ # whether the device is to be brought up on boot or not. converts
+ # the true / false of the type, into yes / no values respectively
+ # writing out the ifcfg-* files
+ def on_boot
+ case @property_hash[:onboot].to_s
+ when "true"
+ return "yes"
+ when "false"
+ return "no"
+ else
+ return "neither"
+ end
+ end
# Mark whether the interface should be started on boot.
def on_boot=(value)
diff --git a/lib/puppet/provider/mailalias/aliases.rb b/lib/puppet/provider/mailalias/aliases.rb
index 85dec29cc..8b5c45617 100755
--- a/lib/puppet/provider/mailalias/aliases.rb
+++ b/lib/puppet/provider/mailalias/aliases.rb
@@ -10,7 +10,10 @@ Puppet::Type.type(:mailalias).provide(:aliases,
record_line :aliases, :fields => %w{name recipient}, :separator => /\s*:\s*/, :block_eval => :instance do
def post_parse(record)
- record[:recipient] = record[:recipient].split(/\s*,\s*/).collect { |d| d.gsub(/^['"]|['"]$/, '') }
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ # It's not sufficient to assign to an existing hash.
+ recipient = record[:recipient].split(/\s*,\s*/).collect { |d| d.gsub(/^['"]|['"]$/, '') }
+ record[:recipient] = recipient
record
end
diff --git a/lib/puppet/provider/nameservice/directoryservice.rb b/lib/puppet/provider/nameservice/directoryservice.rb
index b2ccfbd4e..e2e68b2ca 100644
--- a/lib/puppet/provider/nameservice/directoryservice.rb
+++ b/lib/puppet/provider/nameservice/directoryservice.rb
@@ -139,10 +139,12 @@ class DirectoryService < Puppet::Provider::NameService
dscl_output.split("\n").each do |line|
# JJM: Split the attribute name and the list of values.
ds_attribute, ds_values_string = line.split(':')
+
+ # Split sets the values to nil if there's nothing after the :
+ ds_values_string ||= ""
# JJM: skip this attribute line if the Puppet::Type doesn't care about it.
- next unless (@@ds_to_ns_attribute_map.keys.include?(ds_attribute) \
- and type_properties.include? @@ds_to_ns_attribute_map[ds_attribute])
+ next unless (@@ds_to_ns_attribute_map.keys.include?(ds_attribute) and type_properties.include? @@ds_to_ns_attribute_map[ds_attribute])
# JJM: We asked dscl to output url encoded values so we're able
# to machine parse on whitespace. We need to urldecode:
@@ -178,11 +180,8 @@ class DirectoryService < Puppet::Provider::NameService
# This method spits out proper DSCL commands for us.
# We EXPECT name to be @resource[:name] when called from an instance object.
- # JJM: With dscl, the domain "/" is always the default local domain.
- # The domain /Search will search all domains, and you may
- # get at specific domains with /LDAPv3/server1.foobar.com,
- # /LDAPv3/server2.foobar.com, etc...
- command_vector = [ command(:dscl), "-url", "/" ]
+ # There are two ways to specify paths in 10.5. See man dscl.
+ command_vector = [ command(:dscl), "-url", "." ]
# JJM: The actual action to perform. See "man dscl"
# Common actiosn: -create, -delete, -merge, -append, -passwd
command_vector << ds_action
diff --git a/lib/puppet/provider/package/fink.rb b/lib/puppet/provider/package/fink.rb
index e0933df08..030e1a347 100755
--- a/lib/puppet/provider/package/fink.rb
+++ b/lib/puppet/provider/package/fink.rb
@@ -9,8 +9,6 @@ Puppet::Type.type(:package).provide :fink, :parent => :dpkg, :source => :dpkg do
commands :aptcache => "/sw/bin/apt-cache"
commands :dpkgquery => "/sw/bin/dpkg-query"
- defaultfor :operatingsystem => :darwin
-
has_feature :versionable
# A derivative of DPKG; this is how most people actually manage
diff --git a/lib/puppet/provider/package/gem.rb b/lib/puppet/provider/package/gem.rb
index 6e777a735..bb09bc5b0 100755
--- a/lib/puppet/provider/package/gem.rb
+++ b/lib/puppet/provider/package/gem.rb
@@ -23,14 +23,14 @@ Puppet::Type.type(:package).provide :gem, :parent => Puppet::Provider::Package d
end
begin
- list = execute(command).split("\n\n").collect do |set|
+ list = execute(command).split("\n").collect do |set|
if gemhash = gemsplit(set)
gemhash[:provider] = :gem
gemhash
else
nil
end
- end.reject { |p| p.nil? }
+ end.compact
rescue Puppet::ExecutionFailure => detail
raise Puppet::Error, "Could not list gems: %s" % detail
end
@@ -44,8 +44,8 @@ Puppet::Type.type(:package).provide :gem, :parent => Puppet::Provider::Package d
def self.gemsplit(desc)
case desc
- when /^\*\*\*/: return nil
- when /^(\S+)\s+\((.+)\)\n/
+ when /^\*\*\*/, /^\s*$/, /^\s+/; return nil
+ when /^(\S+)\s+\((.+)\)/
name = $1
version = $2.split(/,\s*/)[0]
return {
@@ -78,7 +78,11 @@ Puppet::Type.type(:package).provide :gem, :parent => Puppet::Provider::Package d
command << @resource[:name]
end
- gemcmd(*command)
+ output = gemcmd(*command)
+ # Apparently some stupid gem versions don't exit non-0 on failure
+ if output.include?("ERROR")
+ self.fail "Could not install: %s" % output.chomp
+ end
end
def latest
diff --git a/lib/puppet/provider/package/openbsd.rb b/lib/puppet/provider/package/openbsd.rb
index ce69dd432..af590eb4d 100755
--- a/lib/puppet/provider/package/openbsd.rb
+++ b/lib/puppet/provider/package/openbsd.rb
@@ -2,6 +2,7 @@ require 'puppet/provider/package'
# Packaging on OpenBSD. Doesn't work anywhere else that I know of.
Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Package do
+ include Puppet::Util::Execution
desc "OpenBSD's form of ``pkg_add`` support."
commands :pkginfo => "pkg_info", :pkgadd => "pkg_add", :pkgdelete => "pkg_delete"
@@ -58,7 +59,14 @@ Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Packa
"You must specify a package source for BSD packages"
end
- pkgadd @resource[:source]
+ if @resource[:source] =~ /\/$/
+ withenv :PKG_PATH => @resource[:source] do
+ pkgadd @resource[:name]
+ end
+ else
+ pkgadd @resource[:source]
+ end
+
end
def query
@@ -66,8 +74,8 @@ Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Packa
info = pkginfo @resource[:name]
# Search for the version info
- if info =~ /Information for #{@resource[:name]}-(\S+)/
- hash[:ensure] = $1
+ if info =~ /Information for (inst:)?#{@resource[:name]}-(\S+)/
+ hash[:ensure] = $2
else
return nil
end
diff --git a/lib/puppet/provider/package/pkgdmg.rb b/lib/puppet/provider/package/pkgdmg.rb
index 2020b6b56..2614d0950 100644
--- a/lib/puppet/provider/package/pkgdmg.rb
+++ b/lib/puppet/provider/package/pkgdmg.rb
@@ -145,11 +145,8 @@ file system and not via a URL method."
begin
open(cached_source) do |dmg|
xml_str = hdiutil "mount", "-plist", "-nobrowse", "-readonly", "-noidme", "-mountrandom", "/tmp", dmg.path
- ptable = Plist::parse_xml xml_str
- # JJM Filter out all mount-paths into a single array, discard the rest.
- mounts = ptable['system-entities'].collect { |entity|
- entity['mount-point']
- }.select { |mountloc|; mountloc }
+ # JJM THIS IS A HORRIBLE HACK (Well, actually it's not so bad...)
+ mounts = xml_str.scan(/<string>(\/tmp.*?)<\/string>/)[0]
begin
mounts.each do |fspath|
Dir.entries(fspath).select { |f|
diff --git a/lib/puppet/provider/package/portage.rb b/lib/puppet/provider/package/portage.rb
index 03274a78d..f795d0302 100644
--- a/lib/puppet/provider/package/portage.rb
+++ b/lib/puppet/provider/package/portage.rb
@@ -10,8 +10,8 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
defaultfor :operatingsystem => :gentoo
def self.instances
- result_format = /(\S+) (\S+) \[([^\[]*)(\[[^\]]*\])?\] \[[^0-9]*([^\s:\[]*)(\[[^\]]*\])?(:\S*)?\] ([\S]*) (.*)/
- result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :overlay, :slot, :vendor, :description]
+ result_format = /(\S+) (\S+) \[(?:([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\([^\)]+\))?(?:\[([^\]]+)\])?[ ]*)*\] \[(?:(?:\{M\})?(?:\([~*]+\))?([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\(([^\)]+)\))?(?:![mf])*(?:\[([^\]]+)\])?)?\] ([\S]*) (.*)/
+ result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :slot, :overlay, :vendor, :description]
search_format = "{installedversionsshort}<category> <name> [<installedversionsshort>] [<best>] <homepage> <description>{}"
@@ -39,7 +39,7 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
return packages
rescue Puppet::ExecutionFailure => detail
- raise Puppet::PackageError.new(detail)
+ raise Puppet::Error.new(detail)
end
end
@@ -67,8 +67,8 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
end
def query
- result_format = /(\S+) (\S+) \[([^\[]*)(\[[^\]]*\])?\] \[[^0-9]*([^\s:\[]*)(\[[^\]]*\])?(:\S*)?\] ([\S]*) (.*)/
- result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :overlay, :slot, :vendor, :description]
+ result_format = /(\S+) (\S+) \[(?:([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\([^\)]+\))?(?:\[([^\]]+)\])?[ ]*)*\] \[(?:(?:\{M\})?(?:\([~*]+\))?([0-9.a-zA-Z]+(?:_(?:alpha|beta|pre|rc|p)[0-9]*)*(?:-r[0-9]*)?)(?:\(([^\)]+)\))?(?:![mf])*(?:\[([^\]]+)\])?)?\] ([\S]*) (.*)/
+ result_fields = [:category, :name, :ensure, :ensure_overlay, :version_available, :slot, :overlay, :vendor, :description]
search_field = @resource[:category] ? "--category-name" : "--name"
search_value = package_name
@@ -99,14 +99,14 @@ Puppet::Type.type(:package).provide :portage, :parent => Puppet::Provider::Packa
case packages.size
when 0
not_found_value = "%s/%s" % [@resource[:category] ? @resource[:category] : "<unspecified category>", @resource[:name]]
- raise Puppet::PackageError.new("No package found with the specified name [#{not_found_value}]")
+ raise Puppet::Error.new("No package found with the specified name [#{not_found_value}]")
when 1
return packages[0]
else
- raise Puppet::PackageError.new("More than one package with the specified name [#{search_value}], please use the category parameter to disambiguate")
+ raise Puppet::Error.new("More than one package with the specified name [#{search_value}], please use the category parameter to disambiguate")
end
rescue Puppet::ExecutionFailure => detail
- raise Puppet::PackageError.new(detail)
+ raise Puppet::Error.new(detail)
end
end
diff --git a/lib/puppet/provider/package/ports.rb b/lib/puppet/provider/package/ports.rb
index 8c7f79e0a..1cff30039 100755
--- a/lib/puppet/provider/package/ports.rb
+++ b/lib/puppet/provider/package/ports.rb
@@ -1,6 +1,5 @@
Puppet::Type.type(:package).provide :ports, :parent => :freebsd, :source => :freebsd do
- desc "Support for FreeBSD's ports. Again, this still mixes packages
- and ports."
+ desc "Support for FreeBSD's ports. Again, this still mixes packages and ports."
commands :portupgrade => "/usr/local/sbin/portupgrade",
:portversion => "/usr/local/sbin/portversion",
diff --git a/lib/puppet/provider/package/yumhelper.py b/lib/puppet/provider/package/yumhelper.py
index 1142401b9..962b96ce4 100644
--- a/lib/puppet/provider/package/yumhelper.py
+++ b/lib/puppet/provider/package/yumhelper.py
@@ -13,8 +13,7 @@ OVERRIDE_OPTS = {
'logfile': '/dev/null'
}
-def pkg_lists():
- my = yum.YumBase()
+def pkg_lists(my):
my.doConfigSetup()
for k in OVERRIDE_OPTS.keys():
@@ -28,10 +27,13 @@ def pkg_lists():
return my.doPackageLists('updates')
try:
- ypl = pkg_lists()
+ try:
+ my = yum.YumBase()
+ ypl = pkg_lists(my)
+ for pkg in ypl.updates:
+ print "_pkg %s %s %s %s %s" % (pkg.name, pkg.epoch, pkg.version, pkg.release, pkg.arch)
+ finally:
+ my.closeRpmDB()
except IOError, e:
print "_err IOError %d %s" % (e.errno, e)
sys.exit(1)
-
-for pkg in ypl.updates:
- print "_pkg %s %s %s %s %s" % (pkg.name, pkg.epoch, pkg.version, pkg.release, pkg.arch)
diff --git a/lib/puppet/provider/service/debian.rb b/lib/puppet/provider/service/debian.rb
index 233242a1c..f0f6fe1ef 100755
--- a/lib/puppet/provider/service/debian.rb
+++ b/lib/puppet/provider/service/debian.rb
@@ -14,6 +14,7 @@ Puppet::Type.type(:service).provide :debian, :parent => :init do
# Remove the symlinks
def disable
update "-f", @resource[:name], "remove"
+ update @resource[:name], "stop", "00", "1", "2", "3", "4", "5", "6", "."
end
def enabled?
@@ -29,7 +30,7 @@ Puppet::Type.type(:service).provide :debian, :parent => :init do
end
def enable
+ update "-f", @resource[:name], "remove"
update @resource[:name], "defaults"
end
end
-
diff --git a/lib/puppet/provider/service/gentoo.rb b/lib/puppet/provider/service/gentoo.rb
index 2dcc3e9c1..adbee6970 100644
--- a/lib/puppet/provider/service/gentoo.rb
+++ b/lib/puppet/provider/service/gentoo.rb
@@ -8,6 +8,10 @@ Puppet::Type.type(:service).provide :gentoo, :parent => :init do
defaultfor :operatingsystem => :gentoo
+ def self.defpath
+ superclass.defpath
+ end
+
def disable
begin
output = update :del, @resource[:name], :default
diff --git a/lib/puppet/provider/service/init.rb b/lib/puppet/provider/service/init.rb
index d9919f58c..274c334a3 100755
--- a/lib/puppet/provider/service/init.rb
+++ b/lib/puppet/provider/service/init.rb
@@ -110,7 +110,7 @@ Puppet::Type.type(:service).provide :init, :parent => :base do
# we just return that; otherwise, we return false, which causes it to
# fallback to other mechanisms.
def statuscmd
- if @resource[:hasstatus]
+ if @resource[:hasstatus] == :true
return [self.initscript, :status]
else
return false
diff --git a/lib/puppet/provider/sshkey/parsed.rb b/lib/puppet/provider/sshkey/parsed.rb
index cb1010c5b..6f7d98f56 100755
--- a/lib/puppet/provider/sshkey/parsed.rb
+++ b/lib/puppet/provider/sshkey/parsed.rb
@@ -12,6 +12,8 @@ Puppet::Type.type(:sshkey).provide(:parsed,
:default_target => known,
:filetype => :flat
) do
+ desc "Parse and generate host-wide known hosts files for SSH."
+
text_line :comment, :match => /^#/
text_line :blank, :match => /^\s+/
diff --git a/lib/puppet/provider/user/useradd.rb b/lib/puppet/provider/user/useradd.rb
index c2476203a..e64601ee0 100644
--- a/lib/puppet/provider/user/useradd.rb
+++ b/lib/puppet/provider/user/useradd.rb
@@ -1,7 +1,7 @@
require 'puppet/provider/nameservice/objectadd'
Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameService::ObjectAdd do
- desc "User management via ``useradd`` and its ilk. Note that you'll have to install the ``Shadow Password`` library to manage user passwords."
+ desc "User management via ``useradd`` and its ilk. Note that you will need to install the ``Shadow Password`` Ruby library often known as ruby-libshadow to manage user passwords."
commands :add => "useradd", :delete => "userdel", :modify => "usermod"
@@ -19,7 +19,7 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
has_features :manages_homedir, :allows_duplicates
- if Puppet.features.libshadow? and (Facter.value(:kernel) == "Linux")
+ if Puppet.features.libshadow?
has_feature :manages_passwords
end
diff --git a/lib/puppet/provider/zone/solaris.rb b/lib/puppet/provider/zone/solaris.rb
index dd8698b92..be2dd97f9 100644
--- a/lib/puppet/provider/zone/solaris.rb
+++ b/lib/puppet/provider/zone/solaris.rb
@@ -26,7 +26,8 @@ Puppet::Type.type(:zone).provide(:solaris) do
end
def self.instances
- adm(:list, "-cp").split("\n").collect do |line|
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = adm(:list, "-cp").split("\n").collect do |line|
new(line2hash(line))
end
end
diff --git a/lib/puppet/rails.rb b/lib/puppet/rails.rb
index a1192bf20..a021c773a 100644
--- a/lib/puppet/rails.rb
+++ b/lib/puppet/rails.rb
@@ -91,6 +91,10 @@ module Puppet::Rails
raise Puppet::Error, "Could not find Puppet::Rails database dir"
end
+ unless ActiveRecord::Base.connection.tables.include?("resources")
+ raise Puppet::Error, "Database has problems, can't migrate."
+ end
+
Puppet.notice "Migrating"
begin
diff --git a/lib/puppet/rails/database/001_add_created_at_to_all_tables.rb b/lib/puppet/rails/database/001_add_created_at_to_all_tables.rb
new file mode 100644
index 000000000..71ee6aeed
--- /dev/null
+++ b/lib/puppet/rails/database/001_add_created_at_to_all_tables.rb
@@ -0,0 +1,17 @@
+class AddCreatedAtToAllTables < ActiveRecord::Migration
+ def self.up
+ ActiveRecord::Base.connection.tables.each do |t|
+ unless ActiveRecord::Base.connection.columns(t).collect {|c| c.name}.include?("created_at")
+ add_column t.to_s, :created_at, :datetime
+ end
+ end
+ end
+
+ def self.down
+ ActiveRecord::Base.connection.tables.each do |t|
+ unless ActiveRecord::Base.connection.columns(t).collect {|c| c.name}.include?("created_at")
+ remove_column t.to_s, :created_at
+ end
+ end
+ end
+end
diff --git a/lib/puppet/rails/external/tagging/README b/lib/puppet/rails/external/tagging/README
deleted file mode 100644
index 8d2f90822..000000000
--- a/lib/puppet/rails/external/tagging/README
+++ /dev/null
@@ -1,4 +0,0 @@
-Acts As Taggable
-=================
-
-Allows for tags to be added to multiple classes. \ No newline at end of file
diff --git a/lib/puppet/rails/external/tagging/acts_as_taggable.rb b/lib/puppet/rails/external/tagging/acts_as_taggable.rb
deleted file mode 100644
index 7fd7f6b12..000000000
--- a/lib/puppet/rails/external/tagging/acts_as_taggable.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-module ActiveRecord
- module Acts #:nodoc:
- module Taggable #:nodoc:
- def self.included(base)
- base.extend(ClassMethods)
- end
-
- module ClassMethods
- def acts_as_taggable(options = {})
- write_inheritable_attribute(:acts_as_taggable_options, {
- :taggable_type => ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s,
- :from => options[:from]
- })
-
- class_inheritable_reader :acts_as_taggable_options
-
- has_many :taggings, :as => :taggable, :dependent => :destroy
- has_many :tags, :through => :taggings
-
- include ActiveRecord::Acts::Taggable::InstanceMethods
- extend ActiveRecord::Acts::Taggable::SingletonMethods
- end
- end
-
- module SingletonMethods
- def find_tagged_with(list)
- find_by_sql([
- "SELECT #{table_name}.* FROM #{table_name}, tags, taggings " +
- "WHERE #{table_name}.#{primary_key} = taggings.taggable_id " +
- "AND taggings.taggable_type = ? " +
- "AND taggings.tag_id = tags.id AND tags.name IN (?)",
- acts_as_taggable_options[:taggable_type], list
- ])
- end
- def tags(options = {})
- options.merge!(:taggable_type => self.to_s)
- Tag.tags(options)
- end
- end
-
- module InstanceMethods
- def tag_with(list)
- Tag.transaction do
- taggings.destroy_all
-
- Tag.parse(list).each do |name|
- if acts_as_taggable_options[:from]
- send(acts_as_taggable_options[:from]).tags.find_or_create_by_name(name).on(self)
- else
- Tag.find_or_create_by_name(name).on(self)
- end
- end
- end
- end
-
- def tag_list
- tags.collect { |tag| tag.name.include?(" ") ? "'#{tag.name}'" : tag.name }.join(" ")
- end
- end
- end
- end
-end
diff --git a/lib/puppet/rails/external/tagging/init.rb b/lib/puppet/rails/external/tagging/init.rb
deleted file mode 100644
index 5069d8040..000000000
--- a/lib/puppet/rails/external/tagging/init.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-require 'puppet/rails/external/tagging/acts_as_taggable'
-ActiveRecord::Base.send(:include, ActiveRecord::Acts::Taggable)
-
-require 'puppet/rails/external/tagging/tagging'
-require 'puppet/rails/external/tagging/tag'
diff --git a/lib/puppet/rails/external/tagging/tag.rb b/lib/puppet/rails/external/tagging/tag.rb
deleted file mode 100644
index c6bf4ca78..000000000
--- a/lib/puppet/rails/external/tagging/tag.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-class Tag < ActiveRecord::Base
- has_many :taggings
-
- def self.tags(options = {})
- query = "select tags.id, name, count(*) as count"
- query << " from taggings, tags"
- query << " where tags.id = tag_id"
- query << " group by tag_id"
- query << " order by #{options[:order]}" if options[:order] != nil
- query << " limit #{options[:limit]}" if options[:limit] != nil
- tags = Tag.find_by_sql(query)
- end
-
- def self.parse(list)
- tag_names = []
-
- # first, pull out the quoted tags
- list.gsub!(/\"(.*?)\"\s*/ ) { tag_names << $1; "" }
-
- # then, replace all commas with a space
- list.gsub!(/,/, " ")
-
- # then, get whatever's left
- tag_names.concat list.split(/\s/)
-
- # strip whitespace from the names
- tag_names = tag_names.map { |t| t.strip }
-
- # delete any blank tag names
- tag_names = tag_names.delete_if { |t| t.empty? }
-
- return tag_names
- end
-
- def tagged
- @tagged ||= taggings.collect { |tagging| tagging.taggable }
- end
-
- def on(taggable)
- taggings.build :taggable => taggable
- end
-
- def ==(comparison_object)
- super || name == comparison_object.to_s
- end
-
- def to_s
- name
- end
-end
diff --git a/lib/puppet/rails/external/tagging/tagging.rb b/lib/puppet/rails/external/tagging/tagging.rb
deleted file mode 100644
index e06e88a14..000000000
--- a/lib/puppet/rails/external/tagging/tagging.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class Tagging < ActiveRecord::Base
- belongs_to :tag
- belongs_to :taggable, :polymorphic => true
-
- def self.tagged_class(taggable)
- ActiveRecord::Base.send(:class_name_of_active_record_descendant, taggable.class).to_s
- end
-
- def self.find_taggable(tagged_class, tagged_id)
- tagged_class.constantize.find(tagged_id)
- end
-end \ No newline at end of file
diff --git a/lib/puppet/rails/fact_value.rb b/lib/puppet/rails/fact_value.rb
index 0eb70be72..b53591d7e 100644
--- a/lib/puppet/rails/fact_value.rb
+++ b/lib/puppet/rails/fact_value.rb
@@ -1,6 +1,10 @@
class Puppet::Rails::FactValue < ActiveRecord::Base
belongs_to :fact_name
belongs_to :host
+
+ def to_label
+ "#{self.fact_name.name}"
+ end
end
# $Id: fact_value.rb 1952 2006-12-19 05:47:57Z luke $
diff --git a/lib/puppet/rails/host.rb b/lib/puppet/rails/host.rb
index 72898fd97..626edaa88 100644
--- a/lib/puppet/rails/host.rb
+++ b/lib/puppet/rails/host.rb
@@ -11,8 +11,7 @@ class Puppet::Rails::Host < ActiveRecord::Base
has_many :fact_values, :dependent => :destroy
has_many :fact_names, :through => :fact_values
- belongs_to :puppet_classes
- has_many :source_files
+ belongs_to :source_file
has_many :resources,
:include => :param_values,
:dependent => :destroy
diff --git a/lib/puppet/rails/param_value.rb b/lib/puppet/rails/param_value.rb
index 02c29c540..fc00a43d4 100644
--- a/lib/puppet/rails/param_value.rb
+++ b/lib/puppet/rails/param_value.rb
@@ -20,5 +20,9 @@ class Puppet::Rails::ParamValue < ActiveRecord::Base
self[:value] = val
end
end
+
+ def to_label
+ "#{self.param_name.name}"
+ end
end
diff --git a/lib/puppet/rails/puppet_class.rb b/lib/puppet/rails/puppet_class.rb
deleted file mode 100644
index 35cef8974..000000000
--- a/lib/puppet/rails/puppet_class.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class Puppet::Rails::PuppetClass < ActiveRecord::Base
- has_many :resources
- has_many :source_files
- has_many :hosts
-end
-
diff --git a/lib/puppet/rails/resource_tag.rb b/lib/puppet/rails/resource_tag.rb
index d06711877..f9694e082 100644
--- a/lib/puppet/rails/resource_tag.rb
+++ b/lib/puppet/rails/resource_tag.rb
@@ -1,4 +1,8 @@
class Puppet::Rails::ResourceTag < ActiveRecord::Base
belongs_to :puppet_tag
belongs_to :resource
+
+ def to_label
+ "#{self.puppet_tag.name}"
+ end
end
diff --git a/lib/puppet/rails/source_file.rb b/lib/puppet/rails/source_file.rb
index 51d1b1fb5..3ccf87ac6 100644
--- a/lib/puppet/rails/source_file.rb
+++ b/lib/puppet/rails/source_file.rb
@@ -1,5 +1,8 @@
class Puppet::Rails::SourceFile < ActiveRecord::Base
has_one :host
- has_one :puppet_class
has_one :resource
+
+ def to_label
+ "#{self.filename}"
+ end
end
diff --git a/lib/puppet/reference/node_source.rb b/lib/puppet/reference/node_source.rb
deleted file mode 100644
index 29a01f850..000000000
--- a/lib/puppet/reference/node_source.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'puppet/node'
-
-noderef = Puppet::Util::Reference.newreference :node_source, :doc => "Sources of node configuration information" do
- Puppet::Network::Handler.node.docs
-end
-
-noderef.header = "
-Nodes can be searched for in different locations. This document describes those different locations.
-"
diff --git a/lib/puppet/reference/report.rb b/lib/puppet/reference/report.rb
deleted file mode 100644
index a8086f8bc..000000000
--- a/lib/puppet/reference/report.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-report = Puppet::Util::Reference.newreference :report, :doc => "All available transaction reports" do
- Puppet::Network::Handler.report.reportdocs
-end
-
-report.header = "
-Puppet clients can report back to the server after each transaction. This
-transaction report is sent as a YAML dump of the
-``Puppet::Transaction::Report`` class and includes every log message that was
-generated during the transaction along with as many metrics as Puppet knows how
-to collect. See `ReportsAndReporting Reports and Reporting`:trac:
-for more information on how to use reports.
-
-Currently, clients default to not sending in reports; you can enable reporting
-by setting the ``report`` parameter to true.
-
-To use a report, set the ``reports`` parameter on the server; multiple
-reports must be comma-separated. You can also specify ``none`` to disable
-reports entirely.
-
-Puppet provides multiple report handlers that will process client reports:
-"
diff --git a/lib/puppet/reports/tagmail.rb b/lib/puppet/reports/tagmail.rb
index a2c973f8f..102647c66 100644
--- a/lib/puppet/reports/tagmail.rb
+++ b/lib/puppet/reports/tagmail.rb
@@ -28,10 +28,12 @@ Puppet::Reports.register_report(:tagmail) do
This will send all messages to ``me@domain.com``, and all messages from
webservers that are not also from mailservers to ``httpadmins@domain.com``.
- "
+ If you are using anti-spam controls, such as grey-listing, on your mail
+ server you should whitelist the sending email (controlled by ``reportform``
+ configuration option) to ensure your email is not discarded as spam.
+ "
- Puppet.settings.use(:tagmail)
# Find all matching messages.
def match(taglists)
@@ -127,7 +129,14 @@ Puppet::Reports.register_report(:tagmail) do
Net::SMTP.start(Puppet[:smtpserver]) do |smtp|
reports.each do |emails, messages|
Puppet.info "Sending report to %s" % emails.join(", ")
- smtp.send_message(messages, Puppet[:reportfrom], *emails)
+ smtp.open_message_stream(Puppet[:reportfrom], *emails) do |p|
+ p.puts "From: #{Puppet[:reportfrom]}"
+ p.puts "Subject: Puppet Report for %s" % self.host
+ p.puts "To: " + emails.join(", ")
+ p.puts "Date: " + Time.now.rfc2822
+ p.puts
+ p.puts messages
+ end
end
end
rescue => detail
diff --git a/lib/puppet/resource_reference.rb b/lib/puppet/resource_reference.rb
index 8af17918a..12b9f54a9 100644
--- a/lib/puppet/resource_reference.rb
+++ b/lib/puppet/resource_reference.rb
@@ -29,7 +29,7 @@ class Puppet::ResourceReference
# If the title has square brackets, treat it like a reference and
# set things appropriately; else, just set it.
def title=(value)
- if value =~ /^(.+)\[(.+)\]$/
+ if value =~ /^([^\[\]]+)\[(.+)\]$/
self.type = $1
@title = $2
else
@@ -42,7 +42,8 @@ class Puppet::ResourceReference
if value.nil? or value.to_s.downcase == "component"
@type = "Class"
else
- @type = value.to_s.split("::").collect { |s| s.capitalize }.join("::")
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = @type = value.to_s.split("::").collect { |s| s.capitalize }.join("::")
end
end
diff --git a/lib/puppet/simple_graph.rb b/lib/puppet/simple_graph.rb
index 11542ad53..48f393f77 100644
--- a/lib/puppet/simple_graph.rb
+++ b/lib/puppet/simple_graph.rb
@@ -51,10 +51,12 @@ class Puppet::SimpleGraph
# Create methods for returning the degree and edges.
[:in, :out].each do |direction|
- define_method("%s_degree" % direction) do
- @adjacencies[direction].length
- end
-
+ # LAK:NOTE If you decide to create methods for directly
+ # testing the degree, you'll have to get the values and flatten
+ # the results -- you might have duplicate edges, which can give
+ # a false impression of what the degree is. That's just
+ # as expensive as just getting the edge list, so I've decided
+ # to only add this method.
define_method("%s_edges" % direction) do
@adjacencies[direction].values.flatten
end
@@ -100,10 +102,10 @@ class Puppet::SimpleGraph
# Return a reversed version of this graph.
def reversal
result = self.class.new
- vertices.each { |vertex| result.add_vertex!(vertex) }
+ vertices.each { |vertex| result.add_vertex(vertex) }
edges.each do |edge|
newedge = edge.class.new(edge.target, edge.source, edge.label)
- result.add_edge!(newedge)
+ result.add_edge(newedge)
end
result
end
@@ -126,8 +128,9 @@ class Puppet::SimpleGraph
# Collect each of our vertices, with the number of in-edges each has.
@vertices.each do |name, wrapper|
- zeros << wrapper if wrapper.in_degree == 0
- degree[wrapper.vertex] = wrapper.in_edges
+ edges = wrapper.in_edges
+ zeros << wrapper if edges.length == 0
+ degree[wrapper.vertex] = edges
end
# Iterate over each 0-degree vertex, decrementing the degree of
@@ -150,7 +153,7 @@ class Puppet::SimpleGraph
end
# Add a new vertex to the graph.
- def add_vertex!(vertex)
+ def add_vertex(vertex)
return false if vertex?(vertex)
setup_vertex(vertex)
true # don't return the VertexWrapper instance.
@@ -176,7 +179,7 @@ class Puppet::SimpleGraph
# Add a new edge. The graph user has to create the edge instance,
# since they have to specify what kind of edge it is.
- def add_edge!(source, target = nil, label = nil)
+ def add_edge(source, target = nil, label = nil)
if target
edge = Puppet::Relationship.new(source, target, label)
else
diff --git a/lib/puppet/sslcertificates.rb b/lib/puppet/sslcertificates.rb
index bd0ce8c92..0c579d0ad 100755
--- a/lib/puppet/sslcertificates.rb
+++ b/lib/puppet/sslcertificates.rb
@@ -72,7 +72,7 @@ module Puppet::SSLCertificates
subject_alt_name << 'DNS:' + name.sub(/^[^.]+./, "puppet.") # add puppet.domain as an alias
end
key_usage = %w{digitalSignature keyEncipherment}
- ext_key_usage = %w{serverAuth clientAuth}
+ ext_key_usage = %w{serverAuth clientAuth emailProtection}
when :ocsp:
basic_constraint = "CA:FALSE"
key_usage = %w{nonRepudiation digitalSignature}
diff --git a/lib/puppet/sslcertificates/ca.rb b/lib/puppet/sslcertificates/ca.rb
index a3edd2cb4..7386318f4 100644
--- a/lib/puppet/sslcertificates/ca.rb
+++ b/lib/puppet/sslcertificates/ca.rb
@@ -194,8 +194,8 @@ class Puppet::SSLCertificates::CA
# Revoke the certificate with serial number SERIAL issued by this
# CA. The REASON must be one of the OpenSSL::OCSP::REVOKED_* reasons
def revoke(serial, reason = OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE)
- if @config[:cacrl] == 'none'
- raise Puppet::Error, "Revocation requires a CRL, but ca_crl is set to 'none'"
+ if @config[:cacrl] == 'false'
+ raise Puppet::Error, "Revocation requires a CRL, but ca_crl is set to 'false'"
end
time = Time.now
revoked = OpenSSL::X509::Revoked.new
@@ -238,33 +238,6 @@ class Puppet::SSLCertificates::CA
}
end
- # Create an exclusive lock for reading and writing, and do the
- # writing in a tmp file.
- def readwritelock(file, mode = 0600)
- tmpfile = file + ".tmp"
- sync = Sync.new
- unless FileTest.directory?(File.dirname(tmpfile))
- raise Puppet::DevError, "Cannot create %s; directory %s does not exist" %
- [file, File.dirname(file)]
- end
- sync.synchronize(Sync::EX) do
- File.open(file, "r+", mode) do |rf|
- rf.lock_exclusive do
- File.open(tmpfile, "w", mode) do |tf|
- yield tf
- end
- begin
- File.rename(tmpfile, file)
- rescue => detail
- Puppet.err "Could not rename %s to %s: %s" %
- [file, tmpfile, detail]
- end
- end
- end
- end
- end
-
-
# Sign a given certificate request.
def sign(csr)
unless csr.is_a?(OpenSSL::X509::Request)
@@ -278,9 +251,8 @@ class Puppet::SSLCertificates::CA
end
serial = nil
- readwritelock(@config[:serial]) { |f|
+ Puppet.settings.readwritelock(:serial) { |f|
serial = File.read(@config[:serial]).chomp.hex
-
# increment the serial
f << "%04X" % (serial + 1)
}
@@ -372,7 +344,7 @@ class Puppet::SSLCertificates::CA
@crl = OpenSSL::X509::CRL.new(
File.read(@config[:cacrl])
)
- elsif @config[:cacrl] == 'none'
+ elsif @config[:cacrl] == 'false'
@crl = nil
else
# Create new CRL
diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb
index b5fbf2b0a..d4bc42100 100644
--- a/lib/puppet/transaction.rb
+++ b/lib/puppet/transaction.rb
@@ -15,8 +15,6 @@ class Transaction
# The list of events generated in this transaction.
attr_reader :events
- attr_writer :tags
-
include Puppet::Util
# Add some additional times for reporting
@@ -173,7 +171,7 @@ class Transaction
relationship_graph.add_resource(gen_child) unless relationship_graph.resource(gen_child.ref)
unless relationship_graph.edge?(edge[1], edge[0])
- relationship_graph.add_edge!(*edge)
+ relationship_graph.add_edge(*edge)
else
resource.debug "Skipping automatic relationship to %s" % gen_child
end
@@ -424,7 +422,7 @@ class Transaction
# Should we ignore tags?
def ignore_tags?
- ! @catalog.host_config?
+ ! (@catalog.host_config? or Puppet[:name] == "puppet")
end
# this should only be called by a Puppet::Type::Component resource now
@@ -636,6 +634,11 @@ class Transaction
@tags
end
+
+ def tags=(tags)
+ tags = [tags] unless tags.is_a?(Array)
+ @tags = tags
+ end
# Is this resource tagged appropriately?
def missing_tags?(resource)
diff --git a/lib/puppet/transportable.rb b/lib/puppet/transportable.rb
index c1d68a881..3ad084b3b 100644
--- a/lib/puppet/transportable.rb
+++ b/lib/puppet/transportable.rb
@@ -83,14 +83,11 @@ module Puppet
end
def to_type
- retobj = nil
if typeklass = Puppet::Type.type(self.type)
return typeklass.create(self)
else
return to_component
end
-
- return retobj
end
end
@@ -179,28 +176,39 @@ module Puppet
end
# Create a resource graph from our structure.
- def to_catalog
- catalog = Puppet::Node::Catalog.new(Facter.value("hostname")) do |config|
- delver = proc do |obj|
- obj.catalog = config
- unless container = config.resource(obj.to_ref)
- container = obj.to_type
- config.add_resource container
+ def to_catalog(clear_on_failure = true)
+ catalog = Puppet::Node::Catalog.new(Facter.value("hostname"))
+
+ # This should really use the 'delve' method, but this
+ # whole class is going away relatively soon, hopefully,
+ # so it's not worth it.
+ delver = proc do |obj|
+ obj.catalog = catalog
+ unless container = catalog.resource(obj.to_ref)
+ container = obj.to_type
+ catalog.add_resource container
+ end
+ obj.each do |child|
+ child.catalog = catalog
+ unless resource = catalog.resource(child.to_ref)
+ resource = child.to_type
+ catalog.add_resource resource
end
- obj.each do |child|
- child.catalog = config
- unless resource = config.resource(child.to_ref)
- next unless resource = child.to_type
- config.add_resource resource
- end
- config.add_edge!(container, resource)
- if child.is_a?(self.class)
- delver.call(child)
- end
+
+ catalog.add_edge(container, resource)
+ if child.is_a?(self.class)
+ delver.call(child)
end
end
+ end
+ begin
delver.call(self)
+ catalog.finalize
+ rescue => detail
+ # This is important until we lose the global resource references.
+ catalog.clear if (clear_on_failure)
+ raise
end
return catalog
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb
index c7a6f4e40..7deb25fff 100644
--- a/lib/puppet/type.rb
+++ b/lib/puppet/type.rb
@@ -155,8 +155,6 @@ class Type
@parameters = {}
end
- # set defalts
- @noop = false
# keeping stats for the total number of changes, and how many were
# completely sync'ed
# this isn't really sufficient either, because it adds lots of special
@@ -257,10 +255,7 @@ class Type
rescue ArgumentError, Puppet::Error, TypeError
raise
rescue => detail
- error = Puppet::DevError.new(
- "Could not set %s on %s: %s" %
- [attr, self.class.name, detail]
- )
+ error = Puppet::DevError.new( "Could not set %s on %s: %s" % [attr, self.class.name, detail])
error.set_backtrace(detail.backtrace)
raise error
end
@@ -422,10 +417,6 @@ end
require 'puppet/propertychange'
require 'puppet/provider'
-require 'puppet/type/component'
-require 'puppet/type/pfile'
-require 'puppet/type/pfilebucket'
-require 'puppet/type/tidy'
-
-
+# Always load these types.
+require 'puppet/type/component'
diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb
index 17cb1667f..c46a7c83b 100755
--- a/lib/puppet/type/cron.rb
+++ b/lib/puppet/type/cron.rb
@@ -23,6 +23,24 @@ Puppet::Type.newtype(:cron) do
hour => 2,
minute => 0
}
+
+ Note that all cron values can be specified as an array of values::
+
+ cron { logrotate:
+ command => \"/usr/sbin/logrotate\",
+ user => root,
+ hour => [2, 4]
+ }
+
+ Or using ranges, or the step syntax ``*/2`` (although there's no guarantee that
+ your ``cron`` daemon supports it)::
+
+ cron { logrotate:
+ command => \"/usr/sbin/logrotate\",
+ user => root,
+ hour => ['2-4'],
+ minute => '*/10'
+ }
"
ensurable
diff --git a/lib/puppet/type/exec.rb b/lib/puppet/type/exec.rb
index 5bb3158c4..d7c3a8a39 100755
--- a/lib/puppet/type/exec.rb
+++ b/lib/puppet/type/exec.rb
@@ -211,10 +211,7 @@ module Puppet
log the output when the command reports an error. Values are
**true**, *false*, *on_failure*, and any legal log level."
- values = [:true, :false, :on_failure]
- # And all of the log levels
- Puppet::Util::Log.eachlevel { |level| values << level }
- newvalues(*values)
+ newvalues(:true, :false, :on_failure)
end
newparam(:refresh) do
@@ -229,6 +226,15 @@ module Puppet
end
newparam(:env) do
+ desc "This parameter is deprecated. Use 'environment' instead."
+
+ munge do |value|
+ warning "'env' is deprecated on exec; use 'environment' instead."
+ resource[:environment] = value
+ end
+ end
+
+ newparam(:environment) do
desc "Any additional environment variables you want to set for a
command. Note that if you use this to set PATH, it will override
the ``path`` attribute. Multiple environment variables should be
@@ -279,7 +285,7 @@ module Puppet
# Rebuild the database, but only when the file changes
exec { newaliases:
path => [\"/usr/bin\", \"/usr/sbin\"],
- subscribe => file[\"/etc/aliases\"],
+ subscribe => File[\"/etc/aliases\"],
refreshonly => true
}
@@ -384,6 +390,11 @@ module Puppet
Note that this command follows the same rules as the main command,
which is to say that it must be fully qualified if the path is not set.
+
+ Also note that onlyif can take an array as its value, eg:
+ onlyif => [\"test -f /tmp/file1\", \"test -f /tmp/file2\"]
+
+ This will only run the exec if /all/ conditions in the array return true.
"
validate do |cmds|
@@ -554,32 +565,32 @@ module Puppet
begin
# Do our chdir
Dir.chdir(dir) do
- env = {}
+ environment = {}
if self[:path]
- env[:PATH] = self[:path].join(":")
+ environment[:PATH] = self[:path].join(":")
end
- if envlist = self[:env]
+ if envlist = self[:environment]
envlist = [envlist] unless envlist.is_a? Array
envlist.each do |setting|
if setting =~ /^(\w+)=((.|\n)+)$/
name = $1
value = $2
- if env.include? name
+ if environment.include? name
warning(
"Overriding environment setting '%s' with '%s'" %
[name, value]
)
end
- env[name] = value
+ environment[name] = value
else
- warning "Cannot understand env setting %s" % setting.inspect
+ warning "Cannot understand environment setting %s" % setting.inspect
end
end
end
- withenv env do
+ withenv environment do
Timeout::timeout(self[:timeout]) do
output, status = Puppet::Util::SUIDManager.run_and_capture(
[command], self[:user], self[:group]
diff --git a/lib/puppet/type/pfile.rb b/lib/puppet/type/file.rb
index c8e63b5ba..7b9233736 100644
--- a/lib/puppet/type/pfile.rb
+++ b/lib/puppet/type/file.rb
@@ -5,10 +5,12 @@ require 'uri'
require 'fileutils'
require 'puppet/network/handler'
require 'puppet/util/diff'
+require 'puppet/util/checksums'
module Puppet
newtype(:file) do
include Puppet::Util::MethodHelper
+ include Puppet::Util::Checksums
@doc = "Manages local files, including setting ownership and
permissions, creation of both files and directories, and
retrieving entire files from remote servers. As Puppet matures, it
@@ -172,11 +174,9 @@ module Puppet
recursion), and ``follow`` will manage the file to which the
link points."
- newvalues(:follow, :manage, :ignore)
+ newvalues(:follow, :manage)
- # :ignore and :manage behave equivalently on local files,
- # but don't copy remote links
- defaultto :ignore
+ defaultto :manage
end
newparam(:purge, :boolean => true) do
@@ -633,7 +633,6 @@ module Puppet
# :file.
return nil unless child = catalog.create_implicit_resource(self.class.name, args)
rescue => detail
- puts detail.backtrace
self.notice "Cannot manage: %s" % [detail]
return nil
end
@@ -641,7 +640,7 @@ module Puppet
# LAK:FIXME This shouldn't be necessary, but as long as we're
# modeling the relationship graph specifically, it is.
- catalog.relationship_graph.add_edge! self, child
+ catalog.relationship_graph.add_edge self, child
return child
end
@@ -760,11 +759,8 @@ module Puppet
begin
File.unlink(newfile)
rescue => detail
- if Puppet[:trace]
- puts detail.backtrace
- end
- self.err "Could not remove old backup: %s" %
- detail
+ puts detail.backtrace if Puppet[:trace]
+ self.err "Could not remove old backup: %s" % detail
return false
end
end
@@ -776,13 +772,14 @@ module Puppet
self.fail "Could not back up; will not replace" unless handlebackup
- return if s.ftype.to_s == should.to_s unless should.to_s == "link"
+ unless should.to_s == "link"
+ return if s.ftype.to_s == should.to_s
+ end
case s.ftype
when "directory":
if self[:force] == :true
- debug "Removing existing directory for replacement with %s" %
- should
+ debug "Removing existing directory for replacement with %s" % should
FileUtils.rmtree(self[:path])
else
notice "Not removing directory; use 'force' to override"
@@ -966,7 +963,7 @@ module Puppet
end
def uri2obj(source)
- sourceobj = FileSource.new
+ sourceobj = Puppet::Type::File::FileSource.new
path = nil
unless source
devfail "Got a nil source"
@@ -1022,54 +1019,38 @@ module Puppet
return [sourceobj, path.sub(/\/\//, '/')]
end
- # Write out the file. We open the file correctly, with all of the
- # uid and mode and such, and then yield the file handle for actual
- # writing.
- def write(property, usetmp = true)
- mode = self.should(:mode)
+ # Write out the file. Requires the content to be written,
+ # the property name for logging, and the checksum for validation.
+ def write(content, property, checksum = nil)
+ if validate = validate_checksum?
+ # Use the appropriate checksum type -- md5, md5lite, etc.
+ sumtype = property(:checksum).checktype
+ checksum ||= "{#{sumtype}}" + property(:checksum).send(sumtype, content)
+ end
remove_existing(:file)
- # The temporary file
- path = nil
- if usetmp
- path = self[:path] + ".puppettmp"
- else
- path = self[:path]
- end
-
- # As the correct user and group
- write_if_writable(File.dirname(path)) do
- f = nil
- # Open our file with the correct modes
- if mode
- Puppet::Util.withumask(000) do
- f = File.open(path,
- File::CREAT|File::WRONLY|File::TRUNC, mode)
- end
- else
- f = File.open(path, File::CREAT|File::WRONLY|File::TRUNC)
- end
+ use_temporary_file = (content.length != 0)
+ path = self[:path]
+ path += ".puppettmp" if use_temporary_file
- # Yield it
- yield f
+ mode = self.should(:mode) # might be nil
+ umask = mode ? 000 : 022
- f.flush
- f.close
+ Puppet::Util.withumask(umask) do
+ File.open(path, File::CREAT|File::WRONLY|File::TRUNC, mode) { |f| f.print content }
end
# And put our new file in place
- if usetmp
+ if use_temporary_file # This is only not true when our file is empty.
begin
+ fail_if_checksum_is_wrong(path, checksum) if validate
File.rename(path, self[:path])
rescue => detail
- self.err "Could not rename tmp %s for replacing: %s" %
- [self[:path], detail]
+ self.err "Could not rename tmp %s for replacing: %s" % [self[:path], detail]
ensure
# Make sure the created file gets removed
- if FileTest.exists?(path)
- File.unlink(path)
- end
+ File.unlink(path) if FileTest.exists?(path)
end
end
@@ -1077,32 +1058,35 @@ module Puppet
property_fix
# And then update our checksum, so the next run doesn't find it.
- # FIXME This is extra work, because it's going to read the whole
- # file back in again.
- self.setchecksum
-
+ self.setchecksum(checksum)
end
-
- # Run the block as the specified user if the dir is writeable, else
- # run it as root (or the current user).
- def write_if_writable(dir)
- yield
- # We're getting different behaviors from different versions of ruby, so...
- # asroot = true
- # Puppet::Util::SUIDManager.asuser(asuser(), self.should(:group)) do
- # if FileTest.writable?(dir)
- # asroot = false
- # yield
- # end
- # end
- #
- # if asroot
- # yield
- # end
+
+ # Should we validate the checksum of the file we're writing?
+ def validate_checksum?
+ if sumparam = @parameters[:checksum]
+ return sumparam.checktype.to_s !~ /time/
+ else
+ return false
+ end
end
private
+ # Make sure the file we wrote out is what we think it is.
+ def fail_if_checksum_is_wrong(path, checksum)
+ if checksum =~ /^\{(\w+)\}.+/
+ sumtype = $1
+ else
+ # This shouldn't happen, but if it happens to, it's nicer
+ # to just use a default sumtype than fail.
+ sumtype = "md5"
+ end
+ newsum = property(:checksum).getsum(sumtype, path)
+ return if newsum == checksum
+
+ self.fail "File written to disk did not match checksum; discarding changes (%s vs %s)" % [checksum, newsum]
+ end
+
# Override the parent method, because we don't want to generate changes
# when the file is missing and there is no 'ensure' state.
def propertychanges(currentvalues)
@@ -1139,20 +1123,20 @@ module Puppet
# the filesource class can't include the path, because the path
# changes for every file instance
- class FileSource
+ class ::Puppet::Type::File::FileSource
attr_accessor :mount, :root, :server, :local
end
# We put all of the properties in separate files, because there are so many
# of them. The order these are loaded is important, because it determines
# the order they are in the property lit.
- require 'puppet/type/pfile/checksum'
- require 'puppet/type/pfile/content' # can create the file
- require 'puppet/type/pfile/source' # can create the file
- require 'puppet/type/pfile/target' # creates a different type of file
- require 'puppet/type/pfile/ensure' # can create the file
- require 'puppet/type/pfile/owner'
- require 'puppet/type/pfile/group'
- require 'puppet/type/pfile/mode'
- require 'puppet/type/pfile/type'
+ require 'puppet/type/file/checksum'
+ require 'puppet/type/file/content' # can create the file
+ require 'puppet/type/file/source' # can create the file
+ require 'puppet/type/file/target' # creates a different type of file
+ require 'puppet/type/file/ensure' # can create the file
+ require 'puppet/type/file/owner'
+ require 'puppet/type/file/group'
+ require 'puppet/type/file/mode'
+ require 'puppet/type/file/type'
end
diff --git a/lib/puppet/type/file/checksum.rb b/lib/puppet/type/file/checksum.rb
new file mode 100755
index 000000000..3be147cb7
--- /dev/null
+++ b/lib/puppet/type/file/checksum.rb
@@ -0,0 +1,274 @@
+require 'puppet/util/checksums'
+
+# Keep a copy of the file checksums, and notify when they change. This
+# property never actually modifies the system, it only notices when the system
+# changes on its own.
+Puppet::Type.type(:file).newproperty(:checksum) do
+ include Puppet::Util::Checksums
+
+ desc "How to check whether a file has changed. This state is used internally
+ for file copying, but it can also be used to monitor files somewhat
+ like Tripwire without managing the file contents in any way. You can
+ specify that a file's checksum should be monitored and then subscribe to
+ the file from another object and receive events to signify
+ checksum changes, for instance."
+
+ @event = :file_changed
+
+ @unmanaged = true
+
+ @validtypes = %w{md5 md5lite timestamp mtime time}
+
+ def self.validtype?(type)
+ @validtypes.include?(type)
+ end
+
+ @validtypes.each do |ctype|
+ newvalue(ctype) do
+ handlesum()
+ end
+ end
+
+ str = @validtypes.join("|")
+
+ # This is here because Puppet sets this internally, using
+ # {md5}......
+ newvalue(/^\{#{str}\}/) do
+ handlesum()
+ end
+
+ newvalue(:nosum) do
+ # nothing
+ :nochange
+ end
+
+ # If they pass us a sum type, behave normally, but if they pass
+ # us a sum type + sum, stick the sum in the cache.
+ munge do |value|
+ if value =~ /^\{(\w+)\}(.+)$/
+ type = symbolize($1)
+ sum = $2
+ cache(type, sum)
+ return type
+ else
+ if FileTest.directory?(@resource[:path])
+ return :time
+ else
+ return symbolize(value)
+ end
+ end
+ end
+
+ # Store the checksum in the data cache, or retrieve it if only the
+ # sum type is provided.
+ def cache(type, sum = nil)
+ unless type
+ raise ArgumentError, "A type must be specified to cache a checksum"
+ end
+ type = symbolize(type)
+ type = :mtime if type == :timestamp
+ type = :ctime if type == :time
+
+ unless state = @resource.cached(:checksums)
+ self.debug "Initializing checksum hash"
+ state = {}
+ @resource.cache(:checksums, state)
+ end
+
+ if sum
+ unless sum =~ /\{\w+\}/
+ sum = "{%s}%s" % [type, sum]
+ end
+ state[type] = sum
+ else
+ return state[type]
+ end
+ end
+
+ # Because source and content and whomever else need to set the checksum
+ # and do the updating, we provide a simple mechanism for doing so.
+ def checksum=(value)
+ munge(@should)
+ self.updatesum(value)
+ end
+
+ def checktype
+ self.should || :md5
+ end
+
+ # Checksums need to invert how changes are printed.
+ def change_to_s(currentvalue, newvalue)
+ begin
+ if currentvalue == :absent
+ return "defined '%s' as '%s'" %
+ [self.name, self.currentsum]
+ elsif newvalue == :absent
+ return "undefined %s from '%s'" %
+ [self.name, self.is_to_s(currentvalue)]
+ else
+ if defined? @cached and @cached
+ return "%s changed '%s' to '%s'" %
+ [self.name, @cached, self.is_to_s(currentvalue)]
+ else
+ return "%s changed '%s' to '%s'" %
+ [self.name, self.currentsum, self.is_to_s(currentvalue)]
+ end
+ end
+ rescue Puppet::Error, Puppet::DevError
+ raise
+ rescue => detail
+ raise Puppet::DevError, "Could not convert change %s to string: %s" %
+ [self.name, detail]
+ end
+ end
+
+ def currentsum
+ cache(checktype())
+ end
+
+ # Retrieve the cached sum
+ def getcachedsum
+ hash = nil
+ unless hash = @resource.cached(:checksums)
+ hash = {}
+ @resource.cache(:checksums, hash)
+ end
+
+ sumtype = self.should
+
+ if hash.include?(sumtype)
+ #self.notice "Found checksum %s for %s" %
+ # [hash[sumtype] ,@resource[:path]]
+ sum = hash[sumtype]
+
+ unless sum =~ /^\{\w+\}/
+ sum = "{%s}%s" % [sumtype, sum]
+ end
+ return sum
+ elsif hash.empty?
+ #self.notice "Could not find sum of type %s" % sumtype
+ return :nosum
+ else
+ #self.notice "Found checksum for %s but not of type %s" %
+ # [@resource[:path],sumtype]
+ return :nosum
+ end
+ end
+
+ # Calculate the sum from disk.
+ def getsum(checktype, file = nil)
+ sum = ""
+
+ checktype = :mtime if checktype == :timestamp
+ checktype = :ctime if checktype == :time
+
+ file ||= @resource[:path]
+
+ return nil unless FileTest.exist?(file)
+
+ if ! FileTest.file?(file)
+ checktype = :mtime
+ end
+ method = checktype.to_s + "_file"
+
+ self.fail("Invalid checksum type %s" % checktype) unless respond_to?(method)
+
+ return "{%s}%s" % [checktype, send(method, file)]
+ end
+
+ # At this point, we don't actually modify the system, we modify
+ # the stored state to reflect the current state, and then kick
+ # off an event to mark any changes.
+ def handlesum
+ currentvalue = self.retrieve
+ if currentvalue.nil?
+ raise Puppet::Error, "Checksum state for %s is somehow nil" %
+ @resource.title
+ end
+
+ if self.insync?(currentvalue)
+ self.debug "Checksum is already in sync"
+ return nil
+ end
+ # If we still can't retrieve a checksum, it means that
+ # the file still doesn't exist
+ if currentvalue == :absent
+ # if they're copying, then we won't worry about the file
+ # not existing yet
+ unless @resource.property(:source)
+ self.warning("File %s does not exist -- cannot checksum" % @resource[:path])
+ end
+ return nil
+ end
+
+ # If the sums are different, then return an event.
+ if self.updatesum(currentvalue)
+ return :file_changed
+ else
+ return nil
+ end
+ end
+
+ def insync?(currentvalue)
+ @should = [checktype()]
+ if cache(checktype())
+ return currentvalue == currentsum()
+ else
+ # If there's no cached sum, then we don't want to generate
+ # an event.
+ return true
+ end
+ end
+
+ # Even though they can specify multiple checksums, the insync?
+ # mechanism can really only test against one, so we'll just retrieve
+ # the first specified sum type.
+ def retrieve(usecache = false)
+ # When the 'source' is retrieving, it passes "true" here so
+ # that we aren't reading the file twice in quick succession, yo.
+ currentvalue = currentsum()
+ return currentvalue if usecache and currentvalue
+
+ stat = nil
+ return :absent unless stat = @resource.stat
+
+ if stat.ftype == "link" and @resource[:links] != :follow
+ self.debug "Not checksumming symlink"
+ # @resource.delete(:checksum)
+ return currentvalue
+ end
+
+ # Just use the first allowed check type
+ currentvalue = getsum(checktype())
+
+ # If there is no sum defined, then store the current value
+ # into the cache, so that we're not marked as being
+ # out of sync. We don't want to generate an event the first
+ # time we get a sum.
+ self.updatesum(currentvalue) unless cache(checktype())
+
+ # @resource.debug "checksum state is %s" % self.is
+ return currentvalue
+ end
+
+ # Store the new sum to the state db.
+ def updatesum(newvalue)
+ result = false
+
+ # if we're replacing, vs. updating
+ if sum = cache(checktype())
+ return false if newvalue == sum
+
+ self.debug "Replacing %s checksum %s with %s" % [@resource.title, sum, newvalue]
+ result = true
+ else
+ @resource.debug "Creating checksum %s" % newvalue
+ result = false
+ end
+
+ # Cache the sum so the log message can be right if possible.
+ @cached = sum
+ cache(checktype(), newvalue)
+ return result
+ end
+end
diff --git a/lib/puppet/type/pfile/content.rb b/lib/puppet/type/file/content.rb
index 6dcda0aa6..1eb1423aa 100755
--- a/lib/puppet/type/pfile/content.rb
+++ b/lib/puppet/type/file/content.rb
@@ -1,5 +1,5 @@
module Puppet
- Puppet.type(:file).newproperty(:content) do
+ Puppet::Type.type(:file).newproperty(:content) do
include Puppet::Util::Diff
desc "Specify the contents of a file as a string. Newlines, tabs, and
@@ -47,23 +47,13 @@ module Puppet
return result
end
- # We should probably take advantage of existing md5 sums if they're there,
- # but I really don't feel like dealing with the complexity right now.
def retrieve
- stat = nil
- unless stat = @resource.stat
- return :absent
- end
+ return :absent unless stat = @resource.stat
- if stat.ftype == "link" and @resource[:links] == :ignore
- return self.should
- end
+ return self.should if stat.ftype == "link" and @resource[:links] == :ignore
# Don't even try to manage the content on directories
- if stat.ftype == "directory" and @resource[:links] == :ignore
- @resource.delete(:content)
- return nil
- end
+ return nil if stat.ftype == "directory"
begin
currentvalue = File.read(@resource[:path])
@@ -74,12 +64,17 @@ module Puppet
end
end
+ # Make sure we're also managing the checksum property.
+ def should=(value)
+ super
+ @resource.newattr(:checksum) unless @resource.property(:checksum)
+ end
# Just write our content out to disk.
def sync
return_event = @resource.stat ? :file_changed : :file_created
- @resource.write(:content) { |f| f.print self.should }
+ @resource.write(self.should, :content)
return return_event
end
diff --git a/lib/puppet/type/pfile/ensure.rb b/lib/puppet/type/file/ensure.rb
index 0a6f73d95..0d2171216 100755
--- a/lib/puppet/type/pfile/ensure.rb
+++ b/lib/puppet/type/file/ensure.rb
@@ -46,7 +46,7 @@ module Puppet
if property = (@resource.property(:content) || @resource.property(:source))
property.sync
else
- @resource.write(false) { |f| f.flush }
+ @resource.write("", :ensure)
mode = @resource.should(:mode)
end
return :file_created
@@ -67,14 +67,12 @@ module Puppet
"Cannot create %s; parent directory %s does not exist" %
[@resource[:path], parent]
end
- @resource.write_if_writable(parent) do
- if mode
- Puppet::Util.withumask(000) do
- Dir.mkdir(@resource[:path],mode)
- end
- else
- Dir.mkdir(@resource[:path])
+ if mode
+ Puppet::Util.withumask(000) do
+ Dir.mkdir(@resource[:path],mode)
end
+ else
+ Dir.mkdir(@resource[:path])
end
@resource.send(:property_fix)
@resource.setchecksum
@@ -101,9 +99,13 @@ module Puppet
munge do |value|
value = super(value)
+ # It doesn't make sense to try to manage links unless, well,
+ # we're managing links.
+ resource[:links] = :manage if value == :link
return value if value.is_a? Symbol
@resource[:target] = value
+ resource[:links] = :manage
return :link
end
@@ -136,6 +138,11 @@ module Puppet
# We have to treat :present specially, because it works with any
# type of file.
def insync?(currentvalue)
+ if property = @resource.property(:source) and ! property.described?
+ warning "No specified sources exist"
+ return true
+ end
+
if self.should == :present
if currentvalue.nil? or currentvalue == :absent
return false
diff --git a/lib/puppet/type/pfile/group.rb b/lib/puppet/type/file/group.rb
index 5f7caf342..5f7caf342 100755
--- a/lib/puppet/type/pfile/group.rb
+++ b/lib/puppet/type/file/group.rb
diff --git a/lib/puppet/type/pfile/mode.rb b/lib/puppet/type/file/mode.rb
index 8674e0a88..8674e0a88 100755
--- a/lib/puppet/type/pfile/mode.rb
+++ b/lib/puppet/type/file/mode.rb
diff --git a/lib/puppet/type/pfile/owner.rb b/lib/puppet/type/file/owner.rb
index 6f9bbd6a2..6f9bbd6a2 100755
--- a/lib/puppet/type/pfile/owner.rb
+++ b/lib/puppet/type/file/owner.rb
diff --git a/lib/puppet/type/pfile/source.rb b/lib/puppet/type/file/source.rb
index 1849d5a61..1b0dd3141 100755
--- a/lib/puppet/type/pfile/source.rb
+++ b/lib/puppet/type/file/source.rb
@@ -101,15 +101,17 @@ module Puppet
begin
desc = server.describe(path, @resource[:links])
rescue Puppet::Network::XMLRPCClientError => detail
- self.err "Could not describe %s: %s" %
- [path, detail]
+ self.err "Could not describe %s: %s" % [path, detail]
return nil
end
+ return nil if desc == ""
+
+ # Collect everything except the checksum
+ values = desc.split("\t")
+ other = values.pop
args = {}
- pinparams.zip(
- desc.split("\t")
- ).each { |param, value|
+ pinparams.zip(values).each { |param, value|
if value =~ /^[0-9]+$/
value = value.to_i
end
@@ -118,16 +120,19 @@ module Puppet
end
}
- # we can't manage ownership as root, so don't even try
- unless Puppet::Util::SUIDManager.uid == 0
- args.delete(:owner)
+ # Now decide whether we're doing checksums or symlinks
+ if args[:type] == "link"
+ args[:target] = other
+ else
+ args[:checksum] = other
end
- if args.empty? or (args[:type] == "link" and @resource[:links] == :ignore)
- return nil
- else
- return args
+ # we can't manage ownership unless we're root, so don't even try
+ unless Puppet::Util::SUIDManager.uid == 0
+ args.delete(:owner)
end
+
+ return args
end
# Have we successfully described the remote source?
@@ -138,10 +143,10 @@ module Puppet
# Use the info we get from describe() to check if we're in sync.
def insync?(currentvalue)
unless described?
- info "No specified sources exist"
+ warning "No specified sources exist"
return true
end
-
+
if currentvalue == :nocopy
return true
end
@@ -163,7 +168,7 @@ module Puppet
# Diff the contents if they ask it. This is quite annoying -- we need to do this in
# 'insync?' because they might be in noop mode, but we don't want to do the file
- # retrieval twice, so we cache the value annoyingly.
+ # retrieval twice, so we cache the value.
if ! result and Puppet[:show_diff] and File.exists?(@resource[:path]) and ! @stats[:_diffed]
@stats[:_remote_content] = get_remote_content
string_file_diff(@resource[:path], @stats[:_remote_content])
@@ -173,7 +178,7 @@ module Puppet
end
def pinparams
- Puppet::Network::Handler.handler(:fileserver).params
+ [:mode, :type, :owner, :group]
end
# This basically calls describe() on our file, and then sets all
@@ -202,14 +207,11 @@ module Puppet
end
case @stats[:type]
- when "directory", "file":
- unless @resource.deleting?
- @resource[:ensure] = @stats[:type]
- end
+ when "directory", "file", "link":
+ @resource[:ensure] = @stats[:type] unless @resource.deleting?
else
self.info @stats.inspect
- self.err "Cannot use files of type %s as sources" %
- @stats[:type]
+ self.err "Cannot use files of type %s as sources" % @stats[:type]
return :nocopy
end
@@ -221,11 +223,9 @@ module Puppet
# was the stat already specified, or should the value
# be inherited from the source?
- unless @resource.argument?(stat)
- @resource[stat] = value
- end
+ @resource[stat] = value unless @resource.argument?(stat)
}
-
+
return @stats[:checksum]
end
@@ -241,9 +241,7 @@ module Puppet
checks.delete(:checksum)
@resource[:check] = checks
- unless @resource.property(:checksum)
- @resource[:checksum] = :md5
- end
+ @resource[:checksum] = :md5 unless @resource.property(:checksum)
end
def sync
@@ -251,7 +249,7 @@ module Puppet
exists = File.exists?(@resource[:path])
- @resource.write(:source) { |f| f.print contents }
+ @resource.write(contents, :source, @stats[:checksum])
if exists
return :file_changed
@@ -261,34 +259,22 @@ module Puppet
end
private
+
def get_remote_content
- unless @stats[:type] == "file"
- #if @stats[:type] == "directory"
- #[@resource.name, @should.inspect]
- #end
- raise Puppet::DevError, "Got told to copy non-file %s" %
- @resource[:path]
- end
+ raise Puppet::DevError, "Got told to copy non-file %s" % @resource[:path] unless @stats[:type] == "file"
sourceobj, path = @resource.uri2obj(@source)
begin
contents = sourceobj.server.retrieve(path, @resource[:links])
- rescue Puppet::Network::XMLRPCClientError => detail
- self.err "Could not retrieve %s: %s" %
- [path, detail]
- return nil
+ rescue => detail
+ self.fail "Could not retrieve %s: %s" % [path, detail]
end
- # FIXME It's stupid that this isn't taken care of in the
- # protocol.
- unless sourceobj.server.local
- contents = CGI.unescape(contents)
- end
+ contents = CGI.unescape(contents) unless sourceobj.server.local
if contents == ""
- self.notice "Could not retrieve contents for %s" %
- @source
+ self.notice "Could not retrieve contents for %s" % @source
end
return contents
diff --git a/lib/puppet/type/pfile/target.rb b/lib/puppet/type/file/target.rb
index a0e5dc401..a0e5dc401 100644
--- a/lib/puppet/type/pfile/target.rb
+++ b/lib/puppet/type/file/target.rb
diff --git a/lib/puppet/type/pfile/type.rb b/lib/puppet/type/file/type.rb
index 65539795b..65539795b 100755
--- a/lib/puppet/type/pfile/type.rb
+++ b/lib/puppet/type/file/type.rb
diff --git a/lib/puppet/type/pfilebucket.rb b/lib/puppet/type/filebucket.rb
index 872bded4e..872bded4e 100755
--- a/lib/puppet/type/pfilebucket.rb
+++ b/lib/puppet/type/filebucket.rb
diff --git a/lib/puppet/type/host.rb b/lib/puppet/type/host.rb
index be5c2ed72..53365bf40 100755
--- a/lib/puppet/type/host.rb
+++ b/lib/puppet/type/host.rb
@@ -4,6 +4,13 @@ module Puppet
newproperty(:ip) do
desc "The host's IP address, IPv4 or IPv6."
+
+ validate do |value|
+ unless value =~ /((([0-9a-fA-F]+:){7}[0-9a-fA-F]+)|(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?::(([0-9a-fA-F]+:)*[0-9a-fA-F]+)?)|((25[0-5]|2[0-4][\d]|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})/
+ raise Puppet::Error, "Invalid IP address"
+ end
+ end
+
end
newproperty(:alias) do
@@ -78,6 +85,15 @@ module Puppet
desc "The host name."
isnamevar
+
+ validate do |value|
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = value.split('.').each do |hostpart|
+ unless hostpart =~ /^([\d\w]+|[\d\w][\d\w\-]+[\d\w])$/
+ raise Puppet::Error, "Invalid host name"
+ end
+ end
+ end
end
@doc = "Installs and manages host entries. For most systems, these
diff --git a/lib/puppet/type/mailalias.rb b/lib/puppet/type/mailalias.rb
index 92f609267..50ca26ef6 100755
--- a/lib/puppet/type/mailalias.rb
+++ b/lib/puppet/type/mailalias.rb
@@ -9,7 +9,7 @@ module Puppet
end
newproperty(:recipient, :array_matching => :all) do
- desc "Where email should should be sent. Multiple values
+ desc "Where email should be sent. Multiple values
should be specified as an array."
def is_to_s(value)
diff --git a/lib/puppet/type/package.rb b/lib/puppet/type/package.rb
index 9173eaa1c..f004f7c42 100644
--- a/lib/puppet/type/package.rb
+++ b/lib/puppet/type/package.rb
@@ -176,7 +176,7 @@ module Puppet
a common name to packages::
# In the 'openssl' class
- $ssl = $operationgsystem ? {
+ $ssl = $operatingsystem ? {
solaris => SMCossl,
default => openssl
}
@@ -190,7 +190,7 @@ module Puppet
. etc. .
- $ssh = $operationgsystem ? {
+ $ssh = $operatingsystem ? {
solaris => SMCossh,
default => openssh
}
@@ -200,7 +200,7 @@ module Puppet
package { $ssh:
ensure => installed,
alias => openssh,
- require => package[openssl]
+ require => Package[openssl]
}
"
@@ -211,14 +211,6 @@ module Puppet
desc "Where to find the actual package. This must be a local file
(or on a network file system) or a URL that your specific
packaging type understands; Puppet will not retrieve files for you."
-
- validate do |value|
- unless value =~ /^#{File::SEPARATOR}/ or value =~ /\w+:\/\//
- self.fail(
- "Package sources must be fully qualified files or URLs, depending on the platform."
- )
- end
- end
end
newparam(:instance) do
desc "A read-only parameter set by the package."
diff --git a/lib/puppet/type/pfile/checksum.rb b/lib/puppet/type/pfile/checksum.rb
deleted file mode 100755
index 08f48ea21..000000000
--- a/lib/puppet/type/pfile/checksum.rb
+++ /dev/null
@@ -1,326 +0,0 @@
-# Keep a copy of the file checksums, and notify when they change.
-
-# This state never actually modifies the system, it only notices when the system
-# changes on its own.
-module Puppet
- Puppet.type(:file).newproperty(:checksum) do
- desc "How to check whether a file has changed. This state is used internally
- for file copying, but it can also be used to monitor files somewhat
- like Tripwire without managing the file contents in any way. You can
- specify that a file's checksum should be monitored and then subscribe to
- the file from another object and receive events to signify
- checksum changes, for instance."
-
- @event = :file_changed
-
- @unmanaged = true
-
- @validtypes = %w{md5 md5lite timestamp mtime time}
-
- def self.validtype?(type)
- @validtypes.include?(type)
- end
-
- @validtypes.each do |ctype|
- newvalue(ctype) do
- handlesum()
- end
- end
-
- str = @validtypes.join("|")
-
- # This is here because Puppet sets this internally, using
- # {md5}......
- newvalue(/^\{#{str}\}/) do
- handlesum()
- end
-
- newvalue(:nosum) do
- # nothing
- :nochange
- end
-
- # If they pass us a sum type, behave normally, but if they pass
- # us a sum type + sum, stick the sum in the cache.
- munge do |value|
- if value =~ /^\{(\w+)\}(.+)$/
- type = symbolize($1)
- sum = $2
- cache(type, sum)
- return type
- else
- if FileTest.directory?(@resource[:path])
- return :time
- else
- return symbolize(value)
- end
- end
- end
-
- # Store the checksum in the data cache, or retrieve it if only the
- # sum type is provided.
- def cache(type, sum = nil)
- unless type
- raise ArgumentError, "A type must be specified to cache a checksum"
- end
- type = symbolize(type)
- unless state = @resource.cached(:checksums)
- self.debug "Initializing checksum hash"
- state = {}
- @resource.cache(:checksums, state)
- end
-
- if sum
- unless sum =~ /\{\w+\}/
- sum = "{%s}%s" % [type, sum]
- end
- state[type] = sum
- else
- return state[type]
- end
- end
-
- # Because source and content and whomever else need to set the checksum
- # and do the updating, we provide a simple mechanism for doing so.
- def checksum=(value)
- munge(@should)
- self.updatesum(value)
- end
-
- def checktype
- self.should || :md5
- end
-
- # Checksums need to invert how changes are printed.
- def change_to_s(currentvalue, newvalue)
- begin
- if currentvalue == :absent
- return "defined '%s' as '%s'" %
- [self.name, self.currentsum]
- elsif newvalue == :absent
- return "undefined %s from '%s'" %
- [self.name, self.is_to_s(currentvalue)]
- else
- if defined? @cached and @cached
- return "%s changed '%s' to '%s'" %
- [self.name, @cached, self.is_to_s(currentvalue)]
- else
- return "%s changed '%s' to '%s'" %
- [self.name, self.currentsum, self.is_to_s(currentvalue)]
- end
- end
- rescue Puppet::Error, Puppet::DevError
- raise
- rescue => detail
- raise Puppet::DevError, "Could not convert change %s to string: %s" %
- [self.name, detail]
- end
- end
-
- def currentsum
- #"{%s}%s" % [self.should, cache(self.should)]
- cache(checktype())
- end
-
- # Retrieve the cached sum
- def getcachedsum
- hash = nil
- unless hash = @resource.cached(:checksums)
- hash = {}
- @resource.cache(:checksums, hash)
- end
-
- sumtype = self.should
-
- if hash.include?(sumtype)
- #self.notice "Found checksum %s for %s" %
- # [hash[sumtype] ,@resource[:path]]
- sum = hash[sumtype]
-
- unless sum =~ /^\{\w+\}/
- sum = "{%s}%s" % [sumtype, sum]
- end
- return sum
- elsif hash.empty?
- #self.notice "Could not find sum of type %s" % sumtype
- return :nosum
- else
- #self.notice "Found checksum for %s but not of type %s" %
- # [@resource[:path],sumtype]
- return :nosum
- end
- end
-
- # Calculate the sum from disk.
- def getsum(checktype)
- sum = ""
-
- checktype = checktype.intern if checktype.is_a? String
- case checktype
- when :md5, :md5lite:
- if ! FileTest.file?(@resource[:path])
- @resource.debug "Cannot MD5 sum %s; using mtime" %
- [@resource.stat.ftype]
- sum = @resource.stat.mtime.to_s
- else
- begin
- File.open(@resource[:path]) { |file|
- hashfunc = Digest::MD5.new
- while (!file.eof)
- readBuf = file.read(512)
- hashfunc.update(readBuf)
- if checktype == :md5lite then
- break
- end
- end
- sum = hashfunc.hexdigest
- }
- rescue Errno::EACCES => detail
- self.notice "Cannot checksum %s: permission denied" %
- @resource[:path]
- @resource.delete(self.class.name)
- rescue => detail
- self.notice "Cannot checksum: %s" %
- detail
- @resource.delete(self.class.name)
- end
- end
- when :timestamp, :mtime:
- sum = @resource.stat.mtime.to_s
- #sum = File.stat(@resource[:path]).mtime.to_s
- when :time:
- sum = @resource.stat.ctime.to_s
- #sum = File.stat(@resource[:path]).ctime.to_s
- else
- raise Puppet::Error, "Invalid sum type %s" % checktype
- end
-
- return "{#{checktype}}" + sum.to_s
- end
-
- # At this point, we don't actually modify the system, we modify
- # the stored state to reflect the current state, and then kick
- # off an event to mark any changes.
- def handlesum
- currentvalue = self.retrieve
- if currentvalue.nil?
- raise Puppet::Error, "Checksum state for %s is somehow nil" %
- @resource.title
- end
-
- if self.insync?(currentvalue)
- self.debug "Checksum is already in sync"
- return nil
- end
- # @resource.debug "%s(%s): after refresh, is '%s'" %
- # [self.class.name,@resource.name,@is]
-
- # If we still can't retrieve a checksum, it means that
- # the file still doesn't exist
- if currentvalue == :absent
- # if they're copying, then we won't worry about the file
- # not existing yet
- unless @resource.property(:source)
- self.warning("File %s does not exist -- cannot checksum" %
- @resource[:path]
- )
- end
- return nil
- end
-
- # If the sums are different, then return an event.
- if self.updatesum(currentvalue)
- return :file_changed
- else
- return nil
- end
- end
-
- def insync?(currentvalue)
- @should = [checktype()]
- if cache(checktype())
- return currentvalue == currentsum()
- else
- # If there's no cached sum, then we don't want to generate
- # an event.
- return true
- end
- end
-
- # Even though they can specify multiple checksums, the insync?
- # mechanism can really only test against one, so we'll just retrieve
- # the first specified sum type.
- def retrieve(usecache = false)
- # When the 'source' is retrieving, it passes "true" here so
- # that we aren't reading the file twice in quick succession, yo.
- currentvalue = currentsum()
- if usecache and currentvalue
- return currentvalue
- end
-
- stat = nil
- unless stat = @resource.stat
- return :absent
- end
-
- if stat.ftype == "link" and @resource[:links] != :follow
- self.debug "Not checksumming symlink"
- # @resource.delete(:checksum)
- return currentvalue
- end
-
- # Just use the first allowed check type
- currentvalue = getsum(checktype())
-
- # If there is no sum defined, then store the current value
- # into the cache, so that we're not marked as being
- # out of sync. We don't want to generate an event the first
- # time we get a sum.
- unless cache(checktype())
- # FIXME we should support an updatechecksums-like mechanism
- self.updatesum(currentvalue)
- end
-
- # @resource.debug "checksum state is %s" % self.is
- return currentvalue
- end
-
- # Store the new sum to the state db.
- def updatesum(newvalue)
- result = false
-
- if newvalue.is_a?(Symbol)
- raise Puppet::Error, "%s has invalid checksum" % @resource.title
- end
-
- # if we're replacing, vs. updating
- if sum = cache(checktype())
- # unless defined? @should
- # raise Puppet::Error.new(
- # ("@should is not initialized for %s, even though we " +
- # "found a checksum") % @resource[:path]
- # )
- # end
-
- if newvalue == sum
- return false
- end
-
- self.debug "Replacing %s checksum %s with %s" %
- [@resource.title, sum, newvalue]
- # @resource.debug "currentvalue: %s; @should: %s" %
- # [newvalue,@should]
- result = true
- else
- @resource.debug "Creating checksum %s" % newvalue
- result = false
- end
-
- # Cache the sum so the log message can be right if possible.
- @cached = sum
- cache(checktype(), newvalue)
- return result
- end
- end
-end
-
diff --git a/lib/puppet/type/service.rb b/lib/puppet/type/service.rb
index c41a7883b..560d81bae 100644
--- a/lib/puppet/type/service.rb
+++ b/lib/puppet/type/service.rb
@@ -28,6 +28,8 @@ module Puppet
feature :enableable, "The provider can enable and disable the service",
:methods => [:disable, :enable, :enabled?]
+ feature :controllable, "The provider uses a control variable."
+
newproperty(:enable, :required_features => :enableable) do
desc "Whether a service should be enabled to start at boot.
This property behaves quite differently depending on the platform;
@@ -111,7 +113,9 @@ module Puppet
munge do |value|
value = [value] unless value.is_a?(Array)
- paths = value.flatten.collect { |p| p.split(":") }.flatten.find_all do |path|
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ # It affects stand-alone blocks, too.
+ paths = value.flatten.collect { |p| x = p.split(":") }.flatten.find_all do |path|
if FileTest.directory?(path)
true
else
@@ -163,6 +167,13 @@ module Puppet
desc "Specify a *stop* command manually."
end
+ newparam(:control) do
+ desc "The control variable used to manage services (originally for HP-UX).
+ Defaults to the upcased service name plus ``START`` replacing dots with
+ underscores, for those providers that support the ``controllable`` feature."
+ defaultto { resource.name.gsub(".","_").upcase + "_START" if resource.provider.controllable? }
+ end
+
newparam :hasrestart do
desc "Specify that an init script has a ``restart`` option. Otherwise,
the init script's ``stop`` and ``start`` methods are used."
diff --git a/lib/puppet/type/sshkey.rb b/lib/puppet/type/sshkey.rb
index bf4b0aac8..c2bdd39e3 100755
--- a/lib/puppet/type/sshkey.rb
+++ b/lib/puppet/type/sshkey.rb
@@ -53,14 +53,14 @@ module Puppet
end
newparam(:name) do
- desc "The host name."
+ desc "The host name that the key is associated with."
isnamevar
end
newproperty(:target) do
- desc "The file in which to store the mount table. Only used by
- those providers that write to disk (i.e., not NetInfo)."
+ desc "The file in which to store the ssh key. Only used by
+ the ``parsed`` provider."
defaultto { if @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
@resource.class.defaultprovider.default_target
diff --git a/lib/puppet/type/tidy.rb b/lib/puppet/type/tidy.rb
index dacf037ac..fe8bde9ab 100755
--- a/lib/puppet/type/tidy.rb
+++ b/lib/puppet/type/tidy.rb
@@ -1,5 +1,5 @@
module Puppet
- newtype(:tidy, Puppet.type(:file)) do
+ newtype(:tidy, :parent => Puppet.type(:file)) do
@doc = "Remove unwanted files based on specific criteria. Multiple
criteria are OR'd together, so a file that is too large but is not
old enough will still get tidied."
diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb
index 2e83a08e9..560afe10b 100644
--- a/lib/puppet/util.rb
+++ b/lib/puppet/util.rb
@@ -226,7 +226,8 @@ module Util
return nil
end
else
- ENV['PATH'].split(":").each do |dir|
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = ENV['PATH'].split(":").each do |dir|
if FileTest.exists? File.join(dir, bin)
return File.join(dir, bin)
end
diff --git a/lib/puppet/util/autoload.rb b/lib/puppet/util/autoload.rb
index a52575522..535d9ef2e 100644
--- a/lib/puppet/util/autoload.rb
+++ b/lib/puppet/util/autoload.rb
@@ -1,6 +1,9 @@
+require 'puppet/util/warnings'
+
# Autoload paths, either based on names or all at once.
class Puppet::Util::Autoload
include Puppet::Util
+ include Puppet::Util::Warnings
@autoloaders = {}
@loaded = []
@@ -109,9 +112,8 @@ class Puppet::Util::Autoload
Dir.glob("#{dir}/*.rb").each do |file|
name = File.basename(file).sub(".rb", '').intern
next if loaded?(name)
- rubypath = File.join(@path, name.to_s)
begin
- Kernel.require rubypath
+ Kernel.require file
loaded(name, file)
rescue => detail
if Puppet[:trace]
@@ -123,8 +125,6 @@ class Puppet::Util::Autoload
end
end
- private
-
# Yield each subdir in turn.
def eachdir
searchpath.each do |dir|
@@ -137,7 +137,7 @@ class Puppet::Util::Autoload
def searchpath
# JJM: Search for optional lib directories in each module bundle.
module_lib_dirs = Puppet[:modulepath].split(":").collect do |d|
- Dir.glob("%s/*/lib" % d).select do |f|
+ Dir.glob("%s/*/{plugins,lib}" % d).select do |f|
FileTest.directory?(f)
end
end.flatten
diff --git a/lib/puppet/util/checksums.rb b/lib/puppet/util/checksums.rb
index 6f6ea59b5..15d2eadd1 100644
--- a/lib/puppet/util/checksums.rb
+++ b/lib/puppet/util/checksums.rb
@@ -1,37 +1,75 @@
+# A stand-alone module for calculating checksums
+# in a generic way.
module Puppet::Util::Checksums
+ # Calculate a checksum using Digest::MD5.
def md5(content)
require 'digest/md5'
Digest::MD5.hexdigest(content)
end
- def md5_file(filename)
+ # Calculate a checksum of the first 500 chars of the content using Digest::MD5.
+ def md5lite(content)
+ md5(content[0..511])
+ end
+
+ # Calculate a checksum of a file's content using Digest::MD5.
+ def md5_file(filename, lite = false)
require 'digest/md5'
- incr_digest = Digest::MD5.new()
- File.open(filename, 'r') do |file|
- file.each_line do |line|
- incr_digest << line
- end
- end
+ digest = Digest::MD5.new()
+ return checksum_file(digest, filename, lite)
+ end
+
+ # Calculate a checksum of the first 500 chars of a file's content using Digest::MD5.
+ def md5lite_file(filename)
+ md5_file(filename, true)
+ end
- return incr_digest.hexdigest
+ # Return the :mtime timestamp of a file.
+ def mtime_file(filename)
+ File.stat(filename).send(:mtime)
end
+ # Calculate a checksum using Digest::SHA1.
def sha1(content)
require 'digest/sha1'
Digest::SHA1.hexdigest(content)
end
- def sha1_file(filename)
+ # Calculate a checksum of the first 500 chars of the content using Digest::SHA1.
+ def sha1lite(content)
+ sha1(content[0..511])
+ end
+
+ # Calculate a checksum of a file's content using Digest::SHA1.
+ def sha1_file(filename, lite = false)
require 'digest/sha1'
- incr_digest = Digest::SHA1.new()
+ digest = Digest::SHA1.new()
+ return checksum_file(digest, filename, lite)
+ end
+
+ # Calculate a checksum of the first 500 chars of a file's content using Digest::SHA1.
+ def sha1lite_file(filename)
+ sha1_file(filename, true)
+ end
+
+ # Return the :ctime of a file.
+ def ctime_file(filename)
+ File.stat(filename).send(:ctime)
+ end
+
+ private
+
+ # Perform an incremental checksum on a file.
+ def checksum_file(digest, filename, lite = false)
File.open(filename, 'r') do |file|
- file.each_line do |line|
- incr_digest << line
+ while content = file.read(512)
+ digest << content
+ break if lite
end
end
- return incr_digest.hexdigest
+ return digest.hexdigest
end
end
diff --git a/lib/puppet/util/constant_inflector.rb b/lib/puppet/util/constant_inflector.rb
new file mode 100644
index 000000000..eeeaa0632
--- /dev/null
+++ b/lib/puppet/util/constant_inflector.rb
@@ -0,0 +1,15 @@
+# Created on 2008-02-12
+# Copyright Luke Kanies
+
+# A common module for converting between constants and
+# file names.
+module Puppet::Util::ConstantInflector
+ def file2constant(file)
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = file.split("/").collect { |name| name.capitalize }.join("::").gsub(/_+(.)/) { |term| $1.capitalize }
+ end
+
+ def constant2file(constant)
+ constant.to_s.gsub(/([a-z])([A-Z])/) { |term| $1 + "_" + $2 }.gsub("::", "/").downcase
+ end
+end
diff --git a/lib/puppet/util/diff.rb b/lib/puppet/util/diff.rb
index e6ff57108..f37ea0850 100644
--- a/lib/puppet/util/diff.rb
+++ b/lib/puppet/util/diff.rb
@@ -27,7 +27,7 @@ module Puppet::Util::Diff
output = ""
- diffs = Diff::LCS.diff(data_old, data_new)
+ diffs = ::Diff::LCS.diff(data_old, data_new)
return output if diffs.empty?
oldhunk = hunk = nil
@@ -35,7 +35,7 @@ module Puppet::Util::Diff
diffs.each do |piece|
begin
- hunk = Diff::LCS::Hunk.new(data_old, data_new, piece,
+ hunk = ::Diff::LCS::Hunk.new(data_old, data_new, piece,
context_lines,
file_length_difference)
file_length_difference = hunk.file_length_difference
diff --git a/lib/puppet/util/fileparsing.rb b/lib/puppet/util/fileparsing.rb
index 8e39719c8..23d02ea60 100644
--- a/lib/puppet/util/fileparsing.rb
+++ b/lib/puppet/util/fileparsing.rb
@@ -223,7 +223,8 @@ module Puppet::Util::FileParsing
# Split text into separate lines using the record separator.
def lines(text)
# Remove any trailing separators, and then split based on them
- text.sub(/#{self.line_separator}\Q/,'').split(self.line_separator)
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ x = text.sub(/#{self.line_separator}\Q/,'').split(self.line_separator)
end
# Split a bunch of text into lines and then parse them individually.
diff --git a/lib/puppet/util/filetype.rb b/lib/puppet/util/filetype.rb
index 95f48e10e..ae078fff4 100755
--- a/lib/puppet/util/filetype.rb
+++ b/lib/puppet/util/filetype.rb
@@ -106,8 +106,14 @@ class Puppet::Util::FileType
# Overwrite the file.
def write(text)
backup()
+
raise("Cannot create file %s in absent directory" % @path) unless FileTest.exist?(File.dirname(@path))
- File.open(@path, "w") { |f| f.print text; f.flush }
+
+ require "tempfile"
+ tf = Tempfile.new("puppet")
+ tf.print text; tf.flush
+ FileUtils.cp(tf.path, @path)
+ tf.close
end
end
@@ -168,7 +174,7 @@ class Puppet::Util::FileType
# Remove a specific @path's cron tab.
def remove
- if Facter.value("operatingsystem") == "FreeBSD"
+ if %w{Darwin FreeBSD}.include?(Facter.value("operatingsystem"))
%x{/bin/echo yes | #{cmdbase()} -r 2>/dev/null}
else
%x{#{cmdbase()} -r 2>/dev/null}
diff --git a/lib/puppet/util/graph.rb b/lib/puppet/util/graph.rb
index a9744578b..d1ef36f8e 100644
--- a/lib/puppet/util/graph.rb
+++ b/lib/puppet/util/graph.rb
@@ -16,7 +16,7 @@ module Puppet::Util::Graph
self.each do |child|
unless block_given? and ! yield(child)
- graph.add_edge!(self, child)
+ graph.add_edge(self, child)
if child.respond_to?(:to_graph)
child.to_graph(graph, &block)
diff --git a/lib/puppet/util/settings.rb b/lib/puppet/util/settings.rb
index b672d9564..089389a09 100644
--- a/lib/puppet/util/settings.rb
+++ b/lib/puppet/util/settings.rb
@@ -44,19 +44,6 @@ class Puppet::Util::Settings
return value
end
- # A simplified equality operator.
- # LAK: For some reason, this causes mocha to not be able to mock
- # the 'value' method, and it's not used anywhere.
-# def ==(other)
-# self.each { |myname, myobj|
-# unless other[myname] == value(myname)
-# return false
-# end
-# }
-#
-# return true
-# end
-
# Generate the list of valid arguments, in a format that GetoptLong can
# understand, and add them to the passed option list.
def addargs(options)
@@ -225,6 +212,9 @@ class Puppet::Util::Settings
# A central concept of a name.
@name = nil
+
+ # The list of sections we've used.
+ @used = []
end
# Return a given object's file metadata.
@@ -243,14 +233,7 @@ class Puppet::Util::Settings
# Make a directory with the appropriate user, group, and mode
def mkdir(default)
- obj = nil
- unless obj = @config[default]
- raise ArgumentError, "Unknown default %s" % default
- end
-
- unless obj.is_a? CFile
- raise ArgumentError, "Default %s is not a file" % default
- end
+ obj = get_config_file_default(default)
Puppet::Util::SUIDManager.asuser(obj.owner, obj.group) do
mode = obj.mode || 0750
@@ -329,94 +312,6 @@ class Puppet::Util::Settings
end
end
- # Parse the configuration file. As of May 2007, this is a backward-compatibility method and
- # will be deprecated soon.
- def old_parse(file)
- text = nil
-
- if file.is_a? Puppet::Util::LoadedFile
- @file = file
- else
- @file = Puppet::Util::LoadedFile.new(file)
- end
-
- # Don't create a timer for the old style parsing.
- # settimer()
-
- begin
- text = File.read(@file.file)
- rescue Errno::ENOENT
- raise Puppet::Error, "No such file %s" % file
- rescue Errno::EACCES
- raise Puppet::Error, "Permission denied to file %s" % file
- end
-
- @values = Hash.new { |names, name|
- names[name] = {}
- }
-
- # Get rid of the values set by the file, keeping cli values.
- self.clear(true)
-
- section = "puppet"
- metas = %w{owner group mode}
- values = Hash.new { |hash, key| hash[key] = {} }
- text.split(/\n/).each { |line|
- case line
- when /^\[(\w+)\]$/: section = $1 # Section names
- when /^\s*#/: next # Skip comments
- when /^\s*$/: next # Skip blanks
- when /^\s*(\w+)\s*=\s*(.+)$/: # settings
- var = $1.intern
- if var == :mode
- value = $2
- else
- value = munge_value($2)
- end
-
- # Only warn if we don't know what this config var is. This
- # prevents exceptions later on.
- unless @config.include?(var) or metas.include?(var.to_s)
- Puppet.warning "Discarded unknown configuration parameter %s" % var.inspect
- next # Skip this line.
- end
-
- # Mmm, "special" attributes
- if metas.include?(var.to_s)
- unless values.include?(section)
- values[section] = {}
- end
- values[section][var.to_s] = value
-
- # If the parameter is valid, then set it.
- if section == Puppet[:name] and @config.include?(var)
- #@config[var].value = value
- @values[:main][var] = value
- end
- next
- end
-
- # Don't override set parameters, since the file is parsed
- # after cli arguments are handled.
- unless @config.include?(var) and @config[var].setbycli
- Puppet.debug "%s: Setting %s to '%s'" % [section, var, value]
- @values[:main][var] = value
- end
- @config[var].section = symbolize(section)
-
- metas.each { |meta|
- if values[section][meta]
- if @config[var].respond_to?(meta + "=")
- @config[var].send(meta + "=", values[section][meta])
- end
- end
- }
- else
- raise Puppet::Error, "Could not match line %s" % line
- end
- }
- end
-
# Create a new element. The value is passed in because it's used to determine
# what kind of element we're creating, but the value itself might be either
# a default or a value, so we can't actually assign it.
@@ -509,19 +404,19 @@ class Puppet::Util::Settings
objects += add_user_resources(section, obj, done)
end
+ value = obj.value
+
# Only files are convertable to transportable resources.
- if obj.respond_to? :to_transportable
- next if value(obj.name) =~ /^\/dev/
- transobjects = obj.to_transportable
- transobjects = [transobjects] unless transobjects.is_a? Array
- transobjects.each do |trans|
- # transportable could return nil
- next unless trans
- unless done[:file].include? trans.name
- @created << trans.name
- objects << trans
- done[:file][trans.name] = trans
- end
+ next unless obj.respond_to? :to_transportable and transobjects = obj.to_transportable
+
+ transobjects = [transobjects] unless transobjects.is_a? Array
+ transobjects.each do |trans|
+ # transportable could return nil
+ next unless trans
+ unless done[:file].include? trans.name
+ @created << trans.name
+ objects << trans
+ done[:file][trans.name] = trans
end
end
end
@@ -670,23 +565,36 @@ Generated on #{Time.now}.
# you can 'use' a section as many times as you want.
def use(*sections)
@@sync.synchronize do # yay, thread-safe
- unless defined? @used
- @used = []
- end
+ sections = sections.reject { |s| @used.include?(s.to_sym) }
+
+ return if sections.empty?
bucket = to_transportable(*sections)
- config = bucket.to_catalog
- config.host_config = false
- config.apply do |transaction|
- if failures = transaction.any_failed?
- raise "Could not configure for running; got %s failure(s)" % failures
+ begin
+ catalog = bucket.to_catalog
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not create resources for managing Puppet's files and directories: %s" % detail
+
+ # We need some way to get rid of any resources created during the catalog creation
+ # but not cleaned up.
+ return
+ end
+
+ begin
+ catalog.host_config = false
+ catalog.apply do |transaction|
+ if failures = transaction.any_failed?
+ raise "Could not configure for running; got %s failure(s)" % failures
+ end
end
+ ensure
+ catalog.clear
end
- config.clear
sections.each { |s| @used << s }
- @used.uniq
+ @used.uniq!
end
end
@@ -737,49 +645,15 @@ Generated on #{Time.now}.
end
# Open a file with the appropriate user, group, and mode
- def write(default, *args)
- obj = nil
- unless obj = @config[default]
- raise ArgumentError, "Unknown default %s" % default
- end
-
- unless obj.is_a? CFile
- raise ArgumentError, "Default %s is not a file" % default
- end
-
- chown = nil
- if Puppet::Util::SUIDManager.uid == 0
- chown = [obj.owner, obj.group]
- else
- chown = [nil, nil]
- end
- Puppet::Util::SUIDManager.asuser(*chown) do
- mode = obj.mode || 0640
-
- if args.empty?
- args << "w"
- end
-
- args << mode
-
- File.open(value(obj.name), *args) do |file|
- yield file
- end
- end
+ def write(default, *args, &bloc)
+ obj = get_config_file_default(default)
+ writesub(default, value(obj.name), *args, &bloc)
end
# Open a non-default file under a default dir with the appropriate user,
# group, and mode
- def writesub(default, file, *args)
- obj = nil
- unless obj = @config[default]
- raise ArgumentError, "Unknown default %s" % default
- end
-
- unless obj.is_a? CFile
- raise ArgumentError, "Default %s is not a file" % default
- end
-
+ def writesub(default, file, *args, &bloc)
+ obj = get_config_file_default(default)
chown = nil
if Puppet::Util::SUIDManager.uid == 0
chown = [obj.owner, obj.group]
@@ -804,8 +678,51 @@ Generated on #{Time.now}.
end
end
+ def readwritelock(default, *args, &bloc)
+ file = value(get_config_file_default(default).name)
+ tmpfile = file + ".tmp"
+ sync = Sync.new
+ unless FileTest.directory?(File.dirname(tmpfile))
+ raise Puppet::DevError, "Cannot create %s; directory %s does not exist" %
+ [file, File.dirname(file)]
+ end
+
+ sync.synchronize(Sync::EX) do
+ File.open(file, "r+", 0600) do |rf|
+ rf.lock_exclusive do
+ if File.exist?(tmpfile)
+ raise Puppet::Error, ".tmp file already exists for %s; Aborting locked write. Check the .tmp file and delete if appropriate" %
+ [file]
+ end
+
+ writesub(default, tmpfile, *args, &bloc)
+
+ begin
+ File.rename(tmpfile, file)
+ rescue => detail
+ Puppet.err "Could not rename %s to %s: %s" %
+ [file, tmpfile, detail]
+ end
+ end
+ end
+ end
+ end
+
private
+ def get_config_file_default(default)
+ obj = nil
+ unless obj = @config[default]
+ raise ArgumentError, "Unknown default %s" % default
+ end
+
+ unless obj.is_a? CFile
+ raise ArgumentError, "Default %s is not a file" % default
+ end
+
+ return obj
+ end
+
# Create the transportable objects for users and groups.
def add_user_resources(section, obj, done)
resources = []
@@ -1124,7 +1041,7 @@ Generated on #{Time.now}.
# the variable 'dir', or adding a slash at the end.
def munge(value)
# If it's not a fully qualified path...
- if value.is_a?(String) and value !~ /^\$/ and value !~ /^\//
+ if value.is_a?(String) and value !~ /^\$/ and value !~ /^\// and value != 'false'
# Make it one
value = File.join(Dir.getwd, value)
end
@@ -1153,12 +1070,15 @@ Generated on #{Time.now}.
def to_transportable
type = self.type
return nil unless type
- path = @parent.value(self.name).split(File::SEPARATOR)
- path.shift # remove the leading nil
- objects = []
path = self.value
+ return nil unless path.is_a?(String)
+ return nil if path =~ /^\/dev/
+ return nil if Puppet::Type.type(:file)[path] # skip files that are in our global resource list.
+
+ objects = []
+
# Skip plain files that don't exist, since we won't be managing them anyway.
return nil unless self.name.to_s =~ /dir$/ or File.exist?(path) or self.create
obj = Puppet::TransObject.new(path, "file")
diff --git a/lib/puppet/util/tagging.rb b/lib/puppet/util/tagging.rb
new file mode 100644
index 000000000..e06e13a2c
--- /dev/null
+++ b/lib/puppet/util/tagging.rb
@@ -0,0 +1,40 @@
+# Created on 2008-01-19
+# Copyright Luke Kanies
+
+# A common module to handle tagging.
+module Puppet::Util::Tagging
+ # Add a tag to our current list. These tags will be added to all
+ # of the objects contained in this scope.
+ def tag(*ary)
+ @tags ||= []
+
+ qualified = []
+
+ ary.collect { |tag| tag.to_s.downcase }.each do |tag|
+ fail(Puppet::ParseError, "Invalid tag %s" % tag.inspect) unless valid_tag?(tag)
+ qualified << tag if tag.include?("::")
+ @tags << tag unless @tags.include?(tag)
+ end
+
+ # LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
+ qualified.collect { |name| x = name.split("::") }.flatten.each { |tag| @tags << tag unless @tags.include?(tag) }
+ end
+
+ # Are we tagged with the provided tag?
+ def tagged?(tag)
+ defined?(@tags) and @tags.include?(tag.to_s)
+ end
+
+ # Return a copy of the tag list, so someone can't ask for our tags
+ # and then modify them.
+ def tags
+ @tags ||= []
+ @tags.dup
+ end
+
+ private
+
+ def valid_tag?(tag)
+ tag =~ /^\w[-\w:.]*$/
+ end
+end
diff --git a/man/man8/filebucket.8 b/man/man8/filebucket.8
new file mode 100644
index 000000000..fdaca9f31
--- /dev/null
+++ b/man/man8/filebucket.8
@@ -0,0 +1,116 @@
+.TH "" "" ""
+.SH NAME
+ \-
+
+.\" Man page generated from reStructeredText.
+
+.SH SYNOPSIS
+A stand\-alone Puppet filebucket client.
+
+
+.SH USAGE
+
+.\" visit_block_quote
+
+.TP
+.B filebucket [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose]
+[\-l|\-\-local] [\-r|\-\-remote]
+[\-s|\-\-server <server>] [\-b|\-\-bucket <directory>] <file> <file> ...
+
+
+.\" depart_block_quote
+
+.SH DESCRIPTION
+This is a stand\-alone filebucket client for sending files to a local or
+central filebucket.
+
+
+.SH USAGE
+This client can operate in three modes, with only one mode per call:
+
+
+.TP
+.B backup: Send one or more files to the specified file bucket. Each sent
+file is printed with its resulting md5 sum.
+
+
+.TP
+.B get: Return the text associated with an md5 sum. The text is printed
+to stdout, and only one file can be retrieved at a time.
+
+
+.TP
+.B restore: Given a file path and an md5 sum, store the content associated
+with the sum into the specified file path. You can specify an
+entirely new path to this argument; you are not restricted to
+restoring the content to its original location.
+
+Note that +filebucket+ defaults to using a network\-based filebucket
+available on the server named +puppet+. To use this, you\'ll have to be
+running as a user with valid Puppet certificates. Alternatively, you can
+use your local file bucket by specifying +\-\-local+.
+
+
+.SH EXAMPLE
+
+.\" visit_block_quote
+$ filebucket backup /etc/passwd
+/etc/passwd: 429b225650b912a2ee067b0a4cf1e949
+$ filebucket restore /tmp/passwd 429b225650b912a2ee067b0a4cf1e949
+$
+
+
+.\" depart_block_quote
+
+.SH OPTIONS
+Note that any configuration parameter that\'s valid in the configuration
+file is also a valid long argument. For example, \'ssldir\' is a valid
+configuration parameter, so you can specify \'\-\-ssldir <directory>\' as an
+argument.
+
+See the configuration file documentation at
+http://reductivelabs.com/projects/puppet/reference/configref.html for
+the full list of acceptable parameters. A commented list of all
+configuration options can also be generated by running puppet with
+\'\-\-genconfig\'.
+
+debug: Enable full debugging.
+
+help: Print this help message
+
+
+.TP
+.B local: Use the local filebucket. This will use the default
+configuration information.
+
+
+.TP
+.B remote: Use a remote filebucket. This will use the default
+configuration information.
+
+server: The server to send the file to, instead of locally.
+
+verbose: Print extra information.
+
+version: Print version information.
+
+
+.SH EXAMPLE
+
+.\" visit_block_quote
+filebucket \-b /tmp/filebucket /my/file
+
+
+.\" depart_block_quote
+
+.SH AUTHOR
+Luke Kanies
+
+
+.SH COPYRIGHT
+Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
+License
+
+
+.\" Generated by docutils manpage writer on 2008-03-22 17:46.
+.\"
diff --git a/man/man8/pi.8 b/man/man8/pi.8
new file mode 100644
index 000000000..da13d8e52
--- /dev/null
+++ b/man/man8/pi.8
@@ -0,0 +1,34 @@
+.TH "" "" ""
+.SH NAME
+ \-
+
+.\" Man page generated from reStructeredText.
+
+.TP
+.B bin/pi [options] [type]
+
+.TP
+.B Print documentation for puppet types and their parameters
+
+.TP
+.B \-l , \-\-list
+List all types
+
+
+.TP
+.B \-p , \-\-providers
+Describe providers in detail
+
+
+.TP
+.B \-s , \-\-short
+Only list parameters without detail
+
+
+.TP
+.B \-m , \-\-meta
+Include metaparams
+
+
+.\" Generated by docutils manpage writer on 2008-03-22 17:46.
+.\"
diff --git a/man/man8/puppet.8 b/man/man8/puppet.8
index 2fd2ab102..0281d330e 100644
--- a/man/man8/puppet.8
+++ b/man/man8/puppet.8
@@ -1,514 +1,77 @@
-.\" -*- nroff -*-
-.\" This file may be copied under the terms of the GNU Public License.
-.\"
-.TH PUPPET 8 "Jan 2007" "Reductive Labs"
+.TH "" "" ""
.SH NAME
-puppet, puppetmasterd, ca \- automated configuration management
+ \-
+
+.\" Man page generated from reStructeredText.
+
.SH SYNOPSIS
-.B puppet
-.RI [options]
-.br
-.B puppetmasterd
-.RI [options]
-.br
-.B ca
-.RI [options]
+Run a stand\-alone +puppet+ script.
+
+
+.SH USAGE
+
+.\" visit_block_quote
+
+.TP
+.B puppet [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose]
+[\-l|\-\-logdest <file>] <file>
+
+
+.\" depart_block_quote
+
.SH DESCRIPTION
-This document is intended as a secondary reference only. Please refer to the complete documentation on the
-.B puppet
-website:
-.PP
-\h"4"http://www.reductivelabs.com/trac/puppet/wiki/DocumentationStart
-.PP
-Every
-.B puppet
-executable (with the exception of
-.B puppetdoc
-) accepts all of the arguments below, but not all of the arguments make sense for every executable. Each argument has a section listed with it in parentheses; often, that section will map to an executable (e.g.,
-.B puppetd
-), in which case it probably only makes sense for that one executable. If
-.B puppet
-is listed as the section, it is most likely an option that is valid for everyone.
-.PP
-This will not always be the case. I have tried to be as thorough as possible in the descriptions of the arguments, so it should be obvious whether an argument is appropriate or not.
-.PP
-These arguments can be supplied to the executables either as command-line arugments or in the configuration file for the appropriate executable. For instance, the command-line invocation below would set the configuration directory to /private/puppet:
-.PP
-\h"4"$ puppetd --confdir=/private/puppet
-.PP
-Note that boolean options are turned on and off with a slightly different syntax on the command line:
-.PP
-\h"4"$ puppetd --storeconfigs
-.PP
-\h"4"$ puppetd --no-storeconfigs
-.PP
-The invocations above will enable and disable, respectively, the storage of the client configuration.
-.PP
-As mentioned above, the configuration parameters can also be stored in a configuration file located in the configuration directory (/etc/puppet by default). The file is named for the executable it is intended for, for example /etc/puppetd.conf is the configuration file for
-.B puppetd.
-.PP
-The file, which follows INI-style formatting, should contain a bracketed heading named for the executable, followed by pairs of parameters with their values. Here is an example of a very simple puppetd.conf file:
-.PP
-\h"4"[puppetd]
-.br
-\h"4"confdir = /private/puppet
-.br
-\h"4"storeconfigs = true
-.br
-.PP
-Note that boolean parameters must be explicitly specified as true or false as seen above.
-.PP
-If you're starting out with a fresh configuration, you may wish to let the executable generate a template configuration file for you by invoking the executable in question with the --genconfig command. The executable will print a template configuration to standard output, which can be redirected to a file like so:
-.PP
-\h"4"$ puppetd --genconfig > /etc/puppet/puppetd.conf
-.PP
-Note that this invocation will "clobber" (throw away) the contents of any pre-existing puppetd.conf file, so make a backup of your present config if it contains valuable information.
-.PP
-Like the --genconfig argument, the executables also accept a --genmanifest argument, which will generate a manifest that can be used to manage all of
-.B Puppet's
-directories and files and prints it to standard output. This can likewise be redirected to a file:
-.PP
-\h"4"$ puppetd --genmanifest > /etc/puppet/manifests/site.pp
-.PP
-.B Puppet
-can also create user and group accounts for itself (one puppet group and one puppet user) if it is invoked as root with the --mkusers argument:
-.PP
-\h"4"$ puppetd --mkusers
-.PP
-.SH SIGNALS
-The
-.B puppetd
-and
-.B puppetmasterd
-executables catch some signals for special handling. Both daemons catch (SIGHUP), which forces the server to restart tself. Predictably, interrupt and terminate (SIGINT and SIGHUP) will shut down the server, whether it be an instance of
-.B puppetd
-or
-.B puppetmasterd.
-.PP
-Sending the SIGUSR1 signal to an instance of
-.B puppetd
-will cause it to immediately begin a new configuration transaction with the server. This signal has no effect on
-.B puppetmasterd.
+This is the standalone puppet execution script; use it to execute
+individual scripts that you write. If you need to execute site\-wide
+scripts, use +puppetd+ and +puppetmasterd+.
+
+
.SH OPTIONS
+Note that any configuration parameter that\'s valid in the configuration
+file is also a valid long argument. For example, \'ssldir\' is a valid
+configuration parameter, so you can specify \'\-\-ssldir <directory>\' as an
+argument.
+
+See the configuration file documentation at
+http://reductivelabs.com/projects/puppet/reference/configref.html for
+the full list of acceptable parameters. A commented list of all
+configuration options can also be generated by running puppet with
+\'\-\-genconfig\'.
+
+debug: Enable full debugging.
+
+help: Print this help message
+
+
.TP
-.B \-\-authconfig
-(puppet) The configuration file that defines the rights to the different namespaces and methods. This can be used as a coarse-grained authorization system for both
-.B puppetd
-and
-.B puppetmasterd
-. Default value is: /etc/puppet/namespaceauth.conf
-.TP
-.B \-\-autoflush
-(puppet) Whether log files should always flush to disk.
-.TP
-.B \-\-autosign
-(ca) Whether to enable autosign. Valid values are true (which autosigns any key request, and is a very bad idea), false (which never autosigns any key request), and the path to a file, which uses that configuration file to determine which keys to sign. Default value is: /etc/puppet/autosign.conf
-.TP
-.B \-\-bucketdir
-(puppetmasterd) Where FileBucket files are stored. Default value is: /var/puppet/bucket
-.TP
-.B \-\-ca_days
-(ca) How long a certificate should be valid. This parameter is deprecated, use ca_ttl instead
-.TP
-.B \-\-ca_md
-(ca) The type of hash used in certificates. Default value is: md5
-.TP
-.B \-\-ca_ttl
-(ca) The default TTL for new certificates; valid values must be an integer, optionally followed by one of the units 'y' (years of 365 days), 'd' (days), 'h' (hours), or 's' (seconds). The unit defaults to seconds. If this parameter is set, ca_days is ignored. Examples are '3600' (one hour) and '1825d', which is the same as '5y' (5 years) 5y
-.TP
-.B \-\-cacert
-(ca) The CA certificate. Default value is: /etc/puppet/ssl/ca/ca_crt.pem
-.TP
-.B \-\-cacrl
-(ca) The certificate revocation list (CRL) for the CA. Set this to 'none' if you do not want to use a CRL. Default value is: /etc/puppet/ssl/ca/ca_crl.pem
-.TP
-.B \-\-cadir
-(ca) The root directory for the certificate authority. Default value is: /etc/puppet/ssl/ca
-.TP
-.B \-\-cakey
-(ca) The CA private key. Default value is: /etc/puppet/ssl/ca/ca_key.pem
-.TP
-.B \-\-capass
-(ca) Where the CA stores the password for the private key. Default value is: /etc/puppet/ssl/ca/private/ca.pass
-.TP
-.B \-\-caprivatedir
-(ca) Where the CA stores private certificate information. Default value is: /etc/puppet/ssl/ca/private
-.TP
-.B \-\-capub
-(ca) The CA public key. Default value is: /etc/puppet/ssl/ca/ca_pub.pem
-.TP
-.B \-\-casesensitive
-(puppet) Whether matching in case statements and selectors should be case-sensitive. Case insensitivity is handled by downcasing all values before comparison.
-.TP
-.B \-\-cert_inventory
-(ca) A Complete listing of all certificates. Default value is: /etc/puppet/ssl/ca/inventory.txt
-.TP
-.B \-\-certdir
-(certificates) The certificate directory. Default value is: /etc/puppet/ssl/certs
-.TP
-.B \-\-classfile
-(puppetd) The file in which
-.B puppetd
-stores a list of the classes associated with the retrieved configuratiion. Can be loaded in the separate puppet executable using the --loadclasses option. Default value is: /etc/puppet/classes.txt
-.TP
-.B \-\-clientbucketdir
-(filebucket) Where FileBucket files are stored locally. Default value is: /var/puppet/clientbucket
-.TP
-.B \-\-color
-(puppet) Whether to use colors when logging to the console. Valid values are ansi (equivalent to true), html (mostly used during testing with TextMate), and false, which produces no color. Default value is: ansi
-.TP
-.B \-\-confdir
-(puppet) The main Puppet configuration directory. Default value is: /etc/puppet
-.TP
-.B \-\-config
-(puppetdoc) The configuration file for puppetdoc. Default value is: /etc/puppet/puppetdoc.conf
-.TP
-.B \-\-configprint
-(puppet) Print the value of a specific configuration parameter. If a parameter is provided for this, then the value is printed and puppet exits. Comma-separate mul.TPle values. For a list of all values, specify 'all'. This feature is only available in Puppet versions higher than 0.18.4.
-.TP
-.B \-\-csrdir
-(ca) Where the CA stores certificate requests Default value is: /etc/puppet/ssl/ca/requests
-.TP
-.B \-\-dbadapter
-(puppetmaster) The type of database to use. Default value is: sqlite3
-.TP
-.B \-\-dblocation
-(puppetmaster) The database cache for client configurations. Used for querying within the language. Default value is: /var/puppet/state/clientconfigs.sqlite3
-.TP
-.B \-\-dbmigrate
-(puppetmaster) Whether to automatically migrate the database.
-.TP
-.B \-\-dbname
-(puppetmaster) The name of the database to use. Default value is: puppet
-.TP
-.B \-\-dbpassword
-(puppetmaster) The database password for Client caching. Only used when networked databases are used. Default value is: puppet
-.TP
-.B \-\-dbserver
-(puppetmaster) The database server for Client caching. Only used when networked databases are used. Default value is: localhost
-.TP
-.B \-\-dbuser
-(puppetmaster) The database user for Client caching. Only used when networked databases are used. Default value is: puppet
-.TP
-.B \-\-evaltrace
-(transaction) Whether each resource should log when it is being evaluated. This allows you to interactively see exactly what is being done.
-.TP
-.B \-\-external_nodes
-(puppet) An external command that can produce node information. The first line of output must be either the parent node or blank, and if there is a second line of output it should be a list of whitespace-separated classes to include on that node. This command makes it straightforward to store your node mapping information in other data sources like databases. For unknown nodes, the commands should exit with an exit code of 1. Default value is: none
-.TP
-.B \-\-factdest
-(puppet) Where Puppet should store facts that it pulls down from the central server. Default value is: /var/puppet/facts
-.TP
-.B \-\-factpath
-(puppet) Where Puppet should look for facts. Mul.TPle directories should be colon-separated, like normal PATH variables. Default value is: /var/puppet/facts
-.TP
-.B \-\-factsignore
-(puppet) What files to ignore when pulling down facts. Default value is: .svn CVS
-.TP
-.B \-\-factsource
-(puppet) From where to retrieve facts. The standard Puppet file type is used for retrieval, so anything that is a valid file source can be used here. Default value is: puppet://puppet/facts
-.TP
-.B \-\-factsync
-(puppet) Whether facts should be synced with the central server.
-.TP
-.B \-\-fileserverconfig
-(fileserver) Where the fileserver configuration is stored. Default value is: /etc/puppet/fileserver.conf
-.TP
-.B \-\-filetimeout
-(puppet) The minimum time to wait between checking for updates in configuration files. Default value is: 15
-.TP
-.B \-\-genconfig
-(puppet) Whether to just print a configuration to stdout and exit. Only makes sense when used interactively. Takes into account arguments specified on the CLI.
-.TP
-.B \-\-genmanifest
-(puppet) Whether to just print a manifest to stdout and exit. Only makes sense when used interactively. Takes into account arguments specified on the CLI.
-.TP
-.B \-\-graph
-(puppet) Whether to create dot graph files for the different configuration graphs. These dot files can be interpreted by tools like OmniGraffle or dot (which is part of ImageMagick).
-.TP
-.B \-\-graphdir
-(puppet) Where to store dot-outputted graphs. Default value is: /var/puppet/state/graphs
-.TP
-.B \-\-group
-(puppetmasterd) The group
-.B puppetmasterd
- should run as. Default value is: puppet
-.TP
-.B \-\-hostcert
-(certificates) Where individual hosts store and look for their certificates. Default value is: /etc/puppet/ssl/certs/culain.madstop.com.pem
-.TP
-.B \-\-hostprivkey
-(certificates) Where individual hosts store and look for their private key. Default value is: /etc/puppet/ssl/private_keys/culain.madstop.com.pem
-.TP
-.B \-\-hostpubkey
-(certificates) Where individual hosts store and look for their public key. Default value is: /etc/puppet/ssl/public_keys/culain.madstop.com.pem
-.TP
-.B \-\-httplog
-(puppetd) Where the
-.B puppetd
-web server logs. Default value is: /var/puppet/log/http.log
-.TP
-.B \-\-ignoreschedules
-(puppetd) Boolean; whether
-.B puppetd
-should ignore schedules. Default value is: This is useful for initial
-.B puppetd
-runs.
-.TP
-.B \-\-keylength
-(ca) The bit length of keys. Default value is: 1024
-.TP
-.B \-\-ldapattrs
-(ldap) The LDAP attributes to use to define Puppet classes. Values should be comma-separated. Default value is: puppetclass
-.TP
-.B \-\-ldapbase
-(ldap) The search base for LDAP searches. It's impossible to provide a meaningful default here, although the LDAP libraries might have one already set. Generally, it should be the 'ou=Hosts' branch under your main directory.
-.TP
-.B \-\-ldapnodes
-(ldap) Whether to search for node configurations in LDAP.
-.TP
-.B \-\-ldapparentattr
-(ldap) The attribute to use to define the parent node. Default value is: parentnode
-.TP
-.B \-\-ldappassword
-(ldap) The password to use to connect to LDAP.
-.TP
-.B \-\-ldapport
-(ldap) The LDAP port. Only used if ldapnodes is enabled. Default value is: 389
-.TP
-.B \-\-ldapserver
-(ldap) The LDAP server. Only used if ldapnodes is enabled. Default value is: ldap
-.TP
-.B \-\-ldapssl
-(ldap) Whether SSL should be used when searching for nodes. Defaults to false because SSL usually requires certificates to be set up on the client side.
-.TP
-.B \-\-ldapstring
-Default value is: (ldap)
-.TP
-.B \-\-The search string used to find an LDAP node.
-Default value is: (&(objectclass=puppetClient)(cn=%s))
-.TP
-.B \-\-ldaptls
-(ldap) Whether TLS should be used when searching for nodes. Defaults to false because TLS usually requires certificates to be set up on the client side.
-.TP
-.B \-\-ldapuser
-(ldap) The user to use to connect to LDAP. Must be specified as a full DN.
-.TP
-.B \-\-lexical
-(puppet) Whether to use lexical scoping (vs. dynamic).
-.TP
-.B \-\-listen
-(puppetd) Whether
-.B puppetd
-should listen for connections. If this is true, then by default only the runner server is started, which allows remote authorized and authenticated nodes to connect and trigger
-.B puppetd
-runs.
-.TP
-.B \-\-localcacert
-(certificates) Where each client stores the CA certificate. Default value is: /etc/puppet/ssl/certs/ca.pem
-.TP
-.B \-\-localconfig
-(puppetd) Where
-.B puppetd
-caches the local configuration. An extension indicating the cache format is added automatically. Default value is: /etc/puppet/localconfig
-.TP
-.B \-\-lockdir
-(puppet) Where lock files are kept. Default value is: /var/puppet/locks
-.TP
-.B \-\-logdir
-(puppet) The Puppet log directory. Default value is: /var/puppet/log
-.TP
-.B \-\-manifest
-(puppetmasterd) The entry-point manifest for
-.B puppetmasterd
-. Default value is: /etc/puppet/manifests/site.pp
-.TP
-.B \-\-manifestdir
-(puppetmasterd) Where
-.B puppetmasterd
- looks for its manifests. Default value is: /etc/puppet/manifests
-.TP
-.B \-\-masterhttplog
-(puppetmasterd) Where the
-.B puppetmasterd
- web server logs. Default value is: /var/puppet/log/masterhttp.log
-.TP
-.B \-\-masterlog
-(puppetmasterd) Where
-.B puppetmasterd
- logs. This is generally not used, since syslog is the default log destination. Default value is: /var/puppet/log/puppetmaster.log
-.TP
-.B \-\-masterport
-(puppetmasterd) Which port
-.B puppetmasterd
- listens on. Default value is: 8140
-.TP
-.B \-\-mkusers
-(puppet) Whether to create the necessary user and group that
-.B puppetd
-will run as.
-.TP
-.B \-\-node_name
-(puppetmasterd) How the puppetmaster determines the client's identity and sets the 'hostname' fact for use in the manifest, in particular for determining which 'node' statement applies to the client. Possible values are 'cert' (use the subject's CN in the client's certificate) and 'facter' (use the hostname that the client reported in its facts) Default value is: cert
-.TP
-.B \-\-noop
-(puppetd) Whether
-.B puppetd
-should be run in noop mode.
-.TP
-.B \-\-paramcheck
-(ast) Whether to validate parameters during parsing. Default value is: true
-.TP
-.B \-\-parseonly
-(puppetmasterd) Just check the syntax of the manifests.
-.TP
-.B \-\-passfile
-(certificates) Where
-.B puppetd
-stores the password for its private key. Generally unused. Default value is: /etc/puppet/ssl/private/password
-.TP
-.B \-\-path
-(puppet) The shell search path. Defaults to whatever is inherited from the parent process. Default value is: none
-.TP
-.B \-\-plugindest
-(puppet) Where Puppet should store plugins that it pulls down from the central server. Default value is: /var/puppet/plugins
-.TP
-.B \-\-pluginpath
-(puppet) Where Puppet should look for plugins. Mul.TPle directories should be colon-separated, like normal PATH variables. Default value is: /var/puppet/plugins
-.TP
-.B \-\-pluginsignore
-(puppet) What files to ignore when pulling down plugins. Default value is: .svn CVS
-.TP
-.B \-\-pluginsource
-(puppet) From where to retrieve plugins. The standard Puppet file type is used for retrieval, so anything that is a valid file source can be used here. Default value is: puppet://puppet/plugins
-.TP
-.B \-\-pluginsync
-(puppet) Whether plugins should be synced with the central server.
-.TP
-.B \-\-privatedir
-(certificates) Where the client stores private certificate information. Default value is: /etc/puppet/ssl/private
-.TP
-.B \-\-privatekeydir
-(certificates) The private key directory. Default value is: /etc/puppet/ssl/private_keys
-.TP
-.B \-\-publickeydir
-(certificates) The public key directory. Default value is: /etc/puppet/ssl/public_keys
-.TP
-.B \-\-puppetdlockfile
-(puppetd) A lock file to temporarily stop
-.B puppetd
-from doing anything. Default value is: /var/puppet/state/puppetdlock
-.TP
-.B \-\-puppetdlog
-(puppetd) The log file for puppetd. This is generally not used. Default value is: /var/puppet/log/puppetd.log
-.TP
-.B \-\-puppetport
-(puppetd) Which port
-.B puppetd
-listens on. Default value is: 8139
-.TP
-.B \-\-railslog
-(puppetmaster) Where Rails-specific logs are sent Default value is: /var/puppet/log/rails.log
-.TP
-.B \-\-report
-(puppetd) Whether to send reports after every transaction.
-.TP
-.B \-\-reportdir
-(reporting) The directory in which to store reports received from the client. Each client gets a separate subdirectory. /var/puppet/reports
-.TP
-.B \-\-reports
-(reporting) The list of reports to generate. All reports are looked for in puppet/reports/.rb, and mul.TPle report names should be comma-separated (whitespace is okay). Default value is: store
-.TP
-.B \-\-reportserver
-(puppetd) The server to which to send transaction reports. Default value is: puppet
-.TP
-.B \-\-req_bits
-(ca) The bit length of the certificates. Default value is: 2048
-.TP
-.B \-\-rrddir
-(metrics) The directory where RRD database files are stored. Directories for each reporting host will be created under this directory. Default value is: /var/puppet/rrd
-.TP
-.B \-\-rrdgraph
-(metrics) Whether RRD information should be graphed.
-.TP
-.B \-\-rrdinterval
-(metrics) How often RRD should expect data. This should match how often the hosts report back to the server. Default value is: 1800
-.TP
-.B \-\-rundir
-(puppet) Where Puppet PID files are kept. Default value is: /var/puppet/run
-.TP
-.B \-\-runinterval
-(puppetd) How often
-.B puppetd
-applies the client configuration; in seconds Default value is: 1800
-.TP
-.B \-\-serial
-(ca) Where the serial number for certificates is stored. Default value is: /etc/puppet/ssl/ca/serial
-.TP
-.B \-\-server
-(puppetd) The server to which server
-.B puppetd
-should connect puppet
-.TP
-.B \-\-setpidfile
-(puppet) Whether to store a PID file for the daemon. Default value is: true
-.TP
-.B \-\-signeddir
-(ca) Where the CA stores signed certificates. Default value is: /etc/puppet/ssl/ca/signed
-.TP
-.B \-\-ssldir
-(puppet) Where SSL certificates are kept. Default value is: /etc/puppet/ssl
-.TP
-.B \-\-statedir
-(puppet) The directory where Puppet state is stored. Generally, this directory can be removed without causing harm (although it might result in spurious service restarts). Default value is: /var/puppet/state
-.TP
-.B \-\-statefile
-(puppet) Where
-.B puppetd
-and
-.B puppetmasterd
- store state associated with the running configuration. In the case of puppetmasterd, this file reflects the state discovered through interacting with clients. Default value is: /var/puppet/state/state.yaml
-.TP
-.B \-\-storeconfigs
-(puppetmaster) Whether to store each client's configuration. This requires ActiveRecord from Ruby on Rails.
-.TP
-.B \-\-syslogfacility
-(puppet) What syslog facility to use when logging to syslog. Syslog has a fixed list of valid facilities, and you must choose one of those; you cannot just make one up. daemon
-.TP
-.B \-\-tags
-(transaction) Tags to use to find resources. If this is set, then only resources tagged with the specified tags will be applied. Values must be comma-separated.
-.TP
-.B \-\-templatedir
-(puppet) Where Puppet looks for template files. Default value is: /var/puppet/templates
-.TP
-.B \-\-trace
-(puppet) Whether to print stack traces on some errors
-.TP
-.B \-\-typecheck
-(ast) Whether to validate types during parsing. Default value is: true
-.TP
-.B \-\-usecacheonfailure
-(puppetd) Whether to use the cached configuration when the remote configuration will not compile. This option is useful for testing new configurations, where you want to fix the broken configuration rather than reverting to a known-good one. Default value is: true
-.TP
-.B \-\-user
-(puppetmasterd) The user
-.B puppetmasterd
- should run as. Default value is: puppet
+.B loadclasses: Load any stored classes. +puppetd+ caches configured
+classes (usually at /etc/puppet/classes.txt), and setting
+this option causes all of those classes to be set in your
++puppet+ manifest.
+
+
.TP
-.B \-\-vardir
-(puppet) Where Puppet stores dynamic and growing data. Default value is: /var/puppet
-.SH SEE ALSO
-.br
-http://www.reductivelabs.com/projects/puppet
-.br
-http://www.reductivelabs.com/trac/puppet/wiki/DocumentationStart
-.PP
+.B logdest: Where to send messages. Choose between syslog, the console,
+and a log file. Defaults to sending messages to the
+console.
+
+verbose: Print extra information.
+
+
+.SH EXAMPLE
+
+.\" visit_block_quote
+puppet \-l /tmp/script.log script.pp
+
+
+.\" depart_block_quote
+
.SH AUTHOR
-.B puppet
-was written by Luke Kanies (luke@reductivelabs.com) along with contributions from a great many tireless developers.
-.SH AVAILABILITY
-.B puppet
-is available from http://www.reductivelabs.com/downloads/.
-.SH SEE ALSO
-.BR facter (8)
+Luke Kanies
+.\" Generated by docutils manpage writer on 2008-01-20 10:28.
+.SH COPYRIGHT
+Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
+License
+
+.\" Generated by docutils manpage writer on 2008-03-22 17:46.
+.\"
diff --git a/man/man8/puppet.conf.8 b/man/man8/puppet.conf.8
new file mode 100644
index 000000000..e8040fb8e
--- /dev/null
+++ b/man/man8/puppet.conf.8
@@ -0,0 +1,1747 @@
+.TH Configuration Reference "" "" ""
+.SH NAME
+Configuration Reference \-
+
+.\" Man page generated from reStructeredText.
+This page is autogenerated; any changes will get overwritten
+.I (last generated on Sat Mar 22 17:46:15 +1100 2008)
+
+
+
+.\" topic: Contents
+.\"
+.\" Specifying Configuration Parameters
+.\"
+.\" Signals
+.\"
+.\" Configuration Parameter Reference
+
+.SH Specifying Configuration Parameters
+
+.SS On The Command\-Line
+Every Puppet executable (with the exception of
+.\" visit_literal
+puppetdoc
+.\" depart_literal
+) accepts all of
+the parameters below, but not all of the arguments make sense for every executable.
+Each parameter has a section listed with it in parentheses; often, that section
+will map to an executable (e.g.,
+.\" visit_literal
+puppetd
+.\" depart_literal
+), in which case it probably only
+makes sense for that one executable. If
+.\" visit_literal
+main
+.\" depart_literal
+ is listed as the section,
+it is most likely an option that is valid for everyone.
+
+I have tried to be as thorough as possible in the descriptions of the
+arguments, so it should be obvious whether an argument is appropriate or not.
+
+These parameters can be supplied to the executables either as command\-line
+options or in the configuration file. For instance, the command\-line
+invocation below would set the configuration directory to
+.\" visit_literal
+/private/puppet
+.\" depart_literal
+:
+
+
+.nf
+$ puppetd \-\-confdir=/private/puppet
+.fi
+Note that boolean options are turned on and off with a slightly different
+syntax on the command line:
+
+
+.nf
+$ puppetd \-\-storeconfigs
+
+$ puppetd \-\-no\-storeconfigs
+.fi
+The invocations above will enable and disable, respectively, the storage of
+the client configuration.
+
+
+.SS Configuration Files
+As mentioned above, the configuration parameters can also be stored in a
+configuration file, located in the configuration directory. As root, the
+default configuration directory is
+.\" visit_literal
+/etc/puppet
+.\" depart_literal
+, and as a regular user, the
+default configuration directory is
+.\" visit_literal
+~user/.puppet
+.\" depart_literal
+. As of 0.23.0, all
+executables look for
+.\" visit_literal
+puppet.conf
+.\" depart_literal
+ in their configuration directory
+(although they previously looked for separate files). For example,
+
+.\" visit_literal
+puppet.conf
+.\" depart_literal
+ is located at
+.\" visit_literal
+/etc/puppet/puppet.conf
+.\" depart_literal
+ as root and
+
+.\" visit_literal
+~user/.puppet/puppet.conf
+.\" depart_literal
+ as a regular user by default.
+
+All executables will set any parameters set within the
+.\" visit_literal
+main
+.\" depart_literal
+ section,
+while each executable will also look for a section named for the executable
+and load those parameters. For example,
+.\" visit_literal
+puppetd
+.\" depart_literal
+ will look for a
+section named
+.\" visit_literal
+puppetd
+.\" depart_literal
+, and
+.\" visit_literal
+puppetmasterd
+.\" depart_literal
+ looks for a section
+named
+.\" visit_literal
+puppetmasterd
+.\" depart_literal
+. This allows you to use a single configuration file
+to customize the settings for all of your executables.
+
+
+.SS File Format
+The file follows INI\-style formatting. Here is an example of a very simple
+
+.\" visit_literal
+puppet.conf
+.\" depart_literal
+ file:
+
+
+.nf
+[main]
+ confdir = /private/puppet
+ storeconfigs = true
+.fi
+Note that boolean parameters must be explicitly specified as
+.I true
+ or
+
+.I false
+ as seen above.
+
+If you need to change file parameters (e.g., reset the mode or owner), do
+so within curly braces on the same line:
+
+
+.nf
+[main]
+ myfile = /tmp/whatever {owner = root, mode = 644}
+.fi
+If you\'re starting out with a fresh configuration, you may wish to let
+the executable generate a template configuration file for you by invoking
+the executable in question with the
+.I \-\-genconfig
+ command. The executable
+will print a template configuration to standard output, which can be
+redirected to a file like so:
+
+
+.nf
+$ puppetd \-\-genconfig > /etc/puppet/puppet.conf
+.fi
+Note that this invocation will replace the contents of any pre\-existing
+
+.I puppet.conf
+ file, so make a backup of your present config if it contains
+valuable information.
+
+All parameters will be under a single section heading matching the name of
+the process used to generate the configuraiton (\'puppetd\', in this case).
+
+Like the
+.I \-\-genconfig
+ argument, the executables also accept a
+.I \-\-genmanifest
+
+argument, which will generate a manifest that can be used to manage all of
+Puppet\'s directories and files and prints it to standard output. This can
+likewise be redirected to a file:
+
+
+.nf
+$ puppetd \-\-genmanifest > /etc/puppet/manifests/site.pp
+.fi
+Puppet can also create user and group accounts for itself (one
+.I puppet
+ group
+and one
+.I puppet
+ user) if it is invoked as
+.I root
+ with the
+.I \-\-mkusers
+ argument:
+
+
+.nf
+$ puppetd \-\-mkusers
+.fi
+
+.SH Signals
+The
+.\" visit_literal
+puppetd
+.\" depart_literal
+ and
+.\" visit_literal
+puppetmasterd
+.\" depart_literal
+ executables catch some signals for special
+handling. Both daemons catch (
+.\" visit_literal
+SIGHUP
+.\" depart_literal
+), which forces the server to restart
+tself. Predictably, interrupt and terminate (
+.\" visit_literal
+SIGINT
+.\" depart_literal
+ and
+.\" visit_literal
+SIGHUP
+.\" depart_literal
+) will shut
+down the server, whether it be an instance of
+.\" visit_literal
+puppetd
+.\" depart_literal
+ or
+.\" visit_literal
+puppetmasterd
+.\" depart_literal
+.
+
+Sending the
+.\" visit_literal
+SIGUSR1
+.\" depart_literal
+ signal to an instance of
+.\" visit_literal
+puppetd
+.\" depart_literal
+ will cause it to
+immediately begin a new configuration transaction with the server. This
+signal has no effect on
+.\" visit_literal
+puppetmasterd
+.\" depart_literal
+.
+
+
+.SH Configuration Parameter Reference
+Below is a list of all documented parameters. Not all of them are valid with all
+Puppet executables, but the executables will ignore any inappropriate values.
+
+
+.SS authconfig
+The configuration file that defines the rights to the different namespaces and methods. This can be used as a coarse\-grained authorization system for both
+.\" visit_literal
+puppetd
+.\" depart_literal
+ and
+.\" visit_literal
+puppetmasterd
+.\" depart_literal
+.
+
+
+.TP 2
+\(bu
+Default: $confdir/namespaceauth.conf
+
+
+.SS autoflush
+Whether log files should always flush to disk.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS autosign
+Whether to enable autosign. Valid values are true (which autosigns any key request, and is a very bad idea), false (which never autosigns any key request), and the path to a file, which uses that configuration file to determine which keys to sign.
+
+
+.TP 2
+\(bu
+Default: $confdir/autosign.conf
+
+
+.SS bindaddress
+The address to bind to. Mongrel servers default to 127.0.0.1 and WEBrick defaults to 0.0.0.0.
+
+
+.SS bucketdir
+Where FileBucket files are stored.
+
+
+.TP 2
+\(bu
+Default: $vardir/bucket
+
+
+.SS ca
+Wether the master should function as a certificate authority.
+
+
+.TP 2
+\(bu
+Default: true
+
+
+.SS ca_days
+How long a certificate should be valid. This parameter is deprecated, use ca_ttl instead
+
+
+.SS ca_md
+The type of hash used in certificates.
+
+
+.TP 2
+\(bu
+Default: md5
+
+
+.SS ca_port
+The port to use for the certificate authority.
+
+
+.TP 2
+\(bu
+Default: $masterport
+
+
+.SS ca_server
+The server to use for certificate authority requests. It\'s a separate server because it cannot and does not need to horizontally scale.
+
+
+.TP 2
+\(bu
+Default: $server
+
+
+.SS ca_ttl
+The default TTL for new certificates; valid values must be an integer, optionally followed by one of the units \'y\' (years of 365 days), \'d\' (days), \'h\' (hours), or \'s\' (seconds). The unit defaults to seconds. If this parameter is set, ca_days is ignored. Examples are \'3600\' (one hour) and \'1825d\', which is the same as \'5y\' (5 years)
+
+
+.TP 2
+\(bu
+Default: 5y
+
+
+.SS cacert
+The CA certificate.
+
+
+.TP 2
+\(bu
+Default: $cadir/ca_crt.pem
+
+
+.SS cacrl
+The certificate revocation list (CRL) for the CA. Set this to \'false\' if you do not want to use a CRL.
+
+
+.TP 2
+\(bu
+Default: $cadir/ca_crl.pem
+
+
+.SS cadir
+The root directory for the certificate authority.
+
+
+.TP 2
+\(bu
+Default: $ssldir/ca
+
+
+.SS cakey
+The CA private key.
+
+
+.TP 2
+\(bu
+Default: $cadir/ca_key.pem
+
+
+.SS capass
+Where the CA stores the password for the private key
+
+
+.TP 2
+\(bu
+Default: $caprivatedir/ca.pass
+
+
+.SS caprivatedir
+Where the CA stores private certificate information.
+
+
+.TP 2
+\(bu
+Default: $cadir/private
+
+
+.SS capub
+The CA public key.
+
+
+.TP 2
+\(bu
+Default: $cadir/ca_pub.pem
+
+
+.SS casesensitive
+Whether matching in case statements and selectors should be case\-sensitive. Case insensitivity is handled by downcasing all values before comparison.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS cert_inventory
+A Complete listing of all certificates
+
+
+.TP 2
+\(bu
+Default: $cadir/inventory.txt
+
+
+.SS certdir
+The certificate directory.
+
+
+.TP 2
+\(bu
+Default: $ssldir/certs
+
+
+.SS certdnsnames
+The DNS names on the Server certificate as a colon\-separated list. If it\'s anything other than an empty string, it will be used as an alias in the created certificate. By default, only the server gets an alias set up, and only for \'puppet\'.
+
+
+.SS certname
+The name to use when handling certificates. Defaults to the fully qualified domain name.
+
+
+.TP 2
+\(bu
+Default: absinthe.lovedthanlost.net
+
+
+.SS classfile
+The file in which puppetd stores a list of the classes associated with the retrieved configuration. Can be loaded in the separate
+.\" visit_literal
+puppet
+.\" depart_literal
+ executable using the
+.\" visit_literal
+\-\-loadclasses
+.\" depart_literal
+ option.
+
+
+.TP 2
+\(bu
+Default: $statedir/classes.txt
+
+
+.SS clientbucketdir
+Where FileBucket files are stored locally.
+
+
+.TP 2
+\(bu
+Default: $vardir/clientbucket
+
+
+.SS code
+Code to parse directly. This is essentially only used by
+.\" visit_literal
+puppet
+.\" depart_literal
+, and should only be set if you\'re writing your own Puppet executable
+
+
+.SS color
+Whether to use colors when logging to the console. Valid values are
+.\" visit_literal
+ansi
+.\" depart_literal
+ (equivalent to
+.\" visit_literal
+true
+.\" depart_literal
+),
+.\" visit_literal
+html
+.\" depart_literal
+ (mostly used during testing with TextMate), and
+.\" visit_literal
+false
+.\" depart_literal
+, which produces no color.
+
+
+.TP 2
+\(bu
+Default: ansi
+
+
+.SS confdir
+The main Puppet configuration directory. The default for this parameter is calculated based on the user. If the process is runnig as root or the user that
+.\" visit_literal
+puppetmasterd
+.\" depart_literal
+ is supposed to run as, it defaults to a system directory, but if it\'s running as any other user, it defaults to being in
+.\" visit_literal
+~
+.\" depart_literal
+.
+
+
+.TP 2
+\(bu
+Default: /etc/puppet
+
+
+.SS config
+The configuration file for puppetdoc.
+
+
+.TP 2
+\(bu
+Default: $confdir/puppet.conf
+
+
+.SS configprint
+Print the value of a specific configuration parameter. If a parameter is provided for this, then the value is printed and puppet exits. Comma\-separate multiple values. For a list of all values, specify \'all\'. This feature is only available in Puppet versions higher than 0.18.4.
+
+
+.SS configtimeout
+How long the client should wait for the configuration to be retrieved before considering it a failure. This can help reduce flapping if too many clients contact the server at one time.
+
+
+.TP 2
+\(bu
+Default: 120
+
+
+.SS csrdir
+Where the CA stores certificate requests
+
+
+.TP 2
+\(bu
+Default: $cadir/requests
+
+
+.SS daemonize
+Send the process into the background. This is the default.
+
+
+.TP 2
+\(bu
+Default: true
+
+
+.SS dbadapter
+The type of database to use.
+
+
+.TP 2
+\(bu
+Default: sqlite3
+
+
+.SS dblocation
+The database cache for client configurations. Used for querying within the language.
+
+
+.TP 2
+\(bu
+Default: $statedir/clientconfigs.sqlite3
+
+
+.SS dbmigrate
+Whether to automatically migrate the database.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS dbname
+The name of the database to use.
+
+
+.TP 2
+\(bu
+Default: puppet
+
+
+.SS dbpassword
+The database password for Client caching. Only used when networked databases are used.
+
+
+.TP 2
+\(bu
+Default: puppet
+
+
+.SS dbserver
+The database server for Client caching. Only used when networked databases are used.
+
+
+.TP 2
+\(bu
+Default: localhost
+
+
+.SS dbsocket
+The database socket location. Only used when networked databases are used. Will be ignored if the value is an empty string.
+
+
+.SS dbuser
+The database user for Client caching. Only used when networked databases are used.
+
+
+.TP 2
+\(bu
+Default: puppet
+
+
+.SS diff
+Which diff command to use when printing differences between files.
+
+
+.TP 2
+\(bu
+Default: diff
+
+
+.SS diff_args
+Which arguments to pass to the diff command when printing differences between files.
+
+
+.SS downcasefacts
+Whether facts should be made all lowercase when sent to the server.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS dynamicfacts
+Facts that are dynamic; these facts will be ignored when deciding whether changed facts should result in a recompile. Multiple facts should be comma\-separated.
+
+
+.TP 2
+\(bu
+Default: memorysize,memoryfree,swapsize,swapfree
+
+
+.SS environment
+The environment Puppet is running in. For clients (e.g.,
+.\" visit_literal
+puppetd
+.\" depart_literal
+) this determines the environment itself, which is used to find modules and much more. For servers (i.e.,
+.\" visit_literal
+puppetmasterd
+.\" depart_literal
+) this provides the default environment for nodes we know nothing about.
+
+
+.TP 2
+\(bu
+Default: development
+
+
+.SS environments
+The valid environments for Puppet clients. This is more useful as a server\-side setting than client, but any environment chosen must be in this list. Values should be separated by a comma.
+
+
+.TP 2
+\(bu
+Default: production,development
+
+
+.SS evaltrace
+Whether each resource should log when it is being evaluated. This allows you to interactively see exactly what is being done.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS external_nodes
+An external command that can produce node information. The output must be a YAML dump of a hash, and that hash must have one or both of
+.\" visit_literal
+classes
+.\" depart_literal
+ and
+.\" visit_literal
+parameters
+.\" depart_literal
+, where
+.\" visit_literal
+classes
+.\" depart_literal
+ is an array and
+.\" visit_literal
+parameters
+.\" depart_literal
+ is a hash. For unknown nodes, the commands should exit with a non\-zero exit code. This command makes it straightforward to store your node mapping information in other data sources like databases.
+
+
+.TP 2
+\(bu
+Default: none
+
+
+.SS factdest
+Where Puppet should store facts that it pulls down from the central server.
+
+
+.TP 2
+\(bu
+Default: $vardir/facts
+
+
+.SS factpath
+Where Puppet should look for facts. Multiple directories should be colon\-separated, like normal PATH variables.
+
+
+.TP 2
+\(bu
+Default: $vardir/facts
+
+
+.SS factsignore
+What files to ignore when pulling down facts.
+
+
+.TP 2
+\(bu
+Default: .svn CVS
+
+
+.SS factsource
+From where to retrieve facts. The standard Puppet
+.\" visit_literal
+file
+.\" depart_literal
+ type is used for retrieval, so anything that is a valid file source can be used here.
+
+
+.TP 2
+\(bu
+Default: puppet://$server/facts
+
+
+.SS factsync
+Whether facts should be synced with the central server.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS fileserverconfig
+Where the fileserver configuration is stored.
+
+
+.TP 2
+\(bu
+Default: $confdir/fileserver.conf
+
+
+.SS filetimeout
+The minimum time to wait (in seconds) between checking for updates in configuration files. This timeout determines how quickly Puppet checks whether a file (such as manifests or templates) has changed on disk.
+
+
+.TP 2
+\(bu
+Default: 15
+
+
+.SS genconfig
+Whether to just print a configuration to stdout and exit. Only makes sense when used interactively. Takes into account arguments specified on the CLI.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS genmanifest
+Whether to just print a manifest to stdout and exit. Only makes sense when used interactively. Takes into account arguments specified on the CLI.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS graph
+Whether to create dot graph files for the different configuration graphs. These dot files can be interpreted by tools like OmniGraffle or dot (which is part of ImageMagick).
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS graphdir
+Where to store dot\-outputted graphs.
+
+
+.TP 2
+\(bu
+Default: $statedir/graphs
+
+
+.SS group
+The group puppetmasterd should run as.
+
+
+.TP 2
+\(bu
+Default: puppet
+
+
+.SS hostcert
+Where individual hosts store and look for their certificates.
+
+
+.TP 2
+\(bu
+Default: $certdir/$certname.pem
+
+
+.SS hostcsr
+Where individual hosts store and look for their certificates.
+
+
+.TP 2
+\(bu
+Default: $ssldir/csr_$certname.pem
+
+
+.SS hostprivkey
+Where individual hosts store and look for their private key.
+
+
+.TP 2
+\(bu
+Default: $privatekeydir/$certname.pem
+
+
+.SS hostpubkey
+Where individual hosts store and look for their public key.
+
+
+.TP 2
+\(bu
+Default: $publickeydir/$certname.pem
+
+
+.SS http_enable_post_connection_check
+Boolean; wheter or not puppetd should validate the server SSL certificate against the request hostname.
+
+
+.TP 2
+\(bu
+Default: true
+
+
+.SS http_proxy_host
+The HTTP proxy host to use for outgoing connections. Note: You may need to use a FQDN for the server hostname when using a proxy.
+
+
+.TP 2
+\(bu
+Default: none
+
+
+.SS http_proxy_port
+The HTTP proxy port to use for outgoing connections
+
+
+.TP 2
+\(bu
+Default: 3128
+
+
+.SS httplog
+Where the puppetd web server logs.
+
+
+.TP 2
+\(bu
+Default: $logdir/http.log
+
+
+.SS ignorecache
+Ignore cache and always recompile the configuration. This is useful for testing new configurations, where the local cache may in fact be stale even if the timestamps are up to date \- if the facts change or if the server changes.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS ignoreimport
+A parameter that can be used in commit hooks, since it enables you to parse\-check a single file rather than requiring that all files exist.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS ignoreschedules
+Boolean; whether puppetd should ignore schedules. This is useful for initial puppetd runs.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS keylength
+The bit length of keys.
+
+
+.TP 2
+\(bu
+Default: 1024
+
+
+.SS ldapattrs
+The LDAP attributes to include when querying LDAP for nodes. All returned attributes are set as variables in the top\-level scope. Multiple values should be comma\-separated. The value \'all\' returns all attributes.
+
+
+.TP 2
+\(bu
+Default: all
+
+
+.SS ldapbase
+The search base for LDAP searches. It\'s impossible to provide a meaningful default here, although the LDAP libraries might have one already set. Generally, it should be the \'ou=Hosts\' branch under your main directory.
+
+
+.SS ldapclassattrs
+The LDAP attributes to use to define Puppet classes. Values should be comma\-separated.
+
+
+.TP 2
+\(bu
+Default: puppetclass
+
+
+.SS ldapnodes
+Whether to search for node configurations in LDAP. See http://reductivelabs.com/puppet/trac/wiki/LdapNodes/ for more information.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS ldapparentattr
+The attribute to use to define the parent node.
+
+
+.TP 2
+\(bu
+Default: parentnode
+
+
+.SS ldappassword
+The password to use to connect to LDAP.
+
+
+.SS ldapport
+The LDAP port. Only used if
+.\" visit_literal
+ldapnodes
+.\" depart_literal
+ is enabled.
+
+
+.TP 2
+\(bu
+Default: 389
+
+
+.SS ldapserver
+The LDAP server. Only used if
+.\" visit_literal
+ldapnodes
+.\" depart_literal
+ is enabled.
+
+
+.TP 2
+\(bu
+Default: ldap
+
+
+.SS ldapssl
+Whether SSL should be used when searching for nodes. Defaults to false because SSL usually requires certificates to be set up on the client side.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS ldapstring
+The search string used to find an LDAP node.
+
+
+.TP 2
+\(bu
+Default: (&(objectclass=puppetClient)(cn=%s))
+
+
+.SS ldaptls
+Whether TLS should be used when searching for nodes. Defaults to false because TLS usually requires certificates to be set up on the client side.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS ldapuser
+The user to use to connect to LDAP. Must be specified as a full DN.
+
+
+.SS lexical
+Whether to use lexical scoping (vs. dynamic).
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS libdir
+An extra search path for Puppet. This is only useful for those files that Puppet will load on demand, and is only guaranteed to work for those cases. In fact, the autoload mechanism is responsible for making sure this directory is in Ruby\'s search path
+
+
+.TP 2
+\(bu
+Default: $vardir/lib
+
+
+.SS listen
+Whether puppetd should listen for connections. If this is true, then by default only the
+.\" visit_literal
+runner
+.\" depart_literal
+ server is started, which allows remote authorized and authenticated nodes to connect and trigger
+.\" visit_literal
+puppetd
+.\" depart_literal
+ runs.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS localcacert
+Where each client stores the CA certificate.
+
+
+.TP 2
+\(bu
+Default: $certdir/ca.pem
+
+
+.SS localconfig
+Where puppetd caches the local configuration. An extension indicating the cache format is added automatically.
+
+
+.TP 2
+\(bu
+Default: $statedir/localconfig
+
+
+.SS logdir
+The Puppet log directory.
+
+
+.TP 2
+\(bu
+Default: $vardir/log
+
+
+.SS manifest
+The entry\-point manifest for puppetmasterd.
+
+
+.TP 2
+\(bu
+Default: $manifestdir/site.pp
+
+
+.SS manifestdir
+Where puppetmasterd looks for its manifests.
+
+
+.TP 2
+\(bu
+Default: $confdir/manifests
+
+
+.SS masterhttplog
+Where the puppetmasterd web server logs.
+
+
+.TP 2
+\(bu
+Default: $logdir/masterhttp.log
+
+
+.SS masterlog
+Where puppetmasterd logs. This is generally not used, since syslog is the default log destination.
+
+
+.TP 2
+\(bu
+Default: $logdir/puppetmaster.log
+
+
+.SS masterport
+Which port puppetmasterd listens on.
+
+
+.TP 2
+\(bu
+Default: 8140
+
+
+.SS maximum_uid
+The maximum allowed UID. Some platforms use negative UIDs but then ship with tools that do not know how to handle signed ints, so the UIDs show up as huge numbers that can then not be fed back into the system. This is a hackish way to fail in a slightly more useful way when that happens.
+
+
+.TP 2
+\(bu
+Default: 4294967290
+
+
+.SS mkusers
+Whether to create the necessary user and group that puppetd will run as.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS modulepath
+The search path for modules as a colon\-separated list of directories.
+
+
+.TP 2
+\(bu
+Default: $confdir/modules:/usr/share/puppet/modules
+
+
+.SS name
+The name of the service, if we are running as one. The default is essentially $0 without the path or
+.\" visit_literal
+.rb
+.\" depart_literal
+.
+
+
+.TP 2
+\(bu
+Default: puppetdoc
+
+
+.SS node_name
+How the puppetmaster determines the client\'s identity and sets the \'hostname\', \'fqdn\' and \'domain\' facts for use in the manifest, in particular for determining which \'node\' statement applies to the client. Possible values are \'cert\' (use the subject\'s CN in the client\'s certificate) and \'facter\' (use the hostname that the client reported in its facts)
+
+
+.TP 2
+\(bu
+Default: cert
+
+
+.SS node_terminus
+Where to find information about nodes.
+
+
+.TP 2
+\(bu
+Default: plain
+
+
+.SS noop
+Whether puppetd should be run in noop mode.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS paramcheck
+Whether to validate parameters during parsing.
+
+
+.TP 2
+\(bu
+Default: true
+
+
+.SS parseonly
+Just check the syntax of the manifests.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS passfile
+Where puppetd stores the password for its private key. Generally unused.
+
+
+.TP 2
+\(bu
+Default: $privatedir/password
+
+
+.SS path
+The shell search path. Defaults to whatever is inherited from the parent process.
+
+
+.TP 2
+\(bu
+Default: none
+
+
+.SS pidfile
+The pid file
+
+
+.SS plugindest
+Where Puppet should store plugins that it pulls down from the central server.
+
+
+.TP 2
+\(bu
+Default: $libdir
+
+
+.SS pluginpath
+Where Puppet should look for plugins. Multiple directories should be colon\-separated, like normal PATH variables. As of 0.23.1, this option is deprecated; download your custom libraries to the $libdir instead.
+
+
+.TP 2
+\(bu
+Default: $vardir/plugins
+
+
+.SS pluginsignore
+What files to ignore when pulling down plugins.
+
+
+.TP 2
+\(bu
+Default: .svn CVS
+
+
+.SS pluginsource
+From where to retrieve plugins. The standard Puppet
+.\" visit_literal
+file
+.\" depart_literal
+ type is used for retrieval, so anything that is a valid file source can be used here.
+
+
+.TP 2
+\(bu
+Default: puppet://$server/plugins
+
+
+.SS pluginsync
+Whether plugins should be synced with the central server.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS privatedir
+Where the client stores private certificate information.
+
+
+.TP 2
+\(bu
+Default: $ssldir/private
+
+
+.SS privatekeydir
+The private key directory.
+
+
+.TP 2
+\(bu
+Default: $ssldir/private_keys
+
+
+.SS publickeydir
+The public key directory.
+
+
+.TP 2
+\(bu
+Default: $ssldir/public_keys
+
+
+.SS puppetdlockfile
+A lock file to temporarily stop puppetd from doing anything.
+
+
+.TP 2
+\(bu
+Default: $statedir/puppetdlock
+
+
+.SS puppetdlog
+The log file for puppetd. This is generally not used.
+
+
+.TP 2
+\(bu
+Default: $logdir/puppetd.log
+
+
+.SS puppetport
+Which port puppetd listens on.
+
+
+.TP 2
+\(bu
+Default: 8139
+
+
+.SS rails_loglevel
+The log level for Rails connections. The value must be a valid log level within Rails. Production environments normally use
+.\" visit_literal
+info
+.\" depart_literal
+ and other environments normally use
+.\" visit_literal
+debug
+.\" depart_literal
+.
+
+
+.TP 2
+\(bu
+Default: info
+
+
+.SS railslog
+Where Rails\-specific logs are sent
+
+
+.TP 2
+\(bu
+Default: $logdir/rails.log
+
+
+.SS report
+Whether to send reports after every transaction.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS reportdir
+The directory in which to store reports received from the client. Each client gets a separate subdirectory.
+
+
+.TP 2
+\(bu
+Default: $vardir/reports
+
+
+.SS reportfrom
+The \'from\' email address for the reports.
+
+
+.TP 2
+\(bu
+Default: report@absinthe.lovedthanlost.net
+
+
+.SS reports
+The list of reports to generate. All reports are looked for in puppet/reports/<name>.rb, and multiple report names should be comma\-separated (whitespace is okay).
+
+
+.TP 2
+\(bu
+Default: store
+
+
+.SS reportserver
+The server to which to send transaction reports.
+
+
+.TP 2
+\(bu
+Default: $server
+
+
+.SS req_bits
+The bit length of the certificates.
+
+
+.TP 2
+\(bu
+Default: 2048
+
+
+.SS rrddir
+The directory where RRD database files are stored. Directories for each reporting host will be created under this directory.
+
+
+.TP 2
+\(bu
+Default: $vardir/rrd
+
+
+.SS rrdgraph
+Whether RRD information should be graphed.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS rrdinterval
+How often RRD should expect data. This should match how often the hosts report back to the server.
+
+
+.TP 2
+\(bu
+Default: $runinterval
+
+
+.SS rundir
+Where Puppet PID files are kept.
+
+
+.TP 2
+\(bu
+Default: $vardir/run
+
+
+.SS runinterval
+How often puppetd applies the client configuration; in seconds.
+
+
+.TP 2
+\(bu
+Default: 1800
+
+
+.SS sendmail
+Where to find the sendmail binary with which to send email.
+
+
+.SS serial
+Where the serial number for certificates is stored.
+
+
+.TP 2
+\(bu
+Default: $cadir/serial
+
+
+.SS server
+The server to which server puppetd should connect
+
+
+.TP 2
+\(bu
+Default: puppet
+
+
+.SS servertype
+The type of server to use. Currently supported options are webrick and mongrel. If you use mongrel, you will need a proxy in front of the process or processes, since Mongrel cannot speak SSL.
+
+
+.TP 2
+\(bu
+Default: webrick
+
+
+.SS show_diff
+Whether to print a contextual diff when files are being replaced. The diff is printed on stdout, so this option is meaningless unless you are running Puppet interactively. This feature currently requires the
+.\" visit_literal
+diff/lcs
+.\" depart_literal
+ Ruby library.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS signeddir
+Where the CA stores signed certificates.
+
+
+.TP 2
+\(bu
+Default: $cadir/signed
+
+
+.SS smtpserver
+The server through which to send email reports.
+
+
+.TP 2
+\(bu
+Default: none
+
+
+.SS splay
+Whether to sleep for a pseudo\-random (but consistent) amount of time before a run.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS splaylimit
+The maximum time to delay before runs. Defaults to being the same as the run interval.
+
+
+.TP 2
+\(bu
+Default: $runinterval
+
+
+.SS ssl_client_header
+The header containing an authenticated client\'s SSL DN. Only used with Mongrel. This header must be set by the proxy to the authenticated client\'s SSL DN (e.g.,
+.\" visit_literal
+/CN=puppet.reductivelabs.com
+.\" depart_literal
+). See http://reductivelabs.com/puppet/trac/wiki/UsingMongrel for more information.
+
+
+.TP 2
+\(bu
+Default: HTTP_X_CLIENT_DN
+
+
+.SS ssl_client_verify_header
+The header containing the status message of the client verification. Only used with Mongrel. This header must be set by the proxy to \'SUCCESS\' if the client successfully authenticated, and anything else otherwise. See http://reductivelabs.com/puppet/trac/wiki/UsingMongrel for more information.
+
+
+.TP 2
+\(bu
+Default: HTTP_X_CLIENT_VERIFY
+
+
+.SS ssldir
+Where SSL certificates are kept.
+
+
+.TP 2
+\(bu
+Default: $confdir/ssl
+
+
+.SS statedir
+The directory where Puppet state is stored. Generally, this directory can be removed without causing harm (although it might result in spurious service restarts).
+
+
+.TP 2
+\(bu
+Default: $vardir/state
+
+
+.SS statefile
+Where puppetd and puppetmasterd store state associated with the running configuration. In the case of puppetmasterd, this file reflects the state discovered through interacting with clients.
+
+
+.TP 2
+\(bu
+Default: $statedir/state.yaml
+
+
+.SS storeconfigs
+Whether to store each client\'s configuration. This requires ActiveRecord from Ruby on Rails.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS summarize
+Whether to print a transaction summary.
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS syslogfacility
+What syslog facility to use when logging to syslog. Syslog has a fixed list of valid facilities, and you must choose one of those; you cannot just make one up.
+
+
+.TP 2
+\(bu
+Default: daemon
+
+
+.SS tagmap
+The mapping between reporting tags and email addresses.
+
+
+.TP 2
+\(bu
+Default: $confdir/tagmail.conf
+
+
+.SS tags
+Tags to use to find resources. If this is set, then only resources tagged with the specified tags will be applied. Values must be comma\-separated.
+
+
+.SS templatedir
+Where Puppet looks for template files.
+
+
+.TP 2
+\(bu
+Default: $vardir/templates
+
+
+.SS trace
+Whether to print stack traces on some errors
+
+
+.TP 2
+\(bu
+Default: false
+
+
+.SS typecheck
+Whether to validate types during parsing.
+
+
+.TP 2
+\(bu
+Default: true
+
+
+.SS usecacheonfailure
+Whether to use the cached configuration when the remote configuration will not compile. This option is useful for testing new configurations, where you want to fix the broken configuration rather than reverting to a known\-good one.
+
+
+.TP 2
+\(bu
+Default: true
+
+
+.SS user
+The user puppetmasterd should run as.
+
+
+.TP 2
+\(bu
+Default: puppet
+
+
+.SS vardir
+Where Puppet stores dynamic and growing data. The default for this parameter is calculated specially, like confdir.
+
+
+.TP 2
+\(bu
+Default: /var/puppet
+
+
+.SS yamldir
+The directory in which YAML data is stored, usually in a subdirectory.
+
+
+.TP 2
+\(bu
+Default: $vardir/yaml
+
+
+.sp
+.ce
+----
+
+.ce 0
+.sp
+
+.I This page autogenerated on Sat Mar 22 17:46:15 +1100 2008
+
+
+
+.\" Generated by docutils manpage writer on 2008-03-22 17:46.
+.\"
diff --git a/man/man8/puppetca.8 b/man/man8/puppetca.8
new file mode 100644
index 000000000..42d6c1f1f
--- /dev/null
+++ b/man/man8/puppetca.8
@@ -0,0 +1,116 @@
+.TH "" "" ""
+.SH NAME
+ \-
+
+.\" Man page generated from reStructeredText.
+
+.SH SYNOPSIS
+Stand\-alone certificate authority. Capable of generating certificates
+but mostly meant for signing certificate requests from puppet clients.
+
+
+.SH USAGE
+
+.\" visit_block_quote
+
+.TP
+.B puppetca [\-h|\-\-help] [\-V|\-\-version] [\-d|\-\-debug] [\-v|\-\-verbose]
+[\-g|\-\-generate] [\-l|\-\-list] [\-s|\-\-sign] [\-r|\-\-revoke]
+[\-p|\-\-print] [\-c|\-\-clean] [\-\-verify] [host]
+
+
+.\" depart_block_quote
+
+.SH DESCRIPTION
+Because the puppetmasterd daemon defaults to not signing client
+certificate requests, this script is available for signing outstanding
+requests. It can be used to list outstanding requests and then either
+sign them individually or sign all of them.
+
+
+.SH OPTIONS
+Note that any configuration parameter that\'s valid in the configuration
+file is also a valid long argument. For example, \'ssldir\' is a valid
+configuration parameter, so you can specify \'\-\-ssldir <directory>\' as an
+argument.
+
+See the configuration file documentation at
+http://reductivelabs.com/projects/puppet/reference/configref.html for
+the full list of acceptable parameters. A commented list of all
+configuration options can also be generated by running puppetca with
+\'\-\-genconfig\'.
+
+
+.TP
+.B all: Operate on all outstanding requests. Only makes sense with
+\'\-\-sign\', or \'\-\-list\'.
+
+
+.TP
+.B clean: Remove all files related to a host from puppetca\'s storage.
+This is useful when rebuilding hosts, since new certificate
+signing requests will only be honored if puppetca does not
+have a copy of a signed certificate for that host. The
+certificate of the host remains valid.
+
+debug: Enable full debugging.
+
+
+.TP
+.B generate: Generate a certificate for a named client. A
+certificate/keypair will be generated for each client named on
+the command line.
+
+help: Print this help message
+
+
+.TP
+.B list: List outstanding certificate requests. If \'\-\-all\' is
+specified, signed certificates are also listed, prefixed by
+\'+\'.
+
+print: Print the full\-text version of a host\'s certificate.
+
+
+.TP
+.B revoke: Revoke the certificate of a client. The certificate can be
+specified either by its serial number, given as a decimal
+number or a hexadecimal number prefixed by \'0x\', or by its
+hostname. The certificate is revoked by adding it to the
+Certificate Revocation List given by the \'cacrl\' config
+parameter. Note that the puppetmasterd needs to be restarted
+after revoking certificates.
+
+
+.TP
+.B sign: Sign an outstanding certificate request. Unless \'\-\-all\' is
+specified, hosts must be listed after all flags.
+
+verbose: Enable verbosity.
+
+version: Print the puppet version number and exit.
+
+verify: Verify the named certificate against the local CA certificate.
+
+
+.SH EXAMPLE
+
+.\" visit_block_quote
+$ puppetca \-l
+culain.madstop.com
+$ puppetca \-s culain.madstop.com
+
+
+.\" depart_block_quote
+
+.SH AUTHOR
+Luke Kanies
+
+
+.SH COPYRIGHT
+Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
+License
+
+
+.\" Generated by docutils manpage writer on 2008-03-22 17:46.
+.\"
diff --git a/man/man8/puppetd.8 b/man/man8/puppetd.8
new file mode 100644
index 000000000..83b172809
--- /dev/null
+++ b/man/man8/puppetd.8
@@ -0,0 +1,184 @@
+.TH Synopsis "" "" ""
+.SH NAME
+Synopsis \-
+
+.\" Man page generated from reStructeredText.
+Retrieve the client configuration from the central puppet server and
+apply it to the local host.
+
+Currently must be run out periodically, using cron or something similar.
+
+
+.SH USAGE
+
+.\" visit_block_quote
+
+.TP
+.B puppetd [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug] [\-\-disable] [\-\-enable]
+[\-h|\-\-help] [\-\-fqdn <host name>] [\-l|\-\-logdest syslog|<file>|console]
+[\-o|\-\-onetime] [\-\-serve <handler>] [\-t|\-\-test]
+[\-V|\-\-version] [\-v|\-\-verbose] [\-w|\-\-waitforcert <seconds>]
+
+
+.\" depart_block_quote
+
+.SH DESCRIPTION
+This is the main puppet client. Its job is to retrieve the local
+machine\'s configuration from a remote server and apply it. In order to
+successfully communicate with the remote server, the client must have a
+certificate signed by a certificate authority that the server trusts;
+the recommended method for this, at the moment, is to run a certificate
+authority as part of the puppet server (which is the default). The
+client will connect and request a signed certificate, and will continue
+connecting until it receives one.
+
+Once the client has a signed certificate, it will retrieve its
+configuration and apply it.
+
+
+.SH USAGE NOTES
++puppetd+ does its best to find a compromise between interactive use and
+daemon use. Run with no arguments and no configuration, it will go into
+the backgroun, attempt to get a signed certificate, and retrieve and
+apply its configuration every 30 minutes.
+
+Some flags are meant specifically for interactive use \-\- in particular,
++test+ and +tags+ are useful. +test+ enables verbose logging, causes the
+daemon to stay in the foreground, exits if the server\'s configuration is
+invalid (this happens if, for instance, you\'ve left a syntax error on
+the server), and exits after running the configuration once (rather than
+hanging around as a long\-running process).
+
++tags+ allows you to specify what portions of a configuration you want
+to apply. Puppet elements are tagged with all of the class or definition
+names that contain them, and you can use the +tags+ flag to specify one
+of these names, causing only configuration elements contained within
+that class or definition to be applied. This is very useful when you are
+testing new configurations \-\- for instance, if you are just starting to
+manage +ntpd+, you would put all of the new elements into an +ntpd+
+class, and call puppet with +\-\-tags ntpd+, which would only apply that
+small portion of the configuration during your testing, rather than
+applying the whole thing.
+
+
+.SH OPTIONS
+Note that any configuration parameter that\'s valid in the configuration
+file is also a valid long argument. For example, \'server\' is a valid
+configuration parameter, so you can specify \'\-\-server <servername>\' as
+an argument.
+
+See the configuration file documentation at
+http://reductivelabs.com/projects/puppet/reference/configref.html for
+the full list of acceptable parameters. A commented list of all
+configuration options can also be generated by running puppetd with
+\'\-\-genconfig\'.
+
+daemonize: Send the process into the background. This is the default.
+
+no\-daemonize: Do not send the process into the background.
+
+debug: Enable full debugging.
+
+
+.TP
+.B disable: Disable working on the local system. This puts a lock file
+in place, causing +puppetd+ not to work on the system
+until the lock file is removed. This is useful if you are
+testing a configuration and do not want the central
+configuration to override the local state until everything
+is tested and committed.
+
++puppetd+ uses the same lock file while it is running, so no more than
+one +puppetd+ process is working at a time.
+
++puppetd+ exits after executing this.
+
+
+.TP
+.B enable: Enable working on the local system. This removes any lock
+file, causing +puppetd+ to start managing the local system
+again (although it will continue to use its normal
+scheduling, so it might not start for another half hour).
+
++puppetd+ exits after executing this.
+
+
+.TP
+.B fqdn: Set the fully\-qualified domain name of the client. This is
+only used for certificate purposes, but can be used to
+override the discovered hostname. If you need to use this
+flag, it is generally an indication of a setup problem.
+
+help: Print this help message
+
+
+.TP
+.B logdest: Where to send messages. Choose between syslog, the
+console, and a log file. Defaults to sending messages to
+syslog, or the console if debugging or verbosity is
+enabled.
+
+
+.TP
+.B no\-client: Do not create a config client. This will cause the daemon
+to run without ever checking for its configuration
+automatically, and only makes sense when used in
+conjunction with \-\-listen.
+
+
+.TP
+.B onetime: Run the configuration once, rather than as a long\-running
+daemon. This is useful for interactively running puppetd.
+
+
+.TP
+.B serve: Start another type of server. By default, +puppetd+ will
+start a service handler that allows authenticated and
+authorized remote nodes to trigger the configuration to be
+pulled down and applied. You can specify any handler here
+that does not require configuration, e.g., filebucket, ca,
+or resource. The handlers are in
++lib/puppet/network/handler+, and the names must match
+exactly, both in the call to +serve+ and in
++namespaceauth.conf+.
+
+
+.TP
+.B test: Enable the most common options used for testing. These are
++onetime+, +verbose+, +ignorecache, and
++no\-usecacheonfailure+.
+
+verbose: Turn on verbose reporting.
+
+version: Print the puppet version number and exit.
+
+
+.TP
+.B waitforcert: This option only matters for daemons that do not yet have
+certificates and it is enabled by default, with a value of
+120 (seconds). This causes +puppetd+ to connect to the
+server every 2 minutes and ask it to sign a certificate
+request. This is useful for the initial setup of a puppet
+client. You can turn off waiting for certificates by
+specifying a time of 0.
+
+
+.SH EXAMPLE
+
+.\" visit_block_quote
+puppetd \-\-server puppet.domain.com
+
+
+.\" depart_block_quote
+
+.SH AUTHOR
+Luke Kanies
+
+
+.SH COPYRIGHT
+Copyright (c) 2005, 2006 Reductive Labs, LLC Licensed under the GNU
+Public License
+
+
+.\" Generated by docutils manpage writer on 2008-03-22 17:46.
+.\"
diff --git a/man/man8/puppetdoc.8 b/man/man8/puppetdoc.8
new file mode 100644
index 000000000..d7aacee75
--- /dev/null
+++ b/man/man8/puppetdoc.8
@@ -0,0 +1,62 @@
+.TH "" "" ""
+.SH NAME
+ \-
+
+.\" Man page generated from reStructeredText.
+
+.SH SYNOPSIS
+Generate a reference for all Puppet types. Largely meant for internal
+Reductive Labs use.
+
+
+.SH USAGE
+
+.\" visit_block_quote
+puppetdoc [\-a|\-\-all] [\-h|\-\-help] [\-m|\-\-mode <text|pdf|trac> [\-r|\-\-reference <[type]|configuration|..>]
+
+
+.\" depart_block_quote
+
+.SH DESCRIPTION
+This command generates a restructured\-text document describing all
+installed Puppet types or all allowable arguments to puppet executables.
+It is largely meant for internal use and is used to generate the
+reference document available on the Reductive Labs web site.
+
+
+.SH OPTIONS
+all: Output the docs for all of the reference types.
+
+help: Print this help message
+
+
+.TP
+.B mode: Determine the output mode. Valid modes are \'text\', \'trac\',
+and \'pdf\'. Note that \'trac\' mode only works on Reductive Labs
+servers. The default mode is \'text\'.
+
+
+.TP
+.B reference: Build a particular reference. Get a list of references by
+running +puppetdoc \-\-list+.
+
+
+.SH EXAMPLE
+
+.\" visit_block_quote
+$ puppetdoc \-r type > /tmp/type_reference.rst
+
+
+.\" depart_block_quote
+
+.SH AUTHOR
+Luke Kanies
+
+
+.SH COPYRIGHT
+Copyright (c) 2005\-2007 Reductive Labs, LLC Licensed under the GNU
+Public License
+
+
+.\" Generated by docutils manpage writer on 2008-03-22 17:46.
+.\"
diff --git a/man/man8/puppetmasterd.8 b/man/man8/puppetmasterd.8
new file mode 100644
index 000000000..5a8f02751
--- /dev/null
+++ b/man/man8/puppetmasterd.8
@@ -0,0 +1,87 @@
+.TH "" "" ""
+.SH NAME
+ \-
+
+.\" Man page generated from reStructeredText.
+
+.SH SYNOPSIS
+The central puppet server. Functions as a certificate authority by
+default.
+
+
+.SH USAGE
+
+.\" visit_block_quote
+
+.TP
+.B puppetmasterd [\-D|\-\-daemonize|\-\-no\-daemonize] [\-d|\-\-debug] [\-h|\-\-help]
+[\-l|\-\-logdest <file>|console|syslog] [\-\-nobucket] [\-\-nonodes]
+[\-v|\-\-verbose] [\-V|\-\-version]
+
+
+.\" depart_block_quote
+
+.SH DESCRIPTION
+This is the puppet central daemon.
+
+
+.SH OPTIONS
+Note that any configuration parameter that\'s valid in the configuration
+file is also a valid long argument. For example, \'ssldir\' is a valid
+configuration parameter, so you can specify \'\-\-ssldir <directory>\' as an
+argument.
+
+See the configuration file documentation at
+http://reductivelabs.com/projects/puppet/reference/configref.html for
+the full list of acceptable parameters. A commented list of all
+configuration options can also be generated by running puppetmasterdd
+with \'\-\-genconfig\'.
+
+daemonize: Send the process into the background. This is the default.
+
+no\-daemonize: Do not send the process into the background.
+
+debug: Enable full debugging.
+
+help: Print this help message.
+
+
+.TP
+.B logdest: Where to send messages. Choose between syslog, the
+console, and a log file. Defaults to sending messages to
+syslog, or the console if debugging or verbosity is
+enabled.
+
+nobucket: Do not function as a file bucket.
+
+
+.TP
+.B nonodes: Do not use individual node designations; each node will
+receive the result of evaluating the entire configuration.
+
+noreports: Do not start the reports server.
+
+verbose: Enable verbosity.
+
+version: Print the puppet version number and exit.
+
+
+.SH EXAMPLE
+
+.\" visit_block_quote
+puppetmasterd
+
+
+.\" depart_block_quote
+
+.SH AUTHOR
+Luke Kanies
+
+
+.SH COPYRIGHT
+Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
+License
+
+
+.\" Generated by docutils manpage writer on 2008-03-22 17:46.
+.\"
diff --git a/man/man8/puppetrun.8 b/man/man8/puppetrun.8
new file mode 100644
index 000000000..753be1ca0
--- /dev/null
+++ b/man/man8/puppetrun.8
@@ -0,0 +1,151 @@
+.TH "" "" ""
+.SH NAME
+ \-
+
+.\" Man page generated from reStructeredText.
+
+.SH SYNOPSIS
+Trigger a puppetd run on a set of hosts.
+
+
+.SH USAGE
+
+.\" visit_block_quote
+
+.TP
+.B puppetrun [\-a|\-\-all] [\-c|\-\-class <class>] [\-d|\-\-debug] [\-f|\-\-foreground]
+[\-h|\-\-help] [\-\-host <host>] [\-\-no\-fqdn] [\-\-ignoreschedules]
+[\-t|\-\-tag <tag>] [\-\-test]
+
+
+.\" depart_block_quote
+
+.SH DESCRIPTION
+This script can be used to connect to a set of machines running
++puppetd+ and trigger them to run their configurations. The most common
+usage would be to specify a class of hosts and a set of tags, and
++puppetrun+ would look up in LDAP all of the hosts matching that class,
+then connect to each host and trigger a run of all of the objects with
+the specified tags.
+
+If you are not storing your host configurations in LDAP, you can specify
+hosts manually.
+
+You will most likely have to run +puppetrun+ as root to get access to
+the SSL certificates.
+
++puppetrun+ reads +puppetmaster+\'s configuration file, so that it can
+copy things like LDAP settings.
+
+
+.SH USAGE NOTES
++puppetrun+ is useless unless +puppetd+ is listening. See its
+documentation for more information, but the gist is that you must enable
++listen+ on the +puppetd+ daemon, either using +\-\-listen+ on the command
+line or adding \'listen: true\' in its config file. In addition, you need
+to set the daemons up to specifically allow connections by creating the
++namespaceauth+ file, normally at \'/etc/puppet/namespaceauth.conf\'. This
+file specifies who has access to each namespace; if you create the file
+you must add every namespace you want any Puppet daemon to allow \-\- it
+is currently global to all Puppet daemons.
+
+An example file looks like this:
+
+
+.nf
+[fileserver]
+ allow *.madstop.com
+
+[puppetmaster]
+ allow *.madstop.com
+
+[puppetrunner]
+ allow culain.madstop.com
+.fi
+This is what you would install on your Puppet master; non\-master hosts
+could leave off the \'fileserver\' and \'puppetmaster\' namespaces.
+
+Expect more documentation on this eventually.
+
+
+.SH OPTIONS
+Note that any configuration parameter that\'s valid in the configuration
+file is also a valid long argument. For example, \'ssldir\' is a valid
+configuration parameter, so you can specify \'\-\-ssldir <directory>\' as an
+argument.
+
+See the configuration file documentation at
+http://reductivelabs.com/projects/puppet/reference/configref.html for
+the full list of acceptable parameters. A commented list of all
+configuration options can also be generated by running puppetmasterdd
+with \'\-\-genconfig\'.
+
+
+.TP
+.B all: Connect to all available hosts. Requires LDAP support
+at this point.
+
+
+.TP
+.B class: Specify a class of machines to which to connect. This
+only works if you have LDAP configured, at the moment.
+
+debug: Enable full debugging.
+
+
+.TP
+.B foreground: Run each configuration in the foreground; that is, when
+connecting to a host, do not return until the host has
+finished its run. The default is false.
+
+help: Print this help message
+
+
+.TP
+.B host: A specific host to which to connect. This flag can be
+specified more than once.
+
+
+.TP
+.B ignoreschedules: Whether the client should ignore schedules when running
+its configuration. This can be used to force the client
+to perform work it would not normally perform so soon.
+The default is false.
+
+
+.TP
+.B parallel: How parallel to make the connections. Parallelization
+is provided by forking for each client to which to
+connect. The default is 1, meaning serial execution.
+
+
+.TP
+.B tag: Specify a tag for selecting the objects to apply. Does
+not work with the \-\-test option.
+
+
+.TP
+.B test: Print the hosts you would connect to but do not
+actually connect. This option requires LDAP support at
+this point.
+
+
+.SH EXAMPLE
+
+.\" visit_block_quote
+sudo puppetrun \-p 10 \-\-host host1 \-\-host host2 \-t remotefile \-t webserver
+
+
+.\" depart_block_quote
+
+.SH AUTHOR
+Luke Kanies
+
+
+.SH COPYRIGHT
+Copyright (c) 2005 Reductive Labs, LLC Licensed under the GNU Public
+License
+
+
+.\" Generated by docutils manpage writer on 2008-03-22 17:46.
+.\"
diff --git a/man/man8/ralsh.8 b/man/man8/ralsh.8
new file mode 100644
index 000000000..fc84fe0df
--- /dev/null
+++ b/man/man8/ralsh.8
@@ -0,0 +1,148 @@
+.TH "" "" ""
+.SH NAME
+ \-
+
+.\" Man page generated from reStructeredText.
+vim: softtabstop=4 shiftwidth=4 expandtab
+
+
+.SH SYNOPSIS
+Use the Puppet RAL to directly interact with the system.
+
+
+.SH USAGE
+
+.\" visit_block_quote
+
+.TP
+.B ralsh [\-h|\-\-help] [\-d|\-\-debug] [\-v|\-\-verbose] [\-e|\-\-edit] [\-H|\-\-host <host>]
+[\-p|\-\-param <param>] [\-t|\-\-types] type <name>
+
+
+.\" depart_block_quote
+
+.SH DESCRIPTION
+This command provides simple facilities for converting current system
+state into Puppet code, along with some ability to use Puppet to affect
+the current state.
+
+By default, you must at least provide a type to list, which case ralsh
+will tell you everything it knows about all instances of that type. You
+can optionally specify an instance name, and ralsh will only describe
+that single instance.
+
+You can also add +\-\-edit+ as an argument, and ralsh will write its
+output to a file, open that file in an editor, and then apply the file
+as a Puppet transaction. You can easily use this to use Puppet to make
+simple changes to a system.
+
+
+.SH OPTIONS
+Note that any configuration parameter that\'s valid in the configuration
+file is also a valid long argument. For example, \'ssldir\' is a valid
+configuration parameter, so you can specify \'\-\-ssldir <directory>\' as an
+argument.
+
+See the configuration file documentation at
+http://reductivelabs.com/projects/puppet/reference/configref.html for
+the full list of acceptable parameters. A commented list of all
+configuration options can also be generated by running puppet with
+\'\-\-genconfig\'.
+
+debug: Enable full debugging.
+
+edit:
+
+
+.\" visit_block_quote
+Write the results of the query to a file, open the file in an editor,
+and read the file back in as an executable Puppet manifest.
+
+
+.\" depart_block_quote
+host:
+
+
+.\" visit_block_quote
+When specified, connect to the resource server on the named host
+and retrieve the list of resouces of the type specified.
+
+
+.\" depart_block_quote
+help:
+
+
+.\" visit_block_quote
+Print this help message.
+
+
+.\" depart_block_quote
+param:
+
+
+.\" visit_block_quote
+Add more parameters to be outputted from queries.
+
+
+.\" depart_block_quote
+types:
+
+
+.\" visit_block_quote
+List all available types.
+
+
+.\" depart_block_quote
+verbose: Print extra information.
+
+
+.SH EXAMPLE
+This example uses
+.\" visit_literal
+ralsh
+.\" depart_literal
+ to return Puppet configuration for the user
+
+.\" visit_literal
+luke
+.\" depart_literal
+:
+
+
+.nf
+$ ralsh user luke
+.fi
+
+.\" visit_block_quote
+
+.TP
+.B user { \'luke\':
+home => \'/home/luke\',
+uid => \'100\',
+ensure => \'present\',
+comment => \'Luke Kanies,,,\',
+gid => \'1000\',
+shell => \'/bin/bash\',
+groups => [\'sysadmin\',\'audio\',\'video\',\'puppet\']
+
+\.SH system-message
+System Message: WARNING/2 (./ralsh.rst:, line 87)
+Definition list ends without a blank line; unexpected unindent.
+
+
+}
+
+
+.\" depart_block_quote
+
+.SH AUTHOR
+Luke Kanies
+
+
+.SH COPYRIGHT
+Copyright (c) 2005\-2007 Reductive Labs, LLC Licensed under the GNU
+Public License
+
+
+.\" Generated by docutils manpage writer on 2008-03-22 17:46.
+.\"
diff --git a/spec/Rakefile b/spec/Rakefile
index 8b45eff89..e2996f64f 100644
--- a/spec/Rakefile
+++ b/spec/Rakefile
@@ -7,10 +7,12 @@ puppetlibdir = File.join(basedir, "../lib")
puppettestlibdir = File.join(basedir, "../test/lib")
speclibdir = File.join(basedir, "lib")
-desc "Run all spec unit tests"
-Spec::Rake::SpecTask.new('unit') do |t|
- t.spec_files = FileList['unit/**/*.rb', 'integration/**/*.rb']
- t.libs = [puppetlibdir, puppettestlibdir, speclibdir]
+libs = [puppetlibdir, puppettestlibdir, speclibdir]
+desc "Run all specs"
+Spec::Rake::SpecTask.new('all') do |t|
+ t.spec_files = FileList['integration/**/*.rb', 'unit/**/*.rb']
+ t.libs = libs
+ t.spec_opts = ['--options', 'spec.opts']
end
-task :default => [:unit]
+task :default => [:all]
diff --git a/spec/integration/file_serving/configuration.rb b/spec/integration/file_serving/configuration.rb
index b6505f096..6975594a8 100755
--- a/spec/integration/file_serving/configuration.rb
+++ b/spec/integration/file_serving/configuration.rb
@@ -12,8 +12,6 @@ describe Puppet::FileServing::Configuration, " when finding files with Puppet::F
# Just in case it already exists.
Puppet::FileServing::Configuration.clear_cache
- @config = Puppet::FileServing::Configuration.create
-
@mount = Puppet::FileServing::Mount.new("mymount")
FileTest.stubs(:exists?).with("/my/path").returns(true)
FileTest.stubs(:readable?).with("/my/path").returns(true)
@@ -25,6 +23,8 @@ describe Puppet::FileServing::Configuration, " when finding files with Puppet::F
@parser.stubs(:parse).returns("mymount" => @mount)
@parser.stubs(:changed?).returns(true)
Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+
+ @config = Puppet::FileServing::Configuration.create
end
it "should return nil if the file does not exist" do
diff --git a/spec/integration/node.rb b/spec/integration/node.rb
index e4a311998..631d4403e 100755
--- a/spec/integration/node.rb
+++ b/spec/integration/node.rb
@@ -10,7 +10,9 @@ require 'puppet/node'
describe Puppet::Node, " when using the memory terminus" do
before do
@name = "me"
- Puppet::Node.terminus_class = :memory
+ @old_terminus = Puppet::Node.indirection.terminus_class
+ @terminus = Puppet::Node.indirection.terminus(:memory)
+ Puppet::Node.indirection.stubs(:terminus).returns @terminus
@node = Puppet::Node.new(@name)
end
@@ -39,8 +41,4 @@ describe Puppet::Node, " when using the memory terminus" do
it "should fail when asked to destroy a node that does not exist" do
proc { Puppet::Node.destroy(@node) }.should raise_error(ArgumentError)
end
-
- after do
- Puppet.settings.clear
- end
end
diff --git a/spec/lib/autotest/puppet_rspec.rb b/spec/lib/autotest/puppet_rspec.rb
deleted file mode 100644
index 8536f3912..000000000
--- a/spec/lib/autotest/puppet_rspec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-require 'autotest'
-require 'autotest/rspec'
-
-class Autotest::PuppetRspec < Autotest::Rspec
- def initialize # :nodoc:
- super
- @test_mappings = {
- # the libraries under lib/puppet
- %r%^lib/puppet/(.*)\.rb$% => proc { |filename, m|
- files_matching %r!spec/(unit|integration)/#{m[1]}.rb!
- },
-
- # the actual spec files themselves
- %r%^spec/(unit|integration)/.*\.rb$% => proc { |filename, _|
- filename
- },
-
- # force a complete re-run for all of these:
-
- # main puppet lib
- %r!^lib/puppet\.rb$! => proc { |filename, _|
- files_matching %r!spec/(unit|integration)/.*\.rb!
- },
-
- # the spec_helper
- %r!^spec/spec_helper\.rb$! => proc { |filename, _|
- files_matching %r!spec/(unit|integration)/.*\.rb!
- },
-
- # the puppet test libraries
- %r!^test/lib/puppettest/.*! => proc { |filename, _|
- files_matching %r!spec/(unit|integration)/.*\.rb!
- },
-
- # the puppet spec libraries
- %r!^spec/lib/spec.*! => proc { |filename, _|
- files_matching %r!spec/(unit|integration)/.*\.rb!
- },
-
- # the monkey patches for rspec
- %r!^spec/lib/monkey_patches/.*! => proc { |filename, _|
- files_matching %r!spec/(unit|integration)/.*\.rb!
- },
- }
- end
-end
diff --git a/spec/lib/autotest/rspec.rb b/spec/lib/autotest/rspec.rb
deleted file mode 100644
index d4b77ea6b..000000000
--- a/spec/lib/autotest/rspec.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-require 'autotest'
-
-class RspecCommandError < StandardError; end
-
-class Autotest::Rspec < Autotest
-
- def initialize(kernel=Kernel, separator=File::SEPARATOR, alt_separator=File::ALT_SEPARATOR) # :nodoc:
- super()
- @kernel, @separator, @alt_separator = kernel, separator, alt_separator
- @spec_command = spec_command
-
- # watch out: Ruby bug (1.8.6):
- # %r(/) != /\//
- # since Ruby compares the REGEXP source, not the resulting pattern
- @test_mappings = {
- %r%^spec/.*\.rb$% => kernel.proc { |filename, _|
- filename
- },
- %r%^lib/(.*)\.rb$% => kernel.proc { |_, m|
- ["spec/#{m[1]}_spec.rb"]
- },
- %r%^spec/(spec_helper|shared/.*)\.rb$% => kernel.proc {
- files_matching %r%^spec/.*_spec\.rb$%
- }
- }
- end
-
- def tests_for_file(filename)
- super.select { |f| @files.has_key? f }
- end
-
- alias :specs_for_file :tests_for_file
-
- def failed_results(results)
- results.scan(/^\d+\)\n(?:\e\[\d*m)?(?:.*?Error in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n(.*?)\n\n/m)
- end
-
- def handle_results(results)
- @files_to_test = consolidate_failures failed_results(results)
- unless @files_to_test.empty? then
- hook :red
- else
- hook :green
- end unless $TESTING
- @tainted = true unless @files_to_test.empty?
- end
-
- def consolidate_failures(failed)
- filters = Hash.new { |h,k| h[k] = [] }
- failed.each do |spec, failed_trace|
- @files.keys.select{|f| f =~ /spec\//}.each do |f|
- if failed_trace =~ Regexp.new(f)
- filters[f] << spec
- break
- end
- end
- end
- return filters
- end
-
- def make_test_cmd(files_to_test)
- return "#{ruby} -S #{@spec_command} #{add_options_if_present} #{files_to_test.keys.flatten.join(' ')}"
- end
-
- def add_options_if_present
- File.exist?("spec/spec.opts") ? "-O spec/spec.opts " : ""
- end
-
- # Finds the proper spec command to use. Precendence
- # is set in the lazily-evaluated method spec_commands. Alias + Override
- # that in ~/.autotest to provide a different spec command
- # then the default paths provided.
- def spec_command
- spec_commands.each do |command|
- if File.exists?(command)
- return @alt_separator ? (command.gsub @separator, @alt_separator) : command
- end
- end
-
- raise RspecCommandError, "No spec command could be found!"
- end
-
- # Autotest will look for spec commands in the following
- # locations, in this order:
- #
- # * bin/spec
- # * default spec bin/loader installed in Rubygems
- def spec_commands
- [
- File.join('bin', 'spec'),
- File.join(Config::CONFIG['bindir'], 'spec')
- ]
- end
-
-end
diff --git a/spec/lib/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb b/spec/lib/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
deleted file mode 100644
index bfa2a0c3c..000000000
--- a/spec/lib/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-dir = File.expand_path(File.dirname(__FILE__))
-[ "#{dir}/../../lib", "#{dir}/../../../lib", "#{dir}/../../../test/lib"].each do |dir|
- fulldir = File.expand_path(dir)
- $LOAD_PATH.unshift(fulldir) unless $LOAD_PATH.include?(fulldir)
-end
-
-require 'spec'
-require 'puppettest'
-require 'puppettest/runnable_test'
-
-module Spec
- module Runner
- class BehaviourRunner
- def run_behaviours
- @behaviours.each do |behaviour|
- # LAK:NOTE: this 'runnable' test is Puppet-specific.
- next unless behaviour.runnable?
- behaviour.run(@options.reporter, @options.dry_run, @options.reverse, @options.timeout)
- end
- end
- end
- end
-end
-
-module Spec
- module DSL
- class EvalModule < Module
- include PuppetTest::RunnableTest
- end
- end
-end
diff --git a/spec/lib/spec.rb b/spec/lib/spec.rb
deleted file mode 100644
index 48c12595c..000000000
--- a/spec/lib/spec.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require 'spec/extensions'
-require 'spec/version'
-require 'spec/matchers'
-require 'spec/expectations'
-require 'spec/translator'
-require 'spec/dsl'
-require 'spec/runner'
-
-class Object
- def metaclass
- class << self; self; end
- end
-end
diff --git a/spec/lib/spec/dsl.rb b/spec/lib/spec/dsl.rb
deleted file mode 100644
index f960eb907..000000000
--- a/spec/lib/spec/dsl.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require 'spec/dsl/description'
-require 'spec/dsl/errors'
-require 'spec/dsl/configuration'
-require 'spec/dsl/behaviour_callbacks'
-require 'spec/dsl/behaviour'
-require 'spec/dsl/behaviour_eval'
-require 'spec/dsl/composite_proc_builder'
-require 'spec/dsl/example'
-require 'spec/dsl/example_matcher'
-require 'spec/dsl/example_should_raise_handler'
-require 'spec/dsl/behaviour_factory'
diff --git a/spec/lib/spec/dsl/behaviour.rb b/spec/lib/spec/dsl/behaviour.rb
deleted file mode 100644
index cc71ccffe..000000000
--- a/spec/lib/spec/dsl/behaviour.rb
+++ /dev/null
@@ -1,221 +0,0 @@
-require(File.expand_path(File.dirname(__FILE__) + '../../../../../test/lib/puppettest/runnable_test.rb'))
-
-module Spec
- module DSL
- class Behaviour
- extend BehaviourCallbacks
-
- class << self
- def add_shared_behaviour(behaviour)
- return if behaviour.equal?(found_behaviour = find_shared_behaviour(behaviour.description))
- return if found_behaviour and File.expand_path(behaviour.description[:spec_path]) == File.expand_path(found_behaviour.description[:spec_path])
- raise ArgumentError.new("Shared Behaviour '#{behaviour.description}' already exists") if found_behaviour
- shared_behaviours << behaviour
- end
-
- def find_shared_behaviour(behaviour_description)
- shared_behaviours.find { |b| b.description == behaviour_description }
- end
-
- def shared_behaviours
- # TODO - this needs to be global, or at least accessible from
- # from subclasses of Behaviour in a centralized place. I'm not loving
- # this as a solution, but it works for now.
- $shared_behaviours ||= []
- end
- end
-
- def initialize(*args, &behaviour_block)
- init_description(*args)
- init_eval_module
- before_eval
- eval_behaviour(&behaviour_block)
- end
-
- private
-
- def init_description(*args)
- unless self.class == Behaviour
- args << {} unless Hash === args.last
- args.last[:behaviour_class] = self.class
- end
- @description = Description.new(*args)
- end
-
- def init_eval_module
- @eval_module = EvalModule.new
- @eval_module.extend BehaviourEval::ModuleMethods
- @eval_module.include BehaviourEval::InstanceMethods
- @eval_module.include described_type if described_type.class == Module
- @eval_module.behaviour = self
- @eval_module.description = @description
- end
-
- def eval_behaviour(&behaviour_block)
- @eval_module.class_eval(&behaviour_block)
- end
-
- protected
-
- def before_eval
- end
-
- public
-
- def run(reporter, dry_run=false, reverse=false, timeout=nil)
- raise "shared behaviours should never run" if shared?
- # TODO - change add_behaviour to add_description ??????
- reporter.add_behaviour(@description)
- prepare_execution_context_class
- before_all_errors = run_before_all(reporter, dry_run)
-
- exs = reverse ? examples.reverse : examples
- example_execution_context = nil
-
- if before_all_errors.empty?
- exs.each do |example|
- example_execution_context = execution_context(example)
- example_execution_context.copy_instance_variables_from(@before_and_after_all_context_instance) unless before_all_proc(behaviour_type).nil?
-
- befores = before_each_proc(behaviour_type) {|e| raise e}
- afters = after_each_proc(behaviour_type)
- example.run(reporter, befores, afters, dry_run, example_execution_context, timeout)
- end
- end
-
- @before_and_after_all_context_instance.copy_instance_variables_from(example_execution_context) unless after_all_proc(behaviour_type).nil?
- run_after_all(reporter, dry_run)
- end
-
- def number_of_examples
- examples.length
- end
-
- def matches?(specified_examples)
- matcher ||= ExampleMatcher.new(description)
-
- examples.each do |example|
- return true if example.matches?(matcher, specified_examples)
- end
- return false
- end
-
- def shared?
- @description[:shared]
- end
-
- def retain_examples_matching!(specified_examples)
- return if specified_examples.index(description)
- matcher = ExampleMatcher.new(description)
- examples.reject! do |example|
- !example.matches?(matcher, specified_examples)
- end
- end
-
- def methods
- my_methods = super
- my_methods |= @eval_module.methods
- my_methods
- end
-
- # Includes modules in the Behaviour (the <tt>describe</tt> block).
- def include(*args)
- @eval_module.include(*args)
- end
-
- def behaviour_type #:nodoc:
- @description[:behaviour_type]
- end
-
- # Sets the #number on each Example and returns the next number
- def set_sequence_numbers(number, reverse) #:nodoc:
- exs = reverse ? examples.reverse : examples
- exs.each do |example|
- example.number = number
- number += 1
- end
- number
- end
-
- protected
-
- # Messages that this class does not understand
- # are passed directly to the @eval_module.
- def method_missing(sym, *args, &block)
- @eval_module.send(sym, *args, &block)
- end
-
- def prepare_execution_context_class
- plugin_mock_framework
- weave_in_included_modules
- define_predicate_matchers #this is in behaviour_eval
- execution_context_class
- end
-
- def weave_in_included_modules
- mods = [@eval_module]
- mods << included_modules.dup
- mods << Spec::Runner.configuration.modules_for(behaviour_type)
- execution_context_class.class_eval do
- # WARNING - the following can be executed in the context of any
- # class, and should never pass more than one module to include
- # even though we redefine include in this class. This is NOT
- # tested anywhere, hence this comment.
- mods.flatten.each {|mod| include mod}
- end
- end
-
- def execution_context(example)
- execution_context_class.new(example)
- end
-
- def run_before_all(reporter, dry_run)
- errors = []
- unless dry_run
- begin
- @before_and_after_all_context_instance = execution_context(nil)
- @before_and_after_all_context_instance.instance_eval(&before_all_proc(behaviour_type))
- rescue Exception => e
- errors << e
- location = "before(:all)"
- # The easiest is to report this as an example failure. We don't have an Example
- # at this point, so we'll just create a placeholder.
- reporter.example_finished(Example.new(location), e, location) if reporter
- end
- end
- errors
- end
-
- def run_after_all(reporter, dry_run)
- unless dry_run
- begin
- @before_and_after_all_context_instance ||= execution_context(nil)
- @before_and_after_all_context_instance.instance_eval(&after_all_proc(behaviour_type))
- rescue Exception => e
- location = "after(:all)"
- reporter.example_finished(Example.new(location), e, location) if reporter
- end
- end
- end
-
- def plugin_mock_framework
- case mock_framework = Spec::Runner.configuration.mock_framework
- when Module
- include mock_framework
- else
- require Spec::Runner.configuration.mock_framework
- include Spec::Plugins::MockFramework
- end
- end
-
- def description
- @description.to_s
- end
-
- def described_type
- @description.described_type
- end
-
- end
- end
-end
diff --git a/spec/lib/spec/dsl/behaviour_callbacks.rb b/spec/lib/spec/dsl/behaviour_callbacks.rb
deleted file mode 100644
index 8b69ad9e5..000000000
--- a/spec/lib/spec/dsl/behaviour_callbacks.rb
+++ /dev/null
@@ -1,82 +0,0 @@
-module Spec
- module DSL
- # See http://rspec.rubyforge.org/documentation/before_and_after.html
- module BehaviourCallbacks
- def prepend_before(*args, &block)
- scope, options = scope_and_options(*args)
- add(scope, options, :before, :unshift, &block)
- end
- def append_before(*args, &block)
- scope, options = scope_and_options(*args)
- add(scope, options, :before, :<<, &block)
- end
- alias_method :before, :append_before
-
- def prepend_after(*args, &block)
- scope, options = scope_and_options(*args)
- add(scope, options, :after, :unshift, &block)
- end
- alias_method :after, :prepend_after
- def append_after(*args, &block)
- scope, options = scope_and_options(*args)
- add(scope, options, :after, :<<, &block)
- end
-
- def scope_and_options(*args)
- args, options = args_and_options(*args)
- scope = (args[0] || :each), options
- end
-
- def add(scope, options, where, how, &block)
- scope ||= :each
- options ||= {}
- behaviour_type = options[:behaviour_type]
- case scope
- when :each; self.__send__("#{where}_each_parts", behaviour_type).__send__(how, block)
- when :all; self.__send__("#{where}_all_parts", behaviour_type).__send__(how, block)
- end
- end
-
- def remove_after(scope, &block)
- after_each_parts.delete(block)
- end
-
- # Deprecated. Use before(:each)
- def setup(&block)
- before(:each, &block)
- end
-
- # Deprecated. Use after(:each)
- def teardown(&block)
- after(:each, &block)
- end
-
- def before_all_parts(behaviour_type=nil) # :nodoc:
- @before_all_parts ||= {}
- @before_all_parts[behaviour_type] ||= []
- end
-
- def after_all_parts(behaviour_type=nil) # :nodoc:
- @after_all_parts ||= {}
- @after_all_parts[behaviour_type] ||= []
- end
-
- def before_each_parts(behaviour_type=nil) # :nodoc:
- @before_each_parts ||= {}
- @before_each_parts[behaviour_type] ||= []
- end
-
- def after_each_parts(behaviour_type=nil) # :nodoc:
- @after_each_parts ||= {}
- @after_each_parts[behaviour_type] ||= []
- end
-
- def clear_before_and_after! # :nodoc:
- @before_all_parts = nil
- @after_all_parts = nil
- @before_each_parts = nil
- @after_each_parts = nil
- end
- end
- end
-end
diff --git a/spec/lib/spec/dsl/behaviour_eval.rb b/spec/lib/spec/dsl/behaviour_eval.rb
deleted file mode 100644
index 9f7b8281e..000000000
--- a/spec/lib/spec/dsl/behaviour_eval.rb
+++ /dev/null
@@ -1,231 +0,0 @@
-module Spec
- module DSL
- module BehaviourEval
- module ModuleMethods
- include BehaviourCallbacks
-
- attr_writer :behaviour
- attr_accessor :description
-
- # RSpec runs every example in a new instance of Object, mixing in
- # the behaviour necessary to run examples. Because this behaviour gets
- # mixed in, it can get mixed in to an instance of any class at all.
- #
- # This is something that you would hardly ever use, but there is one
- # common use case for it - inheriting from Test::Unit::TestCase. RSpec's
- # Rails plugin uses this feature to provide access to all of the features
- # that are available for Test::Unit within RSpec examples.
- def inherit(klass)
- raise ArgumentError.new("Shared behaviours cannot inherit from classes") if @behaviour.shared?
- @behaviour_superclass = klass
- derive_execution_context_class_from_behaviour_superclass
- end
-
- # You can pass this one or many modules. Each module will subsequently
- # be included in the each object in which an example is run. Use this
- # to provide global helper methods to your examples.
- #
- # == Example
- #
- # module HelperMethods
- # def helper_method
- # ...
- # end
- # end
- #
- # describe Thing do
- # include HelperMethods
- # it "should do stuff" do
- # helper_method
- # end
- # end
- def include(*mods)
- mods.each do |mod|
- included_modules << mod
- mod.send :included, self
- end
- end
-
- # Use this to pull in examples from shared behaviours.
- # See Spec::Runner for information about shared behaviours.
- def it_should_behave_like(behaviour_description)
- behaviour = @behaviour.class.find_shared_behaviour(behaviour_description)
- if behaviour.nil?
- raise RuntimeError.new("Shared Behaviour '#{behaviour_description}' can not be found")
- end
- behaviour.copy_to(self)
- end
-
- def copy_to(eval_module) # :nodoc:
- examples.each { |e| eval_module.examples << e; }
- before_each_parts.each { |p| eval_module.before_each_parts << p }
- after_each_parts.each { |p| eval_module.after_each_parts << p }
- before_all_parts.each { |p| eval_module.before_all_parts << p }
- after_all_parts.each { |p| eval_module.after_all_parts << p }
- included_modules.each { |m| eval_module.included_modules << m }
- eval_module.included_modules << self
- end
-
- # :call-seq:
- # predicate_matchers[matcher_name] = method_on_object
- # predicate_matchers[matcher_name] = [method1_on_object, method2_on_object]
- #
- # Dynamically generates a custom matcher that will match
- # a predicate on your class. RSpec provides a couple of these
- # out of the box:
- #
- # exist (or state expectations)
- # File.should exist("path/to/file")
- #
- # an_instance_of (for mock argument constraints)
- # mock.should_receive(:message).with(an_instance_of(String))
- #
- # == Examples
- #
- # class Fish
- # def can_swim?
- # true
- # end
- # end
- #
- # describe Fish do
- # predicate_matchers[:swim] = :can_swim?
- # it "should swim" do
- # Fish.new.should swim
- # end
- # end
- def predicate_matchers
- @predicate_matchers ||= {:exist => :exist?, :an_instance_of => :is_a?}
- end
-
- def define_predicate_matchers(hash=nil) # :nodoc:
- if hash.nil?
- define_predicate_matchers(predicate_matchers)
- define_predicate_matchers(Spec::Runner.configuration.predicate_matchers)
- else
- hash.each_pair do |matcher_method, method_on_object|
- define_method matcher_method do |*args|
- eval("be_#{method_on_object.to_s.gsub('?','')}(*args)")
- end
- end
- end
- end
-
- # Creates an instance of Spec::DSL::Example and adds
- # it to a collection of examples of the current behaviour.
- def it(description=:__generate_description, opts={}, &block)
- examples << Example.new(description, opts, &block)
- end
-
- # Alias for it.
- def specify(description=:__generate_description, opts={}, &block)
- it(description, opts, &block)
- end
-
- def methods # :nodoc:
- my_methods = super
- my_methods |= behaviour_superclass.methods
- my_methods
- end
-
- protected
-
- def method_missing(method_name, *args)
- if behaviour_superclass.respond_to?(method_name)
- return execution_context_class.send(method_name, *args)
- end
- super
- end
-
- def before_each_proc(behaviour_type, &error_handler)
- parts = []
- parts.push(*Behaviour.before_each_parts(nil))
- parts.push(*Behaviour.before_each_parts(behaviour_type)) unless behaviour_type.nil?
- parts.push(*before_each_parts(nil))
- parts.push(*before_each_parts(behaviour_type)) unless behaviour_type.nil?
- CompositeProcBuilder.new(parts).proc(&error_handler)
- end
-
- def before_all_proc(behaviour_type, &error_handler)
- parts = []
- parts.push(*Behaviour.before_all_parts(nil))
- parts.push(*Behaviour.before_all_parts(behaviour_type)) unless behaviour_type.nil?
- parts.push(*before_all_parts(nil))
- parts.push(*before_all_parts(behaviour_type)) unless behaviour_type.nil?
- CompositeProcBuilder.new(parts).proc(&error_handler)
- end
-
- def after_all_proc(behaviour_type)
- parts = []
- parts.push(*after_all_parts(behaviour_type)) unless behaviour_type.nil?
- parts.push(*after_all_parts(nil))
- parts.push(*Behaviour.after_all_parts(behaviour_type)) unless behaviour_type.nil?
- parts.push(*Behaviour.after_all_parts(nil))
- CompositeProcBuilder.new(parts).proc
- end
-
- def after_each_proc(behaviour_type)
- parts = []
- parts.push(*after_each_parts(behaviour_type)) unless behaviour_type.nil?
- parts.push(*after_each_parts(nil))
- parts.push(*Behaviour.after_each_parts(behaviour_type)) unless behaviour_type.nil?
- parts.push(*Behaviour.after_each_parts(nil))
- CompositeProcBuilder.new(parts).proc
- end
-
- private
-
- def execution_context_class
- @execution_context_class ||= derive_execution_context_class_from_behaviour_superclass
- end
-
- def derive_execution_context_class_from_behaviour_superclass
- @execution_context_class = Class.new(behaviour_superclass)
- behaviour_superclass.spec_inherited(self) if behaviour_superclass.respond_to?(:spec_inherited)
- @execution_context_class
- end
-
- def behaviour_superclass
- @behaviour_superclass ||= Object
- end
-
- protected
- def included_modules
- @included_modules ||= [::Spec::Matchers]
- end
-
- def examples
- @examples ||= []
- end
- end
-
- module InstanceMethods
- def initialize(*args, &block) #:nodoc:
- # TODO - inheriting from TestUnit::TestCase fails without this
- # - let's figure out why and move this somewhere else
- end
-
- def violated(message="")
- raise Spec::Expectations::ExpectationNotMetError.new(message)
- end
-
- def inspect
- "[RSpec example]"
- end
-
- def pending(message)
- if block_given?
- begin
- yield
- rescue Exception => e
- raise Spec::DSL::ExamplePendingError.new(message)
- end
- raise Spec::DSL::PendingFixedError.new("Expected pending '#{message}' to fail. No Error was raised.")
- else
- raise Spec::DSL::ExamplePendingError.new(message)
- end
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/dsl/behaviour_factory.rb b/spec/lib/spec/dsl/behaviour_factory.rb
deleted file mode 100755
index 44b60c641..000000000
--- a/spec/lib/spec/dsl/behaviour_factory.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-module Spec
- module DSL
- class BehaviourFactory
-
- class << self
-
- BEHAVIOUR_CLASSES = {:default => Spec::DSL::Behaviour}
-
- # Registers a behaviour class +klass+ with the symbol
- # +behaviour_type+. For example:
- #
- # Spec::DSL::BehaviourFactory.add_behaviour_class(:farm, Spec::Farm::DSL::FarmBehaviour)
- #
- # This will cause Kernel#describe from a file living in
- # <tt>spec/farm</tt> to create behaviour instances of type
- # Spec::Farm::DSL::FarmBehaviour.
- def add_behaviour_class(behaviour_type, klass)
- BEHAVIOUR_CLASSES[behaviour_type] = klass
- end
-
- def remove_behaviour_class(behaviour_type)
- BEHAVIOUR_CLASSES.delete(behaviour_type)
- end
-
- def create(*args, &block)
- opts = Hash === args.last ? args.last : {}
- if opts[:shared]
- behaviour_type = :default
- elsif opts[:behaviour_type]
- behaviour_type = opts[:behaviour_type]
- elsif opts[:spec_path] =~ /spec(\\|\/)(#{BEHAVIOUR_CLASSES.keys.join('|')})/
- behaviour_type = $2.to_sym
- else
- behaviour_type = :default
- end
- return BEHAVIOUR_CLASSES[behaviour_type].new(*args, &block)
- end
-
- end
- end
- end
-end
diff --git a/spec/lib/spec/dsl/composite_proc_builder.rb b/spec/lib/spec/dsl/composite_proc_builder.rb
deleted file mode 100644
index 373f44953..000000000
--- a/spec/lib/spec/dsl/composite_proc_builder.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-module Spec
- module DSL
- class CompositeProcBuilder < Array
- def initialize(callbacks=[])
- push(*callbacks)
- end
-
- def proc(&error_handler)
- parts = self
- errors = []
- Proc.new do
- result = parts.collect do |part|
- begin
- if part.is_a?(UnboundMethod)
- part.bind(self).call
- else
- instance_eval(&part)
- end
- rescue Exception => e
- if error_handler
- error_handler.call(e)
- else
- errors << e
- end
- end
- end
- raise errors.first unless errors.empty?
- result
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/dsl/description.rb b/spec/lib/spec/dsl/description.rb
deleted file mode 100755
index fe8c9b0c9..000000000
--- a/spec/lib/spec/dsl/description.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-module Spec
- module DSL
- class Description
- module ClassMethods
- def generate_description(*args)
- description = args.shift.to_s
- unless args.empty?
- suffix = args.shift.to_s
- description << " " unless suffix =~ /^\s|\.|#/
- description << suffix
- end
- description
- end
- end
- extend ClassMethods
-
- attr_reader :description, :described_type
-
- def initialize(*args)
- args, @options = args_and_options(*args)
- init_behaviour_type(@options)
- init_spec_path(@options)
- init_described_type(args)
- init_description(*args)
- end
-
- def [](key)
- @options[key]
- end
-
- def []=(key, value)
- @options[key] = value
- end
-
- def to_s; @description; end
-
- def ==(value)
- case value
- when Description
- @description == value.description
- else
- @description == value
- end
- end
-
- private
- def init_behaviour_type(options)
- # NOTE - BE CAREFUL IF CHANGING THIS NEXT LINE:
- # this line is as it is to satisfy JRuby - the original version
- # read, simply: "if options[:behaviour_class]", which passed against ruby, but failed against jruby
- if options[:behaviour_class] && options[:behaviour_class].ancestors.include?(Behaviour)
- options[:behaviour_type] = parse_behaviour_type(@options[:behaviour_class])
- end
- end
-
- def init_spec_path(options)
- if options.has_key?(:spec_path)
- options[:spec_path] = File.expand_path(@options[:spec_path])
- end
- end
-
- def init_description(*args)
- @description = self.class.generate_description(*args)
- end
-
- def init_described_type(args)
- @described_type = args.first unless args.first.is_a?(String)
- end
-
- def parse_behaviour_type(behaviour_class)
- behaviour_class.to_s.split("::").reverse[0].gsub!('Behaviour', '').downcase.to_sym
- end
-
- end
- end
-end
diff --git a/spec/lib/spec/dsl/example.rb b/spec/lib/spec/dsl/example.rb
deleted file mode 100644
index d04073f7e..000000000
--- a/spec/lib/spec/dsl/example.rb
+++ /dev/null
@@ -1,135 +0,0 @@
-require 'timeout'
-
-module Spec
- module DSL
- class Example
- # The global sequence number of this example
- attr_accessor :number
-
- def initialize(description, options={}, &example_block)
- @from = caller(0)[3]
- @options = options
- @example_block = example_block
- @description = description
- @description_generated_proc = lambda { |desc| @generated_description = desc }
- end
-
- def run(reporter, before_each_block, after_each_block, dry_run, execution_context, timeout=nil)
- @dry_run = dry_run
- reporter.example_started(self)
- return reporter.example_finished(self) if dry_run
-
- errors = []
- location = nil
- Timeout.timeout(timeout) do
- before_each_ok = before_example(execution_context, errors, &before_each_block)
- example_ok = run_example(execution_context, errors) if before_each_ok
- after_each_ok = after_example(execution_context, errors, &after_each_block)
- location = failure_location(before_each_ok, example_ok, after_each_ok)
- end
-
- ExampleShouldRaiseHandler.new(@from, @options).handle(errors)
- reporter.example_finished(self, errors.first, location, @example_block.nil?) if reporter
- end
-
- def matches?(matcher, specified_examples)
- matcher.example_desc = description
- matcher.matches?(specified_examples)
- end
-
- def description
- @description == :__generate_description ? generated_description : @description
- end
-
- def to_s
- description
- end
-
- private
-
- def generated_description
- return @generated_description if @generated_description
- if @dry_run
- "NO NAME (Because of --dry-run)"
- else
- if @failed
- "NO NAME (Because of Error raised in matcher)"
- else
- "NO NAME (Because there were no expectations)"
- end
- end
- end
-
- def before_example(execution_context, errors, &behaviour_before_block)
- setup_mocks(execution_context)
- Spec::Matchers.description_generated(@description_generated_proc)
-
- builder = CompositeProcBuilder.new
- before_proc = builder.proc(&append_errors(errors))
- execution_context.instance_eval(&before_proc)
-
- execution_context.instance_eval(&behaviour_before_block) if behaviour_before_block
- return errors.empty?
- rescue Exception => e
- @failed = true
- errors << e
- return false
- end
-
- def run_example(execution_context, errors)
- begin
- execution_context.instance_eval(&@example_block) if @example_block
- return true
- rescue Exception => e
- @failed = true
- errors << e
- return false
- end
- end
-
- def after_example(execution_context, errors, &behaviour_after_each)
- execution_context.instance_eval(&behaviour_after_each) if behaviour_after_each
-
- begin
- verify_mocks(execution_context)
- ensure
- teardown_mocks(execution_context)
- end
-
- Spec::Matchers.unregister_description_generated(@description_generated_proc)
-
- builder = CompositeProcBuilder.new
- after_proc = builder.proc(&append_errors(errors))
- execution_context.instance_eval(&after_proc)
-
- return errors.empty?
- rescue Exception => e
- @failed = true
- errors << e
- return false
- end
-
- def setup_mocks(execution_context)
- execution_context.setup_mocks_for_rspec if execution_context.respond_to?(:setup_mocks_for_rspec)
- end
-
- def verify_mocks(execution_context)
- execution_context.verify_mocks_for_rspec if execution_context.respond_to?(:verify_mocks_for_rspec)
- end
-
- def teardown_mocks(execution_context)
- execution_context.teardown_mocks_for_rspec if execution_context.respond_to?(:teardown_mocks_for_rspec)
- end
-
- def append_errors(errors)
- proc {|error| errors << error}
- end
-
- def failure_location(before_each_ok, example_ok, after_each_ok)
- return 'before(:each)' unless before_each_ok
- return description unless example_ok
- return 'after(:each)' unless after_each_ok
- end
- end
- end
-end
diff --git a/spec/lib/spec/dsl/example_matcher.rb b/spec/lib/spec/dsl/example_matcher.rb
deleted file mode 100755
index 18cc47409..000000000
--- a/spec/lib/spec/dsl/example_matcher.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-module Spec
- module DSL
- class ExampleMatcher
-
- attr_writer :example_desc
- def initialize(behaviour_desc, example_desc=nil)
- @behaviour_desc = behaviour_desc
- @example_desc = example_desc
- end
-
- def matches?(specified_examples)
- specified_examples.each do |specified_example|
- return true if matches_literal_example?(specified_example) || matches_example_not_considering_modules?(specified_example)
- end
- false
- end
-
- private
- def matches_literal_example?(specified_example)
- specified_example =~ /(^#{context_regexp} #{example_regexp}$|^#{context_regexp}$|^#{example_regexp}$)/
- end
-
- def matches_example_not_considering_modules?(specified_example)
- specified_example =~ /(^#{context_regexp_not_considering_modules} #{example_regexp}$|^#{context_regexp_not_considering_modules}$|^#{example_regexp}$)/
- end
-
- def context_regexp
- Regexp.escape(@behaviour_desc)
- end
-
- def context_regexp_not_considering_modules
- Regexp.escape(@behaviour_desc.split('::').last)
- end
-
- def example_regexp
- Regexp.escape(@example_desc)
- end
- end
- end
-end
diff --git a/spec/lib/spec/dsl/example_should_raise_handler.rb b/spec/lib/spec/dsl/example_should_raise_handler.rb
deleted file mode 100644
index 942327317..000000000
--- a/spec/lib/spec/dsl/example_should_raise_handler.rb
+++ /dev/null
@@ -1,74 +0,0 @@
-module Spec
- module DSL
- class ExampleShouldRaiseHandler
- def initialize(file_and_line_number, opts)
- @file_and_line_number = file_and_line_number
- @options = opts
- @expected_error_class = determine_error_class(opts)
- @expected_error_message = determine_error_message(opts)
- end
-
- def determine_error_class(opts)
- if candidate = opts[:should_raise]
- if candidate.is_a?(Class)
- return candidate
- elsif candidate.is_a?(Array)
- return candidate[0]
- else
- return Exception
- end
- end
- end
-
- def determine_error_message(opts)
- if candidate = opts[:should_raise]
- if candidate.is_a?(Array)
- return candidate[1]
- end
- end
- return nil
- end
-
- def build_message(exception=nil)
- if @expected_error_message.nil?
- message = "example block expected #{@expected_error_class.to_s}"
- else
- message = "example block expected #{@expected_error_class.new(@expected_error_message.to_s).inspect}"
- end
- message << " but raised #{exception.inspect}" if exception
- message << " but nothing was raised" unless exception
- message << "\n"
- message << @file_and_line_number
- end
-
- def error_matches?(error)
- return false unless error.kind_of?(@expected_error_class)
- unless @expected_error_message.nil?
- if @expected_error_message.is_a?(Regexp)
- return false unless error.message =~ @expected_error_message
- else
- return false unless error.message == @expected_error_message
- end
- end
- return true
- end
-
- def handle(errors)
- if @expected_error_class
- if errors.empty?
- errors << Spec::Expectations::ExpectationNotMetError.new(build_message)
- else
- error_to_remove = errors.detect do |error|
- error_matches?(error)
- end
- if error_to_remove.nil?
- errors.insert(0,Spec::Expectations::ExpectationNotMetError.new(build_message(errors[0])))
- else
- errors.delete(error_to_remove)
- end
- end
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/expectations/errors.rb b/spec/lib/spec/expectations/errors.rb
deleted file mode 100644
index 03e81a064..000000000
--- a/spec/lib/spec/expectations/errors.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Spec
- module Expectations
- class ExpectationNotMetError < StandardError
- end
- end
-end
diff --git a/spec/lib/spec/extensions.rb b/spec/lib/spec/extensions.rb
deleted file mode 100755
index 824f03bfb..000000000
--- a/spec/lib/spec/extensions.rb
+++ /dev/null
@@ -1 +0,0 @@
-require 'spec/extensions/object'
diff --git a/spec/lib/spec/mocks/mock.rb b/spec/lib/spec/mocks/mock.rb
deleted file mode 100644
index aa380e0af..000000000
--- a/spec/lib/spec/mocks/mock.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-module Spec
- module Mocks
- class Mock
- include Methods
-
- # Creates a new mock with a +name+ (that will be used in error messages only)
- # == Options:
- # * <tt>:null_object</tt> - if true, the mock object acts as a forgiving null object allowing any message to be sent to it.
- def initialize(name, options={})
- @name = name
- @options = options
- end
-
- def method_missing(sym, *args, &block)
- __mock_proxy.instance_eval {@messages_received << [sym, args, block]}
- begin
- return self if __mock_proxy.null_object?
- super(sym, *args, &block)
- rescue NoMethodError
- __mock_proxy.raise_unexpected_message_error sym, *args
- end
- end
-
- def inspect
- "#<#{self.class}:#{sprintf '0x%x', self.object_id} @name=#{@name.inspect}>"
- end
- end
- end
-end
diff --git a/spec/lib/spec/mocks/spec_methods.rb b/spec/lib/spec/mocks/spec_methods.rb
deleted file mode 100644
index fd67fd210..000000000
--- a/spec/lib/spec/mocks/spec_methods.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-module Spec
- module Mocks
- module SpecMethods
- include Spec::Mocks::ArgumentConstraintMatchers
-
- # Shortcut for creating an instance of Spec::Mocks::Mock.
- def mock(name, options={})
- Spec::Mocks::Mock.new(name, options)
- end
-
- # Shortcut for creating an instance of Spec::Mocks::Mock with
- # predefined method stubs.
- #
- # == Examples
- #
- # stub_thing = stub("thing", :a => "A")
- # stub_thing.a == "A" => true
- #
- # stub_person = stub("thing", :name => "Joe", :email => "joe@domain.com")
- # stub_person.name => "Joe"
- # stub_person.email => "joe@domain.com"
- def stub(name, stubs={})
- object_stub = mock(name)
- stubs.each { |key, value| object_stub.stub!(key).and_return(value) }
- object_stub
- end
-
- end
- end
-end
diff --git a/spec/lib/spec/runner/behaviour_runner.rb b/spec/lib/spec/runner/behaviour_runner.rb
deleted file mode 100644
index 1ac891f3c..000000000
--- a/spec/lib/spec/runner/behaviour_runner.rb
+++ /dev/null
@@ -1,123 +0,0 @@
-module Spec
- module Runner
- class BehaviourRunner
-
- def initialize(options, arg=nil)
- @behaviours = []
- @options = options
- end
-
- def add_behaviour(behaviour)
- if !specified_examples.nil? && !specified_examples.empty?
- behaviour.retain_examples_matching!(specified_examples)
- end
- @behaviours << behaviour if behaviour.number_of_examples != 0 && !behaviour.shared?
- end
-
- # Runs all behaviours and returns the number of failures.
- def run(paths, exit_when_done)
- prepare!(paths)
- begin
- run_behaviours
- rescue Interrupt
- ensure
- report_end
- end
- failure_count = report_dump
-
- heckle if(failure_count == 0 && !@options.heckle_runner.nil?)
-
- if(exit_when_done)
- exit_code = (failure_count == 0) ? 0 : 1
- exit(exit_code)
- end
- failure_count
- end
-
- def report_end
- @options.reporter.end
- end
-
- def report_dump
- @options.reporter.dump
- end
-
- def prepare!(paths)
- unless paths.nil? # It's nil when running single specs with ruby
- paths = find_paths(paths)
- sorted_paths = sort_paths(paths)
- load_specs(sorted_paths) # This will populate @behaviours via callbacks to add_behaviour
- end
- @options.reporter.start(number_of_examples)
- @behaviours.reverse! if @options.reverse
- set_sequence_numbers
- end
-
- def run_behaviours
- @behaviours.each do |behaviour|
- behaviour.run(@options.reporter, @options.dry_run, @options.reverse, @options.timeout)
- end
- end
-
- def number_of_examples
- @behaviours.inject(0) {|sum, behaviour| sum + behaviour.number_of_examples}
- end
-
- FILE_SORTERS = {
- 'mtime' => lambda {|file_a, file_b| File.mtime(file_b) <=> File.mtime(file_a)}
- }
-
- def sorter(paths)
- FILE_SORTERS[@options.loadby]
- end
-
- def sort_paths(paths)
- sorter = sorter(paths)
- paths = paths.sort(&sorter) unless sorter.nil?
- paths
- end
-
- private
-
- # Sets the #number on each Example
- def set_sequence_numbers
- number = 0
- @behaviours.each do |behaviour|
- number = behaviour.set_sequence_numbers(number, @options.reverse)
- end
- end
-
- def find_paths(paths)
- result = []
- paths.each do |path|
- if File.directory?(path)
- result += Dir["#{path}/**/*.rb"]
- elsif File.file?(path)
- result << path
- else
- raise "File or directory not found: #{path}"
- end
- end
- result
- end
-
- def load_specs(paths)
- paths.each do |path|
- load path
- end
- end
-
- def specified_examples
- @options.examples
- end
-
- def heckle
- heckle_runner = @options.heckle_runner
- @options.heckle_runner = nil
- behaviour_runner = self.class.new(@options)
- behaviour_runner.instance_variable_set(:@behaviours, @behaviours)
- heckle_runner.heckle_with(behaviour_runner)
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/command_line.rb b/spec/lib/spec/runner/command_line.rb
deleted file mode 100644
index 0d70337e1..000000000
--- a/spec/lib/spec/runner/command_line.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-require 'spec/runner/option_parser'
-
-module Spec
- module Runner
- # Facade to run specs without having to fork a new ruby process (using `spec ...`)
- class CommandLine
- # Runs specs. +argv+ is the commandline args as per the spec commandline API, +err+
- # and +out+ are the streams output will be written to. +exit+ tells whether or
- # not a system exit should be called after the specs are run and
- # +warn_if_no_files+ tells whether or not a warning (the help message)
- # should be printed to +err+ in case no files are specified.
- def self.run(argv, err, out, exit=true, warn_if_no_files=true)
- old_behaviour_runner = defined?($behaviour_runner) ? $behaviour_runner : nil
- $behaviour_runner = OptionParser.new.create_behaviour_runner(argv, err, out, warn_if_no_files)
- return if $behaviour_runner.nil? # This is the case if we use --drb
-
- $behaviour_runner.run(argv, exit)
- $behaviour_runner = old_behaviour_runner
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/extensions/kernel.rb b/spec/lib/spec/runner/extensions/kernel.rb
deleted file mode 100644
index 75f2c335e..000000000
--- a/spec/lib/spec/runner/extensions/kernel.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-module Kernel
- # Creates and registers an instance of a Spec::DSL::Behaviour (or a subclass).
- # The instantiated behaviour class depends on the directory of the file
- # calling this method. For example, Spec::Rails will use different
- # classes for specs living in <tt>spec/models</tt>, <tt>spec/helpers</tt>,
- # <tt>spec/views</tt> and <tt>spec/controllers</tt>.
- #
- # It is also possible to override autodiscovery of the behaviour class
- # with an options Hash as the last argument:
- #
- # describe "name", :behaviour_type => :something_special do ...
- #
- # The reason for using different behaviour classes is to have
- # different matcher methods available from within the <tt>describe</tt>
- # block.
- #
- # See Spec::DSL::BehaviourFactory#add_behaviour_class for details about
- # how to register special Spec::DSL::Behaviour implementations.
- #
- def describe(*args, &block)
- raise ArgumentError if args.empty?
- args << {} unless Hash === args.last
- args.last[:spec_path] = caller(0)[1]
- register_behaviour(Spec::DSL::BehaviourFactory.create(*args, &block))
- end
- alias :context :describe
-
- def respond_to(*names)
- Spec::Matchers::RespondTo.new(*names)
- end
-
-private
-
- def register_behaviour(behaviour)
- if behaviour.shared?
- Spec::DSL::Behaviour.add_shared_behaviour(behaviour)
- else
- behaviour_runner.add_behaviour(behaviour)
- end
- end
-
- def behaviour_runner
- # TODO: Figure out a better way to get this considered "covered" and keep this statement on multiple lines
- unless $behaviour_runner; \
- $behaviour_runner = ::Spec::Runner::OptionParser.new.create_behaviour_runner(ARGV.dup, STDERR, STDOUT, false); \
- at_exit { $behaviour_runner.run(nil, false) }; \
- end
- $behaviour_runner
- end
-end
diff --git a/spec/lib/spec/runner/extensions/object.rb b/spec/lib/spec/runner/extensions/object.rb
deleted file mode 100644
index 49745352f..000000000
--- a/spec/lib/spec/runner/extensions/object.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# The following copyright applies to Object#copy_instance_variables_from,
-# which we borrowed from active_support.
-#
-# Copyright (c) 2004 David Heinemeier Hansson
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-class Object
- # From active_support
- def copy_instance_variables_from(object, exclude = []) # :nodoc:
- exclude += object.protected_instance_variables if object.respond_to? :protected_instance_variables
-
- instance_variables = object.instance_variables - exclude.map { |name| name.to_s }
- instance_variables.each { |name| instance_variable_set(name, object.instance_variable_get(name)) }
- end
-end
diff --git a/spec/lib/spec/runner/formatter.rb b/spec/lib/spec/runner/formatter.rb
deleted file mode 100644
index 17512d958..000000000
--- a/spec/lib/spec/runner/formatter.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'spec/runner/formatter/base_formatter'
-require 'spec/runner/formatter/base_text_formatter'
-require 'spec/runner/formatter/progress_bar_formatter'
-require 'spec/runner/formatter/rdoc_formatter'
-require 'spec/runner/formatter/specdoc_formatter'
-require 'spec/runner/formatter/html_formatter'
-require 'spec/runner/formatter/failing_examples_formatter'
-require 'spec/runner/formatter/failing_behaviours_formatter'
-require 'spec/runner/formatter/snippet_extractor'
diff --git a/spec/lib/spec/runner/formatter/failing_behaviours_formatter.rb b/spec/lib/spec/runner/formatter/failing_behaviours_formatter.rb
deleted file mode 100644
index 2b3940fd3..000000000
--- a/spec/lib/spec/runner/formatter/failing_behaviours_formatter.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-module Spec
- module Runner
- module Formatter
- class FailingBehavioursFormatter < BaseTextFormatter
- def add_behaviour(behaviour_name)
- if behaviour_name =~ /(.*) \(druby.*\)$/
- @behaviour_name = $1
- else
- @behaviour_name = behaviour_name
- end
- end
-
- def example_failed(example, counter, failure)
- unless @behaviour_name.nil?
- @output.puts @behaviour_name
- @behaviour_name = nil
- @output.flush
- end
- end
-
- def dump_failure(counter, failure)
- end
-
- def dump_summary(duration, example_count, failure_count, pending_count)
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/formatter/rdoc_formatter.rb b/spec/lib/spec/runner/formatter/rdoc_formatter.rb
deleted file mode 100644
index 0fd22ba6c..000000000
--- a/spec/lib/spec/runner/formatter/rdoc_formatter.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-module Spec
- module Runner
- module Formatter
- class RdocFormatter < BaseTextFormatter
- def add_behaviour(name)
- @output.puts "# #{name}"
- end
-
- def example_passed(example)
- @output.puts "# * #{example.description}"
- @output.flush
- end
-
- def example_failed(example, counter, failure)
- @output.puts "# * #{example.description} [#{counter} - FAILED]"
- end
-
- def example_pending(behaviour_name, example_name, message)
- @output.puts "# * #{behaviour_name} #{example_name} [PENDING: #{message}]"
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/formatter/specdoc_formatter.rb b/spec/lib/spec/runner/formatter/specdoc_formatter.rb
deleted file mode 100644
index ad794b238..000000000
--- a/spec/lib/spec/runner/formatter/specdoc_formatter.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-module Spec
- module Runner
- module Formatter
- class SpecdocFormatter < BaseTextFormatter
- def add_behaviour(name)
- @output.puts
- @output.puts name
- @output.flush
- end
-
- def example_failed(example, counter, failure)
- @output.puts failure.expectation_not_met? ? red("- #{example.description} (FAILED - #{counter})") : magenta("- #{example.description} (ERROR - #{counter})")
- @output.flush
- end
-
- def example_passed(example)
- @output.puts green("- #{example.description}")
- @output.flush
- end
-
- def example_pending(behaviour_name, example_name, message)
- super
- @output.puts yellow("- #{example_name} (PENDING: #{message})")
- @output.flush
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/option_parser.rb b/spec/lib/spec/runner/option_parser.rb
deleted file mode 100644
index 1facb85a8..000000000
--- a/spec/lib/spec/runner/option_parser.rb
+++ /dev/null
@@ -1,227 +0,0 @@
-require 'optparse'
-require 'stringio'
-
-module Spec
- module Runner
- class OptionParser
- BUILT_IN_FORMATTERS = {
- 'specdoc' => Formatter::SpecdocFormatter,
- 's' => Formatter::SpecdocFormatter,
- 'html' => Formatter::HtmlFormatter,
- 'h' => Formatter::HtmlFormatter,
- 'rdoc' => Formatter::RdocFormatter,
- 'r' => Formatter::RdocFormatter,
- 'progress' => Formatter::ProgressBarFormatter,
- 'p' => Formatter::ProgressBarFormatter,
- 'failing_examples' => Formatter::FailingExamplesFormatter,
- 'e' => Formatter::FailingExamplesFormatter,
- 'failing_behaviours' => Formatter::FailingBehavioursFormatter,
- 'b' => Formatter::FailingBehavioursFormatter
- }
-
- COMMAND_LINE = {
- :diff => ["-D", "--diff [FORMAT]", "Show diff of objects that are expected to be equal when they are not",
- "Builtin formats: unified|u|context|c",
- "You can also specify a custom differ class",
- "(in which case you should also specify --require)"],
- :colour => ["-c", "--colour", "--color", "Show coloured (red/green) output"],
- :example => ["-e", "--example [NAME|FILE_NAME]", "Execute example(s) with matching name(s). If the argument is",
- "the path to an existing file (typically generated by a previous",
- "run using --format failing_examples:file.txt), then the examples",
- "on each line of thatfile will be executed. If the file is empty,",
- "all examples will be run (as if --example was not specified).",
- " ",
- "If the argument is not an existing file, then it is treated as",
- "an example name directly, causing RSpec to run just the example",
- "matching that name"],
- :specification => ["-s", "--specification [NAME]", "DEPRECATED - use -e instead", "(This will be removed when autotest works with -e)"],
- :line => ["-l", "--line LINE_NUMBER", Integer, "Execute behaviout or specification at given line.",
- "(does not work for dynamically generated specs)"],
- :format => ["-f", "--format FORMAT[:WHERE]", "Specifies what format to use for output. Specify WHERE to tell",
- "the formatter where to write the output. All built-in formats",
- "expect WHERE to be a file name, and will write to STDOUT if it's",
- "not specified. The --format option may be specified several times",
- "if you want several outputs",
- " ",
- "Builtin formats: ",
- "progress|p : Text progress",
- "specdoc|s : Behaviour doc as text",
- "rdoc|r : Behaviour doc as RDoc",
- "html|h : A nice HTML report",
- "failing_examples|e : Write all failing examples - input for --example",
- "failing_behaviours|b : Write all failing behaviours - input for --example",
- " ",
- "FORMAT can also be the name of a custom formatter class",
- "(in which case you should also specify --require to load it)"],
- :require => ["-r", "--require FILE", "Require FILE before running specs",
- "Useful for loading custom formatters or other extensions.",
- "If this option is used it must come before the others"],
- :backtrace => ["-b", "--backtrace", "Output full backtrace"],
- :loadby => ["-L", "--loadby STRATEGY", "Specify the strategy by which spec files should be loaded.",
- "STRATEGY can currently only be 'mtime' (File modification time)",
- "By default, spec files are loaded in alphabetical order if --loadby",
- "is not specified."],
- :reverse => ["-R", "--reverse", "Run examples in reverse order"],
- :timeout => ["-t", "--timeout FLOAT", "Interrupt and fail each example that doesn't complete in the",
- "specified time"],
- :heckle => ["-H", "--heckle CODE", "If all examples pass, this will mutate the classes and methods",
- "identified by CODE little by little and run all the examples again",
- "for each mutation. The intent is that for each mutation, at least",
- "one example *should* fail, and RSpec will tell you if this is not the",
- "case. CODE should be either Some::Module, Some::Class or",
- "Some::Fabulous#method}"],
- :dry_run => ["-d", "--dry-run", "Invokes formatters without executing the examples."],
- :options_file => ["-O", "--options PATH", "Read options from a file"],
- :generate_options => ["-G", "--generate-options PATH", "Generate an options file for --options"],
- :runner => ["-U", "--runner RUNNER", "Use a custom BehaviourRunner."],
- :drb => ["-X", "--drb", "Run examples via DRb. (For example against script/spec_server)"],
- :version => ["-v", "--version", "Show version"],
- :help => ["-h", "--help", "You're looking at it"]
- }
-
- def initialize
- @spec_parser = SpecParser.new
- @file_factory = File
- end
-
- def create_behaviour_runner(args, err, out, warn_if_no_files)
- options = parse(args, err, out, warn_if_no_files)
- # Some exit points in parse (--generate-options, --drb) don't return the options,
- # but hand over control. In that case we don't want to continue.
- return nil unless options.is_a?(Options)
- options.configure
- options.behaviour_runner
- end
-
- def parse(args, err, out, warn_if_no_files)
- options_file = nil
- args_copy = args.dup
- options = Options.new(err, out)
-
- opts = ::OptionParser.new do |opts|
- opts.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]"
- opts.separator ""
-
- def opts.rspec_on(name, &block)
- on(*COMMAND_LINE[name], &block)
- end
-
- opts.rspec_on(:diff) {|diff| options.parse_diff(diff)}
-
- opts.rspec_on(:colour) {options.colour = true}
-
- opts.rspec_on(:example) {|example| options.parse_example(example)}
-
- opts.rspec_on(:specification) {|example| options.parse_example(example)}
-
- opts.rspec_on(:line) {|line_number| options.line_number = line_number.to_i}
-
- opts.rspec_on(:format) {|format| options.parse_format(format)}
-
- opts.rspec_on(:require) {|req| options.parse_require(req)}
-
- opts.rspec_on(:backtrace) {options.backtrace_tweaker = NoisyBacktraceTweaker.new}
-
- opts.rspec_on(:loadby) {|loadby| options.loadby = loadby}
-
- opts.rspec_on(:reverse) {options.reverse = true}
-
- opts.rspec_on(:timeout) {|timeout| options.timeout = timeout.to_f}
-
- opts.rspec_on(:heckle) {|heckle| options.parse_heckle(heckle)}
-
- opts.rspec_on(:dry_run) {options.dry_run = true}
-
- opts.rspec_on(:options_file) do |options_file|
- return parse_options_file(options_file, out, err, args_copy, warn_if_no_files)
- end
-
- opts.rspec_on(:generate_options) do |options_file|
- options.parse_generate_options(options_file, args_copy, out)
- end
-
- opts.rspec_on(:runner) do |runner|
- options.runner_arg = runner
- end
-
- opts.rspec_on(:drb) do
- return parse_drb(args_copy, out, err, warn_if_no_files)
- end
-
- opts.rspec_on(:version) {parse_version(out)}
-
- opts.on_tail(*COMMAND_LINE[:help]) {parse_help(opts, out)}
- end
- opts.parse!(args)
-
- if args.empty? && warn_if_no_files
- err.puts "No files specified."
- err.puts opts
- exit(6) if err == $stderr
- end
-
- if options.line_number
- set_spec_from_line_number(options, args, err)
- end
-
- if options.formatters.empty?
- options.formatters << Formatter::ProgressBarFormatter.new(out)
- end
-
- options
- end
-
- def parse_options_file(options_file, out_stream, error_stream, args_copy, warn_if_no_files)
- # Remove the --options option and the argument before writing to file
- index = args_copy.index("-O") || args_copy.index("--options")
- args_copy.delete_at(index)
- args_copy.delete_at(index)
-
- new_args = args_copy + IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten
- return CommandLine.run(new_args, error_stream, out_stream, true, warn_if_no_files)
- end
-
- def parse_drb(args_copy, out_stream, error_stream, warn_if_no_files)
- # Remove the --drb option
- index = args_copy.index("-X") || args_copy.index("--drb")
- args_copy.delete_at(index)
-
- return DrbCommandLine.run(args_copy, error_stream, out_stream, true, warn_if_no_files)
- end
-
- def parse_version(out_stream)
- out_stream.puts ::Spec::VERSION::DESCRIPTION
- exit if out_stream == $stdout
- end
-
- def parse_help(opts, out_stream)
- out_stream.puts opts
- exit if out_stream == $stdout
- end
-
- def set_spec_from_line_number(options, args, err)
- if options.examples.empty?
- if args.length == 1
- if @file_factory.file?(args[0])
- source = @file_factory.open(args[0])
- example = @spec_parser.spec_name_for(source, options.line_number)
- options.parse_example(example)
- elsif @file_factory.directory?(args[0])
- err.puts "You must specify one file, not a directory when using the --line option"
- exit(1) if err == $stderr
- else
- err.puts "#{args[0]} does not exist"
- exit(2) if err == $stderr
- end
- else
- err.puts "Only one file can be specified when using the --line option: #{args.inspect}"
- exit(3) if err == $stderr
- end
- else
- err.puts "You cannot use both --line and --example"
- exit(4) if err == $stderr
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/options.rb b/spec/lib/spec/runner/options.rb
deleted file mode 100644
index a940133eb..000000000
--- a/spec/lib/spec/runner/options.rb
+++ /dev/null
@@ -1,175 +0,0 @@
-module Spec
- module Runner
- class Options
- BUILT_IN_FORMATTERS = {
- 'specdoc' => Formatter::SpecdocFormatter,
- 's' => Formatter::SpecdocFormatter,
- 'html' => Formatter::HtmlFormatter,
- 'h' => Formatter::HtmlFormatter,
- 'rdoc' => Formatter::RdocFormatter,
- 'r' => Formatter::RdocFormatter,
- 'progress' => Formatter::ProgressBarFormatter,
- 'p' => Formatter::ProgressBarFormatter,
- 'failing_examples' => Formatter::FailingExamplesFormatter,
- 'e' => Formatter::FailingExamplesFormatter,
- 'failing_behaviours' => Formatter::FailingBehavioursFormatter,
- 'b' => Formatter::FailingBehavioursFormatter
- }
-
- attr_accessor(
- :backtrace_tweaker,
- :colour,
- :context_lines,
- :diff_format,
- :differ_class,
- :dry_run,
- :examples,
- :failure_file,
- :formatters,
- :generate,
- :heckle_runner,
- :line_number,
- :loadby,
- :reporter,
- :reverse,
- :timeout,
- :verbose,
- :runner_arg,
- :behaviour_runner
- )
-
- def initialize(err, out)
- @err, @out = err, out
- @backtrace_tweaker = QuietBacktraceTweaker.new
- @examples = []
- @formatters = []
- @colour = false
- @dry_run = false
- end
-
- def configure
- configure_formatters
- create_reporter
- configure_differ
- create_behaviour_runner
- end
-
- def create_behaviour_runner
- return nil if @generate
- @behaviour_runner = if @runner_arg
- klass_name, arg = split_at_colon(@runner_arg)
- runner_type = load_class(klass_name, 'behaviour runner', '--runner')
- runner_type.new(self, arg)
- else
- BehaviourRunner.new(self)
- end
- end
-
- def configure_formatters
- @formatters.each do |formatter|
- formatter.colour = @colour if formatter.respond_to?(:colour=)
- formatter.dry_run = @dry_run if formatter.respond_to?(:dry_run=)
- end
- end
-
- def create_reporter
- @reporter = Reporter.new(@formatters, @backtrace_tweaker)
- end
-
- def configure_differ
- if @differ_class
- Spec::Expectations.differ = @differ_class.new(@diff_format, @context_lines, @colour)
- end
- end
-
- def parse_diff(format)
- @context_lines = 3
- case format
- when :context, 'context', 'c'
- @diff_format = :context
- when :unified, 'unified', 'u', '', nil
- @diff_format = :unified
- end
-
- if [:context,:unified].include? @diff_format
- require 'spec/expectations/differs/default'
- @differ_class = Spec::Expectations::Differs::Default
- else
- @diff_format = :custom
- @differ_class = load_class(format, 'differ', '--diff')
- end
- end
-
- def parse_example(example)
- if(File.file?(example))
- @examples = File.open(example).read.split("\n")
- else
- @examples = [example]
- end
- end
-
- def parse_format(format_arg)
- format, where = split_at_colon(format_arg)
- # This funky regexp checks whether we have a FILE_NAME or not
- if where.nil?
- raise "When using several --format options only one of them can be without a file" if @out_used
- where = @out
- @out_used = true
- end
-
- formatter_type = BUILT_IN_FORMATTERS[format] || load_class(format, 'formatter', '--format')
- @formatters << formatter_type.new(where)
- end
-
- def parse_require(req)
- req.split(",").each{|file| require file}
- end
-
- def parse_heckle(heckle)
- heckle_require = [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} ? 'spec/runner/heckle_runner_unsupported' : 'spec/runner/heckle_runner'
- require heckle_require
- @heckle_runner = HeckleRunner.new(heckle)
- end
-
- def parse_generate_options(options_file, args_copy, out_stream)
- # Remove the --generate-options option and the argument before writing to file
- index = args_copy.index("-G") || args_copy.index("--generate-options")
- args_copy.delete_at(index)
- args_copy.delete_at(index)
- File.open(options_file, 'w') do |io|
- io.puts args_copy.join("\n")
- end
- out_stream.puts "\nOptions written to #{options_file}. You can now use these options with:"
- out_stream.puts "spec --options #{options_file}"
- @generate = true
- end
-
- def split_at_colon(s)
- if s =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/
- arg = $2 == "" ? nil : $2
- [$1, arg]
- else
- raise "Couldn't parse #{s.inspect}"
- end
- end
-
- def load_class(name, kind, option)
- if name =~ /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/
- arg = $2 == "" ? nil : $2
- [$1, arg]
- else
- m = "#{name.inspect} is not a valid class name"
- @err.puts m
- raise m
- end
- begin
- eval(name, binding, __FILE__, __LINE__)
- rescue NameError => e
- @err.puts "Couldn't find #{kind} class #{name}"
- @err.puts "Make sure the --require option is specified *before* #{option}"
- if $_spec_spec ; raise e ; else exit(1) ; end
- end
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/reporter.rb b/spec/lib/spec/runner/reporter.rb
deleted file mode 100644
index b1dc2a27a..000000000
--- a/spec/lib/spec/runner/reporter.rb
+++ /dev/null
@@ -1,125 +0,0 @@
-module Spec
- module Runner
- class Reporter
-
- def initialize(formatters, backtrace_tweaker)
- @formatters = formatters
- @backtrace_tweaker = backtrace_tweaker
- clear!
- end
-
- def add_behaviour(name)
- @formatters.each{|f| f.add_behaviour(name)}
- @behaviour_names << name
- end
-
- def example_started(name)
- @formatters.each{|f| f.example_started(name)}
- end
-
- def example_finished(name, error=nil, failure_location=nil, not_implemented = false)
- @example_names << name
-
- if not_implemented
- example_pending(@behaviour_names.last, name)
- elsif error.nil?
- example_passed(name)
- elsif Spec::DSL::ExamplePendingError === error
- example_pending(@behaviour_names.last, name, error.message)
- else
- example_failed(name, error, failure_location)
- end
- end
-
- def start(number_of_examples)
- clear!
- @start_time = Time.new
- @formatters.each{|f| f.start(number_of_examples)}
- end
-
- def end
- @end_time = Time.new
- end
-
- # Dumps the summary and returns the total number of failures
- def dump
- @formatters.each{|f| f.start_dump}
- dump_failures
- @formatters.each do |f|
- f.dump_summary(duration, @example_names.length, @failures.length, @pending_count)
- f.close
- end
- @failures.length
- end
-
- private
-
- def clear!
- @behaviour_names = []
- @failures = []
- @pending_count = 0
- @example_names = []
- @start_time = nil
- @end_time = nil
- end
-
- def dump_failures
- return if @failures.empty?
- @failures.inject(1) do |index, failure|
- @formatters.each{|f| f.dump_failure(index, failure)}
- index + 1
- end
- end
-
- def duration
- return @end_time - @start_time unless (@end_time.nil? or @start_time.nil?)
- return "0.0"
- end
-
- def example_passed(name)
- @formatters.each{|f| f.example_passed(name)}
- end
-
- def example_failed(name, error, failure_location)
- @backtrace_tweaker.tweak_backtrace(error, failure_location)
- example_name = "#{@behaviour_names.last} #{name}"
- failure = Failure.new(example_name, error)
- @failures << failure
- @formatters.each{|f| f.example_failed(name, @failures.length, failure)}
- end
-
- def example_pending(behaviour_name, example_name, message="Not Yet Implemented")
- @pending_count += 1
- @formatters.each{|f| f.example_pending(behaviour_name, example_name, message)}
- end
-
- class Failure
- attr_reader :exception
-
- def initialize(example_name, exception)
- @example_name = example_name
- @exception = exception
- end
-
- def header
- if expectation_not_met?
- "'#{@example_name}' FAILED"
- elsif pending_fixed?
- "'#{@example_name}' FIXED"
- else
- "#{@exception.class.name} in '#{@example_name}'"
- end
- end
-
- def pending_fixed?
- @exception.is_a?(Spec::DSL::PendingFixedError)
- end
-
- def expectation_not_met?
- @exception.is_a?(Spec::Expectations::ExpectationNotMetError)
- end
-
- end
- end
- end
-end
diff --git a/spec/lib/spec/runner/spec_parser.rb b/spec/lib/spec/runner/spec_parser.rb
deleted file mode 100644
index bc9170065..000000000
--- a/spec/lib/spec/runner/spec_parser.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-module Spec
- module Runner
- # Parses a spec file and finds the nearest example for a given line number.
- class SpecParser
- def spec_name_for(io, line_number)
- source = io.read
- behaviour, behaviour_line = behaviour_at_line(source, line_number)
- example, example_line = example_at_line(source, line_number)
- if behaviour && example && (behaviour_line < example_line)
- "#{behaviour} #{example}"
- elsif behaviour
- behaviour
- else
- nil
- end
- end
-
- protected
-
- def behaviour_at_line(source, line_number)
- find_above(source, line_number, /^\s*(context|describe)\s+(.*)\s+do/)
- end
-
- def example_at_line(source, line_number)
- find_above(source, line_number, /^\s*(specify|it)\s+(.*)\s+do/)
- end
-
- # Returns the context/describe or specify/it name and the line number
- def find_above(source, line_number, pattern)
- lines_above_reversed(source, line_number).each_with_index do |line, n|
- return [parse_description($2), line_number-n] if line =~ pattern
- end
- nil
- end
-
- def lines_above_reversed(source, line_number)
- lines = source.split("\n")
- lines[0...line_number].reverse
- end
-
- def parse_description(str)
- return str[1..-2] if str =~ /^['"].*['"]$/
- if matches = /^(.*)\s*,\s*['"](.*)['"]$/.match(str)
- return ::Spec::DSL::Description.generate_description(matches[1], matches[2])
- end
- return str
- end
- end
- end
-end
diff --git a/spec/lib/spec/test_case_adapter.rb b/spec/lib/spec/test_case_adapter.rb
deleted file mode 100755
index 992e098fd..000000000
--- a/spec/lib/spec/test_case_adapter.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-require 'spec/expectations'
-require 'spec/matchers'
-
-module Test
- module Unit
- class TestCase
- include Spec::Matchers
- end
- end
-end
diff --git a/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb b/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
new file mode 100644
index 000000000..e2f3d4728
--- /dev/null
+++ b/spec/monkey_patches/add_confine_and_runnable_to_rspec_dsl.rb
@@ -0,0 +1,43 @@
+dir = File.expand_path(File.dirname(__FILE__))
+[ "#{dir}/../../lib", "#{dir}/../../test/lib"].each do |dir|
+ fulldir = File.expand_path(dir)
+ $LOAD_PATH.unshift(fulldir) unless $LOAD_PATH.include?(fulldir)
+end
+
+require 'spec'
+require 'puppettest'
+require 'puppettest/runnable_test'
+
+module Spec
+ module Runner
+ class ExampleGroupRunner
+ def run
+ prepare
+ success = true
+ example_groups.each do |example_group|
+ next unless example_group.runnable?
+ success = success & example_group.run
+ end
+ return success
+ ensure
+ finish
+ end
+ end
+ end
+end
+
+module Spec
+ module Example
+ class ExampleGroup
+ extend PuppetTest::RunnableTest
+ end
+ end
+end
+
+module Test
+ module Unit
+ class TestCase
+ extend PuppetTest::RunnableTest
+ end
+ end
+end
diff --git a/spec/lib/shared_behaviours/file_server_terminus.rb b/spec/shared_behaviours/file_server_terminus.rb
index de08f29fc..de08f29fc 100644
--- a/spec/lib/shared_behaviours/file_server_terminus.rb
+++ b/spec/shared_behaviours/file_server_terminus.rb
diff --git a/spec/lib/shared_behaviours/file_serving.rb b/spec/shared_behaviours/file_serving.rb
index b5ab6b0fd..b5ab6b0fd 100644
--- a/spec/lib/shared_behaviours/file_serving.rb
+++ b/spec/shared_behaviours/file_serving.rb
diff --git a/spec/spec.opts b/spec/spec.opts
index 2cac5f260..2f9bf0d0a 100644
--- a/spec/spec.opts
+++ b/spec/spec.opts
@@ -1,5 +1,3 @@
--colour
---format
-s
--loadby
-mtime \ No newline at end of file
+mtime
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index bfac9095f..db14b47cb 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,22 +1,36 @@
dir = File.expand_path(File.dirname(__FILE__))
-$LOAD_PATH.unshift("#{dir}/lib")
+
+$LOAD_PATH.unshift("#{dir}/")
$LOAD_PATH.unshift("#{dir}/../lib")
$LOAD_PATH.unshift("#{dir}/../test/lib") # Add the old test dir, so that we can still find our local mocha and spec
+# include any gems in vendor/gems
+Dir["#{dir}/../vendor/gems/**"].each do |path|
+ libpath = File.join(path, "lib")
+ if File.directory?(libpath)
+ $LOAD_PATH.unshift(libpath)
+ else
+ $LOAD_PATH.unshift(path)
+ end
+end
+
require 'puppettest'
require 'puppettest/runnable_test'
require 'mocha'
require 'spec'
+# load any monkey-patches
+Dir["#{dir}/monkey_patches/*.rb"].map { |file| require file }
+
Spec::Runner.configure do |config|
config.mock_with :mocha
- config.prepend_before :each do
- setup() if respond_to? :setup
- end
- config.prepend_after :each do
- teardown() if respond_to? :teardown
- end
+# config.prepend_before :all do
+# setup_mocks_for_rspec
+# setup() if respond_to? :setup
+# end
+#
+# config.prepend_after :all do
+# teardown() if respond_to? :teardown
+# end
end
-
-require "#{dir}/lib/monkey_patches/add_confine_and_runnable_to_rspec_dsl"
diff --git a/spec/unit/file_serving/configuration.rb b/spec/unit/file_serving/configuration.rb
index df46b9b6a..eecaefe5f 100755
--- a/spec/unit/file_serving/configuration.rb
+++ b/spec/unit/file_serving/configuration.rb
@@ -4,17 +4,6 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/configuration'
-module FSConfigurationTesting
- def setup
- @path = "/path/to/configuration/file.conf"
- Puppet.settings.stubs(:value).with(:fileserverconfig).returns(@path)
- end
-
- def teardown
- Puppet::FileServing::Configuration.clear_cache
- end
-end
-
describe Puppet::FileServing::Configuration do
it "should make :new a private method" do
proc { Puppet::FileServing::Configuration.new }.should raise_error
@@ -35,193 +24,201 @@ describe Puppet::FileServing::Configuration do
end
end
-describe Puppet::FileServing::Configuration, " when initializing" do
- include FSConfigurationTesting
-
- it "should work without a configuration file" do
- FileTest.stubs(:exists?).with(@path).returns(false)
- proc { Puppet::FileServing::Configuration.create }.should_not raise_error
- end
-
- it "should parse the configuration file if present" do
- FileTest.stubs(:exists?).with(@path).returns(true)
- @parser = mock 'parser'
- @parser.expects(:parse).returns({})
- Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
- Puppet::FileServing::Configuration.create
- end
-
- it "should determine the path to the configuration file from the Puppet settings" do
- Puppet::FileServing::Configuration.create
- end
-end
-
-describe Puppet::FileServing::Configuration, " when parsing the configuration file" do
- include FSConfigurationTesting
-
- before do
- FileTest.stubs(:exists?).with(@path).returns(true)
- @parser = mock 'parser'
- Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
- end
-
- it "should set the mount list to the results of parsing" do
- @parser.expects(:parse).returns("one" => mock("mount"))
- config = Puppet::FileServing::Configuration.create
- config.mounted?("one").should be_true
- end
-
- it "should not raise exceptions" do
- @parser.expects(:parse).raises(ArgumentError)
- proc { Puppet::FileServing::Configuration.create }.should_not raise_error
- end
-
- it "should replace the existing mount list with the results of reparsing" do
- @parser.expects(:parse).returns("one" => mock("mount"))
- config = Puppet::FileServing::Configuration.create
- config.mounted?("one").should be_true
- # Now parse again
- @parser.expects(:parse).returns("two" => mock('other'))
- config.send(:readconfig, false)
- config.mounted?("one").should be_false
- config.mounted?("two").should be_true
- end
-
- it "should not replace the mount list until the file is entirely parsed successfully" do
- @parser.expects(:parse).returns("one" => mock("mount"))
- @parser.expects(:parse).raises(ArgumentError)
- config = Puppet::FileServing::Configuration.create
- # Now parse again, so the exception gets thrown
- config.send(:readconfig, false)
- config.mounted?("one").should be_true
- end
-end
-
-describe Puppet::FileServing::Configuration, " when finding files" do
- include FSConfigurationTesting
-
- before do
- @parser = mock 'parser'
- @parser.stubs(:changed?).returns true
- FileTest.stubs(:exists?).with(@path).returns(true)
- Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
-
- @mount1 = stub 'mount', :name => "one"
- @mounts = {"one" => @mount1}
-
- Facter.stubs(:value).with("hostname").returns("whatever")
-
- @config = Puppet::FileServing::Configuration.create
- end
-
- it "should fail if the uri does not match a leading slash followed by a valid mount name" do
- @parser.expects(:parse).returns(@mounts)
- proc { @config.file_path("something") }.should raise_error(ArgumentError)
- end
-
- it "should use the first term after the first slash for the mount name" do
- @parser.expects(:parse).returns(@mounts)
- FileTest.stubs(:exists?).returns(true)
- @mount1.expects(:file)
- @config.file_path("/one")
- end
-
- it "should use the remainder of the URI after the mount name as the file name" do
- @parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file).with("something/else", {})
- FileTest.stubs(:exists?).returns(true)
- @config.file_path("/one/something/else")
- end
-
- it "should treat a bare name as a mount and no relative file" do
- @parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file).with(nil, {})
- FileTest.stubs(:exists?).returns(true)
- @config.file_path("/one")
- end
-
- it "should treat a name with a trailing slash equivalently to a name with no trailing slash" do
- @parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file).with(nil, {})
- FileTest.stubs(:exists?).returns(true)
- @config.file_path("/one/")
- end
-
- it "should return nil if the mount cannot be found" do
- @parser.expects(:changed?).returns(true)
- @parser.expects(:parse).returns({})
- @config.file_path("/one/something").should be_nil
- end
-
- it "should return nil if the mount does not contain the file" do
- @parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file).with("something/else", {}).returns(nil)
- @config.file_path("/one/something/else").should be_nil
- end
-
- it "should return the fully qualified path if the mount exists" do
- @parser.expects(:parse).returns(@mounts)
- @mount1.expects(:file).with("something/else", {}).returns("/full/path")
- @config.file_path("/one/something/else").should == "/full/path"
- end
-
- it "should reparse the configuration file when it has changed" do
- @mount1.stubs(:file).returns("whatever")
- @parser.expects(:changed?).returns(true)
- @parser.expects(:parse).returns(@mounts)
- FileTest.stubs(:exists?).returns(true)
- @config.file_path("/one/something")
-
- @parser.expects(:changed?).returns(true)
- @parser.expects(:parse).returns({})
- @config.file_path("/one/something").should be_nil
- end
-end
-
-describe Puppet::FileServing::Configuration, " when checking authorization" do
- include FSConfigurationTesting
-
- before do
- @parser = mock 'parser'
- @parser.stubs(:changed?).returns true
- FileTest.stubs(:exists?).with(@path).returns(true)
- Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
-
- @mount1 = stub 'mount', :name => "one"
- @mounts = {"one" => @mount1}
- @parser.stubs(:parse).returns(@mounts)
-
- Facter.stubs(:value).with("hostname").returns("whatever")
-
- @config = Puppet::FileServing::Configuration.create
- end
-
- it "should return false if the mount cannot be found" do
- @config.authorized?("/nope/my/file").should be_false
- end
-
- it "should use the mount to determine authorization" do
- @mount1.expects(:allowed?)
- @config.authorized?("/one/my/file")
- end
-
- it "should pass the client's name to the mount if provided" do
- @mount1.expects(:allowed?).with("myhost", nil)
- @config.authorized?("/one/my/file", :node => "myhost")
- end
+describe Puppet::FileServing::Configuration do
- it "should pass the client's IP to the mount if provided" do
- @mount1.expects(:allowed?).with("myhost", "myip")
- @config.authorized?("/one/my/file", :node => "myhost", :ipaddress => "myip")
+ before :each do
+ @path = "/path/to/configuration/file.conf"
+ Puppet.settings.stubs(:value).with(:fileserverconfig).returns(@path)
end
- it "should return true if the mount allows the client" do
- @mount1.expects(:allowed?).returns(true)
- @config.authorized?("/one/my/file").should be_true
+ after :each do
+ Puppet::FileServing::Configuration.clear_cache
end
- it "should return false if the mount denies the client" do
- @mount1.expects(:allowed?).returns(false)
- @config.authorized?("/one/my/file").should be_false
- end
-end
+ describe Puppet::FileServing::Configuration, " when initializing" do
+
+ it "should work without a configuration file" do
+ FileTest.stubs(:exists?).with(@path).returns(false)
+ proc { Puppet::FileServing::Configuration.create }.should_not raise_error
+ end
+
+ it "should parse the configuration file if present" do
+ FileTest.stubs(:exists?).with(@path).returns(true)
+ @parser = mock 'parser'
+ @parser.expects(:parse).returns({})
+ Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+ Puppet::FileServing::Configuration.create
+ end
+
+ it "should determine the path to the configuration file from the Puppet settings" do
+ Puppet::FileServing::Configuration.create
+ end
+ end
+
+ describe Puppet::FileServing::Configuration, " when parsing the configuration file" do
+
+ before do
+ FileTest.stubs(:exists?).with(@path).returns(true)
+ @parser = mock 'parser'
+ Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+ end
+
+ it "should set the mount list to the results of parsing" do
+ @parser.expects(:parse).returns("one" => mock("mount"))
+ config = Puppet::FileServing::Configuration.create
+ config.mounted?("one").should be_true
+ end
+
+ it "should not raise exceptions" do
+ @parser.expects(:parse).raises(ArgumentError)
+ proc { Puppet::FileServing::Configuration.create }.should_not raise_error
+ end
+
+ it "should replace the existing mount list with the results of reparsing" do
+ @parser.expects(:parse).returns("one" => mock("mount"))
+ config = Puppet::FileServing::Configuration.create
+ config.mounted?("one").should be_true
+ # Now parse again
+ @parser.expects(:parse).returns("two" => mock('other'))
+ config.send(:readconfig, false)
+ config.mounted?("one").should be_false
+ config.mounted?("two").should be_true
+ end
+
+ it "should not replace the mount list until the file is entirely parsed successfully" do
+ @parser.expects(:parse).returns("one" => mock("mount"))
+ @parser.expects(:parse).raises(ArgumentError)
+ config = Puppet::FileServing::Configuration.create
+ # Now parse again, so the exception gets thrown
+ config.send(:readconfig, false)
+ config.mounted?("one").should be_true
+ end
+ end
+
+ describe Puppet::FileServing::Configuration, " when finding files" do
+
+ before do
+ @parser = mock 'parser'
+ @parser.stubs(:changed?).returns true
+ FileTest.stubs(:exists?).with(@path).returns(true)
+ Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+
+ @mount1 = stub 'mount', :name => "one"
+ @mounts = {"one" => @mount1}
+
+ Facter.stubs(:value).with("hostname").returns("whatever")
+
+ @config = Puppet::FileServing::Configuration.create
+ end
+
+ it "should fail if the uri does not match a leading slash followed by a valid mount name" do
+ @parser.expects(:parse).returns(@mounts)
+ proc { @config.file_path("something") }.should raise_error(ArgumentError)
+ end
+
+ it "should use the first term after the first slash for the mount name" do
+ @parser.expects(:parse).returns(@mounts)
+ FileTest.stubs(:exists?).returns(true)
+ @mount1.expects(:file)
+ @config.file_path("/one")
+ end
+
+ it "should use the remainder of the URI after the mount name as the file name" do
+ @parser.expects(:parse).returns(@mounts)
+ @mount1.expects(:file).with("something/else", {})
+ FileTest.stubs(:exists?).returns(true)
+ @config.file_path("/one/something/else")
+ end
+
+ it "should treat a bare name as a mount and no relative file" do
+ @parser.expects(:parse).returns(@mounts)
+ @mount1.expects(:file).with(nil, {})
+ FileTest.stubs(:exists?).returns(true)
+ @config.file_path("/one")
+ end
+
+ it "should treat a name with a trailing slash equivalently to a name with no trailing slash" do
+ @parser.expects(:parse).returns(@mounts)
+ @mount1.expects(:file).with(nil, {})
+ FileTest.stubs(:exists?).returns(true)
+ @config.file_path("/one/")
+ end
+
+ it "should return nil if the mount cannot be found" do
+ @parser.expects(:changed?).returns(true)
+ @parser.expects(:parse).returns({})
+ @config.file_path("/one/something").should be_nil
+ end
+
+ it "should return nil if the mount does not contain the file" do
+ @parser.expects(:parse).returns(@mounts)
+ @mount1.expects(:file).with("something/else", {}).returns(nil)
+ @config.file_path("/one/something/else").should be_nil
+ end
+
+ it "should return the fully qualified path if the mount exists" do
+ @parser.expects(:parse).returns(@mounts)
+ @mount1.expects(:file).with("something/else", {}).returns("/full/path")
+ @config.file_path("/one/something/else").should == "/full/path"
+ end
+
+ it "should reparse the configuration file when it has changed" do
+ @mount1.stubs(:file).returns("whatever")
+ @parser.expects(:changed?).returns(true)
+ @parser.expects(:parse).returns(@mounts)
+ FileTest.stubs(:exists?).returns(true)
+ @config.file_path("/one/something")
+
+ @parser.expects(:changed?).returns(true)
+ @parser.expects(:parse).returns({})
+ @config.file_path("/one/something").should be_nil
+ end
+ end
+
+ describe Puppet::FileServing::Configuration, " when checking authorization" do
+
+ before do
+ @parser = mock 'parser'
+ @parser.stubs(:changed?).returns true
+ FileTest.stubs(:exists?).with(@path).returns(true)
+ Puppet::FileServing::Configuration::Parser.stubs(:new).returns(@parser)
+
+ @mount1 = stub 'mount', :name => "one"
+ @mounts = {"one" => @mount1}
+ @parser.stubs(:parse).returns(@mounts)
+
+ Facter.stubs(:value).with("hostname").returns("whatever")
+
+ @config = Puppet::FileServing::Configuration.create
+ end
+
+ it "should return false if the mount cannot be found" do
+ @config.authorized?("/nope/my/file").should be_false
+ end
+
+ it "should use the mount to determine authorization" do
+ @mount1.expects(:allowed?)
+ @config.authorized?("/one/my/file")
+ end
+
+ it "should pass the client's name to the mount if provided" do
+ @mount1.expects(:allowed?).with("myhost", nil)
+ @config.authorized?("/one/my/file", :node => "myhost")
+ end
+
+ it "should pass the client's IP to the mount if provided" do
+ @mount1.expects(:allowed?).with("myhost", "myip")
+ @config.authorized?("/one/my/file", :node => "myhost", :ipaddress => "myip")
+ end
+
+ it "should return true if the mount allows the client" do
+ @mount1.expects(:allowed?).returns(true)
+ @config.authorized?("/one/my/file").should be_true
+ end
+
+ it "should return false if the mount denies the client" do
+ @mount1.expects(:allowed?).returns(false)
+ @config.authorized?("/one/my/file").should be_false
+ end
+ end
+end \ No newline at end of file
diff --git a/spec/unit/file_serving/configuration/parser.rb b/spec/unit/file_serving/configuration/parser.rb
index aa296cf43..df2f629d5 100755
--- a/spec/unit/file_serving/configuration/parser.rb
+++ b/spec/unit/file_serving/configuration/parser.rb
@@ -10,8 +10,17 @@ describe Puppet::FileServing::Configuration::Parser do
end
end
+
module FSConfigurationParserTesting
- def setup
+ def mock_file_content(content)
+ # We want an array, but we actually want our carriage returns on all of it.
+ lines = content.split("\n").collect { |l| l + "\n" }
+ @filehandle.stubs(:each).multiple_yields(*lines)
+ end
+end
+
+describe Puppet::FileServing::Configuration::Parser do
+ before :each do
@path = "/my/config.conf"
FileTest.stubs(:exists?).with(@path).returns(true)
FileTest.stubs(:readable?).with(@path).returns(true)
@@ -20,113 +29,107 @@ module FSConfigurationParserTesting
@parser = Puppet::FileServing::Configuration::Parser.new(@path)
end
- def mock_file_content(content)
- # We want an array, but we actually want our carriage returns on all of it.
- lines = content.split("\n").collect { |l| l + "\n" }
- @filehandle.stubs(:each).multiple_yields(*lines)
- end
-end
-
-describe Puppet::FileServing::Configuration::Parser, " when parsing" do
- include FSConfigurationParserTesting
+ describe Puppet::FileServing::Configuration::Parser, " when parsing" do
+ include FSConfigurationParserTesting
- before do
- @parser.stubs(:add_modules_mount)
- end
+ before do
+ @parser.stubs(:add_modules_mount)
+ end
- it "should allow comments" do
- @filehandle.expects(:each).yields("# this is a comment\n")
- proc { @parser.parse }.should_not raise_error
- end
+ it "should allow comments" do
+ @filehandle.expects(:each).yields("# this is a comment\n")
+ proc { @parser.parse }.should_not raise_error
+ end
- it "should allow blank lines" do
- @filehandle.expects(:each).yields("\n")
- proc { @parser.parse }.should_not raise_error
- end
+ it "should allow blank lines" do
+ @filehandle.expects(:each).yields("\n")
+ proc { @parser.parse }.should_not raise_error
+ end
- it "should create a new mount for each section in the configuration" do
- mount1 = mock 'one'
- mount2 = mock 'two'
- Puppet::FileServing::Mount.expects(:new).with("one").returns(mount1)
- Puppet::FileServing::Mount.expects(:new).with("two").returns(mount2)
- mock_file_content "[one]\n[two]\n"
- @parser.parse
- end
+ it "should create a new mount for each section in the configuration" do
+ mount1 = mock 'one'
+ mount2 = mock 'two'
+ Puppet::FileServing::Mount.expects(:new).with("one").returns(mount1)
+ Puppet::FileServing::Mount.expects(:new).with("two").returns(mount2)
+ mock_file_content "[one]\n[two]\n"
+ @parser.parse
+ end
- # This test is almost the exact same as the previous one.
- it "should return a hash of the created mounts" do
- mount1 = mock 'one'
- mount2 = mock 'two'
- Puppet::FileServing::Mount.expects(:new).with("one").returns(mount1)
- Puppet::FileServing::Mount.expects(:new).with("two").returns(mount2)
- mock_file_content "[one]\n[two]\n"
+ # This test is almost the exact same as the previous one.
+ it "should return a hash of the created mounts" do
+ mount1 = mock 'one'
+ mount2 = mock 'two'
+ Puppet::FileServing::Mount.expects(:new).with("one").returns(mount1)
+ Puppet::FileServing::Mount.expects(:new).with("two").returns(mount2)
+ mock_file_content "[one]\n[two]\n"
- @parser.parse.should == {"one" => mount1, "two" => mount2}
- end
+ @parser.parse.should == {"one" => mount1, "two" => mount2}
+ end
- it "should only allow mount names that are alphanumeric plus dashes" do
- mock_file_content "[a*b]\n"
- proc { @parser.parse }.should raise_error(ArgumentError)
- end
+ it "should only allow mount names that are alphanumeric plus dashes" do
+ mock_file_content "[a*b]\n"
+ proc { @parser.parse }.should raise_error(ArgumentError)
+ end
- it "should fail if the value for path/allow/deny starts with an equals sign" do
- mock_file_content "[one]\npath = /testing"
- proc { @parser.parse }.should raise_error(ArgumentError)
+ it "should fail if the value for path/allow/deny starts with an equals sign" do
+ mock_file_content "[one]\npath = /testing"
+ proc { @parser.parse }.should raise_error(ArgumentError)
+ end
end
-end
-describe Puppet::FileServing::Configuration::Parser, " when parsing mount attributes" do
- include FSConfigurationParserTesting
+ describe Puppet::FileServing::Configuration::Parser, " when parsing mount attributes" do
+ include FSConfigurationParserTesting
- before do
- @mount = stub 'mount', :name => "one"
- Puppet::FileServing::Mount.expects(:new).with("one").returns(@mount)
- @parser.stubs(:add_modules_mount)
- end
+ before do
+ @mount = stub 'mount', :name => "one"
+ Puppet::FileServing::Mount.expects(:new).with("one").returns(@mount)
+ @parser.stubs(:add_modules_mount)
+ end
- it "should set the mount path to the path attribute from that section" do
- mock_file_content "[one]\npath /some/path\n"
+ it "should set the mount path to the path attribute from that section" do
+ mock_file_content "[one]\npath /some/path\n"
- @mount.expects(:path=).with("/some/path")
- @parser.parse
- end
+ @mount.expects(:path=).with("/some/path")
+ @parser.parse
+ end
- it "should tell the mount to allow any allow values from the section" do
- mock_file_content "[one]\nallow something\n"
+ it "should tell the mount to allow any allow values from the section" do
+ mock_file_content "[one]\nallow something\n"
- @mount.expects(:info)
- @mount.expects(:allow).with("something")
- @parser.parse
- end
+ @mount.expects(:info)
+ @mount.expects(:allow).with("something")
+ @parser.parse
+ end
- it "should tell the mount to deny any deny values from the section" do
- mock_file_content "[one]\ndeny something\n"
+ it "should tell the mount to deny any deny values from the section" do
+ mock_file_content "[one]\ndeny something\n"
- @mount.expects(:info)
- @mount.expects(:deny).with("something")
- @parser.parse
- end
+ @mount.expects(:info)
+ @mount.expects(:deny).with("something")
+ @parser.parse
+ end
- it "should fail on any attributes other than path, allow, and deny" do
- mock_file_content "[one]\ndo something\n"
+ it "should fail on any attributes other than path, allow, and deny" do
+ mock_file_content "[one]\ndo something\n"
- proc { @parser.parse }.should raise_error(ArgumentError)
+ proc { @parser.parse }.should raise_error(ArgumentError)
+ end
end
-end
-describe Puppet::FileServing::Configuration::Parser, " when parsing the modules mount" do
- include FSConfigurationParserTesting
+ describe Puppet::FileServing::Configuration::Parser, " when parsing the modules mount" do
+ include FSConfigurationParserTesting
- before do
- @mount = stub 'mount', :name => "modules"
- Puppet::FileServing::Mount.expects(:new).with("modules").returns(@mount)
- end
+ before do
+ @mount = stub 'mount', :name => "modules"
+ Puppet::FileServing::Mount.expects(:new).with("modules").returns(@mount)
+ end
- it "should warn if a path is set" do
- mock_file_content "[modules]\npath /some/path\n"
+ it "should warn if a path is set" do
+ mock_file_content "[modules]\npath /some/path\n"
- @modules.expects(:path=).never
- Puppet.expects(:warning)
- @parser.parse
+ @modules.expects(:path=).never
+ Puppet.expects(:warning)
+ @parser.parse
+ end
end
-end
+end \ No newline at end of file
diff --git a/spec/unit/file_serving/file_base.rb b/spec/unit/file_serving/file_base.rb
index 4c7724f7c..ded6ae4a8 100755
--- a/spec/unit/file_serving/file_base.rb
+++ b/spec/unit/file_serving/file_base.rb
@@ -4,7 +4,7 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/file_serving/file_base'
-describe Puppet::FileServing::FileBase, " when initializing" do
+describe Puppet::FileServing::FileBase do
it "should accept a key in the form of a URI" do
Puppet::FileServing::FileBase.new("puppet://host/module/dir/file").key.should == "puppet://host/module/dir/file"
end
@@ -13,7 +13,11 @@ describe Puppet::FileServing::FileBase, " when initializing" do
Puppet::FileServing::FileBase.new("puppet://host/module/dir/file", :links => :manage).links.should == :manage
end
- it "should fail if :links is set to anything other than :manage or :follow" do
+ it "should consider :ignore links equivalent to :manage links" do
+ Puppet::FileServing::FileBase.new("puppet://host/module/dir/file", :links => :ignore).links.should == :manage
+ end
+
+ it "should fail if :links is set to anything other than :manage, :follow, or :ignore" do
proc { Puppet::FileServing::FileBase.new("puppet://host/module/dir/file", :links => :else) }.should raise_error(ArgumentError)
end
@@ -30,72 +34,91 @@ describe Puppet::FileServing::FileBase, " when initializing" do
FileTest.stubs(:exists?).returns(true)
Puppet::FileServing::FileBase.new("puppet://host/module/dir/file", :relative_path => "my/file").relative_path.should == "my/file"
end
-end
-describe Puppet::FileServing::FileBase, " when setting the base path" do
- before do
- @file = Puppet::FileServing::FileBase.new("puppet://host/module/dir/file")
+ it "should have a means of determining if the file exists" do
+ Puppet::FileServing::FileBase.new("blah").should respond_to(:exist?)
end
- it "should require that the base path be fully qualified" do
- FileTest.stubs(:exists?).returns(true)
- proc { @file.path = "unqualified/file" }.should raise_error(ArgumentError)
+ it "should correctly indicate if the file is present" do
+ File.expects(:lstat).with("/my/file").returns(mock("stat"))
+ Puppet::FileServing::FileBase.new("blah", :path => "/my/file").exist?.should be_true
end
-end
-describe Puppet::FileServing::FileBase, " when setting the relative path" do
- it "should require that the relative path be unqualified" do
- @file = Puppet::FileServing::FileBase.new("puppet://host/module/dir/file")
- FileTest.stubs(:exists?).returns(true)
- proc { @file.relative_path = "/qualified/file" }.should raise_error(ArgumentError)
+ it "should correctly indicate if the file is asbsent" do
+ File.expects(:lstat).with("/my/file").raises RuntimeError
+ Puppet::FileServing::FileBase.new("blah", :path => "/my/file").exist?.should be_false
end
-end
-describe Puppet::FileServing::FileBase, " when determining the full file path" do
- before do
- @file = Puppet::FileServing::FileBase.new("mykey", :path => "/this/file")
- end
+ describe "when setting the base path" do
+ before do
+ @file = Puppet::FileServing::FileBase.new("puppet://host/module/dir/file")
+ end
- it "should return the path if there is no relative path" do
- @file.full_path.should == "/this/file"
+ it "should require that the base path be fully qualified" do
+ FileTest.stubs(:exists?).returns(true)
+ proc { @file.path = "unqualified/file" }.should raise_error(ArgumentError)
+ end
end
- it "should return the path joined with the relative path if there is a relative path" do
- @file.relative_path = "not/qualified"
- @file.full_path.should == "/this/file/not/qualified"
+ describe "when setting the relative path" do
+ it "should require that the relative path be unqualified" do
+ @file = Puppet::FileServing::FileBase.new("puppet://host/module/dir/file")
+ FileTest.stubs(:exists?).returns(true)
+ proc { @file.relative_path = "/qualified/file" }.should raise_error(ArgumentError)
+ end
end
- it "should should fail if there is no path set" do
- @file = Puppet::FileServing::FileBase.new("not/qualified")
- proc { @file.full_path }.should raise_error(ArgumentError)
- end
-end
+ describe "when determining the full file path" do
+ before do
+ @file = Puppet::FileServing::FileBase.new("mykey", :path => "/this/file")
+ end
-describe Puppet::FileServing::FileBase, " when stat'ing files" do
- before do
- @file = Puppet::FileServing::FileBase.new("mykey", :path => "/this/file")
- end
+ it "should return the path if there is no relative path" do
+ @file.full_path.should == "/this/file"
+ end
- it "should stat the file's full path" do
- @file.stubs(:full_path).returns("/this/file")
- File.expects(:lstat).with("/this/file").returns stub("stat", :ftype => "file")
- @file.stat
- end
+ it "should return the path if the relative_path is set to ''" do
+ @file.relative_path = ""
+ @file.full_path.should == "/this/file"
+ end
- it "should fail if the file does not exist" do
- @file.stubs(:full_path).returns("/this/file")
- File.expects(:lstat).with("/this/file").raises(Errno::ENOENT)
- proc { @file.stat }.should raise_error(Errno::ENOENT)
- end
+ it "should return the path joined with the relative path if there is a relative path and it is not set to '/' or ''" do
+ @file.relative_path = "not/qualified"
+ @file.full_path.should == "/this/file/not/qualified"
+ end
- it "should use :lstat if :links is set to :manage" do
- File.expects(:lstat).with("/this/file").returns stub("stat", :ftype => "file")
- @file.stat
+ it "should should fail if there is no path set" do
+ @file = Puppet::FileServing::FileBase.new("not/qualified")
+ proc { @file.full_path }.should raise_error(ArgumentError)
+ end
end
- it "should use :stat if :links is set to :follow" do
- File.expects(:stat).with("/this/file").returns stub("stat", :ftype => "file")
- @file.links = :follow
- @file.stat
+ describe "when stat'ing files" do
+ before do
+ @file = Puppet::FileServing::FileBase.new("mykey", :path => "/this/file")
+ end
+
+ it "should stat the file's full path" do
+ @file.stubs(:full_path).returns("/this/file")
+ File.expects(:lstat).with("/this/file").returns stub("stat", :ftype => "file")
+ @file.stat
+ end
+
+ it "should fail if the file does not exist" do
+ @file.stubs(:full_path).returns("/this/file")
+ File.expects(:lstat).with("/this/file").raises(Errno::ENOENT)
+ proc { @file.stat }.should raise_error(Errno::ENOENT)
+ end
+
+ it "should use :lstat if :links is set to :manage" do
+ File.expects(:lstat).with("/this/file").returns stub("stat", :ftype => "file")
+ @file.stat
+ end
+
+ it "should use :stat if :links is set to :follow" do
+ File.expects(:stat).with("/this/file").returns stub("stat", :ftype => "file")
+ @file.links = :follow
+ @file.stat
+ end
end
end
diff --git a/spec/unit/file_serving/metadata.rb b/spec/unit/file_serving/metadata.rb
index f7ab0c8d6..9743370c1 100755
--- a/spec/unit/file_serving/metadata.rb
+++ b/spec/unit/file_serving/metadata.rb
@@ -26,8 +26,8 @@ describe Puppet::FileServing::Metadata, " when finding the file to use for setti
@metadata.path = @full
- # Use a symlink because it's easier to test -- no checksumming
- @stat = stub "stat", :uid => 10, :gid => 20, :mode => 0755, :ftype => "symlink"
+ # Use a link because it's easier to test -- no checksumming
+ @stat = stub "stat", :uid => 10, :gid => 20, :mode => 0755, :ftype => "link"
end
it "should accept a base path path to which the file should be relative" do
@@ -55,16 +55,19 @@ end
describe Puppet::FileServing::Metadata, " when collecting attributes" do
before do
@path = "/my/file"
- @stat = stub 'stat', :uid => 10, :gid => 20, :mode => 0755, :ftype => "file"
+ # Use a real file mode, so we can validate the masking is done.
+ @stat = stub 'stat', :uid => 10, :gid => 20, :mode => 33261, :ftype => "file"
File.stubs(:lstat).returns(@stat)
- @filehandle = mock 'filehandle'
- @filehandle.expects(:each_line).yields("some content\n")
- File.stubs(:open).with(@path, 'r').yields(@filehandle)
@checksum = Digest::MD5.hexdigest("some content\n")
@metadata = Puppet::FileServing::Metadata.new("file", :path => "/my/file")
+ @metadata.stubs(:md5_file).returns(@checksum)
@metadata.collect_attributes
end
+ it "should be able to produce xmlrpc-style attribute information" do
+ @metadata.should respond_to(:attributes_with_tabs)
+ end
+
# LAK:FIXME This should actually change at some point
it "should set the owner by id" do
@metadata.owner.should be_instance_of(Fixnum)
@@ -83,28 +86,63 @@ describe Puppet::FileServing::Metadata, " when collecting attributes" do
@metadata.group.should == 20
end
- it "should set the mode to a string version of the mode in octal" do
- @metadata.mode.should == "755"
- end
-
- it "should set the mode to the file's current mode" do
- @metadata.mode.should == "755"
+ it "should set the mode to the file's masked mode" do
+ @metadata.mode.should == 0755
end
it "should set the checksum to the file's current checksum" do
@metadata.checksum.should == "{md5}" + @checksum
end
- it "should default to a checksum of type MD5" do
- @metadata.checksum.should == "{md5}" + @checksum
+ describe "when managing files" do
+ it "should default to a checksum of type MD5" do
+ @metadata.checksum.should == "{md5}" + @checksum
+ end
+
+ it "should produce tab-separated mode, type, owner, group, and checksum for xmlrpc" do
+ @metadata.attributes_with_tabs.should == "#{0755.to_s}\tfile\t10\t20\t{md5}#{@checksum}"
+ end
+ end
+
+ describe "when managing directories" do
+ before do
+ @stat.stubs(:ftype).returns("directory")
+ @time = Time.now
+ @metadata.expects(:ctime_file).returns(@time)
+ @metadata.collect_attributes
+ end
+
+ it "should only use checksums of type 'ctime' for directories" do
+ @metadata.checksum.should == "{ctime}" + @time.to_s
+ end
+
+ it "should produce tab-separated mode, type, owner, group, and checksum for xmlrpc" do
+ @metadata.attributes_with_tabs.should == "#{0755.to_s}\tdirectory\t10\t20\t{ctime}#{@time.to_s}"
+ end
+ end
+
+ describe "when managing links" do
+ before do
+ @stat.stubs(:ftype).returns("link")
+ File.expects(:readlink).with("/my/file").returns("/path/to/link")
+ @metadata.collect_attributes
+ end
+
+ it "should read links instead of returning their checksums" do
+ @metadata.destination.should == "/path/to/link"
+ end
+
+ it "should produce tab-separated mode, type, owner, group, and destination for xmlrpc" do
+ @metadata.attributes_with_tabs.should == "#{0755.to_s}\tlink\t10\t20\t/path/to/link"
+ end
end
end
-describe Puppet::FileServing::Metadata, " when pointing to a symlink" do
- it "should store the destination of the symlink in :destination if links are :manage" do
+describe Puppet::FileServing::Metadata, " when pointing to a link" do
+ it "should store the destination of the link in :destination if links are :manage" do
file = Puppet::FileServing::Metadata.new("mykey", :links => :manage, :path => "/base/path/my/file")
- File.expects(:lstat).with("/base/path/my/file").returns stub("stat", :uid => 1, :gid => 2, :ftype => "symlink", :mode => 0755)
+ File.expects(:lstat).with("/base/path/my/file").returns stub("stat", :uid => 1, :gid => 2, :ftype => "link", :mode => 0755)
File.expects(:readlink).with("/base/path/my/file").returns "/some/other/path"
file.collect_attributes
@@ -114,7 +152,7 @@ describe Puppet::FileServing::Metadata, " when pointing to a symlink" do
it "should not collect the checksum" do
file = Puppet::FileServing::Metadata.new("my/file", :links => :manage, :path => "/base/path/my/file")
- File.expects(:lstat).with("/base/path/my/file").returns stub("stat", :uid => 1, :gid => 2, :ftype => "symlink", :mode => 0755)
+ File.expects(:lstat).with("/base/path/my/file").returns stub("stat", :uid => 1, :gid => 2, :ftype => "link", :mode => 0755)
File.expects(:readlink).with("/base/path/my/file").returns "/some/other/path"
file.collect_attributes
diff --git a/spec/unit/indirector/catalog/compiler.rb b/spec/unit/indirector/catalog/compiler.rb
index 77638a410..a4a0acd58 100755
--- a/spec/unit/indirector/catalog/compiler.rb
+++ b/spec/unit/indirector/catalog/compiler.rb
@@ -171,7 +171,7 @@ describe Puppet::Node::Catalog::Compiler, " when determining a client's availabl
end
it "should use the client's Facts version as the available catalog version if it is the most recent" do
- Puppet::Node::Facts.expects(:version).with(@name).returns(5)
+ Puppet::Node::Facts.stubs(:version).with(@name).returns(5)
Puppet::Node.expects(:version).with(@name).returns(3)
@catalog.interpreter.stubs(:catalog_version).returns(4)
@@ -179,7 +179,7 @@ describe Puppet::Node::Catalog::Compiler, " when determining a client's availabl
end
it "should use the client's Node version as the available catalog version if it is the most recent" do
- Puppet::Node::Facts.expects(:version).with(@name).returns(3)
+ Puppet::Node::Facts.stubs(:version).with(@name).returns(3)
Puppet::Node.expects(:version).with(@name).returns(5)
@catalog.interpreter.stubs(:catalog_version).returns(4)
@@ -187,7 +187,7 @@ describe Puppet::Node::Catalog::Compiler, " when determining a client's availabl
end
it "should use the last parse date as the available catalog version if it is the most recent" do
- Puppet::Node::Facts.expects(:version).with(@name).returns(3)
+ Puppet::Node::Facts.stubs(:version).with(@name).returns(3)
Puppet::Node.expects(:version).with(@name).returns(4)
@catalog.interpreter.stubs(:catalog_version).returns(5)
diff --git a/spec/unit/indirector/checksum/file.rb b/spec/unit/indirector/checksum/file.rb
index 82319fa40..4f8ee98b2 100755
--- a/spec/unit/indirector/checksum/file.rb
+++ b/spec/unit/indirector/checksum/file.rb
@@ -7,22 +7,6 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/checksum/file'
-module FileChecksumTesting
- def setup
- Puppet.settings.stubs(:use)
- @store = Puppet::Checksum::File.new
-
- @value = "70924d6fa4b2d745185fa4660703a5c0"
- @sum = stub 'sum', :name => @value
-
- @dir = "/what/ever"
-
- Puppet.stubs(:[]).with(:bucketdir).returns(@dir)
-
- @path = @store.path(@value)
- end
-end
-
describe Puppet::Checksum::File do
it "should be a subclass of the File terminus class" do
Puppet::Checksum::File.superclass.should equal(Puppet::Indirector::File)
@@ -40,103 +24,117 @@ describe Puppet::Checksum::File, " when initializing" do
end
end
-describe Puppet::Checksum::File, " when determining file paths" do
- include FileChecksumTesting
- # I was previously passing the object in.
- it "should use the value passed in to path() as the checksum" do
- @value.expects(:name).never
- @store.path(@value)
- end
+describe Puppet::Checksum::File do
+ before :each do
+ Puppet.settings.stubs(:use)
+ @store = Puppet::Checksum::File.new
- it "should use the value of the :bucketdir setting as the root directory" do
- @path.should =~ %r{^#{@dir}}
- end
+ @value = "70924d6fa4b2d745185fa4660703a5c0"
+ @sum = stub 'sum', :name => @value
- it "should choose a path 8 directories deep with each directory name being the respective character in the checksum" do
- dirs = @value[0..7].split("").join(File::SEPARATOR)
- @path.should be_include(dirs)
- end
+ @dir = "/what/ever"
- it "should use the full checksum as the final directory name" do
- File.basename(File.dirname(@path)).should == @value
- end
+ Puppet.stubs(:[]).with(:bucketdir).returns(@dir)
- it "should use 'contents' as the actual file name" do
- File.basename(@path).should == "contents"
+ @path = @store.path(@value)
end
- it "should use the bucketdir, the 8 sum character directories, the full checksum, and 'contents' as the full file name" do
- @path.should == [@dir, @value[0..7].split(""), @value, "contents"].flatten.join(File::SEPARATOR)
- end
-end
-describe Puppet::Checksum::File, " when retrieving files" do
- include FileChecksumTesting
+ describe Puppet::Checksum::File, " when determining file paths" do
- # The smallest test that will use the calculated path
- it "should look for the calculated path" do
- File.expects(:exist?).with(@path).returns(false)
- @store.find(@value)
- end
+ # I was previously passing the object in.
+ it "should use the value passed in to path() as the checksum" do
+ @value.expects(:name).never
+ @store.path(@value)
+ end
- it "should return an instance of Puppet::Checksum created with the content if the file exists" do
- content = "my content"
- sum = stub 'file'
- Puppet::Checksum.expects(:new).with(content).returns(sum)
+ it "should use the value of the :bucketdir setting as the root directory" do
+ @path.should =~ %r{^#{@dir}}
+ end
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:read).with(@path).returns(content)
+ it "should choose a path 8 directories deep with each directory name being the respective character in the checksum" do
+ dirs = @value[0..7].split("").join(File::SEPARATOR)
+ @path.should be_include(dirs)
+ end
- @store.find(@value).should equal(sum)
- end
+ it "should use the full checksum as the final directory name" do
+ File.basename(File.dirname(@path)).should == @value
+ end
- it "should return nil if no file is found" do
- File.expects(:exist?).with(@path).returns(false)
- @store.find(@value).should be_nil
- end
+ it "should use 'contents' as the actual file name" do
+ File.basename(@path).should == "contents"
+ end
- it "should fail intelligently if a found file cannot be read" do
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:read).with(@path).raises(RuntimeError)
- proc { @store.find(@value) }.should raise_error(Puppet::Error)
+ it "should use the bucketdir, the 8 sum character directories, the full checksum, and 'contents' as the full file name" do
+ @path.should == [@dir, @value[0..7].split(""), @value, "contents"].flatten.join(File::SEPARATOR)
+ end
end
-end
-describe Puppet::Checksum::File, " when saving files" do
- include FileChecksumTesting
+ describe Puppet::Checksum::File, " when retrieving files" do
+
+ # The smallest test that will use the calculated path
+ it "should look for the calculated path" do
+ File.expects(:exist?).with(@path).returns(false)
+ @store.find(@value)
+ end
+
+ it "should return an instance of Puppet::Checksum created with the content if the file exists" do
+ content = "my content"
+ sum = stub 'file'
+ Puppet::Checksum.expects(:new).with(content).returns(sum)
+
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:read).with(@path).returns(content)
- # LAK:FIXME I don't know how to include in the spec the fact that we're
- # using the superclass's save() method and thus are acquiring all of
- # it's behaviours.
- it "should save the content to the calculated path" do
- File.stubs(:directory?).with(File.dirname(@path)).returns(true)
- File.expects(:open).with(@path, "w")
+ @store.find(@value).should equal(sum)
+ end
- file = stub 'file', :name => @value
- @store.save(file)
+ it "should return nil if no file is found" do
+ File.expects(:exist?).with(@path).returns(false)
+ @store.find(@value).should be_nil
+ end
+
+ it "should fail intelligently if a found file cannot be read" do
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:read).with(@path).raises(RuntimeError)
+ proc { @store.find(@value) }.should raise_error(Puppet::Error)
+ end
end
- it "should make any directories necessary for storage" do
- FileUtils.expects(:mkdir_p).with do |arg|
- File.umask == 0007 and arg == File.dirname(@path)
+ describe Puppet::Checksum::File, " when saving files" do
+
+ # LAK:FIXME I don't know how to include in the spec the fact that we're
+ # using the superclass's save() method and thus are acquiring all of
+ # it's behaviours.
+ it "should save the content to the calculated path" do
+ File.stubs(:directory?).with(File.dirname(@path)).returns(true)
+ File.expects(:open).with(@path, "w")
+
+ file = stub 'file', :name => @value
+ @store.save(file)
end
- File.expects(:directory?).with(File.dirname(@path)).returns(true)
- File.expects(:open).with(@path, "w")
- file = stub 'file', :name => @value
- @store.save(file)
+ it "should make any directories necessary for storage" do
+ FileUtils.expects(:mkdir_p).with do |arg|
+ File.umask == 0007 and arg == File.dirname(@path)
+ end
+ File.expects(:directory?).with(File.dirname(@path)).returns(true)
+ File.expects(:open).with(@path, "w")
+
+ file = stub 'file', :name => @value
+ @store.save(file)
+ end
end
-end
-describe Puppet::Checksum::File, " when deleting files" do
- include FileChecksumTesting
+ describe Puppet::Checksum::File, " when deleting files" do
- it "should remove the file at the calculated path" do
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:unlink).with(@path)
+ it "should remove the file at the calculated path" do
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:unlink).with(@path)
- file = stub 'file', :name => @value
- @store.destroy(file)
+ file = stub 'file', :name => @value
+ @store.destroy(file)
+ end
end
-end
+end \ No newline at end of file
diff --git a/spec/unit/indirector/direct_file_server.rb b/spec/unit/indirector/direct_file_server.rb
index 2a8ec1a49..9f3652536 100755
--- a/spec/unit/indirector/direct_file_server.rb
+++ b/spec/unit/indirector/direct_file_server.rb
@@ -7,8 +7,8 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/direct_file_server'
-module DirectFileServerTerminusTesting
- def setup
+describe Puppet::Indirector::DirectFileServer do
+ before :each do
Puppet::Indirector::Terminus.stubs(:register_terminus_class)
@model = mock 'model'
@indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
@@ -24,72 +24,69 @@ module DirectFileServerTerminusTesting
@uri = "file:///my/local"
end
-end
-describe Puppet::Indirector::DirectFileServer, "when finding a single file" do
- include DirectFileServerTerminusTesting
+ describe Puppet::Indirector::DirectFileServer, "when finding a single file" do
- it "should return nil if the file does not exist" do
- FileTest.expects(:exists?).with("/my/local").returns false
- @server.find(@uri).should be_nil
- end
+ it "should return nil if the file does not exist" do
+ FileTest.expects(:exists?).with("/my/local").returns false
+ @server.find(@uri).should be_nil
+ end
- it "should return a Content instance created with the full path to the file if the file exists" do
- FileTest.expects(:exists?).with("/my/local").returns true
- @model.expects(:new).returns(:mycontent)
- @server.find(@uri).should == :mycontent
+ it "should return a Content instance created with the full path to the file if the file exists" do
+ FileTest.expects(:exists?).with("/my/local").returns true
+ @model.expects(:new).returns(:mycontent)
+ @server.find(@uri).should == :mycontent
+ end
end
-end
-describe Puppet::Indirector::DirectFileServer, "when creating the instance for a single found file" do
- include DirectFileServerTerminusTesting
+ describe Puppet::Indirector::DirectFileServer, "when creating the instance for a single found file" do
- before do
- @data = mock 'content'
- @data.stubs(:collect_attributes)
- FileTest.expects(:exists?).with("/my/local").returns true
- end
+ before do
+ @data = mock 'content'
+ @data.stubs(:collect_attributes)
+ FileTest.expects(:exists?).with("/my/local").returns true
+ end
- it "should create the Content instance with the original key as the key" do
- @model.expects(:new).with { |key, options| key == @uri }.returns(@data)
- @server.find(@uri)
- end
+ it "should create the Content instance with the original key as the key" do
+ @model.expects(:new).with { |key, options| key == @uri }.returns(@data)
+ @server.find(@uri)
+ end
- it "should pass the full path to the instance" do
- @model.expects(:new).with { |key, options| options[:path] == "/my/local" }.returns(@data)
- @server.find(@uri)
- end
+ it "should pass the full path to the instance" do
+ @model.expects(:new).with { |key, options| options[:path] == "/my/local" }.returns(@data)
+ @server.find(@uri)
+ end
- it "should pass the :links setting on to the created Content instance if the file exists and there is a value for :links" do
- @model.expects(:new).returns(@data)
- @data.expects(:links=).with(:manage)
- @server.find(@uri, :links => :manage)
+ it "should pass the :links setting on to the created Content instance if the file exists and there is a value for :links" do
+ @model.expects(:new).returns(@data)
+ @data.expects(:links=).with(:manage)
+ @server.find(@uri, :links => :manage)
+ end
end
-end
-describe Puppet::Indirector::DirectFileServer, "when searching for multiple files" do
- include DirectFileServerTerminusTesting
+ describe Puppet::Indirector::DirectFileServer, "when searching for multiple files" do
- it "should return nil if the file does not exist" do
- FileTest.expects(:exists?).with("/my/local").returns false
- @server.find(@uri).should be_nil
- end
+ it "should return nil if the file does not exist" do
+ FileTest.expects(:exists?).with("/my/local").returns false
+ @server.find(@uri).should be_nil
+ end
- it "should pass the original key to :path2instances" do
- FileTest.expects(:exists?).with("/my/local").returns true
- @server.expects(:path2instances).with { |uri, path, options| uri == @uri }
- @server.search(@uri)
- end
+ it "should pass the original key to :path2instances" do
+ FileTest.expects(:exists?).with("/my/local").returns true
+ @server.expects(:path2instances).with { |uri, path, options| uri == @uri }
+ @server.search(@uri)
+ end
- it "should use :path2instances from the terminus_helper to return instances if the file exists" do
- FileTest.expects(:exists?).with("/my/local").returns true
- @server.expects(:path2instances)
- @server.search(@uri)
- end
+ it "should use :path2instances from the terminus_helper to return instances if the file exists" do
+ FileTest.expects(:exists?).with("/my/local").returns true
+ @server.expects(:path2instances)
+ @server.search(@uri)
+ end
- it "should pass any options on to :path2instances" do
- FileTest.expects(:exists?).with("/my/local").returns true
- @server.expects(:path2instances).with { |uri, path, options| options == {:testing => :one, :other => :two}}
- @server.search(@uri, :testing => :one, :other => :two)
+ it "should pass any options on to :path2instances" do
+ FileTest.expects(:exists?).with("/my/local").returns true
+ @server.expects(:path2instances).with { |uri, path, options| options == {:testing => :one, :other => :two}}
+ @server.search(@uri, :testing => :one, :other => :two)
+ end
end
-end
+end \ No newline at end of file
diff --git a/spec/unit/indirector/facts/facter.rb b/spec/unit/indirector/facts/facter.rb
index 1fad4c859..0974a60ec 100755
--- a/spec/unit/indirector/facts/facter.rb
+++ b/spec/unit/indirector/facts/facter.rb
@@ -31,49 +31,46 @@ describe Puppet::Node::Facts::Facter do
end
end
-module TestingCodeFacts
- def setup
+describe Puppet::Node::Facts::Facter do
+ before :each do
@facter = Puppet::Node::Facts::Facter.new
Facter.stubs(:to_hash).returns({})
@name = "me"
@facts = @facter.find(@name)
end
-end
-describe Puppet::Node::Facts::Facter, " when finding facts" do
- include TestingCodeFacts
+ describe Puppet::Node::Facts::Facter, " when finding facts" do
- it "should return a Facts instance" do
- @facts.should be_instance_of(Puppet::Node::Facts)
- end
+ it "should return a Facts instance" do
+ @facts.should be_instance_of(Puppet::Node::Facts)
+ end
- it "should return a Facts instance with the provided key as the name" do
- @facts.name.should == @name
- end
+ it "should return a Facts instance with the provided key as the name" do
+ @facts.name.should == @name
+ end
- it "should return the Facter facts as the values in the Facts instance" do
- Facter.expects(:to_hash).returns("one" => "two")
- facts = @facter.find(@name)
- facts.values["one"].should == "two"
+ it "should return the Facter facts as the values in the Facts instance" do
+ Facter.expects(:to_hash).returns("one" => "two")
+ facts = @facter.find(@name)
+ facts.values["one"].should == "two"
+ end
end
-end
-describe Puppet::Node::Facts::Facter, " when saving facts" do
- include TestingCodeFacts
+ describe Puppet::Node::Facts::Facter, " when saving facts" do
- it "should fail" do
- proc { @facter.save(@facts) }.should raise_error(Puppet::DevError)
+ it "should fail" do
+ proc { @facter.save(@facts) }.should raise_error(Puppet::DevError)
+ end
end
-end
-describe Puppet::Node::Facts::Facter, " when destroying facts" do
- include TestingCodeFacts
+ describe Puppet::Node::Facts::Facter, " when destroying facts" do
- it "should fail" do
- proc { @facter.destroy(@facts) }.should raise_error(Puppet::DevError)
+ it "should fail" do
+ proc { @facter.destroy(@facts) }.should raise_error(Puppet::DevError)
+ end
end
-end
-describe Puppet::Node::Facts::Facter, " when loading facts from the factpath" do
- it "should load every fact in each factpath directory"
-end
+ describe Puppet::Node::Facts::Facter, " when loading facts from the factpath" do
+ it "should load every fact in each factpath directory"
+ end
+end \ No newline at end of file
diff --git a/spec/unit/indirector/file.rb b/spec/unit/indirector/file.rb
index 216c9bfe1..37740f0d0 100755
--- a/spec/unit/indirector/file.rb
+++ b/spec/unit/indirector/file.rb
@@ -3,8 +3,9 @@
require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/file'
-module FileTerminusTesting
- def setup
+
+describe Puppet::Indirector::File do
+ before :each do
Puppet::Indirector::Terminus.stubs(:register_terminus_class)
@model = mock 'model'
@indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
@@ -21,140 +22,137 @@ module FileTerminusTesting
@path = "/my/file"
@dir = "/my"
end
-end
+
+ describe Puppet::Indirector::File, " when finding files" do
-describe Puppet::Indirector::File, " when finding files" do
- include FileTerminusTesting
+ it "should provide a method to return file contents at a specified path" do
+ @searcher.should respond_to(:find)
+ end
- it "should provide a method to return file contents at a specified path" do
- @searcher.should respond_to(:find)
- end
+ it "should return file contents as an instance of the model" do
+ content = "my content"
- it "should return file contents as an instance of the model" do
- content = "my content"
+ file = mock 'file'
+ @model.expects(:new).with(content).returns(file)
- file = mock 'file'
- @model.expects(:new).with(content).returns(file)
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:read).with(@path).returns(content)
+ @searcher.find(@path)
+ end
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:read).with(@path).returns(content)
- @searcher.find(@path)
- end
+ it "should create the model instance with the content as the only argument to initialization" do
+ content = "my content"
- it "should create the model instance with the content as the only argument to initialization" do
- content = "my content"
+ file = mock 'file'
+ @model.expects(:new).with(content).returns(file)
- file = mock 'file'
- @model.expects(:new).with(content).returns(file)
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:read).with(@path).returns(content)
+ @searcher.find(@path).should equal(file)
+ end
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:read).with(@path).returns(content)
- @searcher.find(@path).should equal(file)
- end
+ it "should return nil if no file is found" do
+ File.expects(:exist?).with(@path).returns(false)
+ @searcher.find(@path).should be_nil
+ end
- it "should return nil if no file is found" do
- File.expects(:exist?).with(@path).returns(false)
- @searcher.find(@path).should be_nil
- end
+ it "should fail intelligently if a found file cannot be read" do
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:read).with(@path).raises(RuntimeError)
+ proc { @searcher.find(@path) }.should raise_error(Puppet::Error)
+ end
- it "should fail intelligently if a found file cannot be read" do
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:read).with(@path).raises(RuntimeError)
- proc { @searcher.find(@path) }.should raise_error(Puppet::Error)
- end
+ it "should use the path() method to calculate the path if it exists" do
+ @searcher.meta_def(:path) do |name|
+ name.upcase
+ end
- it "should use the path() method to calculate the path if it exists" do
- @searcher.meta_def(:path) do |name|
- name.upcase
+ File.expects(:exist?).with(@path.upcase).returns(false)
+ @searcher.find(@path)
end
-
- File.expects(:exist?).with(@path.upcase).returns(false)
- @searcher.find(@path)
end
-end
-describe Puppet::Indirector::File, " when saving files" do
- include FileTerminusTesting
+ describe Puppet::Indirector::File, " when saving files" do
- it "should provide a method to save file contents at a specified path" do
- filehandle = mock 'file'
- content = "my content"
- File.expects(:directory?).with(@dir).returns(true)
- File.expects(:open).with(@path, "w").yields(filehandle)
- filehandle.expects(:print).with(content)
+ it "should provide a method to save file contents at a specified path" do
+ filehandle = mock 'file'
+ content = "my content"
+ File.expects(:directory?).with(@dir).returns(true)
+ File.expects(:open).with(@path, "w").yields(filehandle)
+ filehandle.expects(:print).with(content)
- file = stub 'file', :content => content, :path => @path, :name => @path
+ file = stub 'file', :content => content, :path => @path, :name => @path
- @searcher.save(file)
- end
+ @searcher.save(file)
+ end
- it "should fail intelligently if the file's parent directory does not exist" do
- File.expects(:directory?).with(@dir).returns(false)
+ it "should fail intelligently if the file's parent directory does not exist" do
+ File.expects(:directory?).with(@dir).returns(false)
- file = stub 'file', :path => @path, :name => @path
+ file = stub 'file', :path => @path, :name => @path
- proc { @searcher.save(file) }.should raise_error(Puppet::Error)
- end
-
- it "should fail intelligently if a file cannot be written" do
- filehandle = mock 'file'
- content = "my content"
- File.expects(:directory?).with(@dir).returns(true)
- File.expects(:open).with(@path, "w").yields(filehandle)
- filehandle.expects(:print).with(content).raises(ArgumentError)
+ proc { @searcher.save(file) }.should raise_error(Puppet::Error)
+ end
- file = stub 'file', :content => content, :path => @path, :name => @path
+ it "should fail intelligently if a file cannot be written" do
+ filehandle = mock 'file'
+ content = "my content"
+ File.expects(:directory?).with(@dir).returns(true)
+ File.expects(:open).with(@path, "w").yields(filehandle)
+ filehandle.expects(:print).with(content).raises(ArgumentError)
- proc { @searcher.save(file) }.should raise_error(Puppet::Error)
- end
+ file = stub 'file', :content => content, :path => @path, :name => @path
- it "should use the path() method to calculate the path if it exists" do
- @searcher.meta_def(:path) do |name|
- name.upcase
+ proc { @searcher.save(file) }.should raise_error(Puppet::Error)
end
- file = stub 'file', :name => "/yay"
+ it "should use the path() method to calculate the path if it exists" do
+ @searcher.meta_def(:path) do |name|
+ name.upcase
+ end
+
+ file = stub 'file', :name => "/yay"
- File.expects(:open).with("/YAY", "w")
- @searcher.save(file)
+ File.expects(:open).with("/YAY", "w")
+ @searcher.save(file)
+ end
end
-end
-describe Puppet::Indirector::File, " when removing files" do
- include FileTerminusTesting
+ describe Puppet::Indirector::File, " when removing files" do
- it "should provide a method to remove files at a specified path" do
- file = stub 'file', :path => @path, :name => @path
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:unlink).with(@path)
-
- @searcher.destroy(file)
- end
+ it "should provide a method to remove files at a specified path" do
+ file = stub 'file', :path => @path, :name => @path
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:unlink).with(@path)
- it "should throw an exception if the file is not found" do
- file = stub 'file', :path => @path, :name => @path
- File.expects(:exist?).with(@path).returns(false)
+ @searcher.destroy(file)
+ end
- proc { @searcher.destroy(file) }.should raise_error(Puppet::Error)
- end
+ it "should throw an exception if the file is not found" do
+ file = stub 'file', :path => @path, :name => @path
+ File.expects(:exist?).with(@path).returns(false)
- it "should fail intelligently if the file cannot be removed" do
- file = stub 'file', :path => @path, :name => @path
- File.expects(:exist?).with(@path).returns(true)
- File.expects(:unlink).with(@path).raises(ArgumentError)
+ proc { @searcher.destroy(file) }.should raise_error(Puppet::Error)
+ end
- proc { @searcher.destroy(file) }.should raise_error(Puppet::Error)
- end
+ it "should fail intelligently if the file cannot be removed" do
+ file = stub 'file', :path => @path, :name => @path
+ File.expects(:exist?).with(@path).returns(true)
+ File.expects(:unlink).with(@path).raises(ArgumentError)
- it "should use the path() method to calculate the path if it exists" do
- @searcher.meta_def(:path) do |name|
- name.upcase
+ proc { @searcher.destroy(file) }.should raise_error(Puppet::Error)
end
- file = stub 'file', :name => "/yay"
- File.expects(:exist?).with("/YAY").returns(true)
- File.expects(:unlink).with("/YAY")
+ it "should use the path() method to calculate the path if it exists" do
+ @searcher.meta_def(:path) do |name|
+ name.upcase
+ end
+
+ file = stub 'file', :name => "/yay"
+ File.expects(:exist?).with("/YAY").returns(true)
+ File.expects(:unlink).with("/YAY")
- @searcher.destroy(file)
+ @searcher.destroy(file)
+ end
end
-end
+end \ No newline at end of file
diff --git a/spec/unit/indirector/file_server.rb b/spec/unit/indirector/file_server.rb
index fda60f1ec..974b95e0e 100755
--- a/spec/unit/indirector/file_server.rb
+++ b/spec/unit/indirector/file_server.rb
@@ -8,8 +8,9 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/file_server'
require 'puppet/file_serving/configuration'
-module FileServerTerminusTesting
- def setup
+describe Puppet::Indirector::FileServer do
+
+ before :each do
Puppet::Indirector::Terminus.stubs(:register_terminus_class)
@model = mock 'model'
@indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
@@ -27,147 +28,141 @@ module FileServerTerminusTesting
@configuration = mock 'configuration'
Puppet::FileServing::Configuration.stubs(:create).returns(@configuration)
end
-end
-describe Puppet::Indirector::FileServer, " when finding files" do
- include FileServerTerminusTesting
+ describe Puppet::Indirector::FileServer, " when finding files" do
- it "should use the path portion of the URI as the file name" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil)
- @file_server.find(@uri)
- end
+ it "should use the path portion of the URI as the file name" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil)
+ @file_server.find(@uri)
+ end
- it "should use the FileServing configuration to convert the file name to a fully qualified path" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil)
- @file_server.find(@uri)
- end
+ it "should use the FileServing configuration to convert the file name to a fully qualified path" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil)
+ @file_server.find(@uri)
+ end
- it "should pass the node name to the FileServing configuration if one is provided" do
- @configuration.expects(:file_path).with("/my/local/file", :node => "testing")
- @file_server.find(@uri, :node => "testing")
- end
+ it "should pass the node name to the FileServing configuration if one is provided" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => "testing")
+ @file_server.find(@uri, :node => "testing")
+ end
- it "should return nil if no fully qualified path is found" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns(nil)
- @file_server.find(@uri).should be_nil
- end
+ it "should return nil if no fully qualified path is found" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns(nil)
+ @file_server.find(@uri).should be_nil
+ end
- it "should return an instance of the model created with the full path if a file is found" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/some/file")
- @model.expects(:new).returns(:myinstance)
- @file_server.find(@uri).should == :myinstance
+ it "should return an instance of the model created with the full path if a file is found" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/some/file")
+ @model.expects(:new).returns(:myinstance)
+ @file_server.find(@uri).should == :myinstance
+ end
end
-end
+ describe Puppet::Indirector::FileServer, " when returning instances" do
+ before :each do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/some/file")
+ @instance = mock 'instance'
+ end
-describe Puppet::Indirector::FileServer, " when returning instances" do
- include FileServerTerminusTesting
-
- before do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/some/file")
- @instance = mock 'instance'
- end
-
- it "should create the instance with the key used to find the instance" do
- @model.expects(:new).with { |key, *options| key == @uri }
- @file_server.find(@uri)
- end
+ it "should create the instance with the key used to find the instance" do
+ @model.expects(:new).with { |key, *options| key == @uri }
+ @file_server.find(@uri)
+ end
- it "should create the instance with the path at which the instance was found" do
- @model.expects(:new).with { |key, options| options[:path] == "/some/file" }
- @file_server.find(@uri)
- end
+ it "should create the instance with the path at which the instance was found" do
+ @model.expects(:new).with { |key, options| options[:path] == "/some/file" }
+ @file_server.find(@uri)
+ end
- it "should set the provided :links setting on to the instance if one is provided" do
- @model.expects(:new).returns(@instance)
- @instance.expects(:links=).with(:mytest)
- @file_server.find(@uri, :links => :mytest)
- end
+ it "should set the provided :links setting on to the instance if one is provided" do
+ @model.expects(:new).returns(@instance)
+ @instance.expects(:links=).with(:mytest)
+ @file_server.find(@uri, :links => :mytest)
+ end
- it "should not set a :links value if no :links parameter is provided" do
- @model.expects(:new).returns(@instance)
- @file_server.find(@uri)
+ it "should not set a :links value if no :links parameter is provided" do
+ @model.expects(:new).returns(@instance)
+ @file_server.find(@uri)
+ end
end
-end
-describe Puppet::Indirector::FileServer, " when checking authorization" do
- include FileServerTerminusTesting
+ describe Puppet::Indirector::FileServer, " when checking authorization" do
- it "should have an authorization hook" do
- @file_server.should respond_to(:authorized?)
- end
+ it "should have an authorization hook" do
+ @file_server.should respond_to(:authorized?)
+ end
- it "should deny the :destroy method" do
- @file_server.authorized?(:destroy, "whatever").should be_false
- end
+ it "should deny the :destroy method" do
+ @file_server.authorized?(:destroy, "whatever").should be_false
+ end
- it "should deny the :save method" do
- @file_server.authorized?(:save, "whatever").should be_false
- end
+ it "should deny the :save method" do
+ @file_server.authorized?(:save, "whatever").should be_false
+ end
- it "should use the file server configuration to determine authorization" do
- @configuration.expects(:authorized?)
- @file_server.authorized?(:find, "puppetmounts://host/my/file")
- end
+ it "should use the file server configuration to determine authorization" do
+ @configuration.expects(:authorized?)
+ @file_server.authorized?(:find, "puppetmounts://host/my/file")
+ end
- it "should pass the file path from the URI to the file server configuration" do
- @configuration.expects(:authorized?).with { |uri, *args| uri == "/my/file" }
- @file_server.authorized?(:find, "puppetmounts://host/my/file")
- end
+ it "should pass the file path from the URI to the file server configuration" do
+ @configuration.expects(:authorized?).with { |uri, *args| uri == "/my/file" }
+ @file_server.authorized?(:find, "puppetmounts://host/my/file")
+ end
- it "should pass the node name to the file server configuration" do
- @configuration.expects(:authorized?).with { |key, options| options[:node] == "mynode" }
- @file_server.authorized?(:find, "puppetmounts://host/my/file", :node => "mynode")
- end
+ it "should pass the node name to the file server configuration" do
+ @configuration.expects(:authorized?).with { |key, options| options[:node] == "mynode" }
+ @file_server.authorized?(:find, "puppetmounts://host/my/file", :node => "mynode")
+ end
- it "should pass the IP address to the file server configuration" do
- @configuration.expects(:authorized?).with { |key, options| options[:ipaddress] == "myip" }
- @file_server.authorized?(:find, "puppetmounts://host/my/file", :ipaddress => "myip")
- end
+ it "should pass the IP address to the file server configuration" do
+ @configuration.expects(:authorized?).with { |key, options| options[:ipaddress] == "myip" }
+ @file_server.authorized?(:find, "puppetmounts://host/my/file", :ipaddress => "myip")
+ end
- it "should return false if the file server configuration denies authorization" do
- @configuration.expects(:authorized?).returns(false)
- @file_server.authorized?(:find, "puppetmounts://host/my/file").should be_false
- end
+ it "should return false if the file server configuration denies authorization" do
+ @configuration.expects(:authorized?).returns(false)
+ @file_server.authorized?(:find, "puppetmounts://host/my/file").should be_false
+ end
- it "should return true if the file server configuration approves authorization" do
- @configuration.expects(:authorized?).returns(true)
- @file_server.authorized?(:find, "puppetmounts://host/my/file").should be_true
+ it "should return true if the file server configuration approves authorization" do
+ @configuration.expects(:authorized?).returns(true)
+ @file_server.authorized?(:find, "puppetmounts://host/my/file").should be_true
+ end
end
-end
-describe Puppet::Indirector::FileServer, " when searching for files" do
- include FileServerTerminusTesting
+ describe Puppet::Indirector::FileServer, " when searching for files" do
- it "should use the path portion of the URI as the file name" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil)
- @file_server.search(@uri)
- end
+ it "should use the path portion of the URI as the file name" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil)
+ @file_server.search(@uri)
+ end
- it "should use the FileServing configuration to convert the file name to a fully qualified path" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil)
- @file_server.search(@uri)
- end
+ it "should use the FileServing configuration to convert the file name to a fully qualified path" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil)
+ @file_server.search(@uri)
+ end
- it "should pass the node name to the FileServing configuration if one is provided" do
- @configuration.expects(:file_path).with("/my/local/file", :node => "testing")
- @file_server.search(@uri, :node => "testing")
- end
+ it "should pass the node name to the FileServing configuration if one is provided" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => "testing")
+ @file_server.search(@uri, :node => "testing")
+ end
- it "should return nil if no fully qualified path is found" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns(nil)
- @file_server.search(@uri).should be_nil
- end
+ it "should return nil if no fully qualified path is found" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns(nil)
+ @file_server.search(@uri).should be_nil
+ end
- it "should use :path2instances from the terminus_helper to return instances if a module is found and the file exists" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/my/file")
- @file_server.expects(:path2instances).with(@uri, "/my/file", {})
- @file_server.search(@uri)
- end
+ it "should use :path2instances from the terminus_helper to return instances if a module is found and the file exists" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/my/file")
+ @file_server.expects(:path2instances).with(@uri, "/my/file", {})
+ @file_server.search(@uri)
+ end
- it "should pass any options on to :path2instances" do
- @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/my/file")
- @file_server.expects(:path2instances).with(@uri, "/my/file", :testing => :one, :other => :two)
- @file_server.search(@uri, :testing => :one, :other => :two)
+ it "should pass any options on to :path2instances" do
+ @configuration.expects(:file_path).with("/my/local/file", :node => nil).returns("/my/file")
+ @file_server.expects(:path2instances).with(@uri, "/my/file", :testing => :one, :other => :two)
+ @file_server.search(@uri, :testing => :one, :other => :two)
+ end
end
-end
+end \ No newline at end of file
diff --git a/spec/unit/indirector/indirection.rb b/spec/unit/indirector/indirection.rb
index 36192b8e5..fe456b61e 100755
--- a/spec/unit/indirector/indirection.rb
+++ b/spec/unit/indirector/indirection.rb
@@ -4,21 +4,7 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector'
-module IndirectionTesting
- def setup
- @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
- @terminus = stub 'terminus', :has_most_recent? => false
- @indirection.stubs(:terminus).returns(@terminus)
- @indirection.stubs(:terminus_class).returns(:whatever)
- @instance = stub 'instance', :version => nil, :version= => nil, :name => "whatever"
- @name = :mything
- end
-
- def teardown
- @indirection.delete
- Puppet::Indirector::Indirection.clear_cache
- end
-end
+
describe Puppet::Indirector::Indirection, " when initializing" do
# (LAK) I've no idea how to test this, really.
@@ -55,103 +41,183 @@ describe Puppet::Indirector::Indirection, " when initializing" do
end
end
-describe Puppet::Indirector::Indirection, " when looking for a model instance" do
- include IndirectionTesting
+describe Puppet::Indirector::Indirection do
+ before :each do
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
+ @terminus = stub 'terminus', :has_most_recent? => false
+ @indirection.stubs(:terminus).returns(@terminus)
+ @indirection.stubs(:terminus_class).returns(:whatever)
+ @instance = stub 'instance', :version => nil, :version= => nil, :name => "whatever"
+ @name = :mything
+ end
+
+ describe Puppet::Indirector::Indirection, " when looking for a model instance" do
+
+ it "should let the appropriate terminus perform the lookup" do
+ @terminus.expects(:find).with(@name).returns(@instance)
+ @indirection.find(@name).should == @instance
+ end
+
+ it "should not attempt to set a timestamp if the terminus cannot find the instance" do
+ @terminus.expects(:find).with(@name).returns(nil)
+ proc { @indirection.find(@name) }.should_not raise_error
+ end
- it "should let the appropriate terminus perform the lookup" do
- @terminus.expects(:find).with(@name).returns(@instance)
- @indirection.find(@name).should == @instance
+ it "should pass the instance to the :post_find hook if there is one" do
+ class << @terminus
+ def post_find
+ end
+ end
+ @terminus.expects(:post_find).with(@instance)
+ @terminus.expects(:find).with(@name).returns(@instance)
+ @indirection.find(@name)
+ end
end
+
+ describe Puppet::Indirector::Indirection, " when removing a model instance" do
- it "should not attempt to set a timestamp if the terminus cannot find the instance" do
- @terminus.expects(:find).with(@name).returns(nil)
- proc { @indirection.find(@name) }.should_not raise_error
+ it "should let the appropriate terminus remove the instance" do
+ @terminus.expects(:destroy).with(@name).returns(@instance)
+ @indirection.destroy(@name).should == @instance
+ end
end
- it "should pass the instance to the :post_find hook if there is one" do
- class << @terminus
- def post_find
+ describe Puppet::Indirector::Indirection, " when searching for multiple model instances" do
+
+ it "should let the appropriate terminus find the matching instances" do
+ @terminus.expects(:search).with(@name).returns(@instance)
+ @indirection.search(@name).should == @instance
+ end
+
+ it "should pass the instances to the :post_search hook if there is one" do
+ class << @terminus
+ def post_search
+ end
end
+ @terminus.expects(:post_search).with(@instance)
+ @terminus.expects(:search).with(@name).returns(@instance)
+ @indirection.search(@name)
end
- @terminus.expects(:post_find).with(@instance)
- @terminus.expects(:find).with(@name).returns(@instance)
- @indirection.find(@name)
end
-end
-describe Puppet::Indirector::Indirection, " when removing a model instance" do
- include IndirectionTesting
+ describe Puppet::Indirector::Indirection, " when storing a model instance" do
- it "should let the appropriate terminus remove the instance" do
- @terminus.expects(:destroy).with(@name).returns(@instance)
- @indirection.destroy(@name).should == @instance
+ it "should let the appropriate terminus store the instance" do
+ @terminus.expects(:save).with(@instance).returns(@instance)
+ @indirection.save(@instance).should == @instance
+ end
end
-end
+
+ describe Puppet::Indirector::Indirection, " when handling instance versions" do
-describe Puppet::Indirector::Indirection, " when searching for multiple model instances" do
- include IndirectionTesting
-
- it "should let the appropriate terminus find the matching instances" do
- @terminus.expects(:search).with(@name).returns(@instance)
- @indirection.search(@name).should == @instance
- end
+ it "should let the appropriate terminus perform the lookup" do
+ @terminus.expects(:version).with(@name).returns(5)
+ @indirection.version(@name).should == 5
+ end
+
+ it "should add versions to found instances that do not already have them" do
+ @terminus.expects(:find).with(@name).returns(@instance)
+ time = mock 'time'
+ time.expects(:utc).returns(:mystamp)
+ Time.expects(:now).returns(time)
+ @instance.expects(:version=).with(:mystamp)
+ @indirection.find(@name)
+ end
+
+ it "should add versions to saved instances that do not already have them" do
+ time = mock 'time'
+ time.expects(:utc).returns(:mystamp)
+ Time.expects(:now).returns(time)
+ @instance.expects(:version=).with(:mystamp)
+ @terminus.stubs(:save)
+ @indirection.save(@instance)
+ end
- it "should pass the instances to the :post_search hook if there is one" do
- class << @terminus
- def post_search
+ # We've already tested this, basically, but...
+ it "should use the current time in UTC for versions" do
+ @instance.expects(:version=).with do |time|
+ time.utc?
end
+ @terminus.stubs(:save)
+ @indirection.save(@instance)
end
- @terminus.expects(:post_search).with(@instance)
- @terminus.expects(:search).with(@name).returns(@instance)
- @indirection.search(@name)
end
-end
-describe Puppet::Indirector::Indirection, " when storing a model instance" do
- include IndirectionTesting
-
- it "should let the appropriate terminus store the instance" do
- @terminus.expects(:save).with(@instance).returns(@instance)
- @indirection.save(@instance).should == @instance
- end
-end
-describe Puppet::Indirector::Indirection, " when handling instance versions" do
- include IndirectionTesting
-
- it "should let the appropriate terminus perform the lookup" do
- @terminus.expects(:version).with(@name).returns(5)
- @indirection.version(@name).should == 5
- end
+ describe Puppet::Indirector::Indirection, " when an authorization hook is present" do
- it "should add versions to found instances that do not already have them" do
- @terminus.expects(:find).with(@name).returns(@instance)
- time = mock 'time'
- time.expects(:utc).returns(:mystamp)
- Time.expects(:now).returns(time)
- @instance.expects(:version=).with(:mystamp)
- @indirection.find(@name)
- end
+ before do
+ # So the :respond_to? turns out right.
+ class << @terminus
+ def authorized?
+ end
+ end
+ end
- it "should add versions to saved instances that do not already have them" do
- time = mock 'time'
- time.expects(:utc).returns(:mystamp)
- Time.expects(:now).returns(time)
- @instance.expects(:version=).with(:mystamp)
- @terminus.stubs(:save)
- @indirection.save(@instance)
- end
+ it "should not check authorization if a node name is not provided" do
+ @terminus.expects(:authorized?).never
+ @terminus.stubs(:find)
+ @indirection.find("/my/key")
+ end
+
+ it "should fail while finding instances if authorization returns false" do
+ @terminus.expects(:authorized?).with(:find, "/my/key", :node => "mynode").returns(false)
+ @terminus.stubs(:find)
+ proc { @indirection.find("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ end
+
+ it "should continue finding instances if authorization returns true" do
+ @terminus.expects(:authorized?).with(:find, "/my/key", :node => "mynode").returns(true)
+ @terminus.stubs(:find)
+ @indirection.find("/my/key", :node => "mynode")
+ end
+
+ it "should fail while saving instances if authorization returns false" do
+ @terminus.expects(:authorized?).with(:save, :myinstance, :node => "mynode").returns(false)
+ @terminus.stubs(:save)
+ proc { @indirection.save(:myinstance, :node => "mynode") }.should raise_error(ArgumentError)
+ end
+
+ it "should continue saving instances if authorization returns true" do
+ instance = stub 'instance', :version => 1.0, :name => "eh"
+ @terminus.expects(:authorized?).with(:save, instance, :node => "mynode").returns(true)
+ @terminus.stubs(:save)
+ @indirection.save(instance, :node => "mynode")
+ end
+
+ it "should fail while destroying instances if authorization returns false" do
+ @terminus.expects(:authorized?).with(:destroy, "/my/key", :node => "mynode").returns(false)
+ @terminus.stubs(:destroy)
+ proc { @indirection.destroy("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ end
+
+ it "should continue destroying instances if authorization returns true" do
+ instance = stub 'instance', :version => 1.0, :name => "eh"
+ @terminus.expects(:authorized?).with(:destroy, instance, :node => "mynode").returns(true)
+ @terminus.stubs(:destroy)
+ @indirection.destroy(instance, :node => "mynode")
+ end
+
+ it "should fail while searching for instances if authorization returns false" do
+ @terminus.expects(:authorized?).with(:search, "/my/key", :node => "mynode").returns(false)
+ @terminus.stubs(:search)
+ proc { @indirection.search("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ end
- # We've already tested this, basically, but...
- it "should use the current time in UTC for versions" do
- @instance.expects(:version=).with do |time|
- time.utc?
+ it "should continue searching for instances if authorization returns true" do
+ @terminus.expects(:authorized?).with(:search, "/my/key", :node => "mynode").returns(true)
+ @terminus.stubs(:search)
+ @indirection.search("/my/key", :node => "mynode")
end
- @terminus.stubs(:save)
- @indirection.save(@instance)
+ end
+
+ after :each do
+ @indirection.delete
+ Puppet::Indirector::Indirection.clear_cache
end
end
+
describe Puppet::Indirector::Indirection, " when managing indirection instances" do
it "should allow an indirection to be retrieved by name" do
@indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
@@ -397,8 +463,8 @@ describe Puppet::Indirector::Indirection, " when deciding whether to cache" do
end
end
-module IndirectionCacheTesting
- def setup
+describe Puppet::Indirector::Indirection do
+ before :each do
Puppet.settings.stubs(:value).with("test_terminus").returns("test_terminus")
@terminus_class = mock 'terminus_class'
@terminus = mock 'terminus'
@@ -411,175 +477,104 @@ module IndirectionCacheTesting
@indirection.terminus_class = :test_terminus
end
- def teardown
- @indirection.delete
- Puppet::Indirector::Indirection.clear_cache
- end
-end
-
-describe Puppet::Indirector::Indirection, " when managing the cache terminus" do
- include IndirectionCacheTesting
-
- it "should not create a cache terminus at initialization" do
- # This is weird, because all of the code is in the setup. If we got
- # new() called on the cache class, we'd get an exception here.
- end
-
- it "should reuse the cache terminus" do
- @cache_class.expects(:new).returns(@cache)
- Puppet.settings.stubs(:value).with("test_cache").returns("cache_terminus")
- @indirection.cache_class = :cache_terminus
- @indirection.cache.should equal(@cache)
- @indirection.cache.should equal(@cache)
- end
-
- it "should remove the cache terminus when all other terminus instances are cleared" do
- cache2 = mock 'cache2'
- @cache_class.stubs(:new).returns(@cache, cache2)
- @indirection.cache_class = :cache_terminus
- @indirection.cache.should equal(@cache)
- @indirection.clear_cache
- @indirection.cache.should equal(cache2)
- end
-end
-
-describe Puppet::Indirector::Indirection, " when saving and using a cache" do
- include IndirectionCacheTesting
-
- before do
- @indirection.cache_class = :cache_terminus
- @cache_class.expects(:new).returns(@cache)
- @name = "testing"
- @instance = stub 'instance', :version => 5, :name => @name
- end
-
- it "should not update the cache or terminus if the new object is not different" do
- @cache.expects(:has_most_recent?).with(@name, 5).returns(true)
- @indirection.save(@instance)
- end
+ describe Puppet::Indirector::Indirection, " when managing the cache terminus" do
- it "should update the original and the cache if the cached object is different" do
- @cache.expects(:has_most_recent?).with(@name, 5).returns(false)
- @terminus.expects(:save).with(@instance)
- @cache.expects(:save).with(@instance)
- @indirection.save(@instance)
- end
-end
+ it "should not create a cache terminus at initialization" do
+ # This is weird, because all of the code is in the setup. If we got
+ # new() called on the cache class, we'd get an exception here.
+ end
-describe Puppet::Indirector::Indirection, " when finding and using a cache" do
- include IndirectionCacheTesting
+ it "should reuse the cache terminus" do
+ @cache_class.expects(:new).returns(@cache)
+ Puppet.settings.stubs(:value).with("test_cache").returns("cache_terminus")
+ @indirection.cache_class = :cache_terminus
+ @indirection.cache.should equal(@cache)
+ @indirection.cache.should equal(@cache)
+ end
- before do
- @indirection.cache_class = :cache_terminus
- @cache_class.expects(:new).returns(@cache)
+ it "should remove the cache terminus when all other terminus instances are cleared" do
+ cache2 = mock 'cache2'
+ @cache_class.stubs(:new).returns(@cache, cache2)
+ @indirection.cache_class = :cache_terminus
+ @indirection.cache.should equal(@cache)
+ @indirection.clear_cache
+ @indirection.cache.should equal(cache2)
+ end
end
- it "should return the cached object if the cache is up to date" do
- cached = mock 'cached object'
+ describe Puppet::Indirector::Indirection, " when saving and using a cache" do
- name = "myobject"
-
- @terminus.expects(:version).with(name).returns(1)
- @cache.expects(:has_most_recent?).with(name, 1).returns(true)
+ before do
+ @indirection.cache_class = :cache_terminus
+ @cache_class.expects(:new).returns(@cache)
+ @name = "testing"
+ @instance = stub 'instance', :version => 5, :name => @name
+ end
- @cache.expects(:find).with(name).returns(cached)
+ it "should not update the cache or terminus if the new object is not different" do
+ @cache.expects(:has_most_recent?).with(@name, 5).returns(true)
+ @indirection.save(@instance)
+ end
- @indirection.find(name).should equal(cached)
+ it "should update the original and the cache if the cached object is different" do
+ @cache.expects(:has_most_recent?).with(@name, 5).returns(false)
+ @terminus.expects(:save).with(@instance)
+ @cache.expects(:save).with(@instance)
+ @indirection.save(@instance)
+ end
end
+
+ describe Puppet::Indirector::Indirection, " when finding and using a cache" do
- it "should return the original object if the cache is not up to date" do
- real = stub 'real object', :version => 1
-
- name = "myobject"
+ before do
+ @indirection.cache_class = :cache_terminus
+ @cache_class.expects(:new).returns(@cache)
+ end
- @cache.stubs(:save)
- @cache.expects(:has_most_recent?).with(name, 1).returns(false)
- @terminus.expects(:version).with(name).returns(1)
+ it "should return the cached object if the cache is up to date" do
+ cached = mock 'cached object'
- @terminus.expects(:find).with(name).returns(real)
+ name = "myobject"
- @indirection.find(name).should equal(real)
- end
+ @terminus.expects(:version).with(name).returns(1)
+ @cache.expects(:has_most_recent?).with(name, 1).returns(true)
- it "should cache any newly returned objects" do
- real = stub 'real object', :version => 1
+ @cache.expects(:find).with(name).returns(cached)
- name = "myobject"
+ @indirection.find(name).should equal(cached)
+ end
- @terminus.expects(:version).with(name).returns(1)
- @cache.expects(:has_most_recent?).with(name, 1).returns(false)
+ it "should return the original object if the cache is not up to date" do
+ real = stub 'real object', :version => 1
- @terminus.expects(:find).with(name).returns(real)
- @cache.expects(:save).with(real)
+ name = "myobject"
- @indirection.find(name).should equal(real)
- end
-end
+ @cache.stubs(:save)
+ @cache.expects(:has_most_recent?).with(name, 1).returns(false)
+ @terminus.expects(:version).with(name).returns(1)
-describe Puppet::Indirector::Indirection, " when an authorization hook is present" do
- include IndirectionTesting
+ @terminus.expects(:find).with(name).returns(real)
- before do
- # So the :respond_to? turns out right.
- class << @terminus
- def authorized?
- end
+ @indirection.find(name).should equal(real)
end
- end
- it "should not check authorization if a node name is not provided" do
- @terminus.expects(:authorized?).never
- @terminus.stubs(:find)
- @indirection.find("/my/key")
- end
-
- it "should fail while finding instances if authorization returns false" do
- @terminus.expects(:authorized?).with(:find, "/my/key", :node => "mynode").returns(false)
- @terminus.stubs(:find)
- proc { @indirection.find("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
- end
-
- it "should continue finding instances if authorization returns true" do
- @terminus.expects(:authorized?).with(:find, "/my/key", :node => "mynode").returns(true)
- @terminus.stubs(:find)
- @indirection.find("/my/key", :node => "mynode")
- end
+ it "should cache any newly returned objects" do
+ real = stub 'real object', :version => 1
- it "should fail while saving instances if authorization returns false" do
- @terminus.expects(:authorized?).with(:save, :myinstance, :node => "mynode").returns(false)
- @terminus.stubs(:save)
- proc { @indirection.save(:myinstance, :node => "mynode") }.should raise_error(ArgumentError)
- end
+ name = "myobject"
- it "should continue saving instances if authorization returns true" do
- instance = stub 'instance', :version => 1.0, :name => "eh"
- @terminus.expects(:authorized?).with(:save, instance, :node => "mynode").returns(true)
- @terminus.stubs(:save)
- @indirection.save(instance, :node => "mynode")
- end
+ @terminus.expects(:version).with(name).returns(1)
+ @cache.expects(:has_most_recent?).with(name, 1).returns(false)
- it "should fail while destroying instances if authorization returns false" do
- @terminus.expects(:authorized?).with(:destroy, "/my/key", :node => "mynode").returns(false)
- @terminus.stubs(:destroy)
- proc { @indirection.destroy("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
- end
+ @terminus.expects(:find).with(name).returns(real)
+ @cache.expects(:save).with(real)
- it "should continue destroying instances if authorization returns true" do
- instance = stub 'instance', :version => 1.0, :name => "eh"
- @terminus.expects(:authorized?).with(:destroy, instance, :node => "mynode").returns(true)
- @terminus.stubs(:destroy)
- @indirection.destroy(instance, :node => "mynode")
- end
-
- it "should fail while searching for instances if authorization returns false" do
- @terminus.expects(:authorized?).with(:search, "/my/key", :node => "mynode").returns(false)
- @terminus.stubs(:search)
- proc { @indirection.search("/my/key", :node => "mynode") }.should raise_error(ArgumentError)
+ @indirection.find(name).should equal(real)
+ end
end
-
- it "should continue searching for instances if authorization returns true" do
- @terminus.expects(:authorized?).with(:search, "/my/key", :node => "mynode").returns(true)
- @terminus.stubs(:search)
- @indirection.search("/my/key", :node => "mynode")
+
+ after :each do
+ @indirection.delete
+ Puppet::Indirector::Indirection.clear_cache
end
end
diff --git a/spec/unit/indirector/module_files.rb b/spec/unit/indirector/module_files.rb
index 9011530dd..0f6dbb6df 100755
--- a/spec/unit/indirector/module_files.rb
+++ b/spec/unit/indirector/module_files.rb
@@ -7,239 +7,237 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/module_files'
-module ModuleFilesTerminusTesting
- def setup
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Indirector::Terminus.stubs(:register_terminus_class)
- @model = mock 'model'
- @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
- Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
- @module_files_class = Class.new(Puppet::Indirector::ModuleFiles) do
- def self.to_s
- "Testing::Mytype"
- end
- end
+describe Puppet::Indirector::ModuleFiles do
- @module_files = @module_files_class.new
+ before :each do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ @model = mock 'model'
+ @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
+ Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
- @uri = "puppetmounts://host/modules/my/local/file"
- @module = Puppet::Module.new("mymod", "/module/path")
- end
-end
+ @module_files_class = Class.new(Puppet::Indirector::ModuleFiles) do
+ def self.to_s
+ "Testing::Mytype"
+ end
+ end
-describe Puppet::Indirector::ModuleFiles, " when finding files" do
- include ModuleFilesTerminusTesting
+ @module_files = @module_files_class.new
- it "should strip off the leading '/modules' mount name" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- @module_files.find(@uri)
- end
+ @uri = "puppetmounts://host/modules/my/local/file"
+ @module = Puppet::Module.new("mymod", "/module/path")
+ end
- it "should not strip off leading terms that start with '/modules' but are longer words" do
- Puppet::Module.expects(:find).with('modulestart', "myenv").returns nil
- @module_files.find("puppetmounts://host/modulestart/my/local/file")
- end
+ describe Puppet::Indirector::ModuleFiles, " when finding files" do
- it "should search for a module whose name is the first term in the remaining file path" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- @module_files.find(@uri)
- end
+ it "should strip off the leading '/modules' mount name" do
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ @module_files.find(@uri)
+ end
- it "should search for a file relative to the module's files directory" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file")
- @module_files.find(@uri)
- end
+ it "should not strip off leading terms that start with '/modules' but are longer words" do
+ Puppet::Module.expects(:find).with('modulestart', "myenv").returns nil
+ @module_files.find("puppetmounts://host/modulestart/my/local/file")
+ end
- it "should return nil if the module does not exist" do
- Puppet::Module.expects(:find).with('my', "myenv").returns nil
- @module_files.find(@uri).should be_nil
- end
+ it "should search for a module whose name is the first term in the remaining file path" do
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ @module_files.find(@uri)
+ end
- it "should return nil if the module exists but the file does not" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file").returns(false)
- @module_files.find(@uri).should be_nil
- end
+ it "should search for a file relative to the module's files directory" do
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file")
+ @module_files.find(@uri)
+ end
- it "should return an instance of the model if a module is found and the file exists" do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
- @model.expects(:new).returns(:myinstance)
- @module_files.find(@uri).should == :myinstance
- end
+ it "should return nil if the module does not exist" do
+ Puppet::Module.expects(:find).with('my', "myenv").returns nil
+ @module_files.find(@uri).should be_nil
+ end
- it "should use the node's environment to look up the module if the node name is provided" do
- node = stub "node", :environment => "testing"
- Puppet::Node.expects(:find).with("mynode").returns(node)
- Puppet::Module.expects(:find).with('my', "testing")
- @module_files.find(@uri, :node => "mynode")
- end
+ it "should return nil if the module exists but the file does not" do
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file").returns(false)
+ @module_files.find(@uri).should be_nil
+ end
- it "should use the default environment setting to look up the module if the node name is not provided" do
- env = stub "environment", :name => "testing"
- Puppet::Node::Environment.stubs(:new).returns(env)
- Puppet::Module.expects(:find).with('my', "testing")
- @module_files.find(@uri)
- end
-end
+ it "should return an instance of the model if a module is found and the file exists" do
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
+ @model.expects(:new).returns(:myinstance)
+ @module_files.find(@uri).should == :myinstance
+ end
-describe Puppet::Indirector::ModuleFiles, " when returning instances" do
- include ModuleFilesTerminusTesting
+ it "should use the node's environment to look up the module if the node name is provided" do
+ node = stub "node", :environment => "testing"
+ Puppet::Node.expects(:find).with("mynode").returns(node)
+ Puppet::Module.expects(:find).with('my', "testing")
+ @module_files.find(@uri, :node => "mynode")
+ end
- before do
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
- @instance = mock 'instance'
+ it "should use the default environment setting to look up the module if the node name is not provided" do
+ env = stub "environment", :name => "testing"
+ Puppet::Node::Environment.stubs(:new).returns(env)
+ Puppet::Module.expects(:find).with('my', "testing")
+ @module_files.find(@uri)
+ end
end
- it "should create the instance with the key used to find the instance" do
- @model.expects(:new).with { |key, *options| key == @uri }
- @module_files.find(@uri)
- end
+ describe Puppet::Indirector::ModuleFiles, " when returning instances" do
- it "should create the instance with the path at which the instance was found" do
- @model.expects(:new).with { |key, options| options[:path] == "/module/path/files/local/file" }
- @module_files.find(@uri)
- end
+ before do
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
+ @instance = mock 'instance'
+ end
- it "should set the provided :links setting on to the instance if one is provided" do
- @model.expects(:new).returns(@instance)
- @instance.expects(:links=).with(:mytest)
- @module_files.find(@uri, :links => :mytest)
- end
+ it "should create the instance with the key used to find the instance" do
+ @model.expects(:new).with { |key, *options| key == @uri }
+ @module_files.find(@uri)
+ end
- it "should not set a :links value if no :links parameter is provided" do
- @model.expects(:new).returns(@instance)
- @module_files.find(@uri)
- end
-end
+ it "should create the instance with the path at which the instance was found" do
+ @model.expects(:new).with { |key, options| options[:path] == "/module/path/files/local/file" }
+ @module_files.find(@uri)
+ end
-describe Puppet::Indirector::ModuleFiles, " when authorizing" do
- include ModuleFilesTerminusTesting
+ it "should set the provided :links setting on to the instance if one is provided" do
+ @model.expects(:new).returns(@instance)
+ @instance.expects(:links=).with(:mytest)
+ @module_files.find(@uri, :links => :mytest)
+ end
- before do
- @configuration = mock 'configuration'
- Puppet::FileServing::Configuration.stubs(:create).returns(@configuration)
+ it "should not set a :links value if no :links parameter is provided" do
+ @model.expects(:new).returns(@instance)
+ @module_files.find(@uri)
+ end
end
- it "should have an authorization hook" do
- @module_files.should respond_to(:authorized?)
- end
+ describe Puppet::Indirector::ModuleFiles, " when authorizing" do
- it "should deny the :destroy method" do
- @module_files.authorized?(:destroy, "whatever").should be_false
- end
+ before do
+ @configuration = mock 'configuration'
+ Puppet::FileServing::Configuration.stubs(:create).returns(@configuration)
+ end
- it "should deny the :save method" do
- @module_files.authorized?(:save, "whatever").should be_false
- end
+ it "should have an authorization hook" do
+ @module_files.should respond_to(:authorized?)
+ end
- it "should use the file server configuration to determine authorization" do
- @configuration.expects(:authorized?)
- @module_files.authorized?(:find, "puppetmounts://host/my/file")
- end
+ it "should deny the :destroy method" do
+ @module_files.authorized?(:destroy, "whatever").should be_false
+ end
- it "should use the path directly from the URI if it already includes /modules" do
- @configuration.expects(:authorized?).with { |uri, *args| uri == "/modules/my/file" }
- @module_files.authorized?(:find, "puppetmounts://host/modules/my/file")
- end
+ it "should deny the :save method" do
+ @module_files.authorized?(:save, "whatever").should be_false
+ end
- it "should add /modules to the file path if it's not included in the URI" do
- @configuration.expects(:authorized?).with { |uri, *args| uri == "/modules/my/file" }
- @module_files.authorized?(:find, "puppetmounts://host/my/file")
- end
+ it "should use the file server configuration to determine authorization" do
+ @configuration.expects(:authorized?)
+ @module_files.authorized?(:find, "puppetmounts://host/my/file")
+ end
- it "should pass the node name to the file server configuration" do
- @configuration.expects(:authorized?).with { |key, options| options[:node] == "mynode" }
- @module_files.authorized?(:find, "puppetmounts://host/my/file", :node => "mynode")
- end
+ it "should use the path directly from the URI if it already includes /modules" do
+ @configuration.expects(:authorized?).with { |uri, *args| uri == "/modules/my/file" }
+ @module_files.authorized?(:find, "puppetmounts://host/modules/my/file")
+ end
- it "should pass the IP address to the file server configuration" do
- @configuration.expects(:authorized?).with { |key, options| options[:ipaddress] == "myip" }
- @module_files.authorized?(:find, "puppetmounts://host/my/file", :ipaddress => "myip")
- end
+ it "should add /modules to the file path if it's not included in the URI" do
+ @configuration.expects(:authorized?).with { |uri, *args| uri == "/modules/my/file" }
+ @module_files.authorized?(:find, "puppetmounts://host/my/file")
+ end
- it "should return false if the file server configuration denies authorization" do
- @configuration.expects(:authorized?).returns(false)
- @module_files.authorized?(:find, "puppetmounts://host/my/file").should be_false
- end
+ it "should pass the node name to the file server configuration" do
+ @configuration.expects(:authorized?).with { |key, options| options[:node] == "mynode" }
+ @module_files.authorized?(:find, "puppetmounts://host/my/file", :node => "mynode")
+ end
- it "should return true if the file server configuration approves authorization" do
- @configuration.expects(:authorized?).returns(true)
- @module_files.authorized?(:find, "puppetmounts://host/my/file").should be_true
- end
-end
+ it "should pass the IP address to the file server configuration" do
+ @configuration.expects(:authorized?).with { |key, options| options[:ipaddress] == "myip" }
+ @module_files.authorized?(:find, "puppetmounts://host/my/file", :ipaddress => "myip")
+ end
-describe Puppet::Indirector::ModuleFiles, " when searching for files" do
- include ModuleFilesTerminusTesting
+ it "should return false if the file server configuration denies authorization" do
+ @configuration.expects(:authorized?).returns(false)
+ @module_files.authorized?(:find, "puppetmounts://host/my/file").should be_false
+ end
- it "should strip off the leading '/modules' mount name" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- @module_files.search(@uri)
+ it "should return true if the file server configuration approves authorization" do
+ @configuration.expects(:authorized?).returns(true)
+ @module_files.authorized?(:find, "puppetmounts://host/my/file").should be_true
+ end
end
- it "should not strip off leading terms that start with '/modules' but are longer words" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('modulestart', "myenv").returns nil
- @module_files.search("puppetmounts://host/modulestart/my/local/file")
- end
+ describe Puppet::Indirector::ModuleFiles, " when searching for files" do
- it "should search for a module whose name is the first term in the remaining file path" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- @module_files.search(@uri)
- end
+ it "should strip off the leading '/modules' mount name" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ @module_files.search(@uri)
+ end
- it "should search for a file relative to the module's files directory" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file")
- @module_files.search(@uri)
- end
+ it "should not strip off leading terms that start with '/modules' but are longer words" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('modulestart', "myenv").returns nil
+ @module_files.search("puppetmounts://host/modulestart/my/local/file")
+ end
- it "should return nil if the module does not exist" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns nil
- @module_files.search(@uri).should be_nil
- end
+ it "should search for a module whose name is the first term in the remaining file path" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ @module_files.search(@uri)
+ end
- it "should return nil if the module exists but the file does not" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file").returns(false)
- @module_files.search(@uri).should be_nil
- end
+ it "should search for a file relative to the module's files directory" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file")
+ @module_files.search(@uri)
+ end
- it "should use the node's environment to look up the module if the node name is provided" do
- node = stub "node", :environment => "testing"
- Puppet::Node.expects(:find).with("mynode").returns(node)
- Puppet::Module.expects(:find).with('my', "testing")
- @module_files.search(@uri, :node => "mynode")
- end
+ it "should return nil if the module does not exist" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns nil
+ @module_files.search(@uri).should be_nil
+ end
- it "should use the default environment setting to look up the module if the node name is not provided and the environment is not set to ''" do
- env = stub 'env', :name => "testing"
- Puppet::Node::Environment.stubs(:new).returns(env)
- Puppet::Module.expects(:find).with('my', "testing")
- @module_files.search(@uri)
- end
+ it "should return nil if the module exists but the file does not" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file").returns(false)
+ @module_files.search(@uri).should be_nil
+ end
- it "should use :path2instances from the terminus_helper to return instances if a module is found and the file exists" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
- @module_files.expects(:path2instances).with(@uri, "/module/path/files/local/file", {})
- @module_files.search(@uri)
- end
+ it "should use the node's environment to look up the module if the node name is provided" do
+ node = stub "node", :environment => "testing"
+ Puppet::Node.expects(:find).with("mynode").returns(node)
+ Puppet::Module.expects(:find).with('my', "testing")
+ @module_files.search(@uri, :node => "mynode")
+ end
- it "should pass any options on to :path2instances" do
- Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
- Puppet::Module.expects(:find).with('my', "myenv").returns @module
- FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
- @module_files.expects(:path2instances).with(@uri, "/module/path/files/local/file", :testing => :one, :other => :two)
- @module_files.search(@uri, :testing => :one, :other => :two)
+ it "should use the default environment setting to look up the module if the node name is not provided and the environment is not set to ''" do
+ env = stub 'env', :name => "testing"
+ Puppet::Node::Environment.stubs(:new).returns(env)
+ Puppet::Module.expects(:find).with('my', "testing")
+ @module_files.search(@uri)
+ end
+
+ it "should use :path2instances from the terminus_helper to return instances if a module is found and the file exists" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
+ @module_files.expects(:path2instances).with(@uri, "/module/path/files/local/file", {})
+ @module_files.search(@uri)
+ end
+
+ it "should pass any options on to :path2instances" do
+ Puppet::Node::Environment.stubs(:new).returns(stub('env', :name => "myenv"))
+ Puppet::Module.expects(:find).with('my', "myenv").returns @module
+ FileTest.expects(:exists?).with("/module/path/files/local/file").returns(true)
+ @module_files.expects(:path2instances).with(@uri, "/module/path/files/local/file", :testing => :one, :other => :two)
+ @module_files.search(@uri, :testing => :one, :other => :two)
+ end
end
end
diff --git a/spec/unit/indirector/node/exec.rb b/spec/unit/indirector/node/exec.rb
index 744a32b0a..b67e0fe97 100755
--- a/spec/unit/indirector/node/exec.rb
+++ b/spec/unit/indirector/node/exec.rb
@@ -4,59 +4,70 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/node/exec'
-describe Puppet::Node::Exec, " when constructing the command to run" do
+describe Puppet::Node::Exec do
before do
@indirection = mock 'indirection'
Puppet.settings.stubs(:value).with(:external_nodes).returns("/echo")
@searcher = Puppet::Node::Exec.new
end
- it "should use the external_node script as the command" do
- Puppet.expects(:[]).with(:external_nodes).returns("/bin/echo")
- @searcher.command.should == %w{/bin/echo}
+ it "should use the version of the facts as its version" do
+ version = mock 'version'
+ Puppet::Node::Facts.expects(:version).with("me").returns version
+ @searcher.version("me").should equal(version)
end
- it "should throw an exception if no external node command is set" do
- Puppet.expects(:[]).with(:external_nodes).returns("none")
- proc { @searcher.find("foo") }.should raise_error(ArgumentError)
- end
-end
+ describe "when constructing the command to run" do
+ it "should use the external_node script as the command" do
+ Puppet.expects(:[]).with(:external_nodes).returns("/bin/echo")
+ @searcher.command.should == %w{/bin/echo}
+ end
-describe Puppet::Node::Exec, " when handling the results of the command" do
- before do
- @indirection = mock 'indirection'
- Puppet.settings.stubs(:value).with(:external_nodes).returns("/echo")
- @searcher = Puppet::Node::Exec.new
- @node = stub 'node', :fact_merge => nil
- @name = "yay"
- Puppet::Node.expects(:new).with(@name).returns(@node)
- @result = {}
- # Use a local variable so the reference is usable in the execute() definition.
- result = @result
- @searcher.meta_def(:execute) do |command|
- return YAML.dump(result)
+ it "should throw an exception if no external node command is set" do
+ Puppet.expects(:[]).with(:external_nodes).returns("none")
+ proc { @searcher.find("foo") }.should raise_error(ArgumentError)
end
end
- it "should translate the YAML into a Node instance" do
- # Use an empty hash
- @searcher.find(@name).should equal(@node)
- end
+ describe "when handling the results of the command" do
+ before do
+ @node = stub 'node', :fact_merge => nil
+ @name = "yay"
+ Puppet::Node.expects(:new).with(@name).returns(@node)
+ @result = {}
+ # Use a local variable so the reference is usable in the execute() definition.
+ result = @result
+ @searcher.meta_def(:execute) do |command|
+ return YAML.dump(result)
+ end
+ end
- it "should set the resulting parameters as the node parameters" do
- @result[:parameters] = {"a" => "b", "c" => "d"}
- @node.expects(:parameters=).with "a" => "b", "c" => "d"
- @searcher.find(@name)
- end
+ it "should translate the YAML into a Node instance" do
+ # Use an empty hash
+ @searcher.find(@name).should equal(@node)
+ end
- it "should set the resulting classes as the node classes" do
- @result[:classes] = %w{one two}
- @node.expects(:classes=).with %w{one two}
- @searcher.find(@name)
- end
+ it "should set the resulting parameters as the node parameters" do
+ @result[:parameters] = {"a" => "b", "c" => "d"}
+ @node.expects(:parameters=).with "a" => "b", "c" => "d"
+ @searcher.find(@name)
+ end
- it "should merge the node's facts with its parameters" do
- @node.expects(:fact_merge)
- @searcher.find(@name)
+ it "should set the resulting classes as the node classes" do
+ @result[:classes] = %w{one two}
+ @node.expects(:classes=).with %w{one two}
+ @searcher.find(@name)
+ end
+
+ it "should merge the node's facts with its parameters" do
+ @node.expects(:fact_merge)
+ @searcher.find(@name)
+ end
+
+ it "should set the node's environment if one is provided" do
+ @result[:environment] = "yay"
+ @node.expects(:environment=).with "yay"
+ @searcher.find(@name)
+ end
end
end
diff --git a/spec/unit/indirector/node/ldap.rb b/spec/unit/indirector/node/ldap.rb
index 8c6888357..34456703d 100755
--- a/spec/unit/indirector/node/ldap.rb
+++ b/spec/unit/indirector/node/ldap.rb
@@ -4,168 +4,202 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/indirector/node/ldap'
-module LdapNodeSearching
- def setup
+describe Puppet::Node::Ldap do
+ it "should use the version of the facts as its version" do
@searcher = Puppet::Node::Ldap.new
- @entries = {}
- entries = @entries
-
- @connection = mock 'connection'
- @entry = mock 'entry'
- @connection.stubs(:search).yields(@entry)
- @searcher.stubs(:connection).returns(@connection)
- @searcher.stubs(:class_attributes).returns([])
- @searcher.stubs(:parent_attribute).returns(nil)
- @searcher.stubs(:search_base).returns(:yay)
- @searcher.stubs(:search_filter).returns(:filter)
-
- @node = mock 'node'
- @node.stubs(:fact_merge)
- @name = "mynode"
- Puppet::Node.stubs(:new).with(@name).returns(@node)
+ version = mock 'version'
+ Puppet::Node::Facts.expects(:version).with("me").returns version
+ @searcher.version("me").should equal(version)
end
-end
-describe Puppet::Node::Ldap, " when searching for nodes" do
- include LdapNodeSearching
+ describe "when searching for nodes" do
+ before :each do
+ @searcher = Puppet::Node::Ldap.new
+ @entries = {}
+ entries = @entries
+
+ @connection = mock 'connection'
+ @entry = mock 'entry'
+ @connection.stubs(:search).yields(@entry)
+ @searcher.stubs(:connection).returns(@connection)
+ @searcher.stubs(:class_attributes).returns([])
+ @searcher.stubs(:parent_attribute).returns(nil)
+ @searcher.stubs(:search_base).returns(:yay)
+ @searcher.stubs(:search_filter).returns(:filter)
+
+ @node = mock 'node'
+ @node.stubs(:fact_merge)
+ @name = "mynode"
+ Puppet::Node.stubs(:new).with(@name).returns(@node)
+ end
- it "should return nil if no results are found in ldap" do
- @connection.stubs(:search)
- @searcher.find("mynode").should be_nil
- end
+ it "should return nil if no results are found in ldap" do
+ @connection.stubs(:search)
+ @searcher.find("mynode").should be_nil
+ end
- it "should return a node object if results are found in ldap" do
- @entry.stubs(:to_hash).returns({})
- @searcher.find("mynode").should equal(@node)
- end
+ it "should return a node object if results are found in ldap" do
+ @entry.stubs(:to_hash).returns({})
+ @searcher.find("mynode").should equal(@node)
+ end
- it "should deduplicate class values" do
- @entry.stubs(:to_hash).returns({})
- @searcher.stubs(:class_attributes).returns(%w{one two})
- @entry.stubs(:vals).with("one").returns(%w{a b})
- @entry.stubs(:vals).with("two").returns(%w{b c})
- @node.expects(:classes=).with(%w{a b c})
- @searcher.find("mynode")
- end
+ it "should deduplicate class values" do
+ @entry.stubs(:to_hash).returns({})
+ @searcher.stubs(:class_attributes).returns(%w{one two})
+ @entry.stubs(:vals).with("one").returns(%w{a b})
+ @entry.stubs(:vals).with("two").returns(%w{b c})
+ @node.expects(:classes=).with(%w{a b c})
+ @searcher.find("mynode")
+ end
- it "should add any values stored in the class_attributes attributes to the node classes" do
- @entry.stubs(:to_hash).returns({})
- @searcher.stubs(:class_attributes).returns(%w{one two})
- @entry.stubs(:vals).with("one").returns(%w{a b})
- @entry.stubs(:vals).with("two").returns(%w{c d})
- @node.expects(:classes=).with(%w{a b c d})
- @searcher.find("mynode")
- end
+ it "should add any values stored in the class_attributes attributes to the node classes" do
+ @entry.stubs(:to_hash).returns({})
+ @searcher.stubs(:class_attributes).returns(%w{one two})
+ @entry.stubs(:vals).with("one").returns(%w{a b})
+ @entry.stubs(:vals).with("two").returns(%w{c d})
+ @node.expects(:classes=).with(%w{a b c d})
+ @searcher.find("mynode")
+ end
- it "should add all entry attributes as node parameters" do
- @entry.stubs(:to_hash).returns("one" => ["two"], "three" => ["four"])
- @node.expects(:parameters=).with("one" => "two", "three" => "four")
- @searcher.find("mynode")
- end
+ it "should add all entry attributes as node parameters" do
+ @entry.stubs(:to_hash).returns("one" => ["two"], "three" => ["four"])
+ @node.expects(:parameters=).with("one" => "two", "three" => "four")
+ @searcher.find("mynode")
+ end
- it "should retain false parameter values" do
- @entry.stubs(:to_hash).returns("one" => [false])
- @node.expects(:parameters=).with("one" => false)
- @searcher.find("mynode")
- end
+ it "should set the node's environment to the environment of the results" do
+ @entry.stubs(:to_hash).returns("environment" => ["test"])
+ @node.stubs(:parameters=)
+ @node.expects(:environment=).with("test")
+ @searcher.find("mynode")
+ end
- it "should turn single-value parameter value arrays into single non-arrays" do
- @entry.stubs(:to_hash).returns("one" => ["a"])
- @node.expects(:parameters=).with("one" => "a")
- @searcher.find("mynode")
- end
+ it "should retain false parameter values" do
+ @entry.stubs(:to_hash).returns("one" => [false])
+ @node.expects(:parameters=).with("one" => false)
+ @searcher.find("mynode")
+ end
- it "should keep multi-valued parametes as arrays" do
- @entry.stubs(:to_hash).returns("one" => ["a", "b"])
- @node.expects(:parameters=).with("one" => ["a", "b"])
- @searcher.find("mynode")
- end
-end
+ it "should turn single-value parameter value arrays into single non-arrays" do
+ @entry.stubs(:to_hash).returns("one" => ["a"])
+ @node.expects(:parameters=).with("one" => "a")
+ @searcher.find("mynode")
+ end
-describe Puppet::Node::Ldap, " when a parent node is specified" do
- include LdapNodeSearching
+ it "should keep multi-valued parametes as arrays" do
+ @entry.stubs(:to_hash).returns("one" => ["a", "b"])
+ @node.expects(:parameters=).with("one" => ["a", "b"])
+ @searcher.find("mynode")
+ end
- before do
- @parent = mock 'parent'
- @parent_parent = mock 'parent_parent'
+ describe "and a parent node is specified" do
+ before do
+ @parent = mock 'parent'
+ @parent_parent = mock 'parent_parent'
- @searcher.meta_def(:search_filter) do |name|
- return name
- end
- @connection.stubs(:search).with { |*args| args[2] == @name }.yields(@entry)
- @connection.stubs(:search).with { |*args| args[2] == 'parent' }.yields(@parent)
- @connection.stubs(:search).with { |*args| args[2] == 'parent_parent' }.yields(@parent_parent)
+ @searcher.meta_def(:search_filter) do |name|
+ return name
+ end
+ @connection.stubs(:search).with { |*args| args[2] == @name }.yields(@entry)
+ @connection.stubs(:search).with { |*args| args[2] == 'parent' }.yields(@parent)
+ @connection.stubs(:search).with { |*args| args[2] == 'parent_parent' }.yields(@parent_parent)
- @searcher.stubs(:parent_attribute).returns(:parent)
- end
+ @searcher.stubs(:parent_attribute).returns(:parent)
+ end
- it "should fail if the parent cannot be found" do
- @connection.stubs(:search).with { |*args| args[2] == 'parent' }.returns("whatever")
+ it "should fail if the parent cannot be found" do
+ @connection.stubs(:search).with { |*args| args[2] == 'parent' }.returns("whatever")
- @entry.stubs(:to_hash).returns({})
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ @entry.stubs(:to_hash).returns({})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- proc { @searcher.find("mynode") }.should raise_error(Puppet::Error)
- end
+ proc { @searcher.find("mynode") }.should raise_error(Puppet::Error)
+ end
- it "should add any parent classes to the node's classes" do
- @entry.stubs(:to_hash).returns({})
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
- @entry.stubs(:vals).with("classes").returns(%w{a b})
+ it "should add any parent classes to the node's classes" do
+ @entry.stubs(:to_hash).returns({})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ @entry.stubs(:vals).with("classes").returns(%w{a b})
- @parent.stubs(:to_hash).returns({})
- @parent.stubs(:vals).with("classes").returns(%w{c d})
- @parent.stubs(:vals).with(:parent).returns(nil)
+ @parent.stubs(:to_hash).returns({})
+ @parent.stubs(:vals).with("classes").returns(%w{c d})
+ @parent.stubs(:vals).with(:parent).returns(nil)
- @searcher.stubs(:class_attributes).returns(%w{classes})
- @node.expects(:classes=).with(%w{a b c d})
- @searcher.find("mynode")
- end
+ @searcher.stubs(:class_attributes).returns(%w{classes})
+ @node.expects(:classes=).with(%w{a b c d})
+ @searcher.find("mynode")
+ end
- it "should add any parent parameters to the node's parameters" do
- @entry.stubs(:to_hash).returns("one" => "two")
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ it "should add any parent parameters to the node's parameters" do
+ @entry.stubs(:to_hash).returns("one" => "two")
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- @parent.stubs(:to_hash).returns("three" => "four")
- @parent.stubs(:vals).with(:parent).returns(nil)
+ @parent.stubs(:to_hash).returns("three" => "four")
+ @parent.stubs(:vals).with(:parent).returns(nil)
- @node.expects(:parameters=).with("one" => "two", "three" => "four")
- @searcher.find("mynode")
- end
+ @node.expects(:parameters=).with("one" => "two", "three" => "four")
+ @searcher.find("mynode")
+ end
- it "should prefer node parameters over parent parameters" do
- @entry.stubs(:to_hash).returns("one" => "two")
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ it "should prefer node parameters over parent parameters" do
+ @entry.stubs(:to_hash).returns("one" => "two")
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- @parent.stubs(:to_hash).returns("one" => "three")
- @parent.stubs(:vals).with(:parent).returns(nil)
+ @parent.stubs(:to_hash).returns("one" => "three")
+ @parent.stubs(:vals).with(:parent).returns(nil)
- @node.expects(:parameters=).with("one" => "two")
- @searcher.find("mynode")
- end
+ @node.expects(:parameters=).with("one" => "two")
+ @searcher.find("mynode")
+ end
- it "should recursively look up parent information" do
- @entry.stubs(:to_hash).returns("one" => "two")
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ it "should use the parent's environment if the node has none" do
+ @entry.stubs(:to_hash).returns({})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- @parent.stubs(:to_hash).returns("three" => "four")
- @parent.stubs(:vals).with(:parent).returns(['parent_parent'])
+ @parent.stubs(:to_hash).returns("environment" => ["parent"])
+ @parent.stubs(:vals).with(:parent).returns(nil)
- @parent_parent.stubs(:to_hash).returns("five" => "six")
- @parent_parent.stubs(:vals).with(:parent).returns(nil)
- @parent_parent.stubs(:vals).with(:parent).returns(nil)
+ @node.stubs(:parameters=)
+ @node.expects(:environment=).with("parent")
+ @searcher.find("mynode")
+ end
- @node.expects(:parameters=).with("one" => "two", "three" => "four", "five" => "six")
- @searcher.find("mynode")
- end
+ it "should prefer the node's environment to the parent's" do
+ @entry.stubs(:to_hash).returns("environment" => %w{child})
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
+
+ @parent.stubs(:to_hash).returns("environment" => ["parent"])
+ @parent.stubs(:vals).with(:parent).returns(nil)
+
+ @node.stubs(:parameters=)
+ @node.expects(:environment=).with("child")
+ @searcher.find("mynode")
+ end
+
+ it "should recursively look up parent information" do
+ @entry.stubs(:to_hash).returns("one" => "two")
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
- it "should not allow loops in parent declarations" do
- @entry.stubs(:to_hash).returns("one" => "two")
- @entry.stubs(:vals).with(:parent).returns(%w{parent})
+ @parent.stubs(:to_hash).returns("three" => "four")
+ @parent.stubs(:vals).with(:parent).returns(['parent_parent'])
- @parent.stubs(:to_hash).returns("three" => "four")
- @parent.stubs(:vals).with(:parent).returns([@name])
- proc { @searcher.find("mynode") }.should raise_error(ArgumentError)
+ @parent_parent.stubs(:to_hash).returns("five" => "six")
+ @parent_parent.stubs(:vals).with(:parent).returns(nil)
+ @parent_parent.stubs(:vals).with(:parent).returns(nil)
+
+ @node.expects(:parameters=).with("one" => "two", "three" => "four", "five" => "six")
+ @searcher.find("mynode")
+ end
+
+ it "should not allow loops in parent declarations" do
+ @entry.stubs(:to_hash).returns("one" => "two")
+ @entry.stubs(:vals).with(:parent).returns(%w{parent})
+
+ @parent.stubs(:to_hash).returns("three" => "four")
+ @parent.stubs(:vals).with(:parent).returns([@name])
+ proc { @searcher.find("mynode") }.should raise_error(ArgumentError)
+ end
+ end
end
end
diff --git a/spec/unit/indirector/node/plain.rb b/spec/unit/indirector/node/plain.rb
index 105d0ed63..943af52b4 100755
--- a/spec/unit/indirector/node/plain.rb
+++ b/spec/unit/indirector/node/plain.rb
@@ -15,4 +15,10 @@ describe Puppet::Node::Plain do
node.expects(:fact_merge)
@searcher.find("mynode")
end
+
+ it "should use the version of the facts as its version" do
+ version = mock 'version'
+ Puppet::Node::Facts.expects(:version).with("me").returns version
+ @searcher.version("me").should equal(version)
+ end
end
diff --git a/spec/unit/indirector/rest.rb b/spec/unit/indirector/rest.rb
index cf29577b9..3c4716dc8 100755
--- a/spec/unit/indirector/rest.rb
+++ b/spec/unit/indirector/rest.rb
@@ -13,7 +13,7 @@ describe Puppet::Indirector::REST do
@rest_class = Class.new(Puppet::Indirector::REST) do
def self.to_s
- "Testing"
+ "This::Is::A::Test::Class"
end
end
diff --git a/spec/unit/indirector/terminus.rb b/spec/unit/indirector/terminus.rb
index 99193dbc3..86813e4e5 100755
--- a/spec/unit/indirector/terminus.rb
+++ b/spec/unit/indirector/terminus.rb
@@ -5,8 +5,8 @@ require 'puppet/defaults'
require 'puppet/indirector'
require 'puppet/indirector/file'
-module TerminusInstanceTesting
- def setup
+describe Puppet::Indirector::Terminus do
+ before :each do
Puppet::Indirector::Terminus.stubs(:register_terminus_class)
@indirection = stub 'indirection', :name => :my_stuff, :register_terminus_type => nil
Puppet::Indirector::Indirection.stubs(:instance).with(:my_stuff).returns(@indirection)
@@ -22,51 +22,143 @@ module TerminusInstanceTesting
end
@terminus = @terminus_class.new
end
-end
-describe Puppet::Indirector::Terminus do
- include TerminusInstanceTesting
+ describe Puppet::Indirector::Terminus do
- it "should provide a method for setting terminus class documentation" do
- @terminus_class.should respond_to(:desc)
- end
+ it "should provide a method for setting terminus class documentation" do
+ @terminus_class.should respond_to(:desc)
+ end
- it "should support a class-level name attribute" do
- @terminus_class.should respond_to(:name)
- end
+ it "should support a class-level name attribute" do
+ @terminus_class.should respond_to(:name)
+ end
- it "should support a class-level indirection attribute" do
- @terminus_class.should respond_to(:indirection)
- end
+ it "should support a class-level indirection attribute" do
+ @terminus_class.should respond_to(:indirection)
+ end
- it "should support a class-level terminus-type attribute" do
- @terminus_class.should respond_to(:terminus_type)
- end
+ it "should support a class-level terminus-type attribute" do
+ @terminus_class.should respond_to(:terminus_type)
+ end
- it "should support a class-level model attribute" do
- @terminus_class.should respond_to(:model)
+ it "should support a class-level model attribute" do
+ @terminus_class.should respond_to(:model)
+ end
+
+ it "should accept indirection instances as its indirection" do
+ indirection = stub 'indirection', :is_a? => true, :register_terminus_type => nil
+ proc { @terminus_class.indirection = indirection }.should_not raise_error
+ @terminus_class.indirection.should equal(indirection)
+ end
+
+ it "should look up indirection instances when only a name has been provided" do
+ indirection = mock 'indirection'
+ Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(indirection)
+ @terminus_class.indirection = :myind
+ @terminus_class.indirection.should equal(indirection)
+ end
+
+ it "should fail when provided a name that does not resolve to an indirection" do
+ Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(nil)
+ proc { @terminus_class.indirection = :myind }.should raise_error(ArgumentError)
+
+ # It shouldn't overwrite our existing one (or, more normally, it shouldn't set
+ # anything).
+ @terminus_class.indirection.should equal(@indirection)
+ end
end
- it "should accept indirection instances as its indirection" do
- indirection = stub 'indirection', :is_a? => true, :register_terminus_type => nil
- proc { @terminus_class.indirection = indirection }.should_not raise_error
- @terminus_class.indirection.should equal(indirection)
+ describe Puppet::Indirector::Terminus, " when creating terminus classes" do
+ it "should associate the subclass with an indirection based on the subclass constant" do
+ @terminus.indirection.should equal(@indirection)
+ end
+
+ it "should set the subclass's type to the abstract terminus name" do
+ @terminus.terminus_type.should == :abstract
+ end
+
+ it "should set the subclass's name to the indirection name" do
+ @terminus.name.should == :term_type
+ end
+
+ it "should set the subclass's model to the indirection model" do
+ @indirection.expects(:model).returns :yay
+ @terminus.model.should == :yay
+ end
end
- it "should look up indirection instances when only a name has been provided" do
- indirection = mock 'indirection'
- Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(indirection)
- @terminus_class.indirection = :myind
- @terminus_class.indirection.should equal(indirection)
+ describe Puppet::Indirector::Terminus, " when a terminus instance" do
+
+ it "should return the class's name as its name" do
+ @terminus.name.should == :term_type
+ end
+
+ it "should return the class's indirection as its indirection" do
+ @terminus.indirection.should equal(@indirection)
+ end
+
+ it "should set the instances's type to the abstract terminus type's name" do
+ @terminus.terminus_type.should == :abstract
+ end
+
+ it "should set the instances's model to the indirection's model" do
+ @indirection.expects(:model).returns :yay
+ @terminus.model.should == :yay
+ end
end
- it "should fail when provided a name that does not resolve to an indirection" do
- Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(nil)
- proc { @terminus_class.indirection = :myind }.should raise_error(ArgumentError)
+ describe Puppet::Indirector::Terminus, " when managing indirected instances" do
+
+ it "should support comparing an instance's version with the terminus's version using just the instance's key" do
+ @terminus.should respond_to(:has_most_recent?)
+ end
+
+ it "should fail if the :version method has not been overridden and no :find method is available" do
+ proc { @terminus.version('yay') }.should raise_error(Puppet::DevError)
+ end
+
+ it "should use a found instance's version by default" do
+ name = 'instance'
+ instance = stub name, :version => 2
+ @terminus.expects(:find).with(name).returns(instance)
+ @terminus.version(name).should == 2
+ end
- # It shouldn't overwrite our existing one (or, more normally, it shouldn't set
- # anything).
- @terminus_class.indirection.should equal(@indirection)
+ it "should return nil as the version if no instance can be found" do
+ name = 'instance'
+ @terminus.expects(:find).with(name).returns(nil)
+ @terminus.version(name).should be_nil
+ end
+
+ it "should consider an instance fresh if its version is more recent than the version provided" do
+ name = "yay"
+ @terminus.expects(:version).with(name).returns(5)
+ @terminus.has_most_recent?(name, 4).should be_true
+ end
+
+ it "should consider an instance fresh if its version is equal to the version provided" do
+ name = "yay"
+ @terminus.expects(:version).with(name).returns(5)
+ @terminus.has_most_recent?(name, 5).should be_true
+ end
+
+ it "should consider an instance not fresh if the provided version is more recent than its version" do
+ name = "yay"
+ @terminus.expects(:version).with(name).returns(4)
+ @terminus.has_most_recent?(name, 5).should be_false
+ end
+
+ # Times annoyingly can't be compared directly to numbers, and our
+ # default version is 0.
+ it "should convert versions to floats when checking for freshness" do
+ existing = mock 'existing version'
+ new = mock 'new version'
+ existing.expects(:to_f).returns(1.0)
+ new.expects(:to_f).returns(1.0)
+ name = "yay"
+ @terminus.expects(:version).with(name).returns(existing)
+ @terminus.has_most_recent?(name, new)
+ end
end
end
@@ -205,98 +297,3 @@ describe Puppet::Indirector::Terminus, " when creating terminus class types" do
end
end
-describe Puppet::Indirector::Terminus, " when creating terminus classes" do
- include TerminusInstanceTesting
- it "should associate the subclass with an indirection based on the subclass constant" do
- @terminus.indirection.should equal(@indirection)
- end
-
- it "should set the subclass's type to the abstract terminus name" do
- @terminus.terminus_type.should == :abstract
- end
-
- it "should set the subclass's name to the indirection name" do
- @terminus.name.should == :term_type
- end
-
- it "should set the subclass's model to the indirection model" do
- @indirection.expects(:model).returns :yay
- @terminus.model.should == :yay
- end
-end
-
-describe Puppet::Indirector::Terminus, " when a terminus instance" do
- include TerminusInstanceTesting
-
- it "should return the class's name as its name" do
- @terminus.name.should == :term_type
- end
-
- it "should return the class's indirection as its indirection" do
- @terminus.indirection.should equal(@indirection)
- end
-
- it "should set the instances's type to the abstract terminus type's name" do
- @terminus.terminus_type.should == :abstract
- end
-
- it "should set the instances's model to the indirection's model" do
- @indirection.expects(:model).returns :yay
- @terminus.model.should == :yay
- end
-end
-
-describe Puppet::Indirector::Terminus, " when managing indirected instances" do
- include TerminusInstanceTesting
-
- it "should support comparing an instance's version with the terminus's version using just the instance's key" do
- @terminus.should respond_to(:has_most_recent?)
- end
-
- it "should fail if the :version method has not been overridden and no :find method is available" do
- proc { @terminus.version('yay') }.should raise_error(Puppet::DevError)
- end
-
- it "should use a found instance's version by default" do
- name = 'instance'
- instance = stub name, :version => 2
- @terminus.expects(:find).with(name).returns(instance)
- @terminus.version(name).should == 2
- end
-
- it "should return nil as the version if no instance can be found" do
- name = 'instance'
- @terminus.expects(:find).with(name).returns(nil)
- @terminus.version(name).should be_nil
- end
-
- it "should consider an instance fresh if its version is more recent than the version provided" do
- name = "yay"
- @terminus.expects(:version).with(name).returns(5)
- @terminus.has_most_recent?(name, 4).should be_true
- end
-
- it "should consider an instance fresh if its version is equal to the version provided" do
- name = "yay"
- @terminus.expects(:version).with(name).returns(5)
- @terminus.has_most_recent?(name, 5).should be_true
- end
-
- it "should consider an instance not fresh if the provided version is more recent than its version" do
- name = "yay"
- @terminus.expects(:version).with(name).returns(4)
- @terminus.has_most_recent?(name, 5).should be_false
- end
-
- # Times annoyingly can't be compared directly to numbers, and our
- # default version is 0.
- it "should convert versions to floats when checking for freshness" do
- existing = mock 'existing version'
- new = mock 'new version'
- existing.expects(:to_f).returns(1.0)
- new.expects(:to_f).returns(1.0)
- name = "yay"
- @terminus.expects(:version).with(name).returns(existing)
- @terminus.has_most_recent?(name, new)
- end
-end
diff --git a/spec/unit/indirector/yaml.rb b/spec/unit/indirector/yaml.rb
index f217a31b5..339529ab0 100755
--- a/spec/unit/indirector/yaml.rb
+++ b/spec/unit/indirector/yaml.rb
@@ -4,8 +4,8 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector/yaml'
-module YamlTesting
- def setup
+describe Puppet::Indirector::Yaml, " when choosing file location" do
+ before :each do
@indirection = stub 'indirection', :name => :my_yaml, :register_terminus_type => nil
Puppet::Indirector::Indirection.stubs(:instance).with(:my_yaml).returns(@indirection)
@store_class = Class.new(Puppet::Indirector::Yaml) do
@@ -20,85 +20,91 @@ module YamlTesting
@subject.name = :me
@dir = "/what/ever"
- Puppet.settings.stubs(:use)
Puppet.settings.stubs(:value).with(:yamldir).returns(@dir)
end
-end
-describe Puppet::Indirector::Yaml, " when choosing file location" do
- include YamlTesting
+ it "should use the mtime of the written file as the version" do
+ stat = mock 'stat'
+ FileTest.stubs(:exist?).returns true
+ File.expects(:stat).returns stat
+ time = Time.now
+ stat.expects(:mtime).returns time
- it "should store all files in a single file root set in the Puppet defaults" do
- @store.send(:path, :me).should =~ %r{^#{@dir}}
+ @store.version(:me).should equal(time)
end
- it "should use the terminus name for choosing the subdirectory" do
- @store.send(:path, :me).should =~ %r{^#{@dir}/my_yaml}
- end
+ describe Puppet::Indirector::Yaml, " when choosing file location" do
- it "should use the object's name to determine the file name" do
- @store.send(:path, :me).should =~ %r{me.yaml$}
- end
-end
+ it "should store all files in a single file root set in the Puppet defaults" do
+ @store.send(:path, :me).should =~ %r{^#{@dir}}
+ end
-describe Puppet::Indirector::Yaml, " when storing objects as YAML" do
- include YamlTesting
+ it "should use the terminus name for choosing the subdirectory" do
+ @store.send(:path, :me).should =~ %r{^#{@dir}/my_yaml}
+ end
- it "should only store objects that respond to :name" do
- proc { @store.save(Object.new) }.should raise_error(ArgumentError)
+ it "should use the object's name to determine the file name" do
+ @store.send(:path, :me).should =~ %r{me.yaml$}
+ end
end
- it "should convert Ruby objects to YAML and write them to disk" do
- yaml = @subject.to_yaml
- file = mock 'file'
- path = @store.send(:path, @subject.name)
- FileTest.expects(:exist?).with(File.dirname(path)).returns(true)
- File.expects(:open).with(path, "w", 0660).yields(file)
- file.expects(:print).with(yaml)
+ describe Puppet::Indirector::Yaml, " when storing objects as YAML" do
- @store.save(@subject)
- end
+ it "should only store objects that respond to :name" do
+ proc { @store.save(Object.new) }.should raise_error(ArgumentError)
+ end
- it "should create the indirection subdirectory if it does not exist" do
- yaml = @subject.to_yaml
- file = mock 'file'
- path = @store.send(:path, @subject.name)
- dir = File.dirname(path)
- FileTest.expects(:exist?).with(dir).returns(false)
- Dir.expects(:mkdir).with(dir)
- File.expects(:open).with(path, "w", 0660).yields(file)
- file.expects(:print).with(yaml)
-
- @store.save(@subject)
- end
-end
+ it "should convert Ruby objects to YAML and write them to disk" do
+ yaml = @subject.to_yaml
+ file = mock 'file'
+ path = @store.send(:path, @subject.name)
+ FileTest.expects(:exist?).with(File.dirname(path)).returns(true)
+ File.expects(:open).with(path, "w", 0660).yields(file)
+ file.expects(:print).with(yaml)
-describe Puppet::Indirector::Yaml, " when retrieving YAML" do
- include YamlTesting
+ @store.save(@subject)
+ end
- it "should require the name of the object to retrieve" do
- proc { @store.find(nil) }.should raise_error(ArgumentError)
+ it "should create the indirection subdirectory if it does not exist" do
+ yaml = @subject.to_yaml
+ file = mock 'file'
+ path = @store.send(:path, @subject.name)
+ dir = File.dirname(path)
+ FileTest.expects(:exist?).with(dir).returns(false)
+ Dir.expects(:mkdir).with(dir)
+ File.expects(:open).with(path, "w", 0660).yields(file)
+ file.expects(:print).with(yaml)
+
+ @store.save(@subject)
+ end
end
- it "should read YAML in from disk and convert it to Ruby objects" do
- path = @store.send(:path, @subject.name)
+ describe Puppet::Indirector::Yaml, " when retrieving YAML" do
+
+ it "should require the name of the object to retrieve" do
+ proc { @store.find(nil) }.should raise_error(ArgumentError)
+ end
- yaml = @subject.to_yaml
- FileTest.expects(:exist?).with(path).returns(true)
- File.expects(:read).with(path).returns(yaml)
+ it "should read YAML in from disk and convert it to Ruby objects" do
+ path = @store.send(:path, @subject.name)
- @store.find(@subject.name).instance_variable_get("@name").should == :me
- end
+ yaml = @subject.to_yaml
+ FileTest.expects(:exist?).with(path).returns(true)
+ File.expects(:read).with(path).returns(yaml)
- it "should fail coherently when the stored YAML is invalid" do
- path = @store.send(:path, @subject.name)
+ @store.find(@subject.name).instance_variable_get("@name").should == :me
+ end
- # Something that will fail in yaml
- yaml = "--- !ruby/object:Hash"
+ it "should fail coherently when the stored YAML is invalid" do
+ path = @store.send(:path, @subject.name)
- FileTest.expects(:exist?).with(path).returns(true)
- File.expects(:read).with(path).returns(yaml)
+ # Something that will fail in yaml
+ yaml = "--- !ruby/object:Hash"
- proc { @store.find(@subject.name) }.should raise_error(Puppet::Error)
+ FileTest.expects(:exist?).with(path).returns(true)
+ File.expects(:read).with(path).returns(yaml)
+
+ proc { @store.find(@subject.name) }.should raise_error(Puppet::Error)
+ end
end
end
diff --git a/spec/unit/network/client.rb b/spec/unit/network/client.rb
new file mode 100644
index 000000000..bc41efb4f
--- /dev/null
+++ b/spec/unit/network/client.rb
@@ -0,0 +1,43 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-3-24.
+# Copyright (c) 2008. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/network/client'
+
+describe Puppet::Network::Client do
+ before do
+ Puppet::Network::HttpPool.stubs(:cert_setup)
+ end
+ describe "when keep-alive is enabled" do
+ before do
+ Puppet::Network::HttpPool.stubs(:keep_alive?).returns true
+ end
+ it "should start the http client up on creation" do
+ http = mock 'http'
+ http.stub_everything
+ http.expects(:start)
+ Net::HTTP.stubs(:new).returns http
+
+ # Pick a random subclass...
+ Puppet::Network::Client.master.new :Server => Puppet[:server]
+ end
+ end
+
+ describe "when keep-alive is disabled" do
+ before do
+ Puppet::Network::HttpPool.stubs(:keep_alive?).returns false
+ end
+ it "should not start the http client up on creation" do
+ http = mock 'http'
+ http.stub_everything
+ http.expects(:start).never
+ Net::HTTP.stubs(:new).returns http
+
+ # Pick a random subclass...
+ Puppet::Network::Client.master.new :Server => Puppet[:server]
+ end
+ end
+end
diff --git a/spec/unit/network/http_pool.rb b/spec/unit/network/http_pool.rb
index 49da7d8f3..1fbc17471 100755
--- a/spec/unit/network/http_pool.rb
+++ b/spec/unit/network/http_pool.rb
@@ -9,6 +9,13 @@ require 'puppet/network/http_pool'
describe Puppet::Network::HttpPool, " when adding certificate information to http instances" do
before do
@http = mock 'http'
+ [:cert_store=, :verify_mode=, :ca_file=, :cert=, :key=].each { |m| @http.stubs(m) }
+ @store = stub 'store'
+ [:add_file,:purpose=].each { |m| @store.stubs(m) }
+ end
+
+ it "should have keep-alive disabled" do
+ Puppet::Network::HttpPool::HTTP_KEEP_ALIVE.should be_false
end
it "should do nothing if no certificate is available" do
@@ -19,26 +26,19 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
it "should add a certificate store" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
- store = stub "store"
- OpenSSL::X509::Store.expects(:new).returns(store)
- store.stubs(:add_file)
- store.stubs(:purpose=)
- [:verify_mode=, :ca_file=, :cert=, :key=].each { |method| @http.stubs(method) }
- @http.expects(:cert_store=).with(store)
+ Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
+ OpenSSL::X509::Store.expects(:new).returns(@store)
+ @http.expects(:cert_store=).with(@store)
Puppet::Network::HttpPool.cert_setup(@http)
end
it "should add the local CA cert to the certificate store" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
- store = stub "store"
- OpenSSL::X509::Store.expects(:new).returns(store)
- store.stubs(:purpose=)
- @http.stubs(:cert_store=)
+ OpenSSL::X509::Store.expects(:new).returns(@store)
Puppet.settings.stubs(:value).with(:localcacert).returns("/some/file")
Puppet.settings.stubs(:value).with(:localcacert).returns("/some/file")
- store.expects(:add_file).with("/some/file")
- [:store=, :verify_mode=, :ca_file=, :cert=, :key=].each { |method| @http.stubs(method) }
+ @store.expects(:add_file).with("/some/file")
Puppet::Network::HttpPool.stubs(:key).returns(:whatever)
@@ -47,12 +47,10 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
it "should set the purpose of the cert store to OpenSSL::X509::PURPOSE_SSL_CLIENT" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
- store = stub "store"
- OpenSSL::X509::Store.expects(:new).returns(store)
- store.stubs(:add_file)
- [:cert_store=, :verify_mode=, :ca_file=, :cert=, :key=].each { |method| @http.stubs(method) }
+ Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
+ OpenSSL::X509::Store.expects(:new).returns(@store)
- store.expects(:purpose=).with(OpenSSL::X509::PURPOSE_SSL_CLIENT)
+ @store.expects(:purpose=).with(OpenSSL::X509::PURPOSE_SSL_CLIENT)
Puppet::Network::HttpPool.cert_setup(@http)
end
@@ -60,7 +58,8 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
it "should add the client certificate" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
Puppet::Network::HttpPool.stubs(:cert).returns(:mycert)
- [:cert_store=, :verify_mode=, :ca_file=, :key=].each { |method| @http.stubs(method) }
+ Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
+ OpenSSL::X509::Store.expects(:new).returns(@store)
@http.expects(:cert=).with(:mycert)
@@ -70,7 +69,7 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
it "should add the client key" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
- [:cert_store=, :verify_mode=, :cert=, :ca_file=].each { |method| @http.stubs(method) }
+ OpenSSL::X509::Store.expects(:new).returns(@store)
@http.expects(:key=).with(:mykey)
@@ -79,7 +78,8 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
it "should set the verify mode to OpenSSL::SSL::VERIFY_PEER" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
- [:key=, :cert=, :cert_store=, :ca_file=].each { |method| @http.stubs(method) }
+ Puppet::Network::HttpPool.stubs(:key).returns(:mykey)
+ OpenSSL::X509::Store.expects(:new).returns(@store)
@http.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
@@ -89,12 +89,7 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
it "should set the ca file" do
Puppet::Network::HttpPool.stubs(:read_cert).returns(true)
Puppet.settings.stubs(:value).with(:localcacert).returns("/some/file")
- [:key=, :cert=, :cert_store=, :verify_mode=].each { |method| @http.stubs(method) }
-
- store = stub "store"
- OpenSSL::X509::Store.expects(:new).returns(store)
- store.stubs(:purpose=)
- store.stubs(:add_file)
+ OpenSSL::X509::Store.expects(:new).returns(@store)
@http.expects(:ca_file=).with("/some/file")
@@ -111,117 +106,135 @@ describe Puppet::Network::HttpPool, " when adding certificate information to htt
after do
Puppet::Network::HttpPool.clear_http_instances
end
-end
-describe Puppet::Network::HttpPool, " when managing http instances" do
- def stub_settings(settings)
- settings.each do |param, value|
- Puppet.settings.stubs(:value).with(param).returns(value)
+ describe "when managing http instances" do
+ def stub_settings(settings)
+ settings.each do |param, value|
+ Puppet.settings.stubs(:value).with(param).returns(value)
+ end
end
- end
-
- before do
- # All of hte cert stuff is tested elsewhere
- Puppet::Network::HttpPool.stubs(:cert_setup)
- end
- it "should return an http instance created with the passed host and port" do
- http = stub 'http', :use_ssl= => nil, :read_timeout= => nil, :open_timeout= => nil, :enable_post_connection_check= => nil, :started? => false
- Net::HTTP.expects(:new).with("me", 54321, nil, nil).returns(http)
- Puppet::Network::HttpPool.http_instance("me", 54321).should equal(http)
- end
-
- it "should enable ssl on the http instance" do
- Puppet::Network::HttpPool.http_instance("me", 54321).instance_variable_get("@use_ssl").should be_true
- end
-
- it "should set the read timeout" do
- Puppet::Network::HttpPool.http_instance("me", 54321).read_timeout.should == 120
- end
+ before do
+ # All of hte cert stuff is tested elsewhere
+ Puppet::Network::HttpPool.stubs(:cert_setup)
+ end
- it "should set the open timeout" do
- Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120
- end
+ it "should return an http instance created with the passed host and port" do
+ http = stub 'http', :use_ssl= => nil, :read_timeout= => nil, :open_timeout= => nil, :enable_post_connection_check= => nil, :started? => false
+ Net::HTTP.expects(:new).with("me", 54321, nil, nil).returns(http)
+ Puppet::Network::HttpPool.http_instance("me", 54321).should equal(http)
+ end
- it "should default to http_enable_post_connection_check being enabled" do
- Puppet.settings[:http_enable_post_connection_check].should be_true
- end
+ it "should enable ssl on the http instance" do
+ Puppet::Network::HttpPool.http_instance("me", 54321).instance_variable_get("@use_ssl").should be_true
+ end
- # JJM: I'm not sure if this is correct, as this really follows the
- # configuration option.
- it "should set enable_post_connection_check true " do
- Puppet::Network::HttpPool.http_instance("me", 54321).instance_variable_get("@enable_post_connection_check").should be_true
- end
+ it "should set the read timeout" do
+ Puppet::Network::HttpPool.http_instance("me", 54321).read_timeout.should == 120
+ end
- it "should create the http instance with the proxy host and port set if the http_proxy is not set to 'none'" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120
- end
+ it "should set the open timeout" do
+ Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120
+ end
- it "should cache http instances" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old)
- end
+ it "should default to http_enable_post_connection_check being enabled" do
+ Puppet.settings[:http_enable_post_connection_check].should be_true
+ end
- it "should have a mechanism for getting a new http instance instead of the cached instance" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- Puppet::Network::HttpPool.http_instance("me", 54321, true).should_not equal(old)
- end
+ # JJM: I'm not sure if this is correct, as this really follows the
+ # configuration option.
+ it "should set enable_post_connection_check true " do
+ Puppet::Network::HttpPool.http_instance("me", 54321).instance_variable_get("@enable_post_connection_check").should be_true
+ end
- it "should close existing, open connections when requesting a new connection" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- old.expects(:started?).returns(true)
- old.expects(:finish)
- Puppet::Network::HttpPool.http_instance("me", 54321, true)
- end
+ it "should create the http instance with the proxy host and port set if the http_proxy is not set to 'none'" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ Puppet::Network::HttpPool.http_instance("me", 54321).open_timeout.should == 120
+ end
- it "should have a mechanism for clearing the http cache" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old)
- old = Puppet::Network::HttpPool.http_instance("me", 54321)
- Puppet::Network::HttpPool.clear_http_instances
- Puppet::Network::HttpPool.http_instance("me", 54321).should_not equal(old)
- end
+ describe "when http keep-alive is enabled" do
+ before do
+ Puppet::Network::HttpPool.stubs(:keep_alive?).returns true
+ end
+
+ it "should cache http instances" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old)
+ end
+
+ it "should have a mechanism for getting a new http instance instead of the cached instance" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.http_instance("me", 54321, true).should_not equal(old)
+ end
+
+ it "should close existing, open connections when requesting a new connection" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ old.expects(:started?).returns(true)
+ old.expects(:finish)
+ Puppet::Network::HttpPool.http_instance("me", 54321, true)
+ end
+
+ it "should have a mechanism for clearing the http cache" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.http_instance("me", 54321).should equal(old)
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.clear_http_instances
+ Puppet::Network::HttpPool.http_instance("me", 54321).should_not equal(old)
+ end
+
+ it "should close open http connections when clearing the cache" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ one = Puppet::Network::HttpPool.http_instance("me", 54321)
+ one.expects(:started?).returns(true)
+ one.expects(:finish).returns(true)
+ Puppet::Network::HttpPool.clear_http_instances
+ end
+
+ it "should not close unopened http connections when clearing the cache" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ one = Puppet::Network::HttpPool.http_instance("me", 54321)
+ one.expects(:started?).returns(false)
+ one.expects(:finish).never
+ Puppet::Network::HttpPool.clear_http_instances
+ end
+ end
- it "should close open http connections when clearing the cache" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- one = Puppet::Network::HttpPool.http_instance("me", 54321)
- one.expects(:started?).returns(true)
- one.expects(:finish).returns(true)
- Puppet::Network::HttpPool.clear_http_instances
- end
+ describe "when http keep-alive is disabled" do
+ before do
+ Puppet::Network::HttpPool.stubs(:keep_alive?).returns false
+ end
- it "should not close unopened http connections when clearing the cache" do
- stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
- one = Puppet::Network::HttpPool.http_instance("me", 54321)
- one.expects(:started?).returns(false)
- one.expects(:finish).never
- Puppet::Network::HttpPool.clear_http_instances
- end
+ it "should not cache http instances" do
+ stub_settings :http_proxy_host => "myhost", :http_proxy_port => 432, :http_enable_post_connection_check => true
+ old = Puppet::Network::HttpPool.http_instance("me", 54321)
+ Puppet::Network::HttpPool.http_instance("me", 54321).should_not equal(old)
+ end
+ end
- # We mostly have to do this for testing, since in real life people
- # won't change certs within a single process.
- it "should remove its loaded certificate when clearing the cache" do
- Puppet::Network::HttpPool.instance_variable_set("@cert", :yay)
- Puppet::Network::HttpPool.clear_http_instances
- # Can't use the accessor, because it will read the cert in
- Puppet::Network::HttpPool.instance_variable_get("@cert").should be_nil
- end
+ # We mostly have to do this for testing, since in real life people
+ # won't change certs within a single process.
+ it "should remove its loaded certificate when clearing the cache" do
+ Puppet::Network::HttpPool.instance_variable_set("@cert", :yay)
+ Puppet::Network::HttpPool.clear_http_instances
+ # Can't use the accessor, because it will read the cert in
+ Puppet::Network::HttpPool.instance_variable_get("@cert").should be_nil
+ end
- # We mostly have to do this for testing, since in real life people
- # won't change certs within a single process.
- it "should remove its loaded key when clearing the cache" do
- Puppet::Network::HttpPool.instance_variable_set("@key", :yay)
- Puppet::Network::HttpPool.clear_http_instances
- # Can't use the accessor, because it will read the cert in
- Puppet::Network::HttpPool.instance_variable_get("@key").should be_nil
- end
+ # We mostly have to do this for testing, since in real life people
+ # won't change certs within a single process.
+ it "should remove its loaded key when clearing the cache" do
+ Puppet::Network::HttpPool.instance_variable_set("@key", :yay)
+ Puppet::Network::HttpPool.clear_http_instances
+ # Can't use the accessor, because it will read the cert in
+ Puppet::Network::HttpPool.instance_variable_get("@key").should be_nil
+ end
- after do
- Puppet::Network::HttpPool.clear_http_instances
+ after do
+ Puppet::Network::HttpPool.clear_http_instances
+ end
end
end
diff --git a/spec/unit/network/server.rb b/spec/unit/network/server.rb
index 3e29807ad..846b5471d 100644
--- a/spec/unit/network/server.rb
+++ b/spec/unit/network/server.rb
@@ -212,7 +212,7 @@ describe Puppet::Network::Server, "when listening is on" do
@server.listen
end
- it "should indicate that listening is turned off" do
+ it "should indicate that it is listening" do
@server.should be_listening
end
@@ -235,14 +235,14 @@ describe Puppet::Network::Server, "when listening is being turned on" do
@mock_http_server.stubs(:listen)
end
- it "should fetch an instance of an HTTP server when listening is turned on" do
+ it "should fetch an instance of an HTTP server" do
mock_http_server_class = mock('http server class')
mock_http_server_class.expects(:new).returns(@mock_http_server)
@server.expects(:http_server_class).returns(mock_http_server_class)
@server.listen
end
- it "should cause the HTTP server to listen when listening is turned on" do
+ it "should cause the HTTP server to listen" do
@mock_http_server.expects(:listen)
@server.expects(:http_server).returns(@mock_http_server)
@server.listen
@@ -261,7 +261,7 @@ describe Puppet::Network::Server, "when listening is being turned off" do
@server.listen
end
- it "should cause the HTTP server to stop listening when listening is turned off" do
+ it "should cause the HTTP server to stop listening" do
@mock_http_server.expects(:unlisten)
@server.unlisten
end
diff --git a/spec/unit/node.rb b/spec/unit/node.rb
index 0ce702936..bb99378d9 100755
--- a/spec/unit/node.rb
+++ b/spec/unit/node.rb
@@ -113,6 +113,22 @@ describe Puppet::Node, " when merging facts" do
@node.merge "two" => "three"
@node.parameters["two"].should == "three"
end
+
+ it "should add the environment to the list of parameters" do
+ Puppet.settings.stubs(:value).with(:environments).returns("one,two")
+ Puppet.settings.stubs(:value).with(:environment).returns("one")
+ @node = Puppet::Node.new("testnode", :environment => "one")
+ @node.merge "two" => "three"
+ @node.parameters["environment"].should == "one"
+ end
+
+ it "should not set the environment if it is already set in the parameters" do
+ Puppet.settings.stubs(:value).with(:environments).returns("one,two")
+ Puppet.settings.stubs(:value).with(:environment).returns("one")
+ @node = Puppet::Node.new("testnode", :environment => "one")
+ @node.merge "environment" => "two"
+ @node.parameters["environment"].should == "two"
+ end
end
describe Puppet::Node, " when indirecting" do
@@ -127,6 +143,10 @@ describe Puppet::Node, " when indirecting" do
Puppet::Node.indirection.terminus_class.should == :plain
end
+ it "should not have a cache class defined" do
+ Puppet::Node.indirection.cache_class.should be_nil
+ end
+
after do
Puppet::Indirector::Indirection.clear_cache
end
diff --git a/spec/unit/node/catalog.rb b/spec/unit/node/catalog.rb
index 4f9613d00..434242103 100755
--- a/spec/unit/node/catalog.rb
+++ b/spec/unit/node/catalog.rb
@@ -57,11 +57,11 @@ describe Puppet::Node::Catalog, " when extracting transobjects" do
def mkscope
@parser = Puppet::Parser::Parser.new :Code => ""
@node = Puppet::Node.new("mynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
# XXX This is ridiculous.
- @compile.send(:evaluate_main)
- @scope = @compile.topscope
+ @compiler.send(:evaluate_main)
+ @scope = @compiler.topscope
end
def mkresource(type, name)
@@ -75,7 +75,7 @@ describe Puppet::Node::Catalog, " when extracting transobjects" do
@source = mock 'source'
main = mkresource("class", :main)
- config.add_vertex!(main)
+ config.add_vertex(main)
bucket = mock 'bucket'
bucket.expects(:classes=).with(config.classes)
@@ -95,7 +95,7 @@ describe Puppet::Node::Catalog, " when extracting transobjects" do
defined = mkresource("class", :main)
builtin = mkresource("file", "/yay")
- config.add_edge!(defined, builtin)
+ config.add_edge(defined, builtin)
bucket = []
bucket.expects(:classes=).with(config.classes)
@@ -121,21 +121,21 @@ describe Puppet::Node::Catalog, " when extracting transobjects" do
top.expects(:to_trans).returns(topbucket)
topres = mkresource "file", "/top"
topres.expects(:to_trans).returns(:topres)
- config.add_edge! top, topres
+ config.add_edge top, topres
middle = mkresource "class", "middle"
middle.expects(:to_trans).returns([])
- config.add_edge! top, middle
+ config.add_edge top, middle
midres = mkresource "file", "/mid"
midres.expects(:to_trans).returns(:midres)
- config.add_edge! middle, midres
+ config.add_edge middle, midres
bottom = mkresource "class", "bottom"
bottom.expects(:to_trans).returns([])
- config.add_edge! middle, bottom
+ config.add_edge middle, bottom
botres = mkresource "file", "/bot"
botres.expects(:to_trans).returns(:botres)
- config.add_edge! bottom, botres
+ config.add_edge bottom, botres
toparray = config.extract_to_transportable
@@ -196,13 +196,13 @@ describe Puppet::Node::Catalog, " when converting to a transobject catalog" do
@resources = [@top, @topobject, @middle, @middleobject, @bottom, @bottomobject]
- @original.add_edge!(@top, @topobject)
- @original.add_edge!(@top, @virtual)
- @original.add_edge!(@virtual, @virtualobject)
- @original.add_edge!(@top, @middle)
- @original.add_edge!(@middle, @middleobject)
- @original.add_edge!(@middle, @bottom)
- @original.add_edge!(@bottom, @bottomobject)
+ @original.add_edge(@top, @topobject)
+ @original.add_edge(@top, @virtual)
+ @original.add_edge(@virtual, @virtualobject)
+ @original.add_edge(@top, @middle)
+ @original.add_edge(@middle, @middleobject)
+ @original.add_edge(@middle, @bottom)
+ @original.add_edge(@bottom, @bottomobject)
@catalog = @original.to_transportable
end
@@ -261,11 +261,11 @@ describe Puppet::Node::Catalog, " when converting to a RAL catalog" do
@original.add_resource(*@resources)
- @original.add_edge!(@top, @topobject)
- @original.add_edge!(@top, @middle)
- @original.add_edge!(@middle, @middleobject)
- @original.add_edge!(@middle, @bottom)
- @original.add_edge!(@bottom, @bottomobject)
+ @original.add_edge(@top, @topobject)
+ @original.add_edge(@top, @middle)
+ @original.add_edge(@middle, @middleobject)
+ @original.add_edge(@middle, @bottom)
+ @original.add_edge(@bottom, @bottomobject)
@catalog = @original.to_ral
end
@@ -300,10 +300,12 @@ describe Puppet::Node::Catalog, " when converting to a RAL catalog" do
config.add_resource(changer)
config.add_resource(@top)
- config.add_edge!(@top, changer)
+ config.add_edge(@top, changer)
resource = stub 'resource', :name => "changer2", :title => "changer2", :ref => "Test[changer2]", :catalog= => nil, :remove => nil
+ #changer is going to get duplicated as part of a fix for aliases 1094
+ changer.expects(:dup).returns(changer)
changer.expects(:to_type).returns(resource)
newconfig = nil
@@ -363,6 +365,12 @@ describe Puppet::Node::Catalog, " when functioning as a resource container" do
it "should not allow two resources with the same resource reference" do
@catalog.add_resource(@one)
+
+ # These are used to build the failure
+ @dupe.stubs(:file)
+ @dupe.stubs(:line)
+ @one.stubs(:file)
+ @one.stubs(:line)
proc { @catalog.add_resource(@dupe) }.should raise_error(ArgumentError)
end
@@ -469,9 +477,15 @@ describe Puppet::Node::Catalog, " when functioning as a resource container" do
proc { @catalog.alias @two, "one" }.should raise_error(ArgumentError)
end
- it "should fail to add an alias if the aliased name already exists as an alias" do
- @catalog.alias(@one, "yayness")
- proc { @catalog.alias @two, "yayness" }.should raise_error(ArgumentError)
+ it "should not fail when a resource has duplicate aliases created" do
+ @catalog.add_resource @one
+ proc { @catalog.alias @one, "one" }.should_not raise_error
+ end
+
+ it "should be able to look resources up by their aliases" do
+ @catalog.add_resource @one
+ @catalog.alias @one, "two"
+ @catalog.resource(:me, "two").should equal(@one)
end
it "should remove resource aliases when the target resource is removed" do
@@ -482,15 +496,32 @@ describe Puppet::Node::Catalog, " when functioning as a resource container" do
@catalog.resource("me", "other").should be_nil
end
- it "should return aliased resources when asked for the resource by the alias" do
- @catalog.add_resource @one
- @catalog.alias(@one, "other")
- @catalog.resource("Me[other]").should equal(@one)
+ it "should add an alias for the namevar when the title and name differ on isomorphic resource types" do
+ resource = Puppet::Type.type(:file).create :path => "/something", :title => "other", :content => "blah"
+ resource.expects(:isomorphic?).returns(true)
+ @catalog.add_resource(resource)
+ @catalog.resource(:file, "other").should equal(resource)
+ @catalog.resource(:file, "/something").ref.should == resource.ref
+ end
+
+ it "should not add an alias for the namevar when the title and name differ on non-isomorphic resource types" do
+ resource = Puppet::Type.type(:file).create :path => "/something", :title => "other", :content => "blah"
+ resource.expects(:isomorphic?).returns(false)
+ @catalog.add_resource(resource)
+ @catalog.resource(:file, resource.title).should equal(resource)
+ # We can't use .should here, because the resources respond to that method.
+ if @catalog.resource(:file, resource.name)
+ raise "Aliased non-isomorphic resource"
+ end
+ end
+
+ after do
+ Puppet::Type.allclear
end
end
-module ApplyingCatalogs
- def setup
+describe Puppet::Node::Catalog do
+ before :each do
@catalog = Puppet::Node::Catalog.new("host")
@catalog.retrieval_duration = Time.now
@@ -500,130 +531,124 @@ module ApplyingCatalogs
@transaction.stubs(:cleanup)
@transaction.stubs(:addtimes)
end
-end
-describe Puppet::Node::Catalog, " when applying" do
- include ApplyingCatalogs
+ describe Puppet::Node::Catalog, " when applying" do
- it "should create and evaluate a transaction" do
- @transaction.expects(:evaluate)
- @catalog.apply
- end
+ it "should create and evaluate a transaction" do
+ @transaction.expects(:evaluate)
+ @catalog.apply
+ end
- it "should provide the catalog time to the transaction" do
- @transaction.expects(:addtimes).with do |arg|
- arg[:config_retrieval].should be_instance_of(Time)
- true
+ it "should provide the catalog time to the transaction" do
+ @transaction.expects(:addtimes).with do |arg|
+ arg[:config_retrieval].should be_instance_of(Time)
+ true
+ end
+ @catalog.apply
end
- @catalog.apply
- end
- it "should clean up the transaction" do
- @transaction.expects :cleanup
- @catalog.apply
- end
+ it "should clean up the transaction" do
+ @transaction.expects :cleanup
+ @catalog.apply
+ end
- it "should return the transaction" do
- @catalog.apply.should equal(@transaction)
- end
+ it "should return the transaction" do
+ @catalog.apply.should equal(@transaction)
+ end
- it "should yield the transaction if a block is provided" do
- @catalog.apply do |trans|
- trans.should equal(@transaction)
+ it "should yield the transaction if a block is provided" do
+ @catalog.apply do |trans|
+ trans.should equal(@transaction)
+ end
end
- end
- it "should default to not being a host catalog" do
- @catalog.host_config.should be_nil
- end
+ it "should default to not being a host catalog" do
+ @catalog.host_config.should be_nil
+ end
- it "should pass supplied tags on to the transaction" do
- @transaction.expects(:tags=).with(%w{one two})
- @catalog.apply(:tags => %w{one two})
- end
+ it "should pass supplied tags on to the transaction" do
+ @transaction.expects(:tags=).with(%w{one two})
+ @catalog.apply(:tags => %w{one two})
+ end
- it "should set ignoreschedules on the transaction if specified in apply()" do
- @transaction.expects(:ignoreschedules=).with(true)
- @catalog.apply(:ignoreschedules => true)
+ it "should set ignoreschedules on the transaction if specified in apply()" do
+ @transaction.expects(:ignoreschedules=).with(true)
+ @catalog.apply(:ignoreschedules => true)
+ end
end
-end
-describe Puppet::Node::Catalog, " when applying host catalogs" do
- include ApplyingCatalogs
+ describe Puppet::Node::Catalog, " when applying host catalogs" do
- # super() doesn't work in the setup method for some reason
- before do
- @catalog.host_config = true
- end
+ # super() doesn't work in the setup method for some reason
+ before do
+ @catalog.host_config = true
+ end
- it "should send a report if reporting is enabled" do
- Puppet[:report] = true
- @transaction.expects :send_report
- @transaction.stubs :any_failed? => false
- @catalog.apply
- end
+ it "should send a report if reporting is enabled" do
+ Puppet[:report] = true
+ @transaction.expects :send_report
+ @transaction.stubs :any_failed? => false
+ @catalog.apply
+ end
- it "should send a report if report summaries are enabled" do
- Puppet[:summarize] = true
- @transaction.expects :send_report
- @transaction.stubs :any_failed? => false
- @catalog.apply
- end
+ it "should send a report if report summaries are enabled" do
+ Puppet[:summarize] = true
+ @transaction.expects :send_report
+ @transaction.stubs :any_failed? => false
+ @catalog.apply
+ end
- it "should initialize the state database before applying a catalog" do
- Puppet::Util::Storage.expects(:load)
+ it "should initialize the state database before applying a catalog" do
+ Puppet::Util::Storage.expects(:load)
- # Short-circuit the apply, so we know we're loading before the transaction
- Puppet::Transaction.expects(:new).raises ArgumentError
- proc { @catalog.apply }.should raise_error(ArgumentError)
- end
+ # Short-circuit the apply, so we know we're loading before the transaction
+ Puppet::Transaction.expects(:new).raises ArgumentError
+ proc { @catalog.apply }.should raise_error(ArgumentError)
+ end
- it "should sync the state database after applying" do
- Puppet::Util::Storage.expects(:store)
- @transaction.stubs :any_failed? => false
- @catalog.apply
- end
+ it "should sync the state database after applying" do
+ Puppet::Util::Storage.expects(:store)
+ @transaction.stubs :any_failed? => false
+ @catalog.apply
+ end
- after { Puppet.settings.clear }
-end
+ after { Puppet.settings.clear }
+ end
-describe Puppet::Node::Catalog, " when applying non-host catalogs" do
- include ApplyingCatalogs
+ describe Puppet::Node::Catalog, " when applying non-host catalogs" do
- before do
- @catalog.host_config = false
- end
+ before do
+ @catalog.host_config = false
+ end
- it "should never send reports" do
- Puppet[:report] = true
- Puppet[:summarize] = true
- @transaction.expects(:send_report).never
- @catalog.apply
- end
+ it "should never send reports" do
+ Puppet[:report] = true
+ Puppet[:summarize] = true
+ @transaction.expects(:send_report).never
+ @catalog.apply
+ end
- it "should never modify the state database" do
- Puppet::Util::Storage.expects(:load).never
- Puppet::Util::Storage.expects(:store).never
- @catalog.apply
- end
+ it "should never modify the state database" do
+ Puppet::Util::Storage.expects(:load).never
+ Puppet::Util::Storage.expects(:store).never
+ @catalog.apply
+ end
- after { Puppet.settings.clear }
+ after { Puppet.settings.clear }
+ end
end
describe Puppet::Node::Catalog, " when creating a relationship graph" do
before do
+ Puppet::Type.type(:component)
@catalog = Puppet::Node::Catalog.new("host")
@compone = Puppet::Type::Component.create :name => "one"
@comptwo = Puppet::Type::Component.create :name => "two", :require => ["class", "one"]
@file = Puppet::Type.type(:file)
@one = @file.create :path => "/one"
@two = @file.create :path => "/two"
- @sub = @file.create :path => "/two/three"
-
- @sub.stubs(:autorequire).returns([Puppet::Relationship.new(@two, @sub)])
-
- @catalog.add_edge! @compone, @one
- @catalog.add_edge! @comptwo, @two
+ @catalog.add_edge @compone, @one
+ @catalog.add_edge @comptwo, @two
@three = @file.create :path => "/three"
@four = @file.create :path => "/four", :require => ["file", "/three"]
@@ -796,7 +821,7 @@ end
describe Puppet::Node::Catalog, " when converting to yaml" do
before do
@catalog = Puppet::Node::Catalog.new("me")
- @catalog.add_edge!("one", "two")
+ @catalog.add_edge("one", "two")
end
it "should be able to be dumped to yaml" do
@@ -807,7 +832,7 @@ end
describe Puppet::Node::Catalog, " when converting from yaml" do
before do
@catalog = Puppet::Node::Catalog.new("me")
- @catalog.add_edge!("one", "two")
+ @catalog.add_edge("one", "two")
text = YAML.dump(@catalog)
@newcatalog = YAML.load(text)
diff --git a/spec/unit/other/pgraph.rb b/spec/unit/other/pgraph.rb
index 252a807ec..10ab934a6 100755
--- a/spec/unit/other/pgraph.rb
+++ b/spec/unit/other/pgraph.rb
@@ -5,6 +5,7 @@
require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/pgraph'
require 'puppet/util/graph'
class Container
@@ -35,8 +36,8 @@ describe Puppet::PGraph do
end
it "should correctly clear vertices and edges when asked" do
- @graph.add_edge!("a", "b")
- @graph.add_vertex! "c"
+ @graph.add_edge("a", "b")
+ @graph.add_vertex "c"
@graph.clear
@graph.vertices.should be_empty
@graph.edges.should be_empty
@@ -52,7 +53,7 @@ describe Puppet::PGraph, " when matching edges" do
@edges = {}
@edges["a/b"] = Puppet::Relationship.new("a", "b", {:event => :yay, :callback => :refresh})
@edges["a/c"] = Puppet::Relationship.new("a", "c", {:event => :yay, :callback => :refresh})
- @graph.add_edge!(@edges["a/b"])
+ @graph.add_edge(@edges["a/b"])
end
it "should match edges whose source matches the source of the event" do
@@ -64,7 +65,7 @@ describe Puppet::PGraph, " when matching edges" do
end
it "should match multiple edges" do
- @graph.add_edge!(@edges["a/c"])
+ @graph.add_edge(@edges["a/c"])
edges = @graph.matching_edges([@event])
edges.should be_include(@edges["a/b"])
edges.should be_include(@edges["a/c"])
@@ -75,9 +76,9 @@ describe Puppet::PGraph, " when determining dependencies" do
before do
@graph = Puppet::PGraph.new
- @graph.add_edge!("a", "b")
- @graph.add_edge!("a", "c")
- @graph.add_edge!("b", "d")
+ @graph.add_edge("a", "b")
+ @graph.add_edge("a", "c")
+ @graph.add_edge("b", "d")
end
it "should find all dependents when they are on multiple levels" do
@@ -118,19 +119,19 @@ describe Puppet::PGraph, " when splicing the relationship graph" do
# We have to add the container to the main graph, else it won't
# be spliced in the dependency graph.
- @contgraph.add_vertex!(@empty)
+ @contgraph.add_vertex(@empty)
end
def dependency_graph
@depgraph = Puppet::PGraph.new
@contgraph.vertices.each do |v|
- @depgraph.add_vertex!(v)
+ @depgraph.add_vertex(v)
end
# We have to specify a relationship to our empty container, else it
# never makes it into the dep graph in the first place.
{@one => @two, "f" => "c", "h" => @middle, "c" => @empty}.each do |source, target|
- @depgraph.add_edge!(source, target, :callback => :refresh)
+ @depgraph.add_edge(source, target, :callback => :refresh)
end
end
@@ -176,13 +177,13 @@ describe Puppet::PGraph, " when splicing the relationship graph" do
end
it "should not add labels to edges that have none" do
- @depgraph.add_edge!(@two, @three)
+ @depgraph.add_edge(@two, @three)
splice
@depgraph.edge_label("c", "i").should == {}
end
it "should copy labels over edges that have none" do
- @depgraph.add_edge!("c", @three, {:callback => :refresh})
+ @depgraph.add_edge("c", @three, {:callback => :refresh})
splice
# And make sure the label got copied.
@depgraph.edge_label("c", "i").should == {:callback => :refresh}
@@ -190,18 +191,18 @@ describe Puppet::PGraph, " when splicing the relationship graph" do
it "should not replace a label with a nil label" do
# Lastly, add some new label-less edges and make sure the label stays.
- @depgraph.add_edge!(@middle, @three)
- @depgraph.add_edge!("c", @three, {:callback => :refresh})
+ @depgraph.add_edge(@middle, @three)
+ @depgraph.add_edge("c", @three, {:callback => :refresh})
splice
@depgraph.edge_label("c", "i").should == {:callback => :refresh}
end
it "should copy labels to all created edges" do
- @depgraph.add_edge!(@middle, @three)
- @depgraph.add_edge!("c", @three, {:callback => :refresh})
+ @depgraph.add_edge(@middle, @three)
+ @depgraph.add_edge("c", @three, {:callback => :refresh})
splice
@three.each do |child|
- edge = @depgraph.edge_class.new("c", child)
+ edge = Puppet::Relationship.new("c", child)
@depgraph.should be_edge(edge.source, edge.target)
@depgraph.edge_label(edge.source, edge.target).should == {:callback => :refresh}
end
diff --git a/spec/unit/other/transaction.rb b/spec/unit/other/transaction.rb
index d88f03005..0db470d26 100755
--- a/spec/unit/other/transaction.rb
+++ b/spec/unit/other/transaction.rb
@@ -2,6 +2,8 @@
require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/transaction'
+
describe Puppet::Transaction, " when determining tags" do
before do
@config = Puppet::Node::Catalog.new
@@ -23,4 +25,9 @@ describe Puppet::Transaction, " when determining tags" do
@transaction.tags = %w{one two}
@transaction.tags.should == %w{one two}
end
+
+ it "should always convert assigned tags to an array" do
+ @transaction.tags = "one::two"
+ @transaction.tags.should == %w{one::two}
+ end
end
diff --git a/spec/unit/other/transbucket.rb b/spec/unit/other/transbucket.rb
index 89f48ad41..4494f2abb 100755
--- a/spec/unit/other/transbucket.rb
+++ b/spec/unit/other/transbucket.rb
@@ -87,35 +87,49 @@ describe Puppet::TransBucket, " when generating a catalog" do
@top.push(@topobj)
@top.push(@middle)
- @config = @top.to_catalog
-
@users = %w{top middle bottom}
@fakes = %w{Fake[bottom] Fake[middle] Fake[top]}
end
+ after do
+ Puppet::Type.allclear
+ end
+
it "should convert all transportable objects to RAL resources" do
+ @catalog = @top.to_catalog
@users.each do |name|
- @config.vertices.find { |r| r.class.name == :user and r.title == name }.should be_instance_of(Puppet::Type.type(:user))
+ @catalog.vertices.find { |r| r.class.name == :user and r.title == name }.should be_instance_of(Puppet::Type.type(:user))
end
end
+ it "should fail if any transportable resources fail to convert to RAL resources" do
+ @bottomobj.expects(:to_type).raises ArgumentError
+ lambda { @bottom.to_catalog }.should raise_error(ArgumentError)
+ end
+
it "should convert all transportable buckets to RAL components" do
+ @catalog = @top.to_catalog
@fakes.each do |name|
- @config.vertices.find { |r| r.class.name == :component and r.title == name }.should be_instance_of(Puppet::Type.type(:component))
+ @catalog.vertices.find { |r| r.class.name == :component and r.title == name }.should be_instance_of(Puppet::Type.type(:component))
end
end
it "should add all resources to the graph's resource table" do
- @config.resource("fake[top]").should equal(@top)
+ @catalog = @top.to_catalog
+ @catalog.resource("fake[top]").should equal(@top)
end
it "should finalize all resources" do
- @config.vertices.each do |vertex| vertex.should be_finalized end
+ @catalog = @top.to_catalog
+ @catalog.vertices.each do |vertex| vertex.should be_finalized end
end
it "should only call to_type on each resource once" do
- @topobj.expects(:to_type)
- @bottomobj.expects(:to_type)
+ # We just raise exceptions here because we're not interested in
+ # what happens with the result, only that the method only
+ # gets called once.
+ resource = @topobj.to_type
+ @topobj.expects(:to_type).once.returns resource
@top.to_catalog
end
diff --git a/spec/unit/parser/ast/definition.rb b/spec/unit/parser/ast/definition.rb
index a27fb4721..a58e4d00e 100755
--- a/spec/unit/parser/ast/definition.rb
+++ b/spec/unit/parser/ast/definition.rb
@@ -12,8 +12,8 @@ describe Puppet::Parser::AST::Definition, "when evaluating" do
@source = @parser.newclass ""
@definition = @parser.newdefine "mydefine"
@node = Puppet::Node.new("yaynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- @scope = @compile.topscope
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+ @scope = @compiler.topscope
@resource = Puppet::Parser::Resource.new(:type => "mydefine", :title => "myresource", :scope => @scope, :source => @source)
end
@@ -21,12 +21,12 @@ describe Puppet::Parser::AST::Definition, "when evaluating" do
it "should create a new scope" do
scope = nil
code = mock 'code'
- code.expects(:safeevaluate).with do |options|
- options[:scope].object_id.should_not == @scope.object_id
+ code.expects(:safeevaluate).with do |scope|
+ scope.object_id.should_not == @scope.object_id
true
end
@definition.stubs(:code).returns(code)
- @definition.evaluate(:scope => @scope, :resource => @resource)
+ @definition.evaluate_code(@resource)
end
# it "should copy its namespace to the scope"
@@ -44,4 +44,152 @@ describe Puppet::Parser::AST::Definition, "when evaluating" do
# it "should not copy the resource's title as the name if 'name' is one of the resource parameters"
#
# it "should evaluate the associated code with the new scope"
+
+ def old_test_initialize
+ parser = mkparser
+
+ # Create a new definition
+ klass = parser.newdefine "yayness",
+ :arguments => [["owner", stringobj("nobody")], %w{mode}],
+ :code => AST::ASTArray.new(
+ :children => [resourcedef("file", "/tmp/$name",
+ "owner" => varref("owner"), "mode" => varref("mode"))]
+ )
+
+ # Test validattr? a couple different ways
+ [:owner, "owner", :schedule, "schedule"].each do |var|
+ assert(klass.validattr?(var), "%s was not considered valid" % var.inspect)
+ end
+
+ [:random, "random"].each do |var|
+ assert(! klass.validattr?(var), "%s was considered valid" % var.inspect)
+ end
+
+ end
+
+ def oldtest_evaluate
+ parser = mkparser
+ config = mkcompiler
+ config.send(:evaluate_main)
+ scope = config.topscope
+ klass = parser.newdefine "yayness",
+ :arguments => [["owner", stringobj("nobody")], %w{mode}],
+ :code => AST::ASTArray.new(
+ :children => [resourcedef("file", "/tmp/$name",
+ "owner" => varref("owner"), "mode" => varref("mode"))]
+ )
+
+ resource = Puppet::Parser::Resource.new(
+ :title => "first",
+ :type => "yayness",
+ :exported => false,
+ :virtual => false,
+ :scope => scope,
+ :source => scope.source
+ )
+ resource.send(:set_parameter, "name", "first")
+ resource.send(:set_parameter, "mode", "755")
+
+ resource.stubs(:title)
+ assert_nothing_raised do
+ klass.evaluate_code(resource)
+ end
+
+ firstobj = config.findresource("File[/tmp/first]")
+ assert(firstobj, "Did not create /tmp/first obj")
+
+ assert_equal("File", firstobj.type)
+ assert_equal("/tmp/first", firstobj.title)
+ assert_equal("nobody", firstobj[:owner])
+ assert_equal("755", firstobj[:mode])
+
+ # Make sure we can't evaluate it with the same args
+ assert_raise(Puppet::ParseError) do
+ klass.evaluate_code(resource)
+ end
+
+ # Now create another with different args
+ resource2 = Puppet::Parser::Resource.new(
+ :title => "second",
+ :type => "yayness",
+ :exported => false,
+ :virtual => false,
+ :scope => scope,
+ :source => scope.source
+ )
+ resource2.send(:set_parameter, "name", "second")
+ resource2.send(:set_parameter, "mode", "755")
+ resource2.send(:set_parameter, "owner", "daemon")
+
+ assert_nothing_raised do
+ klass.evaluate_code(resource2)
+ end
+
+ secondobj = config.findresource("File[/tmp/second]")
+ assert(secondobj, "Did not create /tmp/second obj")
+
+ assert_equal("File", secondobj.type)
+ assert_equal("/tmp/second", secondobj.title)
+ assert_equal("daemon", secondobj[:owner])
+ assert_equal("755", secondobj[:mode])
+ end
+
+ # #539 - definitions should support both names and titles
+ def oldtest_names_and_titles
+ parser = mkparser
+ scope = mkscope :parser => parser
+
+ [
+ {:name => "one", :title => "two"},
+ {:title => "mytitle"}
+ ].each_with_index do |hash, i|
+ # Create a definition that uses both name and title. Put this
+ # inside the loop so the subscope expectations work.
+ klass = parser.newdefine "yayness%s" % i
+
+ resource = Puppet::Parser::Resource.new(
+ :title => hash[:title],
+ :type => "yayness%s" % i,
+ :exported => false,
+ :virtual => false,
+ :scope => scope,
+ :source => scope.source
+ )
+
+ subscope = klass.subscope(scope, resource)
+
+ klass.expects(:subscope).returns(subscope)
+
+ if hash[:name]
+ resource.stubs(:to_hash).returns({:name => hash[:name]})
+ end
+
+ assert_nothing_raised("Could not evaluate definition with %s" % hash.inspect) do
+ klass.evaluate_code(resource)
+ end
+
+ name = hash[:name] || hash[:title]
+ title = hash[:title]
+
+ assert_equal(name, subscope.lookupvar("name"),
+ "Name did not get set correctly")
+ assert_equal(title, subscope.lookupvar("title"),
+ "title did not get set correctly")
+
+ [:name, :title].each do |param|
+ val = resource.send(param)
+ assert(subscope.tags.include?(val),
+ "Scope was not tagged with %s '%s'" % [param, val])
+ end
+ end
+ end
+
+ # Testing the root cause of #615. We should be using the fqname for the type, instead
+ # of just the short name.
+ def oldtest_fully_qualified_types
+ parser = mkparser
+ klass = parser.newclass("one::two")
+
+ assert_equal("one::two", klass.classname, "Class did not get fully qualified class name")
+ end
end
diff --git a/spec/unit/parser/ast/hostclass.rb b/spec/unit/parser/ast/hostclass.rb
new file mode 100755
index 000000000..0abc174d9
--- /dev/null
+++ b/spec/unit/parser/ast/hostclass.rb
@@ -0,0 +1,135 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Parser::AST::HostClass do
+ before :each do
+ @node = Puppet::Node.new "testnode"
+ @parser = Puppet::Parser::Parser.new :environment => "development"
+ @scope_resource = stub 'scope_resource', :builtin? => true
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+
+ @scope = @compiler.topscope
+ end
+
+ describe Puppet::Parser::AST::HostClass, "when evaluating" do
+
+ before do
+ @top = @parser.newclass "top"
+ @middle = @parser.newclass "middle", :parent => "top"
+ end
+
+ it "should create a resource that references itself" do
+ @top.evaluate(@scope)
+
+ @compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
+ end
+
+ it "should evaluate the parent class if one exists" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.resource(:class, "top").should be_instance_of(Puppet::Parser::Resource)
+ end
+
+ it "should fail to evaluate if a parent class is defined but cannot be found" do
+ othertop = @parser.newclass "something", :parent => "yay"
+ lambda { othertop.evaluate(@scope) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should not create a new resource if one already exists" do
+ @compiler.catalog.expects(:resource).with(:class, "top").returns("something")
+ @compiler.catalog.expects(:add_resource).never
+ @top.evaluate(@scope)
+ end
+
+ it "should return the existing resource when not creating a new one" do
+ @compiler.catalog.expects(:resource).with(:class, "top").returns("something")
+ @compiler.catalog.expects(:add_resource).never
+ @top.evaluate(@scope).should == "something"
+ end
+
+ it "should not create a new parent resource if one already exists and it has a parent class" do
+ @top.evaluate(@scope)
+
+ top_resource = @compiler.catalog.resource(:class, "top")
+
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.resource(:class, "top").should equal(top_resource)
+ end
+
+ # #795 - tag before evaluation.
+ it "should tag the catalog with the resource tags when it is evaluated" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.should be_tagged("middle")
+ end
+
+ it "should tag the catalog with the parent class tags when it is evaluated" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.should be_tagged("top")
+ end
+ end
+
+ describe Puppet::Parser::AST::HostClass, "when evaluating code" do
+
+ before do
+ @top_resource = stub "top_resource"
+ @top = @parser.newclass "top", :code => @top_resource
+
+ @middle_resource = stub "middle_resource"
+ @middle = @parser.newclass "top::middle", :parent => "top", :code => @middle_resource
+ end
+
+ it "should set its namespace to its fully qualified name" do
+ @middle.namespace.should == "top::middle"
+ end
+
+ it "should evaluate the code referred to by the class" do
+ @top_resource.expects(:safeevaluate)
+
+ resource = @top.evaluate(@scope)
+
+ @top.evaluate_code(resource)
+ end
+
+ it "should evaluate the parent class's code if it has a parent" do
+ @top_resource.expects(:safeevaluate)
+ @middle_resource.expects(:safeevaluate)
+
+ resource = @middle.evaluate(@scope)
+
+ @middle.evaluate_code(resource)
+ end
+
+ it "should not evaluate the parent class's code if the parent has already been evaluated" do
+ @top_resource.stubs(:safeevaluate)
+ resource = @top.evaluate(@scope)
+ @top.evaluate_code(resource)
+
+ @top_resource.expects(:safeevaluate).never
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+ end
+
+ it "should use the parent class's scope as its parent scope" do
+ @top_resource.stubs(:safeevaluate)
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+
+ @compiler.class_scope(@middle).parent.should equal(@compiler.class_scope(@top))
+ end
+
+ it "should add the parent class's namespace to its namespace search path" do
+ @top_resource.stubs(:safeevaluate)
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+
+ @compiler.class_scope(@middle).namespaces.should be_include(@top.namespace)
+ end
+ end
+end
diff --git a/spec/unit/parser/ast/node.rb b/spec/unit/parser/ast/node.rb
new file mode 100755
index 000000000..757934415
--- /dev/null
+++ b/spec/unit/parser/ast/node.rb
@@ -0,0 +1,125 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Parser::AST::Node do
+ before :each do
+ @node = Puppet::Node.new "testnode"
+ @parser = Puppet::Parser::Parser.new :environment => "development"
+ @scope_resource = stub 'scope_resource', :builtin? => true
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+
+ @scope = @compiler.topscope
+ end
+
+ describe Puppet::Parser::AST::Node, "when evaluating" do
+
+ before do
+ @top = @parser.newnode("top").shift
+ @middle = @parser.newnode("middle", :parent => "top").shift
+ end
+
+ it "should create a resource that references itself" do
+ @top.evaluate(@scope)
+
+ @compiler.catalog.resource(:node, "top").should be_an_instance_of(Puppet::Parser::Resource)
+ end
+
+ it "should evaluate the parent class if one exists" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.resource(:node, "top").should be_an_instance_of(Puppet::Parser::Resource)
+ end
+
+ it "should fail to evaluate if a parent class is defined but cannot be found" do
+ othertop = @parser.newnode("something", :parent => "yay").shift
+ lambda { othertop.evaluate(@scope) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should not create a new resource if one already exists" do
+ @compiler.catalog.expects(:resource).with(:node, "top").returns("something")
+ @compiler.catalog.expects(:add_resource).never
+ @top.evaluate(@scope)
+ end
+
+ it "should not create a new parent resource if one already exists and it has a parent class" do
+ @top.evaluate(@scope)
+
+ top_resource = @compiler.catalog.resource(:node, "top")
+
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.resource(:node, "top").should equal(top_resource)
+ end
+
+ # #795 - tag before evaluation.
+ it "should tag the catalog with the resource tags when it is evaluated" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.should be_tagged("middle")
+ end
+
+ it "should tag the catalog with the parent class tags when it is evaluated" do
+ @middle.evaluate(@scope)
+
+ @compiler.catalog.should be_tagged("top")
+ end
+ end
+
+ describe Puppet::Parser::AST::Node, "when evaluating code" do
+
+ before do
+ @top_resource = stub "top_resource"
+ @top = @parser.newnode("top", :code => @top_resource).shift
+
+ @middle_resource = stub "middle_resource"
+ @middle = @parser.newnode("middle", :parent => "top", :code => @middle_resource).shift
+ end
+
+ it "should evaluate the code referred to by the class" do
+ @top_resource.expects(:safeevaluate)
+
+ resource = @top.evaluate(@scope)
+
+ @top.evaluate_code(resource)
+ end
+
+ it "should evaluate the parent class's code if it has a parent" do
+ @top_resource.expects(:safeevaluate)
+ @middle_resource.expects(:safeevaluate)
+
+ resource = @middle.evaluate(@scope)
+
+ @middle.evaluate_code(resource)
+ end
+
+ it "should not evaluate the parent class's code if the parent has already been evaluated" do
+ @top_resource.stubs(:safeevaluate)
+ resource = @top.evaluate(@scope)
+ @top.evaluate_code(resource)
+
+ @top_resource.expects(:safeevaluate).never
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+ end
+
+ it "should use the parent class's scope as its parent scope" do
+ @top_resource.stubs(:safeevaluate)
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+
+ @compiler.class_scope(@middle).parent.should equal(@compiler.class_scope(@top))
+ end
+
+ it "should add the parent class's namespace to its namespace search path" do
+ @top_resource.stubs(:safeevaluate)
+ @middle_resource.stubs(:safeevaluate)
+ resource = @middle.evaluate(@scope)
+ @middle.evaluate_code(resource)
+
+ @compiler.class_scope(@middle).namespaces.should be_include(@top.namespace)
+ end
+ end
+end \ No newline at end of file
diff --git a/spec/unit/parser/collector.rb b/spec/unit/parser/collector.rb
index 9b5eab1f4..e1ceb23ed 100755
--- a/spec/unit/parser/collector.rb
+++ b/spec/unit/parser/collector.rb
@@ -79,8 +79,8 @@ describe Puppet::Parser::Collector, "when collecting specific virtual resources"
@collector.resources = ["File[virtual1]"]
one = mock 'one'
one.stubs(:virtual=)
- @compile.expects(:delete_collection).with(@collector)
- @scope.expects(:compile).returns(@compile)
+ @compiler.expects(:delete_collection).with(@collector)
+ @scope.expects(:compiler).returns(@compiler)
@scope.stubs(:findresource).with("File[virtual1]").returns(one)
@collector.evaluate
end
@@ -89,7 +89,7 @@ describe Puppet::Parser::Collector, "when collecting specific virtual resources"
@collector.resources = ["File[virtual1]"]
one = mock 'one'
one.stubs(:virtual=)
- @compile.expects(:delete_collection).never
+ @compiler.expects(:delete_collection).never
@scope.stubs(:findresource).with("File[virtual1]").returns(nil)
@collector.evaluate
end
@@ -98,8 +98,8 @@ end
describe Puppet::Parser::Collector, "when collecting virtual resources" do
before do
@scope = mock 'scope'
- @compile = mock 'compile'
- @scope.stubs(:compile).returns(@compile)
+ @compiler = mock 'compile'
+ @scope.stubs(:compiler).returns(@compiler)
@resource_type = "Mytype"
@vquery = proc { |res| true }
@@ -113,7 +113,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.stubs(:virtual=)
two.stubs(:virtual=)
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one, two]
end
@@ -123,7 +123,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).with(false)
- @compile.expects(:resources).returns([one])
+ @compiler.expects(:resources).returns([one])
@collector.evaluate
end
@@ -135,7 +135,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.stubs(:virtual=)
two.stubs(:virtual=)
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one, two]
end
@@ -147,7 +147,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).with(false)
two.expects(:virtual=).with(false)
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector = Puppet::Parser::Collector.new(@scope, @resource_type, nil, nil, :virtual)
@@ -161,7 +161,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).with(false)
two.expects(:virtual=).never
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one]
end
@@ -173,7 +173,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).never
two.expects(:virtual=).never
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should be_false
end
@@ -187,7 +187,7 @@ describe Puppet::Parser::Collector, "when collecting virtual resources" do
one.expects(:virtual=).with(false)
two.expects(:virtual=).never
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one]
end
@@ -198,8 +198,8 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
before do
@scope = stub 'scope', :host => "myhost", :debug => nil
- @compile = mock 'compile'
- @scope.stubs(:compile).returns(@compile)
+ @compiler = mock 'compile'
+ @scope.stubs(:compiler).returns(@compiler)
@resource_type = "Mytype"
@equery = "test = true"
@vquery = proc { |r| true }
@@ -218,7 +218,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
end
it "should use initialize the Rails support if ActiveRecord is not connected" do
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
ActiveRecord::Base.expects(:connected?).returns(false)
Puppet::Rails.expects(:init)
Puppet::Rails::Host.stubs(:find_by_name).returns(nil)
@@ -238,7 +238,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
two.stubs(:exported=)
two.stubs(:virtual=)
- @compile.expects(:resources).returns([one, two])
+ @compiler.expects(:resources).returns([one, two])
@collector.evaluate.should == [one, two]
end
@@ -251,7 +251,7 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
one.stubs(:exported=)
one.expects(:virtual=).with(false)
- @compile.expects(:resources).returns([one])
+ @compiler.expects(:resources).returns([one])
@collector.evaluate.should == [one]
end
@@ -268,10 +268,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource.stubs(:exported=)
resource.stubs(:virtual=)
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(nil)
- @compile.stubs(:store_resource)
+ @compiler.stubs(:add_resource)
@collector.evaluate.should == [resource]
end
@@ -288,10 +288,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource.stubs(:exported=)
resource.stubs(:virtual=)
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(nil)
- @compile.expects(:store_resource).with(@scope, resource)
+ @compiler.expects(:add_resource).with(@scope, resource)
@collector.evaluate.should == [resource]
end
@@ -309,10 +309,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource.expects(:exported=).with(false)
resource.stubs(:virtual=)
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(nil)
- @compile.stubs(:store_resource)
+ @compiler.stubs(:add_resource)
@collector.evaluate
end
@@ -328,10 +328,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource = mock 'resource'
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(inmemory)
- @compile.stubs(:store_resource)
+ @compiler.stubs(:add_resource)
proc { @collector.evaluate }.should raise_error(Puppet::ParseError)
end
@@ -347,10 +347,10 @@ describe Puppet::Parser::Collector, "when collecting exported resources" do
resource = mock 'resource'
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
@scope.stubs(:findresource).returns(inmemory)
- @compile.stubs(:store_resource)
+ @compiler.stubs(:add_resource)
proc { @collector.evaluate }.should_not raise_error(Puppet::ParseError)
end
@@ -361,14 +361,14 @@ describe Puppet::Parser::Collector, "when building its ActiveRecord query for co
before do
@scope = stub 'scope', :host => "myhost", :debug => nil
- @compile = mock 'compile'
- @scope.stubs(:compile).returns(@compile)
+ @compiler = mock 'compile'
+ @scope.stubs(:compiler).returns(@compiler)
@resource_type = "Mytype"
@equery = nil
@vquery = proc { |r| true }
@collector = Puppet::Parser::Collector.new(@scope, @resource_type, @equery, @vquery, :exported)
- @compile.stubs(:resources).returns([])
+ @compiler.stubs(:resources).returns([])
ActiveRecord::Base.stubs(:connected?).returns(false)
diff --git a/spec/unit/parser/compile.rb b/spec/unit/parser/compile.rb
deleted file mode 100755
index 092bece0c..000000000
--- a/spec/unit/parser/compile.rb
+++ /dev/null
@@ -1,281 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../spec_helper'
-
-describe Puppet::Parser::Compile, " when compiling" do
- before do
- @node = stub 'node', :name => 'mynode'
- @parser = stub 'parser', :version => "1.0"
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- end
-
- def compile_methods
- [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated,
- :finish, :store, :extract]
- end
-
- # Stub all of the main compile methods except the ones we're specifically interested in.
- def compile_stub(*except)
- (compile_methods - except).each { |m| @compile.stubs(m) }
- end
-
- it "should set node parameters as variables in the top scope" do
- params = {"a" => "b", "c" => "d"}
- @node.stubs(:parameters).returns(params)
- compile_stub(:set_node_parameters)
- @compile.compile
- @compile.topscope.lookupvar("a").should == "b"
- @compile.topscope.lookupvar("c").should == "d"
- end
-
- it "should evaluate any existing classes named in the node" do
- classes = %w{one two three four}
- main = stub 'main'
- one = stub 'one', :classname => "one"
- three = stub 'three', :classname => "three"
- @node.stubs(:name).returns("whatever")
- @node.stubs(:classes).returns(classes)
-
- @compile.expects(:evaluate_classes).with(classes, @compile.topscope)
- @compile.send :evaluate_node_classes
- end
-
- it "should enable ast_nodes if the parser has any nodes" do
- @parser.expects(:nodes).returns(:one => :yay)
- @compile.ast_nodes?.should be_true
- end
-
- it "should disable ast_nodes if the parser has no nodes" do
- @parser.expects(:nodes).returns({})
- @compile.ast_nodes?.should be_false
- end
-end
-
-describe Puppet::Parser::Compile, " when evaluating classes" do
- before do
- @node = stub 'node', :name => 'mynode'
- @parser = stub 'parser', :version => "1.0"
- @scope = stub 'scope', :source => mock("source")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- end
-
- it "should fail if there's no source listed for the scope" do
- scope = stub 'scope', :source => nil
- proc { @compile.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError)
- end
-
- it "should tag the catalog with the name of each not-found class" do
- @compile.catalog.expects(:tag).with("notfound")
- @scope.expects(:findclass).with("notfound").returns(nil)
- @compile.evaluate_classes(%w{notfound}, @scope)
- end
-end
-
-describe Puppet::Parser::Compile, " when evaluating collections" do
- before do
- @node = stub 'node', :name => 'mynode'
- @parser = stub 'parser', :version => "1.0"
- @scope = stub 'scope', :source => mock("source")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- end
-
- it "should evaluate each collection" do
- 2.times { |i|
- coll = mock 'coll%s' % i
- @compile.add_collection(coll)
-
- # This is the hard part -- we have to emulate the fact that
- # collections delete themselves if they are done evaluating.
- coll.expects(:evaluate).with do
- @compile.delete_collection(coll)
- end
- }
-
- @compile.class.publicize_methods(:evaluate_collections) { @compile.evaluate_collections }
- end
-end
-
-
-describe Puppet::Parser::Compile, " when evaluating found classes" do
- before do
- @node = stub 'node', :name => 'mynode'
- @parser = stub 'parser', :version => "1.0"
- @scope = stub 'scope', :source => mock("source")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
-
- @class = stub 'class', :classname => "my::class"
- @scope.stubs(:findclass).with("myclass").returns(@class)
-
- @resource = stub 'resource', :ref => 'Class[myclass]'
- end
-
- it "should create a resource for each found class" do
- @compile.catalog.stubs(:tag)
-
- @compile.stubs :store_resource
-
- Puppet::Parser::Resource.expects(:new).with(:scope => @scope, :source => @scope.source, :title => "my::class", :type => "class").returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope)
- end
-
- it "should store each created resource in the compile" do
- @compile.catalog.stubs(:tag)
-
- @compile.expects(:store_resource).with(@scope, @resource)
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope)
- end
-
- it "should tag the catalog with the fully-qualified name of each found class" do
- @compile.catalog.expects(:tag).with("my::class")
-
- @compile.stubs(:store_resource)
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope)
- end
-
- it "should not evaluate the resources created for found classes unless asked" do
- @compile.catalog.stubs(:tag)
-
- @compile.stubs(:store_resource)
- @resource.expects(:evaluate).never
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope)
- end
-
- it "should immediately evaluate the resources created for found classes when asked" do
- @compile.catalog.stubs(:tag)
-
- @compile.stubs(:store_resource)
- @resource.expects(:evaluate)
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass}, @scope, false)
- end
-
- it "should skip classes that have already been evaluated" do
- @compile.catalog.stubs(:tag)
-
- @compile.expects(:class_scope).with(@class).returns("something")
-
- @compile.expects(:store_resource).never
-
- @resource.expects(:evaluate).never
-
- Puppet::Parser::Resource.expects(:new).never
- @compile.evaluate_classes(%w{myclass}, @scope, false)
- end
-
- it "should return the list of found classes" do
- @compile.catalog.stubs(:tag)
-
- @compile.stubs(:store_resource)
- @scope.stubs(:findclass).with("notfound").returns(nil)
-
- Puppet::Parser::Resource.stubs(:new).returns(@resource)
- @compile.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass}
- end
-end
-
-describe Puppet::Parser::Compile, " when evaluating AST nodes with no AST nodes present" do
- before do
- @node = stub 'node', :name => "foo"
- @parser = stub 'parser', :version => "1.0", :nodes => {}
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- end
-
- it "should do nothing" do
- @compile.expects(:ast_nodes?).returns(false)
- @compile.parser.expects(:nodes).never
- Puppet::Parser::Resource.expects(:new).never
-
- @compile.send(:evaluate_ast_node)
- end
-end
-
-describe Puppet::Parser::Compile, " when evaluating AST nodes with AST nodes present" do
- before do
- @node = stub 'node', :name => "foo"
- @parser = stub 'parser', :version => "1.0", :nodes => {}
- @compile = Puppet::Parser::Compile.new(@node, @parser)
-
- @nodes = mock 'node_hash'
- @compile.stubs(:ast_nodes?).returns(true)
- @compile.parser.stubs(:nodes).returns(@nodes)
-
- # Set some names for our test
- @node.stubs(:names).returns(%w{a b c})
- @nodes.stubs(:[]).with("a").returns(nil)
- @nodes.stubs(:[]).with("b").returns(nil)
- @nodes.stubs(:[]).with("c").returns(nil)
-
- # It should check this last, of course.
- @nodes.stubs(:[]).with("default").returns(nil)
- end
-
- it "should fail if the named node cannot be found" do
- proc { @compile.send(:evaluate_ast_node) }.should raise_error(Puppet::ParseError)
- end
-
- it "should create a resource for the first node class matching the node name" do
- node_class = stub 'node', :classname => "c"
- @nodes.stubs(:[]).with("c").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
- Puppet::Parser::Resource.expects(:new).with { |args| args[:title] == "c" and args[:type] == "node" }.returns(node_resource)
-
- @compile.send(:evaluate_ast_node)
- end
-
- it "should match the default node if no matching node can be found" do
- node_class = stub 'node', :classname => "default"
- @nodes.stubs(:[]).with("default").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil
- Puppet::Parser::Resource.expects(:new).with { |args| args[:title] == "default" and args[:type] == "node" }.returns(node_resource)
-
- @compile.send(:evaluate_ast_node)
- end
-
- it "should tag the catalog with the found node name" do
- node_class = stub 'node', :classname => "c"
- @nodes.stubs(:[]).with("c").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
- Puppet::Parser::Resource.stubs(:new).returns(node_resource)
-
- @compile.catalog.expects(:tag).with("c")
- @compile.send(:evaluate_ast_node)
- end
-
- it "should evaluate the node resource immediately rather than using lazy evaluation" do
- node_class = stub 'node', :classname => "c"
- @nodes.stubs(:[]).with("c").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[c]"
- Puppet::Parser::Resource.stubs(:new).returns(node_resource)
-
- node_resource.expects(:evaluate)
-
- @compile.send(:evaluate_ast_node)
- end
-
- it "should set the node's scope as the top scope" do
- node_class = stub 'node', :classname => "c"
- @nodes.stubs(:[]).with("c").returns(node_class)
-
- node_resource = stub 'node resource', :ref => "Node[c]"
- Puppet::Parser::Resource.stubs(:new).returns(node_resource)
-
- # The #evaluate method normally does this.
- @compile.class_set(node_class.classname, :my_node_scope)
- node_resource.stubs(:evaluate)
-
- @compile.send(:evaluate_ast_node)
-
- @compile.topscope.should == :my_node_scope
- end
-end
diff --git a/spec/unit/parser/compiler.rb b/spec/unit/parser/compiler.rb
new file mode 100755
index 000000000..ab430da62
--- /dev/null
+++ b/spec/unit/parser/compiler.rb
@@ -0,0 +1,532 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+describe Puppet::Parser::Compiler do
+ before :each do
+ @node = Puppet::Node.new "testnode"
+ @parser = Puppet::Parser::Parser.new :environment => "development"
+
+ @scope_resource = stub 'scope_resource', :builtin? => true, :finish => nil, :ref => 'Class[main]'
+ @scope = stub 'scope', :resource => @scope_resource, :source => mock("source")
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+ end
+
+ describe Puppet::Parser::Compiler do
+
+ it "should be able to store references to class scopes" do
+ lambda { @compiler.class_set "myname", "myscope" }.should_not raise_error
+ end
+
+ it "should be able to retrieve class scopes by name" do
+ @compiler.class_set "myname", "myscope"
+ @compiler.class_scope("myname").should == "myscope"
+ end
+
+ it "should be able to retrieve class scopes by object" do
+ klass = mock 'ast_class'
+ klass.expects(:classname).returns("myname")
+ @compiler.class_set "myname", "myscope"
+ @compiler.class_scope(klass).should == "myscope"
+ end
+
+ it "should be able to return a class list containing all set classes" do
+ @compiler.class_set "", "empty"
+ @compiler.class_set "one", "yep"
+ @compiler.class_set "two", "nope"
+
+ @compiler.classlist.sort.should == %w{one two}.sort
+ end
+ end
+
+ describe Puppet::Parser::Compiler, " when initializing" do
+
+ it "should set its node attribute" do
+ @compiler.node.should equal(@node)
+ end
+
+ it "should set its parser attribute" do
+ @compiler.parser.should equal(@parser)
+ end
+
+ it "should detect when ast nodes are absent" do
+ @compiler.ast_nodes?.should be_false
+ end
+
+ it "should detect when ast nodes are present" do
+ @parser.nodes["testing"] = "yay"
+ @compiler.ast_nodes?.should be_true
+ end
+ end
+
+ describe Puppet::Parser::Compiler, "when managing scopes" do
+
+ it "should create a top scope" do
+ @compiler.topscope.should be_instance_of(Puppet::Parser::Scope)
+ end
+
+ it "should be able to create new scopes" do
+ @compiler.newscope(@compiler.topscope).should be_instance_of(Puppet::Parser::Scope)
+ end
+
+ it "should correctly set the level of newly created scopes" do
+ @compiler.newscope(@compiler.topscope, :level => 5).level.should == 5
+ end
+
+ it "should set the parent scope of the new scope to be the passed-in parent" do
+ scope = mock 'scope'
+ newscope = @compiler.newscope(scope)
+
+ @compiler.parent(newscope).should equal(scope)
+ end
+ end
+
+ describe Puppet::Parser::Compiler, " when compiling" do
+
+ def compile_methods
+ [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated,
+ :finish, :store, :extract]
+ end
+
+ # Stub all of the main compile methods except the ones we're specifically interested in.
+ def compile_stub(*except)
+ (compile_methods - except).each { |m| @compiler.stubs(m) }
+ end
+
+ it "should set node parameters as variables in the top scope" do
+ params = {"a" => "b", "c" => "d"}
+ @node.stubs(:parameters).returns(params)
+ compile_stub(:set_node_parameters)
+ @compiler.compile
+ @compiler.topscope.lookupvar("a").should == "b"
+ @compiler.topscope.lookupvar("c").should == "d"
+ end
+
+ it "should evaluate any existing classes named in the node" do
+ classes = %w{one two three four}
+ main = stub 'main'
+ one = stub 'one', :classname => "one"
+ three = stub 'three', :classname => "three"
+ @node.stubs(:name).returns("whatever")
+ @node.stubs(:classes).returns(classes)
+
+ @compiler.expects(:evaluate_classes).with(classes, @compiler.topscope)
+ @compiler.class.publicize_methods(:evaluate_node_classes) { @compiler.evaluate_node_classes }
+ end
+
+ it "should enable ast_nodes if the parser has any nodes" do
+ @parser.expects(:nodes).returns(:one => :yay)
+ @compiler.ast_nodes?.should be_true
+ end
+
+ it "should disable ast_nodes if the parser has no nodes" do
+ @parser.expects(:nodes).returns({})
+ @compiler.ast_nodes?.should be_false
+ end
+
+ it "should evaluate the main class if it exists" do
+ compile_stub(:evaluate_main)
+ main_class = mock 'main_class'
+ main_class.expects(:evaluate_code).with { |r| r.is_a?(Puppet::Parser::Resource) }
+ @compiler.topscope.expects(:source=).with(main_class)
+ @parser.stubs(:findclass).with("", "").returns(main_class)
+
+ @compiler.compile
+ end
+
+ it "should evaluate any node classes" do
+ @node.stubs(:classes).returns(%w{one two three four})
+ @compiler.expects(:evaluate_classes).with(%w{one two three four}, @compiler.topscope)
+ @compiler.send(:evaluate_node_classes)
+ end
+
+ it "should evaluate all added collections" do
+ colls = []
+ # And when the collections fail to evaluate.
+ colls << mock("coll1-false")
+ colls << mock("coll2-false")
+ colls.each { |c| c.expects(:evaluate).returns(false) }
+
+ @compiler.add_collection(colls[0])
+ @compiler.add_collection(colls[1])
+
+ compile_stub(:evaluate_generators)
+ @compiler.compile
+ end
+
+ it "should ignore builtin resources" do
+ resource = stub 'builtin', :ref => "File[testing]", :builtin? => true
+
+ @compiler.add_resource(@scope, resource)
+ resource.expects(:evaluate).never
+
+ @compiler.compile
+ end
+
+ it "should evaluate unevaluated resources" do
+ resource = stub 'notevaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => false, :virtual? => false
+ @compiler.add_resource(@scope, resource)
+
+ # We have to now mark the resource as evaluated
+ resource.expects(:evaluate).with { |*whatever| resource.stubs(:evaluated?).returns true }
+
+ @compiler.compile
+ end
+
+ it "should not evaluate already-evaluated resources" do
+ resource = stub 'already_evaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => true, :virtual? => false
+ @compiler.add_resource(@scope, resource)
+ resource.expects(:evaluate).never
+
+ @compiler.compile
+ end
+
+ it "should evaluate unevaluated resources created by evaluating other resources" do
+ resource = stub 'notevaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => false, :virtual? => false
+ @compiler.add_resource(@scope, resource)
+
+ resource2 = stub 'created', :ref => "File[other]", :builtin? => false, :evaluated? => false, :virtual? => false
+
+ # We have to now mark the resource as evaluated
+ resource.expects(:evaluate).with { |*whatever| resource.stubs(:evaluated?).returns(true); @compiler.add_resource(@scope, resource2) }
+ resource2.expects(:evaluate).with { |*whatever| resource2.stubs(:evaluated?).returns(true) }
+
+
+ @compiler.compile
+ end
+
+ it "should call finish() on all resources" do
+ # Add a resource that does respond to :finish
+ resource = Puppet::Parser::Resource.new :scope => @scope, :type => "file", :title => "finish"
+ resource.expects(:finish)
+
+ @compiler.add_resource(@scope, resource)
+
+ # And one that does not
+ dnf = stub "dnf", :ref => "File[dnf]"
+
+ @compiler.add_resource(@scope, dnf)
+
+ @compiler.send(:finish)
+ end
+
+ it "should add resources that do not conflict with existing resources" do
+ resource = stub "noconflict", :ref => "File[yay]"
+ @compiler.add_resource(@scope, resource)
+
+ @compiler.catalog.should be_vertex(resource)
+ end
+
+ it "should fail to add resources that conflict with existing resources" do
+ type = stub 'faketype', :isomorphic? => true, :name => "mytype"
+ Puppet::Type.stubs(:type).with("mytype").returns(type)
+
+ resource1 = stub "iso1conflict", :ref => "Mytype[yay]", :type => "mytype", :file => "eh", :line => 0
+ resource2 = stub "iso2conflict", :ref => "Mytype[yay]", :type => "mytype", :file => "eh", :line => 0
+
+ @compiler.add_resource(@scope, resource1)
+ lambda { @compiler.add_resource(@scope, resource2) }.should raise_error(ArgumentError)
+ end
+
+ it "should have a method for looking up resources" do
+ resource = stub 'resource', :ref => "Yay[foo]"
+ @compiler.add_resource(@scope, resource)
+ @compiler.findresource("Yay[foo]").should equal(resource)
+ end
+
+ it "should be able to look resources up by type and title" do
+ resource = stub 'resource', :ref => "Yay[foo]"
+ @compiler.add_resource(@scope, resource)
+ @compiler.findresource("Yay", "foo").should equal(resource)
+ end
+
+ it "should not evaluate virtual defined resources" do
+ resource = stub 'notevaluated', :ref => "File[testing]", :builtin? => false, :evaluated? => false, :virtual? => true
+ @compiler.add_resource(@scope, resource)
+
+ resource.expects(:evaluate).never
+
+ @compiler.compile
+ end
+ end
+
+ describe Puppet::Parser::Compiler, " when evaluating collections" do
+
+ it "should evaluate each collection" do
+ 2.times { |i|
+ coll = mock 'coll%s' % i
+ @compiler.add_collection(coll)
+
+ # This is the hard part -- we have to emulate the fact that
+ # collections delete themselves if they are done evaluating.
+ coll.expects(:evaluate).with do
+ @compiler.delete_collection(coll)
+ end
+ }
+
+ @compiler.class.publicize_methods(:evaluate_collections) { @compiler.evaluate_collections }
+ end
+
+ it "should not fail when there are unevaluated resource collections that do not refer to specific resources" do
+ coll = stub 'coll', :evaluate => false
+ coll.expects(:resources).returns(nil)
+
+ @compiler.add_collection(coll)
+
+ lambda { @compiler.compile }.should_not raise_error
+ end
+
+ it "should fail when there are unevaluated resource collections that refer to a specific resource" do
+ coll = stub 'coll', :evaluate => false
+ coll.expects(:resources).returns(:something)
+
+ @compiler.add_collection(coll)
+
+ lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail when there are unevaluated resource collections that refer to multiple specific resources" do
+ coll = stub 'coll', :evaluate => false
+ coll.expects(:resources).returns([:one, :two])
+
+ @compiler.add_collection(coll)
+
+ lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
+ end
+ end
+
+ describe Puppet::Parser::Compiler, "when told to evaluate missing classes" do
+
+ it "should fail if there's no source listed for the scope" do
+ scope = stub 'scope', :source => nil
+ proc { @compiler.evaluate_classes(%w{one two}, scope) }.should raise_error(Puppet::DevError)
+ end
+
+ it "should tag the catalog with the name of each not-found class" do
+ @compiler.catalog.expects(:tag).with("notfound")
+ @scope.expects(:findclass).with("notfound").returns(nil)
+ @compiler.evaluate_classes(%w{notfound}, @scope)
+ end
+ end
+
+ describe Puppet::Parser::Compiler, " when evaluating found classes" do
+
+ before do
+ @class = stub 'class', :classname => "my::class"
+ @scope.stubs(:findclass).with("myclass").returns(@class)
+
+ @resource = stub 'resource', :ref => "Class[myclass]"
+ end
+
+ it "should evaluate each class" do
+ @compiler.catalog.stubs(:tag)
+
+ @class.expects(:evaluate).with(@scope)
+
+ @compiler.evaluate_classes(%w{myclass}, @scope)
+ end
+
+ it "should not evaluate the resources created for found classes unless asked" do
+ @compiler.catalog.stubs(:tag)
+
+ @resource.expects(:evaluate).never
+
+ @class.expects(:evaluate).returns(@resource)
+
+ @compiler.evaluate_classes(%w{myclass}, @scope)
+ end
+
+ it "should immediately evaluate the resources created for found classes when asked" do
+ @compiler.catalog.stubs(:tag)
+
+ @resource.expects(:evaluate)
+ @class.expects(:evaluate).returns(@resource)
+
+ @compiler.evaluate_classes(%w{myclass}, @scope, false)
+ end
+
+ it "should skip classes that have already been evaluated" do
+ @compiler.catalog.stubs(:tag)
+
+ @compiler.expects(:class_scope).with(@class).returns("something")
+
+ @compiler.expects(:add_resource).never
+
+ @resource.expects(:evaluate).never
+
+ Puppet::Parser::Resource.expects(:new).never
+ @compiler.evaluate_classes(%w{myclass}, @scope, false)
+ end
+
+ it "should return the list of found classes" do
+ @compiler.catalog.stubs(:tag)
+
+ @compiler.stubs(:add_resource)
+ @scope.stubs(:findclass).with("notfound").returns(nil)
+
+ Puppet::Parser::Resource.stubs(:new).returns(@resource)
+ @class.stubs :evaluate
+ @compiler.evaluate_classes(%w{myclass notfound}, @scope).should == %w{myclass}
+ end
+ end
+
+ describe Puppet::Parser::Compiler, " when evaluating AST nodes with no AST nodes present" do
+
+ it "should do nothing" do
+ @compiler.expects(:ast_nodes?).returns(false)
+ @compiler.parser.expects(:nodes).never
+ Puppet::Parser::Resource.expects(:new).never
+
+ @compiler.send(:evaluate_ast_node)
+ end
+ end
+
+ describe Puppet::Parser::Compiler, " when evaluating AST nodes with AST nodes present" do
+
+ before do
+ @nodes = mock 'node_hash'
+ @compiler.stubs(:ast_nodes?).returns(true)
+ @compiler.parser.stubs(:nodes).returns(@nodes)
+
+ # Set some names for our test
+ @node.stubs(:names).returns(%w{a b c})
+ @nodes.stubs(:[]).with("a").returns(nil)
+ @nodes.stubs(:[]).with("b").returns(nil)
+ @nodes.stubs(:[]).with("c").returns(nil)
+
+ # It should check this last, of course.
+ @nodes.stubs(:[]).with("default").returns(nil)
+ end
+
+ it "should fail if the named node cannot be found" do
+ proc { @compiler.send(:evaluate_ast_node) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should evaluate the first node class matching the node name" do
+ node_class = stub 'node', :classname => "c", :evaluate_code => nil
+ @nodes.stubs(:[]).with("c").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
+ node_class.expects(:evaluate).returns(node_resource)
+
+ @compiler.compile
+ end
+
+ it "should match the default node if no matching node can be found" do
+ node_class = stub 'node', :classname => "default", :evaluate_code => nil
+ @nodes.stubs(:[]).with("default").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[default]", :evaluate => nil
+ node_class.expects(:evaluate).returns(node_resource)
+
+ @compiler.compile
+ end
+
+ it "should evaluate the node resource immediately rather than using lazy evaluation" do
+ node_class = stub 'node', :classname => "c"
+ @nodes.stubs(:[]).with("c").returns(node_class)
+
+ node_resource = stub 'node resource', :ref => "Node[c]"
+ node_class.expects(:evaluate).returns(node_resource)
+
+ node_resource.expects(:evaluate)
+
+ @compiler.send(:evaluate_ast_node)
+ end
+
+ it "should set the node's scope as the top scope" do
+ node_resource = stub 'node resource', :ref => "Node[c]", :evaluate => nil
+ node_class = stub 'node', :classname => "c", :evaluate => node_resource
+
+ @nodes.stubs(:[]).with("c").returns(node_class)
+
+ # The #evaluate method normally does this.
+ scope = stub 'scope', :source => "mysource"
+ @compiler.class_set(node_class.classname, scope)
+ node_resource.stubs(:evaluate)
+
+ @compiler.compile
+
+ @compiler.topscope.should equal(scope)
+ end
+ end
+
+ describe Puppet::Parser::Compiler, "when storing compiled resources" do
+
+ it "should store the resources" do
+ Puppet.features.expects(:rails?).returns(true)
+ Puppet::Rails.expects(:connect)
+
+ @compiler.catalog.expects(:vertices).returns(:resources)
+
+ @compiler.expects(:store_to_active_record).with(@node, :resources)
+ @compiler.send(:store)
+ end
+
+ it "should store to active_record" do
+ @node.expects(:name).returns("myname")
+ Puppet::Rails::Host.stubs(:transaction).yields
+ Puppet::Rails::Host.expects(:store).with(@node, :resources)
+ @compiler.send(:store_to_active_record, @node, :resources)
+ end
+ end
+
+ describe Puppet::Parser::Compiler, "when managing resource overrides" do
+
+ before do
+ @override = stub 'override', :ref => "My[ref]"
+ @resource = stub 'resource', :ref => "My[ref]", :builtin? => true
+ end
+
+ it "should be able to store overrides" do
+ lambda { @compiler.add_override(@override) }.should_not raise_error
+ end
+
+ it "should apply overrides to the appropriate resources" do
+ @compiler.add_resource(@scope, @resource)
+ @resource.expects(:merge).with(@override)
+
+ @compiler.add_override(@override)
+
+ @compiler.compile
+ end
+
+ it "should accept overrides before the related resource has been created" do
+ @resource.expects(:merge).with(@override)
+
+ # First store the override
+ @compiler.add_override(@override)
+
+ # Then the resource
+ @compiler.add_resource(@scope, @resource)
+
+ # And compile, so they get resolved
+ @compiler.compile
+ end
+
+ it "should fail if the compile is finished and resource overrides have not been applied" do
+ @compiler.add_override(@override)
+
+ lambda { @compiler.compile }.should raise_error(Puppet::ParseError)
+ end
+ end
+
+ # #620 - Nodes and classes should conflict, else classes don't get evaluated
+ describe Puppet::Parser::Compiler, "when evaluating nodes and classes with the same name (#620)" do
+
+ before do
+ @node = stub :nodescope? => true
+ @class = stub :nodescope? => false
+ end
+
+ it "should fail if a node already exists with the same name as the class being evaluated" do
+ @compiler.class_set("one", @node)
+ lambda { @compiler.class_set("one", @class) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail if a class already exists with the same name as the node being evaluated" do
+ @compiler.class_set("one", @class)
+ lambda { @compiler.class_set("one", @node) }.should raise_error(Puppet::ParseError)
+ end
+ end
+end
diff --git a/spec/unit/parser/interpreter.rb b/spec/unit/parser/interpreter.rb
index ed30ced93..f2526c73d 100755
--- a/spec/unit/parser/interpreter.rb
+++ b/spec/unit/parser/interpreter.rb
@@ -2,147 +2,158 @@
require File.dirname(__FILE__) + '/../../spec_helper'
-describe Puppet::Parser::Interpreter, " when creating parser instances" do
+describe Puppet::Parser::Interpreter do
before do
@interp = Puppet::Parser::Interpreter.new
- @parser = mock('parser')
- end
-
- it "should create a parser with code if there is code defined in the :code setting" do
- Puppet.settings.stubs(:value).with(:code, :myenv).returns("mycode")
- @parser.expects(:string=).with("mycode")
- @parser.expects(:parse)
- Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).returns(@parser)
- @interp.send(:create_parser, :myenv).object_id.should equal(@parser.object_id)
- end
-
- it "should create a parser with the main manifest when the code setting is an empty string" do
- Puppet.settings.stubs(:value).with(:code, :myenv).returns("")
- Puppet.settings.stubs(:value).with(:manifest, :myenv).returns("/my/file")
- @parser.expects(:parse)
- @parser.expects(:file=).with("/my/file")
- Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).returns(@parser)
- @interp.send(:create_parser, :myenv).should equal(@parser)
- end
-
- it "should return nothing when new parsers fail" do
- Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).raises(ArgumentError)
- proc { @interp.send(:create_parser, :myenv) }.should raise_error(Puppet::Error)
- end
-
- it "should create parsers with environment-appropriate manifests" do
- # Set our per-environment values. We can't just stub :value, because
- # it's called by too much of the rest of the code.
- text = "[env1]\nmanifest = /t/env1.pp\n[env2]\nmanifest = /t/env2.pp"
- file = mock 'file'
- file.stubs(:changed?).returns(true)
- file.stubs(:file).returns("/whatever")
- Puppet.settings.stubs(:read_file).with(file).returns(text)
- Puppet.settings.parse(file)
-
- parser1 = mock 'parser1'
- Puppet::Parser::Parser.expects(:new).with(:environment => :env1).returns(parser1)
- parser1.expects(:file=).with("/t/env1.pp")
- parser1.expects(:parse)
- @interp.send(:create_parser, :env1)
-
- parser2 = mock 'parser2'
- Puppet::Parser::Parser.expects(:new).with(:environment => :env2).returns(parser2)
- parser2.expects(:file=).with("/t/env2.pp")
- parser2.expects(:parse)
- @interp.send(:create_parser, :env2)
- end
-end
-
-describe Puppet::Parser::Interpreter, " when managing parser instances" do
- before do
- @interp = Puppet::Parser::Interpreter.new
- @parser = mock('parser')
- end
-
- it "should use the same parser when the parser does not need reparsing" do
- @interp.expects(:create_parser).with(:myenv).returns(@parser)
- @interp.send(:parser, :myenv).should equal(@parser)
-
- @parser.expects(:reparse?).returns(false)
- @interp.send(:parser, :myenv).should equal(@parser)
- end
-
- it "should create a new parser when reparse is true" do
- oldparser = mock('oldparser')
- newparser = mock('newparser')
- oldparser.expects(:reparse?).returns(true)
- oldparser.expects(:clear)
-
- @interp.expects(:create_parser).with(:myenv).returns(oldparser)
- @interp.send(:parser, :myenv).should equal(oldparser)
- @interp.expects(:create_parser).with(:myenv).returns(newparser)
- @interp.send(:parser, :myenv).should equal(newparser)
- end
-
- it "should fail intelligently if a parser cannot be created and one does not already exist" do
- @interp.expects(:create_parser).with(:myenv).raises(ArgumentError)
- proc { @interp.send(:parser, :myenv) }.should raise_error(ArgumentError)
- end
-
- it "should keep the old parser if a new parser cannot be created" do
- # Get the first parser in the hash.
- @interp.expects(:create_parser).with(:myenv).returns(@parser)
- @interp.send(:parser, :myenv).should equal(@parser)
-
- # Have it indicate something has changed
- @parser.expects(:reparse?).returns(true)
-
- # But fail to create a new parser
- @interp.expects(:create_parser).with(:myenv).raises(ArgumentError)
-
- # And make sure we still get the old valid parser
- @interp.send(:parser, :myenv).should equal(@parser)
- end
-
- it "should use different parsers for different environments" do
- # get one for the first env
- @interp.expects(:create_parser).with(:first_env).returns(@parser)
- @interp.send(:parser, :first_env).should equal(@parser)
-
- other_parser = mock('otherparser')
- @interp.expects(:create_parser).with(:second_env).returns(other_parser)
- @interp.send(:parser, :second_env).should equal(other_parser)
- end
-end
-
-describe Puppet::Parser::Interpreter, " when compiling catalog" do
- before do
- @interp = Puppet::Parser::Interpreter.new
- @node = stub 'node', :environment => :myenv
- @compile = mock 'compile'
@parser = mock 'parser'
end
- it "should create a compile with the node and parser" do
- @compile.expects(:compile).returns(:config)
- @interp.expects(:parser).with(:myenv).returns(@parser)
- Puppet::Parser::Compile.expects(:new).with(@node, @parser).returns(@compile)
- @interp.compile(@node)
- end
-
- it "should fail intelligently when no parser can be found" do
- @interp.expects(:parser).with(:myenv).returns(nil)
- proc { @interp.compile(@node) }.should raise_error(Puppet::ParseError)
- end
-end
-
-describe Puppet::Parser::Interpreter, " when returning catalog version" do
- before do
- @interp = Puppet::Parser::Interpreter.new
- end
-
- it "should ask the appropriate parser for the catalog version" do
- node = mock 'node'
- node.expects(:environment).returns(:myenv)
- parser = mock 'parser'
- parser.expects(:version).returns(:myvers)
- @interp.expects(:parser).with(:myenv).returns(parser)
- @interp.configuration_version(node).should equal(:myvers)
+ describe "when creating parser instances" do
+ it "should create a parser with code if there is code defined in the :code setting" do
+ Puppet.settings.stubs(:value).with(:code, :myenv).returns("mycode")
+ @parser.expects(:string=).with("mycode")
+ @parser.expects(:parse)
+ Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).returns(@parser)
+ @interp.send(:create_parser, :myenv).object_id.should equal(@parser.object_id)
+ end
+
+ it "should create a parser with the main manifest when the code setting is an empty string" do
+ Puppet.settings.stubs(:value).with(:code, :myenv).returns("")
+ Puppet.settings.stubs(:value).with(:manifest, :myenv).returns("/my/file")
+ @parser.expects(:parse)
+ @parser.expects(:file=).with("/my/file")
+ Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).returns(@parser)
+ @interp.send(:create_parser, :myenv).should equal(@parser)
+ end
+
+ it "should return nothing when new parsers fail" do
+ Puppet::Parser::Parser.expects(:new).with(:environment => :myenv).raises(ArgumentError)
+ proc { @interp.send(:create_parser, :myenv) }.should raise_error(Puppet::Error)
+ end
+
+ it "should create parsers with environment-appropriate manifests" do
+ # Set our per-environment values. We can't just stub :value, because
+ # it's called by too much of the rest of the code.
+ text = "[env1]\nmanifest = /t/env1.pp\n[env2]\nmanifest = /t/env2.pp"
+ file = mock 'file'
+ file.stubs(:changed?).returns(true)
+ file.stubs(:file).returns("/whatever")
+ Puppet.settings.stubs(:read_file).with(file).returns(text)
+ Puppet.settings.parse(file)
+
+ parser1 = mock 'parser1'
+ Puppet::Parser::Parser.expects(:new).with(:environment => :env1).returns(parser1)
+ parser1.expects(:file=).with("/t/env1.pp")
+ parser1.expects(:parse)
+ @interp.send(:create_parser, :env1)
+
+ parser2 = mock 'parser2'
+ Puppet::Parser::Parser.expects(:new).with(:environment => :env2).returns(parser2)
+ parser2.expects(:file=).with("/t/env2.pp")
+ parser2.expects(:parse)
+ @interp.send(:create_parser, :env2)
+ end
+ end
+
+ describe "when managing parser instances" do
+ it "should use the same parser when the parser does not need reparsing" do
+ @interp.expects(:create_parser).with(:myenv).returns(@parser)
+ @interp.send(:parser, :myenv).should equal(@parser)
+
+ @parser.expects(:reparse?).returns(false)
+ @interp.send(:parser, :myenv).should equal(@parser)
+ end
+
+ it "should fail intelligently if a parser cannot be created and one does not already exist" do
+ @interp.expects(:create_parser).with(:myenv).raises(ArgumentError)
+ proc { @interp.send(:parser, :myenv) }.should raise_error(ArgumentError)
+ end
+
+ it "should use different parsers for different environments" do
+ # get one for the first env
+ @interp.expects(:create_parser).with(:first_env).returns(@parser)
+ @interp.send(:parser, :first_env).should equal(@parser)
+
+ other_parser = mock('otherparser')
+ @interp.expects(:create_parser).with(:second_env).returns(other_parser)
+ @interp.send(:parser, :second_env).should equal(other_parser)
+ end
+
+ describe "when files need reparsing" do
+ it "should create a new parser" do
+ oldparser = mock('oldparser')
+ newparser = mock('newparser')
+ oldparser.expects(:reparse?).returns(true)
+ oldparser.expects(:clear)
+
+ @interp.expects(:create_parser).with(:myenv).returns(oldparser)
+ @interp.send(:parser, :myenv).should equal(oldparser)
+ @interp.expects(:create_parser).with(:myenv).returns(newparser)
+ @interp.send(:parser, :myenv).should equal(newparser)
+ end
+
+ it "should keep the old parser if a new parser cannot be created" do
+ # Get the first parser in the hash.
+ @interp.expects(:create_parser).with(:myenv).returns(@parser)
+ @interp.send(:parser, :myenv).should equal(@parser)
+
+ # Have it indicate something has changed
+ @parser.expects(:reparse?).returns(true)
+
+ # But fail to create a new parser
+ @interp.expects(:create_parser).with(:myenv).raises(ArgumentError)
+
+ # And make sure we still get the old valid parser
+ @interp.send(:parser, :myenv).should equal(@parser)
+ end
+
+ it "should log syntax errors when using the old parser" do
+ # Get the first parser in the hash.
+ @interp.stubs(:create_parser).with(:myenv).returns(@parser)
+ @interp.send(:parser, :myenv)
+
+ # Have it indicate something has changed
+ @parser.stubs(:reparse?).returns(true)
+
+ # But fail to create a new parser
+ @interp.stubs(:create_parser).with(:myenv).raises(ArgumentError)
+
+ Puppet.expects(:err)
+
+ # And make sure we still get the old valid parser
+ @interp.send(:parser, :myenv)
+ end
+ end
+ end
+
+ describe "when compiling a catalog" do
+ before do
+ @node = stub 'node', :environment => :myenv
+ @compiler = mock 'compile'
+ end
+
+ it "should create a compile with the node and parser" do
+ @compiler.expects(:compile).returns(:config)
+ @interp.expects(:parser).with(:myenv).returns(@parser)
+ Puppet::Parser::Compiler.expects(:new).with(@node, @parser).returns(@compiler)
+ @interp.compile(@node)
+ end
+
+ it "should fail intelligently when no parser can be found" do
+ @node.stubs(:name).returns("whatever")
+ @interp.expects(:parser).with(:myenv).returns(nil)
+ proc { @interp.compile(@node) }.should raise_error(Puppet::ParseError)
+ end
+ end
+
+ describe "when returning catalog version" do
+ it "should ask the appropriate parser for the catalog version" do
+ node = mock 'node'
+ node.expects(:environment).returns(:myenv)
+ parser = mock 'parser'
+ parser.expects(:version).returns(:myvers)
+ @interp.expects(:parser).with(:myenv).returns(parser)
+ @interp.configuration_version(node).should equal(:myvers)
+ end
end
end
diff --git a/spec/unit/parser/lexer.rb b/spec/unit/parser/lexer.rb
new file mode 100755
index 000000000..9972f7268
--- /dev/null
+++ b/spec/unit/parser/lexer.rb
@@ -0,0 +1,465 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/parser/lexer'
+
+describe Puppet::Parser::Lexer::Token do
+ before do
+ @token = Puppet::Parser::Lexer::Token.new(%r{something}, :NAME)
+ end
+
+ [:regex, :name, :string, :skip, :incr_line, :skip_text].each do |param|
+ it "should have a #{param.to_s} reader" do
+ @token.should be_respond_to(param)
+ end
+
+ it "should have a #{param.to_s} writer" do
+ @token.should be_respond_to(param.to_s + "=")
+ end
+ end
+end
+
+describe Puppet::Parser::Lexer::Token, "when initializing" do
+ it "should create a regex if the first argument is a string" do
+ Puppet::Parser::Lexer::Token.new("something", :NAME).regex.should == %r{something}
+ end
+
+ it "should set the string if the first argument is one" do
+ Puppet::Parser::Lexer::Token.new("something", :NAME).string.should == "something"
+ end
+
+ it "should set the regex if the first argument is one" do
+ Puppet::Parser::Lexer::Token.new(%r{something}, :NAME).regex.should == %r{something}
+ end
+end
+
+describe Puppet::Parser::Lexer::TokenList do
+ before do
+ @list = Puppet::Parser::Lexer::TokenList.new
+ end
+
+ it "should have a method for retrieving tokens by the name" do
+ token = @list.add_token :name, "whatever"
+ @list[:name].should equal(token)
+ end
+
+ it "should have a method for retrieving string tokens by the string" do
+ token = @list.add_token :name, "whatever"
+ @list.lookup("whatever").should equal(token)
+ end
+
+ it "should add tokens to the list when directed" do
+ token = @list.add_token :name, "whatever"
+ @list[:name].should equal(token)
+ end
+
+ it "should have a method for adding multiple tokens at once" do
+ @list.add_tokens "whatever" => :name, "foo" => :bar
+ @list[:name].should_not be_nil
+ @list[:bar].should_not be_nil
+ end
+
+ it "should fail to add tokens sharing a name with an existing token" do
+ @list.add_token :name, "whatever"
+ lambda { @list.add_token :name, "whatever" }.should raise_error(ArgumentError)
+ end
+
+ it "should set provided options on tokens being added" do
+ token = @list.add_token :name, "whatever", :skip_text => true
+ token.skip_text.should == true
+ end
+
+ it "should define any provided blocks as a :convert method" do
+ token = @list.add_token(:name, "whatever") do "foo" end
+ token.convert.should == "foo"
+ end
+
+ it "should store all string tokens in the :string_tokens list" do
+ one = @list.add_token(:name, "1")
+ @list.string_tokens.should be_include(one)
+ end
+
+ it "should store all regex tokens in the :regex_tokens list" do
+ one = @list.add_token(:name, %r{one})
+ @list.regex_tokens.should be_include(one)
+ end
+
+ it "should not store string tokens in the :regex_tokens list" do
+ one = @list.add_token(:name, "1")
+ @list.regex_tokens.should_not be_include(one)
+ end
+
+ it "should not store regex tokens in the :string_tokens list" do
+ one = @list.add_token(:name, %r{one})
+ @list.string_tokens.should_not be_include(one)
+ end
+
+ it "should sort the string tokens inversely by length when asked" do
+ one = @list.add_token(:name, "1")
+ two = @list.add_token(:other, "12")
+ @list.sort_tokens
+ @list.string_tokens.should == [two, one]
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS do
+ before do
+ @lexer = Puppet::Parser::Lexer.new()
+ end
+
+ {
+ :LBRACK => '[',
+ :RBRACK => ']',
+ :LBRACE => '{',
+ :RBRACE => '}',
+ :LPAREN => '(',
+ :RPAREN => ')',
+ :EQUALS => '=',
+ :ISEQUAL => '==',
+ :GREATEREQUAL => '>=',
+ :GREATERTHAN => '>',
+ :LESSTHAN => '<',
+ :LESSEQUAL => '<=',
+ :NOTEQUAL => '!=',
+ :NOT => '!',
+ :COMMA => ',',
+ :DOT => '.',
+ :COLON => ':',
+ :AT => '@',
+ :LLCOLLECT => '<<|',
+ :RRCOLLECT => '|>>',
+ :LCOLLECT => '<|',
+ :RCOLLECT => '|>',
+ :SEMIC => ';',
+ :QMARK => '?',
+ :BACKSLASH => '\\',
+ :FARROW => '=>',
+ :PARROW => '+>'
+ }.each do |name, string|
+ it "should have a token named #{name.to_s}" do
+ Puppet::Parser::Lexer::TOKENS[name].should_not be_nil
+ end
+
+ it "should match '#{string}' for the token #{name.to_s}" do
+ Puppet::Parser::Lexer::TOKENS[name].string.should == string
+ end
+ end
+
+ {
+ "case" => :CASE,
+ "class" => :CLASS,
+ "default" => :DEFAULT,
+ "define" => :DEFINE,
+ "import" => :IMPORT,
+ "if" => :IF,
+ "elsif" => :ELSIF,
+ "else" => :ELSE,
+ "inherits" => :INHERITS,
+ "node" => :NODE,
+ "and" => :AND,
+ "or" => :OR,
+ "undef" => :UNDEF,
+ "false" => :FALSE,
+ "true" => :TRUE
+ }.each do |string, name|
+ it "should have a keyword named #{name.to_s}" do
+ Puppet::Parser::Lexer::KEYWORDS[name].should_not be_nil
+ end
+
+ it "should have the keyword for #{name.to_s} set to #{string}" do
+ Puppet::Parser::Lexer::KEYWORDS[name].string.should == string
+ end
+ end
+
+ # These tokens' strings don't matter, just that the tokens exist.
+ [:DQTEXT, :SQTEXT, :BOOLEAN, :NAME, :NUMBER, :COMMENT, :RETURN, :SQUOTE, :DQUOTE, :VARIABLE].each do |name|
+ it "should have a token named #{name.to_s}" do
+ Puppet::Parser::Lexer::TOKENS[name].should_not be_nil
+ end
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:NAME] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:NAME] }
+
+ it "should match against lower-case alpha-numeric terms" do
+ @token.regex.should =~ "one-two"
+ end
+
+ it "should return itself and the value if the matched term is not a keyword" do
+ Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(nil)
+ @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"]
+ end
+
+ it "should return the keyword token and the value if the matched term is a keyword" do
+ keyword = stub 'keyword', :name => :testing
+ Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword)
+ @token.convert(stub("lexer"), "myval").should == [keyword, "myval"]
+ end
+
+ it "should return the BOOLEAN token and 'true' if the matched term is the string 'true'" do
+ keyword = stub 'keyword', :name => :TRUE
+ Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword)
+ @token.convert(stub('lexer'), "true").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], true]
+ end
+
+ it "should return the BOOLEAN token and 'false' if the matched term is the string 'false'" do
+ keyword = stub 'keyword', :name => :FALSE
+ Puppet::Parser::Lexer::KEYWORDS.expects(:lookup).returns(keyword)
+ @token.convert(stub('lexer'), "false").should == [Puppet::Parser::Lexer::TOKENS[:BOOLEAN], false]
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:NUMBER] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:NUMBER] }
+
+ it "should match against numeric terms" do
+ @token.regex.should =~ "2982383139"
+ end
+
+ it "should return the NAME token and the value" do
+ @token.convert(stub("lexer"), "myval").should == [Puppet::Parser::Lexer::TOKENS[:NAME], "myval"]
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:COMMENT] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:COMMENT] }
+
+ it "should match against lines starting with '#'" do
+ @token.regex.should =~ "# this is a comment"
+ end
+
+ it "should be marked to get skipped" do
+ @token.skip?.should be_true
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:RETURN] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:RETURN] }
+
+ it "should match against carriage returns" do
+ @token.regex.should =~ "\n"
+ end
+
+ it "should be marked to initiate text skipping" do
+ @token.skip_text.should be_true
+ end
+
+ it "should be marked to increment the line" do
+ @token.incr_line.should be_true
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:SQUOTE] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:SQUOTE] }
+
+ it "should match against single quotes" do
+ @token.regex.should =~ "'"
+ end
+
+ it "should slurp the rest of the quoted string" do
+ lexer = stub("lexer")
+ lexer.expects(:slurpstring).with("myval").returns("otherval")
+ @token.convert(lexer, "myval")
+ end
+
+ it "should return the SQTEXT token with the slurped string" do
+ lexer = stub("lexer")
+ lexer.stubs(:slurpstring).with("myval").returns("otherval")
+ @token.convert(lexer, "myval").should == [Puppet::Parser::Lexer::TOKENS[:SQTEXT], "otherval"]
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:DQUOTE] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:DQUOTE] }
+
+ it "should match against single quotes" do
+ @token.regex.should =~ '"'
+ end
+
+ it "should slurp the rest of the quoted string" do
+ lexer = stub("lexer")
+ lexer.expects(:slurpstring).with("myval").returns("otherval")
+ @token.convert(lexer, "myval")
+ end
+
+ it "should return the DQTEXT token with the slurped string" do
+ lexer = stub("lexer")
+ lexer.stubs(:slurpstring).with("myval").returns("otherval")
+ @token.convert(lexer, "myval").should == [Puppet::Parser::Lexer::TOKENS[:DQTEXT], "otherval"]
+ end
+end
+
+describe Puppet::Parser::Lexer::TOKENS[:VARIABLE] do
+ before { @token = Puppet::Parser::Lexer::TOKENS[:VARIABLE] }
+
+ it "should match against alpha words prefixed with '$'" do
+ @token.regex.should =~ '$this_var'
+ end
+
+ it "should return the VARIABLE token and the variable name stripped of the '$'" do
+ @token.convert(stub("lexer"), "$myval").should == [Puppet::Parser::Lexer::TOKENS[:VARIABLE], "myval"]
+ end
+end
+
+# FIXME: We need to rewrite all of these tests, but I just don't want to take the time right now.
+describe "Puppet::Parser::Lexer in the old tests" do
+ before { @lexer = Puppet::Parser::Lexer.new }
+
+ it "should do simple lexing" do
+ strings = {
+%q{\\} => [[:BACKSLASH,"\\"],[false,false]],
+%q{simplest scanner test} => [[:NAME,"simplest"],[:NAME,"scanner"],[:NAME,"test"],[false,false]],
+%q{returned scanner test
+} => [[:NAME,"returned"],[:NAME,"scanner"],[:NAME,"test"],[false,false]]
+ }
+ strings.each { |str,ary|
+ @lexer.string = str
+ @lexer.fullscan().should == ary
+ }
+ end
+
+ it "should correctly lex quoted strings" do
+ strings = {
+%q{a simple "scanner" test
+} => [[:NAME,"a"],[:NAME,"simple"],[:DQTEXT,"scanner"],[:NAME,"test"],[false,false]],
+%q{a simple 'single quote scanner' test
+} => [[:NAME,"a"],[:NAME,"simple"],[:SQTEXT,"single quote scanner"],[:NAME,"test"],[false,false]],
+%q{a harder 'a $b \c"'
+} => [[:NAME,"a"],[:NAME,"harder"],[:SQTEXT,'a $b \c"'],[false,false]],
+%q{a harder "scanner test"
+} => [[:NAME,"a"],[:NAME,"harder"],[:DQTEXT,"scanner test"],[false,false]],
+%q{a hardest "scanner \"test\""
+} => [[:NAME,"a"],[:NAME,"hardest"],[:DQTEXT,'scanner "test"'],[false,false]],
+%q{a hardestest "scanner \"test\"
+"
+} => [[:NAME,"a"],[:NAME,"hardestest"],[:DQTEXT,'scanner "test"
+'],[false,false]],
+%q{function("call")} => [[:NAME,"function"],[:LPAREN,"("],[:DQTEXT,'call'],[:RPAREN,")"],[false,false]]
+}
+ strings.each { |str,array|
+ @lexer.string = str
+ @lexer.fullscan().should == array
+ }
+ end
+
+ it "should fail usefully" do
+ strings = %w{
+ ^
+ }
+ strings.each { |str|
+ @lexer.string = str
+ lambda { @lexer.fullscan() }.should raise_error(RuntimeError)
+ }
+ end
+
+ it "should fail if the string is not set" do
+ lambda { @lexer.fullscan() }.should raise_error(Puppet::LexError)
+ end
+
+ it "should correctly identify keywords" do
+ @lexer.string = "case"
+ @lexer.fullscan.should == [[:CASE, "case"], [false, false]]
+ end
+
+ it "should correctly match strings" do
+ names = %w{this is a bunch of names}
+ types = %w{Many Different Words A Word}
+ words = %w{differently Cased words A a}
+
+ names.each { |t|
+ @lexer.string = t
+ @lexer.fullscan.should == [[:NAME,t],[false,false]]
+ }
+ types.each { |t|
+ @lexer.string = t
+ @lexer.fullscan.should == [[:CLASSREF,t],[false,false]]
+ }
+ end
+
+ it "should correctly parse empty strings" do
+ bit = '$var = ""'
+
+ @lexer.string = bit
+
+ lambda { @lexer.fullscan }.should_not raise_error
+ end
+
+ it "should correctly parse virtual resources" do
+ string = "@type {"
+
+ @lexer.string = string
+
+ @lexer.fullscan.should == [[:AT, "@"], [:NAME, "type"], [:LBRACE, "{"], [false,false]]
+ end
+
+ it "should correctly deal with namespaces" do
+ @lexer.string = %{class myclass}
+
+ @lexer.fullscan
+
+ @lexer.namespace.should == "myclass"
+
+ @lexer.namepop
+
+ @lexer.namespace.should == ""
+
+ @lexer.string = "class base { class sub { class more"
+
+ @lexer.fullscan
+
+ @lexer.namespace.should == "base::sub::more"
+
+ @lexer.namepop
+
+ @lexer.namespace.should == "base::sub"
+ end
+
+ it "should correctly handle fully qualified names" do
+ @lexer.string = "class base { class sub::more {"
+
+ @lexer.fullscan
+
+ @lexer.namespace.should == "base::sub::more"
+
+ @lexer.namepop
+
+ @lexer.namespace.should == "base"
+ end
+
+ it "should correctly lex variables" do
+ ["$variable", "$::variable", "$qualified::variable", "$further::qualified::variable"].each do |string|
+ @lexer.string = string
+
+ @lexer.scan do |t, s|
+ t.should == :VARIABLE
+ string.sub(/^\$/, '').should == s
+ break
+ end
+ end
+ end
+
+ # #774
+ it "should correctly parse the CLASSREF token" do
+ string = ["Foo", "::Foo","Foo::Bar","::Foo::Bar"]
+
+ string.each do |foo|
+ @lexer.string = foo
+ @lexer.fullscan[0].should == [:CLASSREF, foo]
+ end
+ end
+end
+
+require 'puppettest/support/utils'
+describe "Puppet::Parser::Lexer in the old tests when lexing example files" do
+ extend PuppetTest
+ extend PuppetTest::Support::Utils
+ textfiles() do |file|
+ it "should correctly lex #{file}" do
+ lexer = Puppet::Parser::Lexer.new()
+ lexer.file = file
+ lambda { lexer.fullscan() }.should_not raise_error
+ end
+ end
+end
diff --git a/spec/unit/parser/resource.rb b/spec/unit/parser/resource.rb
index 3d048f7e6..776e9c742 100755
--- a/spec/unit/parser/resource.rb
+++ b/spec/unit/parser/resource.rb
@@ -4,86 +4,316 @@ require File.dirname(__FILE__) + '/../../spec_helper'
# LAK: FIXME This is just new tests for resources; I have
# not moved all tests over yet.
-describe Puppet::Parser::Resource, " when evaluating" do
- before do
- @type = Puppet::Parser::Resource
+describe Puppet::Parser::Resource do
+ before do
@parser = Puppet::Parser::Parser.new :Code => ""
@source = @parser.newclass ""
- @definition = @parser.newdefine "mydefine"
- @class = @parser.newclass "myclass"
- @nodedef = @parser.newnode("mynode")[0]
@node = Puppet::Node.new("yaynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- @scope = @compile.topscope
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
+ @scope = @compiler.topscope
end
- it "should evaluate the associated AST definition" do
- res = @type.new(:type => "mydefine", :title => "whatever", :scope => @scope, :source => @source)
- @definition.expects(:evaluate).with(:scope => @scope, :resource => res)
+ def mkresource(args = {})
+ args[:source] ||= "source"
+ args[:scope] ||= stub('scope', :source => mock('source'))
+
+ {:type => "resource", :title => "testing", :source => "source", :scope => "scope"}.each do |param, value|
+ args[param] ||= value
+ end
+
+ params = args[:params] || {:one => "yay", :three => "rah"}
+ if args[:params] == :none
+ args.delete(:params)
+ else
+ args[:params] = paramify(args[:source], params)
+ end
- res.evaluate
+ Puppet::Parser::Resource.new(args)
end
- it "should evaluate the associated AST class" do
- res = @type.new(:type => "class", :title => "myclass", :scope => @scope, :source => @source)
- @class.expects(:evaluate).with(:scope => @scope, :resource => res)
- res.evaluate
+ def param(name, value, source)
+ Puppet::Parser::Resource::Param.new(:name => name, :value => value, :source => source)
end
- it "should evaluate the associated AST node" do
- res = @type.new(:type => "node", :title => "mynode", :scope => @scope, :source => @source)
- @nodedef.expects(:evaluate).with(:scope => @scope, :resource => res)
- res.evaluate
+ def paramify(source, hash)
+ hash.collect do |name, value|
+ Puppet::Parser::Resource::Param.new(
+ :name => name, :value => value, :source => source
+ )
+ end
end
-end
-describe Puppet::Parser::Resource, " when finishing" do
- before do
- @parser = Puppet::Parser::Parser.new :Code => ""
- @source = @parser.newclass ""
- @definition = @parser.newdefine "mydefine"
- @class = @parser.newclass "myclass"
- @nodedef = @parser.newnode("mynode")[0]
- @node = Puppet::Node.new("yaynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
- @scope = @compile.topscope
+ it "should be isomorphic if it is builtin and models an isomorphic type" do
+ Puppet::Type.type(:file).expects(:isomorphic?).returns(true)
+ @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
+ end
+
+ it "should not be isomorphic if it is builtin and models a non-isomorphic type" do
+ Puppet::Type.type(:file).expects(:isomorphic?).returns(false)
+ @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_false
+ end
- @resource = Puppet::Parser::Resource.new(:type => "mydefine", :title => "whatever", :scope => @scope, :source => @source)
+ it "should be isomorphic if it is not builtin" do
+ @parser.newdefine "whatever"
+ @resource = Puppet::Parser::Resource.new(:type => "whatever", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true
end
- it "should copy metaparams from its scope" do
- @scope.setvar("noop", "true")
+ it "should have a array-indexing method for retrieving parameter values" do
+ @resource = mkresource
+ @resource[:one].should == "yay"
+ end
+
+ describe "when initializing" do
+ before do
+ @arguments = {:type => "resource", :title => "testing", :scope => stub('scope', :source => mock('source'))}
+ end
- @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+ [:type, :title, :scope].each do |name|
+ it "should fail unless #{name.to_s} is specified" do
+ try = @arguments.dup
+ try.delete(name)
+ lambda { Puppet::Parser::Resource.new(try) }.should raise_error(ArgumentError)
+ end
+ end
- @resource["noop"].should == "true"
+ it "should set the reference correctly" do
+ res = Puppet::Parser::Resource.new(@arguments)
+ res.ref.should == "Resource[testing]"
+ end
end
- it "should not copy metaparams that it already has" do
- @resource.class.publicize_methods(:set_parameter) { @resource.set_parameter("noop", "false") }
- @scope.setvar("noop", "true")
+ describe "when evaluating" do
+ before do
+ @type = Puppet::Parser::Resource
+
+ @definition = @parser.newdefine "mydefine"
+ @class = @parser.newclass "myclass"
+ @nodedef = @parser.newnode("mynode")[0]
+ end
+
+ it "should evaluate the associated AST definition" do
+ res = @type.new(:type => "mydefine", :title => "whatever", :scope => @scope, :source => @source)
+ @definition.expects(:evaluate_code).with(res)
+
+ res.evaluate
+ end
+
+ it "should evaluate the associated AST class" do
+ res = @type.new(:type => "class", :title => "myclass", :scope => @scope, :source => @source)
+ @class.expects(:evaluate_code).with(res)
+ res.evaluate
+ end
+
+ it "should evaluate the associated AST node" do
+ res = @type.new(:type => "node", :title => "mynode", :scope => @scope, :source => @source)
+ @nodedef.expects(:evaluate_code).with(res)
+ res.evaluate
+ end
+ end
+
+ describe "when finishing" do
+ before do
+ @class = @parser.newclass "myclass"
+ @nodedef = @parser.newnode("mynode")[0]
+
+ @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source)
+ end
+
+ it "should do nothing if it has already been finished" do
+ @resource.finish
+ @resource.expects(:add_metaparams).never
+ @resource.finish
+ end
+
+ it "should add all defaults available from the scope" do
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => param(:owner, "default", @resource.source))
+ @resource.finish
+
+ @resource[:owner].should == "default"
+ end
+
+ it "should not replace existing parameters with defaults" do
+ @resource.set_parameter :owner, "oldvalue"
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => :replaced)
+ @resource.finish
+
+ @resource[:owner].should == "oldvalue"
+ end
+
+ it "should add a copy of each default, rather than the actual default parameter instance" do
+ newparam = param(:owner, "default", @resource.source)
+ other = newparam.dup
+ other.value = "other"
+ newparam.expects(:dup).returns(other)
+ @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => newparam)
+ @resource.finish
+
+ @resource[:owner].should == "other"
+ end
+
+ it "should copy metaparams from its scope" do
+ @scope.setvar("noop", "true")
+
+ @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
- @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+ @resource["noop"].should == "true"
+ end
- @resource["noop"].should == "false"
+ it "should not copy metaparams that it already has" do
+ @resource.set_parameter("noop", "false")
+ @scope.setvar("noop", "true")
+
+ @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+
+ @resource["noop"].should == "false"
+ end
+
+ it "should stack relationship metaparams from its container if it already has them" do
+ @resource.set_parameter("require", "resource")
+ @scope.setvar("require", "container")
+
+ @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+
+ @resource["require"].sort.should == %w{container resource}
+ end
+
+ it "should flatten the array resulting from stacking relationship metaparams" do
+ @resource.set_parameter("require", ["resource1", "resource2"])
+ @scope.setvar("require", %w{container1 container2})
+
+ @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+
+ @resource["require"].sort.should == %w{container1 container2 resource1 resource2}
+ end
+
+ it "should add any tags from the scope resource" do
+ scope_resource = stub 'scope_resource', :tags => %w{one two}
+ @scope.stubs(:resource).returns(scope_resource)
+
+ @resource.class.publicize_methods(:add_scope_tags) { @resource.add_scope_tags }
+
+ @resource.tags.should be_include("one")
+ @resource.tags.should be_include("two")
+ end
end
- it "should stack relationship metaparams from its container if it already has them" do
- @resource.class.publicize_methods(:set_parameter) { @resource.set_parameter("require", "resource") }
- @scope.setvar("require", "container")
+ describe "when being tagged" do
+ before do
+ @scope_resource = stub 'scope_resource', :tags => %w{srone srtwo}
+ @scope = stub 'scope', :resource => @scope_resource
+ @resource = Puppet::Parser::Resource.new(:type => "file", :title => "yay", :scope => @scope, :source => mock('source'))
+ end
+
+ it "should get tagged with the resource type" do
+ @resource.tags.should be_include("file")
+ end
+
+ it "should get tagged with the title" do
+ @resource.tags.should be_include("yay")
+ end
+
+ it "should get tagged with each name in the title if the title is a qualified class name" do
+ resource = Puppet::Parser::Resource.new(:type => "file", :title => "one::two", :scope => @scope, :source => mock('source'))
+ resource.tags.should be_include("one")
+ resource.tags.should be_include("two")
+ end
+
+ it "should get tagged with each name in the type if the type is a qualified class name" do
+ resource = Puppet::Parser::Resource.new(:type => "one::two", :title => "whatever", :scope => @scope, :source => mock('source'))
+ resource.tags.should be_include("one")
+ resource.tags.should be_include("two")
+ end
+
+ it "should not get tagged with non-alphanumeric titles" do
+ resource = Puppet::Parser::Resource.new(:type => "file", :title => "this is a test", :scope => @scope, :source => mock('source'))
+ resource.tags.should_not be_include("this is a test")
+ end
- @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
+ it "should fail on tags containing '*' characters" do
+ lambda { @resource.tag("bad*tag") }.should raise_error(Puppet::ParseError)
+ end
- @resource["require"].sort.should == %w{container resource}
+ it "should fail on tags starting with '-' characters" do
+ lambda { @resource.tag("-badtag") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail on tags containing ' ' characters" do
+ lambda { @resource.tag("bad tag") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should allow alpha tags" do
+ lambda { @resource.tag("good_tag") }.should_not raise_error(Puppet::ParseError)
+ end
end
- it "should flatten the array resulting from stacking relationship metaparams" do
- @resource.class.publicize_methods(:set_parameter) { @resource.set_parameter("require", ["resource1", "resource2"]) }
- @scope.setvar("require", %w{container1 container2})
+ describe "when merging overrides" do
+ before do
+ @source = "source1"
+ @resource = mkresource :source => @source
+ @override = mkresource :source => @source
+ end
+
+ it "should fail when the override was not created by a parent class" do
+ @override.source = "source2"
+ @override.source.expects(:child_of?).with("source1").returns(false)
+ lambda { @resource.merge(@override) }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should succeed when the override was created in the current scope" do
+ @resource.source = "source3"
+ @override.source = @resource.source
+ @override.source.expects(:child_of?).with("source3").never
+ params = {:a => :b, :c => :d}
+ @override.expects(:params).returns(params)
+ @resource.expects(:override_parameter).with(:b)
+ @resource.expects(:override_parameter).with(:d)
+ @resource.merge(@override)
+ end
+
+ it "should succeed when a parent class created the override" do
+ @resource.source = "source3"
+ @override.source = "source4"
+ @override.source.expects(:child_of?).with("source3").returns(true)
+ params = {:a => :b, :c => :d}
+ @override.expects(:params).returns(params)
+ @resource.expects(:override_parameter).with(:b)
+ @resource.expects(:override_parameter).with(:d)
+ @resource.merge(@override)
+ end
+
+ it "should add new parameters when the parameter is not set" do
+ @source.stubs(:child_of?).returns true
+ @override.set_parameter(:testing, "value")
+ @resource.merge(@override)
+
+ @resource[:testing].should == "value"
+ end
+
+ it "should replace existing parameter values" do
+ @source.stubs(:child_of?).returns true
+ @resource.set_parameter(:testing, "old")
+ @override.set_parameter(:testing, "value")
+
+ @resource.merge(@override)
+
+ @resource[:testing].should == "value"
+ end
+
+ it "should add values to the parameter when the override was created with the '+>' syntax" do
+ @source.stubs(:child_of?).returns true
+ param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "testing", :source => @resource.source)
+ param.add = true
+
+ @override.set_parameter(param)
+
+ @resource.set_parameter(:testing, "other")
+
+ @resource.merge(@override)
+
+ @resource[:testing].should == %w{other testing}
+ end
- @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams }
- @resource["require"].sort.should == %w{container1 container2 resource1 resource2}
end
end
diff --git a/spec/unit/parser/resource/reference.rb b/spec/unit/parser/resource/reference.rb
index e7385f796..147f772d1 100755
--- a/spec/unit/parser/resource/reference.rb
+++ b/spec/unit/parser/resource/reference.rb
@@ -52,23 +52,23 @@ describe Puppet::Parser::Resource::Reference, " when modeling defined types" do
@nodedef = @parser.newnode("mynode")[0]
@node = Puppet::Node.new("yaynode")
- @compile = Puppet::Parser::Compile.new(@node, @parser)
+ @compiler = Puppet::Parser::Compiler.new(@node, @parser)
end
it "should be able to find defined types" do
- ref = @type.new(:type => "mydefine", :title => "/tmp/yay", :scope => @compile.topscope)
+ ref = @type.new(:type => "mydefine", :title => "/tmp/yay", :scope => @compiler.topscope)
ref.builtin?.should be_false
ref.definedtype.should equal(@definition)
end
it "should be able to find classes" do
- ref = @type.new(:type => "class", :title => "myclass", :scope => @compile.topscope)
+ ref = @type.new(:type => "class", :title => "myclass", :scope => @compiler.topscope)
ref.builtin?.should be_false
ref.definedtype.should equal(@class)
end
it "should be able to find nodes" do
- ref = @type.new(:type => "node", :title => "mynode", :scope => @compile.topscope)
+ ref = @type.new(:type => "node", :title => "mynode", :scope => @compiler.topscope)
ref.builtin?.should be_false
ref.definedtype.object_id.should == @nodedef.object_id
end
diff --git a/spec/unit/ral/provider/interface/redhat.rb b/spec/unit/ral/provider/interface/redhat.rb
index 0b3b75ffc..9bf1b9722 100755
--- a/spec/unit/ral/provider/interface/redhat.rb
+++ b/spec/unit/ral/provider/interface/redhat.rb
@@ -5,9 +5,6 @@
require File.dirname(__FILE__) + '/../../../../spec_helper'
-require 'puppet/provider/interface/redhat'
-
-
provider_class = Puppet::Type.type(:interface).provider(:redhat)
describe provider_class do
diff --git a/spec/unit/ral/provider/mount.rb b/spec/unit/ral/provider/mount.rb
index 65aaf7053..0b90d53c9 100755
--- a/spec/unit/ral/provider/mount.rb
+++ b/spec/unit/ral/provider/mount.rb
@@ -4,8 +4,8 @@ require File.dirname(__FILE__) + '/../../../spec_helper'
require 'puppet/provider/mount'
-module MountModuleTesting
- def setup
+describe Puppet::Provider::Mount do
+ before :each do
@mounter = Object.new
@mounter.extend(Puppet::Provider::Mount)
@@ -16,119 +16,115 @@ module MountModuleTesting
@mounter.stubs(:resource).returns(@resource)
end
-end
-describe Puppet::Provider::Mount, " when mounting" do
- include MountModuleTesting
+ describe Puppet::Provider::Mount, " when mounting" do
- it "should use the 'mountcmd' method to mount" do
- @mounter.stubs(:options).returns(nil)
- @mounter.expects(:mountcmd)
+ it "should use the 'mountcmd' method to mount" do
+ @mounter.stubs(:options).returns(nil)
+ @mounter.expects(:mountcmd)
- @mounter.mount
- end
+ @mounter.mount
+ end
- it "should flush before mounting if a flush method exists" do
- @mounter.meta_def(:flush) { }
- @mounter.expects(:flush)
- @mounter.stubs(:mountcmd)
- @mounter.stubs(:options).returns(nil)
+ it "should flush before mounting if a flush method exists" do
+ @mounter.meta_def(:flush) { }
+ @mounter.expects(:flush)
+ @mounter.stubs(:mountcmd)
+ @mounter.stubs(:options).returns(nil)
- @mounter.mount
- end
+ @mounter.mount
+ end
- it "should add the options following '-o' if they exist and are not set to :absent" do
- @mounter.stubs(:options).returns("ro")
- @mounter.expects(:mountcmd).with { |*ary| ary[0] == "-o" and ary[1] == "ro" }
+ it "should add the options following '-o' if they exist and are not set to :absent" do
+ @mounter.stubs(:options).returns("ro")
+ @mounter.expects(:mountcmd).with { |*ary| ary[0] == "-o" and ary[1] == "ro" }
- @mounter.mount
- end
+ @mounter.mount
+ end
- it "should specify the filesystem name to the mount command" do
- @mounter.stubs(:options).returns(nil)
- @mounter.expects(:mountcmd).with { |*ary| ary[-1] == @name }
+ it "should specify the filesystem name to the mount command" do
+ @mounter.stubs(:options).returns(nil)
+ @mounter.expects(:mountcmd).with { |*ary| ary[-1] == @name }
- @mounter.mount
+ @mounter.mount
+ end
end
-end
-describe Puppet::Provider::Mount, " when remounting" do
- include MountModuleTesting
-
- it "should use '-o remount' if the resource specifies it supports remounting" do
- @mounter.stubs(:info)
- @resource.stubs(:[]).with(:remounts).returns(:true)
- @mounter.expects(:mountcmd).with("-o", "remount", @name)
- @mounter.remount
+ describe Puppet::Provider::Mount, " when remounting" do
+
+ it "should use '-o remount' if the resource specifies it supports remounting" do
+ @mounter.stubs(:info)
+ @resource.stubs(:[]).with(:remounts).returns(:true)
+ @mounter.expects(:mountcmd).with("-o", "remount", @name)
+ @mounter.remount
+ end
+
+ it "should unmount and mount if the resource does not specify it supports remounting" do
+ @mounter.stubs(:info)
+ @resource.stubs(:[]).with(:remounts).returns(false)
+ @mounter.expects(:unmount)
+ @mounter.expects(:mount)
+ @mounter.remount
+ end
+
+ it "should log that it is remounting" do
+ @resource.stubs(:[]).with(:remounts).returns(:true)
+ @mounter.stubs(:mountcmd)
+ @mounter.expects(:info).with("Remounting")
+ @mounter.remount
+ end
end
- it "should unmount and mount if the resource does not specify it supports remounting" do
- @mounter.stubs(:info)
- @resource.stubs(:[]).with(:remounts).returns(false)
- @mounter.expects(:unmount)
- @mounter.expects(:mount)
- @mounter.remount
- end
+ describe Puppet::Provider::Mount, " when unmounting" do
- it "should log that it is remounting" do
- @resource.stubs(:[]).with(:remounts).returns(:true)
- @mounter.stubs(:mountcmd)
- @mounter.expects(:info).with("Remounting")
- @mounter.remount
+ it "should call the :umount command with the resource name" do
+ @mounter.expects(:umount).with(@name)
+ @mounter.unmount
+ end
end
-end
-describe Puppet::Provider::Mount, " when unmounting" do
- include MountModuleTesting
+ describe Puppet::Provider::Mount, " when determining if it is mounted" do
- it "should call the :umount command with the resource name" do
- @mounter.expects(:umount).with(@name)
- @mounter.unmount
- end
-end
-
-describe Puppet::Provider::Mount, " when determining if it is mounted" do
- include MountModuleTesting
+ it "should parse the results of running the mount command with no arguments" do
+ Facter.stubs(:value).returns("whatever")
+ @mounter.expects(:mountcmd).returns("")
- it "should parse the results of running the mount command with no arguments" do
- Facter.stubs(:value).returns("whatever")
- @mounter.expects(:mountcmd).returns("")
-
- @mounter.mounted?
- end
+ @mounter.mounted?
+ end
- it "should match ' on /private/var/automount<name>' if the operating system is Darwin" do
- Facter.stubs(:value).with("operatingsystem").returns("Darwin")
- @mounter.expects(:mountcmd).returns("/dev/whatever on /private/var/automount/\ndevfs on /dev")
+ it "should match ' on /private/var/automount<name>' if the operating system is Darwin" do
+ Facter.stubs(:value).with("operatingsystem").returns("Darwin")
+ @mounter.expects(:mountcmd).returns("/dev/whatever on /private/var/automount/\ndevfs on /dev")
- @mounter.should be_mounted
- end
+ @mounter.should be_mounted
+ end
- it "should match ' on <name>' if the operating system is Darwin" do
- Facter.stubs(:value).with("operatingsystem").returns("Darwin")
- @mounter.expects(:mountcmd).returns("/dev/disk03 on / (local, journaled)\ndevfs on /dev")
+ it "should match ' on <name>' if the operating system is Darwin" do
+ Facter.stubs(:value).with("operatingsystem").returns("Darwin")
+ @mounter.expects(:mountcmd).returns("/dev/disk03 on / (local, journaled)\ndevfs on /dev")
- @mounter.should be_mounted
- end
+ @mounter.should be_mounted
+ end
- it "should match '^<name> on' if the operating system is Solaris" do
- Facter.stubs(:value).with("operatingsystem").returns("Solaris")
- @mounter.expects(:mountcmd).returns("/ on /dev/dsk/whatever\n/var on /dev/dsk/other")
+ it "should match '^<name> on' if the operating system is Solaris" do
+ Facter.stubs(:value).with("operatingsystem").returns("Solaris")
+ @mounter.expects(:mountcmd).returns("/ on /dev/dsk/whatever\n/var on /dev/dsk/other")
- @mounter.should be_mounted
- end
+ @mounter.should be_mounted
+ end
- it "should match ' on <name>' if the operating system is not Darwin or Solaris" do
- Facter.stubs(:value).with("operatingsystem").returns("Debian")
- @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on / and stuff\n/dev/other/disk on /var and stuff")
+ it "should match ' on <name>' if the operating system is not Darwin or Solaris" do
+ Facter.stubs(:value).with("operatingsystem").returns("Debian")
+ @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on / and stuff\n/dev/other/disk on /var and stuff")
- @mounter.should be_mounted
- end
+ @mounter.should be_mounted
+ end
- it "should not be considered mounted if it did not match the mount output" do
- Facter.stubs(:value).with("operatingsystem").returns("Debian")
- @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on /something/else and stuff\n/dev/other/disk on /var and stuff")
+ it "should not be considered mounted if it did not match the mount output" do
+ Facter.stubs(:value).with("operatingsystem").returns("Debian")
+ @mounter.expects(:mountcmd).returns("/dev/dsk/whatever on /something/else and stuff\n/dev/other/disk on /var and stuff")
- @mounter.should_not be_mounted
+ @mounter.should_not be_mounted
+ end
end
end
diff --git a/spec/unit/ral/provider/mount/parsed.rb b/spec/unit/ral/provider/mount/parsed.rb
index 2fd15a543..b7f08a464 100755
--- a/spec/unit/ral/provider/mount/parsed.rb
+++ b/spec/unit/ral/provider/mount/parsed.rb
@@ -12,11 +12,6 @@ module ParsedMountTesting
include PuppetTest::Support::Utils
include PuppetTest::FileParsing
- def setup
- @mount_class = Puppet.type(:mount)
- @provider_class = @mount_class.provider(:parsed)
- end
-
def fake_fstab
os = Facter['operatingsystem']
if os == "Solaris"
@@ -79,100 +74,108 @@ end
provider_class = Puppet::Type.type(:mount).provider(:parsed)
describe provider_class do
- include ParsedMountTesting
+ before :each do
+ @mount_class = Puppet.type(:mount)
+ @provider_class = @mount_class.provider(:parsed)
+ end
- it "should be able to parse all of the example mount tabs" do
- tab = fake_fstab
- @provider = @provider_class
- # LAK:FIXME Again, a relatively bad test, but I don't know how to rspec-ify this.
- # I suppose this is more of an integration test? I dunno.
- fakedataparse(tab) do
- # Now just make we've got some mounts we know will be there
- hashes = @provider_class.target_records(tab).find_all { |i| i.is_a? Hash }
- (hashes.length > 0).should be_true
- root = hashes.find { |i| i[:name] == "/" }
+ describe provider_class do
+ include ParsedMountTesting
- proc { @provider_class.to_file(hashes) }.should_not raise_error
- end
- end
+ it "should be able to parse all of the example mount tabs" do
+ tab = fake_fstab
+ @provider = @provider_class
+
+ # LAK:FIXME Again, a relatively bad test, but I don't know how to rspec-ify this.
+ # I suppose this is more of an integration test? I dunno.
+ fakedataparse(tab) do
+ # Now just make we've got some mounts we know will be there
+ hashes = @provider_class.target_records(tab).find_all { |i| i.is_a? Hash }
+ (hashes.length > 0).should be_true
+ root = hashes.find { |i| i[:name] == "/" }
- # LAK:FIXME I can't mock Facter because this test happens at parse-time.
- it "should default to /etc/vfstab on Solaris and /etc/fstab everywhere else" do
- should = case Facter.value(:operatingsystem)
- when "Solaris": "/etc/vfstab"
- else
- "/etc/fstab"
+ proc { @provider_class.to_file(hashes) }.should_not raise_error
end
- Puppet::Type.type(:mount).provider(:parsed).default_target.should == should
+ end
+
+ # LAK:FIXME I can't mock Facter because this test happens at parse-time.
+ it "should default to /etc/vfstab on Solaris and /etc/fstab everywhere else" do
+ should = case Facter.value(:operatingsystem)
+ when "Solaris": "/etc/vfstab"
+ else
+ "/etc/fstab"
+ end
+ Puppet::Type.type(:mount).provider(:parsed).default_target.should == should
+ end
end
-end
-describe provider_class, " when mounting an absent filesystem" do
- include ParsedMountTesting
+ describe provider_class, " when mounting an absent filesystem" do
+ include ParsedMountTesting
- # #730 - Make sure 'flush' is called when a mount is moving from absent to mounted
- it "should flush the fstab to disk" do
- mount = mkmount
+ # #730 - Make sure 'flush' is called when a mount is moving from absent to mounted
+ it "should flush the fstab to disk" do
+ mount = mkmount
- # Mark the mount as absent
- mount.property_hash[:ensure] = :absent
+ # Mark the mount as absent
+ mount.property_hash[:ensure] = :absent
- mount.stubs(:mountcmd) # just so we don't actually try to mount anything
+ mount.stubs(:mountcmd) # just so we don't actually try to mount anything
- mount.expects(:flush)
- mount.mount
+ mount.expects(:flush)
+ mount.mount
+ end
end
-end
-describe provider_class, " when modifying the filesystem tab" do
- include ParsedMountTesting
- before do
- @mount = mkmount
- @target = @provider_class.default_target
+ describe provider_class, " when modifying the filesystem tab" do
+ include ParsedMountTesting
+ before do
+ @mount = mkmount
+ @target = @provider_class.default_target
- # Never write to disk, only to RAM.
- @provider_class.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
- end
+ # Never write to disk, only to RAM.
+ @provider_class.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram))
+ end
- it "should write the mount to disk when :flush is called" do
- @mount.flush
+ it "should write the mount to disk when :flush is called" do
+ @mount.flush
- text = @provider_class.target_object(@provider_class.default_target).read
- text.should == @mount.class.to_line(@mount.property_hash) + "\n"
+ text = @provider_class.target_object(@provider_class.default_target).read
+ text.should == @mount.class.to_line(@mount.property_hash) + "\n"
+ end
end
-end
-describe provider_class, " when parsing information about the root filesystem" do
- confine "Mount type not tested on Darwin" => Facter["operatingsystem"].value != "Darwin"
- include ParsedMountTesting
+ describe provider_class, " when parsing information about the root filesystem" do
+ confine "Mount type not tested on Darwin" => Facter["operatingsystem"].value != "Darwin"
+ include ParsedMountTesting
- before do
- @mount = @mount_class.create :name => "/"
- @provider = @mount.provider
- end
+ before do
+ @mount = @mount_class.create :name => "/"
+ @provider = @mount.provider
+ end
- it "should have a filesystem tab" do
- FileTest.should be_exist(@provider_class.default_target)
- end
+ it "should have a filesystem tab" do
+ FileTest.should be_exist(@provider_class.default_target)
+ end
- it "should find the root filesystem" do
- @provider_class.prefetch("/" => @mount)
- @mount.provider.property_hash[:ensure].should == :present
- end
+ it "should find the root filesystem" do
+ @provider_class.prefetch("/" => @mount)
+ @mount.provider.property_hash[:ensure].should == :present
+ end
- it "should determine that the root fs is mounted" do
- @provider_class.prefetch("/" => @mount)
- @mount.provider.should be_mounted
+ it "should determine that the root fs is mounted" do
+ @provider_class.prefetch("/" => @mount)
+ @mount.provider.should be_mounted
+ end
end
-end
-describe provider_class, " when mounting and unmounting" do
- include ParsedMountTesting
+ describe provider_class, " when mounting and unmounting" do
+ include ParsedMountTesting
- it "should call the 'mount' command to mount the filesystem"
+ it "should call the 'mount' command to mount the filesystem"
- it "should call the 'unmount' command to unmount the filesystem"
+ it "should call the 'unmount' command to unmount the filesystem"
- it "should specify the filesystem when remounting a filesystem"
+ it "should specify the filesystem when remounting a filesystem"
+ end
end
diff --git a/spec/unit/ral/type.rb b/spec/unit/ral/type.rb
index 25f8cbaf1..5980167d6 100755
--- a/spec/unit/ral/type.rb
+++ b/spec/unit/ral/type.rb
@@ -11,8 +11,8 @@ describe Puppet::Type, " when in a configuration" do
@catalog.add_resource @container
@catalog.add_resource @one
@catalog.add_resource @two
- @catalog.add_edge! @container, @one
- @catalog.add_edge! @container, @two
+ @catalog.add_edge @container, @one
+ @catalog.add_edge @container, @two
end
it "should have no parent if there is no in edge" do
diff --git a/spec/unit/ral/types/exec.rb b/spec/unit/ral/type/exec.rb
index 260804227..260804227 100755
--- a/spec/unit/ral/types/exec.rb
+++ b/spec/unit/ral/type/exec.rb
diff --git a/spec/unit/ral/type/file.rb b/spec/unit/ral/type/file.rb
new file mode 100755
index 000000000..83546bef0
--- /dev/null
+++ b/spec/unit/ral/type/file.rb
@@ -0,0 +1,96 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Type.type(:file) do
+ before do
+ @path = Tempfile.new("puppetspec")
+ @path.close!()
+ @path = @path.path
+ @file = Puppet::Type::File.create(:name => @path)
+ end
+
+ describe "when used with content and replace=>false" do
+ before do
+ @file[:content] = "foo"
+ @file[:replace] = false
+ end
+
+ it "should be insync if the file exists and the content is different" do
+ File.open(@path, "w") do |f| f.puts "bar" end
+ @file.property(:content).insync?("bar").should be_true
+ end
+
+ it "should be insync if the file exists and the content is right" do
+ File.open(@path, "w") do |f| f.puts "foo" end
+ @file.property(:content).insync?("foo").should be_true
+ end
+
+ it "should not be insync if the file does not exist" do
+ @file.property(:content).insync?(:nil).should be_false
+ end
+ end
+
+ describe "when retrieving remote files" do
+ before do
+ @filesource = Puppet::Type::File::FileSource.new
+ @filesource.server = mock 'fileserver'
+
+ @file.stubs(:uri2obj).returns(@filesource)
+
+ @file[:source] = "puppet:///test"
+ end
+
+ it "should fail without writing if it cannot retrieve remote contents" do
+ # create the file, because we only get the problem when it starts
+ # out absent.
+ File.open(@file[:path], "w") { |f| f.puts "a" }
+ @file.expects(:write).never
+
+ @filesource.server.stubs(:describe).returns("493\tfile\t100\t0\t{md5}3f5fef3bddbc4398c46a7bd7ba7b3af7")
+ @filesource.server.stubs(:retrieve).raises(RuntimeError)
+ @file.property(:source).retrieve
+ lambda { @file.property(:source).sync }.should raise_error(Puppet::Error)
+ end
+ end
+
+ describe "when managing links" do
+ require 'puppettest/support/assertions'
+ include PuppetTest
+ require 'tempfile'
+
+ before do
+ @basedir = tempfile
+ Dir.mkdir(@basedir)
+ @file = File.join(@basedir, "file")
+ @link = File.join(@basedir, "link")
+
+ File.open(@file, "w", 0644) { |f| f.puts "yayness"; f.flush }
+ File.symlink(@file, @link)
+
+ @resource = Puppet.type(:file).create(
+ :path => @link,
+ :mode => "755"
+ )
+ @catalog = Puppet::Node::Catalog.new
+ @catalog.add_resource @resource
+ end
+
+ after do
+ remove_tmp_files
+ end
+
+ it "should default to managing the link" do
+ @catalog.apply
+ # I convert them to strings so they display correctly if there's an error.
+ ("%o" % (File.stat(@file).mode & 007777)).should == "%o" % 0644
+ end
+
+ it "should be able to follow links" do
+ @resource[:links] = :follow
+ @catalog.apply
+
+ ("%o" % (File.stat(@file).mode & 007777)).should == "%o" % 0755
+ end
+ end
+end
diff --git a/spec/unit/ral/types/interface.rb b/spec/unit/ral/type/interface.rb
index e51465a0c..e51465a0c 100755
--- a/spec/unit/ral/types/interface.rb
+++ b/spec/unit/ral/type/interface.rb
diff --git a/spec/unit/ral/type/mount.rb b/spec/unit/ral/type/mount.rb
new file mode 100755
index 000000000..b1a01749d
--- /dev/null
+++ b/spec/unit/ral/type/mount.rb
@@ -0,0 +1,184 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/type/mount'
+
+describe Puppet::Type::Mount do
+ it "should have a :refreshable feature that requires the :remount method" do
+ Puppet::Type::Mount.provider_feature(:refreshable).methods.should == [:remount]
+ end
+
+ it "should have no default value for :ensure" do
+ mount = Puppet::Type::Mount.create(:name => "yay")
+ mount.should(:ensure).should be_nil
+ end
+end
+
+describe Puppet::Type::Mount, "when validating attributes" do
+ [:name, :remounts].each do |param|
+ it "should have a #{param} parameter" do
+ Puppet::Type::Mount.attrtype(param).should == :param
+ end
+ end
+
+ [:ensure, :device, :blockdevice, :fstype, :options, :pass, :dump, :atboot, :target].each do |param|
+ it "should have a #{param} property" do
+ Puppet::Type::Mount.attrtype(param).should == :property
+ end
+ end
+end
+
+describe Puppet::Type::Mount::Ensure, "when validating values" do
+ before do
+ @provider = stub 'provider', :class => Puppet::Type::Mount.defaultprovider, :clear => nil
+ Puppet::Type::Mount.defaultprovider.expects(:new).returns(@provider)
+ end
+
+ it "should support :present as a value to :ensure" do
+ Puppet::Type::Mount.create(:name => "yay", :ensure => :present)
+ end
+
+ it "should alias :unmounted to :present as a value to :ensure" do
+ mount = Puppet::Type::Mount.create(:name => "yay", :ensure => :unmounted)
+ mount.should(:ensure).should == :present
+ end
+
+ it "should support :absent as a value to :ensure" do
+ Puppet::Type::Mount.create(:name => "yay", :ensure => :absent)
+ end
+
+ it "should support :mounted as a value to :ensure" do
+ Puppet::Type::Mount.create(:name => "yay", :ensure => :mounted)
+ end
+end
+
+describe Puppet::Type::Mount::Ensure do
+ before :each do
+ @provider = stub 'provider', :class => Puppet::Type::Mount.defaultprovider, :clear => nil, :satisfies? => true, :name => :mock
+ Puppet::Type::Mount.defaultprovider.stubs(:new).returns(@provider)
+ @mount = Puppet::Type::Mount.create(:name => "yay", :check => :ensure)
+
+ @ensure = @mount.property(:ensure)
+ end
+
+ def mount_stub(params)
+ Puppet::Type::Mount.validproperties.each do |prop|
+ unless params[prop]
+ params[prop] = :absent
+ @mount[prop] = :absent
+ end
+ end
+
+ params.each do |param, value|
+ @provider.stubs(param).returns(value)
+ end
+ end
+
+ describe Puppet::Type::Mount::Ensure, "when retrieving its current state" do
+
+ it "should return the provider's value if it is :absent" do
+ @provider.expects(:ensure).returns(:absent)
+ @ensure.retrieve.should == :absent
+ end
+
+ it "should return :mounted if the provider indicates it is mounted and the value is not :absent" do
+ @provider.expects(:ensure).returns(:present)
+ @provider.expects(:mounted?).returns(true)
+ @ensure.retrieve.should == :mounted
+ end
+
+ it "should return :present if the provider indicates it is not mounted and the value is not :absent" do
+ @provider.expects(:ensure).returns(:present)
+ @provider.expects(:mounted?).returns(false)
+ @ensure.retrieve.should == :present
+ end
+ end
+
+ describe Puppet::Type::Mount::Ensure, "when changing the host" do
+
+ it "should destroy itself if it should be absent" do
+ @provider.stubs(:mounted?).returns(false)
+ @provider.expects(:destroy)
+ @ensure.should = :absent
+ @ensure.sync
+ end
+
+ it "should unmount itself before destroying if it is mounted and should be absent" do
+ @provider.expects(:mounted?).returns(true)
+ @provider.expects(:unmount)
+ @provider.expects(:destroy)
+ @ensure.should = :absent
+ @ensure.sync
+ end
+
+ it "should create itself if it is absent and should be present" do
+ @provider.stubs(:mounted?).returns(false)
+ @provider.expects(:create)
+ @ensure.should = :present
+ @ensure.sync
+ end
+
+ it "should unmount itself if it is mounted and should be present" do
+ @provider.stubs(:mounted?).returns(true)
+
+ # The interface here is just too much work to test right now.
+ @ensure.stubs(:syncothers)
+ @provider.expects(:unmount)
+ @ensure.should = :present
+ @ensure.sync
+ end
+
+ it "should create and mount itself if it does not exist and should be mounted" do
+ @provider.stubs(:ensure).returns(:absent)
+ @provider.stubs(:mounted?).returns(false)
+ @provider.expects(:create)
+ @ensure.stubs(:syncothers)
+ @provider.expects(:mount)
+ @ensure.should = :mounted
+ @ensure.sync
+ end
+
+ it "should mount itself if it is present and should be mounted" do
+ @provider.stubs(:ensure).returns(:present)
+ @provider.stubs(:mounted?).returns(false)
+ @ensure.stubs(:syncothers)
+ @provider.expects(:mount)
+ @ensure.should = :mounted
+ @ensure.sync
+ end
+
+ it "should create but not mount itself if it is absent and mounted and should be mounted" do
+ @provider.stubs(:ensure).returns(:absent)
+ @provider.stubs(:mounted?).returns(true)
+ @ensure.stubs(:syncothers)
+ @provider.expects(:create)
+ @ensure.should = :mounted
+ @ensure.sync
+ end
+ end
+
+ describe Puppet::Type::Mount, "when responding to events" do
+
+ it "should remount if it is currently mounted" do
+ @provider.expects(:mounted?).returns(true)
+ @provider.expects(:remount)
+
+ @mount.refresh
+ end
+
+ it "should not remount if it is not currently mounted" do
+ @provider.expects(:mounted?).returns(false)
+ @provider.expects(:remount).never
+
+ @mount.refresh
+ end
+
+ it "should not remount swap filesystems" do
+ @mount[:fstype] = "swap"
+ @provider.expects(:remount).never
+
+ @mount.refresh
+ end
+ end
+end
diff --git a/spec/unit/ral/types/nagios.rb b/spec/unit/ral/type/nagios.rb
index 8aca7d401..8aca7d401 100755
--- a/spec/unit/ral/types/nagios.rb
+++ b/spec/unit/ral/type/nagios.rb
diff --git a/spec/unit/ral/type/noop_metaparam.rb b/spec/unit/ral/type/noop_metaparam.rb
new file mode 100755
index 000000000..0cbed3714
--- /dev/null
+++ b/spec/unit/ral/type/noop_metaparam.rb
@@ -0,0 +1,38 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/metatype/metaparams'
+
+describe Puppet::Type.type(:file).attrclass(:noop) do
+ before do
+ @file = Puppet::Type.newfile :path => "/what/ever"
+ end
+
+ after { Puppet::Type::File.clear }
+
+ it "should accept true as a value" do
+ lambda { @file[:noop] = true }.should_not raise_error
+ end
+
+ it "should accept false as a value" do
+ lambda { @file[:noop] = false }.should_not raise_error
+ end
+
+ describe "when set on a resource" do
+ it "should default to the :noop setting" do
+ Puppet.settings.expects(:value).with(:noop).returns "myval"
+ @file.noop.should == "myval"
+ end
+
+ it "should prefer true values from the attribute" do
+ @file[:noop] = true
+ @file.noop.should be_true
+ end
+
+ it "should prefer false values from the attribute" do
+ @file[:noop] = false
+ @file.noop.should be_false
+ end
+ end
+end
diff --git a/spec/unit/ral/types/package.rb b/spec/unit/ral/type/package.rb
index e9e3b9e4e..8cc11cc2c 100755
--- a/spec/unit/ral/types/package.rb
+++ b/spec/unit/ral/type/package.rb
@@ -92,13 +92,19 @@ describe Puppet::Type::Package, "when validating attribute values" do
proc { Puppet::Type::Package.create(:name => "yay", :ensure => "1.0") }.should raise_error(Puppet::Error)
end
- it "should only accept files and URLs as values to :source" do
- proc { Puppet::Type::Package.create(:name => "yay", :source => "stuff") }.should raise_error(Puppet::Error)
+ it "should accept any string as an argument to :source" do
+ proc { Puppet::Type::Package.create(:name => "yay", :source => "stuff") }.should_not raise_error(Puppet::Error)
end
end
module PackageEvaluationTesting
- def setup
+ def setprops(properties)
+ @provider.stubs(:properties).returns(properties)
+ end
+end
+
+describe Puppet::Type::Package do
+ before :each do
@provider = stub 'provider', :class => Puppet::Type::Package.defaultprovider, :clear => nil, :satisfies? => true, :name => :mock
Puppet::Type::Package.defaultprovider.stubs(:new).returns(@provider)
@package = Puppet::Type::Package.create(:name => "yay")
@@ -107,129 +113,125 @@ module PackageEvaluationTesting
@catalog.add_resource(@package)
end
- def setprops(properties)
- @provider.stubs(:properties).returns(properties)
- end
-end
-
-describe Puppet::Type::Package, "when it should be purged" do
- include PackageEvaluationTesting
+ describe Puppet::Type::Package, "when it should be purged" do
+ include PackageEvaluationTesting
- before { @package[:ensure] = :purged }
+ before { @package[:ensure] = :purged }
- it "should do nothing if it is :purged" do
- @provider.expects(:properties).returns(:ensure => :purged)
- @catalog.apply
- end
-
- [:absent, :installed, :present, :latest].each do |state|
- it "should purge if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
- @provider.expects(:purge)
+ it "should do nothing if it is :purged" do
+ @provider.expects(:properties).returns(:ensure => :purged)
@catalog.apply
end
+
+ [:absent, :installed, :present, :latest].each do |state|
+ it "should purge if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:purge)
+ @catalog.apply
+ end
+ end
end
-end
-describe Puppet::Type::Package, "when it should be absent" do
- include PackageEvaluationTesting
+ describe Puppet::Type::Package, "when it should be absent" do
+ include PackageEvaluationTesting
- before { @package[:ensure] = :absent }
+ before { @package[:ensure] = :absent }
- [:purged, :absent].each do |state|
- it "should do nothing if it is #{state.to_s}" do
- @provider.expects(:properties).returns(:ensure => state)
- @catalog.apply
+ [:purged, :absent].each do |state|
+ it "should do nothing if it is #{state.to_s}" do
+ @provider.expects(:properties).returns(:ensure => state)
+ @catalog.apply
+ end
end
- end
- [:installed, :present, :latest].each do |state|
- it "should uninstall if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
- @provider.expects(:uninstall)
- @catalog.apply
+ [:installed, :present, :latest].each do |state|
+ it "should uninstall if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:uninstall)
+ @catalog.apply
+ end
end
end
-end
-describe Puppet::Type::Package, "when it should be present" do
- include PackageEvaluationTesting
+ describe Puppet::Type::Package, "when it should be present" do
+ include PackageEvaluationTesting
- before { @package[:ensure] = :present }
+ before { @package[:ensure] = :present }
- [:present, :latest, "1.0"].each do |state|
- it "should do nothing if it is #{state.to_s}" do
- @provider.expects(:properties).returns(:ensure => state)
- @catalog.apply
+ [:present, :latest, "1.0"].each do |state|
+ it "should do nothing if it is #{state.to_s}" do
+ @provider.expects(:properties).returns(:ensure => state)
+ @catalog.apply
+ end
end
- end
- [:purged, :absent].each do |state|
- it "should install if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
- @provider.expects(:install)
- @catalog.apply
+ [:purged, :absent].each do |state|
+ it "should install if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:install)
+ @catalog.apply
+ end
end
end
-end
-describe Puppet::Type::Package, "when it should be latest" do
- include PackageEvaluationTesting
+ describe Puppet::Type::Package, "when it should be latest" do
+ include PackageEvaluationTesting
- before { @package[:ensure] = :latest }
+ before { @package[:ensure] = :latest }
- [:purged, :absent].each do |state|
- it "should upgrade if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
+ [:purged, :absent].each do |state|
+ it "should upgrade if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:update)
+ @catalog.apply
+ end
+ end
+
+ it "should upgrade if the current version is not equal to the latest version" do
+ @provider.stubs(:properties).returns(:ensure => "1.0")
+ @provider.stubs(:latest).returns("2.0")
@provider.expects(:update)
@catalog.apply
end
- end
- it "should upgrade if the current version is not equal to the latest version" do
- @provider.stubs(:properties).returns(:ensure => "1.0")
- @provider.stubs(:latest).returns("2.0")
- @provider.expects(:update)
- @catalog.apply
- end
+ it "should do nothing if it is equal to the latest version" do
+ @provider.stubs(:properties).returns(:ensure => "1.0")
+ @provider.stubs(:latest).returns("1.0")
+ @provider.expects(:update).never
+ @catalog.apply
+ end
- it "should do nothing if it is equal to the latest version" do
- @provider.stubs(:properties).returns(:ensure => "1.0")
- @provider.stubs(:latest).returns("1.0")
- @provider.expects(:update).never
- @catalog.apply
+ it "should do nothing if the provider returns :present as the latest version" do
+ @provider.stubs(:properties).returns(:ensure => :present)
+ @provider.stubs(:latest).returns("1.0")
+ @provider.expects(:update).never
+ @catalog.apply
+ end
end
- it "should do nothing if the provider returns :present as the latest version" do
- @provider.stubs(:properties).returns(:ensure => :present)
- @provider.stubs(:latest).returns("1.0")
- @provider.expects(:update).never
- @catalog.apply
- end
-end
+ describe Puppet::Type::Package, "when it should be a specific version" do
+ include PackageEvaluationTesting
-describe Puppet::Type::Package, "when it should be a specific version" do
- include PackageEvaluationTesting
+ before { @package[:ensure] = "1.0" }
- before { @package[:ensure] = "1.0" }
+ [:purged, :absent].each do |state|
+ it "should install if it is #{state.to_s}" do
+ @provider.stubs(:properties).returns(:ensure => state)
+ @provider.expects(:install)
+ @catalog.apply
+ end
+ end
- [:purged, :absent].each do |state|
- it "should install if it is #{state.to_s}" do
- @provider.stubs(:properties).returns(:ensure => state)
- @provider.expects(:install)
+ it "should do nothing if the current version is equal to the desired version" do
+ @provider.stubs(:properties).returns(:ensure => "1.0")
+ @provider.expects(:install).never
@catalog.apply
end
- end
- it "should do nothing if the current version is equal to the desired version" do
- @provider.stubs(:properties).returns(:ensure => "1.0")
- @provider.expects(:install).never
- @catalog.apply
- end
-
- it "should install if the current version is not equal to the specified version" do
- @provider.stubs(:properties).returns(:ensure => "2.0")
- @provider.expects(:install)
- @catalog.apply
+ it "should install if the current version is not equal to the specified version" do
+ @provider.stubs(:properties).returns(:ensure => "2.0")
+ @provider.expects(:install)
+ @catalog.apply
+ end
end
end
diff --git a/spec/unit/ral/type/schedule.rb b/spec/unit/ral/type/schedule.rb
new file mode 100755
index 000000000..e53138c5e
--- /dev/null
+++ b/spec/unit/ral/type/schedule.rb
@@ -0,0 +1,335 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/type/schedule'
+
+module ScheduleTesting
+
+ def format(time)
+ time.strftime("%H:%M:%S")
+ end
+
+ def diff(unit, incr, method, count)
+ diff = Time.now.to_i.send(method, incr * count)
+ Time.at(diff)
+ end
+
+ def month(method, count)
+ diff(:hour, 3600 * 24 * 30, method, count)
+ end
+
+ def week(method, count)
+ diff(:hour, 3600 * 24 * 7, method, count)
+ end
+
+ def day(method, count)
+ diff(:hour, 3600 * 24, method, count)
+ end
+
+ def hour(method, count)
+ diff(:hour, 3600, method, count)
+ end
+
+ def min(method, count)
+ diff(:min, 60, method, count)
+ end
+
+ def sec(method, count)
+ diff(:sec, 1, method, count)
+ end
+
+end
+
+describe Puppet::Type::Schedule do
+ before :each do
+ Puppet.settings.stubs(:value).with(:ignoreschedules).returns(false)
+
+ @schedule = Puppet::Type::Schedule.create(:name => "testing")
+ end
+
+ describe Puppet::Type::Schedule do
+ include ScheduleTesting
+
+ it "should default to :distance for period-matching" do
+ @schedule[:periodmatch].should == :distance
+ end
+
+ it "should default to a :repeat of 1" do
+ @schedule[:repeat].should == 1
+ end
+
+ it "should never match when the period is :never" do
+ @schedule[:period] = :never
+ @schedule.match?.should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when producing default schedules" do
+ include ScheduleTesting
+
+ %w{hourly daily weekly monthly never}.each do |period|
+ period = period.to_sym
+ it "should produce a #{period} schedule with the period set appropriately" do
+ schedules = Puppet::Type::Schedule.mkdefaultschedules
+ schedules.find { |s| s[:name] == period.to_s and s[:period] == period }.should be_instance_of(Puppet::Type::Schedule)
+ end
+ end
+
+ it "should produce a schedule named puppet with a period of hourly and a repeat of 2" do
+ schedules = Puppet::Type::Schedule.mkdefaultschedules
+ schedules.find { |s|
+ s[:name] == "puppet" and s[:period] == :hourly and s[:repeat] == 2
+ }.should be_instance_of(Puppet::Type::Schedule)
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching ranges" do
+ include ScheduleTesting
+
+ it "should match when the start time is before the current time and the end time is after the current time" do
+ @schedule[:range] = "%s - %s" % [format(Time.now - 10), format(Time.now + 10)]
+ @schedule.match?.should be_true
+ end
+
+ it "should not match when the start time is after the current time" do
+ @schedule[:range] = "%s - %s" % [format(Time.now + 5), format(Time.now + 10)]
+ @schedule.match?.should be_false
+ end
+
+ it "should not match when the end time is previous to the current time" do
+ @schedule[:range] = "%s - %s" % [format(Time.now - 10), format(Time.now - 5)]
+ @schedule.match?.should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching hourly by distance" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :hourly
+ @schedule[:periodmatch] = :distance
+ end
+
+ it "should match an hour ago" do
+ @schedule.match?(hour("-", 1)).should be_true
+ end
+
+ it "should not match now" do
+ @schedule.match?(Time.now).should be_false
+ end
+
+ it "should not match 59 minutes ago" do
+ @schedule.match?(min("-", 59)).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching daily by distance" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :daily
+ @schedule[:periodmatch] = :distance
+ end
+
+ it "should match when the previous time was one day ago" do
+ @schedule.match?(day("-", 1)).should be_true
+ end
+
+ it "should not match when the previous time is now" do
+ @schedule.match?(Time.now).should be_false
+ end
+
+ it "should not match when the previous time was 23 hours ago" do
+ @schedule.match?(hour("-", 23)).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching weekly by distance" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :weekly
+ @schedule[:periodmatch] = :distance
+ end
+
+ it "should match seven days ago" do
+ @schedule.match?(day("-", 7)).should be_true
+ end
+
+ it "should not match now" do
+ @schedule.match?(Time.now).should be_false
+ end
+
+ it "should not match six days ago" do
+ @schedule.match?(day("-", 6)).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching monthly by distance" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :monthly
+ @schedule[:periodmatch] = :distance
+ end
+
+ it "should match 32 days ago" do
+ @schedule.match?(day("-", 32)).should be_true
+ end
+
+ it "should not match now" do
+ @schedule.match?(Time.now).should be_false
+ end
+
+ it "should not match 27 days ago" do
+ @schedule.match?(day("-", 27)).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching hourly by number" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :hourly
+ @schedule[:periodmatch] = :number
+ end
+
+ it "should match if the times are one minute apart and the current minute is 0" do
+ current = Time.now
+
+ # Subtract an hour, reset the minute to zero, then add 59 minutes, so we're the previous hour plus 59 minutes.
+ previous = (current - 3600 - (current.min * 60) + (59 * 60))
+
+ # Now set the "current" time to the zero minute of the current hour.
+ now = (current - (current.min * 60))
+ Time.stubs(:now).returns(now)
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match if the times are 58 minutes apart and the current minute is 59" do
+ current = Time.now
+
+ # reset the minute to zero
+ previous = current - (current.min * 60)
+
+ # Now set the "current" time to the 59th minute of the current hour.
+ now = (current - (current.min * 60) + (59 * 60))
+ Time.stubs(:now).returns(now)
+ @schedule.match?(previous).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching daily by number" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :daily
+ @schedule[:periodmatch] = :number
+ end
+
+ it "should match if the times are one minute apart and the current minute and hour are 0" do
+ zero = Time.now
+
+ # Reset the current time to X:00:00
+ current = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
+
+ # Now set the previous time to one minute before that
+ previous = current - 60
+
+ Time.stubs(:now).returns(current)
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match if the times are 23 hours and 58 minutes apart and the current hour is 23 and the current minute is 59" do
+ zero = Time.now
+
+ # Reset the previous time to 00:00:00
+ previous = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
+
+ # Set the current time to 23:59
+ now = previous + (23 * 3600) + (59 * 60)
+
+ Time.stubs(:now).returns(now)
+ @schedule.match?(previous).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching weekly by number" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :weekly
+ @schedule[:periodmatch] = :number
+ end
+
+ it "should match if the previous time is prior to the most recent Sunday" do
+ now = Time.now
+
+ # Subtract the number days we've progressed into the week, plus one because we're zero-indexed.
+ previous = now - (3600 * 24 * (now.wday + 1))
+
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match if the previous time is after the most recent Saturday" do
+ now = Time.now
+
+ # Subtract the number days we've progressed into the week
+ previous = now - (3600 * 24 * now.wday)
+
+ @schedule.match?(previous).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching monthly by number" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :monthly
+ @schedule[:periodmatch] = :number
+ end
+
+ it "should match when the previous time is prior to the first day of this month" do
+ now = Time.now
+
+ # Subtract the number days we've progressed into the month
+ previous = now - (3600 * 24 * now.day)
+
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match when the previous time is after the last day of last month" do
+ now = Time.now
+
+ # Subtract the number days we've progressed into the month, minus one
+ previous = now - (3600 * 24 * (now.day - 1))
+
+ @schedule.match?(previous).should be_false
+ end
+ end
+
+ describe Puppet::Type::Schedule, "when matching with a repeat greater than one" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :daily
+ @schedule[:repeat] = 2
+ end
+
+ it "should fail if the periodmatch is 'number'" do
+ @schedule[:periodmatch] = :number
+ proc { @schedule[:repeat] = 2 }.should raise_error(Puppet::Error)
+ end
+
+ it "should match if the previous run was further away than the distance divided by the repeat" do
+ previous = Time.now - (3600 * 13)
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match if the previous run was closer than the distance divided by the repeat" do
+ previous = Time.now - (3600 * 11)
+ @schedule.match?(previous).should be_false
+ end
+ end
+end
diff --git a/spec/unit/ral/types/service.rb b/spec/unit/ral/type/service.rb
index 3944f146c..17cb2105d 100755
--- a/spec/unit/ral/types/service.rb
+++ b/spec/unit/ral/type/service.rb
@@ -15,7 +15,7 @@ describe Puppet::Type::Service do
end
describe Puppet::Type::Service, "when validating attributes" do
- [:name, :binary, :hasstatus, :path, :pattern, :start, :restart, :stop, :status, :hasrestart].each do |param|
+ [:name, :binary, :hasstatus, :path, :pattern, :start, :restart, :stop, :status, :hasrestart, :control].each do |param|
it "should have a #{param} parameter" do
Puppet::Type::Service.attrtype(param).should == :param
end
@@ -30,7 +30,7 @@ end
describe Puppet::Type::Service, "when validating attribute values" do
before do
- @provider = stub 'provider', :class => Puppet::Type::Service.defaultprovider, :clear => nil
+ @provider = stub 'provider', :class => Puppet::Type::Service.defaultprovider, :clear => nil, :controllable? => false
Puppet::Type::Service.defaultprovider.stubs(:new).returns(@provider)
end
@@ -130,15 +130,22 @@ describe Puppet::Type::Service, "when setting default attribute values" do
svc[:path].should == ["testing"]
end
- it "should default to the binary for the pattern if one is provided" do
+ it "should default 'pattern' to the binary if one is provided" do
svc = Puppet::Type::Service.create(:name => "other", :binary => "/some/binary")
svc[:pattern].should == "/some/binary"
end
- it "should default to the name for the pattern if no pattern is provided" do
+ it "should default 'pattern' to the name if no pattern is provided" do
svc = Puppet::Type::Service.create(:name => "other")
svc[:pattern].should == "other"
end
+
+ it "should default 'control' to the upcased service name with periods replaced by underscores if the provider supports the 'controllable' feature" do
+ provider = stub 'provider', :controllable? => true, :class => Puppet::Type::Service.defaultprovider, :clear => nil
+ Puppet::Type::Service.defaultprovider.stubs(:new).returns(provider)
+ svc = Puppet::Type::Service.create(:name => "nfs.client")
+ svc[:control].should == "NFS_CLIENT_START"
+ end
end
describe Puppet::Type::Service, "when retrieving the host's current state" do
diff --git a/spec/unit/ral/types/user.rb b/spec/unit/ral/type/user.rb
index 4e43a8ceb..4e43a8ceb 100755
--- a/spec/unit/ral/types/user.rb
+++ b/spec/unit/ral/type/user.rb
diff --git a/spec/unit/ral/types/file.rb b/spec/unit/ral/types/file.rb
deleted file mode 100755
index 5ade79012..000000000
--- a/spec/unit/ral/types/file.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-
-require 'puppet/type/pfile'
-
-describe Puppet::Type::File, " when used with replace=>false and content" do
- before do
- @path = Tempfile.new("puppetspec")
- @path.close!()
- @path = @path.path
- @file = Puppet::Type::File.create( { :name => @path, :content => "foo", :replace => :false } )
- end
-
- it "should be insync if the file exists and the content is different" do
- File.open(@path, "w") do |f| f.puts "bar" end
- @file.property(:content).insync?("bar").should be_true
- end
-
- it "should be insync if the file exists and the content is right" do
- File.open(@path, "w") do |f| f.puts "foo" end
- @file.property(:content).insync?("foo").should be_true
- end
-
- it "should not be insync if the file doesnot exist" do
- @file.property(:content).insync?(:nil).should be_false
- end
-end
diff --git a/spec/unit/ral/types/mount.rb b/spec/unit/ral/types/mount.rb
deleted file mode 100755
index 5965908cb..000000000
--- a/spec/unit/ral/types/mount.rb
+++ /dev/null
@@ -1,187 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-
-require 'puppet/type/mount'
-
-describe Puppet::Type::Mount do
- it "should have a :refreshable feature that requires the :remount method" do
- Puppet::Type::Mount.provider_feature(:refreshable).methods.should == [:remount]
- end
-
- it "should have no default value for :ensure" do
- mount = Puppet::Type::Mount.create(:name => "yay")
- mount.should(:ensure).should be_nil
- end
-end
-
-describe Puppet::Type::Mount, "when validating attributes" do
- [:name, :remounts].each do |param|
- it "should have a #{param} parameter" do
- Puppet::Type::Mount.attrtype(param).should == :param
- end
- end
-
- [:ensure, :device, :blockdevice, :fstype, :options, :pass, :dump, :atboot, :target].each do |param|
- it "should have a #{param} property" do
- Puppet::Type::Mount.attrtype(param).should == :property
- end
- end
-end
-
-describe Puppet::Type::Mount::Ensure, "when validating values" do
- before do
- @provider = stub 'provider', :class => Puppet::Type::Mount.defaultprovider, :clear => nil
- Puppet::Type::Mount.defaultprovider.expects(:new).returns(@provider)
- end
-
- it "should support :present as a value to :ensure" do
- Puppet::Type::Mount.create(:name => "yay", :ensure => :present)
- end
-
- it "should alias :unmounted to :present as a value to :ensure" do
- mount = Puppet::Type::Mount.create(:name => "yay", :ensure => :unmounted)
- mount.should(:ensure).should == :present
- end
-
- it "should support :absent as a value to :ensure" do
- Puppet::Type::Mount.create(:name => "yay", :ensure => :absent)
- end
-
- it "should support :mounted as a value to :ensure" do
- Puppet::Type::Mount.create(:name => "yay", :ensure => :mounted)
- end
-end
-
-module MountEvaluationTesting
- def setup
- @provider = stub 'provider', :class => Puppet::Type::Mount.defaultprovider, :clear => nil, :satisfies? => true, :name => :mock
- Puppet::Type::Mount.defaultprovider.stubs(:new).returns(@provider)
- @mount = Puppet::Type::Mount.create(:name => "yay", :check => :ensure)
-
- @ensure = @mount.property(:ensure)
- end
-
- def mount_stub(params)
- Puppet::Type::Mount.validproperties.each do |prop|
- unless params[prop]
- params[prop] = :absent
- @mount[prop] = :absent
- end
- end
-
- params.each do |param, value|
- @provider.stubs(param).returns(value)
- end
- end
-end
-
-describe Puppet::Type::Mount::Ensure, "when retrieving its current state" do
- include MountEvaluationTesting
-
- it "should return the provider's value if it is :absent" do
- @provider.expects(:ensure).returns(:absent)
- @ensure.retrieve.should == :absent
- end
-
- it "should return :mounted if the provider indicates it is mounted and the value is not :absent" do
- @provider.expects(:ensure).returns(:present)
- @provider.expects(:mounted?).returns(true)
- @ensure.retrieve.should == :mounted
- end
-
- it "should return :present if the provider indicates it is not mounted and the value is not :absent" do
- @provider.expects(:ensure).returns(:present)
- @provider.expects(:mounted?).returns(false)
- @ensure.retrieve.should == :present
- end
-end
-
-describe Puppet::Type::Mount::Ensure, "when changing the host" do
- include MountEvaluationTesting
-
- it "should destroy itself if it should be absent" do
- @provider.stubs(:mounted?).returns(false)
- @provider.expects(:destroy)
- @ensure.should = :absent
- @ensure.sync
- end
-
- it "should unmount itself before destroying if it is mounted and should be absent" do
- @provider.expects(:mounted?).returns(true)
- @provider.expects(:unmount)
- @provider.expects(:destroy)
- @ensure.should = :absent
- @ensure.sync
- end
-
- it "should create itself if it is absent and should be present" do
- @provider.stubs(:mounted?).returns(false)
- @provider.expects(:create)
- @ensure.should = :present
- @ensure.sync
- end
-
- it "should unmount itself if it is mounted and should be present" do
- @provider.stubs(:mounted?).returns(true)
-
- # The interface here is just too much work to test right now.
- @ensure.stubs(:syncothers)
- @provider.expects(:unmount)
- @ensure.should = :present
- @ensure.sync
- end
-
- it "should create and mount itself if it does not exist and should be mounted" do
- @provider.stubs(:ensure).returns(:absent)
- @provider.stubs(:mounted?).returns(false)
- @provider.expects(:create)
- @ensure.stubs(:syncothers)
- @provider.expects(:mount)
- @ensure.should = :mounted
- @ensure.sync
- end
-
- it "should mount itself if it is present and should be mounted" do
- @provider.stubs(:ensure).returns(:present)
- @provider.stubs(:mounted?).returns(false)
- @ensure.stubs(:syncothers)
- @provider.expects(:mount)
- @ensure.should = :mounted
- @ensure.sync
- end
-
- it "should create but not mount itself if it is absent and mounted and should be mounted" do
- @provider.stubs(:ensure).returns(:absent)
- @provider.stubs(:mounted?).returns(true)
- @ensure.stubs(:syncothers)
- @provider.expects(:create)
- @ensure.should = :mounted
- @ensure.sync
- end
-end
-
-describe Puppet::Type::Mount, "when responding to events" do
- include MountEvaluationTesting
-
- it "should remount if it is currently mounted" do
- @provider.expects(:mounted?).returns(true)
- @provider.expects(:remount)
-
- @mount.refresh
- end
-
- it "should not remount if it is not currently mounted" do
- @provider.expects(:mounted?).returns(false)
- @provider.expects(:remount).never
-
- @mount.refresh
- end
-
- it "should not remount swap filesystems" do
- @mount[:fstype] = "swap"
- @provider.expects(:remount).never
-
- @mount.refresh
- end
-end
diff --git a/spec/unit/ral/types/schedule.rb b/spec/unit/ral/types/schedule.rb
deleted file mode 100755
index 856a73186..000000000
--- a/spec/unit/ral/types/schedule.rb
+++ /dev/null
@@ -1,370 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-
-require 'puppet/type/schedule'
-
-module ScheduleTesting
- def setup
- Puppet.settings.stubs(:value).with(:ignoreschedules).returns(false)
-
- @schedule = Puppet::Type::Schedule.create(:name => "testing")
- end
-
- def format(time)
- time.strftime("%H:%M:%S")
- end
-
- def diff(unit, incr, method, count)
- diff = Time.now.to_i.send(method, incr * count)
- Time.at(diff)
- end
-
- def month(method, count)
- diff(:hour, 3600 * 24 * 30, method, count)
- end
-
- def week(method, count)
- diff(:hour, 3600 * 24 * 7, method, count)
- end
-
- def day(method, count)
- diff(:hour, 3600 * 24, method, count)
- end
-
- def hour(method, count)
- diff(:hour, 3600, method, count)
- end
-
- def min(method, count)
- diff(:min, 60, method, count)
- end
-
- def sec(method, count)
- diff(:sec, 1, method, count)
- end
-end
-
-describe Puppet::Type::Schedule do
- include ScheduleTesting
-
- it "should default to :distance for period-matching" do
- @schedule[:periodmatch].should == :distance
- end
-
- it "should default to a :repeat of 1" do
- @schedule[:repeat].should == 1
- end
-
- it "should never match when the period is :never" do
- @schedule[:period] = :never
- @schedule.match?.should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when producing default schedules" do
- include ScheduleTesting
-
- %w{hourly daily weekly monthly never}.each do |period|
- period = period.to_sym
- it "should produce a #{period} schedule with the period set appropriately" do
- schedules = Puppet::Type::Schedule.mkdefaultschedules
- schedules.find { |s| s[:name] == period.to_s and s[:period] == period }.should be_instance_of(Puppet::Type::Schedule)
- end
- end
-
- it "should produce a schedule named puppet with a period of hourly and a repeat of 2" do
- schedules = Puppet::Type::Schedule.mkdefaultschedules
- schedules.find { |s|
- s[:name] == "puppet" and s[:period] == :hourly and s[:repeat] == 2
- }.should be_instance_of(Puppet::Type::Schedule)
- end
-end
-
-describe Puppet::Type::Schedule, "when matching ranges" do
- include ScheduleTesting
-
- it "should match when the start time is before the current time and the end time is after the current time" do
- @schedule[:range] = "%s - %s" % [format(Time.now - 10), format(Time.now + 10)]
- @schedule.match?.should be_true
- end
-
- it "should not match when the start time is after the current time" do
- @schedule[:range] = "%s - %s" % [format(Time.now + 5), format(Time.now + 10)]
- @schedule.match?.should be_false
- end
-
- it "should not match when the end time is previous to the current time" do
- @schedule[:range] = "%s - %s" % [format(Time.now - 10), format(Time.now - 5)]
- @schedule.match?.should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching hourly by distance" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :hourly
- @schedule[:periodmatch] = :distance
- end
-
- it "should match an hour ago" do
- @schedule.match?(hour("-", 1)).should be_true
- end
-
- it "should not match now" do
- @schedule.match?(Time.now).should be_false
- end
-
- it "should not match 59 minutes ago" do
- @schedule.match?(min("-", 59)).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching daily by distance" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :daily
- @schedule[:periodmatch] = :distance
- end
-
- it "should match when the previous time was one day ago" do
- @schedule.match?(day("-", 1)).should be_true
- end
-
- it "should not match when the previous time is now" do
- @schedule.match?(Time.now).should be_false
- end
-
- it "should not match when the previous time was 23 hours ago" do
- @schedule.match?(hour("-", 23)).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching weekly by distance" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :weekly
- @schedule[:periodmatch] = :distance
- end
-
- it "should match seven days ago" do
- @schedule.match?(day("-", 7)).should be_true
- end
-
- it "should not match now" do
- @schedule.match?(Time.now).should be_false
- end
-
- it "should not match six days ago" do
- @schedule.match?(day("-", 6)).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching monthly by distance" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :monthly
- @schedule[:periodmatch] = :distance
- end
-
- it "should match 32 days ago" do
- @schedule.match?(day("-", 32)).should be_true
- end
-
- it "should not match now" do
- @schedule.match?(Time.now).should be_false
- end
-
- it "should not match 27 days ago" do
- @schedule.match?(day("-", 27)).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching hourly by number" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :hourly
- @schedule[:periodmatch] = :number
- end
-
- it "should match if the times are one minute apart and the current minute is 0" do
- current = Time.now
-
- # Subtract an hour, reset the minute to zero, then add 59 minutes, so we're the previous hour plus 59 minutes.
- previous = (current - 3600 - (current.min * 60) + (59 * 60))
-
- # Now set the "current" time to the zero minute of the current hour.
- now = (current - (current.min * 60))
- Time.stubs(:now).returns(now)
- @schedule.match?(previous).should be_true
- end
-
- it "should not match if the times are 58 minutes apart and the current minute is 59" do
- current = Time.now
-
- # reset the minute to zero
- previous = current - (current.min * 60)
-
- # Now set the "current" time to the 59th minute of the current hour.
- now = (current - (current.min * 60) + (59 * 60))
- Time.stubs(:now).returns(now)
- @schedule.match?(previous).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching daily by number" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :daily
- @schedule[:periodmatch] = :number
- end
-
- it "should match if the times are one minute apart and the current minute and hour are 0" do
- zero = Time.now
-
- # Reset the current time to X:00:00
- current = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
-
- # Now set the previous time to one minute before that
- previous = current - 60
-
- Time.stubs(:now).returns(current)
- @schedule.match?(previous).should be_true
- end
-
- it "should not match if the times are 23 hours and 58 minutes apart and the current hour is 23 and the current minute is 59" do
- zero = Time.now
-
- # Reset the previous time to 00:00:00
- previous = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
-
- # Set the current time to 23:59
- now = previous + (23 * 3600) + (59 * 60)
-
- Time.stubs(:now).returns(now)
- @schedule.match?(previous).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching weekly by number" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :weekly
- @schedule[:periodmatch] = :number
- end
-
- it "should match if the previous time is prior to the most recent Sunday" do
- now = Time.now
-
- # Subtract the number days we've progressed into the week, plus one because we're zero-indexed.
- previous = now - (3600 * 24 * (now.wday + 1))
-
- @schedule.match?(previous).should be_true
- end
-
- it "should not match if the previous time is after the most recent Saturday" do
- now = Time.now
-
- # Subtract the number days we've progressed into the week
- previous = now - (3600 * 24 * now.wday)
-
- @schedule.match?(previous).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching monthly by number" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :monthly
- @schedule[:periodmatch] = :number
- end
-
- it "should match when the previous time is prior to the first day of this month" do
- now = Time.now
-
- # Subtract the number days we've progressed into the month
- previous = now - (3600 * 24 * now.day)
-
- @schedule.match?(previous).should be_true
- end
-
- it "should not match when the previous time is after the last day of last month" do
- now = Time.now
-
- # Subtract the number days we've progressed into the month, minus one
- previous = now - (3600 * 24 * (now.day - 1))
-
- @schedule.match?(previous).should be_false
- end
-end
-
-describe Puppet::Type::Schedule, "when matching with a repeat greater than one" do
- include ScheduleTesting
-
- before do
- @schedule[:period] = :daily
- @schedule[:repeat] = 2
- end
-
- it "should fail if the periodmatch is 'number'" do
- @schedule[:periodmatch] = :number
- proc { @schedule[:repeat] = 2 }.should raise_error(Puppet::Error)
- end
-
- it "should match if the previous run was further away than the distance divided by the repeat" do
- previous = Time.now - (3600 * 13)
- @schedule.match?(previous).should be_true
- end
-
- it "should not match if the previous run was closer than the distance divided by the repeat" do
- previous = Time.now - (3600 * 11)
- @schedule.match?(previous).should be_false
- end
-end
-
-module OldTesting
- def mksched
- @stype.create(:name => "testsched")
- end
-
- def test_period_with_repeat
- previous = @now
-
- s = mksched
- s[:period] = :hourly
-
- assert_nothing_raised("Was not able to set periodmatch") {
- s[:periodmatch] = :number
- }
- assert_raise(Puppet::Error) {
- s[:repeat] = 2
- }
- assert_nothing_raised("Was not able to reset periodmatch") {
- s[:periodmatch] = :distance
- }
-
- assert(! s.match?(min("-", 40)), "matched minus 40 minutes")
-
- assert_nothing_raised("Was not able to set period") {
- s[:repeat] = 2
- }
-
- assert(! s.match?(min("-", 20)), "matched minus 20 minutes with half-hourly")
- assert(s.match?(min("-", 40)), "Did not match minus 40 with half-hourly")
-
- assert_nothing_raised("Was not able to set period") {
- s[:repeat] = 3
- }
-
- assert(! s.match?(min("-", 15)), "matched minus 15 minutes with half-hourly")
- assert(s.match?(min("-", 25)), "Did not match minus 25 with half-hourly")
- end
-end
diff --git a/spec/unit/resource_reference.rb b/spec/unit/resource_reference.rb
index e629d0b82..ee71a5077 100755
--- a/spec/unit/resource_reference.rb
+++ b/spec/unit/resource_reference.rb
@@ -40,6 +40,12 @@ describe Puppet::ResourceReference do
ref.type.should == "Foo::Bar"
ref.title.should == "yay"
end
+
+ it "should interpret the title as a reference and assign appropriately if the type is nil and the title contains nested square brackets" do
+ ref = Puppet::ResourceReference.new(nil, "foo::bar[baz[yay]]")
+ ref.type.should == "Foo::Bar"
+ ref.title.should =="baz[yay]"
+ end
end
describe Puppet::ResourceReference, "when resolving resources with a catalog" do
diff --git a/spec/unit/simple_graph.rb b/spec/unit/simple_graph.rb
index 061a07458..e1e42e40f 100755
--- a/spec/unit/simple_graph.rb
+++ b/spec/unit/simple_graph.rb
@@ -9,8 +9,8 @@ require 'puppet/simple_graph'
describe Puppet::SimpleGraph do
it "should return the number of its vertices as its length" do
@graph = Puppet::SimpleGraph.new
- @graph.add_vertex!("one")
- @graph.add_vertex!("two")
+ @graph.add_vertex("one")
+ @graph.add_vertex("two")
@graph.size.should == 2
end
@@ -20,13 +20,13 @@ describe Puppet::SimpleGraph do
it "should provide a method for reversing the graph" do
@graph = Puppet::SimpleGraph.new
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
@graph.reversal.edge?(:two, :one).should be_true
end
it "should be able to produce a dot graph" do
@graph = Puppet::SimpleGraph.new
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
proc { @graph.to_dot_graph }.should_not raise_error
end
@@ -38,17 +38,17 @@ describe Puppet::SimpleGraph, " when managing vertices" do
end
it "should provide a method to add a vertex" do
- @graph.add_vertex!(:test)
+ @graph.add_vertex(:test)
@graph.vertex?(:test).should be_true
end
it "should ignore already-present vertices when asked to add a vertex" do
- @graph.add_vertex!(:test)
- proc { @graph.add_vertex!(:test) }.should_not raise_error
+ @graph.add_vertex(:test)
+ proc { @graph.add_vertex(:test) }.should_not raise_error
end
it "should return true when asked if a vertex is present" do
- @graph.add_vertex!(:test)
+ @graph.add_vertex(:test)
@graph.vertex?(:test).should be_true
end
@@ -57,15 +57,15 @@ describe Puppet::SimpleGraph, " when managing vertices" do
end
it "should return all set vertices when asked" do
- @graph.add_vertex!(:one)
- @graph.add_vertex!(:two)
+ @graph.add_vertex(:one)
+ @graph.add_vertex(:two)
@graph.vertices.length.should == 2
@graph.vertices.should include(:one)
@graph.vertices.should include(:two)
end
it "should remove a given vertex when asked" do
- @graph.add_vertex!(:one)
+ @graph.add_vertex(:one)
@graph.remove_vertex!(:one)
@graph.vertex?(:one).should be_false
end
@@ -86,49 +86,49 @@ describe Puppet::SimpleGraph, " when managing edges" do
it "should provide a method to add an edge as an instance of the edge class" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.edge?(:one, :two).should be_true
end
it "should provide a method to add an edge by specifying the two vertices" do
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
@graph.edge?(:one, :two).should be_true
end
it "should provide a method to add an edge by specifying the two vertices and a label" do
- @graph.add_edge!(:one, :two, :stuff => :awesome)
+ @graph.add_edge(:one, :two, :stuff => :awesome)
@graph.edge?(:one, :two).should be_true
end
it "should provide a method for retrieving an edge label" do
edge = Puppet::Relationship.new(:one, :two, :stuff => :awesome)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.edge_label(:one, :two).should == {:stuff => :awesome}
end
it "should provide a method for retrieving an edge" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.edge(:one, :two).should equal(edge)
end
it "should add the edge source as a vertex if it is not already" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.vertex?(:one).should be_true
end
it "should add the edge target as a vertex if it is not already" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.vertex?(:two).should be_true
end
it "should return all edges as edge instances when asked" do
one = Puppet::Relationship.new(:one, :two)
two = Puppet::Relationship.new(:two, :three)
- @graph.add_edge!(one)
- @graph.add_edge!(two)
+ @graph.add_edge(one)
+ @graph.add_edge(two)
edges = @graph.edges
edges.length.should == 2
edges.should include(one)
@@ -137,7 +137,7 @@ describe Puppet::SimpleGraph, " when managing edges" do
it "should remove an edge when asked" do
edge = Puppet::Relationship.new(:one, :two)
- @graph.add_edge!(edge)
+ @graph.add_edge(edge)
@graph.remove_edge!(edge)
@graph.edge?(edge.source, edge.target).should be_false
end
@@ -145,8 +145,8 @@ describe Puppet::SimpleGraph, " when managing edges" do
it "should remove all related edges when a vertex is removed" do
one = Puppet::Relationship.new(:one, :two)
two = Puppet::Relationship.new(:two, :three)
- @graph.add_edge!(one)
- @graph.add_edge!(two)
+ @graph.add_edge(one)
+ @graph.add_edge(two)
@graph.remove_vertex!(:two)
@graph.edge?(:one, :two).should be_false
@graph.edge?(:two, :three).should be_false
@@ -160,9 +160,9 @@ describe Puppet::SimpleGraph, " when finding adjacent vertices" do
@one_two = Puppet::Relationship.new(:one, :two)
@two_three = Puppet::Relationship.new(:two, :three)
@one_three = Puppet::Relationship.new(:one, :three)
- @graph.add_edge!(@one_two)
- @graph.add_edge!(@one_three)
- @graph.add_edge!(@two_three)
+ @graph.add_edge(@one_two)
+ @graph.add_edge(@one_three)
+ @graph.add_edge(@two_three)
end
it "should return adjacent vertices" do
@@ -193,8 +193,8 @@ describe Puppet::SimpleGraph, " when clearing" do
@graph = Puppet::SimpleGraph.new
one = Puppet::Relationship.new(:one, :two)
two = Puppet::Relationship.new(:two, :three)
- @graph.add_edge!(one)
- @graph.add_edge!(two)
+ @graph.add_edge(one)
+ @graph.add_edge(two)
@graph.clear
end
@@ -214,18 +214,18 @@ describe Puppet::SimpleGraph, " when reversing graphs" do
end
it "should provide a method for reversing the graph" do
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
@graph.reversal.edge?(:two, :one).should be_true
end
it "should add all vertices to the reversed graph" do
- @graph.add_edge!(:one, :two)
+ @graph.add_edge(:one, :two)
@graph.vertex?(:one).should be_true
@graph.vertex?(:two).should be_true
end
it "should retain labels on edges" do
- @graph.add_edge!(:one, :two, :stuff => :awesome)
+ @graph.add_edge(:one, :two, :stuff => :awesome)
edge = @graph.reversal.edge(:two, :one)
edge.label.should == {:stuff => :awesome}
end
@@ -238,7 +238,7 @@ describe Puppet::SimpleGraph, " when sorting the graph" do
def add_edges(hash)
hash.each do |a,b|
- @graph.add_edge!(a, b)
+ @graph.add_edge(a, b)
end
end
@@ -266,4 +266,15 @@ describe Puppet::SimpleGraph, " when sorting the graph" do
add_edges :a => :b, :b => :e, :c => :a, :d => :c
proc { @graph.topsort }.should_not raise_error
end
+
+ # Our graph's add_edge method is smart enough not to add
+ # duplicate edges, so we use the objects, which it doesn't
+ # check.
+ it "should be able to sort graphs with duplicate edges" do
+ one = Puppet::Relationship.new(:a, :b)
+ @graph.add_edge(one)
+ two = Puppet::Relationship.new(:a, :b)
+ @graph.add_edge(two)
+ proc { @graph.topsort }.should_not raise_error
+ end
end
diff --git a/spec/unit/util/checksums.rb b/spec/unit/util/checksums.rb
new file mode 100755
index 000000000..0e0d06c0d
--- /dev/null
+++ b/spec/unit/util/checksums.rb
@@ -0,0 +1,99 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2007-9-22.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/util/checksums'
+
+describe Puppet::Util::Checksums do
+ before do
+ @summer = Object.new
+ @summer.extend(Puppet::Util::Checksums)
+ end
+
+ content_sums = [:md5, :md5lite, :sha1, :sha1lite]
+ file_only = [:ctime, :mtime]
+
+ content_sums.each do |sumtype|
+ it "should be able to calculate %s sums from strings" % sumtype do
+ @summer.should be_respond_to(sumtype)
+ end
+ end
+
+ [content_sums, file_only].flatten.each do |sumtype|
+ it "should be able to calculate %s sums from files" % sumtype do
+ @summer.should be_respond_to(sumtype.to_s + "_file")
+ end
+ end
+
+ {:md5 => Digest::MD5, :sha1 => Digest::SHA1}.each do |sum, klass|
+ describe("when using %s" % sum) do
+ it "should use #{klass} to calculate string checksums" do
+ klass.expects(:hexdigest).with("mycontent").returns "whatever"
+ @summer.send(sum, "mycontent").should == "whatever"
+ end
+
+ it "should use incremental #{klass} sums to calculate file checksums" do
+ digest = mock 'digest'
+ klass.expects(:new).returns digest
+
+ file = "/path/to/my/file"
+
+ fh = mock 'filehandle'
+ fh.expects(:read).with(512).times(3).returns("firstline").then.returns("secondline").then.returns(nil)
+ #fh.expects(:read).with(512).returns("secondline")
+ #fh.expects(:read).with(512).returns(nil)
+
+ File.expects(:open).with(file, "r").yields(fh)
+
+ digest.expects(:<<).with "firstline"
+ digest.expects(:<<).with "secondline"
+ digest.expects(:hexdigest).returns :mydigest
+
+ @summer.send(sum.to_s + "_file", file).should == :mydigest
+ end
+ end
+ end
+
+ {:md5lite => Digest::MD5, :sha1lite => Digest::SHA1}.each do |sum, klass|
+ describe("when using %s" % sum) do
+ it "should use #{klass} to calculate string checksums from the first 512 characters of the string" do
+ content = "this is a test" * 100
+ klass.expects(:hexdigest).with(content[0..511]).returns "whatever"
+ @summer.send(sum, content).should == "whatever"
+ end
+
+ it "should use #{klass} to calculate a sum from the first 512 characters in the file" do
+ digest = mock 'digest'
+ klass.expects(:new).returns digest
+
+ file = "/path/to/my/file"
+
+ fh = mock 'filehandle'
+ fh.expects(:read).with(512).returns('my content')
+
+ File.expects(:open).with(file, "r").yields(fh)
+
+ digest.expects(:<<).with "my content"
+ digest.expects(:hexdigest).returns :mydigest
+
+ @summer.send(sum.to_s + "_file", file).should == :mydigest
+ end
+ end
+ end
+
+ [:ctime, :mtime].each do |sum|
+ describe("when using %s" % sum) do
+ it "should use the '#{sum}' on the file to determine the ctime" do
+ file = "/my/file"
+ stat = mock 'stat', sum => "mysum"
+
+ File.expects(:stat).with(file).returns(stat)
+
+ @summer.send(sum.to_s + "_file", file).should == "mysum"
+ end
+ end
+ end
+end
diff --git a/spec/unit/util/constant_inflector.rb b/spec/unit/util/constant_inflector.rb
new file mode 100755
index 000000000..5112e730f
--- /dev/null
+++ b/spec/unit/util/constant_inflector.rb
@@ -0,0 +1,70 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-02-12.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/util/constant_inflector'
+
+describe Puppet::Util::ConstantInflector, "when converting file names to constants" do
+ before do
+ @inflector = Object.new
+ @inflector.extend(Puppet::Util::ConstantInflector)
+ end
+
+ it "should capitalize terms" do
+ @inflector.file2constant("file").should == "File"
+ end
+
+ it "should switch all '/' characters to double colons" do
+ @inflector.file2constant("file/other").should == "File::Other"
+ end
+
+ it "should remove underscores and capitalize the proceeding letter" do
+ @inflector.file2constant("file_other").should == "FileOther"
+ end
+
+ it "should correctly replace as many underscores as exist in the file name" do
+ @inflector.file2constant("two_under_scores/with_some_more_underscores").should == "TwoUnderScores::WithSomeMoreUnderscores"
+ end
+
+ it "should collapse multiple underscores" do
+ @inflector.file2constant("many___scores").should == "ManyScores"
+ end
+
+ it "should correctly handle file names deeper than two directories" do
+ @inflector.file2constant("one_two/three_four/five_six").should == "OneTwo::ThreeFour::FiveSix"
+ end
+end
+
+describe Puppet::Util::ConstantInflector, "when converting constnats to file names" do
+ before do
+ @inflector = Object.new
+ @inflector.extend(Puppet::Util::ConstantInflector)
+ end
+
+ it "should convert them to a string if necessary" do
+ @inflector.constant2file(Puppet::Util::ConstantInflector).should be_instance_of(String)
+ end
+
+ it "should accept string inputs" do
+ @inflector.constant2file("Puppet::Util::ConstantInflector").should be_instance_of(String)
+ end
+
+ it "should downcase all terms" do
+ @inflector.constant2file("Puppet").should == "puppet"
+ end
+
+ it "should convert '::' to '/'" do
+ @inflector.constant2file("Puppet::Util::Constant").should == "puppet/util/constant"
+ end
+
+ it "should convert mid-word capitalization to an underscore" do
+ @inflector.constant2file("OneTwo::ThreeFour").should == "one_two/three_four"
+ end
+
+ it "should correctly handle constants with more than two parts" do
+ @inflector.constant2file("OneTwoThree::FourFiveSixSeven").should == "one_two_three/four_five_six_seven"
+ end
+end
diff --git a/spec/unit/util/settings.rb b/spec/unit/util/settings.rb
index 540743d7e..9f7018697 100755
--- a/spec/unit/util/settings.rb
+++ b/spec/unit/util/settings.rb
@@ -284,11 +284,6 @@ describe Puppet::Util::Settings, " when parsing its configuration" do
lambda { @settings.parse(file) }.should_not raise_error
end
- it "should support an old parse method when per-executable configuration files still exist" do
- # I'm not going to bother testing this method.
- @settings.should respond_to(:old_parse)
- end
-
it "should convert booleans in the configuration file into Ruby booleans" do
text = "[main]
one = true
@@ -481,7 +476,7 @@ describe Puppet::Util::Settings, " when being used to manage the host machine" d
def stub_transaction
@bucket = mock 'bucket'
- @config = mock 'config'
+ @config = mock 'config', :clear => nil
@trans = mock 'transaction'
@settings.expects(:to_transportable).with(:whatever).returns(@bucket)
@@ -597,6 +592,72 @@ describe Puppet::Util::Settings, " when being used to manage the host machine" d
file.should be_nil
end
+ it "should not try to manage files in memory" do
+ main = Puppet::Type.type(:file).create(:path => "/maindir")
+
+ trans = @settings.to_transportable
+
+ lambda { trans.to_catalog }.should_not raise_error
+ end
+
+ it "should do nothing if a catalog cannot be created" do
+ bucket = mock 'bucket'
+ catalog = mock 'catalog'
+
+ @settings.expects(:to_transportable).returns bucket
+ bucket.expects(:to_catalog).raises RuntimeError
+ catalog.expects(:apply).never
+
+ @settings.use(:mysection)
+ end
+
+ it "should clear the catalog after applying" do
+ bucket = mock 'bucket'
+ catalog = mock 'catalog'
+
+ @settings.expects(:to_transportable).returns bucket
+ bucket.expects(:to_catalog).returns catalog
+ catalog.stubs(:host_config=)
+ catalog.stubs(:apply)
+ catalog.expects(:clear)
+
+ @settings.use(:mysection)
+ end
+
+ it "should clear the catalog even if there is an exception during applying" do
+ bucket = mock 'bucket'
+ catalog = mock 'catalog'
+
+ @settings.expects(:to_transportable).returns bucket
+ bucket.expects(:to_catalog).returns catalog
+ catalog.stubs(:host_config=)
+ catalog.expects(:apply).raises(ArgumentError)
+ catalog.expects(:clear)
+
+ # We don't care about the raised exception, we just care that
+ # we clear the catalog even with the exception
+ lambda { @settings.use(:mysection) }.should raise_error
+ end
+
+ it "should do nothing if all specified sections have already been used" do
+ bucket = mock 'bucket'
+ catalog = mock 'catalog'
+
+ @settings.expects(:to_transportable).once.returns(bucket)
+ bucket.expects(:to_catalog).returns catalog
+ catalog.stub_everything
+
+ @settings.use(:whatever)
+
+ @settings.use(:whatever)
+ end
+
+ it "should ignore file settings whose values are not strings" do
+ @settings[:maindir] = false
+
+ lambda { trans = @settings.to_transportable }.should_not raise_error
+ end
+
it "should be able to turn the current configuration into a parseable manifest"
it "should convert octal numbers correctly when producing a manifest"
@@ -635,4 +696,6 @@ describe Puppet::Util::Settings, " when being used to manage the host machine" d
proc { @settings.use(:whatever) }.should raise_error(RuntimeError)
end
+
+ after { Puppet::Type.allclear }
end
diff --git a/spec/unit/util/tagging.rb b/spec/unit/util/tagging.rb
new file mode 100755
index 000000000..d61ee8ccb
--- /dev/null
+++ b/spec/unit/util/tagging.rb
@@ -0,0 +1,92 @@
+#!/usr/bin/env ruby
+#
+# Created by Luke Kanies on 2008-01-19.
+# Copyright (c) 2007. All rights reserved.
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/util/tagging'
+
+describe Puppet::Util::Tagging, "when adding tags" do
+ before do
+ @tagger = Object.new
+ @tagger.extend(Puppet::Util::Tagging)
+ end
+
+ it "should have a method for adding tags" do
+ @tagger.should be_respond_to(:tag)
+ end
+
+ it "should have a method for returning all tags" do
+ @tagger.should be_respond_to(:tags)
+ end
+
+ it "should add tags to the returned tag list" do
+ @tagger.tag("one")
+ @tagger.tags.should be_include("one")
+ end
+
+ it "should not add duplicate tags to the returned tag list" do
+ @tagger.tag("one")
+ @tagger.tag("one")
+ @tagger.tags.should == ["one"]
+ end
+
+ it "should return a duplicate of the tag list, rather than the original" do
+ @tagger.tag("one")
+ tags = @tagger.tags
+ tags << "two"
+ @tagger.tags.should_not be_include("two")
+ end
+
+ it "should add all provided tags to the tag list" do
+ @tagger.tag("one", "two")
+ @tagger.tags.should be_include("one")
+ @tagger.tags.should be_include("two")
+ end
+
+ it "should fail on tags containing '*' characters" do
+ lambda { @tagger.tag("bad*tag") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail on tags starting with '-' characters" do
+ lambda { @tagger.tag("-badtag") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should fail on tags containing ' ' characters" do
+ lambda { @tagger.tag("bad tag") }.should raise_error(Puppet::ParseError)
+ end
+
+ it "should allow alpha tags" do
+ lambda { @tagger.tag("good_tag") }.should_not raise_error(Puppet::ParseError)
+ end
+
+ it "should allow tags containing '.' characters" do
+ lambda { @tagger.tag("good.tag") }.should_not raise_error(Puppet::ParseError)
+ end
+
+ it "should provide a method for testing tag validity" do
+ @tagger.metaclass.publicize_methods(:valid_tag?) { @tagger.should be_respond_to(:valid_tag?) }
+ end
+
+ it "should add qualified classes as tags" do
+ @tagger.tag("one::two")
+ @tagger.tags.should be_include("one::two")
+ end
+
+ it "should add each part of qualified classes as tags" do
+ @tagger.tag("one::two::three")
+ @tagger.tags.should be_include("one")
+ @tagger.tags.should be_include("two")
+ @tagger.tags.should be_include("three")
+ end
+
+ it "should indicate when the object is tagged with a provided tag" do
+ @tagger.tag("one")
+ @tagger.should be_tagged("one")
+ end
+
+ it "should indicate when the object is not tagged with a provided tag" do
+ @tagger.should_not be_tagged("one")
+ end
+end
diff --git a/test/data/snippets/collection_within_virtual_definitions.pp b/test/data/snippets/collection_within_virtual_definitions.pp
new file mode 100644
index 000000000..3c21468b0
--- /dev/null
+++ b/test/data/snippets/collection_within_virtual_definitions.pp
@@ -0,0 +1,20 @@
+define test($name) {
+ file {"/tmp/collection_within_virtual_definitions1_$name.txt":
+ content => "File name $name\n"
+ }
+ Test2 <||>
+}
+
+define test2() {
+ file {"/tmp/collection_within_virtual_definitions2_$name.txt":
+ content => "This is a test\n"
+ }
+}
+
+node default {
+ @test {"foo":
+ name => "foo"
+ }
+ @test2 {"foo2": }
+ Test <||>
+}
diff --git a/test/data/snippets/realize_defined_types.pp b/test/data/snippets/realize_defined_types.pp
deleted file mode 100644
index a4b562258..000000000
--- a/test/data/snippets/realize_defined_types.pp
+++ /dev/null
@@ -1,13 +0,0 @@
-define testing {
- file { "/tmp/realize_defined_test1": ensure => file }
-}
-@testing { yay: }
-
-define deeper {
- file { "/tmp/realize_defined_test2": ensure => file }
-}
-
-@deeper { boo: }
-
-realize Testing[yay]
-realize File["/tmp/realize_defined_test2"]
diff --git a/test/executables/puppetbin.rb b/test/executables/puppetbin.rb
index 218787c92..08329efb6 100755
--- a/test/executables/puppetbin.rb
+++ b/test/executables/puppetbin.rb
@@ -83,5 +83,22 @@ class TestPuppetBin < Test::Unit::TestCase
assert(FileTest.exists?(path), "Failed to create config'ed file")
end
+
+ def test_parseonly
+ path = tempfile()
+ manifest = tempfile()
+ puppet = %x{which puppet}.chomp
+ if puppet == ""
+ Puppet.info "cannot find puppet; cannot test parseonly"
+ return
+ end
+ code = 'File <<| |>>
+ include nosuchclass'
+
+ assert_nothing_raised {
+ IO.popen("#{puppet} --parseonly", 'w') { |p| p.puts code }
+ }
+ assert($? == 0, "parseonly test exited with code %s" % $?.to_i)
+ end
end
diff --git a/test/language/ast.rb b/test/language/ast.rb
index b31012d38..8c0f31aba 100755
--- a/test/language/ast.rb
+++ b/test/language/ast.rb
@@ -35,14 +35,14 @@ class TestAST < Test::Unit::TestCase
# We initialized it to true, so we should get that first
ret = nil
assert_nothing_raised {
- ret = astif.evaluate(:scope => "yay")
+ ret = astif.evaluate("yay")
}
assert_equal(:if, ret)
# Now set it to false and check that
faketest.evaluate = false
assert_nothing_raised {
- ret = astif.evaluate(:scope => "yay")
+ ret = astif.evaluate("yay")
}
assert_equal(:else, ret)
end
@@ -57,10 +57,10 @@ class TestAST < Test::Unit::TestCase
end
Puppet::Parser::Resource.expects(:new).with { |o| o.is_a?(Hash) }.returns(:override)
- scope.compile.expects(:store_override).with(:override)
+ scope.compiler.expects(:add_override).with(:override)
ret = nil
assert_nothing_raised do
- ret = ref.evaluate :scope => scope
+ ret = ref.evaluate scope
end
assert_equal(:override, ret, "Did not return override")
@@ -74,7 +74,7 @@ class TestAST < Test::Unit::TestCase
args = {:source => "/yay/ness", :group => "yayness"}
assert_nothing_raised do
obj = defaultobj "file", args
- obj.evaluate :scope => scope
+ obj.evaluate scope
end
hash = nil
@@ -93,56 +93,6 @@ class TestAST < Test::Unit::TestCase
end
end
- def test_node
- scope = mkscope
- parser = scope.compile.parser
-
- # Define a base node
- basenode = parser.newnode "basenode", :code => AST::ASTArray.new(:children => [
- resourcedef("file", "/tmp/base", "owner" => "root")
- ])
-
- # Now define a subnode
- nodes = parser.newnode ["mynode", "othernode"],
- :code => AST::ASTArray.new(:children => [
- resourcedef("file", "/tmp/mynode", "owner" => "root"),
- resourcedef("file", "/tmp/basenode", "owner" => "daemon")
- ])
-
- assert_instance_of(Array, nodes)
-
- # Make sure we can find them all.
- %w{mynode othernode}.each do |node|
- assert(parser.nodes[node], "Could not find %s" % node)
- end
- mynode = parser.nodes["mynode"]
-
- # Now try evaluating the node
- assert_nothing_raised do
- mynode.evaluate :scope => scope, :resource => scope.resource
- end
-
- # Make sure that we can find each of the files
- myfile = scope.findresource "File[/tmp/mynode]"
- assert(myfile, "Could not find file from node")
- assert_equal("root", myfile[:owner])
-
- basefile = scope.findresource "File[/tmp/basenode]"
- assert(basefile, "Could not find file from base node")
- assert_equal("daemon", basefile[:owner])
-
- # Now make sure we can evaluate nodes with parents
- child = parser.newnode(%w{child}, :parent => "basenode").shift
-
- newscope = mkscope :parser => parser
- assert_nothing_raised do
- child.evaluate :scope => newscope, :resource => scope.resource
- end
-
- assert(newscope.findresource("File[/tmp/base]"),
- "Could not find base resource")
- end
-
def test_collection
scope = mkscope
@@ -155,13 +105,13 @@ class TestAST < Test::Unit::TestCase
ret = nil
assert_nothing_raised do
- ret = coll.evaluate :scope => scope
+ ret = coll.evaluate scope
end
assert_instance_of(Puppet::Parser::Collector, ret)
# Now make sure we get it back from the scope
- colls = scope.compile.instance_variable_get("@collections")
+ colls = scope.compiler.instance_variable_get("@collections")
assert_equal([ret], colls, "Did not store collector in config's collection list")
end
@@ -175,7 +125,7 @@ class TestAST < Test::Unit::TestCase
run_collection_queries(:virtual) do |string, result, query|
code = nil
assert_nothing_raised do
- str, code = query.evaluate :scope => scope
+ str, code = query.evaluate scope
end
assert_instance_of(Proc, code)
diff --git a/test/language/ast/casestatement.rb b/test/language/ast/casestatement.rb
index 0a744b686..d95d788d9 100755
--- a/test/language/ast/casestatement.rb
+++ b/test/language/ast/casestatement.rb
@@ -45,7 +45,7 @@ class TestCaseStatement < Test::Unit::TestCase
result = nil
assert_nothing_raised do
- result = ast.evaluate :scope => scope
+ result = ast.evaluate scope
end
assert(result, "did not get valid result")
assert_equal(["upper"], $evaluated, "Did not match case-sensitively")
@@ -56,7 +56,7 @@ class TestCaseStatement < Test::Unit::TestCase
$evaluated.clear
hash["MyParam"].reset
assert_nothing_raised do
- result = ast.evaluate :scope => scope
+ result = ast.evaluate scope
end
assert(result, "did not get valid result")
assert_equal(["lower"], result, "Did not match case-insensitively")
@@ -92,7 +92,7 @@ class TestCaseStatement < Test::Unit::TestCase
scope = mkscope
scope.setvar("testparam", value)
assert_nothing_raised do
- result = ast.evaluate(:scope => scope)
+ result = ast.evaluate(scope)
end
assert_equal(should, result, "Got incorrect result for %s" % value)
diff --git a/test/language/ast/definition.rb b/test/language/ast/definition.rb
deleted file mode 100755
index 2a71aaa45..000000000
--- a/test/language/ast/definition.rb
+++ /dev/null
@@ -1,166 +0,0 @@
-#!/usr/bin/env ruby
-#
-# Created by Luke A. Kanies on 2006-02-20.
-# Copyright (c) 2006. All rights reserved.
-
-require File.dirname(__FILE__) + '/../../lib/puppettest'
-
-require 'puppettest'
-require 'mocha'
-require 'puppettest/parsertesting'
-require 'puppettest/resourcetesting'
-
-class TestASTDefinition < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::ParserTesting
- include PuppetTest::ResourceTesting
- AST = Puppet::Parser::AST
-
- def test_initialize
- parser = mkparser
-
- # Create a new definition
- klass = parser.newdefine "yayness",
- :arguments => [["owner", stringobj("nobody")], %w{mode}],
- :code => AST::ASTArray.new(
- :children => [resourcedef("file", "/tmp/$name",
- "owner" => varref("owner"), "mode" => varref("mode"))]
- )
-
- # Test validattr? a couple different ways
- [:owner, "owner", :schedule, "schedule"].each do |var|
- assert(klass.validattr?(var), "%s was not considered valid" % var.inspect)
- end
-
- [:random, "random"].each do |var|
- assert(! klass.validattr?(var), "%s was considered valid" % var.inspect)
- end
-
- end
-
- def test_evaluate
- parser = mkparser
- config = mkcompile
- config.send(:evaluate_main)
- scope = config.topscope
- klass = parser.newdefine "yayness",
- :arguments => [["owner", stringobj("nobody")], %w{mode}],
- :code => AST::ASTArray.new(
- :children => [resourcedef("file", "/tmp/$name",
- "owner" => varref("owner"), "mode" => varref("mode"))]
- )
-
- resource = Puppet::Parser::Resource.new(
- :title => "first",
- :type => "yayness",
- :exported => false,
- :virtual => false,
- :scope => scope,
- :source => scope.source
- )
- resource.send(:set_parameter, "name", "first")
- resource.send(:set_parameter, "mode", "755")
-
- resource.stubs(:title)
- assert_nothing_raised do
- klass.evaluate(:scope => scope, :resource => resource)
- end
-
- firstobj = config.findresource("File[/tmp/first]")
- assert(firstobj, "Did not create /tmp/first obj")
-
- assert_equal("File", firstobj.type)
- assert_equal("/tmp/first", firstobj.title)
- assert_equal("nobody", firstobj[:owner])
- assert_equal("755", firstobj[:mode])
-
- # Make sure we can't evaluate it with the same args
- assert_raise(Puppet::ParseError) do
- klass.evaluate(:scope => scope, :resource => resource)
- end
-
- # Now create another with different args
- resource2 = Puppet::Parser::Resource.new(
- :title => "second",
- :type => "yayness",
- :exported => false,
- :virtual => false,
- :scope => scope,
- :source => scope.source
- )
- resource2.send(:set_parameter, "name", "second")
- resource2.send(:set_parameter, "mode", "755")
- resource2.send(:set_parameter, "owner", "daemon")
-
- assert_nothing_raised do
- klass.evaluate(:scope => scope, :resource => resource2)
- end
-
- secondobj = config.findresource("File[/tmp/second]")
- assert(secondobj, "Did not create /tmp/second obj")
-
- assert_equal("File", secondobj.type)
- assert_equal("/tmp/second", secondobj.title)
- assert_equal("daemon", secondobj[:owner])
- assert_equal("755", secondobj[:mode])
- end
-
- # #539 - definitions should support both names and titles
- def test_names_and_titles
- parser = mkparser
- scope = mkscope :parser => parser
-
- [
- {:name => "one", :title => "two"},
- {:title => "mytitle"}
- ].each_with_index do |hash, i|
- # Create a definition that uses both name and title. Put this
- # inside the loop so the subscope expectations work.
- klass = parser.newdefine "yayness%s" % i
-
- resource = Puppet::Parser::Resource.new(
- :title => hash[:title],
- :type => "yayness%s" % i,
- :exported => false,
- :virtual => false,
- :scope => scope,
- :source => scope.source
- )
-
- subscope = klass.subscope(scope, resource)
-
- klass.expects(:subscope).returns(subscope)
-
- if hash[:name]
- resource.stubs(:to_hash).returns({:name => hash[:name]})
- end
-
- assert_nothing_raised("Could not evaluate definition with %s" % hash.inspect) do
- klass.evaluate(:scope => scope, :resource => resource)
- end
-
- name = hash[:name] || hash[:title]
- title = hash[:title]
-
- assert_equal(name, subscope.lookupvar("name"),
- "Name did not get set correctly")
- assert_equal(title, subscope.lookupvar("title"),
- "title did not get set correctly")
-
- [:name, :title].each do |param|
- val = resource.send(param)
- assert(subscope.tags.include?(val),
- "Scope was not tagged with %s '%s'" % [param, val])
- end
- end
- end
-
- # Testing the root cause of #615. We should be using the fqname for the type, instead
- # of just the short name.
- def test_fully_qualified_types
- parser = mkparser
- klass = parser.newclass("one::two")
-
- assert_equal("one::two", klass.classname, "Class did not get fully qualified class name")
- end
-end
diff --git a/test/language/ast/hostclass.rb b/test/language/ast/hostclass.rb
deleted file mode 100755
index 80032f30c..000000000
--- a/test/language/ast/hostclass.rb
+++ /dev/null
@@ -1,184 +0,0 @@
-#!/usr/bin/env ruby
-#
-# Created by Luke A. Kanies on 2006-02-20.
-# Copyright (c) 2006. All rights reserved.
-
-require File.dirname(__FILE__) + '/../../lib/puppettest'
-
-require 'puppettest'
-require 'puppettest/parsertesting'
-require 'puppettest/resourcetesting'
-require 'mocha'
-
-class TestASTHostClass < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::ParserTesting
- include PuppetTest::ResourceTesting
- AST = Puppet::Parser::AST
-
- def test_hostclass
- scope = mkscope
- parser = scope.compile.parser
-
- # Create the class we're testing, first with no parent
- klass = parser.newclass "first",
- :code => AST::ASTArray.new(
- :children => [resourcedef("file", "/tmp",
- "owner" => "nobody", "mode" => "755")]
- )
-
- resource = Puppet::Parser::Resource.new(:type => "class", :title => "first", :scope => scope)
- assert_nothing_raised do
- klass.evaluate(:scope => scope, :resource => resource)
- end
-
- # Then try it again
- assert_nothing_raised do
- klass.evaluate(:scope => scope, :resource => resource)
- end
-
- assert(scope.compile.class_scope(klass), "Class was not considered evaluated")
-
- tmp = scope.findresource("File[/tmp]")
- assert(tmp, "Could not find file /tmp")
- assert_equal("nobody", tmp[:owner])
- assert_equal("755", tmp[:mode])
-
- # Now create a couple more classes.
- newbase = parser.newclass "newbase",
- :code => AST::ASTArray.new(
- :children => [resourcedef("file", "/tmp/other",
- "owner" => "nobody", "mode" => "644")]
- )
-
- newsub = parser.newclass "newsub",
- :parent => "newbase",
- :code => AST::ASTArray.new(
- :children => [resourcedef("file", "/tmp/yay",
- "owner" => "nobody", "mode" => "755"),
- resourceoverride("file", "/tmp/other",
- "owner" => "daemon")
- ]
- )
-
- # Override a different variable in the top scope.
- moresub = parser.newclass "moresub",
- :parent => "newbase",
- :code => AST::ASTArray.new(
- :children => [resourceoverride("file", "/tmp/other",
- "mode" => "755")]
- )
-
- assert_nothing_raised do
- newsub.evaluate(:scope => scope, :resource => resource)
- end
-
- assert_nothing_raised do
- moresub.evaluate(:scope => scope, :resource => resource)
- end
-
- assert(scope.compile.class_scope(newbase), "Did not eval newbase")
- assert(scope.compile.class_scope(newsub), "Did not eval newsub")
-
- yay = scope.findresource("File[/tmp/yay]")
- assert(yay, "Did not find file /tmp/yay")
- assert_equal("nobody", yay[:owner])
- assert_equal("755", yay[:mode])
-
- other = scope.findresource("File[/tmp/other]")
- assert(other, "Did not find file /tmp/other")
- assert_equal("daemon", other[:owner])
- assert_equal("755", other[:mode])
- end
-
- # Make sure that classes set their namespaces to themselves. This
- # way they start looking for definitions in their own namespace.
- def test_hostclass_namespace
- scope = mkscope
- parser = scope.compile.parser
-
- # Create a new class
- klass = nil
- assert_nothing_raised do
- klass = parser.newclass "funtest"
- end
-
- # Now define a definition in that namespace
-
- define = nil
- assert_nothing_raised do
- define = parser.newdefine "funtest::mydefine"
- end
-
- assert_equal("funtest", klass.namespace,
- "component namespace was not set in the class")
-
- assert_equal("funtest", define.namespace,
- "component namespace was not set in the definition")
-
- newscope = klass.subscope(scope, mock("resource"))
-
- assert_equal(["funtest"], newscope.namespaces,
- "Scope did not inherit namespace")
-
- # Now make sure we can find the define
- assert(newscope.finddefine("mydefine"),
- "Could not find definition in my enclosing class")
- end
-
- # Make sure that our scope is a subscope of the parentclass's scope.
- # At the same time, make sure definitions in the parent class can be
- # found within the subclass (#517).
- def test_parent_scope_from_parentclass
- scope = mkscope
- parser = scope.compile.parser
-
- source = parser.newclass ""
- parser.newclass("base")
- fun = parser.newdefine("base::fun")
- parser.newclass("middle", :parent => "base")
- parser.newclass("sub", :parent => "middle")
- scope = mkscope :parser => parser
-
- ret = nil
- assert_nothing_raised do
- ret = scope.compile.evaluate_classes(["sub"], scope)
- end
- scope.compile.send(:evaluate_generators)
-
- subscope = scope.compile.class_scope(scope.findclass("sub"))
- assert(subscope, "could not find sub scope")
- mscope = scope.compile.class_scope(scope.findclass("middle"))
- assert(mscope, "could not find middle scope")
- pscope = scope.compile.class_scope(scope.findclass("base"))
- assert(pscope, "could not find parent scope")
-
- assert(pscope == mscope.parent, "parent scope of middle was not set correctly")
- assert(mscope == subscope.parent, "parent scope of sub was not set correctly")
-
- result = mscope.finddefine("fun")
- assert(result, "could not find parent-defined definition from middle")
- assert(fun == result, "found incorrect parent-defined definition from middle")
-
- result = subscope.finddefine("fun")
- assert(result, "could not find parent-defined definition from sub")
- assert(fun == result, "found incorrect parent-defined definition from sub")
- end
-
- # #795 - make sure the subclass's tags get set before we
- # evaluate the parent class, so we can be sure that the parent
- # class can switch based on the sub classes.
- def test_tags_set_before_parent_is_evaluated
- scope = mkscope
- parser = scope.compile.parser
- base = parser.newclass "base"
- sub = parser.newclass "sub", :parent => "base"
-
- base.expects(:safeevaluate).with do |args|
- assert(scope.compile.catalog.tags.include?("sub"), "Did not tag with sub class name before evaluating base class")
- base.evaluate(args)
- true
- end
- sub.evaluate :scope => scope, :resource => scope.resource
- end
-end
diff --git a/test/language/ast/resource.rb b/test/language/ast/resource.rb
index c99d98eeb..97541d92f 100755
--- a/test/language/ast/resource.rb
+++ b/test/language/ast/resource.rb
@@ -16,8 +16,7 @@ class TestASTResource< Test::Unit::TestCase
def setup
super
@scope = mkscope
- @parser = @scope.compile.parser
- @scope.compile.send(:evaluate_main)
+ @parser = @scope.compiler.parser
end
def newdef(type, title, params = nil)
@@ -36,24 +35,24 @@ class TestASTResource< Test::Unit::TestCase
title = "title"
# First try a qualified type
- assert_equal("One::Two", newdef("two", title).evaluate(:scope => twoscope)[0].type,
+ assert_equal("One::Two", newdef("two", title).evaluate(twoscope)[0].type,
"Defined type was not made fully qualified")
# Then try a type that does not need to be qualified
- assert_equal("One", newdef("one", title).evaluate(:scope => twoscope)[0].type,
+ assert_equal("One", newdef("one", title).evaluate(twoscope)[0].type,
"Unqualified defined type was not handled correctly")
# Then an unqualified type from within the one namespace
- assert_equal("Three", newdef("three", title).evaluate(:scope => twoscope)[0].type,
+ assert_equal("Three", newdef("three", title).evaluate(twoscope)[0].type,
"Defined type was not made fully qualified")
# Then a builtin type
- assert_equal("File", newdef("file", title).evaluate(:scope => twoscope)[0].type,
+ assert_equal("File", newdef("file", title).evaluate(twoscope)[0].type,
"Builtin type was not handled correctly")
# Now try a type that does not exist, which should throw an error.
assert_raise(Puppet::ParseError, "Did not fail on a missing type in a resource reference") do
- newdef("nosuchtype", title).evaluate(:scope => twoscope)
+ newdef("nosuchtype", title).evaluate(twoscope)
end
end
end
diff --git a/test/language/ast/resource_reference.rb b/test/language/ast/resource_reference.rb
index c9fde078f..1f554d90f 100755
--- a/test/language/ast/resource_reference.rb
+++ b/test/language/ast/resource_reference.rb
@@ -20,7 +20,7 @@ class TestASTResourceReference < Test::Unit::TestCase
def setup
super
@scope = mkscope
- @parser = @scope.compile.parser
+ @parser = @scope.compiler.parser
end
def test_evaluate
@@ -31,7 +31,7 @@ class TestASTResourceReference < Test::Unit::TestCase
evaled = nil
assert_nothing_raised("Could not evaluate resource ref") do
- evaled = ref.evaluate(:scope => @scope)
+ evaled = ref.evaluate(@scope)
end
assert_equal(type, evaled.type, "Type did not translate correctly")
@@ -44,7 +44,7 @@ class TestASTResourceReference < Test::Unit::TestCase
ref = newref("Class", "one")
evaled = nil
assert_nothing_raised("Could not evaluate resource ref") do
- evaled = ref.evaluate(:scope => @scope)
+ evaled = ref.evaluate(@scope)
end
assert_equal("Class", evaled.type, "Did not set type to 'class'")
@@ -61,24 +61,24 @@ class TestASTResourceReference < Test::Unit::TestCase
title = "title"
# First try a qualified type
- assert_equal("One::Two", newref("two", title).evaluate(:scope => twoscope).type,
+ assert_equal("One::Two", newref("two", title).evaluate(twoscope).type,
"Defined type was not made fully qualified")
# Then try a type that does not need to be qualified
- assert_equal("One", newref("one", title).evaluate(:scope => twoscope).type,
+ assert_equal("One", newref("one", title).evaluate(twoscope).type,
"Unqualified defined type was not handled correctly")
# Then an unqualified type from within the one namespace
- assert_equal("Three", newref("three", title).evaluate(:scope => twoscope).type,
+ assert_equal("Three", newref("three", title).evaluate(twoscope).type,
"Defined type was not made fully qualified")
# Then a builtin type
- assert_equal("File", newref("file", title).evaluate(:scope => twoscope).type,
+ assert_equal("File", newref("file", title).evaluate(twoscope).type,
"Builtin type was not handled correctly")
# Now try a type that does not exist, which should throw an error.
assert_raise(Puppet::ParseError, "Did not fail on a missing type in a resource reference") do
- newref("nosuchtype", title).evaluate(:scope => twoscope)
+ newref("nosuchtype", title).evaluate(twoscope)
end
# Now run the same tests, but with the classes
@@ -86,20 +86,20 @@ class TestASTResourceReference < Test::Unit::TestCase
@parser.newclass "one::five"
# First try an unqualified type
- assert_equal("four", newref("class", "four").evaluate(:scope => twoscope).title,
+ assert_equal("four", newref("class", "four").evaluate(twoscope).title,
"Unqualified class was not found")
# Then a qualified class
- assert_equal("one::five", newref("class", "five").evaluate(:scope => twoscope).title,
+ assert_equal("one::five", newref("class", "five").evaluate(twoscope).title,
"Class was not made fully qualified")
# Then try a type that does not need to be qualified
- assert_equal("four", newref("class", "four").evaluate(:scope => twoscope).title,
+ assert_equal("four", newref("class", "four").evaluate(twoscope).title,
"Unqualified class was not handled correctly")
# Now try a type that does not exist, which should throw an error.
assert_raise(Puppet::ParseError, "Did not fail on a missing type in a resource reference") do
- newref("class", "nosuchclass").evaluate(:scope => twoscope)
+ newref("class", "nosuchclass").evaluate(twoscope)
end
end
end
diff --git a/test/language/ast/selector.rb b/test/language/ast/selector.rb
index 535fcbf70..6e923bdcb 100755
--- a/test/language/ast/selector.rb
+++ b/test/language/ast/selector.rb
@@ -37,7 +37,7 @@ class TestSelector < Test::Unit::TestCase
params = maker.call()
sel = AST::Selector.new(:param => param, :values => params.values)
result = nil
- assert_nothing_raised { result = sel.evaluate(:scope => scope) }
+ assert_nothing_raised { result = sel.evaluate(scope) }
assert_equal(should[str], result, "did not case-sensitively match %s" % str)
end
@@ -53,7 +53,7 @@ class TestSelector < Test::Unit::TestCase
params.delete(:upper)
sel = AST::Selector.new(:param => param, :values => params.values)
result = nil
- assert_nothing_raised { result = sel.evaluate(:scope => scope) }
+ assert_nothing_raised { result = sel.evaluate(scope) }
assert_equal("lower", result, "did not case-insensitively match %s" % str)
end
end
diff --git a/test/language/ast/variable.rb b/test/language/ast/variable.rb
index 09122ce16..bde397bb4 100755
--- a/test/language/ast/variable.rb
+++ b/test/language/ast/variable.rb
@@ -22,9 +22,9 @@ class TestVariable < Test::Unit::TestCase
end
def test_evaluate
- assert_equal("", @var.evaluate(:scope => @scope), "did not return empty string on unset var")
+ assert_equal("", @var.evaluate(@scope), "did not return empty string on unset var")
@scope.setvar(@name, "something")
- assert_equal("something", @var.evaluate(:scope => @scope), "incorrect variable value")
+ assert_equal("something", @var.evaluate(@scope), "incorrect variable value")
end
end
diff --git a/test/language/compile.rb b/test/language/compile.rb
deleted file mode 100755
index 082b37a1c..000000000
--- a/test/language/compile.rb
+++ /dev/null
@@ -1,569 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../lib/puppettest'
-
-require 'mocha'
-require 'puppettest'
-require 'puppettest/parsertesting'
-require 'puppet/parser/compile'
-
-# Test our compile object.
-class TestCompile < Test::Unit::TestCase
- include PuppetTest
- include PuppetTest::ParserTesting
-
- Compile = Puppet::Parser::Compile
- Scope = Puppet::Parser::Scope
- Node = Puppet::Network::Handler.handler(:node)
- SimpleNode = Puppet::Node
-
- def mknode(name = "foo")
- @node = SimpleNode.new(name)
- end
-
- def mkparser
- # This should mock an interpreter
- @parser = stub 'parser', :version => "1.0", :nodes => {}
- end
-
- def mkcompile(options = {})
- if node = options[:node]
- options.delete(:node)
- else
- node = mknode
- end
- @compile = Compile.new(node, mkparser, options)
- end
-
- def test_initialize
- compile = nil
- node = stub 'node', :name => "foo"
- parser = stub 'parser', :version => "1.0", :nodes => {}
- assert_nothing_raised("Could not init compile with all required options") do
- compile = Compile.new(node, parser)
- end
-
- assert_equal(node, compile.node, "Did not set node correctly")
- assert_equal(parser, compile.parser, "Did not set parser correctly")
-
- # We're not testing here whether we call initvars, because it's too difficult to
- # mock.
-
- # Now try it with some options
- assert_nothing_raised("Could not init compile with extra options") do
- compile = Compile.new(node, parser)
- end
-
- assert_equal(false, compile.ast_nodes?, "Did not set ast_nodes? correctly")
- end
-
- def test_initvars
- compile = mkcompile
- [:class_scopes, :resource_table, :exported_resources, :resource_overrides].each do |table|
- assert_instance_of(Hash, compile.send(:instance_variable_get, "@#{table}"), "Did not set %s table correctly" % table)
- end
- assert_instance_of(Scope, compile.topscope, "Did not create a topscope")
- graph = compile.instance_variable_get("@scope_graph")
- assert_instance_of(Puppet::SimpleGraph, graph, "Did not create scope graph")
- assert(graph.vertex?(compile.topscope), "Did not add top scope as a vertex in the graph")
- end
-
- # Make sure we store and can retrieve references to classes and their scopes.
- def test_class_set_and_class_scope
- klass = mock 'ast_class'
- klass.expects(:classname).returns("myname")
-
- compile = mkcompile
- compile.catalog.expects(:tag).with("myname")
-
- assert_nothing_raised("Could not set class") do
- compile.class_set "myname", "myscope"
- end
- # First try to retrieve it by name.
- assert_equal("myscope", compile.class_scope("myname"), "Could not retrieve class scope by name")
-
- # Then by object
- assert_equal("myscope", compile.class_scope(klass), "Could not retrieve class scope by object")
- end
-
- def test_classlist
- compile = mkcompile
-
- compile.class_set "", "empty"
- compile.class_set "one", "yep"
- compile.class_set "two", "nope"
-
- # Make sure our class list is correct
- assert_equal(%w{one two}.sort, compile.classlist.sort, "Did not get correct class list")
- end
-
- # Make sure collections get added to our internal array
- def test_add_collection
- compile = mkcompile
- assert_nothing_raised("Could not add collection") do
- compile.add_collection "nope"
- end
- assert_equal(%w{nope}, compile.instance_variable_get("@collections"), "Did not add collection")
- end
-
- # Make sure we create a graph of scopes.
- def test_newscope
- compile = mkcompile
- graph = compile.instance_variable_get("@scope_graph")
- assert_instance_of(Scope, compile.topscope, "Did not create top scope")
- assert_instance_of(Puppet::SimpleGraph, graph, "Did not create graph")
-
- assert(graph.vertex?(compile.topscope), "The top scope is not a vertex in the graph")
-
- # Now that we've got the top scope, create a new, subscope
- subscope = nil
- assert_nothing_raised("Could not create subscope") do
- subscope = compile.newscope(compile.topscope)
- end
- assert_instance_of(Scope, subscope, "Did not create subscope")
- assert(graph.edge?(compile.topscope, subscope), "An edge between top scope and subscope was not added")
-
- # Make sure a scope can find its parent.
- assert(compile.parent(subscope), "Could not look up parent scope on compile")
- assert_equal(compile.topscope.object_id, compile.parent(subscope).object_id, "Did not get correct parent scope from compile")
- assert_equal(compile.topscope.object_id, subscope.parent.object_id, "Scope did not correctly retrieve its parent scope")
-
- # Now create another, this time specifying options
- another = nil
- assert_nothing_raised("Could not create subscope") do
- another = compile.newscope(subscope, :level => 5)
- end
- assert_equal(5, another.level, "did not set scope option correctly")
- assert_instance_of(Scope, another, "Did not create second subscope")
- assert(graph.edge?(subscope, another), "An edge between parent scope and second subscope was not added")
-
- # Make sure it can find its parent.
- assert(compile.parent(another), "Could not look up parent scope of second subscope on compile")
- assert_equal(subscope.object_id, compile.parent(another).object_id, "Did not get correct parent scope of second subscope from compile")
- assert_equal(subscope.object_id, another.parent.object_id, "Second subscope did not correctly retrieve its parent scope")
-
- # And make sure both scopes show up in the right order in the search path
- assert_equal([another.object_id, subscope.object_id, compile.topscope.object_id], another.scope_path.collect { |p| p.object_id },
- "Did not get correct scope path")
- end
-
- # The heart of the action.
- def test_compile
- compile = mkcompile
- [:set_node_parameters, :evaluate_main, :evaluate_ast_node, :evaluate_node_classes, :evaluate_generators, :fail_on_unevaluated, :finish].each do |method|
- compile.expects(method)
- end
- assert_instance_of(Puppet::Node::Catalog, compile.compile, "Did not return the catalog")
- end
-
- # Test setting the node's parameters into the top scope.
- def test_set_node_parameters
- compile = mkcompile
- @node.parameters = {"a" => "b", "c" => "d"}
- scope = compile.topscope
- @node.parameters.each do |param, value|
- scope.expects(:setvar).with(param, value)
- end
-
- assert_nothing_raised("Could not call 'set_node_parameters'") do
- compile.send(:set_node_parameters)
- end
- end
-
- # Test that we can evaluate the main class, which is the one named "" in namespace
- # "".
- def test_evaluate_main
- compile = mkcompile
- main_class = mock 'main_class'
- compile.topscope.expects(:source=).with(main_class)
- @parser.expects(:findclass).with("", "").returns(main_class)
-
- main_resource = mock 'main resource'
- Puppet::Parser::Resource.expects(:new).with { |args| args[:title] == :main }.returns(main_resource)
-
- main_resource.expects(:evaluate)
-
- assert_nothing_raised("Could not call evaluate_main") do
- compile.send(:evaluate_main)
- end
- end
-
- def test_evaluate_node_classes
- compile = mkcompile
- @node.classes = %w{one two three four}
- compile.expects(:evaluate_classes).with(%w{one two three four}, compile.topscope)
- assert_nothing_raised("could not call evaluate_node_classes") do
- compile.send(:evaluate_node_classes)
- end
- end
-
- def test_evaluate_collections
- compile = mkcompile
-
- colls = []
-
- # Make sure we return false when there's nothing there.
- assert(! compile.send(:evaluate_collections), "Returned true when there were no collections")
-
- # And when the collections fail to evaluate.
- colls << mock("coll1-false")
- colls << mock("coll2-false")
- colls.each { |c| c.expects(:evaluate).returns(false) }
-
- compile.instance_variable_set("@collections", colls)
- assert(! compile.send(:evaluate_collections), "Returned true when collections both evaluated nothing")
-
- # Now have one of the colls evaluate
- colls.clear
- colls << mock("coll1-one-true")
- colls << mock("coll2-one-true")
- colls[0].expects(:evaluate).returns(true)
- colls[1].expects(:evaluate).returns(false)
- assert(compile.send(:evaluate_collections), "Did not return true when one collection evaluated true")
-
- # And have them both eval true
- colls.clear
- colls << mock("coll1-both-true")
- colls << mock("coll2-both-true")
- colls[0].expects(:evaluate).returns(true)
- colls[1].expects(:evaluate).returns(true)
- assert(compile.send(:evaluate_collections), "Did not return true when both collections evaluated true")
- end
-
- def test_unevaluated_resources
- compile = mkcompile
- resources = {}
- compile.instance_variable_set("@resource_table", resources)
-
- # First test it when the table is empty
- assert_nil(compile.send(:unevaluated_resources), "Somehow found unevaluated resources in an empty table")
-
- # Then add a builtin resources
- resources["one"] = mock("builtin only")
- resources["one"].expects(:builtin?).returns(true)
- assert_nil(compile.send(:unevaluated_resources), "Considered a builtin resource unevaluated")
-
- # And do both builtin and non-builtin but already evaluated
- resources.clear
- resources["one"] = mock("builtin (with eval)")
- resources["one"].expects(:builtin?).returns(true)
- resources["two"] = mock("evaled (with builtin)")
- resources["two"].expects(:builtin?).returns(false)
- resources["two"].expects(:evaluated?).returns(true)
- assert_nil(compile.send(:unevaluated_resources), "Considered either a builtin or evaluated resource unevaluated")
-
- # Now a single unevaluated resource.
- resources.clear
- resources["one"] = mock("unevaluated")
- resources["one"].expects(:builtin?).returns(false)
- resources["one"].expects(:evaluated?).returns(false)
- assert_equal([resources["one"]], compile.send(:unevaluated_resources), "Did not find unevaluated resource")
-
- # With two uneval'ed resources, and an eval'ed one thrown in
- resources.clear
- resources["one"] = mock("unevaluated one")
- resources["one"].expects(:builtin?).returns(false)
- resources["one"].expects(:evaluated?).returns(false)
- resources["two"] = mock("unevaluated two")
- resources["two"].expects(:builtin?).returns(false)
- resources["two"].expects(:evaluated?).returns(false)
- resources["three"] = mock("evaluated")
- resources["three"].expects(:builtin?).returns(false)
- resources["three"].expects(:evaluated?).returns(true)
-
- result = compile.send(:unevaluated_resources)
- %w{one two}.each do |name|
- assert(result.include?(resources[name]), "Did not find %s in the unevaluated list" % name)
- end
- end
-
- def test_evaluate_definitions
- # First try the case where there's nothing to return
- compile = mkcompile
- compile.expects(:unevaluated_resources).returns(nil)
-
- assert_nothing_raised("Could not test for unevaluated resources") do
- assert(! compile.send(:evaluate_definitions), "evaluate_definitions returned true when no resources were evaluated")
- end
-
- # Now try it with resources left to evaluate
- resources = []
- res1 = mock("resource1")
- res1.expects(:evaluate)
- res2 = mock("resource2")
- res2.expects(:evaluate)
- resources << res1 << res2
- compile = mkcompile
- compile.expects(:unevaluated_resources).returns(resources)
-
- assert_nothing_raised("Could not test for unevaluated resources") do
- assert(compile.send(:evaluate_definitions), "evaluate_definitions returned false when resources were evaluated")
- end
- end
-
- def test_evaluate_generators
- # First try the case where we have nothing to do
- compile = mkcompile
- compile.expects(:evaluate_definitions).returns(false)
- compile.expects(:evaluate_collections).returns(false)
-
- assert_nothing_raised("Could not call :eval_iterate") do
- compile.send(:evaluate_generators)
- end
-
- # FIXME I could not get this test to work, but the code is short
- # enough that I'm ok with it.
- # It's important that collections are evaluated before definitions,
- # so make sure that's the case by verifying that collections get tested
- # twice but definitions only once.
- #compile = mkcompile
- #compile.expects(:evaluate_collections).returns(true).returns(false)
- #compile.expects(:evaluate_definitions).returns(false)
- #compile.send(:eval_iterate)
- end
-
- def test_store
- compile = mkcompile
- Puppet.features.expects(:rails?).returns(true)
- Puppet::Rails.expects(:connect)
-
- node = mock 'node'
- resource_table = mock 'resources'
- resource_table.expects(:values).returns(:resources)
- compile.instance_variable_set("@node", node)
- compile.instance_variable_set("@resource_table", resource_table)
- compile.expects(:store_to_active_record).with(node, :resources)
- compile.send(:store)
- end
-
- def test_store_to_active_record
- compile = mkcompile
- node = mock 'node'
- node.expects(:name).returns("myname")
- Puppet::Rails::Host.stubs(:transaction).yields
- Puppet::Rails::Host.expects(:store).with(node, :resources)
- compile.send(:store_to_active_record, node, :resources)
- end
-
- # Make sure that 'finish' gets called on all of our resources.
- def test_finish
- compile = mkcompile
- table = compile.instance_variable_get("@resource_table")
-
- # Add a resource that does respond to :finish
- yep = mock("finisher")
- yep.expects(:respond_to?).with(:finish).returns(true)
- yep.expects(:finish)
- table["yep"] = yep
-
- # And one that does not
- dnf = mock("dnf")
- dnf.expects(:respond_to?).with(:finish).returns(false)
- table["dnf"] = dnf
-
- compile.send(:finish)
- end
-
- def test_verify_uniqueness
- compile = mkcompile
-
- resources = compile.instance_variable_get("@resource_table")
- resource = mock("noconflict")
- resource.expects(:ref).returns("File[yay]")
- assert_nothing_raised("Raised an exception when there should have been no conflict") do
- compile.send(:verify_uniqueness, resource)
- end
-
- # Now try the case where our type is isomorphic
- resources["thing"] = true
-
- isoconflict = mock("isoconflict")
- isoconflict.expects(:ref).returns("thing")
- isoconflict.expects(:type).returns("testtype")
- faketype = mock("faketype")
- faketype.expects(:isomorphic?).returns(false)
- faketype.expects(:name).returns("whatever")
- Puppet::Type.expects(:type).with("testtype").returns(faketype)
- assert_nothing_raised("Raised an exception when was a conflict in non-isomorphic types") do
- compile.send(:verify_uniqueness, isoconflict)
- end
-
- # Now test for when we actually have an exception
- initial = mock("initial")
- resources["thing"] = initial
- initial.expects(:file).returns(false)
-
- conflict = mock("conflict")
- conflict.expects(:ref).returns("thing").times(2)
- conflict.expects(:type).returns("conflict")
- conflict.expects(:file).returns(false)
- conflict.expects(:line).returns(false)
-
- faketype = mock("faketype")
- faketype.expects(:isomorphic?).returns(true)
- Puppet::Type.expects(:type).with("conflict").returns(faketype)
- assert_raise(Puppet::ParseError, "Did not fail when two isomorphic resources conflicted") do
- compile.send(:verify_uniqueness, conflict)
- end
- end
-
- def test_store_resource
- # Run once when there's no conflict
- compile = mkcompile
- table = compile.instance_variable_get("@resource_table")
- resource = mock("resource")
- resource.expects(:ref).returns("yay")
- compile.expects(:verify_uniqueness).with(resource)
- scope = stub("scope", :resource => mock('resource'))
-
- compile.catalog.expects(:add_edge!).with(scope.resource, resource)
-
- assert_nothing_raised("Could not store resource") do
- compile.store_resource(scope, resource)
- end
- assert_equal(resource, table["yay"], "Did not store resource in table")
-
- # Now for conflicts
- compile = mkcompile
- table = compile.instance_variable_get("@resource_table")
- resource = mock("resource")
- compile.expects(:verify_uniqueness).with(resource).raises(ArgumentError)
-
- assert_raise(ArgumentError, "Did not raise uniqueness exception") do
- compile.store_resource(scope, resource)
- end
- assert(table.empty?, "Conflicting resource was stored in table")
- end
-
- def test_fail_on_unevaluated
- compile = mkcompile
- compile.expects(:fail_on_unevaluated_overrides)
- compile.expects(:fail_on_unevaluated_resource_collections)
- compile.send :fail_on_unevaluated
- end
-
- def test_store_override
- # First test the case when the resource is not present.
- compile = mkcompile
- overrides = compile.instance_variable_get("@resource_overrides")
- override = Object.new
- override.expects(:ref).returns(:myref).times(2)
- override.expects(:override=).with(true)
-
- assert_nothing_raised("Could not call store_override") do
- compile.store_override(override)
- end
- assert_instance_of(Array, overrides[:myref], "Overrides table is not a hash of arrays")
- assert_equal(override, overrides[:myref][0], "Did not store override in appropriately named array")
-
- # And when the resource already exists.
- resource = mock 'resource'
- resources = compile.instance_variable_get("@resource_table")
- resources[:resref] = resource
-
- override = mock 'override'
- resource.expects(:merge).with(override)
- override.expects(:override=).with(true)
- override.expects(:ref).returns(:resref)
- assert_nothing_raised("Could not call store_override when the resource already exists.") do
- compile.store_override(override)
- end
- end
-
- def test_resource_overrides
- compile = mkcompile
- overrides = compile.instance_variable_get("@resource_overrides")
- overrides[:test] = :yay
- resource = mock 'resource'
- resource.expects(:ref).returns(:test)
-
- assert_equal(:yay, compile.resource_overrides(resource), "Did not return overrides from table")
- end
-
- def test_fail_on_unevaluated_resource_collections
- compile = mkcompile
- collections = compile.instance_variable_get("@collections")
-
- # Make sure we're fine when the list is empty
- assert_nothing_raised("Failed when no collections were present") do
- compile.send :fail_on_unevaluated_resource_collections
- end
-
- # And that we're fine when we've got collections but with no resources
- collections << mock('coll')
- collections[0].expects(:resources).returns(nil)
- assert_nothing_raised("Failed when no resource collections were present") do
- compile.send :fail_on_unevaluated_resource_collections
- end
-
- # But that we do fail when we've got resource collections left.
- collections.clear
-
- # return both an array and a string, because that's tested internally
- collections << mock('coll returns one')
- collections[0].expects(:resources).returns(:something)
-
- collections << mock('coll returns many')
- collections[1].expects(:resources).returns([:one, :two])
-
- assert_raise(Puppet::ParseError, "Did not fail on unevaluated resource collections") do
- compile.send :fail_on_unevaluated_resource_collections
- end
- end
-
- def test_fail_on_unevaluated_overrides
- compile = mkcompile
- overrides = compile.instance_variable_get("@resource_overrides")
-
- # Make sure we're fine when the list is empty
- assert_nothing_raised("Failed when no collections were present") do
- compile.send :fail_on_unevaluated_overrides
- end
-
- # But that we fail if there are any overrides left in the table.
- overrides[:yay] = []
- overrides[:foo] = []
- overrides[:bar] = [mock("override")]
- overrides[:bar][0].expects(:ref).returns("yay")
- assert_raise(Puppet::ParseError, "Failed to fail when overrides remain") do
- compile.send :fail_on_unevaluated_overrides
- end
- end
-
- def test_find_resource
- compile = mkcompile
- resources = compile.instance_variable_get("@resource_table")
-
- assert_nothing_raised("Could not call findresource when the resource table was empty") do
- assert_nil(compile.findresource("yay", "foo"), "Returned a non-existent resource")
- assert_nil(compile.findresource("yay[foo]"), "Returned a non-existent resource")
- end
-
- resources["Foo[bar]"] = :yay
- assert_nothing_raised("Could not call findresource when the resource table was not empty") do
- assert_equal(:yay, compile.findresource("foo", "bar"), "Returned a non-existent resource")
- assert_equal(:yay, compile.findresource("Foo[bar]"), "Returned a non-existent resource")
- end
- end
-
- # #620 - Nodes and classes should conflict, else classes don't get evaluated
- def test_nodes_and_classes_name_conflict
- # Test node then class
- compile = mkcompile
- node = stub :nodescope? => true
- klass = stub :nodescope? => false
- compile.class_set("one", node)
- assert_raise(Puppet::ParseError, "Did not fail when replacing node with class") do
- compile.class_set("one", klass)
- end
-
- # and class then node
- compile = mkcompile
- node = stub :nodescope? => true
- klass = stub :nodescope? => false
- compile.class_set("two", klass)
- assert_raise(Puppet::ParseError, "Did not fail when replacing node with class") do
- compile.class_set("two", node)
- end
- end
-end
diff --git a/test/language/functions.rb b/test/language/functions.rb
index 132ee97ac..a5d52d7ac 100755
--- a/test/language/functions.rb
+++ b/test/language/functions.rb
@@ -41,7 +41,7 @@ class TestLangFunctions < Test::Unit::TestCase
scope = mkscope
val = nil
assert_nothing_raised do
- val = func.evaluate(:scope => scope)
+ val = func.evaluate(scope)
end
assert_equal("output avalue", val)
@@ -57,7 +57,7 @@ class TestLangFunctions < Test::Unit::TestCase
val = nil
assert_nothing_raised do
- val = func.evaluate(:scope => scope)
+ val = func.evaluate(scope)
end
assert_equal(retval, val, "'tagged' returned %s for %s" % [val, tag])
@@ -66,7 +66,7 @@ class TestLangFunctions < Test::Unit::TestCase
# Now make sure we correctly get tags.
scope.resource.tag("resourcetag")
assert(scope.function_tagged("resourcetag"), "tagged function did not catch resource tags")
- scope.compile.catalog.tag("configtag")
+ scope.compiler.catalog.tag("configtag")
assert(scope.function_tagged("configtag"), "tagged function did not catch catalog tags")
end
@@ -86,7 +86,7 @@ class TestLangFunctions < Test::Unit::TestCase
scope = mkscope
val = nil
assert_raise(Puppet::ParseError) do
- val = func.evaluate(:scope => scope)
+ val = func.evaluate(scope)
end
end
@@ -117,16 +117,16 @@ class TestLangFunctions < Test::Unit::TestCase
scope = mkscope
assert_raise(Puppet::ParseError) do
- ast.evaluate(:scope => scope)
+ ast.evaluate(scope)
end
scope.setvar("one", "One")
assert_raise(Puppet::ParseError) do
- ast.evaluate(:scope => scope)
+ ast.evaluate(scope)
end
scope.setvar("two", "Two")
assert_nothing_raised do
- ast.evaluate(:scope => scope)
+ ast.evaluate(scope)
end
assert_equal("template One\ntemplate Two\n", scope.lookupvar("output"),
@@ -155,13 +155,13 @@ class TestLangFunctions < Test::Unit::TestCase
scope = mkscope
assert_raise(Puppet::ParseError) do
- ast.evaluate(:scope => scope)
+ ast.evaluate(scope)
end
scope.setvar("yayness", "this is yayness")
assert_nothing_raised do
- ast.evaluate(:scope => scope)
+ ast.evaluate(scope)
end
assert_equal("template this is yayness\n", scope.lookupvar("output"),
@@ -191,7 +191,7 @@ class TestLangFunctions < Test::Unit::TestCase
scope = mkscope
scope.setvar("myvar", "this is yayness")
assert_raise(Puppet::ParseError) do
- ast.evaluate(:scope => scope)
+ ast.evaluate(scope)
end
end
@@ -264,14 +264,14 @@ class TestLangFunctions < Test::Unit::TestCase
}.each do |string, value|
scope = mkscope
assert_raise(Puppet::ParseError) do
- ast.evaluate(:scope => scope)
+ ast.evaluate(scope)
end
scope.setvar("yayness", string)
assert_equal(string, scope.lookupvar("yayness", false))
assert_nothing_raised("An empty string was not a valid variable value") do
- ast.evaluate(:scope => scope)
+ ast.evaluate(scope)
end
assert_equal("template #{value}\n", scope.lookupvar("output"),
@@ -308,7 +308,7 @@ class TestLangFunctions < Test::Unit::TestCase
def test_realize
scope = mkscope
- parser = scope.compile.parser
+ parser = scope.compiler.parser
# Make a definition
parser.newdefine("mytype")
@@ -318,7 +318,7 @@ class TestLangFunctions < Test::Unit::TestCase
virtual = mkresource(:type => type, :title => title,
:virtual => true, :params => {}, :scope => scope)
- scope.compile.store_resource(scope, virtual)
+ scope.compiler.add_resource(scope, virtual)
ref = Puppet::Parser::Resource::Reference.new(
:type => type, :title => title,
@@ -330,13 +330,13 @@ class TestLangFunctions < Test::Unit::TestCase
end
# Make sure it created a collection
- assert_equal(1, scope.compile.collections.length,
+ assert_equal(1, scope.compiler.collections.length,
"Did not set collection")
assert_nothing_raised do
- scope.compile.collections.each do |coll| coll.evaluate end
+ scope.compiler.collections.each do |coll| coll.evaluate end
end
- scope.compile.collections.clear
+ scope.compiler.collections.clear
# Now make sure the virtual resource is no longer virtual
assert(! virtual.virtual?, "Did not make virtual resource real")
@@ -354,17 +354,17 @@ class TestLangFunctions < Test::Unit::TestCase
end
# Make sure it created a collection
- assert_equal(1, scope.compile.collections.length,
+ assert_equal(1, scope.compiler.collections.length,
"Did not set collection")
# And the collection has our resource in it
- assert_equal([none.to_s], scope.compile.collections[0].resources,
+ assert_equal([none.to_s], scope.compiler.collections[0].resources,
"Did not set resources in collection")
end
def test_defined
scope = mkscope
- parser = scope.compile.parser
+ parser = scope.compiler.parser
parser.newclass("yayness")
parser.newdefine("rahness")
@@ -385,7 +385,7 @@ class TestLangFunctions < Test::Unit::TestCase
"Multiple falses were somehow true")
# Now make sure we can test resources
- scope.compile.store_resource(scope, mkresource(:type => "file", :title => "/tmp/rahness",
+ scope.compiler.add_resource(scope, mkresource(:type => "file", :title => "/tmp/rahness",
:scope => scope, :source => scope.source,
:params => {:owner => "root"}))
@@ -420,7 +420,7 @@ class TestLangFunctions < Test::Unit::TestCase
def test_include
scope = mkscope
- parser = scope.compile.parser
+ parser = scope.compiler.parser
assert_raise(Puppet::ParseError, "did not throw error on missing class") do
scope.function_include("nosuchclass")
@@ -428,7 +428,7 @@ class TestLangFunctions < Test::Unit::TestCase
parser.newclass("myclass")
- scope.compile.expects(:evaluate_classes).with(%w{myclass otherclass}, scope, false).returns(%w{myclass otherclass})
+ scope.compiler.expects(:evaluate_classes).with(%w{myclass otherclass}, scope, false).returns(%w{myclass otherclass})
assert_nothing_raised do
scope.function_include(["myclass", "otherclass"])
@@ -480,7 +480,7 @@ class TestLangFunctions < Test::Unit::TestCase
assert_equal("yay-foo\n", %x{#{command} foo}, "command did not work")
scope = mkscope
- parser = scope.compile.parser
+ parser = scope.compiler.parser
val = nil
assert_nothing_raised("Could not call generator with no args") do
diff --git a/test/language/lexer.rb b/test/language/lexer.rb
deleted file mode 100755
index 5ac028052..000000000
--- a/test/language/lexer.rb
+++ /dev/null
@@ -1,275 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../lib/puppettest'
-
-require 'puppet'
-require 'puppet/parser/lexer'
-require 'puppettest'
-
-#%q{service("telnet") = \{
-# port => "23",
-# protocol => "tcp",
-# name => "telnet",
-#\}
-#} => [[:NAME, "service"], [:LPAREN, "("], [:DQUOTE, "\""], [:NAME, "telnet"], [:DQUOTE, "\""], [:RPAREN, ")"], [:EQUALS, "="], [:lbrace, "{"], [:NAME, "port"], [:FARROW, "=>"], [:DQUOTE, "\""], [:NAME, "23"], [:DQUOTE, "\""], [:COMMA, ","], [:NAME, "protocol"], [:FARROW, "=>"], [:DQUOTE, "\""], [:NAME, "tcp"], [:DQUOTE, "\""], [:COMMA, ","], [:NAME, "name"], [:FARROW, "=>"], [:DQUOTE, "\""], [:NAME, "telnet"], [:DQUOTE, "\""], [:COMMA, ","], [:RBRACE, "}"]]
-
-class TestLexer < Test::Unit::TestCase
- include PuppetTest
- def setup
- super
- mklexer
- end
-
- def mklexer
- @lexer = Puppet::Parser::Lexer.new()
- end
-
- def test_simple_lex
- strings = {
-%q{\\} => [[:BACKSLASH,"\\"],[false,false]],
-%q{simplest scanner test} => [[:NAME,"simplest"],[:NAME,"scanner"],[:NAME,"test"],[false,false]],
-%q{returned scanner test
-} => [[:NAME,"returned"],[:NAME,"scanner"],[:NAME,"test"],[false,false]]
- }
- strings.each { |str,ary|
- @lexer.string = str
- assert_equal(
- ary,
- @lexer.fullscan()
- )
- }
- end
-
- def test_quoted_strings
- strings = {
-%q{a simple "scanner" test
-} => [[:NAME,"a"],[:NAME,"simple"],[:DQTEXT,"scanner"],[:NAME,"test"],[false,false]],
-%q{a simple 'single quote scanner' test
-} => [[:NAME,"a"],[:NAME,"simple"],[:SQTEXT,"single quote scanner"],[:NAME,"test"],[false,false]],
-%q{a harder 'a $b \c"'
-} => [[:NAME,"a"],[:NAME,"harder"],[:SQTEXT,'a $b \c"'],[false,false]],
-%q{a harder "scanner test"
-} => [[:NAME,"a"],[:NAME,"harder"],[:DQTEXT,"scanner test"],[false,false]],
-%q{a hardest "scanner \"test\""
-} => [[:NAME,"a"],[:NAME,"hardest"],[:DQTEXT,'scanner "test"'],[false,false]],
-%q{a hardestest "scanner \"test\"
-"
-} => [[:NAME,"a"],[:NAME,"hardestest"],[:DQTEXT,'scanner "test"
-'],[false,false]],
-%q{function("call")} => [[:NAME,"function"],[:LPAREN,"("],[:DQTEXT,'call'],[:RPAREN,")"],[false,false]]
-}
- strings.each { |str,array|
- @lexer.string = str
- assert_equal(
- array,
- @lexer.fullscan()
- )
- }
- end
-
- def test_errors
- strings = %w{
- ^
- }
- strings.each { |str|
- @lexer.string = str
- assert_raise(RuntimeError) {
- @lexer.fullscan()
- }
- }
- end
-
- def test_more_error
- assert_raise(TypeError) {
- @lexer.fullscan()
- }
- end
-
- def test_files
- textfiles() { |file|
- lexer = Puppet::Parser::Lexer.new()
- lexer.file = file
- assert_nothing_raised("Failed to lex %s" % file) {
- lexer.fullscan()
- }
- }
- end
-
- def test_strings
- names = %w{this is a bunch of names}
- types = %w{Many Different Words A Word}
- words = %w{differently Cased words A a}
-
- names.each { |t|
- @lexer.string = t
- assert_equal(
- [[:NAME,t],[false,false]],
- @lexer.fullscan
- )
- }
- types.each { |t|
- @lexer.string = t
- assert_equal(
- [[:CLASSREF,t],[false,false]],
- @lexer.fullscan
- )
- }
- end
-
- def test_emptystring
- bit = '$var = ""'
-
- assert_nothing_raised {
- @lexer.string = bit
- }
-
- assert_nothing_raised {
- @lexer.fullscan
- }
- end
-
- def test_collectlexing
- {"@" => :AT, "<|" => :LCOLLECT, "|>" => :RCOLLECT}.each do |string, token|
- assert_nothing_raised {
- @lexer.string = string
- }
-
- ret = nil
- assert_nothing_raised {
- ret = @lexer.fullscan
- }
-
- assert_equal([[token, string],[false, false]], ret)
- end
- end
-
- def test_collectabletype
- string = "@type {"
-
- assert_nothing_raised {
- @lexer.string = string
- }
-
- ret = nil
- assert_nothing_raised {
- ret = @lexer.fullscan
- }
-
- assert_equal([[:AT, "@"], [:NAME, "type"], [:LBRACE, "{"], [false,false]],ret)
- end
-
- def test_namespace
- @lexer.string = %{class myclass}
-
- assert_nothing_raised {
- @lexer.fullscan
- }
-
- assert_equal("myclass", @lexer.namespace)
-
- assert_nothing_raised do
- @lexer.namepop
- end
-
- assert_equal("", @lexer.namespace)
-
- @lexer.string = "class base { class sub { class more"
-
- assert_nothing_raised {
- @lexer.fullscan
- }
-
- assert_equal("base::sub::more", @lexer.namespace)
-
- assert_nothing_raised do
- @lexer.namepop
- end
-
- assert_equal("base::sub", @lexer.namespace)
-
- # Now try it with some fq names
- mklexer
-
- @lexer.string = "class base { class sub::more {"
-
- assert_nothing_raised {
- @lexer.fullscan
- }
-
- assert_equal("base::sub::more", @lexer.namespace)
-
- assert_nothing_raised do
- @lexer.namepop
- end
-
- assert_equal("base", @lexer.namespace)
- end
-
- def test_indefine
- @lexer.string = %{define me}
-
- assert_nothing_raised {
- @lexer.scan { |t,s| }
- }
-
- assert(@lexer.indefine?, "Lexer not considered in define")
-
- # Now make sure we throw an error when trying to nest defines.
- assert_raise(Puppet::ParseError) do
- @lexer.string = %{define another}
- @lexer.scan { |t,s| }
- end
-
- assert_nothing_raised do
- @lexer.indefine = false
- end
-
- assert(! @lexer.indefine?, "Lexer still considered in define")
- end
-
- # Make sure the different qualified variables work.
- def test_variable
- ["$variable", "$::variable", "$qualified::variable", "$further::qualified::variable"].each do |string|
- @lexer.string = string
-
- assert_nothing_raised("Could not lex %s" % string) do
- @lexer.scan do |t, s|
- assert_equal(:VARIABLE, t, "did not get variable as token")
- assert_equal(string.sub(/^\$/, ''), s, "did not get correct string back")
- break
- end
- end
- end
- end
-
- # Make sure the expected stack works as it should
- def test_expected
- @lexer.string = "[a{"
- expected = @lexer.instance_variable_get("@expected")
- @lexer.scan {}
- assert_equal("}", @lexer.expected, "expected value is wrong")
-
- @lexer.string = "}"
- @lexer.scan {}
- assert_equal("]", @lexer.expected, "expected value is wrong after pop")
- end
-
- # #774
- def test_classref_token
- string = ["Foo", "::Foo","Foo::Bar","::Foo::Bar"]
-
- string.each do |foo|
- assert_nothing_raised {
- @lexer.string = foo
- }
-
- ret = nil
- assert_nothing_raised {
- ret = @lexer.fullscan
- }
-
- assert_equal([:CLASSREF, foo],ret[0], "Did not correctly tokenize '%s'" % foo)
- end
- end
-end
-
diff --git a/test/language/parser.rb b/test/language/parser.rb
index 6ff83054a..f7e7d8762 100755
--- a/test/language/parser.rb
+++ b/test/language/parser.rb
@@ -36,9 +36,9 @@ class TestParser < Test::Unit::TestCase
assert_raise(Puppet::ParseError, "Did not fail while parsing %s" % file) {
parser.file = file
ast = parser.parse
- config = mkcompile(parser)
+ config = mkcompiler(parser)
config.compile
- #ast.classes[""].evaluate :scope => config.topscope
+ #ast.classes[""].evaluate config.topscope
}
}
end
@@ -857,7 +857,7 @@ file { "/tmp/yayness":
def test_newclass
scope = mkscope
- parser = scope.compile.parser
+ parser = scope.compiler.parser
mkcode = proc do |ary|
classes = ary.collect do |string|
@@ -880,7 +880,7 @@ file { "/tmp/yayness":
assert(parser.classes["myclass"], "Could not find definition")
assert_equal("myclass", parser.classes["myclass"].classname)
assert_equal(%w{original code},
- parser.classes["myclass"].code.evaluate(:scope => scope))
+ parser.classes["myclass"].code.evaluate(scope))
# Newclass behaves differently than the others -- it just appends
# the code to the existing class.
@@ -890,7 +890,7 @@ file { "/tmp/yayness":
end
assert(klass, "Did not return class when appending")
assert_equal(%w{original code something new},
- parser.classes["myclass"].code.evaluate(:scope => scope))
+ parser.classes["myclass"].code.evaluate(scope))
# Now create the same class name in a different scope
assert_nothing_raised {
@@ -903,7 +903,7 @@ file { "/tmp/yayness":
assert_equal("other::myclass", other.classname)
assert_equal("other::myclass", other.namespace)
assert_equal(%w{something diff},
- other.code.evaluate(:scope => scope))
+ other.code.evaluate(scope))
# Make sure newclass deals correctly with nodes with no code
klass = parser.newclass("nocode")
@@ -914,7 +914,7 @@ file { "/tmp/yayness":
end
assert(klass, "Did not return class with no code")
assert_equal(%w{yay test},
- parser.classes["nocode"].code.evaluate(:scope => scope))
+ parser.classes["nocode"].code.evaluate(scope))
# Then try merging something into nothing
parser.newclass("nocode2", :code => mkcode.call(%w{foo test}))
@@ -925,7 +925,7 @@ file { "/tmp/yayness":
end
assert(klass, "Did not return class with no code")
assert_equal(%w{foo test},
- parser.classes["nocode2"].code.evaluate(:scope => scope))
+ parser.classes["nocode2"].code.evaluate(scope))
# And lastly, nothing and nothing
klass = parser.newclass("nocode3")
@@ -1130,6 +1130,7 @@ file { "/tmp/yayness":
name = "sub"
mk_module(modname, :init => %w{separate}, :sub => %w{separate::sub})
+ Puppet.err :yay
# First try it with a namespace
klass = parser.findclass("separate", name)
assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from separate file with a namespace")
@@ -1177,5 +1178,17 @@ file { "/tmp/yayness":
assert_equal(result, parser.finddefine("", "fUntEst"),
"%s was not matched" % "fUntEst")
end
+
+ def test_manifests_with_multiple_environments
+ parser = mkparser :environment => "something"
+
+ # We use an exception to cut short the processing to simplify our stubbing
+ #Puppet::Module.expects(:find_manifests).with("test", {:cwd => ".", :environment => "something"}).raises(Puppet::ParseError)
+ Puppet::Module.expects(:find_manifests).with("test", {:cwd => ".", :environment => "something"}).returns([])
+
+ assert_raise(Puppet::ImportError) do
+ parser.import("test")
+ end
+ end
end
diff --git a/test/language/resource.rb b/test/language/resource.rb
index 84a30b029..b3eaf0390 100755
--- a/test/language/resource.rb
+++ b/test/language/resource.rb
@@ -23,96 +23,6 @@ class TestResource < PuppetTest::TestCase
mocha_verify
end
- def test_initialize
- args = {:type => "resource", :title => "testing",
- :scope => mkscope}
- # Check our arg requirements
- args.each do |name, value|
- try = args.dup
- try.delete(name)
- assert_raise(ArgumentError, "Did not fail when %s was missing" % name) do
- Parser::Resource.new(try)
- end
- end
-
- res = nil
- assert_nothing_raised do
- res = Parser::Resource.new(args)
- end
-
- ref = res.instance_variable_get("@ref")
- assert_equal("Resource", ref.type, "did not set resource type")
- assert_equal("testing", ref.title, "did not set resource title")
- end
-
- def test_merge
- res = mkresource
- other = mkresource
-
- # First try the case where the resource is not allowed to override
- res.source = "source1"
- other.source = "source2"
- other.source.expects(:child_of?).with("source1").returns(false)
- assert_raise(Puppet::ParseError, "Allowed unrelated resources to override") do
- res.merge(other)
- end
-
- # Next try it when the sources are equal.
- res.source = "source3"
- other.source = res.source
- other.source.expects(:child_of?).with("source3").never
- params = {:a => :b, :c => :d}
- other.expects(:params).returns(params)
- res.expects(:override_parameter).with(:b)
- res.expects(:override_parameter).with(:d)
- res.merge(other)
-
- # And then parentage is involved
- other = mkresource
- res.source = "source3"
- other.source = "source4"
- other.source.expects(:child_of?).with("source3").returns(true)
- params = {:a => :b, :c => :d}
- other.expects(:params).returns(params)
- res.expects(:override_parameter).with(:b)
- res.expects(:override_parameter).with(:d)
- res.merge(other)
- end
-
- # the [] method
- def test_array_accessors
- res = mkresource
- params = res.instance_variable_get("@params")
- assert_nil(res[:missing], "Found a missing parameter somehow")
- params[:something] = stub(:value => "yay")
- assert_equal("yay", res[:something], "Did not correctly call value on the parameter")
-
- res.expects(:title).returns(:mytitle)
- assert_equal(:mytitle, res[:title], "Did not call title when asked for it as a param")
- end
-
- # Make sure any defaults stored in the scope get added to our resource.
- def test_add_defaults
- res = mkresource
- params = res.instance_variable_get("@params")
- params[:a] = :b
- res.scope.expects(:lookupdefaults).with(res.type).returns(:a => :replaced, :c => :d)
- res.expects(:debug)
-
- res.send(:add_defaults)
- assert_equal(:d, params[:c], "Did not set default")
- assert_equal(:b, params[:a], "Replaced parameter with default")
- end
-
- def test_finish
- res = mkresource
- res.expects(:add_overrides)
- res.expects(:add_defaults)
- res.expects(:add_metaparams)
- res.expects(:validate)
- res.finish
- end
-
# Make sure we paramcheck our params
def test_validate
res = mkresource
@@ -124,43 +34,6 @@ class TestResource < PuppetTest::TestCase
res.send(:validate)
end
- def test_override_parameter
- res = mkresource
- params = res.instance_variable_get("@params")
-
- # There are three cases, with the second having two options:
-
- # No existing parameter.
- param = stub(:name => "myparam")
- res.send(:override_parameter, param)
- assert_equal(param, params["myparam"], "Override was not added to param list")
-
- # An existing parameter that we can override.
- source = stub(:child_of? => true)
- # Start out without addition
- params["param2"] = stub(:source => :whatever)
- param = stub(:name => "param2", :source => source, :add => false)
- res.send(:override_parameter, param)
- assert_equal(param, params["param2"], "Override was not added to param list")
-
- # Try with addition.
- params["param2"] = stub(:value => :a, :source => :whatever)
- param = stub(:name => "param2", :source => source, :add => true, :value => :b)
- param.expects(:value=).with([:a, :b])
- res.send(:override_parameter, param)
- assert_equal(param, params["param2"], "Override was not added to param list")
-
- # And finally, make sure we throw an exception when the sources aren't related
- source = stub(:child_of? => false)
- params["param2"] = stub(:source => :whatever, :file => :f, :line => :l)
- old = params["param2"]
- param = stub(:name => "param2", :source => source, :file => :f, :line => :l)
- assert_raise(Puppet::ParseError, "Did not fail when params conflicted") do
- res.send(:override_parameter, param)
- end
- assert_equal(old, params["param2"], "Param was replaced irrespective of conflict")
- end
-
def test_set_parameter
res = mkresource
params = res.instance_variable_get("@params")
@@ -266,48 +139,12 @@ class TestResource < PuppetTest::TestCase
ref.expects(:definedtype).returns(type)
res.expects(:finish)
res.scope = mock("scope")
- config = mock("config")
- res.scope.expects(:compile).returns(config)
- config.expects(:delete_resource).with(res)
- args = {:scope => res.scope, :resource => res}
- type.expects(:evaluate).with(args)
+ type.expects(:evaluate_code).with(res)
res.evaluate
end
- def test_add_overrides
- # Try it with nil
- res = mkresource
- res.scope = mock('scope')
- config = mock("config")
- res.scope.expects(:compile).returns(config)
- config.expects(:resource_overrides).with(res).returns(nil)
- res.expects(:merge).never
- res.send(:add_overrides)
-
- # And an empty array
- res = mkresource
- res.scope = mock('scope')
- config = mock("config")
- res.scope.expects(:compile).returns(config)
- config.expects(:resource_overrides).with(res).returns([])
- res.expects(:merge).never
- res.send(:add_overrides)
-
- # And with some overrides
- res = mkresource
- res.scope = mock('scope')
- config = mock("config")
- res.scope.expects(:compile).returns(config)
- returns = %w{a b}
- config.expects(:resource_overrides).with(res).returns(returns)
- res.expects(:merge).with("a")
- res.expects(:merge).with("b")
- res.send(:add_overrides)
- assert(returns.empty?, "Did not clear overrides")
- end
-
def test_proxymethods
res = Parser::Resource.new :type => "evaltest", :title => "yay",
:source => mock("source"), :scope => mkscope
@@ -378,7 +215,7 @@ class TestResource < PuppetTest::TestCase
{:name => "one", :title => "two"},
{:title => "three"},
].each do |hash|
- config = mkcompile parser
+ config = mkcompiler parser
args = {:type => "yayness", :title => hash[:title],
:source => klass, :scope => config.topscope}
if hash[:name]
@@ -425,7 +262,7 @@ class TestResource < PuppetTest::TestCase
:code => resourcedef("file", varref("name"),
"mode" => "644"))
- config = mkcompile(parser)
+ config = mkcompiler(parser)
res = mkresource :type => "yayness", :title => "foo", :params => {}, :scope => config.topscope
res.virtual = true
@@ -457,37 +294,4 @@ class TestResource < PuppetTest::TestCase
assert(newres.exported?, "Exported defined resource generated non-exported resources")
assert(newres.virtual?, "Exported defined resource generated non-virtual resources")
end
-
- # Make sure tags behave appropriately.
- def test_tags
- scope_resource = stub 'scope_resource', :tags => %w{srone srtwo}
- scope = stub 'scope', :resource => scope_resource
- resource = Puppet::Parser::Resource.new(:type => "file", :title => "yay", :scope => scope, :source => mock('source'))
-
- # Make sure we get the scope resource's tags, plus the type and title
- %w{srone srtwo yay file}.each do |tag|
- assert(resource.tags.include?(tag), "Did not tag resource with %s" % tag)
- end
-
- # make sure we can only set legal tags
- ["an invalid tag", "-anotherinvalid", "bad*tag"].each do |tag|
- assert_raise(Puppet::ParseError, "Tag #{tag} was considered valid") do
- resource.tag tag
- end
- end
-
- # make sure good tags make it through.
- tags = %w{good-tag yaytag GoodTag another_tag a ab A}
- tags.each do |tag|
- assert_nothing_raised("Tag #{tag} was considered invalid") do
- resource.tag tag
- end
- end
-
- # make sure we get each of them.
- ptags = resource.tags
- tags.each do |tag|
- assert(ptags.include?(tag.downcase), "missing #{tag}")
- end
- end
end
diff --git a/test/language/scope.rb b/test/language/scope.rb
index ec11a864e..c96581a23 100755
--- a/test/language/scope.rb
+++ b/test/language/scope.rb
@@ -27,7 +27,7 @@ class TestScope < Test::Unit::TestCase
end
def test_variables
- config = mkcompile
+ config = mkcompiler
topscope = config.topscope
midscope = config.newscope(topscope)
botscope = config.newscope(midscope)
@@ -94,7 +94,7 @@ class TestScope < Test::Unit::TestCase
classes = ["", "one", "one::two", "one::two::three"].each do |name|
klass = parser.newclass(name)
Puppet::Parser::Resource.new(:type => "class", :title => name, :scope => scope, :source => mock('source')).evaluate
- scopes[name] = scope.compile.class_scope(klass)
+ scopes[name] = scope.compiler.class_scope(klass)
end
classes.each do |name|
@@ -125,7 +125,7 @@ class TestScope < Test::Unit::TestCase
end
def test_setdefaults
- config = mkcompile
+ config = mkcompiler
scope = config.topscope
@@ -151,7 +151,7 @@ class TestScope < Test::Unit::TestCase
end
def test_lookupdefaults
- config = mkcompile
+ config = mkcompiler
top = config.topscope
# Make a subscope
@@ -179,7 +179,7 @@ class TestScope < Test::Unit::TestCase
end
def test_parent
- config = mkcompile
+ config = mkcompiler
top = config.topscope
# Make a subscope
@@ -205,7 +205,7 @@ class TestScope < Test::Unit::TestCase
%w{one one::two one::two::three}.each do |name|
klass = parser.newclass(name)
Puppet::Parser::Resource.new(:type => "class", :title => name, :scope => scope, :source => mock('source')).evaluate
- scopes[name] = scope.compile.class_scope(klass)
+ scopes[name] = scope.compiler.class_scope(klass)
scopes[name].setvar("test", "value-%s" % name.sub(/.+::/,''))
end
@@ -284,13 +284,13 @@ class TestScope < Test::Unit::TestCase
)
assert_nothing_raised do
- function.evaluate :scope => scope
+ function.evaluate scope
end
- scope.compile.send(:evaluate_generators)
+ scope.compiler.send(:evaluate_generators)
[myclass, otherclass].each do |klass|
- assert(scope.compile.class_scope(klass),
+ assert(scope.compiler.class_scope(klass),
"%s was not set" % klass.classname)
end
end
@@ -328,18 +328,17 @@ class TestScope < Test::Unit::TestCase
"undef considered true")
end
- if defined? ActiveRecord
# Verify that we recursively mark as exported the results of collectable
# components.
- def test_exportedcomponents
- config = mkcompile
+ def test_virtual_definitions_do_not_get_evaluated
+ config = mkcompiler
parser = config.parser
# Create a default source
config.topscope.source = parser.newclass "", ""
# And a scope resource
- scope_res = stub 'scope_resource', :virtual? => true, :exported? => false, :tags => []
+ scope_res = stub 'scope_resource', :virtual? => true, :exported? => false, :tags => [], :builtin? => true, :type => "eh", :title => "bee"
config.topscope.resource = scope_res
args = AST::ASTArray.new(
@@ -348,7 +347,7 @@ class TestScope < Test::Unit::TestCase
:children => [nameobj("arg")]
)
- # Create a top-level component
+ # Create a top-level define
parser.newdefine "one", :arguments => [%w{arg}],
:code => AST::ASTArray.new(
:children => [
@@ -356,41 +355,26 @@ class TestScope < Test::Unit::TestCase
]
)
- # And a component that calls it
- parser.newdefine "two", :arguments => [%w{arg}],
- :code => AST::ASTArray.new(
- :children => [
- resourcedef("one", "ptest", {"arg" => varref("arg")})
- ]
- )
-
- # And then a third component that calls the second
- parser.newdefine "three", :arguments => [%w{arg}],
- :code => AST::ASTArray.new(
- :children => [
- resourcedef("two", "yay", {"arg" => varref("arg")})
- ]
- )
-
- # lastly, create an object that calls our third component
- obj = resourcedef("three", "boo", {"arg" => "parentfoo"})
+ # create a resource that calls our third define
+ obj = resourcedef("one", "boo", {"arg" => "parentfoo"})
- # And mark it as exported
- obj.exported = true
+ # And mark it as virtual
+ obj.virtual = true
# And then evaluate it
- obj.evaluate :scope => config.topscope
+ obj.evaluate config.topscope
# And run the loop.
config.send(:evaluate_generators)
%w{File}.each do |type|
- objects = config.resources.find_all { |r| r.type == type and r.exported }
+ objects = config.resources.find_all { |r| r.type == type and r.virtual }
- assert(!objects.empty?, "Did not get an exported %s" % type)
+ assert(objects.empty?, "Virtual define got evaluated")
end
end
+ if defined? ActiveRecord
# Verify that we can both store and collect an object in the same
# run, whether it's in the same scope as a collection or a different
# scope.
diff --git a/test/language/snippets.rb b/test/language/snippets.rb
index 01d77c265..95a518388 100755
--- a/test/language/snippets.rb
+++ b/test/language/snippets.rb
@@ -14,6 +14,7 @@ class TestSnippets < Test::Unit::TestCase
def setup
super
+ @file = Puppet::Type.type(:file)
Facter.stubs(:to_hash).returns({})
Facter.stubs(:value).returns("whatever")
end
@@ -422,6 +423,11 @@ class TestSnippets < Test::Unit::TestCase
assert_file("/tmp/realize_defined_test2")
end
+ def snippet_collection_within_virtual_definitions
+ assert_file("/tmp/collection_within_virtual_definitions1_foo.txt")
+ assert_file("/tmp/collection_within_virtual_definitions2_foo2.txt")
+ end
+
def snippet_fqparents
assert_file("/tmp/fqparent1", "Did not make file from parent class")
assert_file("/tmp/fqparent2", "Did not make file from subclass")
diff --git a/test/lib/mocha/expectation_error.rb b/test/lib/mocha/expectation_error.rb
deleted file mode 100644
index c01482e63..000000000
--- a/test/lib/mocha/expectation_error.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-module Mocha
-
- class ExpectationError < StandardError
- end
-
-end \ No newline at end of file
diff --git a/test/lib/mocha/missing_expectation.rb b/test/lib/mocha/missing_expectation.rb
deleted file mode 100644
index f84227d1a..000000000
--- a/test/lib/mocha/missing_expectation.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-require 'mocha/expectation'
-
-module Mocha # :nodoc:
-
- class MissingExpectation < Expectation # :nodoc:
-
- def initialize(mock, method_name)
- super
- @invoked_count = true
- end
-
- def verify
- msg = error_message(0, 1)
- similar_expectations_list = similar_expectations.collect { |expectation| expectation.method_signature }.join("\n")
- msg << "\nSimilar expectations:\n#{similar_expectations_list}" unless similar_expectations.empty?
- error = ExpectationError.new(msg)
- error.set_backtrace(filtered_backtrace)
- raise error if @invoked_count
- end
-
- def similar_expectations
- @mock.expectations.select { |expectation| expectation.method_name == self.method_name }
- end
-
- end
-
-end \ No newline at end of file
diff --git a/test/lib/mocha/parameter_matchers.rb b/test/lib/mocha/parameter_matchers.rb
deleted file mode 100644
index 193f77d93..000000000
--- a/test/lib/mocha/parameter_matchers.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-module Mocha
-
- # Used as parameters for Expectation#with to restrict the parameter values which will match the expectation.
- module ParameterMatchers; end
-
-end
-
-
-Dir[File.expand_path(File.join(File.dirname(__FILE__), 'parameter_matchers', "*.rb"))].each { |lib| require lib }
diff --git a/test/lib/puppettest.rb b/test/lib/puppettest.rb
index 68add6dd5..40764e38c 100755
--- a/test/lib/puppettest.rb
+++ b/test/lib/puppettest.rb
@@ -6,6 +6,17 @@ mainlib = File.expand_path(File.join(File.dirname(__FILE__), '../../lib'))
$LOAD_PATH.unshift(mainlib) unless $LOAD_PATH.include?(mainlib)
require 'puppet'
+
+# include any gems in vendor/gems
+Dir["#{mainlib}/../vendor/gems/**"].each do |path|
+ libpath = File.join(path, "lib")
+ if File.directory?(libpath)
+ $LOAD_PATH.unshift(libpath)
+ else
+ $LOAD_PATH.unshift(path)
+ end
+end
+
require 'mocha'
# Only load the test/unit class if we're not in the spec directory.
@@ -25,13 +36,17 @@ class Class
def publicize_methods(*methods)
saved_private_instance_methods = methods.empty? ? self.private_instance_methods : methods
- self.class_eval { public *saved_private_instance_methods }
+ self.class_eval { public(*saved_private_instance_methods) }
yield
- self.class_eval { private *saved_private_instance_methods }
+ self.class_eval { private(*saved_private_instance_methods) }
end
end
module PuppetTest
+ # These need to be here for when rspec tests use these
+ # support methods.
+ @@tmpfiles = []
+
# Munge cli arguments, so we can enable debugging if we want
# and so we can run just specific methods.
def self.munge_argv
@@ -178,7 +193,7 @@ module PuppetTest
Dir.mkdir(@configpath)
end
- @@tmpfiles = [@configpath, tmpdir()]
+ @@tmpfiles << @configpath << tmpdir()
@@tmppids = []
@@cleaners = []
@@ -187,7 +202,7 @@ module PuppetTest
# If we're running under rake, then disable debugging and such.
#if rake? or ! Puppet[:debug]
- if defined?($puppet_debug) or ! rake?
+ #if defined?($puppet_debug) or ! rake?
if textmate?
Puppet[:color] = false
end
@@ -199,11 +214,11 @@ module PuppetTest
end
Puppet::Util::Log.level = :debug
#$VERBOSE = 1
- else
- Puppet::Util::Log.close
- Puppet::Util::Log.newdestination(@logs)
- Puppet[:httplog] = tempfile()
- end
+ #else
+ # Puppet::Util::Log.close
+ # Puppet::Util::Log.newdestination(@logs)
+ # Puppet[:httplog] = tempfile()
+ #end
Puppet[:ignoreschedules] = true
@@ -256,11 +271,7 @@ module PuppetTest
@tmpdir
end
- def teardown
- #@stop = Time.now
- #File.open("/tmp/test_times.log", ::File::WRONLY|::File::CREAT|::File::APPEND) { |f| f.puts "%0.4f %s %s" % [@stop - @start, @method_name, self.class] }
- @@cleaners.each { |cleaner| cleaner.call() }
-
+ def remove_tmp_files
@@tmpfiles.each { |file|
unless file =~ /tmp/
puts "Not deleting tmpfile %s" % file
@@ -272,12 +283,21 @@ module PuppetTest
end
}
@@tmpfiles.clear
+ end
+
+ def teardown
+ #@stop = Time.now
+ #File.open("/tmp/test_times.log", ::File::WRONLY|::File::CREAT|::File::APPEND) { |f| f.puts "%0.4f %s %s" % [@stop - @start, @method_name, self.class] }
+ @@cleaners.each { |cleaner| cleaner.call() }
+
+ remove_tmp_files
@@tmppids.each { |pid|
%x{kill -INT #{pid} 2>/dev/null}
}
@@tmppids.clear
+
Puppet::Util::Storage.clear
Puppet.clear
Puppet.settings.clear
@@ -305,7 +325,6 @@ module PuppetTest
rescue Timeout::Error
# just move on
end
- mocha_verify
end
def logstore
diff --git a/test/lib/puppettest/parsertesting.rb b/test/lib/puppettest/parsertesting.rb
index 6fd60180a..1a08ecbae 100644
--- a/test/lib/puppettest/parsertesting.rb
+++ b/test/lib/puppettest/parsertesting.rb
@@ -5,7 +5,7 @@ module PuppetTest::ParserTesting
include PuppetTest
AST = Puppet::Parser::AST
- Compile = Puppet::Parser::Compile
+ Compiler = Puppet::Parser::Compiler
# A fake class that we can use for testing evaluation.
class FakeAST
@@ -41,10 +41,10 @@ module PuppetTest::ParserTesting
)
end
- def mkcompile(parser = nil)
+ def mkcompiler(parser = nil)
parser ||= mkparser
node = mknode
- return Compile.new(node, parser)
+ return Compiler.new(node, parser)
end
def mknode(name = nil)
@@ -58,21 +58,21 @@ module PuppetTest::ParserTesting
Puppet::Parser::Interpreter.new
end
- def mkparser
- Puppet::Parser::Parser.new()
+ def mkparser(args = {})
+ Puppet::Parser::Parser.new(args)
end
def mkscope(hash = {})
hash[:parser] ||= mkparser
- compile ||= mkcompile(hash[:parser])
- compile.topscope.source = (hash[:parser].findclass("", "") || hash[:parser].newclass(""))
+ compiler ||= mkcompiler(hash[:parser])
+ compiler.topscope.source = (hash[:parser].findclass("", "") || hash[:parser].newclass(""))
- unless compile.topscope.source
+ unless compiler.topscope.source
raise "Could not find source for scope"
end
# Make the 'main' stuff
- compile.send(:evaluate_main)
- compile.topscope
+ compiler.send(:evaluate_main)
+ compiler.topscope
end
def classobj(name, hash = {})
diff --git a/test/lib/puppettest/support/resources.rb b/test/lib/puppettest/support/resources.rb
index 384f61c33..255c55569 100755
--- a/test/lib/puppettest/support/resources.rb
+++ b/test/lib/puppettest/support/resources.rb
@@ -18,7 +18,7 @@ module PuppetTest::Support::Resources
if resource.is_a?(String)
resource = tree_resource(resource)
end
- config.add_edge!(comp, resource)
+ config.add_edge(comp, resource)
config.add_resource resource unless config.resource(resource.ref)
end
return comp
diff --git a/test/network/client/client.rb b/test/network/client/client.rb
index b6b915d31..5f96cac11 100755
--- a/test/network/client/client.rb
+++ b/test/network/client/client.rb
@@ -140,35 +140,6 @@ class TestClient < Test::Unit::TestCase
}
end
- def test_classfile
- Puppet[:code] = "class yaytest {}\n class bootest {}\n include yaytest, bootest"
-
- Puppet::Node::Facts.indirection.stubs(:save)
-
- master = client = nil
- assert_nothing_raised() {
- master = Puppet::Network::Handler.master.new(
- :Local => false
- )
- }
- assert_nothing_raised() {
- client = Puppet::Network::Client.master.new(
- :Master => master
- )
- }
-
- # Fake that it's local, so it creates the class file
- client.local = false
-
- # We can't guarantee class ordering
- client.expects(:setclasses).with do |array|
- array.length == 2 and array.include?("yaytest") and array.include?("bootest")
- end
- assert_nothing_raised {
- client.getconfig
- }
- end
-
def test_client_loading
# Make sure we don't get a failure but that we also get nothing back
assert_nothing_raised do
diff --git a/test/network/client/master.rb b/test/network/client/master.rb
index 48be3cafa..682d48eb5 100755
--- a/test/network/client/master.rb
+++ b/test/network/client/master.rb
@@ -211,6 +211,16 @@ end
"Lost value to hostname")
end
+ # Make sure that setting environment by fact takes precedence to configuration
+ def test_setenvironmentwithfact
+ name = "environment"
+ value = "test_environment"
+
+ Facter.stubs(:to_hash).returns(name => value)
+
+ assert_equal(value, Puppet::Network::Client.master.facts[name])
+ end
+
# Make sure we load all facts on startup.
def test_loadfacts
dirs = [tempfile(), tempfile()]
@@ -339,6 +349,8 @@ end
File.open(source, "w") { |f| f.puts "something" }
dest = tempfile
Puppet[:noop] = true
+ node = stub 'node', :environment => "development"
+ Puppet::Node.stubs(:find).returns node
assert_nothing_raised("Could not download in noop") do
@master.download(:dest => dest, :source => source, :tag => "yay")
end
@@ -546,4 +558,33 @@ end
# Doesn't throw an exception, but definitely fails.
client.run
end
+
+ def test_classfile
+ Puppet[:code] = "class yaytest {}\n class bootest {}\n include yaytest, bootest"
+
+ Puppet::Node::Facts.indirection.stubs(:save)
+
+ master = client = nil
+ assert_nothing_raised() {
+ master = Puppet::Network::Handler.master.new(
+ :Local => false
+ )
+ }
+ assert_nothing_raised() {
+ client = Puppet::Network::Client.master.new(
+ :Master => master
+ )
+ }
+
+ # Fake that it's local, so it creates the class file
+ client.local = false
+
+ # We can't guarantee class ordering
+ client.expects(:setclasses).with do |array|
+ array.length == 2 and array.include?("yaytest") and array.include?("bootest")
+ end
+ assert_nothing_raised {
+ client.getconfig
+ }
+ end
end
diff --git a/test/network/handler/fileserver.rb b/test/network/handler/fileserver.rb
index e4b1ac3df..b3a9aef2b 100755
--- a/test/network/handler/fileserver.rb
+++ b/test/network/handler/fileserver.rb
@@ -109,13 +109,13 @@ class TestFileServer < Test::Unit::TestCase
# and verify different iterations of 'root' return the same value
list = nil
assert_nothing_raised {
- list = server.list("/test/", :ignore, true, false)
+ list = server.list("/test/", :manage, true, false)
}
assert(list =~ pattern)
assert_nothing_raised {
- list = server.list("/test", :ignore, true, false)
+ list = server.list("/test", :manage, true, false)
}
assert(list =~ pattern)
@@ -143,7 +143,7 @@ class TestFileServer < Test::Unit::TestCase
list = nil
sfile = "/test/tmpfile"
assert_nothing_raised {
- list = server.list(sfile, :ignore, true, false)
+ list = server.list(sfile, :manage, true, false)
}
output = "/\tfile"
@@ -196,7 +196,7 @@ class TestFileServer < Test::Unit::TestCase
list = nil
sfile = "/test/"
assert_nothing_raised {
- list = server.list(sfile, :ignore, true, false)
+ list = server.list(sfile, :manage, true, false)
}
# create the new file
@@ -206,7 +206,7 @@ class TestFileServer < Test::Unit::TestCase
newlist = nil
assert_nothing_raised {
- newlist = server.list(sfile, :ignore, true, false)
+ newlist = server.list(sfile, :manage, true, false)
}
# verify the list has changed
@@ -235,12 +235,12 @@ class TestFileServer < Test::Unit::TestCase
list = nil
assert_nothing_raised {
- list = server.list("/root/" + testdir, :ignore, true, false)
+ list = server.list("/root/" + testdir, :manage, true, false)
}
assert(list =~ pattern)
assert_nothing_raised {
- list = server.list("/root" + testdir, :ignore, true, false)
+ list = server.list("/root" + testdir, :manage, true, false)
}
assert(list =~ pattern)
@@ -275,7 +275,7 @@ class TestFileServer < Test::Unit::TestCase
# get our list
list = nil
assert_nothing_raised {
- list = server.list("/test/with", :ignore, false, false)
+ list = server.list("/test/with", :manage, false, false)
}
# make sure we only got one line, since we're not recursing
@@ -284,7 +284,7 @@ class TestFileServer < Test::Unit::TestCase
# for each level of recursion, make sure we get the right list
[0, 1, 2].each { |num|
assert_nothing_raised {
- list = server.list("/test/with", :ignore, num, false)
+ list = server.list("/test/with", :manage, num, false)
}
count = 0
@@ -328,13 +328,13 @@ class TestFileServer < Test::Unit::TestCase
list = nil
# and then check a few dirs
assert_nothing_raised {
- list = server.list("/localhost/with", :ignore, false, false)
+ list = server.list("/localhost/with", :manage, false, false)
}
assert(list !~ /with/)
assert_nothing_raised {
- list = server.list("/localhost/with/some/sub", :ignore, true, false)
+ list = server.list("/localhost/with/some/sub", :manage, true, false)
}
assert(list !~ /sub/)
@@ -366,7 +366,7 @@ class TestFileServer < Test::Unit::TestCase
list = nil
assert_nothing_raised {
- list = server.list("/localhost/", :ignore, 1, false)
+ list = server.list("/localhost/", :manage, 1, false)
}
assert_instance_of(String, list, "Server returned %s instead of string")
list = list.split("\n")
@@ -398,7 +398,7 @@ class TestFileServer < Test::Unit::TestCase
list = nil
sfile = "/test/"
assert_nothing_raised {
- list = server.list(sfile, :ignore, true, false)
+ list = server.list(sfile, :manage, true, false)
}
# and describe each file in the list
@@ -488,7 +488,7 @@ class TestFileServer < Test::Unit::TestCase
mounts.each { |mount, files|
mount = "/#{mount}/"
assert_nothing_raised {
- list = server.list(mount, :ignore, true, false)
+ list = server.list(mount, :manage, true, false)
}
assert_nothing_raised {
@@ -540,12 +540,12 @@ class TestFileServer < Test::Unit::TestCase
assert_raise(Puppet::AuthorizationError,
"Host %s, ip %s, allowed %s" %
[host, ip, mount]) {
- list = server.list(mount, :ignore, true, false, host, ip)
+ list = server.list(mount, :manage, true, false, host, ip)
}
when :allow:
assert_nothing_raised("Host %s, ip %s, denied %s" %
[host, ip, mount]) {
- list = server.list(mount, :ignore, true, false, host, ip)
+ list = server.list(mount, :manage, true, false, host, ip)
}
end
}
@@ -598,7 +598,7 @@ class TestFileServer < Test::Unit::TestCase
assert_raise(Puppet::Network::Handler::FileServerError,
"Invalid mount was mounted") {
- server.list(mount, :ignore)
+ server.list(mount, :manage)
}
}
@@ -650,13 +650,13 @@ class TestFileServer < Test::Unit::TestCase
list = nil
assert_nothing_raised {
- list = server.list("/thing/", :ignore, false, false,
+ list = server.list("/thing/", :manage, false, false,
"test1.domain.com", "127.0.0.1")
}
assert(list != "", "List returned nothing in rereard test")
assert_raise(Puppet::AuthorizationError, "List allowed invalid host") {
- list = server.list("/thing/", :ignore, false, false,
+ list = server.list("/thing/", :manage, false, false,
"test2.domain.com", "127.0.0.1")
}
@@ -671,12 +671,12 @@ class TestFileServer < Test::Unit::TestCase
}
assert_raise(Puppet::AuthorizationError, "List allowed invalid host") {
- list = server.list("/thing/", :ignore, false, false,
+ list = server.list("/thing/", :manage, false, false,
"test1.domain.com", "127.0.0.1")
}
assert_nothing_raised {
- list = server.list("/thing/", :ignore, false, false,
+ list = server.list("/thing/", :manage, false, false,
"test2.domain.com", "127.0.0.1")
}
@@ -731,7 +731,7 @@ class TestFileServer < Test::Unit::TestCase
# Then not
results = {}
assert_nothing_raised {
- server.describe("/mount/link", :ignore).split("\t").zip(
+ server.describe("/mount/link", :manage).split("\t").zip(
Puppet::Network::Handler.fileserver::CHECKPARAMS
).each { |v,p| results[p] = v }
}
@@ -797,28 +797,28 @@ allow *
list = nil
sfile = "/host/file.txt"
assert_nothing_raised {
- list = server.list(sfile, :ignore, true, false, client1, ip)
+ list = server.list(sfile, :manage, true, false, client1, ip)
}
assert_equal("/\tfile", list)
assert_nothing_raised {
- list = server.list(sfile, :ignore, true, false, client2, ip)
+ list = server.list(sfile, :manage, true, false, client2, ip)
}
assert_equal("", list)
sfile = "/fqdn/file.txt"
assert_nothing_raised {
- list = server.list(sfile, :ignore, true, false, client1, ip)
+ list = server.list(sfile, :manage, true, false, client1, ip)
}
assert_equal("", list)
assert_nothing_raised {
- list = server.list(sfile, :ignore, true, false, client2, ip)
+ list = server.list(sfile, :manage, true, false, client2, ip)
}
assert_equal("/\tfile", list)
# check describe
sfile = "/host/file.txt"
assert_nothing_raised {
- list = server.describe(sfile, :ignore, client1, ip).split("\t")
+ list = server.describe(sfile, :manage, client1, ip).split("\t")
}
assert_equal(5, list.size)
assert_equal("file", list[1])
@@ -826,18 +826,18 @@ allow *
assert_equal("{md5}#{md5}", list[4])
assert_nothing_raised {
- list = server.describe(sfile, :ignore, client2, ip).split("\t")
+ list = server.describe(sfile, :manage, client2, ip).split("\t")
}
assert_equal([], list)
sfile = "/fqdn/file.txt"
assert_nothing_raised {
- list = server.describe(sfile, :ignore, client1, ip).split("\t")
+ list = server.describe(sfile, :manage, client1, ip).split("\t")
}
assert_equal([], list)
assert_nothing_raised {
- list = server.describe(sfile, :ignore, client2, ip).split("\t")
+ list = server.describe(sfile, :manage, client2, ip).split("\t")
}
assert_equal(5, list.size)
assert_equal("file", list[1])
@@ -847,23 +847,23 @@ allow *
# Check retrieve
sfile = "/host/file.txt"
assert_nothing_raised {
- list = server.retrieve(sfile, :ignore, client1, ip).chomp
+ list = server.retrieve(sfile, :manage, client1, ip).chomp
}
assert_equal(contents[client1_hostdir].chomp, list)
assert_nothing_raised {
- list = server.retrieve(sfile, :ignore, client2, ip).chomp
+ list = server.retrieve(sfile, :manage, client2, ip).chomp
}
assert_equal("", list)
sfile = "/fqdn/file.txt"
assert_nothing_raised {
- list = server.retrieve(sfile, :ignore, client1, ip).chomp
+ list = server.retrieve(sfile, :manage, client1, ip).chomp
}
assert_equal("", list)
assert_nothing_raised {
- list = server.retrieve(sfile, :ignore, client2, ip).chomp
+ list = server.retrieve(sfile, :manage, client2, ip).chomp
}
assert_equal(contents[client2_fqdndir].chomp, list)
end
@@ -941,12 +941,14 @@ allow *
# Now, check that they use Facter info
Puppet.notice "The following messages are normal"
client = nil
- local = Facter["hostname"].value
- domain = Facter["domain"].value
- fqdn = [local, domain].join(".")
- {"%h" => local, # Short name
- "%H" => fqdn, # Full name
- "%d" => domain, # domain
+ Facter.stubs(:value).with(:ipaddress).returns("127.0.0.1")
+ Facter.stubs(:value).with { |v| v.to_s == "hostname" }.returns("myhost")
+ Facter.stubs(:value).with { |v| v.to_s == "domain" }.returns("mydomain.com")
+ Facter.stubs(:value).with(:domain).returns("mydomain.com")
+
+ {"%h" => "myhost", # Short name
+ "%H" => "myhost.mydomain.com", # Full name
+ "%d" => "mydomain.com", # domain
"%%" => "%", # escape
"%o" => "%o" # other
}.each do |pat, repl|
@@ -989,18 +991,18 @@ allow *
ret = nil
assert_nothing_raised do
- ret = server.list("/name", :ignore, false, false, host, ip)
+ ret = server.list("/name", :manage, false, false, host, ip)
end
assert_equal("/\tfile", ret)
assert_nothing_raised do
- ret = server.describe("/name", :ignore, host, ip)
+ ret = server.describe("/name", :manage, host, ip)
end
- assert(ret =~ /\tfile\t/, "Did not get valid a description")
+ assert(ret =~ /\tfile\t/, "Did not get valid a description (#{ret.inspect})")
assert_nothing_raised do
- ret = server.retrieve("/name", :ignore, host, ip)
+ ret = server.retrieve("/name", :manage, host, ip)
end
assert_equal(ret, File.read(file))
@@ -1046,7 +1048,7 @@ allow *
mount = "/#{mod.name}/"
list = nil
assert_nothing_raised {
- list = server.list(mount, :ignore, true, false)
+ list = server.list(mount, :manage, true, false)
}
list = list.split("\n")
if mod.name == "green"
@@ -1059,7 +1061,7 @@ allow *
end
assert_nothing_raised("Host 'allow' denied #{mount}") {
- server.list(mount, :ignore, true, false,
+ server.list(mount, :manage, true, false,
'allow.example.com', "192.168.0.1")
}
end
@@ -1102,7 +1104,7 @@ allow *
list = nil
mount = "/#{mod.name}/"
assert_nothing_raised {
- list = server.list(mount, :ignore, true, false)
+ list = server.list(mount, :manage, true, false)
}
assert_nothing_raised {
@@ -1117,11 +1119,11 @@ allow *
# now let's check that things are being correctly forbidden
assert_raise(Puppet::AuthorizationError,
"Host 'deny' allowed #{mount}") {
- server.list(mount, :ignore, true, false,
+ server.list(mount, :manage, true, false,
'deny.example.com', "192.168.1.1")
}
assert_nothing_raised("Host 'allow' denied #{mount}") {
- server.list(mount, :ignore, true, false,
+ server.list(mount, :manage, true, false,
'allow.example.com', "192.168.0.1")
}
end
diff --git a/test/network/handler/master.rb b/test/network/handler/master.rb
index 25117030e..55522237b 100755
--- a/test/network/handler/master.rb
+++ b/test/network/handler/master.rb
@@ -76,18 +76,29 @@ class TestMaster < Test::Unit::TestCase
Puppet[:node_name] = "cert"
# Make sure we get the fact data back when nothing is set
- facts = {"hostname" => "fact_hostname", "ipaddress" => "fact_ip"}
- certname = "cert_hostname"
+ facts = {
+ "hostname" => "fact_hostname",
+ "domain" => "fact_domain",
+ "fqdn" => "fact_hostname.fact_domain",
+ "ipaddress" => "fact_ip"
+ }
+ certhostname = "cert_hostname"
+ certdomain = "cert_domain"
+ certname = certhostname + "." + certdomain
certip = "cert_ip"
resname, resip = master.send(:clientname, nil, nil, facts)
assert_equal(facts["hostname"], resname, "Did not use fact hostname when no certname was present")
assert_equal(facts["ipaddress"], resip, "Did not use fact ip when no certname was present")
+ assert_equal(facts["domain"], "fact_domain", "Did not use fact domain when no certname was present")
+ assert_equal(facts["fqdn"], "fact_hostname.fact_domain", "Did not use fact fqdn when no certname was present")
# Now try it with the cert stuff present
resname, resip = master.send(:clientname, certname, certip, facts)
assert_equal(certname, resname, "Did not use cert hostname when certname was present")
assert_equal(certip, resip, "Did not use cert ip when certname was present")
+ assert_equal(facts["domain"], certdomain, "Did not use cert domain when certname was present")
+ assert_equal(facts["fqdn"], certname, "Did not use cert fqdn when certname was present")
# And reset the node_name stuff and make sure we use it.
Puppet[:node_name] = :facter
diff --git a/test/network/server/webrick.rb b/test/network/server/webrick.rb
index e44d84dda..f4e5398b8 100755
--- a/test/network/server/webrick.rb
+++ b/test/network/server/webrick.rb
@@ -95,7 +95,7 @@ class TestWebrickServer < Test::Unit::TestCase
# the client starts its connection immediately, thus throwing
# the error.
assert_raise(OpenSSL::SSL::SSLError) {
- client = Puppet::Network::Client.status.new(:Server => "localhost", :Port => @@port)
+ Puppet::Network::HttpPool.http_instance("localhost", @@port).start
}
end
diff --git a/test/other/dsl.rb b/test/other/dsl.rb
index b4dd0659b..45b51982d 100755
--- a/test/other/dsl.rb
+++ b/test/other/dsl.rb
@@ -12,7 +12,7 @@ class TestDSL < Test::Unit::TestCase
def teardown
super
- Puppet::Aspect.clear
+ Puppet::DSL::Aspect.clear
end
def test_aspect
@@ -22,7 +22,7 @@ class TestDSL < Test::Unit::TestCase
end
end
- assert_equal(a, Puppet::Aspect[:yaytest])
+ assert_equal(a, Puppet::DSL::Aspect[:yaytest])
# Now make a child aspect
b = nil
@@ -154,8 +154,7 @@ class TestDSL < Test::Unit::TestCase
resource = nil
assert_nothing_raised do
- resource = a.newresource filetype, path,
- :content => "yay", :mode => "640"
+ resource = a.newresource filetype, path, :content => "yay", :mode => "640"
end
assert_instance_of(Puppet::Parser::Resource, resource)
diff --git a/test/other/transactions.rb b/test/other/transactions.rb
index 649a3cd32..8cae3388b 100755
--- a/test/other/transactions.rb
+++ b/test/other/transactions.rb
@@ -350,12 +350,12 @@ class TestTransactions < Test::Unit::TestCase
fcomp = Puppet::Type.type(:component).create(:name => "file")
config.add_resource fcomp
config.add_resource file
- config.add_edge!(fcomp, file)
+ config.add_edge(fcomp, file)
ecomp = Puppet::Type.type(:component).create(:name => "exec")
config.add_resource ecomp
config.add_resource exec
- config.add_edge!(ecomp, exec)
+ config.add_edge(ecomp, exec)
# 'subscribe' expects an array of arrays
#component[:require] = [[file.class.name,file.name]]
@@ -826,10 +826,10 @@ class TestTransactions < Test::Unit::TestCase
c = trigger.new(:c)
nope = Puppet::Relationship.new(a, b)
yep = Puppet::Relationship.new(a, c, {:callback => :refresh})
- graph.add_edge!(nope)
+ graph.add_edge(nope)
# And a triggering one.
- graph.add_edge!(yep)
+ graph.add_edge(yep)
# Create our transaction
trans = Puppet::Transaction.new(graph)
diff --git a/test/rails/ast.rb b/test/rails/ast.rb
index e51fa6cf7..1deaec0f4 100755
--- a/test/rails/ast.rb
+++ b/test/rails/ast.rb
@@ -44,12 +44,12 @@ class TestRailsAST < PuppetTest::TestCase
# And if it is, make sure we throw an error.
if bad
assert_raise(Puppet::ParseError, "Evaluated '#{string}'") do
- str, code = query.evaluate :scope => @scope
+ str, code = query.evaluate @scope
end
next
else
assert_nothing_raised("Could not evaluate '#{string}'") do
- str, code = query.evaluate :scope => @scope
+ str, code = query.evaluate @scope
end
end
assert_nothing_raised("Could not find resource") do
diff --git a/test/rails/configuration.rb b/test/rails/configuration.rb
index 9e2ddfedd..a878d1381 100755
--- a/test/rails/configuration.rb
+++ b/test/rails/configuration.rb
@@ -24,7 +24,7 @@ class ConfigurationRailsTests < PuppetTest::TestCase
# We need to make sure finished objects are stored in the db.
def test_finish_before_store
railsinit
- compile = mkcompile
+ compile = mkcompiler
parser = compile.parser
node = parser.newnode [compile.node.name], :code => AST::ASTArray.new(:children => [
diff --git a/test/rails/railsparameter.rb b/test/rails/railsparameter.rb
index d83115b1a..7c99ac38d 100755
--- a/test/rails/railsparameter.rb
+++ b/test/rails/railsparameter.rb
@@ -25,6 +25,8 @@ class TestRailsParameter < Test::Unit::TestCase
source = parser.newclass "myclass"
host = Puppet::Rails::Host.new(:name => "myhost")
+
+ host.save
resource = host.resources.create(
:title => "/tmp/to_resource",
diff --git a/test/rails/railsresource.rb b/test/rails/railsresource.rb
index 58058472d..3df5001be 100755
--- a/test/rails/railsresource.rb
+++ b/test/rails/railsresource.rb
@@ -29,6 +29,7 @@ class TestRailsResource < Test::Unit::TestCase
def mktest_resource
# We need a host for resources
host = Puppet::Rails::Host.new(:name => "myhost")
+ host.save
# Now build a resource
resource = host.resources.create(
diff --git a/test/ral/manager/provider.rb b/test/ral/manager/provider.rb
index bb7a21485..89aa49b9e 100755
--- a/test/ral/manager/provider.rb
+++ b/test/ral/manager/provider.rb
@@ -73,11 +73,6 @@ class TestTypeProviders < Test::Unit::TestCase
confine :exists => "/no/such/file"
end
- inst = provider.new(:name => "bar")
- assert_raise(Puppet::Error, "Did not fail on unsuitable provider instance") do
- resource = @type.create :name => "bar", :provider => inst
- end
-
# And make sure the provider must be a valid provider type for this resource
pkgprov = Puppet::Type.type(:package).create(:name => "yayness").provider
assert(provider, "did not get package provider")
@@ -87,5 +82,26 @@ class TestTypeProviders < Test::Unit::TestCase
end
end
+
+ # #571 -- so we can cause a provider to become suitable within
+ # a run.
+ def test_unsuitable_providers_should_not_fail_at_initialization
+ Puppet::Type.type(:user).provider(:useradd).stubs(:suitable?).returns false
+
+ assert_nothing_raised("Unsuitable providers failed at initialization") do
+ Puppet::Type.type(:user).create :name => "luke", :ensure => :present, :provider => :useradd
+ end
+ end
+
+ # #571 -- so we can cause a provider to become suitable within
+ # a run.
+ def test_unsuitable_providers_should_fail_at_evaluation
+ Puppet::Type.type(:user).provider(:useradd).stubs(:suitable?).returns false
+
+ user = Puppet::Type.type(:user).create :name => "luke", :ensure => :present, :provider => :useradd
+ assert_raise(Puppet::Error, "Unsuitable provider did not fail at evaluation") do
+ user.evaluate
+ end
+ end
end
diff --git a/test/ral/manager/type.rb b/test/ral/manager/type.rb
index bb13a7b78..f3a116f6f 100755
--- a/test/ral/manager/type.rb
+++ b/test/ral/manager/type.rb
@@ -477,8 +477,8 @@ class TestType < Test::Unit::TestCase
assert_equal(greater, type.defaultprovider)
end
- # Make sure that we can have multiple isomorphic objects with the same name,
- # but not with non-isomorphic objects.
+ # Make sure that we can have multiple non-isomorphic objects with the same name,
+ # but not with isomorphic objects.
def test_isomorphic_names
catalog = mk_catalog
# First do execs, since they're not isomorphic.
@@ -562,22 +562,6 @@ class TestType < Test::Unit::TestCase
assert_equal("Exec[yay]", exec.ref)
end
- def test_noop_metaparam
- file = Puppet::Type.newfile :path => tempfile
- assert(!file.noop, "file incorrectly in noop")
-
- assert_nothing_raised do
- file[:noop] = true
- end
- assert(file.noop, "file should be in noop")
-
- # Now set the main one
- Puppet[:noop] = true
- assert(file.noop, "file should be in noop")
- file[:noop] = false
- assert(file.noop, "file should be in noop")
- end
-
def test_path
config = mk_catalog
@@ -592,7 +576,7 @@ class TestType < Test::Unit::TestCase
res = type.create(hash)
config.add_resource res
if parent
- config.add_edge!(parent, res)
+ config.add_edge(parent, res)
end
res
end
@@ -625,7 +609,7 @@ class TestType < Test::Unit::TestCase
newcomp = Puppet::Type.newcomponent :type => "yay", :name => "Good[bad]"
config.add_resource newcomp
- config.add_edge! comp, newcomp
+ config.add_edge comp, newcomp
exec = mk.call(6, :parent => newcomp)
assert_equal("//Good[bad]/Exec[exec6]", exec.path)
end
diff --git a/test/ral/providers/cron/crontab.rb b/test/ral/providers/cron/crontab.rb
index 2da4b1b57..53bd76c50 100755
--- a/test/ral/providers/cron/crontab.rb
+++ b/test/ral/providers/cron/crontab.rb
@@ -5,7 +5,6 @@ require File.dirname(__FILE__) + '/../../../lib/puppettest'
require 'puppettest'
require 'mocha'
require 'puppettest/fileparsing'
-require 'puppet/type/cron'
class TestCronParsedProvider < Test::Unit::TestCase
include PuppetTest
@@ -344,7 +343,9 @@ class TestCronParsedProvider < Test::Unit::TestCase
end
end
- # Make sure we can create a cron in an empty tab
+ # Make sure we can create a cron in an empty tab.
+ # LAK:FIXME This actually modifies the user's crontab,
+ # which is pretty heinous.
def test_mkcron_if_empty
setme
@provider.filetype = @oldfiletype
diff --git a/test/ral/providers/mailalias/aliases.rb b/test/ral/providers/mailalias/aliases.rb
index 663d4359c..ec8b84684 100755
--- a/test/ral/providers/mailalias/aliases.rb
+++ b/test/ral/providers/mailalias/aliases.rb
@@ -4,7 +4,6 @@ require File.dirname(__FILE__) + '/../../../lib/puppettest'
require 'puppettest'
require 'puppettest/fileparsing'
-require 'puppet/type/mailalias'
class TestMailaliasAliasesProvider < Test::Unit::TestCase
include PuppetTest
diff --git a/test/ral/providers/sshkey/parsed.rb b/test/ral/providers/sshkey/parsed.rb
index b94b7a69a..4f18e6494 100755
--- a/test/ral/providers/sshkey/parsed.rb
+++ b/test/ral/providers/sshkey/parsed.rb
@@ -4,7 +4,6 @@ require File.dirname(__FILE__) + '/../../../lib/puppettest'
require 'puppettest'
require 'puppettest/fileparsing'
-require 'puppet/type/sshkey'
class TestParsedSSHKey < Test::Unit::TestCase
include PuppetTest
diff --git a/test/ral/types/basic.rb b/test/ral/type/basic.rb
index e46d96d1c..3c5faeee0 100755
--- a/test/ral/types/basic.rb
+++ b/test/ral/type/basic.rb
@@ -36,8 +36,13 @@ class TestBasic < Test::Unit::TestCase
)
}
@config = mk_catalog(@component, @configfile, @command)
- @config.add_edge! @component, @configfile
- @config.add_edge! @component, @command
+ @config.add_edge @component, @configfile
+ @config.add_edge @component, @command
+ end
+
+ def teardown
+ super
+ stopservices
end
def test_values
@@ -63,6 +68,13 @@ class TestBasic < Test::Unit::TestCase
assert_equal("echo", @command.title)
end
+ def test_object_retrieval
+ [@command, @configfile].each { |obj|
+ assert_equal(obj.class[obj.name].object_id, obj.object_id,
+ "%s did not match class version" % obj.ref)
+ }
+ end
+
def test_paths
[@configfile, @command, @component].each { |obj|
assert_nothing_raised {
diff --git a/test/ral/types/cron.rb b/test/ral/type/cron.rb
index 8e3d25350..8e3d25350 100755
--- a/test/ral/types/cron.rb
+++ b/test/ral/type/cron.rb
diff --git a/test/ral/types/exec.rb b/test/ral/type/exec.rb
index 976e3f3ab..3444b1312 100755
--- a/test/ral/types/exec.rb
+++ b/test/ral/type/exec.rb
@@ -200,7 +200,6 @@ class TestExec < Test::Unit::TestCase
comp = mk_catalog("Testing", file, exec)
- Facter.stubs(:to_hash).returns({})
assert_events([:file_created, :executed_command], comp)
end
@@ -239,8 +238,6 @@ class TestExec < Test::Unit::TestCase
:command => "cat %s %s" % [exe, oexe],
:path => ENV["PATH"]
)
-
- catalog = mk_catalog(file, baseobj, ofile, exec, cat)
rels = nil
assert_nothing_raised do
@@ -350,6 +347,10 @@ class TestExec < Test::Unit::TestCase
if user
assert_equal(user.uid, File.stat(file).uid, "File UIDs do not match")
end
+
+ # We can't actually test group ownership, unfortunately, because
+ # behaviour changes wildlly based on platform.
+ Puppet::Type.allclear
end
def test_userngroup
@@ -389,8 +390,8 @@ class TestExec < Test::Unit::TestCase
assert_apply(exec)
assert_nothing_raised {
- exec[:command] = "echo logoutput is warning"
- exec[:logoutput] = "warning"
+ exec[:command] = "echo logoutput is on_failure"
+ exec[:logoutput] = "on_failure"
}
assert_apply(exec)
@@ -582,6 +583,46 @@ and stuff"
assert_equal("A B\n", output)
end
+ def test_environmentparam
+ exec = Puppet::Type.newexec(
+ :command => "echo $environmenttest",
+ :path => ENV["PATH"],
+ :environment => "environmenttest=yayness"
+ )
+
+ assert(exec, "Could not make exec")
+
+ output = status = nil
+ assert_nothing_raised {
+ output, status = exec.run("echo $environmenttest")
+ }
+
+ assert_equal("yayness\n", output)
+
+ # Now check whether we can do multiline settings
+ assert_nothing_raised do
+ exec[:environment] = "environmenttest=a list of things
+and stuff"
+ end
+
+ output = status = nil
+ assert_nothing_raised {
+ output, status = exec.run('echo "$environmenttest"')
+ }
+ assert_equal("a list of things\nand stuff\n", output)
+
+ # Now test arrays
+ assert_nothing_raised do
+ exec[:environment] = ["funtest=A", "yaytest=B"]
+ end
+
+ output = status = nil
+ assert_nothing_raised {
+ output, status = exec.run('echo "$funtest" "$yaytest"')
+ }
+ assert_equal("A B\n", output)
+ end
+
def test_timeout
exec = Puppet::Type.type(:exec).create(:command => "sleep 1", :path => ENV["PATH"], :timeout => "0.2")
time = Time.now
diff --git a/test/ral/types/file.rb b/test/ral/type/file.rb
index aaf007e24..fc7c39796 100755
--- a/test/ral/types/file.rb
+++ b/test/ral/type/file.rb
@@ -9,9 +9,7 @@ require 'fileutils'
class TestFile < Test::Unit::TestCase
include PuppetTest::Support::Utils
include PuppetTest::FileTesting
- # hmmm
- # this is complicated, because we store references to the created
- # objects in a central store
+
def mkfile(hash)
file = nil
assert_nothing_raised {
@@ -21,8 +19,6 @@ class TestFile < Test::Unit::TestCase
end
def mktestfile
- # because luke's home directory is on nfs, it can't be used for testing
- # as root
tmpfile = tempfile()
File.open(tmpfile, "w") { |f| f.puts rand(100) }
@@tmpfiles.push tmpfile
@@ -181,7 +177,7 @@ class TestFile < Test::Unit::TestCase
assert_equal(inituser, File.stat(file).uid)
obj.delete(:owner)
- obj[:links] = :ignore
+ obj[:links] = :follow
# And then test 'group'
group = nonrootgroup
@@ -189,12 +185,6 @@ class TestFile < Test::Unit::TestCase
initgroup = File.stat(file).gid
obj[:group] = group.name
- assert_events([:file_changed], obj)
- assert_equal(initgroup, File.stat(file).gid)
- assert_equal(group.gid, File.lstat(link).gid)
- File.chown(nil, initgroup, file)
- File.lchown(nil, initgroup, link)
-
obj[:links] = :follow
assert_events([:file_changed], obj)
assert_equal(group.gid, File.stat(file).gid)
@@ -407,8 +397,7 @@ class TestFile < Test::Unit::TestCase
assert(events)
- assert(! events.include?(:file_changed),
- "File incorrectly changed")
+ assert(! events.include?(:file_changed), "File incorrectly changed")
assert_events([], file)
# We have to sleep because the time resolution of the time-based
@@ -1001,66 +990,6 @@ class TestFile < Test::Unit::TestCase
"directory mode is incorrect")
end
- def test_followlinks
- File.umask(0022)
-
- basedir = tempfile()
- Dir.mkdir(basedir)
- file = File.join(basedir, "file")
- link = File.join(basedir, "link")
-
- File.open(file, "w", 0644) { |f| f.puts "yayness"; f.flush }
- File.symlink(file, link)
-
- obj = nil
- assert_nothing_raised {
- obj = Puppet.type(:file).create(
- :path => link,
- :mode => "755"
- )
- }
- obj.retrieve
-
- assert_events([], obj)
-
- # Assert that we default to not following links
- assert_equal("%o" % 0644, "%o" % (File.stat(file).mode & 007777))
-
- # Assert that we can manage the link directly, but modes still don't change
- obj[:links] = :manage
- assert_events([], obj)
-
- assert_equal("%o" % 0644, "%o" % (File.stat(file).mode & 007777))
-
- obj[:links] = :follow
- assert_events([:file_changed], obj)
-
- assert_equal("%o" % 0755, "%o" % (File.stat(file).mode & 007777))
-
- # Now verify that content and checksum don't update, either
- obj.delete(:mode)
- obj[:checksum] = "md5"
- obj[:links] = :ignore
-
- assert_events([], obj)
- File.open(file, "w") { |f| f.puts "more text" }
- assert_events([], obj)
- obj[:links] = :follow
- assert_events([], obj)
- File.open(file, "w") { |f| f.puts "even more text" }
- assert_events([:file_changed], obj)
-
- obj.delete(:checksum)
- obj[:content] = "this is some content"
- obj[:links] = :ignore
-
- assert_events([], obj)
- File.open(file, "w") { |f| f.puts "more text" }
- assert_events([], obj)
- obj[:links] = :follow
- assert_events([:file_changed], obj)
- end
-
# If both 'ensure' and 'content' are used, make sure that all of the other
# properties are handled correctly.
def test_contentwithmode
@@ -1244,6 +1173,7 @@ class TestFile < Test::Unit::TestCase
:title => "localfile",
:path => localfile,
:content => "rahtest",
+ :ensure => :file,
:backup => false
)
@@ -1256,8 +1186,8 @@ class TestFile < Test::Unit::TestCase
config.apply
assert(FileTest.exists?(dsourcefile), "File did not get copied")
- assert(FileTest.exists?(localfile), "File did not get created")
- assert(FileTest.exists?(purgee), "File got prematurely purged")
+ assert(FileTest.exists?(localfile), "Local file did not get created")
+ assert(FileTest.exists?(purgee), "Purge target got prematurely purged")
assert_nothing_raised { destobj[:purge] = true }
config.apply
@@ -1337,8 +1267,7 @@ class TestFile < Test::Unit::TestCase
File.symlink(dir, link)
File.open(file, "w") { |f| f.puts "" }
assert_equal(dir, File.readlink(link))
- obj = Puppet::Type.newfile :path => link, :ensure => :link,
- :target => file, :recurse => false, :backup => "main"
+ obj = Puppet::Type.newfile :path => link, :ensure => :link, :target => file, :recurse => false, :backup => "main"
catalog = mk_catalog(bucket, obj)
@@ -1774,5 +1703,26 @@ class TestFile < Test::Unit::TestCase
obj = Puppet::Type.newfile(:path => '/', :mode => 0755)
assert_equal("/", obj.title, "/ directory was changed to empty string")
end
-end
+ # #1010 and #1037 -- write should fail if the written checksum does not
+ # match the file we thought we were writing.
+ def test_write_validates_checksum
+ file = tempfile
+ inst = Puppet::Type.newfile(:path => file, :content => "something")
+
+ tmpfile = file + ".puppettmp"
+
+ wh = mock 'writehandle', :print => nil
+ rh = mock 'readhandle'
+ rh.expects(:read).with(512).times(2).returns("other").then.returns(nil)
+ File.expects(:open).with { |*args| args[0] == tmpfile and args[1] != "r" }.yields(wh)
+ File.expects(:open).with { |*args| args[0] == tmpfile and args[1] == "r" }.yields(rh)
+
+ File.stubs(:rename)
+ FileTest.stubs(:exist?).returns(true)
+ FileTest.stubs(:file?).returns(true)
+
+ inst.expects(:fail)
+ inst.write("something", :whatever)
+ end
+end
diff --git a/test/ral/types/file/target.rb b/test/ral/type/file/target.rb
index b6c84df99..b6c84df99 100755
--- a/test/ral/types/file/target.rb
+++ b/test/ral/type/file/target.rb
diff --git a/test/ral/types/filebucket.rb b/test/ral/type/filebucket.rb
index 28be67b0c..28be67b0c 100755
--- a/test/ral/types/filebucket.rb
+++ b/test/ral/type/filebucket.rb
diff --git a/test/ral/types/fileignoresource.rb b/test/ral/type/fileignoresource.rb
index 996bca424..996bca424 100755
--- a/test/ral/types/fileignoresource.rb
+++ b/test/ral/type/fileignoresource.rb
diff --git a/test/ral/types/filesources.rb b/test/ral/type/filesources.rb
index f21fc9b20..f21fc9b20 100755
--- a/test/ral/types/filesources.rb
+++ b/test/ral/type/filesources.rb
diff --git a/test/ral/types/group.rb b/test/ral/type/group.rb
index 3c29fe505..3c29fe505 100755
--- a/test/ral/types/group.rb
+++ b/test/ral/type/group.rb
diff --git a/test/ral/types/host.rb b/test/ral/type/host.rb
index d44fe888c..124563cbc 100755
--- a/test/ral/types/host.rb
+++ b/test/ral/type/host.rb
@@ -54,6 +54,19 @@ class TestHost < Test::Unit::TestCase
return host
end
+ def test_list
+ assert_nothing_raised do
+ @hosttype.defaultprovider.prefetch
+ end
+
+ count = 0
+ @hosttype.each do |h|
+ count += 1
+ end
+
+ assert_equal(0, count, "Found hosts in empty file somehow")
+ end
+
# Darwin will actually write to netinfo here.
if Facter.value(:operatingsystem) != "Darwin" or Process.uid == 0
def test_simplehost
@@ -125,8 +138,68 @@ class TestHost < Test::Unit::TestCase
host[:ensure] = :absent
assert_events([:host_removed], host)
end
+
+ def test_invalid_ipaddress
+ host = mkhost()
+
+ assert_raise(Puppet::Error) {
+ host[:ip] = "abc.def.ghi.jkl"
+ }
+ end
+
+ def test_invalid_hostname
+ host = mkhost()
+
+ assert_raise(Puppet::Error) {
+ host[:name] = "!invalid.hostname.$$$"
+ }
+
+ assert_raise(Puppet::Error) {
+ host[:name] = "-boo"
+ }
+
+ assert_raise(Puppet::Error) {
+ host[:name] = "boo-.ness"
+ }
+
+ assert_raise(Puppet::Error) {
+ host[:name] = "boo..ness"
+ }
+ end
+
+ def test_valid_hostname
+ host = mkhost()
+
+ assert_nothing_raised {
+ host[:name] = "yayness"
+ }
+
+ assert_nothing_raised {
+ host[:name] = "yay-ness"
+ }
+
+ assert_nothing_raised {
+ host[:name] = "yay.ness"
+ }
+
+ assert_nothing_raised {
+ host[:name] = "yay.ne-ss"
+ }
+
+ assert_nothing_raised {
+ host[:name] = "y.ay-ne-ss.com"
+ }
+
+ assert_nothing_raised {
+ host[:name] = "y4y.n3-ss"
+ }
+
+ assert_nothing_raised {
+ host[:name] = "y"
+ }
end
+ end
def test_aliasisproperty
assert_equal(:property, @hosttype.attrtype(:alias))
end
diff --git a/test/ral/types/mailalias.rb b/test/ral/type/mailalias.rb
index ff1dd562a..ff1dd562a 100755
--- a/test/ral/types/mailalias.rb
+++ b/test/ral/type/mailalias.rb
diff --git a/test/ral/types/parameter.rb b/test/ral/type/parameter.rb
index 04c4b0ce1..04c4b0ce1 100755
--- a/test/ral/types/parameter.rb
+++ b/test/ral/type/parameter.rb
diff --git a/test/ral/types/port.rb b/test/ral/type/port.rb
index e28904d55..e28904d55 100755
--- a/test/ral/types/port.rb
+++ b/test/ral/type/port.rb
diff --git a/test/ral/types/property.rb b/test/ral/type/property.rb
index 6a3370caa..6a3370caa 100755
--- a/test/ral/types/property.rb
+++ b/test/ral/type/property.rb
diff --git a/test/ral/types/resources.rb b/test/ral/type/resources.rb
index 0663fe795..0663fe795 100755
--- a/test/ral/types/resources.rb
+++ b/test/ral/type/resources.rb
diff --git a/test/ral/types/service.rb b/test/ral/type/service.rb
index 01533c63e..01533c63e 100755
--- a/test/ral/types/service.rb
+++ b/test/ral/type/service.rb
diff --git a/test/ral/types/sshkey.rb b/test/ral/type/sshkey.rb
index 333bc377d..333bc377d 100755
--- a/test/ral/types/sshkey.rb
+++ b/test/ral/type/sshkey.rb
diff --git a/test/ral/types/tidy.rb b/test/ral/type/tidy.rb
index 4e3bb53b7..a3a3b4b01 100755
--- a/test/ral/types/tidy.rb
+++ b/test/ral/type/tidy.rb
@@ -75,7 +75,7 @@ class TestTidy < Test::Unit::TestCase
# Test the different age iterations.
def test_age_conversions
- tidy = Puppet::Type.newtidy :path => tempfile(), :age => "1m"
+ tidy = Puppet::Type.type(:tidy).create :path => tempfile(), :age => "1m"
convertors = {
:second => 1,
@@ -118,7 +118,7 @@ class TestTidy < Test::Unit::TestCase
:gb => 3
}
- tidy = Puppet::Type.newtidy :path => tempfile(), :age => "1m"
+ tidy = Puppet::Type.type(:tidy).create :path => tempfile(), :age => "1m"
# First make sure we default to kb
assert_nothing_raised do
@@ -148,7 +148,7 @@ class TestTidy < Test::Unit::TestCase
end
def test_agetest
- tidy = Puppet::Type.newtidy :path => tempfile(), :age => "1m"
+ tidy = Puppet::Type.type(:tidy).create :path => tempfile(), :age => "1m"
age = tidy.property(:age)
@@ -160,7 +160,7 @@ class TestTidy < Test::Unit::TestCase
end
def test_sizetest
- tidy = Puppet::Type.newtidy :path => tempfile(), :size => "1k"
+ tidy = Puppet::Type.type(:tidy).create :path => tempfile(), :size => "1k"
size = tidy.property(:size)
@@ -174,7 +174,7 @@ class TestTidy < Test::Unit::TestCase
# Make sure we can remove different types of files
def test_tidytypes
path = tempfile()
- tidy = Puppet::Type.newtidy :path => path, :size => "1b", :age => "1s"
+ tidy = Puppet::Type.type(:tidy).create :path => path, :size => "1b", :age => "1s"
# Start with a file
File.open(path, "w") { |f| f.puts "this is a test" }
@@ -229,7 +229,7 @@ class TestTidy < Test::Unit::TestCase
Dir.mkdir(dir)
File.symlink(target, link)
- tidy = Puppet::Type.newtidy :path => dir, :size => "1b", :recurse => true
+ tidy = Puppet::Type.type(:tidy).create :path => dir, :size => "1b", :recurse => true
assert_apply(tidy)
assert(! FileTest.symlink?(link), "link was not tidied")
end
diff --git a/test/ral/types/user.rb b/test/ral/type/user.rb
index ec9b12923..ec9b12923 100755
--- a/test/ral/types/user.rb
+++ b/test/ral/type/user.rb
diff --git a/test/ral/types/yumrepo.rb b/test/ral/type/yumrepo.rb
index 65c4cb50c..899a02135 100755
--- a/test/ral/types/yumrepo.rb
+++ b/test/ral/type/yumrepo.rb
@@ -19,10 +19,6 @@ class TestYumRepo < Test::Unit::TestCase
Puppet.type(:yumrepo).yumconf = @yumconf
end
- def teardown
- Puppet.type(:yumrepo).clear
- end
-
# Modify one existing section
def test_modify
copy_datafiles
diff --git a/test/ral/types/zone.rb b/test/ral/type/zone.rb
index eb485b944..eb485b944 100755
--- a/test/ral/types/zone.rb
+++ b/test/ral/type/zone.rb
diff --git a/test/util/autoload.rb b/test/util/autoload.rb
index 6babed774..de503ab99 100755
--- a/test/util/autoload.rb
+++ b/test/util/autoload.rb
@@ -103,10 +103,10 @@ TestAutoload.newthing(:#{name.to_s})
assert(loader.send(:searchpath).include?(dir), "searchpath does not include the libdir")
end
- # This causes very strange behaviour in the tests. We need to make sure we
- # require the same path that a user would use, otherwise we'll result in
- # a reload of the
- def test_require_does_not_cause_reload
+ # This tests #1027, which was caused by using the unqualified
+ # path for requires, which was initially done so that the kernel
+ # would keep track of which files got loaded.
+ def test_require_uses_full_path
loadname = "testing"
loader = Puppet::Util::Autoload.new(self.class, loadname)
@@ -120,7 +120,26 @@ TestAutoload.newthing(:#{name.to_s})
Dir.expects(:glob).with("#{dir}/*.rb").returns(file)
- Kernel.expects(:require).with(File.join(loadname, subname))
+ Kernel.expects(:require).with(file)
loader.loadall
end
+
+ def test_searchpath_includes_plugin_dirs
+ moddir = "/what/ever"
+ libdir = "/other/dir"
+ Puppet.settings.stubs(:value).with(:modulepath).returns(moddir)
+ Puppet.settings.stubs(:value).with(:libdir).returns(libdir)
+
+ loadname = "testing"
+ loader = Puppet::Util::Autoload.new(self.class, loadname)
+
+ # Currently, include both plugins and libs.
+ paths = %w{plugins lib}.inject({}) { |hash, d| hash[d] = File.join(moddir, "testing", d); FileTest.stubs(:directory?).with(hash[d]).returns(true); hash }
+ Dir.expects(:glob).with("#{moddir}/*/{plugins,lib}").returns(paths.values)
+
+ searchpath = loader.searchpath
+ paths.each do |dir, path|
+ assert(searchpath.include?(path), "search path did not include path for %s" % dir)
+ end
+ end
end
diff --git a/test/util/settings.rb b/test/util/settings.rb
index cf5dca76d..de6fff946 100755
--- a/test/util/settings.rb
+++ b/test/util/settings.rb
@@ -256,69 +256,6 @@ yay = /a/path
end
end
- def test_old_parse
- text = %{
-one = this is a test
-two = another test
-owner = root
-group = root
-yay = /a/path
-
-[section1]
- attr = value
- owner = puppet
- group = puppet
- attrdir = /some/dir
- attr3 = $attrdir/other
- }
-
- file = tempfile()
- File.open(file, "w") { |f| f.puts text }
-
- assert_nothing_raised {
- @config.setdefaults("puppet",
- :one => ["a", "one"],
- :two => ["a", "two"],
- :yay => ["/default/path", "boo"],
- :mkusers => [true, "uh, yeah"]
- )
- }
-
- assert_nothing_raised {
- @config.setdefaults("section1",
- :attr => ["a", "one"],
- :attrdir => ["/another/dir", "two"],
- :attr3 => ["$attrdir/maybe", "boo"]
- )
- }
-
- assert_nothing_raised {
- @config.old_parse(file)
- }
-
- assert_equal("value", @config[:attr])
- assert_equal("/some/dir", @config[:attrdir])
- assert_equal(:directory, @config.element(:attrdir).type)
- assert_equal("/some/dir/other", @config[:attr3])
-
- elem = nil
- assert_nothing_raised {
- elem = @config.element(:attr3)
- }
-
- assert(elem)
- assert_equal("puppet", elem.owner)
-
- config = nil
- assert_nothing_raised {
- config = @config.to_config
- }
-
- assert_nothing_raised("Could not create transportable config") {
- @config.to_transportable
- }
- end
-
def test_parse
result = {
:main => {:main => "main", :bad => "invalid", :cliparam => "reset"},
diff --git a/vendor/gems/mocha-0.5.6/._RELEASE b/vendor/gems/mocha-0.5.6/._RELEASE
new file mode 100644
index 000000000..12bf79cb2
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/._RELEASE
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/._Rakefile b/vendor/gems/mocha-0.5.6/._Rakefile
new file mode 100644
index 000000000..22220c1ee
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/._Rakefile
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/COPYING b/vendor/gems/mocha-0.5.6/COPYING
new file mode 100644
index 000000000..8f74d7116
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/COPYING
@@ -0,0 +1,3 @@
+Copyright Revieworld Ltd. 2006
+
+You may use, copy and redistribute this library under the same terms as Ruby itself (see http://www.ruby-lang.org/en/LICENSE.txt) or under the MIT license (see MIT-LICENSE file).
diff --git a/vendor/gems/mocha-0.5.6/MIT-LICENSE b/vendor/gems/mocha-0.5.6/MIT-LICENSE
new file mode 100644
index 000000000..fa4efe793
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/MIT-LICENSE
@@ -0,0 +1,7 @@
+Copyright (c) 2006 Revieworld Ltd.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/README b/vendor/gems/mocha-0.5.6/README
new file mode 100644
index 000000000..262c6ec27
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/README
@@ -0,0 +1,35 @@
+= Mocha
+
+Mocha is a library for mocking and stubbing using a syntax like that of JMock[http://www.jmock.org], and SchMock[http://rubyforge.org/projects/schmock]. Most commonly Mocha is used in conjunction with Test::Unit[http://www.ruby-doc.org/core/classes/Test/Unit.html], but it can be used in other contexts.
+
+One of its main advantages is that it allows you to mock and stub methods on _real_ (non-mock) classes and instances. You can for example stub ActiveRecord[http://api.rubyonrails.com/classes/ActiveRecord/Base.html] instance methods like +create+, +save+, +destroy+ and even class methods like +find+ to avoid hitting the database in unit tests.
+
+Mocha provides a unified, simple and readable syntax for both traditional mocking and for mocking with _real_ objects.
+
+Mocha has been harvested from projects at Reevoo[http://www.reevoo.com] by me (James[http://blog.floehopper.org]) and my colleagues Ben[http://www.reevoo.com/blogs/bengriffiths], Chris[http://blog.seagul.co.uk] and Paul[http://po-ru.com]. Mocha is in use on real-world Rails[http://www.rubyonrails.org] projects.
+
+== Download and Installation
+
+Install the gem with the following command...
+
+ $ gem install mocha
+
+Or install the Rails[http://www.rubyonrails.org] plugin...
+
+ $ script/plugin install svn://rubyforge.org/var/svn/mocha/trunk
+
+Or download Mocha from here - http://rubyforge.org/projects/mocha
+
+== Examples
+
+* Quick Start - {Usage Examples}[link:examples/misc.html]
+* Traditional mocking - {Star Trek Example}[link:examples/mocha.html]
+* Setting expectations on real classes - {Order Example}[link:examples/stubba.html]
+* More examples on {Floehopper's Blog}[http://blog.floehopper.org]
+* {Mailing List Archives}[http://rubyforge.org/pipermail/mocha-developer/]
+
+== License
+
+Copyright Revieworld Ltd. 2006
+
+You may use, copy and redistribute this library under the same terms as {Ruby itself}[http://www.ruby-lang.org/en/LICENSE.txt] or under the {MIT license}[http://mocha.rubyforge.org/files/MIT-LICENSE.html]. \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/RELEASE b/vendor/gems/mocha-0.5.6/RELEASE
new file mode 100644
index 000000000..0e8fb8573
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/RELEASE
@@ -0,0 +1,188 @@
+= 0.5.5 (r167)
+
+- Renamed Matches parameter matcher to RegexpMatches for clarity.
+- Added noframes tag to rdoc index to assist Google.
+
+= 0.5.4 (r166)
+
+- Added matches parameter matcher for matching regular expressions.
+
+= 0.5.3 (r165)
+
+- Attempt to fix packaging problems by switching to newer version (1.15.1) of gnutar and setting COPY_EXTENDED_ATTRIBUTES_DISABLE environment variable.
+- Removed unused ExpectationSequenceError exception.
+- Added instance_of and kind_of parameter matchers.
+- Added Google Webmaster meta tag to rdoc template header.
+- Put Google Webmaster meta tag in the right header i.e. the one for the index page.
+
+= 0.5.2 (r159)
+
+- Fix bug 11885 - "never doesn't work with stub_everything" submitted by Alexander Lang. In fixing this bug, also fixed undiscoverd bug where expected & actual invocation counts were being incorrectly reported which seems to have been introduced when fixes were added for invocation dispatch (see MockedMethodDispatchAcceptanceTest).
+- Previously when an expectation did not allow more invocations, it was treated as not matching. Now we prefer matching expectations which allow more invocations, but still match expectations which cannot allow more invocations. I think this may be overcomplicating things, but let's see how it goes.
+
+= 0.5.1 (r149)
+
+- Fixed bug #11583 "Mocha 0.5.0 throwing unexpected warnings". Also switched on ruby warning for all rake test tasks. Fixed majority of warnings, but some left to fix.
+
+= 0.5.0 (r147)
+
+- Parameter Matchers - I’ve added a few Hamcrest-style parameter matchers which are designed to be used inside Expectation#with. The following matchers are currently available: anything(), includes(), has_key(), has_value(), has_entry(), all_of() & any_of(). More to follow soon. The idea is eventually to get rid of the nasty parameter_block option on Expectation#with.
+
+ object = mock()
+ object.expects(:method).with(has_key('key_1'))
+ object.method('key_1' => 1, 'key_2' => 2)
+ # no verification error raised
+
+ object = mock()
+ object.expects(:method).with(has_key('key_1'))
+ object.method('key_2' => 2)
+ # verification error raised, because method was not called with Hash containing key: 'key_1'
+
+- Values Returned and Exceptions Raised on Consecutive Invocations - Allow multiple calls to Expectation#returns and Expectation#raises to build up a sequence of responses to invocations on the mock. Added syntactic sugar method Expectation#then to allow more readable expectations.
+
+ object = mock()
+ object.stubs(:method).returns(1, 2).then.raises(Exception).then.returns(4)
+ object.method # => 1
+ object.method # => 2
+ object.method # => raises exception of class Exception
+ object.method # => 4
+
+- Yields on Consecutive Invocations - Allow multiple calls to yields on single expectation to allow yield parameters to be specified for consecutive invocations.
+
+ object = mock()
+ object.stubs(:method).yields(1, 2).then.yields(3)
+ object.method { |*values| p values } # => [1, 2]
+ object.method { |*values| p values } # => [3]
+
+- Multiple Yields on Single Invocation - Added Expectation#multiple_yields to allow a mocked or stubbed method to yield multiple times for a single invocation.
+
+ object = mock()
+ object.stubs(:method).multiple_yields([1, 2], [3])
+ object.method { |*values| p values } # => [1, 2] # => [3]
+
+- Invocation Dispatch - Expectations were already being matched in reverse order i.e. the most recently defined one was being found first. This is still the case, but we now stop matching an expectation when its maximum number of expected invocations is reached. c.f. JMock v1. A stub will never stop matching by default. Hopefully this means we can soon get rid of the need to pass a Proc to Expectation#returns.
+
+ object = mock()
+ object.stubs(:method).returns(2)
+ object.expects(:method).once.returns(1)
+ object.method # => 1
+ object.method # => 2
+ object.method # => 2
+ # no verification error raised
+
+ # The following should still work...
+
+ Time.stubs(:now).returns(Time.parse('Mon Jan 01 00:00:00 UTC 2007'))
+ Time.now # => Mon Jan 01 00:00:00 UTC 2007
+ Time.stubs(:now).returns(Time.parse('Thu Feb 01 00:00:00 UTC 2007'))
+ Time.now # => Thu Feb 01 00:00:00 UTC 2007
+
+- Deprecate passing an instance of Proc to Expectation#returns.
+- Explicitly include all Rakefile dependencies in project.
+- Fixed old Stubba example.
+- Fix so that it is possible for a stubbed method to raise an Interrupt exception without a message in Ruby 1.8.6
+- Added responds_like and quacks_like.
+- Capture standard object methods before Mocha adds any.
+- Added Expectation#once method to make interface less surprising.
+- Use Rake::TestTask to run tests. Created three separate tasks to run unit, integration & acceptance tests. Split inspect_test into one file per TestCase. Deleted superfluous all_tests file.
+- Fiddled with mocha_inspect and tests to give more sensible results on x86 platform.
+- Fixed bug #7834 "infinite_range.rb makes incorrect assumption about to_f" logged by James Moore.
+
+= 0.4.0 (r92)
+
+- Allow naming of mocks (patch from Chris Roos).
+- Specify multiple return values for consecutive calls.
+- Improved consistency of expectation error messages.
+- Allow mocking of Object instance methods e.g. kind_of?, type.
+- Provide aliased versions of #expects and #stubs to allow mocking of these methods.
+- Added at_least, at_most, at_most_once methods to expectation.
+- Allow expects and stubs to take a hash of method and return values.
+- Eliminate warning: "instance variable @yield not initialized" (patch from Xavier Shay).
+- Restore instance methods on partial mocks (patch from Chris Roos).
+- Allow stubbing of a method with non-word characters in its name (patch from Paul Battley).
+- Removed coupling to Test::Unit.
+- Allow specified exception instance to be raised (patch from Chris Roos).
+- Make mock object_id appear in hex like normal Ruby inspect (patch from Paul Battley).
+- Fix path to object.rb in rdoc rake task (patch from Tomas Pospisek).
+- Reverse order in which expectations are matched, so that last expectation is matched first. This allows e.g. a call to #stubs to be effectively overridden by a call to #expects (patch from Tobias Lutke).
+- Stubba & SmartTestCase modules incorporated into Mocha module so only need to require 'mocha' - no longer need to require 'stubba'.
+- AutoMocha removed.
+
+= 0.3.3
+
+- Quick bug fix to restore instance methods on partial mocks (for Kevin Clark).
+
+= 0.3.2
+
+- Examples added.
+
+= 0.3.1
+
+- Dual licensing with MIT license added.
+
+= 0.3.0
+
+* Rails plugin.
+* Auto-verify for expectations on concrete classes.
+* Include each expectation verification in the test result assertion count.
+* Filter out noise from assertion backtraces.
+* Point assertion backtrace to line where failing expectation was created.
+* New yields method for expectations.
+* Create stubs which stub all method calls.
+* Mocks now respond_to? expected methods.
+
+= 0.2.1
+
+* Rename MochaAcceptanceTest::Rover#move method to avoid conflict with Rake (in Ruby 1.8.4 only?)
+
+= 0.2.0
+
+* Small change to SetupAndTeardown#teardown_stubs suggested by Luke Redpath (http://www.lukeredpath.co.uk) to allow use of Stubba with RSpec (http://rspec.rubyforge.org).
+* Reorganized directory structure and extracted addition of setup and teardown methods into SmartTestCase mini-library.
+* Addition of auto-verify for Mocha (but not Stubba). This means there is more significance in the choice of expects or stubs in that any expects on a mock will automatically get verified.
+
+So instead of...
+
+ wotsit = Mocha.new
+ wotsit.expects(:thingummy).with(5).returns(10)
+ doobrey = Doobrey.new(wotsit)
+ doobrey.hoojamaflip
+ wotsit.verify
+
+you need to do...
+
+ wotsit = mock()
+ wotsit.expects(:thingummy).with(5).returns(10)
+ doobrey = Doobrey.new(wotsit)
+ doobrey.hoojamaflip
+ # no need to verify
+
+There are also shortcuts as follows...
+
+instead of...
+
+ wotsit = Mocha.new
+ wotsit.expects(:thingummy).returns(10)
+ wotsit.expects(:summat).returns(25)
+
+you can have...
+
+ wotsit = mock(:thingummy => 5, :summat => 25)
+
+and instead of...
+
+ wotsit = Mocha.new
+ wotsit.stubs(:thingummy).returns(10)
+ wotsit.stubs(:summat).returns(25)
+
+you can have...
+
+ wotsit = stub(:thingummy => 5, :summat => 25)
+
+= 0.1.2
+
+* Minor tweaks
+
+= 0.1.1
+
+* Initial release.
diff --git a/vendor/gems/mocha-0.5.6/Rakefile b/vendor/gems/mocha-0.5.6/Rakefile
new file mode 100644
index 000000000..2e2f7287a
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/Rakefile
@@ -0,0 +1,149 @@
+require 'rubygems'
+require 'rake/rdoctask'
+require 'rake/gempackagetask'
+require 'rake/testtask'
+require 'rake/contrib/sshpublisher'
+
+module Mocha
+ VERSION = "0.5.6"
+end
+
+desc "Run all tests"
+task :default => :test_all
+
+task :test_all => [:test_unit, :test_integration, :test_acceptance]
+
+desc "Run unit tests"
+Rake::TestTask.new(:test_unit) do |t|
+ t.libs << 'test'
+ t.test_files = FileList['test/unit/**/*_test.rb']
+ t.verbose = true
+ t.warning = true
+end
+
+desc "Run integration tests"
+Rake::TestTask.new(:test_integration) do |t|
+ t.libs << 'test'
+ t.test_files = FileList['test/integration/*_test.rb']
+ t.verbose = true
+ t.warning = true
+end
+
+desc "Run acceptance tests"
+Rake::TestTask.new(:test_acceptance) do |t|
+ t.libs << 'test'
+ t.test_files = FileList['test/acceptance/*_test.rb']
+ t.verbose = true
+ t.warning = true
+end
+
+desc 'Generate RDoc'
+Rake::RDocTask.new do |task|
+ task.main = 'README'
+ task.title = "Mocha #{Mocha::VERSION}"
+ task.rdoc_dir = 'doc'
+ task.template = File.expand_path(File.join(File.dirname(__FILE__), "templates", "html_with_google_analytics"))
+ task.rdoc_files.include('README', 'RELEASE', 'COPYING', 'MIT-LICENSE', 'agiledox.txt', 'lib/mocha/auto_verify.rb', 'lib/mocha/mock.rb', 'lib/mocha/expectation.rb', 'lib/mocha/object.rb', 'lib/mocha/parameter_matchers.rb', 'lib/mocha/parameter_matchers')
+end
+task :rdoc => :examples
+
+desc "Upload RDoc to RubyForge"
+task :publish_rdoc => [:rdoc, :examples] do
+ Rake::SshDirPublisher.new("jamesmead@rubyforge.org", "/var/www/gforge-projects/mocha", "doc").upload
+end
+
+desc "Generate agiledox-like documentation for tests"
+file 'agiledox.txt' do
+ File.open('agiledox.txt', 'w') do |output|
+ tests = FileList['test/**/*_test.rb']
+ tests.each do |file|
+ m = %r".*/([^/].*)_test.rb".match(file)
+ output << m[1]+" should:\n"
+ test_definitions = File::readlines(file).select {|line| line =~ /.*def test.*/}
+ test_definitions.sort.each do |definition|
+ m = %r"test_(should_)?(.*)".match(definition)
+ output << " - "+m[2].gsub(/_/," ") << "\n"
+ end
+ end
+ end
+end
+
+desc "Convert example ruby files to syntax-highlighted html"
+task :examples do
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "vendor", "coderay-0.7.4.215", "lib"))
+ require 'coderay'
+ mkdir_p 'doc/examples'
+ File.open('doc/examples/coderay.css', 'w') do |output|
+ output << CodeRay::Encoders[:html]::CSS.new.stylesheet
+ end
+ ['mocha', 'stubba', 'misc'].each do |filename|
+ File.open("doc/examples/#{filename}.html", 'w') do |file|
+ file << "<html>"
+ file << "<head>"
+ file << %q(<link rel="stylesheet" media="screen" href="coderay.css" type="text/css">)
+ file << "</head>"
+ file << "<body>"
+ file << CodeRay.scan_file("examples/#{filename}.rb").html.div
+ file << "</body>"
+ file << "</html>"
+ end
+ end
+end
+
+Gem::manage_gems
+
+specification = Gem::Specification.new do |s|
+ s.name = "mocha"
+ s.summary = "Mocking and stubbing library"
+ s.version = Mocha::VERSION
+ s.platform = Gem::Platform::RUBY
+ s.author = 'James Mead'
+ s.description = <<-EOF
+ Mocking and stubbing library with JMock/SchMock syntax, which allows mocking and stubbing of methods on real (non-mock) classes.
+ EOF
+ s.email = 'mocha-developer@rubyforge.org'
+ s.homepage = 'http://mocha.rubyforge.org'
+ s.rubyforge_project = 'mocha'
+
+ s.has_rdoc = true
+ s.extra_rdoc_files = ['README', 'COPYING']
+ s.rdoc_options << '--title' << 'Mocha' << '--main' << 'README' << '--line-numbers'
+
+ s.autorequire = 'mocha'
+ s.add_dependency('rake')
+ s.files = FileList['{lib,test,examples}/**/*.rb', '[A-Z]*'].exclude('TODO').to_a
+end
+
+Rake::GemPackageTask.new(specification) do |package|
+ package.need_zip = true
+ package.need_tar = true
+end
+
+task :verify_user do
+ raise "RUBYFORGE_USER environment variable not set!" unless ENV['RUBYFORGE_USER']
+end
+
+task :verify_password do
+ raise "RUBYFORGE_PASSWORD environment variable not set!" unless ENV['RUBYFORGE_PASSWORD']
+end
+
+desc "Publish package files on RubyForge."
+task :publish_packages => [:verify_user, :verify_password, :package] do
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "vendor", "meta_project-0.4.15", "lib"))
+ require 'meta_project'
+ require 'rake/contrib/xforge'
+ release_files = FileList[
+ "pkg/mocha-#{Mocha::VERSION}.gem",
+ "pkg/mocha-#{Mocha::VERSION}.tgz",
+ "pkg/mocha-#{Mocha::VERSION}.zip"
+ ]
+
+ Rake::XForge::Release.new(MetaProject::Project::XForge::RubyForge.new('mocha')) do |release|
+ release.user_name = ENV['RUBYFORGE_USER']
+ release.password = ENV['RUBYFORGE_PASSWORD']
+ release.files = release_files.to_a
+ release.release_name = "Mocha #{Mocha::VERSION}"
+ release.release_changes = ''
+ release.release_notes = ''
+ end
+end
diff --git a/vendor/gems/mocha-0.5.6/examples/._misc.rb b/vendor/gems/mocha-0.5.6/examples/._misc.rb
new file mode 100644
index 000000000..c425bb341
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/examples/._misc.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/examples/._mocha.rb b/vendor/gems/mocha-0.5.6/examples/._mocha.rb
new file mode 100644
index 000000000..0c1998db8
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/examples/._mocha.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/examples/._stubba.rb b/vendor/gems/mocha-0.5.6/examples/._stubba.rb
new file mode 100644
index 000000000..4eae8fa0f
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/examples/._stubba.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/examples/misc.rb b/vendor/gems/mocha-0.5.6/examples/misc.rb
new file mode 100644
index 000000000..1cb8b55d0
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/examples/misc.rb
@@ -0,0 +1,44 @@
+require 'test/unit'
+require 'rubygems'
+require 'mocha'
+
+class MiscExampleTest < Test::Unit::TestCase
+
+ def test_mocking_a_class_method
+ product = Product.new
+ Product.expects(:find).with(1).returns(product)
+ assert_equal product, Product.find(1)
+ end
+
+ def test_mocking_an_instance_method_on_a_real_object
+ product = Product.new
+ product.expects(:save).returns(true)
+ assert product.save
+ end
+
+ def test_stubbing_instance_methods_on_real_objects
+ prices = [stub(:pence => 1000), stub(:pence => 2000)]
+ product = Product.new
+ product.stubs(:prices).returns(prices)
+ assert_equal [1000, 2000], product.prices.collect {|p| p.pence}
+ end
+
+ def test_stubbing_an_instance_method_on_all_instances_of_a_class
+ Product.any_instance.stubs(:name).returns('stubbed_name')
+ product = Product.new
+ assert_equal 'stubbed_name', product.name
+ end
+
+ def test_traditional_mocking
+ object = mock()
+ object.expects(:expected_method).with(:p1, :p2).returns(:result)
+ assert_equal :result, object.expected_method(:p1, :p2)
+ end
+
+ def test_shortcuts
+ object = stub(:method1 => :result1, :method2 => :result2)
+ assert_equal :result1, object.method1
+ assert_equal :result2, object.method2
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/examples/mocha.rb b/vendor/gems/mocha-0.5.6/examples/mocha.rb
new file mode 100644
index 000000000..863270d53
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/examples/mocha.rb
@@ -0,0 +1,26 @@
+class Enterprise
+
+ def initialize(dilithium)
+ @dilithium = dilithium
+ end
+
+ def go(warp_factor)
+ warp_factor.times { @dilithium.nuke(:anti_matter) }
+ end
+
+end
+
+require 'test/unit'
+require 'rubygems'
+require 'mocha'
+
+class EnterpriseTest < Test::Unit::TestCase
+
+ def test_should_boldly_go
+ dilithium = mock()
+ dilithium.expects(:nuke).with(:anti_matter).at_least_once # auto-verified at end of test
+ enterprise = Enterprise.new(dilithium)
+ enterprise.go(2)
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/examples/stubba.rb b/vendor/gems/mocha-0.5.6/examples/stubba.rb
new file mode 100644
index 000000000..2788d1b62
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/examples/stubba.rb
@@ -0,0 +1,65 @@
+class Order
+
+ attr_accessor :shipped_on
+
+ def total_cost
+ line_items.inject(0) { |total, line_item| total + line_item.price } + shipping_cost
+ end
+
+ def total_weight
+ line_items.inject(0) { |total, line_item| total + line_item.weight }
+ end
+
+ def shipping_cost
+ total_weight * 5 + 10
+ end
+
+ class << self
+
+ def find_all
+ # Database.connection.execute('select * from orders...
+ end
+
+ def number_shipped_since(date)
+ find_all.select { |order| order.shipped_on > date }.length
+ end
+
+ def unshipped_value
+ find_all.inject(0) { |total, order| order.shipped_on ? total : total + order.total_cost }
+ end
+
+ end
+
+end
+
+require 'test/unit'
+require 'rubygems'
+require 'mocha'
+
+class OrderTest < Test::Unit::TestCase
+
+ # illustrates stubbing instance method
+ def test_should_calculate_shipping_cost_based_on_total_weight
+ order = Order.new
+ order.stubs(:total_weight).returns(10)
+ assert_equal 60, order.shipping_cost
+ end
+
+ # illustrates stubbing class method
+ def test_should_count_number_of_orders_shipped_after_specified_date
+ now = Time.now; week_in_secs = 7 * 24 * 60 * 60
+ order_1 = Order.new; order_1.shipped_on = now - 1 * week_in_secs
+ order_2 = Order.new; order_2.shipped_on = now - 3 * week_in_secs
+ Order.stubs(:find_all).returns([order_1, order_2])
+ assert_equal 1, Order.number_shipped_since(now - 2 * week_in_secs)
+ end
+
+ # illustrates stubbing instance method for all instances of a class
+ def test_should_calculate_value_of_unshipped_orders
+ Order.stubs(:find_all).returns([Order.new, Order.new, Order.new])
+ Order.any_instance.stubs(:shipped_on).returns(nil)
+ Order.any_instance.stubs(:total_cost).returns(10)
+ assert_equal 30, Order.unshipped_value
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/lib/._mocha.rb b/vendor/gems/mocha-0.5.6/lib/._mocha.rb
new file mode 100644
index 000000000..cf6ff4839
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/._mocha.rb
Binary files differ
diff --git a/test/lib/mocha.rb b/vendor/gems/mocha-0.5.6/lib/mocha.rb
index 58571156a..58571156a 100644
--- a/test/lib/mocha.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha.rb
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._any_instance_method.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._any_instance_method.rb
new file mode 100644
index 000000000..00711bd39
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._any_instance_method.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._auto_verify.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._auto_verify.rb
new file mode 100644
index 000000000..b0167dfe3
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._auto_verify.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._central.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._central.rb
new file mode 100644
index 000000000..8515018e0
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._central.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._class_method.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._class_method.rb
new file mode 100644
index 000000000..66871a56f
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._class_method.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._deprecation.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._deprecation.rb
new file mode 100644
index 000000000..3e11a4d5a
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._deprecation.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._expectation.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._expectation.rb
new file mode 100644
index 000000000..2deed467d
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._expectation.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._expectation_error.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._expectation_error.rb
new file mode 100644
index 000000000..dbb6154b3
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._expectation_error.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._expectation_list.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._expectation_list.rb
new file mode 100644
index 000000000..21a5f32b4
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._expectation_list.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._infinite_range.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._infinite_range.rb
new file mode 100644
index 000000000..07e0b709a
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._infinite_range.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._inspect.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._inspect.rb
new file mode 100644
index 000000000..28d27abde
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._inspect.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._instance_method.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._instance_method.rb
new file mode 100644
index 000000000..c11d0ea30
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._instance_method.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._metaclass.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._metaclass.rb
new file mode 100644
index 000000000..3ab4a8b5f
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._metaclass.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._method_matcher.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._method_matcher.rb
new file mode 100644
index 000000000..392843f65
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._method_matcher.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._missing_expectation.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._missing_expectation.rb
new file mode 100644
index 000000000..4049e36b4
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._missing_expectation.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._mock.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._mock.rb
new file mode 100644
index 000000000..8eefd1314
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._mock.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._object.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._object.rb
new file mode 100644
index 000000000..2fa785b57
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._object.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._parameter_matchers.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._parameter_matchers.rb
new file mode 100644
index 000000000..1a81dea1e
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._parameter_matchers.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._parameters_matcher.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._parameters_matcher.rb
new file mode 100644
index 000000000..de250a8e2
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._parameters_matcher.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._pretty_parameters.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._pretty_parameters.rb
new file mode 100644
index 000000000..0a4f4854b
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._pretty_parameters.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._return_values.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._return_values.rb
new file mode 100644
index 000000000..0d41af3d6
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._return_values.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._sequence.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._sequence.rb
new file mode 100644
index 000000000..af2494888
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._sequence.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._setup_and_teardown.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._setup_and_teardown.rb
new file mode 100644
index 000000000..fb1bde164
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._setup_and_teardown.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._single_return_value.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._single_return_value.rb
new file mode 100644
index 000000000..fec4c56f5
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._single_return_value.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._standalone.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._standalone.rb
new file mode 100644
index 000000000..f33f028a2
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._standalone.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._test_case_adapter.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._test_case_adapter.rb
new file mode 100644
index 000000000..99a49dc52
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._test_case_adapter.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/._yield_parameters.rb b/vendor/gems/mocha-0.5.6/lib/mocha/._yield_parameters.rb
new file mode 100644
index 000000000..a9646d7bb
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/._yield_parameters.rb
Binary files differ
diff --git a/test/lib/mocha/any_instance_method.rb b/vendor/gems/mocha-0.5.6/lib/mocha/any_instance_method.rb
index 4d55293b9..4d55293b9 100644
--- a/test/lib/mocha/any_instance_method.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/any_instance_method.rb
diff --git a/test/lib/mocha/auto_verify.rb b/vendor/gems/mocha-0.5.6/lib/mocha/auto_verify.rb
index dce877bde..896648bcd 100644
--- a/test/lib/mocha/auto_verify.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/auto_verify.rb
@@ -1,4 +1,5 @@
require 'mocha/mock'
+require 'mocha/sequence'
module Mocha # :nodoc:
@@ -17,9 +18,9 @@ module Mocha # :nodoc:
@mocks = nil
end
- # :call-seq: mock(name) -> mock object
- # mock(expected_methods = {}) -> mock object
- # mock(name, expected_methods = {}) -> mock object
+ # :call-seq: mock(name, &block) -> mock object
+ # mock(expected_methods = {}, &block) -> mock object
+ # mock(name, expected_methods = {}, &block) -> mock object
#
# Creates a mock object.
#
@@ -27,6 +28,8 @@ module Mocha # :nodoc:
#
# +expected_methods+ is a +Hash+ with expected method name symbols as keys and corresponding return values as values.
#
+ # +block+ is a block to be evaluated against the mock object instance, giving an alernative way to set up expectations & stubs.
+ #
# Note that (contrary to expectations set up by #stub) these expectations <b>must</b> be fulfilled during the test.
# def test_product
# product = mock('ipod_product', :manufacturer => 'ipod', :price => 100)
@@ -34,14 +37,18 @@ module Mocha # :nodoc:
# assert_equal 100, product.price
# # an error will be raised unless both Product#manufacturer and Product#price have been called
# end
- def mock(*args)
- name, expectations = name_and_expectations_from_args(args)
- build_mock_with_expectations(:expects, expectations, name)
+ def mock(*arguments, &block)
+ name = arguments.shift if arguments.first.is_a?(String)
+ expectations = arguments.shift || {}
+ mock = Mock.new(name, &block)
+ mock.expects(expectations)
+ mocks << mock
+ mock
end
- # :call-seq: stub(name) -> mock object
- # stub(stubbed_methods = {}) -> mock object
- # stub(name, stubbed_methods = {}) -> mock object
+ # :call-seq: stub(name, &block) -> mock object
+ # stub(stubbed_methods = {}, &block) -> mock object
+ # stub(name, stubbed_methods = {}, &block) -> mock object
#
# Creates a mock object.
#
@@ -49,6 +56,8 @@ module Mocha # :nodoc:
#
# +stubbed_methods+ is a +Hash+ with stubbed method name symbols as keys and corresponding return values as values.
#
+ # +block+ is a block to be evaluated against the mock object instance, giving an alernative way to set up expectations & stubs.
+ #
# Note that (contrary to expectations set up by #mock) these expectations <b>need not</b> be fulfilled during the test.
# def test_product
# product = stub('ipod_product', :manufacturer => 'ipod', :price => 100)
@@ -56,19 +65,25 @@ module Mocha # :nodoc:
# assert_equal 100, product.price
# # an error will not be raised even if Product#manufacturer and Product#price have not been called
# end
- def stub(*args)
- name, expectations = name_and_expectations_from_args(args)
- build_mock_with_expectations(:stubs, expectations, name)
+ def stub(*arguments, &block)
+ name = arguments.shift if arguments.first.is_a?(String)
+ expectations = arguments.shift || {}
+ stub = Mock.new(name, &block)
+ stub.stubs(expectations)
+ mocks << stub
+ stub
end
- # :call-seq: stub_everything(name) -> mock object
- # stub_everything(stubbed_methods = {}) -> mock object
- # stub_everything(name, stubbed_methods = {}) -> mock object
+ # :call-seq: stub_everything(name, &block) -> mock object
+ # stub_everything(stubbed_methods = {}, &block) -> mock object
+ # stub_everything(name, stubbed_methods = {}, &block) -> mock object
#
# Creates a mock object that accepts calls to any method.
#
# By default it will return +nil+ for any method call.
#
+ # +block+ is a block to be evaluated against the mock object instance, giving an alernative way to set up expectations & stubs.
+ #
# +name+ and +stubbed_methods+ work in the same way as for #stub.
# def test_product
# product = stub_everything('ipod_product', :price => 100)
@@ -76,9 +91,14 @@ module Mocha # :nodoc:
# assert_nil product.any_old_method
# assert_equal 100, product.price
# end
- def stub_everything(*args)
- name, expectations = name_and_expectations_from_args(args)
- build_mock_with_expectations(:stub_everything, expectations, name)
+ def stub_everything(*arguments, &block)
+ name = arguments.shift if arguments.first.is_a?(String)
+ expectations = arguments.shift || {}
+ stub = Mock.new(name, &block)
+ stub.stub_everything
+ stub.stubs(expectations)
+ mocks << stub
+ stub
end
def verify_mocks # :nodoc:
@@ -88,24 +108,9 @@ module Mocha # :nodoc:
def teardown_mocks # :nodoc:
reset_mocks
end
-
- def build_mock_with_expectations(expectation_type = :expects, expectations = {}, name = nil) # :nodoc:
- stub_everything = (expectation_type == :stub_everything)
- expectation_type = :stubs if expectation_type == :stub_everything
- mock = Mocha::Mock.new(stub_everything, name)
- expectations.each do |method, result|
- mock.__send__(expectation_type, method).returns(result)
- end
- mocks << mock
- mock
- end
- private
-
- def name_and_expectations_from_args(args) # :nodoc:
- name = args.first.is_a?(String) ? args.delete_at(0) : nil
- expectations = args.first || {}
- [name, expectations]
+ def sequence(name) # :nodoc:
+ Sequence.new(name)
end
end
diff --git a/test/lib/mocha/central.rb b/vendor/gems/mocha-0.5.6/lib/mocha/central.rb
index 3dde7350f..0445f2151 100644
--- a/test/lib/mocha/central.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/central.rb
@@ -24,7 +24,7 @@ module Mocha
end
def unstub_all
- while stubba_methods.size > 0
+ while stubba_methods.length > 0
method = stubba_methods.pop
method.unstub
end
diff --git a/test/lib/mocha/class_method.rb b/vendor/gems/mocha-0.5.6/lib/mocha/class_method.rb
index 915fe71b5..e2178be17 100644
--- a/test/lib/mocha/class_method.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/class_method.rb
@@ -42,7 +42,11 @@ module Mocha
end
def hidden_method
- method_name = method.to_s.gsub(/\W/) {|s| "_substituted_character_#{s[0]}_" }
+ if RUBY_VERSION < '1.9'
+ method_name = method.to_s.gsub(/\W/) { |s| "_substituted_character_#{s[0]}_" }
+ else
+ method_name = method.to_s.gsub(/\W/) { |s| "_substituted_character_#{s.ord}_" }
+ end
"__stubba__#{method_name}__stubba__"
end
diff --git a/test/lib/mocha/deprecation.rb b/vendor/gems/mocha-0.5.6/lib/mocha/deprecation.rb
index 7448510ec..7448510ec 100644
--- a/test/lib/mocha/deprecation.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/deprecation.rb
diff --git a/test/lib/mocha/exception_raiser.rb b/vendor/gems/mocha-0.5.6/lib/mocha/exception_raiser.rb
index 266e209a2..266e209a2 100644
--- a/test/lib/mocha/exception_raiser.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/exception_raiser.rb
diff --git a/test/lib/mocha/expectation.rb b/vendor/gems/mocha-0.5.6/lib/mocha/expectation.rb
index 49b39bea9..e3da2533f 100644
--- a/test/lib/mocha/expectation.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/expectation.rb
@@ -1,5 +1,6 @@
require 'mocha/infinite_range'
-require 'mocha/pretty_parameters'
+require 'mocha/method_matcher'
+require 'mocha/parameters_matcher'
require 'mocha/expectation_error'
require 'mocha/return_values'
require 'mocha/exception_raiser'
@@ -11,42 +12,6 @@ module Mocha # :nodoc:
# Methods on expectations returned from Mock#expects, Mock#stubs, Object#expects and Object#stubs.
class Expectation
- # :stopdoc:
-
- class AlwaysEqual
- def ==(other)
- true
- end
- end
-
- attr_reader :method_name, :backtrace
-
- def initialize(mock, method_name, backtrace = nil)
- @mock, @method_name = mock, method_name
- @expected_count = 1
- @parameters, @parameter_block = AlwaysEqual.new, nil
- @invoked_count, @return_values = 0, ReturnValues.new
- @backtrace = backtrace || caller
- @yield_parameters = YieldParameters.new
- end
-
- def match?(method_name, *arguments)
- return false unless @method_name == method_name
- if @parameter_block then
- return false unless @parameter_block.call(*arguments)
- else
- return false unless (@parameters == arguments)
- end
- if @expected_count.is_a?(Range) then
- return false unless @invoked_count < @expected_count.last
- else
- return false unless @invoked_count < @expected_count
- end
- return true
- end
-
- # :startdoc:
-
# :call-seq: times(range) -> expectation
#
# Modifies expectation so that the number of calls to the expected method must be within a specific +range+.
@@ -183,9 +148,9 @@ module Mocha # :nodoc:
self
end
- # :call-seq: with(*arguments, &parameter_block) -> expectation
+ # :call-seq: with(*expected_parameters, &matching_block) -> expectation
#
- # Modifies expectation so that the expected method must be called with specified +arguments+.
+ # Modifies expectation so that the expected method must be called with +expected_parameters+.
# object = mock()
# object.expects(:expected_method).with(:param1, :param2)
# object.expected_method(:param1, :param2)
@@ -197,7 +162,7 @@ module Mocha # :nodoc:
# # => verify fails
# May be used with parameter matchers in Mocha::ParameterMatchers.
#
- # If a +parameter_block+ is given, the block is called with the parameters passed to the expected method.
+ # If a +matching_block+ is given, the block is called with the parameters passed to the expected method.
# The expectation is matched if the block evaluates to +true+.
# object = mock()
# object.expects(:expected_method).with() { |value| value % 4 == 0 }
@@ -208,9 +173,8 @@ module Mocha # :nodoc:
# object.expects(:expected_method).with() { |value| value % 4 == 0 }
# object.expected_method(17)
# # => verify fails
- def with(*arguments, &parameter_block)
- @parameters, @parameter_block = arguments, parameter_block
- class << @parameters; def to_s; join(', '); end; end
+ def with(*expected_parameters, &matching_block)
+ @parameters_matcher = ParametersMatcher.new(expected_parameters, &matching_block)
self
end
@@ -259,7 +223,7 @@ module Mocha # :nodoc:
end
# :call-seq: returns(value) -> expectation
- # :call-seq: returns(*values) -> expectation
+ # returns(*values) -> expectation
#
# Modifies expectation so that when the expected method is called, it returns the specified +value+.
# object = mock()
@@ -335,6 +299,56 @@ module Mocha # :nodoc:
# :stopdoc:
+ def in_sequence(*sequences)
+ sequences.each { |sequence| sequence.constrain_as_next_in_sequence(self) }
+ self
+ end
+
+ attr_reader :backtrace
+
+ def initialize(mock, expected_method_name, backtrace = nil)
+ @mock = mock
+ @method_matcher = MethodMatcher.new(expected_method_name)
+ @parameters_matcher = ParametersMatcher.new
+ @ordering_constraints = []
+ @expected_count, @invoked_count = 1, 0
+ @return_values = ReturnValues.new
+ @yield_parameters = YieldParameters.new
+ @backtrace = backtrace || caller
+ end
+
+ def add_ordering_constraint(ordering_constraint)
+ @ordering_constraints << ordering_constraint
+ end
+
+ def in_correct_order?
+ @ordering_constraints.all? { |ordering_constraint| ordering_constraint.allows_invocation_now? }
+ end
+
+ def matches_method?(method_name)
+ @method_matcher.match?(method_name)
+ end
+
+ def match?(actual_method_name, *actual_parameters)
+ @method_matcher.match?(actual_method_name) && @parameters_matcher.match?(actual_parameters) && in_correct_order?
+ end
+
+ def invocations_allowed?
+ if @expected_count.is_a?(Range) then
+ @invoked_count < @expected_count.last
+ else
+ @invoked_count < @expected_count
+ end
+ end
+
+ def satisfied?
+ if @expected_count.is_a?(Range) then
+ @invoked_count >= @expected_count.first
+ else
+ @invoked_count >= @expected_count
+ end
+ end
+
def invoke
@invoked_count += 1
if block_given? then
@@ -348,27 +362,19 @@ module Mocha # :nodoc:
def verify
yield(self) if block_given?
unless (@expected_count === @invoked_count) then
- error = ExpectationError.new(error_message(@expected_count, @invoked_count))
- error.set_backtrace(filtered_backtrace)
+ error = ExpectationError.new(error_message(@expected_count, @invoked_count), backtrace)
raise error
end
end
- def mocha_lib_directory
- File.expand_path(File.join(File.dirname(__FILE__), "..")) + File::SEPARATOR
- end
-
- def filtered_backtrace
- backtrace.reject { |location| Regexp.new(mocha_lib_directory).match(File.expand_path(location)) }
- end
-
def method_signature
- return "#{method_name}" if @parameters.__is_a__(AlwaysEqual)
- "#{@method_name}(#{PrettyParameters.new(@parameters).pretty})"
+ signature = "#{@mock.mocha_inspect}.#{@method_matcher.mocha_inspect}#{@parameters_matcher.mocha_inspect}"
+ signature << "; #{@ordering_constraints.map { |oc| oc.mocha_inspect }.join("; ")}" unless @ordering_constraints.empty?
+ signature
end
def error_message(expected_count, actual_count)
- "#{@mock.mocha_inspect}.#{method_signature} - expected calls: #{expected_count.mocha_inspect}, actual calls: #{actual_count}"
+ "#{method_signature} - expected calls: #{expected_count.mocha_inspect}, actual calls: #{actual_count}"
end
# :startdoc:
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/expectation_error.rb b/vendor/gems/mocha-0.5.6/lib/mocha/expectation_error.rb
new file mode 100644
index 000000000..705571b85
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/expectation_error.rb
@@ -0,0 +1,15 @@
+module Mocha
+
+ class ExpectationError < StandardError
+
+ LIB_DIRECTORY = File.expand_path(File.join(File.dirname(__FILE__), "..")) + File::SEPARATOR
+
+ def initialize(message = nil, backtrace = [], lib_directory = LIB_DIRECTORY)
+ super(message)
+ filtered_backtrace = backtrace.reject { |location| Regexp.new(lib_directory).match(File.expand_path(location)) }
+ set_backtrace(filtered_backtrace)
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/expectation_list.rb b/vendor/gems/mocha-0.5.6/lib/mocha/expectation_list.rb
new file mode 100644
index 000000000..5ca13d5af
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/expectation_list.rb
@@ -0,0 +1,46 @@
+module Mocha # :nodoc:
+
+ class ExpectationList
+
+ def initialize
+ @expectations = []
+ end
+
+ def add(expectation)
+ @expectations << expectation
+ expectation
+ end
+
+ def matches_method?(method_name)
+ @expectations.any? { |expectation| expectation.matches_method?(method_name) }
+ end
+
+ def similar(method_name)
+ @expectations.select { |expectation| expectation.matches_method?(method_name) }
+ end
+
+ def detect(method_name, *arguments)
+ expectations = @expectations.reverse.select { |e| e.match?(method_name, *arguments) }
+ expectation = expectations.detect { |e| e.invocations_allowed? }
+ expectation || expectations.first
+ end
+
+ def verify(&block)
+ @expectations.each { |expectation| expectation.verify(&block) }
+ end
+
+ def to_a
+ @expectations
+ end
+
+ def to_set
+ @expectations.to_set
+ end
+
+ def length
+ @expectations.length
+ end
+
+ end
+
+end
diff --git a/test/lib/mocha/infinite_range.rb b/vendor/gems/mocha-0.5.6/lib/mocha/infinite_range.rb
index 05dfe559e..05dfe559e 100644
--- a/test/lib/mocha/infinite_range.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/infinite_range.rb
diff --git a/test/lib/mocha/inspect.rb b/vendor/gems/mocha-0.5.6/lib/mocha/inspect.rb
index ad82ef70e..ad82ef70e 100644
--- a/test/lib/mocha/inspect.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/inspect.rb
diff --git a/test/lib/mocha/instance_method.rb b/vendor/gems/mocha-0.5.6/lib/mocha/instance_method.rb
index f0d4b04b8..f0d4b04b8 100644
--- a/test/lib/mocha/instance_method.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/instance_method.rb
diff --git a/test/lib/mocha/is_a.rb b/vendor/gems/mocha-0.5.6/lib/mocha/is_a.rb
index ee23c86a9..ee23c86a9 100644
--- a/test/lib/mocha/is_a.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/is_a.rb
diff --git a/test/lib/mocha/metaclass.rb b/vendor/gems/mocha-0.5.6/lib/mocha/metaclass.rb
index f78fb892b..f78fb892b 100644
--- a/test/lib/mocha/metaclass.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/metaclass.rb
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/method_matcher.rb b/vendor/gems/mocha-0.5.6/lib/mocha/method_matcher.rb
new file mode 100644
index 000000000..6ce5f6d57
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/method_matcher.rb
@@ -0,0 +1,21 @@
+module Mocha
+
+ class MethodMatcher
+
+ attr_reader :expected_method_name
+
+ def initialize(expected_method_name)
+ @expected_method_name = expected_method_name
+ end
+
+ def match?(actual_method_name)
+ @expected_method_name == actual_method_name
+ end
+
+ def mocha_inspect
+ "#{@expected_method_name}"
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/missing_expectation.rb b/vendor/gems/mocha-0.5.6/lib/mocha/missing_expectation.rb
new file mode 100644
index 000000000..ccff6bff4
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/missing_expectation.rb
@@ -0,0 +1,17 @@
+require 'mocha/expectation'
+
+module Mocha # :nodoc:
+
+ class MissingExpectation < Expectation # :nodoc:
+
+ def verify
+ message = error_message(0, 1)
+ similar_expectations = @mock.expectations.similar(@method_matcher.expected_method_name)
+ method_signatures = similar_expectations.map { |expectation| expectation.method_signature }
+ message << "\nSimilar expectations:\n#{method_signatures.join("\n")}" unless method_signatures.empty?
+ raise ExpectationError.new(message, backtrace)
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/test/lib/mocha/mock.rb b/vendor/gems/mocha-0.5.6/lib/mocha/mock.rb
index 18c23fede..59193e728 100644
--- a/test/lib/mocha/mock.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/mock.rb
@@ -1,28 +1,16 @@
require 'mocha/expectation'
+require 'mocha/expectation_list'
require 'mocha/stub'
require 'mocha/missing_expectation'
require 'mocha/metaclass'
module Mocha # :nodoc:
-
+
# Traditional mock object.
#
# Methods return an Expectation which can be further modified by methods on Expectation.
class Mock
- # :stopdoc:
-
- def initialize(stub_everything = false, name = nil)
- @stub_everything = stub_everything
- @mock_name = name
- @expectations = []
- @responder = nil
- end
-
- attr_reader :stub_everything, :expectations
-
- # :startdoc:
-
# :call-seq: expects(method_name) -> expectation
# expects(method_names) -> last expectation
#
@@ -50,10 +38,12 @@ module Mocha # :nodoc:
def expects(method_name_or_hash, backtrace = nil)
if method_name_or_hash.is_a?(Hash) then
method_name_or_hash.each do |method_name, return_value|
- add_expectation(Expectation.new(self, method_name, backtrace).returns(return_value))
+ ensure_method_not_already_defined(method_name)
+ @expectations.add(Expectation.new(self, method_name, backtrace).returns(return_value))
end
else
- add_expectation(Expectation.new(self, method_name_or_hash, backtrace))
+ ensure_method_not_already_defined(method_name_or_hash)
+ @expectations.add(Expectation.new(self, method_name_or_hash, backtrace))
end
end
@@ -81,10 +71,12 @@ module Mocha # :nodoc:
def stubs(method_name_or_hash, backtrace = nil)
if method_name_or_hash.is_a?(Hash) then
method_name_or_hash.each do |method_name, return_value|
- add_expectation(Stub.new(self, method_name, backtrace).returns(return_value))
+ ensure_method_not_already_defined(method_name)
+ @expectations.add(Stub.new(self, method_name, backtrace).returns(return_value))
end
else
- add_expectation(Stub.new(self, method_name_or_hash, backtrace))
+ ensure_method_not_already_defined(method_name_or_hash)
+ @expectations.add(Stub.new(self, method_name_or_hash, backtrace))
end
end
@@ -134,6 +126,16 @@ module Mocha # :nodoc:
end
# :stopdoc:
+
+ def initialize(name = nil, &block)
+ @mock_name = name
+ @expectations = ExpectationList.new
+ @everything_stubbed = false
+ @responder = nil
+ instance_eval(&block) if block
+ end
+
+ attr_reader :everything_stubbed, :expectations
alias_method :__expects__, :expects
@@ -142,52 +144,41 @@ module Mocha # :nodoc:
alias_method :quacks_like, :responds_like
def add_expectation(expectation)
- @expectations << expectation
- method_name = expectation.method_name
- self.__metaclass__.send(:undef_method, method_name) if self.__metaclass__.method_defined?(method_name)
- expectation
+ @expectations.add(expectation)
end
-
+
+ def stub_everything
+ @everything_stubbed = true
+ end
+
def method_missing(symbol, *arguments, &block)
if @responder and not @responder.respond_to?(symbol)
raise NoMethodError, "undefined method `#{symbol}' for #{self.mocha_inspect} which responds like #{@responder.mocha_inspect}"
end
- matching_expectation = matching_expectation(symbol, *arguments)
+ matching_expectation = @expectations.detect(symbol, *arguments)
if matching_expectation then
matching_expectation.invoke(&block)
- elsif stub_everything then
+ elsif @everything_stubbed then
return
else
- begin
- super_method_missing(symbol, *arguments, &block)
- rescue NoMethodError
- unexpected_method_called(symbol, *arguments)
- end
- end
- end
-
- def respond_to?(symbol)
- if @responder then
- @responder.respond_to?(symbol)
+ unexpected_method_called(symbol, *arguments)
+ end
+ end
+
+ def respond_to?(symbol)
+ if @responder then
+ @responder.respond_to?(symbol)
else
- @expectations.any? { |expectation| expectation.method_name == symbol }
- end
- end
-
- def super_method_missing(symbol, *arguments, &block)
- raise NoMethodError
+ @expectations.matches_method?(symbol)
+ end
end
-
- def unexpected_method_called(symbol, *arguments)
+
+ def unexpected_method_called(symbol, *arguments)
MissingExpectation.new(self, symbol).with(*arguments).verify
end
-
- def matching_expectation(symbol, *arguments)
- @expectations.reverse.detect { |expectation| expectation.match?(symbol, *arguments) }
- end
def verify(&block)
- @expectations.each { |expectation| expectation.verify(&block) }
+ @expectations.verify(&block)
end
def mocha_inspect
@@ -199,9 +190,13 @@ module Mocha # :nodoc:
def inspect
mocha_inspect
end
+
+ def ensure_method_not_already_defined(method_name)
+ self.__metaclass__.send(:undef_method, method_name) if self.__metaclass__.method_defined?(method_name)
+ end
# :startdoc:
end
-end \ No newline at end of file
+end
diff --git a/test/lib/mocha/multiple_yields.rb b/vendor/gems/mocha-0.5.6/lib/mocha/multiple_yields.rb
index 8186c3076..8186c3076 100644
--- a/test/lib/mocha/multiple_yields.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/multiple_yields.rb
diff --git a/test/lib/mocha/no_yields.rb b/vendor/gems/mocha-0.5.6/lib/mocha/no_yields.rb
index b0fba415d..b0fba415d 100644
--- a/test/lib/mocha/no_yields.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/no_yields.rb
diff --git a/test/lib/mocha/object.rb b/vendor/gems/mocha-0.5.6/lib/mocha/object.rb
index 7ccdbad0d..7ccdbad0d 100644
--- a/test/lib/mocha/object.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/object.rb
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers.rb
new file mode 100644
index 000000000..a11047998
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers.rb
@@ -0,0 +1,25 @@
+module Mocha
+
+ # Used as parameters for Expectation#with to restrict the parameter values which will match the expectation.
+ module ParameterMatchers; end
+
+end
+
+require 'mocha/parameter_matchers/object'
+
+require 'mocha/parameter_matchers/all_of'
+require 'mocha/parameter_matchers/any_of'
+require 'mocha/parameter_matchers/any_parameters'
+require 'mocha/parameter_matchers/anything'
+require 'mocha/parameter_matchers/equals'
+require 'mocha/parameter_matchers/has_entry'
+require 'mocha/parameter_matchers/has_entries'
+require 'mocha/parameter_matchers/has_key'
+require 'mocha/parameter_matchers/has_value'
+require 'mocha/parameter_matchers/includes'
+require 'mocha/parameter_matchers/instance_of'
+require 'mocha/parameter_matchers/is_a'
+require 'mocha/parameter_matchers/kind_of'
+require 'mocha/parameter_matchers/not'
+require 'mocha/parameter_matchers/optionally'
+require 'mocha/parameter_matchers/regexp_matches'
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._all_of.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._all_of.rb
new file mode 100644
index 000000000..41edbb869
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._all_of.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._any_of.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._any_of.rb
new file mode 100644
index 000000000..ff228f5c7
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._any_of.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._any_parameters.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._any_parameters.rb
new file mode 100644
index 000000000..7f2968c8c
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._any_parameters.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._anything.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._anything.rb
new file mode 100644
index 000000000..5efdf5440
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._anything.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._base.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._base.rb
new file mode 100644
index 000000000..fc871fdda
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._base.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._equals.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._equals.rb
new file mode 100644
index 000000000..c0dfb4cf5
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._equals.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_entries.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_entries.rb
new file mode 100644
index 000000000..622858418
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_entries.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_entry.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_entry.rb
new file mode 100644
index 000000000..fe7b51cfa
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_entry.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_key.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_key.rb
new file mode 100644
index 000000000..e045911be
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_key.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_value.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_value.rb
new file mode 100644
index 000000000..a9565f2d4
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._has_value.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._includes.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._includes.rb
new file mode 100644
index 000000000..0139a2dd2
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._includes.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._instance_of.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._instance_of.rb
new file mode 100644
index 000000000..718e37697
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._instance_of.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._is_a.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._is_a.rb
new file mode 100644
index 000000000..189a411cd
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._is_a.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._kind_of.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._kind_of.rb
new file mode 100644
index 000000000..b99d0d771
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._kind_of.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._not.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._not.rb
new file mode 100644
index 000000000..72ad06517
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._not.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._object.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._object.rb
new file mode 100644
index 000000000..5b117348e
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._object.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._optionally.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._optionally.rb
new file mode 100644
index 000000000..2177fc74a
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._optionally.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._regexp_matches.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._regexp_matches.rb
new file mode 100644
index 000000000..2b30b084a
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/._regexp_matches.rb
Binary files differ
diff --git a/test/lib/mocha/parameter_matchers/all_of.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/all_of.rb
index 343d9eea0..369eb4340 100644
--- a/test/lib/mocha/parameter_matchers/all_of.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/all_of.rb
@@ -1,3 +1,5 @@
+require 'mocha/parameter_matchers/base'
+
module Mocha
module ParameterMatchers
@@ -18,14 +20,15 @@ module Mocha
AllOf.new(*matchers)
end
- class AllOf # :nodoc:
+ class AllOf < Base # :nodoc:
def initialize(*matchers)
@matchers = matchers
end
- def ==(parameter)
- @matchers.all? { |matcher| matcher == parameter }
+ def matches?(available_parameters)
+ parameter = available_parameters.shift
+ @matchers.all? { |matcher| matcher.matches?([parameter]) }
end
def mocha_inspect
diff --git a/test/lib/mocha/parameter_matchers/any_of.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/any_of.rb
index a1f88075d..dd254b12f 100644
--- a/test/lib/mocha/parameter_matchers/any_of.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/any_of.rb
@@ -1,3 +1,5 @@
+require 'mocha/parameter_matchers/base'
+
module Mocha
module ParameterMatchers
@@ -23,14 +25,15 @@ module Mocha
AnyOf.new(*matchers)
end
- class AnyOf # :nodoc:
+ class AnyOf < Base # :nodoc:
def initialize(*matchers)
@matchers = matchers
end
- def ==(parameter)
- @matchers.any? { |matcher| matcher == parameter }
+ def matches?(available_parameters)
+ parameter = available_parameters.shift
+ @matchers.any? { |matcher| matcher.matches?([parameter]) }
end
def mocha_inspect
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/any_parameters.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/any_parameters.rb
new file mode 100644
index 000000000..11dae83ed
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/any_parameters.rb
@@ -0,0 +1,40 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+ module ParameterMatchers
+
+ # :call-seq: any_parameters() -> parameter_matcher
+ #
+ # Matches any parameters.
+ # object = mock()
+ # object.expects(:method_1).with(any_parameters)
+ # object.method_1(1, 2, 3, 4)
+ # # no error raised
+ #
+ # object = mock()
+ # object.expects(:method_1).with(any_parameters)
+ # object.method_1(5, 6, 7, 8, 9, 0)
+ # # no error raised
+ def any_parameters
+ AnyParameters.new
+ end
+
+ class AnyParameters < Base # :nodoc:
+
+ def matches?(available_parameters)
+ while available_parameters.length > 0 do
+ available_parameters.shift
+ end
+ return true
+ end
+
+ def mocha_inspect
+ "any_parameters"
+ end
+
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/test/lib/mocha/parameter_matchers/anything.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/anything.rb
index 57d0eeab4..e82ef86a0 100644
--- a/test/lib/mocha/parameter_matchers/anything.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/anything.rb
@@ -1,3 +1,5 @@
+require 'mocha/parameter_matchers/base'
+
module Mocha
module ParameterMatchers
@@ -13,9 +15,10 @@ module Mocha
Anything.new
end
- class Anything # :nodoc:
+ class Anything < Base # :nodoc:
- def ==(parameter)
+ def matches?(available_parameters)
+ available_parameters.shift
return true
end
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/base.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/base.rb
new file mode 100644
index 000000000..6aaec51a1
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/base.rb
@@ -0,0 +1,15 @@
+module Mocha
+
+ module ParameterMatchers
+
+ class Base # :nodoc:
+
+ def to_matcher
+ self
+ end
+
+ end
+
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/equals.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/equals.rb
new file mode 100644
index 000000000..bdc61a0f5
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/equals.rb
@@ -0,0 +1,42 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+ module ParameterMatchers
+
+ # :call-seq: equals(value) -> parameter_matcher
+ #
+ # Matches +Object+ equalling +value+.
+ # object = mock()
+ # object.expects(:method_1).with(equals(2))
+ # object.method_1(2)
+ # # no error raised
+ #
+ # object = mock()
+ # object.expects(:method_1).with(equals(2))
+ # object.method_1(3)
+ # # error raised, because method_1 was not called with Object equalling 3
+ def equals(value)
+ Equals.new(value)
+ end
+
+ class Equals < Base # :nodoc:
+
+ def initialize(value)
+ @value = value
+ end
+
+ def matches?(available_parameters)
+ parameter = available_parameters.shift
+ parameter == @value
+ end
+
+ def mocha_inspect
+ @value.mocha_inspect
+ end
+
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/has_entries.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/has_entries.rb
new file mode 100644
index 000000000..30cf025a5
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/has_entries.rb
@@ -0,0 +1,42 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+ module ParameterMatchers
+
+ # :call-seq: has_entries(entries) -> parameter_matcher
+ #
+ # Matches +Hash+ containing all +entries+.
+ # object = mock()
+ # object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2))
+ # object.method_1('key_1' => 1, 'key_2' => 2, 'key_3' => 3)
+ # # no error raised
+ #
+ # object = mock()
+ # object.expects(:method_1).with(has_entries('key_1' => 1, 'key_2' => 2))
+ # object.method_1('key_1' => 1, 'key_2' => 99)
+ # # error raised, because method_1 was not called with Hash containing entries: 'key_1' => 1, 'key_2' => 2
+ def has_entries(entries)
+ HasEntries.new(entries)
+ end
+
+ class HasEntries < Base # :nodoc:
+
+ def initialize(entries)
+ @entries = entries
+ end
+
+ def matches?(available_parameters)
+ parameter = available_parameters.shift
+ @entries.all? { |key, value| parameter[key] == value }
+ end
+
+ def mocha_inspect
+ "has_entries(#{@entries.mocha_inspect})"
+ end
+
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/test/lib/mocha/parameter_matchers/has_entry.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/has_entry.rb
index 3d7cac4e6..b6459613d 100644
--- a/test/lib/mocha/parameter_matchers/has_entry.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/has_entry.rb
@@ -1,8 +1,11 @@
+require 'mocha/parameter_matchers/base'
+
module Mocha
module ParameterMatchers
# :call-seq: has_entry(key, value) -> parameter_matcher
+ # has_entry(key => value) -> parameter_matcher
#
# Matches +Hash+ containing entry with +key+ and +value+.
# object = mock()
@@ -11,20 +14,33 @@ module Mocha
# # no error raised
#
# object = mock()
+ # object.expects(:method_1).with(has_entry('key_1' => 1))
+ # object.method_1('key_1' => 1, 'key_2' => 2)
+ # # no error raised
+ #
+ # object = mock()
# object.expects(:method_1).with(has_entry('key_1', 1))
# object.method_1('key_1' => 2, 'key_2' => 1)
# # error raised, because method_1 was not called with Hash containing entry: 'key_1' => 1
- def has_entry(key, value)
+ #
+ # object = mock()
+ # object.expects(:method_1).with(has_entry('key_1' => 1))
+ # object.method_1('key_1' => 2, 'key_2' => 1)
+ # # error raised, because method_1 was not called with Hash containing entry: 'key_1' => 1
+ def has_entry(*options)
+ key, value = options.shift, options.shift
+ key, value = key.to_a[0][0..1] if key.is_a?(Hash)
HasEntry.new(key, value)
end
-
- class HasEntry # :nodoc:
+
+ class HasEntry < Base # :nodoc:
def initialize(key, value)
@key, @value = key, value
end
- def ==(parameter)
+ def matches?(available_parameters)
+ parameter = available_parameters.shift
parameter[@key] == @value
end
diff --git a/test/lib/mocha/parameter_matchers/has_key.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/has_key.rb
index 5a1fcd2e8..247815219 100644
--- a/test/lib/mocha/parameter_matchers/has_key.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/has_key.rb
@@ -1,3 +1,5 @@
+require 'mocha/parameter_matchers/base'
+
module Mocha
module ParameterMatchers
@@ -18,13 +20,14 @@ module Mocha
HasKey.new(key)
end
- class HasKey # :nodoc:
+ class HasKey < Base # :nodoc:
def initialize(key)
@key = key
end
- def ==(parameter)
+ def matches?(available_parameters)
+ parameter = available_parameters.shift
parameter.keys.include?(@key)
end
diff --git a/test/lib/mocha/parameter_matchers/has_value.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/has_value.rb
index 742f84268..2c6fe7c5e 100644
--- a/test/lib/mocha/parameter_matchers/has_value.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/has_value.rb
@@ -1,3 +1,5 @@
+require 'mocha/parameter_matchers/base'
+
module Mocha
module ParameterMatchers
@@ -18,13 +20,14 @@ module Mocha
HasValue.new(value)
end
- class HasValue # :nodoc:
+ class HasValue < Base # :nodoc:
def initialize(value)
@value = value
end
- def ==(parameter)
+ def matches?(available_parameters)
+ parameter = available_parameters.shift
parameter.values.include?(@value)
end
diff --git a/test/lib/mocha/parameter_matchers/includes.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/includes.rb
index 0e4fbe960..4539a5c44 100644
--- a/test/lib/mocha/parameter_matchers/includes.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/includes.rb
@@ -1,3 +1,5 @@
+require 'mocha/parameter_matchers/base'
+
module Mocha
module ParameterMatchers
@@ -16,13 +18,14 @@ module Mocha
Includes.new(item)
end
- class Includes # :nodoc:
+ class Includes < Base # :nodoc:
def initialize(item)
@item = item
end
- def ==(parameter)
+ def matches?(available_parameters)
+ parameter = available_parameters.shift
return parameter.include?(@item)
end
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/instance_of.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/instance_of.rb
new file mode 100644
index 000000000..49b4a478d
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/instance_of.rb
@@ -0,0 +1,42 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+ module ParameterMatchers
+
+ # :call-seq: instance_of(klass) -> parameter_matcher
+ #
+ # Matches any object that is an instance of +klass+
+ # object = mock()
+ # object.expects(:method_1).with(instance_of(String))
+ # object.method_1('string')
+ # # no error raised
+ #
+ # object = mock()
+ # object.expects(:method_1).with(instance_of(String))
+ # object.method_1(99)
+ # # error raised, because method_1 was not called with an instance of String
+ def instance_of(klass)
+ InstanceOf.new(klass)
+ end
+
+ class InstanceOf < Base # :nodoc:
+
+ def initialize(klass)
+ @klass = klass
+ end
+
+ def matches?(available_parameters)
+ parameter = available_parameters.shift
+ parameter.instance_of?(@klass)
+ end
+
+ def mocha_inspect
+ "instance_of(#{@klass.mocha_inspect})"
+ end
+
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/is_a.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/is_a.rb
new file mode 100644
index 000000000..a721db523
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/is_a.rb
@@ -0,0 +1,42 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+ module ParameterMatchers
+
+ # :call-seq: is_a(klass) -> parameter_matcher
+ #
+ # Matches any object that is a +klass+
+ # object = mock()
+ # object.expects(:method_1).with(is_a(Integer))
+ # object.method_1(99)
+ # # no error raised
+ #
+ # object = mock()
+ # object.expects(:method_1).with(is_a(Integer))
+ # object.method_1('string')
+ # # error raised, because method_1 was not called with an Integer
+ def is_a(klass)
+ IsA.new(klass)
+ end
+
+ class IsA < Base # :nodoc:
+
+ def initialize(klass)
+ @klass = klass
+ end
+
+ def matches?(available_parameters)
+ parameter = available_parameters.shift
+ parameter.is_a?(@klass)
+ end
+
+ def mocha_inspect
+ "is_a(#{@klass.mocha_inspect})"
+ end
+
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/kind_of.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/kind_of.rb
new file mode 100644
index 000000000..710d709d0
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/kind_of.rb
@@ -0,0 +1,42 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+ module ParameterMatchers
+
+ # :call-seq: kind_of(klass) -> parameter_matcher
+ #
+ # Matches any object that is a kind of +klass+
+ # object = mock()
+ # object.expects(:method_1).with(kind_of(Integer))
+ # object.method_1(99)
+ # # no error raised
+ #
+ # object = mock()
+ # object.expects(:method_1).with(kind_of(Integer))
+ # object.method_1('string')
+ # # error raised, because method_1 was not called with a kind of Integer
+ def kind_of(klass)
+ KindOf.new(klass)
+ end
+
+ class KindOf < Base # :nodoc:
+
+ def initialize(klass)
+ @klass = klass
+ end
+
+ def matches?(available_parameters)
+ parameter = available_parameters.shift
+ parameter.kind_of?(@klass)
+ end
+
+ def mocha_inspect
+ "kind_of(#{@klass.mocha_inspect})"
+ end
+
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/not.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/not.rb
new file mode 100644
index 000000000..ec48ade3d
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/not.rb
@@ -0,0 +1,42 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+ module ParameterMatchers
+
+ # :call-seq: Not(matcher) -> parameter_matcher
+ #
+ # Matches if +matcher+ does not match.
+ # object = mock()
+ # object.expects(:method_1).with(Not(includes(1)))
+ # object.method_1([0, 2, 3])
+ # # no error raised
+ #
+ # object = mock()
+ # object.expects(:method_1).with(Not(includes(1)))
+ # object.method_1([0, 1, 2, 3])
+ # # error raised, because method_1 was not called with object not including 1
+ def Not(matcher)
+ Not.new(matcher)
+ end
+
+ class Not < Base # :nodoc:
+
+ def initialize(matcher)
+ @matcher = matcher
+ end
+
+ def matches?(available_parameters)
+ parameter = available_parameters.shift
+ !@matcher.matches?([parameter])
+ end
+
+ def mocha_inspect
+ "Not(#{@matcher.mocha_inspect})"
+ end
+
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/object.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/object.rb
new file mode 100644
index 000000000..f3a639bfa
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/object.rb
@@ -0,0 +1,9 @@
+require 'mocha/parameter_matchers/equals'
+
+class Object
+
+ def to_matcher
+ Mocha::ParameterMatchers::Equals.new(self)
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/optionally.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/optionally.rb
new file mode 100644
index 000000000..bb9625187
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/optionally.rb
@@ -0,0 +1,33 @@
+module Mocha
+
+ module ParameterMatchers
+
+ def optionally(*matchers)
+ Optionally.new(*matchers)
+ end
+
+ class Optionally < Base # :nodoc:
+
+ def initialize(*parameters)
+ @matchers = parameters.map { |parameter| parameter.to_matcher }
+ end
+
+ def matches?(available_parameters)
+ index = 0
+ while (available_parameters.length > 0) && (index < @matchers.length) do
+ matcher = @matchers[index]
+ return false unless matcher.matches?(available_parameters)
+ index += 1
+ end
+ return true
+ end
+
+ def mocha_inspect
+ "optionally(#{@matchers.map { |matcher| matcher.mocha_inspect }.join(", ") })"
+ end
+
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/regexp_matches.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/regexp_matches.rb
new file mode 100644
index 000000000..cc46436eb
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameter_matchers/regexp_matches.rb
@@ -0,0 +1,43 @@
+require 'mocha/parameter_matchers/base'
+
+module Mocha
+
+ module ParameterMatchers
+
+ # :call-seq: regexp_matches(regexp) -> parameter_matcher
+ #
+ # Matches any object that matches the regular expression, +regexp+.
+ # object = mock()
+ # object.expects(:method_1).with(regexp_matches(/e/))
+ # object.method_1('hello')
+ # # no error raised
+ #
+ # object = mock()
+ # object.expects(:method_1).with(regexp_matches(/a/))
+ # object.method_1('hello')
+ # # error raised, because method_1 was not called with a parameter that matched the
+ # # regular expression
+ def regexp_matches(regexp)
+ RegexpMatches.new(regexp)
+ end
+
+ class RegexpMatches < Base # :nodoc:
+
+ def initialize(regexp)
+ @regexp = regexp
+ end
+
+ def matches?(available_parameters)
+ parameter = available_parameters.shift
+ parameter =~ @regexp
+ end
+
+ def mocha_inspect
+ "regexp_matches(#{@regexp.mocha_inspect})"
+ end
+
+ end
+
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/parameters_matcher.rb b/vendor/gems/mocha-0.5.6/lib/mocha/parameters_matcher.rb
new file mode 100644
index 000000000..d43ae4375
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/parameters_matcher.rb
@@ -0,0 +1,37 @@
+require 'mocha/inspect'
+require 'mocha/parameter_matchers'
+
+module Mocha
+
+ class ParametersMatcher
+
+ def initialize(expected_parameters = [ParameterMatchers::AnyParameters.new], &matching_block)
+ @expected_parameters, @matching_block = expected_parameters, matching_block
+ end
+
+ def match?(actual_parameters = [])
+ if @matching_block
+ return @matching_block.call(*actual_parameters)
+ else
+ return parameters_match?(actual_parameters)
+ end
+ end
+
+ def parameters_match?(actual_parameters)
+ matchers.all? { |matcher| matcher.matches?(actual_parameters) } && (actual_parameters.length == 0)
+ end
+
+ def mocha_inspect
+ signature = matchers.mocha_inspect
+ signature = signature.gsub(/^\[|\]$/, '')
+ signature = signature.gsub(/^\{|\}$/, '') if matchers.length == 1
+ "(#{signature})"
+ end
+
+ def matchers
+ @expected_parameters.map { |parameter| parameter.to_matcher }
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/test/lib/mocha/pretty_parameters.rb b/vendor/gems/mocha-0.5.6/lib/mocha/pretty_parameters.rb
index 6d3c165f8..59ed636f8 100644
--- a/test/lib/mocha/pretty_parameters.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/pretty_parameters.rb
@@ -20,7 +20,7 @@ module Mocha
end
def remove_outer_hash_braces!
- @params_string = @params_string.gsub(/^\{|\}$/, '') if @params.size == 1
+ @params_string = @params_string.gsub(/^\{|\}$/, '') if @params.length == 1
end
end
diff --git a/test/lib/mocha/return_values.rb b/vendor/gems/mocha-0.5.6/lib/mocha/return_values.rb
index ea0fbbd40..b4852c5f6 100644
--- a/test/lib/mocha/return_values.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/return_values.rb
@@ -15,10 +15,13 @@ module Mocha # :nodoc:
end
def next
- case @values.size
- when 0: nil
- when 1: @values.first.evaluate
- else @values.shift.evaluate
+ case @values.length
+ when 0
+ nil
+ when 1
+ @values.first.evaluate
+ else
+ @values.shift.evaluate
end
end
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha/sequence.rb b/vendor/gems/mocha-0.5.6/lib/mocha/sequence.rb
new file mode 100644
index 000000000..ed9852e0c
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/sequence.rb
@@ -0,0 +1,42 @@
+module Mocha # :nodoc:
+
+ class Sequence
+
+ class InSequenceOrderingConstraint
+
+ def initialize(sequence, index)
+ @sequence, @index = sequence, index
+ end
+
+ def allows_invocation_now?
+ @sequence.satisfied_to_index?(@index)
+ end
+
+ def mocha_inspect
+ "in sequence #{@sequence.mocha_inspect}"
+ end
+
+ end
+
+ def initialize(name)
+ @name = name
+ @expectations = []
+ end
+
+ def constrain_as_next_in_sequence(expectation)
+ index = @expectations.length
+ @expectations << expectation
+ expectation.add_ordering_constraint(InSequenceOrderingConstraint.new(self, index))
+ end
+
+ def satisfied_to_index?(index)
+ @expectations[0...index].all? { |expectation| expectation.satisfied? }
+ end
+
+ def mocha_inspect
+ "#{@name.mocha_inspect}"
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/test/lib/mocha/setup_and_teardown.rb b/vendor/gems/mocha-0.5.6/lib/mocha/setup_and_teardown.rb
index 034ce1d6b..034ce1d6b 100644
--- a/test/lib/mocha/setup_and_teardown.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/setup_and_teardown.rb
diff --git a/test/lib/mocha/single_return_value.rb b/vendor/gems/mocha-0.5.6/lib/mocha/single_return_value.rb
index f420b8b8c..f420b8b8c 100644
--- a/test/lib/mocha/single_return_value.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/single_return_value.rb
diff --git a/test/lib/mocha/single_yield.rb b/vendor/gems/mocha-0.5.6/lib/mocha/single_yield.rb
index 5af571621..5af571621 100644
--- a/test/lib/mocha/single_yield.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/single_yield.rb
diff --git a/test/lib/mocha/standalone.rb b/vendor/gems/mocha-0.5.6/lib/mocha/standalone.rb
index 8e3a7cefc..8e3a7cefc 100644
--- a/test/lib/mocha/standalone.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/standalone.rb
diff --git a/test/lib/mocha/stub.rb b/vendor/gems/mocha-0.5.6/lib/mocha/stub.rb
index 1b3cccb8a..1b3cccb8a 100644
--- a/test/lib/mocha/stub.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/stub.rb
diff --git a/test/lib/mocha/test_case_adapter.rb b/vendor/gems/mocha-0.5.6/lib/mocha/test_case_adapter.rb
index dc7e33b68..dc7e33b68 100644
--- a/test/lib/mocha/test_case_adapter.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/test_case_adapter.rb
diff --git a/test/lib/mocha/yield_parameters.rb b/vendor/gems/mocha-0.5.6/lib/mocha/yield_parameters.rb
index b1623bf71..cb5898508 100644
--- a/test/lib/mocha/yield_parameters.rb
+++ b/vendor/gems/mocha-0.5.6/lib/mocha/yield_parameters.rb
@@ -11,9 +11,9 @@ module Mocha # :nodoc:
end
def next_invocation
- case @parameter_groups.size
- when 0: NoYields.new
- when 1: @parameter_groups.first
+ case @parameter_groups.length
+ when 0; NoYields.new
+ when 1; @parameter_groups.first
else @parameter_groups.shift
end
end
diff --git a/vendor/gems/mocha-0.5.6/lib/mocha_standalone.rb b/vendor/gems/mocha-0.5.6/lib/mocha_standalone.rb
new file mode 100644
index 000000000..ce605811a
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/mocha_standalone.rb
@@ -0,0 +1,2 @@
+require 'mocha/standalone'
+require 'mocha/object'
diff --git a/vendor/gems/mocha-0.5.6/lib/stubba.rb b/vendor/gems/mocha-0.5.6/lib/stubba.rb
new file mode 100644
index 000000000..eade747f6
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/lib/stubba.rb
@@ -0,0 +1,2 @@
+# for backwards compatibility
+require 'mocha' \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/._deprecation_disabler.rb b/vendor/gems/mocha-0.5.6/test/._deprecation_disabler.rb
new file mode 100644
index 000000000..64a1d063a
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/._deprecation_disabler.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/._execution_point.rb b/vendor/gems/mocha-0.5.6/test/._execution_point.rb
new file mode 100644
index 000000000..dd624fd16
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/._execution_point.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/._method_definer.rb b/vendor/gems/mocha-0.5.6/test/._method_definer.rb
new file mode 100644
index 000000000..d51c1adf4
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/._method_definer.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/._test_helper.rb b/vendor/gems/mocha-0.5.6/test/._test_helper.rb
new file mode 100644
index 000000000..ef386d597
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/._test_helper.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/._test_runner.rb b/vendor/gems/mocha-0.5.6/test/._test_runner.rb
new file mode 100644
index 000000000..614cc3f52
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/._test_runner.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/._expected_invocation_count_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/._expected_invocation_count_acceptance_test.rb
new file mode 100644
index 000000000..86e37bdbb
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/._expected_invocation_count_acceptance_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/._mocha_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/._mocha_acceptance_test.rb
new file mode 100644
index 000000000..39f36f877
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/._mocha_acceptance_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/._mock_with_initializer_block_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/._mock_with_initializer_block_acceptance_test.rb
new file mode 100644
index 000000000..8e3a0e715
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/._mock_with_initializer_block_acceptance_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/._mocked_methods_dispatch_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/._mocked_methods_dispatch_acceptance_test.rb
new file mode 100644
index 000000000..de0671d7e
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/._mocked_methods_dispatch_acceptance_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/._optional_parameters_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/._optional_parameters_acceptance_test.rb
new file mode 100644
index 000000000..b21de1fbc
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/._optional_parameters_acceptance_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/._parameter_matcher_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/._parameter_matcher_acceptance_test.rb
new file mode 100644
index 000000000..421ef5a29
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/._parameter_matcher_acceptance_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/._partial_mocks_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/._partial_mocks_acceptance_test.rb
new file mode 100644
index 000000000..c5650224d
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/._partial_mocks_acceptance_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/._sequence_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/._sequence_acceptance_test.rb
new file mode 100644
index 000000000..8bb33ec9f
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/._sequence_acceptance_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/._standalone_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/._standalone_acceptance_test.rb
new file mode 100644
index 000000000..68a7236cd
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/._standalone_acceptance_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/._stubba_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/._stubba_acceptance_test.rb
new file mode 100644
index 000000000..5140f1228
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/._stubba_acceptance_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/expected_invocation_count_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/expected_invocation_count_acceptance_test.rb
new file mode 100644
index 000000000..c09168cb5
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/expected_invocation_count_acceptance_test.rb
@@ -0,0 +1,187 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha'
+require 'test_runner'
+
+class ExpectedInvocationCountAcceptanceTest < Test::Unit::TestCase
+
+ include TestRunner
+
+ def test_should_pass_if_method_is_never_expected_and_is_never_called
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).never
+ 0.times { mock.method }
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_fail_if_method_is_never_expected_but_is_called_once
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).never
+ 1.times { mock.method }
+ end
+ assert_failed(test_result)
+ failure_messages = test_result.failures.map { |failure| failure.message }
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: 0, actual calls: 1'], failure_messages
+ end
+
+ def test_should_pass_if_method_is_expected_twice_and_is_called_twice
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).times(2)
+ 2.times { mock.method }
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_fail_if_method_is_expected_twice_but_is_called_once
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).times(2)
+ 1.times { mock.method }
+ end
+ assert_failed(test_result)
+ failure_messages = test_result.failures.map { |failure| failure.message }
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: 2, actual calls: 1'], failure_messages
+ end
+
+ def test_should_fail_if_method_is_expected_twice_but_is_called_three_times
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).times(2)
+ 3.times { mock.method }
+ end
+ assert_failed(test_result)
+ failure_messages = test_result.failures.map { |failure| failure.message }
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: 2, actual calls: 3'], failure_messages
+ end
+
+ def test_should_pass_if_method_is_expected_between_two_and_four_times_and_is_called_twice
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).times(2..4)
+ 2.times { mock.method }
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_pass_if_method_is_expected_between_two_and_four_times_and_is_called_three_times
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).times(2..4)
+ 3.times { mock.method }
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_pass_if_method_is_expected_between_two_and_four_times_and_is_called_four_times
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).times(2..4)
+ 4.times { mock.method }
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_fail_if_method_is_expected_between_two_and_four_times_and_is_called_once
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).times(2..4)
+ 1.times { mock.method }
+ end
+ assert_failed(test_result)
+ failure_messages = test_result.failures.map { |failure| failure.message }
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: 2..4, actual calls: 1'], failure_messages
+ end
+
+ def test_should_fail_if_method_is_expected_between_two_and_four_times_and_is_called_five_times
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).times(2..4)
+ 5.times { mock.method }
+ end
+ assert_failed(test_result)
+ failure_messages = test_result.failures.map { |failure| failure.message }
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: 2..4, actual calls: 5'], failure_messages
+ end
+
+ def test_should_pass_if_method_is_expected_at_least_once_and_is_called_once
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).at_least_once
+ 1.times { mock.method }
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_pass_if_method_is_expected_at_least_once_and_is_called_twice
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).at_least_once
+ 2.times { mock.method }
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_fail_if_method_is_expected_at_least_once_but_is_never_called
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).at_least_once
+ 0.times { mock.method }
+ end
+ assert_failed(test_result)
+ failure_messages = test_result.failures.map { |failure| failure.message }
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: at least 1, actual calls: 0'], failure_messages
+ end
+
+ def test_should_pass_if_method_is_expected_at_most_once_and_is_never_called
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).at_most_once
+ 0.times { mock.method }
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_pass_if_method_is_expected_at_most_once_and_called_once
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).at_most_once
+ 1.times { mock.method }
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_fail_if_method_is_expected_at_most_once_but_is_called_twice
+ test_result = run_test do
+ mock = mock('mock')
+ mock.expects(:method).at_most_once
+ 2.times { mock.method }
+ end
+ assert_failed(test_result)
+ failure_messages = test_result.failures.map { |failure| failure.message }
+ assert_equal ['#<Mock:mock>.method(any_parameters) - expected calls: at most 1, actual calls: 2'], failure_messages
+ end
+
+ def test_should_pass_if_method_is_never_expected_and_is_never_called_even_if_everything_is_stubbed
+ test_result = run_test do
+ stub = stub_everything('stub')
+ stub.expects(:method).never
+ 0.times { stub.method }
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_fail_if_method_is_never_expected_but_is_called_once_even_if_everything_is_stubbed
+ test_result = run_test do
+ stub = stub_everything('stub')
+ stub.expects(:method).never
+ 1.times { stub.method }
+ end
+ assert_failed(test_result)
+ failure_messages = test_result.failures.map { |failure| failure.message }
+ assert_equal ['#<Mock:stub>.method(any_parameters) - expected calls: 0, actual calls: 1'], failure_messages
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/mocha_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/mocha_acceptance_test.rb
new file mode 100644
index 000000000..4e38b4e57
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/mocha_acceptance_test.rb
@@ -0,0 +1,98 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha'
+
+class MochaAcceptanceTest < Test::Unit::TestCase
+
+ class Rover
+
+ def initialize(left_track, right_track, steps_per_metre, steps_per_degree)
+ @left_track, @right_track, @steps_per_metre, @steps_per_degree = left_track, right_track, steps_per_metre, steps_per_degree
+ end
+
+ def forward(metres)
+ @left_track.step(metres * @steps_per_metre)
+ @right_track.step(metres * @steps_per_metre)
+ wait
+ end
+
+ def backward(metres)
+ forward(-metres)
+ end
+
+ def left(degrees)
+ @left_track.step(-degrees * @steps_per_degree)
+ @right_track.step(+degrees * @steps_per_degree)
+ wait
+ end
+
+ def right(degrees)
+ left(-degrees)
+ end
+
+ def wait
+ while (@left_track.moving? or @right_track.moving?); end
+ end
+
+ end
+
+ def test_should_step_both_tracks_forward_ten_steps
+ left_track = mock('left_track')
+ right_track = mock('right_track')
+ steps_per_metre = 5
+ rover = Rover.new(left_track, right_track, steps_per_metre, nil)
+
+ left_track.expects(:step).with(10)
+ right_track.expects(:step).with(10)
+
+ left_track.stubs(:moving?).returns(false)
+ right_track.stubs(:moving?).returns(false)
+
+ rover.forward(2)
+ end
+
+ def test_should_step_both_tracks_backward_ten_steps
+ left_track = mock('left_track')
+ right_track = mock('right_track')
+ steps_per_metre = 5
+ rover = Rover.new(left_track, right_track, steps_per_metre, nil)
+
+ left_track.expects(:step).with(-10)
+ right_track.expects(:step).with(-10)
+
+ left_track.stubs(:moving?).returns(false)
+ right_track.stubs(:moving?).returns(false)
+
+ rover.backward(2)
+ end
+
+ def test_should_step_left_track_forwards_five_steps_and_right_track_backwards_five_steps
+ left_track = mock('left_track')
+ right_track = mock('right_track')
+ steps_per_degree = 5.0 / 90.0
+ rover = Rover.new(left_track, right_track, nil, steps_per_degree)
+
+ left_track.expects(:step).with(+5)
+ right_track.expects(:step).with(-5)
+
+ left_track.stubs(:moving?).returns(false)
+ right_track.stubs(:moving?).returns(false)
+
+ rover.right(90)
+ end
+
+ def test_should_step_left_track_backwards_five_steps_and_right_track_forwards_five_steps
+ left_track = mock('left_track')
+ right_track = mock('right_track')
+ steps_per_degree = 5.0 / 90.0
+ rover = Rover.new(left_track, right_track, nil, steps_per_degree)
+
+ left_track.expects(:step).with(-5)
+ right_track.expects(:step).with(+5)
+
+ left_track.stubs(:moving?).returns(false)
+ right_track.stubs(:moving?).returns(false)
+
+ rover.left(90)
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/mock_with_initializer_block_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/mock_with_initializer_block_acceptance_test.rb
new file mode 100644
index 000000000..51488e61f
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/mock_with_initializer_block_acceptance_test.rb
@@ -0,0 +1,44 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha'
+require 'test_runner'
+
+class MockWithInitializerBlockAcceptanceTest < Test::Unit::TestCase
+
+ include TestRunner
+
+ def test_should_expect_two_method_invocations_and_receive_both_of_them
+ test_result = run_test do
+ mock = mock() do
+ expects(:method_1)
+ expects(:method_2)
+ end
+ mock.method_1
+ mock.method_2
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_expect_two_method_invocations_but_receive_only_one_of_them
+ test_result = run_test do
+ mock = mock() do
+ expects(:method_1)
+ expects(:method_2)
+ end
+ mock.method_1
+ end
+ assert_failed(test_result)
+ end
+
+ def test_should_stub_methods
+ test_result = run_test do
+ mock = mock() do
+ stubs(:method_1).returns(1)
+ stubs(:method_2).returns(2)
+ end
+ assert_equal 1, mock.method_1
+ assert_equal 2, mock.method_2
+ end
+ assert_passed(test_result)
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/mocked_methods_dispatch_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/mocked_methods_dispatch_acceptance_test.rb
new file mode 100644
index 000000000..d77021553
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/mocked_methods_dispatch_acceptance_test.rb
@@ -0,0 +1,71 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha'
+require 'test_runner'
+
+class MockedMethodDispatchAcceptanceTest < Test::Unit::TestCase
+
+ include TestRunner
+
+ def test_should_find_latest_matching_expectation
+ test_result = run_test do
+ mock = mock()
+ mock.stubs(:method).returns(1)
+ mock.stubs(:method).returns(2)
+ assert_equal 2, mock.method
+ assert_equal 2, mock.method
+ assert_equal 2, mock.method
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_find_latest_expectation_which_has_not_stopped_matching
+ test_result = run_test do
+ mock = mock()
+ mock.stubs(:method).returns(1)
+ mock.stubs(:method).once.returns(2)
+ assert_equal 2, mock.method
+ assert_equal 1, mock.method
+ assert_equal 1, mock.method
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_keep_finding_later_stub_and_so_never_satisfy_earlier_expectation
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).returns(1)
+ mock.stubs(:method).returns(2)
+ assert_equal 2, mock.method
+ assert_equal 2, mock.method
+ assert_equal 2, mock.method
+ end
+ assert_failed(test_result)
+ end
+
+ def test_should_find_later_expectation_until_it_stops_matching_then_find_earlier_stub
+ test_result = run_test do
+ mock = mock()
+ mock.stubs(:method).returns(1)
+ mock.expects(:method).returns(2)
+ assert_equal 2, mock.method
+ assert_equal 1, mock.method
+ assert_equal 1, mock.method
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_find_latest_expectation_with_range_of_expected_invocation_count_which_has_not_stopped_matching
+ test_result = run_test do
+ mock = mock()
+ mock.stubs(:method).returns(1)
+ mock.stubs(:method).times(2..3).returns(2)
+ assert_equal 2, mock.method
+ assert_equal 2, mock.method
+ assert_equal 2, mock.method
+ assert_equal 1, mock.method
+ assert_equal 1, mock.method
+ end
+ assert_passed(test_result)
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/optional_parameters_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/optional_parameters_acceptance_test.rb
new file mode 100644
index 000000000..3a6f8322e
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/optional_parameters_acceptance_test.rb
@@ -0,0 +1,63 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha'
+require 'test_runner'
+
+class OptionalParameterMatcherAcceptanceTest < Test::Unit::TestCase
+
+ include TestRunner
+
+ def test_should_pass_if_all_required_parameters_match_and_no_optional_parameters_are_supplied
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(1, 2, optionally(3, 4))
+ mock.method(1, 2)
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_pass_if_all_required_and_optional_parameters_match_and_some_optional_parameters_are_supplied
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(1, 2, optionally(3, 4))
+ mock.method(1, 2, 3)
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_pass_if_all_required_and_optional_parameters_match_and_all_optional_parameters_are_supplied
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(1, 2, optionally(3, 4))
+ mock.method(1, 2, 3, 4)
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_fail_if_all_required_and_optional_parameters_match_but_too_many_optional_parameters_are_supplied
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(1, 2, optionally(3, 4))
+ mock.method(1, 2, 3, 4, 5)
+ end
+ assert_failed(test_result)
+ end
+
+ def test_should_fail_if_all_required_parameters_match_but_some_optional_parameters_do_not_match
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(1, 2, optionally(3, 4))
+ mock.method(1, 2, 4)
+ end
+ assert_failed(test_result)
+ end
+
+ def test_should_fail_if_all_required_parameters_match_but_no_optional_parameters_match
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(1, 2, optionally(3, 4))
+ mock.method(1, 2, 4, 5)
+ end
+ assert_failed(test_result)
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/parameter_matcher_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/parameter_matcher_acceptance_test.rb
new file mode 100644
index 000000000..c23880d16
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/parameter_matcher_acceptance_test.rb
@@ -0,0 +1,117 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha'
+require 'test_runner'
+
+class ParameterMatcherAcceptanceTest < Test::Unit::TestCase
+
+ include TestRunner
+
+ def test_should_match_hash_parameter_with_specified_key
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(has_key(:key_1))
+ mock.method(:key_1 => 'value_1', :key_2 => 'value_2')
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_not_match_hash_parameter_with_specified_key
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(has_key(:key_1))
+ mock.method(:key_2 => 'value_2')
+ end
+ assert_failed(test_result)
+ end
+
+ def test_should_match_hash_parameter_with_specified_value
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(has_value('value_1'))
+ mock.method(:key_1 => 'value_1', :key_2 => 'value_2')
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_not_match_hash_parameter_with_specified_value
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(has_value('value_1'))
+ mock.method(:key_2 => 'value_2')
+ end
+ assert_failed(test_result)
+ end
+
+ def test_should_match_hash_parameter_with_specified_key_value_pair
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(has_entry(:key_1, 'value_1'))
+ mock.method(:key_1 => 'value_1', :key_2 => 'value_2')
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_not_match_hash_parameter_with_specified_key_value_pair
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(has_entry(:key_1, 'value_2'))
+ mock.method(:key_1 => 'value_1', :key_2 => 'value_2')
+ end
+ assert_failed(test_result)
+ end
+
+ def test_should_match_hash_parameter_with_specified_hash_entry
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(has_entry(:key_1 => 'value_1'))
+ mock.method(:key_1 => 'value_1', :key_2 => 'value_2')
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_not_match_hash_parameter_with_specified_hash_entry
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(has_entry(:key_1 => 'value_2'))
+ mock.method(:key_1 => 'value_1', :key_2 => 'value_2')
+ end
+ assert_failed(test_result)
+ end
+
+ def test_should_match_hash_parameter_with_specified_entries
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(has_entries(:key_1 => 'value_1', :key_2 => 'value_2'))
+ mock.method(:key_1 => 'value_1', :key_2 => 'value_2', :key_3 => 'value_3')
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_not_match_hash_parameter_with_specified_entries
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(has_entries(:key_1 => 'value_1', :key_2 => 'value_2'))
+ mock.method(:key_1 => 'value_1', :key_2 => 'value_3')
+ end
+ assert_failed(test_result)
+ end
+
+ def test_should_match_parameter_that_matches_regular_expression
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(regexp_matches(/meter/))
+ mock.method('this parameter should match')
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_not_match_parameter_that_does_not_match_regular_expression
+ test_result = run_test do
+ mock = mock()
+ mock.expects(:method).with(regexp_matches(/something different/))
+ mock.method('this parameter should not match')
+ end
+ assert_failed(test_result)
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/partial_mocks_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/partial_mocks_acceptance_test.rb
new file mode 100644
index 000000000..20fc7b84e
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/partial_mocks_acceptance_test.rb
@@ -0,0 +1,40 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha'
+require 'test_runner'
+
+class PartialMockAcceptanceTest < Test::Unit::TestCase
+
+ include TestRunner
+
+ def test_should_pass_if_all_expectations_are_satisfied
+ test_result = run_test do
+ partial_mock_one = "partial_mock_one"
+ partial_mock_two = "partial_mock_two"
+
+ partial_mock_one.expects(:first)
+ partial_mock_one.expects(:second)
+ partial_mock_two.expects(:third)
+
+ partial_mock_one.first
+ partial_mock_one.second
+ partial_mock_two.third
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_fail_if_all_expectations_are_not_satisfied
+ test_result = run_test do
+ partial_mock_one = "partial_mock_one"
+ partial_mock_two = "partial_mock_two"
+
+ partial_mock_one.expects(:first)
+ partial_mock_one.expects(:second)
+ partial_mock_two.expects(:third)
+
+ partial_mock_one.first
+ partial_mock_two.third
+ end
+ assert_failed(test_result)
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/sequence_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/sequence_acceptance_test.rb
new file mode 100644
index 000000000..3be6e7d75
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/sequence_acceptance_test.rb
@@ -0,0 +1,179 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha'
+require 'test_runner'
+
+class SequenceAcceptanceTest < Test::Unit::TestCase
+
+ include TestRunner
+
+ def test_should_constrain_invocations_to_occur_in_expected_order
+ test_result = run_test do
+ mock = mock()
+ sequence = sequence('one')
+
+ mock.expects(:first).in_sequence(sequence)
+ mock.expects(:second).in_sequence(sequence)
+
+ mock.second
+ end
+ assert_failed(test_result)
+ end
+
+ def test_should_allow_invocations_in_sequence
+ test_result = run_test do
+ mock = mock()
+ sequence = sequence('one')
+
+ mock.expects(:first).in_sequence(sequence)
+ mock.expects(:second).in_sequence(sequence)
+
+ mock.first
+ mock.second
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_constrain_invocations_to_occur_in_expected_order_even_if_expected_on_different_mocks
+ test_result = run_test do
+ mock_one = mock('1')
+ mock_two = mock('2')
+ sequence = sequence('one')
+
+ mock_one.expects(:first).in_sequence(sequence)
+ mock_two.expects(:second).in_sequence(sequence)
+
+ mock_two.second
+ end
+ assert_failed(test_result)
+ end
+
+ def test_should_allow_invocations_in_sequence_even_if_expected_on_different_mocks
+ test_result = run_test do
+ mock_one = mock('1')
+ mock_two = mock('2')
+ sequence = sequence('one')
+
+ mock_one.expects(:first).in_sequence(sequence)
+ mock_two.expects(:second).in_sequence(sequence)
+
+ mock_one.first
+ mock_two.second
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_constrain_invocations_to_occur_in_expected_order_even_if_expected_on_partial_mocks
+ test_result = run_test do
+ partial_mock_one = "1"
+ partial_mock_two = "2"
+ sequence = sequence('one')
+
+ partial_mock_one.expects(:first).in_sequence(sequence)
+ partial_mock_two.expects(:second).in_sequence(sequence)
+
+ partial_mock_two.second
+ end
+ assert_failed(test_result)
+ end
+
+ def test_should_allow_invocations_in_sequence_even_if_expected_on_partial_mocks
+ test_result = run_test do
+ partial_mock_one = "1"
+ partial_mock_two = "2"
+ sequence = sequence('one')
+
+ partial_mock_one.expects(:first).in_sequence(sequence)
+ partial_mock_two.expects(:second).in_sequence(sequence)
+
+ partial_mock_one.first
+ partial_mock_two.second
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_allow_stub_expectations_to_be_skipped_in_sequence
+ test_result = run_test do
+ mock = mock()
+ sequence = sequence('one')
+
+ mock.expects(:first).in_sequence(sequence)
+ s = mock.stubs(:second).in_sequence(sequence)
+ mock.expects(:third).in_sequence(sequence)
+
+ mock.first
+ mock.third
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_regard_sequences_as_independent_of_each_other
+ test_result = run_test do
+ mock = mock()
+ sequence_one = sequence('one')
+ sequence_two = sequence('two')
+
+ mock.expects(:first).in_sequence(sequence_one)
+ mock.expects(:second).in_sequence(sequence_one)
+
+ mock.expects(:third).in_sequence(sequence_two)
+ mock.expects(:fourth).in_sequence(sequence_two)
+
+ mock.first
+ mock.third
+ mock.second
+ mock.fourth
+ end
+ assert_passed(test_result)
+ end
+
+ def test_should_include_sequence_in_failure_message
+ test_result = run_test do
+ mock = mock()
+ sequence = sequence('one')
+
+ mock.expects(:first).in_sequence(sequence)
+ mock.expects(:second).in_sequence(sequence)
+
+ mock.second
+ end
+ assert_failed(test_result)
+ assert_match Regexp.new("in sequence 'one'"), test_result.failures.first.message
+ end
+
+ def test_should_allow_expectations_to_be_in_more_than_one_sequence
+ test_result = run_test do
+ mock = mock()
+ sequence_one = sequence('one')
+ sequence_two = sequence('two')
+
+ mock.expects(:first).in_sequence(sequence_one)
+ mock.expects(:second).in_sequence(sequence_two)
+ mock.expects(:three).in_sequence(sequence_one).in_sequence(sequence_two)
+
+ mock.first
+ mock.three
+ end
+ assert_failed(test_result)
+ assert_match Regexp.new("in sequence 'one'"), test_result.failures.first.message
+ assert_match Regexp.new("in sequence 'two'"), test_result.failures.first.message
+ end
+
+ def test_should_have_shortcut_for_expectations_to_be_in_more_than_one_sequence
+ test_result = run_test do
+ mock = mock()
+ sequence_one = sequence('one')
+ sequence_two = sequence('two')
+
+ mock.expects(:first).in_sequence(sequence_one)
+ mock.expects(:second).in_sequence(sequence_two)
+ mock.expects(:three).in_sequence(sequence_one, sequence_two)
+
+ mock.first
+ mock.three
+ end
+ assert_failed(test_result)
+ assert_match Regexp.new("in sequence 'one'"), test_result.failures.first.message
+ assert_match Regexp.new("in sequence 'two'"), test_result.failures.first.message
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/standalone_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/standalone_acceptance_test.rb
new file mode 100644
index 000000000..1e101d7ca
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/standalone_acceptance_test.rb
@@ -0,0 +1,131 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha_standalone'
+
+class NotATestUnitAssertionFailedError < StandardError
+end
+
+class NotATestUnitTestCase
+
+ include Mocha::Standalone
+
+ attr_reader :assertion_count
+
+ def initialize
+ @assertion_count = 0
+ end
+
+ def run(test_method)
+ mocha_setup
+ begin
+ prepare
+ begin
+ send(test_method)
+ mocha_verify { @assertion_count += 1 }
+ rescue Mocha::ExpectationError => e
+ new_error = NotATestUnitAssertionFailedError.new(e.message)
+ new_error.set_backtrace(e.backtrace)
+ raise new_error
+ ensure
+ cleanup
+ end
+ ensure
+ mocha_teardown
+ end
+ end
+
+ def prepare
+ end
+
+ def cleanup
+ end
+
+end
+
+class SampleTest < NotATestUnitTestCase
+
+ def mocha_with_fulfilled_expectation
+ mockee = mock()
+ mockee.expects(:blah)
+ mockee.blah
+ end
+
+ def mocha_with_unfulfilled_expectation
+ mockee = mock()
+ mockee.expects(:blah)
+ end
+
+ def mocha_with_unexpected_invocation
+ mockee = mock()
+ mockee.blah
+ end
+
+ def stubba_with_fulfilled_expectation
+ stubbee = Class.new { define_method(:blah) {} }.new
+ stubbee.expects(:blah)
+ stubbee.blah
+ end
+
+ def stubba_with_unfulfilled_expectation
+ stubbee = Class.new { define_method(:blah) {} }.new
+ stubbee.expects(:blah)
+ end
+
+ def mocha_with_matching_parameter
+ mockee = mock()
+ mockee.expects(:blah).with(has_key(:wibble))
+ mockee.blah(:wibble => 1)
+ end
+
+ def mocha_with_non_matching_parameter
+ mockee = mock()
+ mockee.expects(:blah).with(has_key(:wibble))
+ mockee.blah(:wobble => 2)
+ end
+
+end
+
+require 'test/unit'
+
+class StandaloneAcceptanceTest < Test::Unit::TestCase
+
+ attr_reader :sample_test
+
+ def setup
+ @sample_test = SampleTest.new
+ end
+
+ def test_should_pass_mocha_test
+ assert_nothing_raised { sample_test.run(:mocha_with_fulfilled_expectation) }
+ assert_equal 1, sample_test.assertion_count
+ end
+
+ def test_should_fail_mocha_test_due_to_unfulfilled_exception
+ assert_raises(NotATestUnitAssertionFailedError) { sample_test.run(:mocha_with_unfulfilled_expectation) }
+ assert_equal 1, sample_test.assertion_count
+ end
+
+ def test_should_fail_mocha_test_due_to_unexpected_invocation
+ assert_raises(NotATestUnitAssertionFailedError) { sample_test.run(:mocha_with_unexpected_invocation) }
+ assert_equal 0, sample_test.assertion_count
+ end
+
+ def test_should_pass_stubba_test
+ assert_nothing_raised { sample_test.run(:stubba_with_fulfilled_expectation) }
+ assert_equal 1, sample_test.assertion_count
+ end
+
+ def test_should_fail_stubba_test
+ assert_raises(NotATestUnitAssertionFailedError) { sample_test.run(:stubba_with_unfulfilled_expectation) }
+ assert_equal 1, sample_test.assertion_count
+ end
+
+ def test_should_pass_mocha_test_with_matching_parameter
+ assert_nothing_raised { sample_test.run(:mocha_with_matching_parameter) }
+ assert_equal 1, sample_test.assertion_count
+ end
+
+ def test_should_fail_mocha_test_with_non_matching_parameter
+ assert_raises(NotATestUnitAssertionFailedError) { sample_test.run(:mocha_with_non_matching_parameter) }
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/acceptance/stubba_acceptance_test.rb b/vendor/gems/mocha-0.5.6/test/acceptance/stubba_acceptance_test.rb
new file mode 100644
index 000000000..93d8d1259
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/acceptance/stubba_acceptance_test.rb
@@ -0,0 +1,102 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha'
+
+class Widget
+
+ def model
+ 'original_model'
+ end
+
+ class << self
+
+ def find(options)
+ []
+ end
+
+ def create(attributes)
+ Widget.new
+ end
+
+ end
+
+end
+
+module Thingy
+
+ def self.wotsit
+ :hoojamaflip
+ end
+
+end
+
+class StubbaAcceptanceTest < Test::Unit::TestCase
+
+ def test_should_stub_instance_method
+ widget = Widget.new
+ widget.expects(:model).returns('different_model')
+ assert_equal 'different_model', widget.model
+ end
+
+ def test_should_stub_module_method
+ should_stub_module_method
+ end
+
+ def test_should_stub_module_method_again
+ should_stub_module_method
+ end
+
+ def test_should_stub_class_method
+ should_stub_class_method
+ end
+
+ def test_should_stub_class_method_again
+ should_stub_class_method
+ end
+
+ def test_should_stub_instance_method_on_any_instance_of_a_class
+ should_stub_instance_method_on_any_instance_of_a_class
+ end
+
+ def test_should_stub_instance_method_on_any_instance_of_a_class_again
+ should_stub_instance_method_on_any_instance_of_a_class
+ end
+
+ def test_should_stub_two_different_class_methods
+ should_stub_two_different_class_methods
+ end
+
+ def test_should_stub_two_different_class_methods_again
+ should_stub_two_different_class_methods
+ end
+
+ private
+
+ def should_stub_module_method
+ Thingy.expects(:wotsit).returns(:dooda)
+ assert_equal :dooda, Thingy.wotsit
+ end
+
+ def should_stub_class_method
+ widgets = [Widget.new]
+ Widget.expects(:find).with(:all).returns(widgets)
+ assert_equal widgets, Widget.find(:all)
+ end
+
+ def should_stub_two_different_class_methods
+ found_widgets = [Widget.new]
+ created_widget = Widget.new
+ Widget.expects(:find).with(:all).returns(found_widgets)
+ Widget.expects(:create).with(:model => 'wombat').returns(created_widget)
+ assert_equal found_widgets, Widget.find(:all)
+ assert_equal created_widget, Widget.create(:model => 'wombat')
+ end
+
+ def should_stub_instance_method_on_any_instance_of_a_class
+ Widget.any_instance.expects(:model).at_least_once.returns('another_model')
+ widget_1 = Widget.new
+ widget_2 = Widget.new
+ assert_equal 'another_model', widget_1.model
+ assert_equal 'another_model', widget_2.model
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/active_record_test_case.rb b/vendor/gems/mocha-0.5.6/test/active_record_test_case.rb
new file mode 100644
index 000000000..ae6507380
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/active_record_test_case.rb
@@ -0,0 +1,36 @@
+module ActiveRecordTestCase
+
+ def setup_with_fixtures
+ methods_called << :setup_with_fixtures
+ end
+
+ alias_method :setup, :setup_with_fixtures
+
+ def teardown_with_fixtures
+ methods_called << :teardown_with_fixtures
+ end
+
+ alias_method :teardown, :teardown_with_fixtures
+
+ def self.method_added(method)
+ case method.to_s
+ when 'setup'
+ unless method_defined?(:setup_without_fixtures)
+ alias_method :setup_without_fixtures, :setup
+ define_method(:setup) do
+ setup_with_fixtures
+ setup_without_fixtures
+ end
+ end
+ when 'teardown'
+ unless method_defined?(:teardown_without_fixtures)
+ alias_method :teardown_without_fixtures, :teardown
+ define_method(:teardown) do
+ teardown_without_fixtures
+ teardown_with_fixtures
+ end
+ end
+ end
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/deprecation_disabler.rb b/vendor/gems/mocha-0.5.6/test/deprecation_disabler.rb
new file mode 100644
index 000000000..c57fb3c9a
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/deprecation_disabler.rb
@@ -0,0 +1,15 @@
+require 'mocha/deprecation'
+
+module DeprecationDisabler
+
+ def disable_deprecations
+ original_mode = Mocha::Deprecation.mode
+ Mocha::Deprecation.mode = :disabled
+ begin
+ yield
+ ensure
+ Mocha::Deprecation.mode = original_mode
+ end
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/execution_point.rb b/vendor/gems/mocha-0.5.6/test/execution_point.rb
new file mode 100644
index 000000000..33c85699e
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/execution_point.rb
@@ -0,0 +1,34 @@
+class ExecutionPoint
+
+ attr_reader :backtrace
+
+ def self.current
+ new(caller)
+ end
+
+ def initialize(backtrace)
+ @backtrace = backtrace
+ end
+
+ def file_name
+ /\A(.*?):\d+/.match(@backtrace.first)[1]
+ end
+
+ def line_number
+ Integer(/\A.*?:(\d+)/.match(@backtrace.first)[1])
+ end
+
+ def ==(other)
+ return false unless other.is_a?(ExecutionPoint)
+ (file_name == other.file_name) and (line_number == other.line_number)
+ end
+
+ def to_s
+ "file: #{file_name} line: #{line_number}"
+ end
+
+ def inspect
+ to_s
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/integration/._mocha_test_result_integration_test.rb b/vendor/gems/mocha-0.5.6/test/integration/._mocha_test_result_integration_test.rb
new file mode 100644
index 000000000..78cbfbe92
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/integration/._mocha_test_result_integration_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/integration/._stubba_integration_test.rb b/vendor/gems/mocha-0.5.6/test/integration/._stubba_integration_test.rb
new file mode 100644
index 000000000..c88497c45
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/integration/._stubba_integration_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/integration/._stubba_test_result_integration_test.rb b/vendor/gems/mocha-0.5.6/test/integration/._stubba_test_result_integration_test.rb
new file mode 100644
index 000000000..931f6315d
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/integration/._stubba_test_result_integration_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/integration/mocha_test_result_integration_test.rb b/vendor/gems/mocha-0.5.6/test/integration/mocha_test_result_integration_test.rb
new file mode 100644
index 000000000..d5f29e845
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/integration/mocha_test_result_integration_test.rb
@@ -0,0 +1,105 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/standalone'
+require 'mocha/test_case_adapter'
+require 'execution_point'
+
+class MochaTestResultIntegrationTest < Test::Unit::TestCase
+
+ def test_should_include_expectation_verification_in_assertion_count
+ test_result = run_test do
+ object = mock()
+ object.expects(:message)
+ object.message
+ end
+ assert_equal 1, test_result.assertion_count
+ end
+
+ def test_should_include_assertions_in_assertion_count
+ test_result = run_test do
+ assert true
+ end
+ assert_equal 1, test_result.assertion_count
+ end
+
+ def test_should_not_include_stubbing_expectation_verification_in_assertion_count
+ test_result = run_test do
+ object = mock()
+ object.stubs(:message)
+ object.message
+ end
+ assert_equal 0, test_result.assertion_count
+ end
+
+ def test_should_include_expectation_verification_failure_in_failure_count
+ test_result = run_test do
+ object = mock()
+ object.expects(:message)
+ end
+ assert_equal 1, test_result.failure_count
+ end
+
+ def test_should_include_unexpected_verification_failure_in_failure_count
+ test_result = run_test do
+ object = mock()
+ object.message
+ end
+ assert_equal 1, test_result.failure_count
+ end
+
+ def test_should_include_assertion_failure_in_failure_count
+ test_result = run_test do
+ flunk
+ end
+ assert_equal 1, test_result.failure_count
+ end
+
+ def test_should_display_backtrace_indicating_line_number_where_expects_was_called
+ test_result = Test::Unit::TestResult.new
+ faults = []
+ test_result.add_listener(Test::Unit::TestResult::FAULT, &lambda { |fault| faults << fault })
+ execution_point = nil
+ run_test(test_result) do
+ object = mock()
+ execution_point = ExecutionPoint.current; object.expects(:message)
+ end
+ assert_equal 1, faults.length
+ assert_equal execution_point, ExecutionPoint.new(faults.first.location)
+ end
+
+ def test_should_display_backtrace_indicating_line_number_where_unexpected_method_was_called
+ test_result = Test::Unit::TestResult.new
+ faults = []
+ test_result.add_listener(Test::Unit::TestResult::FAULT, &lambda { |fault| faults << fault })
+ execution_point = nil
+ run_test(test_result) do
+ object = mock()
+ execution_point = ExecutionPoint.current; object.message
+ end
+ assert_equal 1, faults.length
+ assert_equal execution_point, ExecutionPoint.new(faults.first.location)
+ end
+
+ def test_should_display_backtrace_indicating_line_number_where_failing_assertion_was_called
+ test_result = Test::Unit::TestResult.new
+ faults = []
+ test_result.add_listener(Test::Unit::TestResult::FAULT, &lambda { |fault| faults << fault })
+ execution_point = nil
+ run_test(test_result) do
+ execution_point = ExecutionPoint.current; flunk
+ end
+ assert_equal 1, faults.length
+ assert_equal execution_point, ExecutionPoint.new(faults.first.location)
+ end
+
+ def run_test(test_result = Test::Unit::TestResult.new, &block)
+ test_class = Class.new(Test::Unit::TestCase) do
+ include Mocha::Standalone
+ include Mocha::TestCaseAdapter
+ define_method(:test_me, &block)
+ end
+ test = test_class.new(:test_me)
+ test.run(test_result) {}
+ test_result
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/integration/stubba_integration_test.rb b/vendor/gems/mocha-0.5.6/test/integration/stubba_integration_test.rb
new file mode 100644
index 000000000..4285c179a
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/integration/stubba_integration_test.rb
@@ -0,0 +1,89 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+
+require 'mocha/object'
+require 'mocha/test_case_adapter'
+require 'mocha/standalone'
+
+class StubbaIntegrationTest < Test::Unit::TestCase
+
+ class DontMessWithMe
+ def self.my_class_method
+ :original_return_value
+ end
+ def my_instance_method
+ :original_return_value
+ end
+ end
+
+ def test_should_stub_class_method_within_test
+ test = build_test do
+ DontMessWithMe.expects(:my_class_method).returns(:new_return_value)
+ assert_equal :new_return_value, DontMessWithMe.my_class_method
+ end
+
+ test_result = Test::Unit::TestResult.new
+ test.run(test_result) {}
+ assert test_result.passed?
+ end
+
+ def test_should_leave_stubbed_class_method_unchanged_after_test
+ test = build_test do
+ DontMessWithMe.expects(:my_class_method).returns(:new_return_value)
+ end
+
+ test.run(Test::Unit::TestResult.new) {}
+ assert_equal :original_return_value, DontMessWithMe.my_class_method
+ end
+
+ def test_should_reset_class_expectations_after_test
+ test = build_test do
+ DontMessWithMe.expects(:my_class_method)
+ end
+
+ test.run(Test::Unit::TestResult.new) {}
+ assert_equal 0, DontMessWithMe.mocha.expectations.length
+ end
+
+ def test_should_stub_instance_method_within_test
+ instance = DontMessWithMe.new
+ test = build_test do
+ instance.expects(:my_instance_method).returns(:new_return_value)
+ assert_equal :new_return_value, instance.my_instance_method
+ end
+ test_result = Test::Unit::TestResult.new
+ test.run(test_result) {}
+ assert test_result.passed?
+ end
+
+ def test_should_leave_stubbed_instance_method_unchanged_after_test
+ instance = DontMessWithMe.new
+ test = build_test do
+ instance.expects(:my_instance_method).returns(:new_return_value)
+ end
+
+ test.run(Test::Unit::TestResult.new) {}
+ assert_equal :original_return_value, instance.my_instance_method
+ end
+
+ def test_should_reset_instance_expectations_after_test
+ instance = DontMessWithMe.new
+ test = build_test do
+ instance.expects(:my_instance_method).returns(:new_return_value)
+ end
+
+ test.run(Test::Unit::TestResult.new) {}
+ assert_equal 0, instance.mocha.expectations.length
+ end
+
+ private
+
+ def build_test(&block)
+ test_class = Class.new(Test::Unit::TestCase) do
+ include Mocha::Standalone
+ include Mocha::TestCaseAdapter
+ define_method(:test_me, &block)
+ end
+ test_class.new(:test_me)
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/integration/stubba_test_result_integration_test.rb b/vendor/gems/mocha-0.5.6/test/integration/stubba_test_result_integration_test.rb
new file mode 100644
index 000000000..34264e7c6
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/integration/stubba_test_result_integration_test.rb
@@ -0,0 +1,85 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/object'
+require 'mocha/standalone'
+require 'mocha/test_case_adapter'
+require 'execution_point'
+
+class StubbaTestResultIntegrationTest < Test::Unit::TestCase
+
+ def test_should_include_expectation_verification_in_assertion_count
+ test_result = run_test do
+ object = Class.new { def message; end }.new
+ object.expects(:message)
+ object.message
+ end
+ assert_equal 1, test_result.assertion_count
+ end
+
+ def test_should_include_assertions_in_assertion_count
+ test_result = run_test do
+ assert true
+ end
+ assert_equal 1, test_result.assertion_count
+ end
+
+ def test_should_not_include_stubbing_expectation_verification_in_assertion_count
+ test_result = run_test do
+ object = Class.new { def message; end }.new
+ object.stubs(:message)
+ object.message
+ end
+ assert_equal 0, test_result.assertion_count
+ end
+
+ def test_should_include_expectation_verification_failure_in_failure_count
+ test_result = run_test do
+ object = Class.new { def message; end }.new
+ object.expects(:message)
+ end
+ assert_equal 1, test_result.failure_count
+ end
+
+ def test_should_include_assertion_failure_in_failure_count
+ test_result = run_test do
+ flunk
+ end
+ assert_equal 1, test_result.failure_count
+ end
+
+ def test_should_display_backtrace_indicating_line_number_where_expects_was_called
+ test_result = Test::Unit::TestResult.new
+ faults = []
+ test_result.add_listener(Test::Unit::TestResult::FAULT, &lambda { |fault| faults << fault })
+ execution_point = nil
+ run_test(test_result) do
+ object = Class.new { def message; end }.new
+ execution_point = ExecutionPoint.current; object.expects(:message)
+ end
+ assert_equal 1, faults.length
+ assert_equal execution_point, ExecutionPoint.new(faults.first.location)
+ end
+
+ def test_should_display_backtrace_indicating_line_number_where_failing_assertion_was_called
+ test_result = Test::Unit::TestResult.new
+ faults = []
+ test_result.add_listener(Test::Unit::TestResult::FAULT, &lambda { |fault| faults << fault })
+ execution_point = nil
+ run_test(test_result) do
+ execution_point = ExecutionPoint.current; flunk
+ end
+ assert_equal 1, faults.length
+ assert_equal execution_point, ExecutionPoint.new(faults.first.location)
+ end
+
+ def run_test(test_result = Test::Unit::TestResult.new, &block)
+ test_class = Class.new(Test::Unit::TestCase) do
+ include Mocha::Standalone
+ include Mocha::TestCaseAdapter
+ define_method(:test_me, &block)
+ end
+ test = test_class.new(:test_me)
+ test.run(test_result) {}
+ test_result
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/method_definer.rb b/vendor/gems/mocha-0.5.6/test/method_definer.rb
new file mode 100644
index 000000000..1aef8868b
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/method_definer.rb
@@ -0,0 +1,18 @@
+require 'mocha/metaclass'
+
+class Object
+
+ def define_instance_method(method_symbol, &block)
+ __metaclass__.send(:define_method, method_symbol, block)
+ end
+
+ def replace_instance_method(method_symbol, &block)
+ raise "Cannot replace #{method_symbol} as #{self} does not respond to it." unless self.respond_to?(method_symbol)
+ define_instance_method(method_symbol, &block)
+ end
+
+ def define_instance_accessor(*symbols)
+ symbols.each { |symbol| __metaclass__.send(:attr_accessor, symbol) }
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/test_helper.rb b/vendor/gems/mocha-0.5.6/test/test_helper.rb
new file mode 100644
index 000000000..dc0494273
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/test_helper.rb
@@ -0,0 +1,12 @@
+unless defined?(STANDARD_OBJECT_PUBLIC_INSTANCE_METHODS)
+ STANDARD_OBJECT_PUBLIC_INSTANCE_METHODS = Object.public_instance_methods
+end
+
+$:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
+$:.unshift File.expand_path(File.join(File.dirname(__FILE__)))
+$:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'unit'))
+$:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'unit', 'parameter_matchers'))
+$:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'integration'))
+$:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'acceptance'))
+
+require 'test/unit' \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/test_runner.rb b/vendor/gems/mocha-0.5.6/test/test_runner.rb
new file mode 100644
index 000000000..fbadd9297
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/test_runner.rb
@@ -0,0 +1,31 @@
+require 'test/unit/testresult'
+require 'test/unit/testcase'
+require 'mocha/standalone'
+require 'mocha/test_case_adapter'
+
+module TestRunner
+
+ def run_test(test_result = Test::Unit::TestResult.new, &block)
+ test_class = Class.new(Test::Unit::TestCase) do
+ include Mocha::Standalone
+ include Mocha::TestCaseAdapter
+ define_method(:test_me, &block)
+ end
+ test = test_class.new(:test_me)
+ test.run(test_result) {}
+ class << test_result
+ attr_reader :failures, :errors
+ end
+ test_result
+ end
+
+ def assert_passed(test_result)
+ flunk "Test failed unexpectedly with message: #{test_result.failures}" if test_result.failure_count > 0
+ flunk "Test failed unexpectedly with message: #{test_result.errors}" if test_result.error_count > 0
+ end
+
+ def assert_failed(test_result)
+ flunk "Test passed unexpectedly" if test_result.passed?
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._any_instance_method_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._any_instance_method_test.rb
new file mode 100644
index 000000000..83d91fdf2
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._any_instance_method_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._auto_verify_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._auto_verify_test.rb
new file mode 100644
index 000000000..9052afc95
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._auto_verify_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._central_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._central_test.rb
new file mode 100644
index 000000000..a8cc77d1a
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._central_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._class_method_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._class_method_test.rb
new file mode 100644
index 000000000..30c6ce8de
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._class_method_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._expectation_error_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._expectation_error_test.rb
new file mode 100644
index 000000000..6bd7f7152
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._expectation_error_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._expectation_list_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._expectation_list_test.rb
new file mode 100644
index 000000000..753636a0f
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._expectation_list_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._expectation_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._expectation_test.rb
new file mode 100644
index 000000000..b92a766c0
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._expectation_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._hash_inspect_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._hash_inspect_test.rb
new file mode 100644
index 000000000..2d092d906
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._hash_inspect_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._method_matcher_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._method_matcher_test.rb
new file mode 100644
index 000000000..5de837673
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._method_matcher_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._missing_expectation_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._missing_expectation_test.rb
new file mode 100644
index 000000000..166d7827f
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._missing_expectation_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._mock_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._mock_test.rb
new file mode 100644
index 000000000..e9005d167
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._mock_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._object_inspect_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._object_inspect_test.rb
new file mode 100644
index 000000000..e39ba3134
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._object_inspect_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._parameters_matcher_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._parameters_matcher_test.rb
new file mode 100644
index 000000000..ca04d98e7
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._parameters_matcher_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/._sequence_test.rb b/vendor/gems/mocha-0.5.6/test/unit/._sequence_test.rb
new file mode 100644
index 000000000..ec9e9d76e
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/._sequence_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/any_instance_method_test.rb b/vendor/gems/mocha-0.5.6/test/unit/any_instance_method_test.rb
new file mode 100644
index 000000000..804fcde2b
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/any_instance_method_test.rb
@@ -0,0 +1,126 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'method_definer'
+require 'mocha/mock'
+require 'mocha/any_instance_method'
+
+class AnyInstanceMethodTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_hide_original_method
+ klass = Class.new { def method_x; end }
+ method = AnyInstanceMethod.new(klass, :method_x)
+ hidden_method_x = method.hidden_method.to_sym
+
+ method.hide_original_method
+
+ assert klass.method_defined?(hidden_method_x)
+ end
+
+ def test_should_not_hide_original_method_if_it_is_not_defined
+ klass = Class.new
+ method = AnyInstanceMethod.new(klass, :method_x)
+ hidden_method_x = method.hidden_method.to_sym
+
+ method.hide_original_method
+
+ assert_equal false, klass.method_defined?(hidden_method_x)
+ end
+
+ def test_should_define_a_new_method
+ klass = Class.new { def method_x; end }
+ method = AnyInstanceMethod.new(klass, :method_x)
+ mocha = Mock.new
+ mocha.expects(:method_x).with(:param1, :param2).returns(:result)
+ any_instance = Object.new
+ any_instance.define_instance_method(:mocha) { mocha }
+ klass.define_instance_method(:any_instance) { any_instance }
+
+ method.hide_original_method
+ method.define_new_method
+
+ instance = klass.new
+ result = instance.method_x(:param1, :param2)
+
+ assert_equal :result, result
+ mocha.verify
+ end
+
+ def test_should_restore_original_method
+ klass = Class.new { def method_x; end }
+ method = AnyInstanceMethod.new(klass, :method_x)
+ hidden_method_x = method.hidden_method.to_sym
+ klass.send(:define_method, hidden_method_x, Proc.new { :original_result })
+
+ method.remove_new_method
+ method.restore_original_method
+
+ instance = klass.new
+ assert_equal :original_result, instance.method_x
+ assert !klass.method_defined?(hidden_method_x)
+ end
+
+ def test_should_not_restore_original_method_if_hidden_method_not_defined
+ klass = Class.new { def method_x; :new_result; end }
+ method = AnyInstanceMethod.new(klass, :method_x)
+
+ method.restore_original_method
+
+ instance = klass.new
+ assert_equal :new_result, instance.method_x
+ end
+
+ def test_should_call_remove_new_method
+ klass = Class.new { def method_x; end }
+ any_instance = Mock.new
+ any_instance.stubs(:reset_mocha)
+ klass.define_instance_method(:any_instance) { any_instance }
+ method = AnyInstanceMethod.new(klass, :method_x)
+ method.replace_instance_method(:restore_original_method) { }
+ method.define_instance_accessor(:remove_called)
+ method.replace_instance_method(:remove_new_method) { self.remove_called = true }
+
+ method.unstub
+
+ assert method.remove_called
+ end
+
+ def test_should_call_restore_original_method
+ klass = Class.new { def method_x; end }
+ any_instance = Mock.new
+ any_instance.stubs(:reset_mocha)
+ klass.define_instance_method(:any_instance) { any_instance }
+ method = AnyInstanceMethod.new(klass, :method_x)
+ method.replace_instance_method(:remove_new_method) { }
+ method.define_instance_accessor(:restore_called)
+ method.replace_instance_method(:restore_original_method) { self.restore_called = true }
+
+ method.unstub
+
+ assert method.restore_called
+ end
+
+ def test_should_call_reset_mocha
+ klass = Class.new { def method_x; end }
+ any_instance = Class.new { attr_accessor :mocha_was_reset; def reset_mocha; self.mocha_was_reset = true; end }.new
+ klass.define_instance_method(:any_instance) { any_instance }
+ method = AnyInstanceMethod.new(klass, :method_x)
+ method.replace_instance_method(:remove_new_method) { }
+ method.replace_instance_method(:restore_original_method) { }
+
+ method.unstub
+
+ assert any_instance.mocha_was_reset
+ end
+
+ def test_should_return_any_instance_mocha_for_stubbee
+ mocha = Object.new
+ any_instance = Object.new
+ any_instance.define_instance_method(:mocha) { mocha }
+ stubbee = Class.new
+ stubbee.define_instance_method(:any_instance) { any_instance }
+ method = AnyInstanceMethod.new(stubbee, :method_name)
+ assert_equal stubbee.any_instance.mocha, method.mock
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/array_inspect_test.rb b/vendor/gems/mocha-0.5.6/test/unit/array_inspect_test.rb
new file mode 100644
index 000000000..9cc06a456
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/array_inspect_test.rb
@@ -0,0 +1,16 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/inspect'
+
+class ArrayInstanceTest < Test::Unit::TestCase
+
+ def test_should_use_inspect
+ array = [1, 2]
+ assert_equal array.inspect, array.mocha_inspect
+ end
+
+ def test_should_use_mocha_inspect_on_each_item
+ array = [1, 2, "chris"]
+ assert_equal "[1, 2, 'chris']", array.mocha_inspect
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/auto_verify_test.rb b/vendor/gems/mocha-0.5.6/test/unit/auto_verify_test.rb
new file mode 100644
index 000000000..10a612457
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/auto_verify_test.rb
@@ -0,0 +1,129 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/auto_verify'
+require 'method_definer'
+
+class AutoVerifyTest < Test::Unit::TestCase
+
+ attr_reader :test_case
+
+ def setup
+ @test_case = Object.new
+ class << test_case
+ include Mocha::AutoVerify
+ end
+ end
+
+ def test_should_build_mock
+ mock = test_case.mock
+ assert mock.is_a?(Mocha::Mock)
+ end
+
+ def test_should_add_expectations_to_mock
+ mock = test_case.mock(:method_1 => 'result_1', :method_2 => 'result_2')
+ assert_equal 'result_1', mock.method_1
+ assert_equal 'result_2', mock.method_2
+ end
+
+ def test_should_build_stub
+ stub = test_case.stub
+ assert stub.is_a?(Mocha::Mock)
+ end
+
+ def test_should_add_expectation_to_stub
+ stub = test_case.stub(:method_1 => 'result_1', :method_2 => 'result_2')
+ assert_equal 'result_1', stub.method_1
+ assert_equal 'result_2', stub.method_2
+ end
+
+ def test_should_build_stub_that_stubs_all_methods
+ stub = test_case.stub_everything
+ assert stub.everything_stubbed
+ end
+
+ def test_should_add_expectations_to_stub_that_stubs_all_methods
+ stub = test_case.stub_everything(:method_1 => 'result_1', :method_2 => 'result_2')
+ assert_equal 'result_1', stub.method_1
+ assert_equal 'result_2', stub.method_2
+ end
+
+ def test_should_always_new_mock
+ assert_not_equal test_case.mock, test_case.mock
+ end
+
+ def test_should_always_build_new_stub
+ assert_not_equal test_case.stub, test_case.stub
+ end
+
+ def test_should_always_build_new_stub_that_stubs_all_methods
+ assert_not_equal test_case.stub, test_case.stub
+ end
+
+ def test_should_store_each_new_mock
+ expected = Array.new(3) { test_case.mock }
+ assert_equal expected, test_case.mocks
+ end
+
+ def test_should_store_each_new_stub
+ expected = Array.new(3) { test_case.stub }
+ assert_equal expected, test_case.mocks
+ end
+
+ def test_should_store_each_new_stub_that_stubs_all_methods
+ expected = Array.new(3) { test_case.stub_everything }
+ assert_equal expected, test_case.mocks
+ end
+
+ def test_should_verify_each_mock
+ mocks = Array.new(3) do
+ mock = Object.new
+ mock.define_instance_accessor(:verify_called)
+ class << mock
+ def verify(&block)
+ self.verify_called = true
+ end
+ end
+ mock
+ end
+ test_case.replace_instance_method(:mocks) { mocks }
+ test_case.verify_mocks
+ assert mocks.all? { |mock| mock.verify_called }
+ end
+
+ def test_should_yield_to_block_for_each_assertion
+ mock_class = Class.new do
+ def verify(&block); yield; end
+ end
+ mock = mock_class.new
+ test_case.replace_instance_method(:mocks) { [mock] }
+ yielded = false
+ test_case.verify_mocks { yielded = true }
+ assert yielded
+ end
+
+ def test_should_reset_mocks_on_teardown
+ mock = Class.new { define_method(:verify) {} }.new
+ test_case.mocks << mock
+ test_case.teardown_mocks
+ assert test_case.mocks.empty?
+ end
+
+ def test_should_create_named_mock
+ mock = test_case.mock('named_mock')
+ assert_equal '#<Mock:named_mock>', mock.mocha_inspect
+ end
+
+ def test_should_create_named_stub
+ stub = test_case.stub('named_stub')
+ assert_equal '#<Mock:named_stub>', stub.mocha_inspect
+ end
+
+ def test_should_create_named_stub_that_stubs_all_methods
+ stub = test_case.stub_everything('named_stub')
+ assert_equal '#<Mock:named_stub>', stub.mocha_inspect
+ end
+
+ def test_should_build_sequence
+ assert_not_nil test_case.sequence('name')
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/central_test.rb b/vendor/gems/mocha-0.5.6/test/unit/central_test.rb
new file mode 100644
index 000000000..2cc834591
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/central_test.rb
@@ -0,0 +1,124 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+
+require 'mocha/central'
+require 'mocha/mock'
+require 'method_definer'
+
+class CentralTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_start_with_empty_stubba_methods
+ stubba = Central.new
+
+ assert_equal [], stubba.stubba_methods
+ end
+
+ def test_should_stub_method_if_not_already_stubbed
+ method = Mock.new
+ method.expects(:stub)
+ stubba = Central.new
+
+ stubba.stub(method)
+
+ method.verify
+ end
+
+ def test_should_not_stub_method_if_already_stubbed
+ method = Mock.new
+ method.expects(:stub).times(0)
+ stubba = Central.new
+ stubba_methods = Mock.new
+ stubba_methods.stubs(:include?).with(method).returns(true)
+ stubba.stubba_methods = stubba_methods
+
+ stubba.stub(method)
+
+ method.verify
+ end
+
+ def test_should_record_method
+ method = Mock.new
+ method.expects(:stub)
+ stubba = Central.new
+
+ stubba.stub(method)
+
+ assert_equal [method], stubba.stubba_methods
+ end
+
+ def test_should_unstub_all_methods
+ stubba = Central.new
+ method_1 = Mock.new
+ method_1.expects(:unstub)
+ method_2 = Mock.new
+ method_2.expects(:unstub)
+ stubba.stubba_methods = [method_1, method_2]
+
+ stubba.unstub_all
+
+ assert_equal [], stubba.stubba_methods
+ method_1.verify
+ method_2.verify
+ end
+
+ def test_should_collect_mocks_from_all_methods
+ method_1 = Mock.new
+ method_1.stubs(:mock).returns(:mock_1)
+
+ method_2 = Mock.new
+ method_2.stubs(:mock).returns(:mock_2)
+
+ stubba = Central.new
+ stubba.stubba_methods = [method_1, method_2]
+
+ assert_equal 2, stubba.unique_mocks.length
+ assert stubba.unique_mocks.include?(:mock_1)
+ assert stubba.unique_mocks.include?(:mock_2)
+ end
+
+ def test_should_return_unique_mochas
+ method_1 = Mock.new
+ method_1.stubs(:mock).returns(:mock_1)
+
+ method_2 = Mock.new
+ method_2.stubs(:mock).returns(:mock_1)
+
+ stubba = Central.new
+ stubba.stubba_methods = [method_1, method_2]
+
+ assert_equal [:mock_1], stubba.unique_mocks
+ end
+
+ def test_should_call_verify_on_all_unique_mocks
+ mock_class = Class.new do
+ attr_accessor :verify_called
+ def verify
+ self.verify_called = true
+ end
+ end
+ mocks = [mock_class.new, mock_class.new]
+ stubba = Central.new
+ stubba.replace_instance_method(:unique_mocks) { mocks }
+
+ stubba.verify_all
+
+ assert mocks.all? { |mock| mock.verify_called }
+ end
+
+ def test_should_call_verify_on_all_unique_mochas
+ mock_class = Class.new do
+ def verify(&block)
+ yield if block_given?
+ end
+ end
+ stubba = Central.new
+ stubba.replace_instance_method(:unique_mocks) { [mock_class.new] }
+ yielded = false
+
+ stubba.verify_all { yielded = true }
+
+ assert yielded
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/class_method_test.rb b/vendor/gems/mocha-0.5.6/test/unit/class_method_test.rb
new file mode 100644
index 000000000..95d059908
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/class_method_test.rb
@@ -0,0 +1,200 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'method_definer'
+require 'mocha/mock'
+
+require 'mocha/class_method'
+
+class ClassMethodTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_provide_hidden_version_of_method_name_starting_with_prefix
+ method = ClassMethod.new(nil, :original_method_name)
+ assert_match(/^__stubba__/, method.hidden_method)
+ end
+
+ def test_should_provide_hidden_version_of_method_name_ending_with_suffix
+ method = ClassMethod.new(nil, :original_method_name)
+ assert_match(/__stubba__$/, method.hidden_method)
+ end
+
+ def test_should_provide_hidden_version_of_method_name_including_original_method_name
+ method = ClassMethod.new(nil, :original_method_name)
+ assert_match(/original_method_name/, method.hidden_method)
+ end
+
+ def test_should_provide_hidden_version_of_method_name_substituting_question_mark
+ method = ClassMethod.new(nil, :question_mark?)
+ assert_no_match(/\?/, method.hidden_method)
+ assert_match(/question_mark_substituted_character_63/, method.hidden_method)
+ end
+
+ def test_should_provide_hidden_version_of_method_name_substituting_exclamation_mark
+ method = ClassMethod.new(nil, :exclamation_mark!)
+ assert_no_match(/!/, method.hidden_method)
+ assert_match(/exclamation_mark_substituted_character_33/, method.hidden_method)
+ end
+
+ def test_should_provide_hidden_version_of_method_name_substituting_equals_sign
+ method = ClassMethod.new(nil, :equals_sign=)
+ assert_no_match(/\=/, method.hidden_method)
+ assert_match(/equals_sign_substituted_character_61/, method.hidden_method)
+ end
+
+ def test_should_provide_hidden_version_of_method_name_substituting_brackets
+ method = ClassMethod.new(nil, :[])
+ assert_no_match(/\[\]/, method.hidden_method)
+ assert_match(/substituted_character_91__substituted_character_93/, method.hidden_method)
+ end
+
+ def test_should_provide_hidden_version_of_method_name_substituting_plus_sign
+ method = ClassMethod.new(nil, :+)
+ assert_no_match(/\+/, method.hidden_method)
+ assert_match(/substituted_character_43/, method.hidden_method)
+ end
+
+ def test_should_hide_original_method
+ klass = Class.new { def self.method_x; end }
+ method = ClassMethod.new(klass, :method_x)
+ hidden_method_x = method.hidden_method
+
+ method.hide_original_method
+
+ assert klass.respond_to?(hidden_method_x)
+ end
+
+ def test_should_respond_to_original_method_name_after_original_method_has_been_hidden
+ klass = Class.new { def self.original_method_name; end }
+ method = ClassMethod.new(klass, :original_method_name)
+ hidden_method_x = method.hidden_method
+
+ method.hide_original_method
+
+ assert klass.respond_to?(:original_method_name)
+ end
+
+ def test_should_not_hide_original_method_if_method_not_defined
+ klass = Class.new
+ method = ClassMethod.new(klass, :method_x)
+ hidden_method_x = method.hidden_method
+
+ method.hide_original_method
+
+ assert_equal false, klass.respond_to?(hidden_method_x)
+ end
+
+ def test_should_define_a_new_method_which_should_call_mocha_method_missing
+ klass = Class.new { def self.method_x; end }
+ mocha = Mocha::Mock.new
+ klass.define_instance_method(:mocha) { mocha }
+ mocha.expects(:method_x).with(:param1, :param2).returns(:result)
+ method = ClassMethod.new(klass, :method_x)
+
+ method.hide_original_method
+ method.define_new_method
+ result = klass.method_x(:param1, :param2)
+
+ assert_equal :result, result
+ mocha.verify
+ end
+
+ def test_should_remove_new_method
+ klass = Class.new { def self.method_x; end }
+ method = ClassMethod.new(klass, :method_x)
+
+ method.remove_new_method
+
+ assert_equal false, klass.respond_to?(:method_x)
+ end
+
+ def test_should_restore_original_method
+ klass = Class.new { def self.method_x; end }
+ method = ClassMethod.new(klass, :method_x)
+ hidden_method_x = method.hidden_method.to_sym
+ klass.define_instance_method(hidden_method_x) { :original_result }
+
+ method.remove_new_method
+ method.restore_original_method
+
+ assert_equal :original_result, klass.method_x
+ assert_equal false, klass.respond_to?(hidden_method_x)
+ end
+
+ def test_should_not_restore_original_method_if_hidden_method_is_not_defined
+ klass = Class.new { def self.method_x; :new_result; end }
+ method = ClassMethod.new(klass, :method_x)
+
+ method.restore_original_method
+
+ assert_equal :new_result, klass.method_x
+ end
+
+ def test_should_call_hide_original_method
+ klass = Class.new { def self.method_x; end }
+ method = ClassMethod.new(klass, :method_x)
+ method.hide_original_method
+ method.define_instance_accessor(:hide_called)
+ method.replace_instance_method(:hide_original_method) { self.hide_called = true }
+
+ method.stub
+
+ assert method.hide_called
+ end
+
+ def test_should_call_define_new_method
+ klass = Class.new { def self.method_x; end }
+ method = ClassMethod.new(klass, :method_x)
+ method.define_instance_accessor(:define_called)
+ method.replace_instance_method(:define_new_method) { self.define_called = true }
+
+ method.stub
+
+ assert method.define_called
+ end
+
+ def test_should_call_remove_new_method
+ klass = Class.new { def self.method_x; end }
+ klass.define_instance_method(:reset_mocha) { }
+ method = ClassMethod.new(klass, :method_x)
+ method.define_instance_accessor(:remove_called)
+ method.replace_instance_method(:remove_new_method) { self.remove_called = true }
+
+ method.unstub
+
+ assert method.remove_called
+ end
+
+ def test_should_call_restore_original_method
+ klass = Class.new { def self.method_x; end }
+ klass.define_instance_method(:reset_mocha) { }
+ method = ClassMethod.new(klass, :method_x)
+ method.define_instance_accessor(:restore_called)
+ method.replace_instance_method(:restore_original_method) { self.restore_called = true }
+
+ method.unstub
+
+ assert method.restore_called
+ end
+
+ def test_should_call_reset_mocha
+ klass = Class.new { def self.method_x; end }
+ klass.define_instance_accessor(:reset_called)
+ klass.define_instance_method(:reset_mocha) { self.reset_called = true }
+ method = ClassMethod.new(klass, :method_x)
+ method.replace_instance_method(:restore_original_method) { }
+
+ method.unstub
+
+ assert klass.reset_called
+ end
+
+ def test_should_return_mock_for_stubbee
+ mocha = Object.new
+ stubbee = Object.new
+ stubbee.define_instance_accessor(:mocha) { mocha }
+ stubbee.mocha = nil
+ method = ClassMethod.new(stubbee, :method_name)
+ assert_equal stubbee.mocha, method.mock
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/date_time_inspect_test.rb b/vendor/gems/mocha-0.5.6/test/unit/date_time_inspect_test.rb
new file mode 100644
index 000000000..8a9b2ee02
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/date_time_inspect_test.rb
@@ -0,0 +1,21 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/inspect'
+
+class TimeDateInspectTest < Test::Unit::TestCase
+
+ def test_should_use_include_date_in_seconds
+ time = Time.now
+ assert_equal "#{time.inspect} (#{time.to_f} secs)", time.mocha_inspect
+ end
+
+ def test_should_use_to_s_for_date
+ date = Date.new(2006, 1, 1)
+ assert_equal date.to_s, date.mocha_inspect
+ end
+
+ def test_should_use_to_s_for_datetime
+ datetime = DateTime.new(2006, 1, 1)
+ assert_equal datetime.to_s, datetime.mocha_inspect
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/expectation_error_test.rb b/vendor/gems/mocha-0.5.6/test/unit/expectation_error_test.rb
new file mode 100644
index 000000000..6206acf64
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/expectation_error_test.rb
@@ -0,0 +1,24 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/expectation_error'
+
+class ExpectationErrorTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_exclude_mocha_locations_from_backtrace
+ mocha_lib = "/username/workspace/mocha_wibble/lib/"
+ backtrace = [ mocha_lib + 'exclude/me/1', mocha_lib + 'exclude/me/2', '/keep/me', mocha_lib + 'exclude/me/3']
+ expectation_error = ExpectationError.new(nil, backtrace, mocha_lib)
+ assert_equal ['/keep/me'], expectation_error.backtrace
+ end
+
+ def test_should_determine_path_for_mocha_lib_directory
+ assert_match Regexp.new("/lib/$"), ExpectationError::LIB_DIRECTORY
+ end
+
+ def test_should_set_error_message
+ expectation_error = ExpectationError.new('message')
+ assert_equal 'message', expectation_error.message
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/expectation_list_test.rb b/vendor/gems/mocha-0.5.6/test/unit/expectation_list_test.rb
new file mode 100644
index 000000000..59dd410a1
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/expectation_list_test.rb
@@ -0,0 +1,75 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/expectation_list'
+require 'mocha/expectation'
+require 'set'
+require 'method_definer'
+
+class ExpectationListTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_return_added_expectation
+ expectation_list = ExpectationList.new
+ expectation = Expectation.new(nil, :my_method)
+ assert_same expectation, expectation_list.add(expectation)
+ end
+
+ def test_should_find_matching_expectation
+ expectation_list = ExpectationList.new
+ expectation1 = Expectation.new(nil, :my_method).with(:argument1, :argument2)
+ expectation2 = Expectation.new(nil, :my_method).with(:argument3, :argument4)
+ expectation_list.add(expectation1)
+ expectation_list.add(expectation2)
+ assert_same expectation2, expectation_list.detect(:my_method, :argument3, :argument4)
+ end
+
+ def test_should_find_most_recent_matching_expectation
+ expectation_list = ExpectationList.new
+ expectation1 = Expectation.new(nil, :my_method).with(:argument1, :argument2)
+ expectation2 = Expectation.new(nil, :my_method).with(:argument1, :argument2)
+ expectation_list.add(expectation1)
+ expectation_list.add(expectation2)
+ assert_same expectation2, expectation_list.detect(:my_method, :argument1, :argument2)
+ end
+
+ def test_should_find_most_recent_matching_expectation_but_give_preference_to_those_allowing_invocations
+ expectation_list = ExpectationList.new
+ expectation1 = Expectation.new(nil, :my_method)
+ expectation2 = Expectation.new(nil, :my_method)
+ expectation1.define_instance_method(:invocations_allowed?) { true }
+ expectation2.define_instance_method(:invocations_allowed?) { false }
+ expectation_list.add(expectation1)
+ expectation_list.add(expectation2)
+ assert_same expectation1, expectation_list.detect(:my_method)
+ end
+
+ def test_should_find_most_recent_matching_expectation_if_no_matching_expectations_allow_invocations
+ expectation_list = ExpectationList.new
+ expectation1 = Expectation.new(nil, :my_method)
+ expectation2 = Expectation.new(nil, :my_method)
+ expectation1.define_instance_method(:invocations_allowed?) { false }
+ expectation2.define_instance_method(:invocations_allowed?) { false }
+ expectation_list.add(expectation1)
+ expectation_list.add(expectation2)
+ assert_same expectation2, expectation_list.detect(:my_method)
+ end
+
+ def test_should_find_expectations_for_the_same_method_no_matter_what_the_arguments
+ expectation_list = ExpectationList.new
+ expectation1 = Expectation.new(nil, :my_method).with(:argument1, :argument2)
+ expectation_list.add(expectation1)
+ expectation2 = Expectation.new(nil, :my_method).with(:argument3, :argument4)
+ expectation_list.add(expectation2)
+ assert_equal [expectation1, expectation2].to_set, expectation_list.similar(:my_method).to_set
+ end
+
+ def test_should_ignore_expectations_for_different_methods
+ expectation_list = ExpectationList.new
+ expectation1 = Expectation.new(nil, :method1).with(:argument1, :argument2)
+ expectation_list.add(expectation1)
+ expectation2 = Expectation.new(nil, :method2).with(:argument1, :argument2)
+ expectation_list.add(expectation2)
+ assert_equal [expectation2], expectation_list.similar(:method2)
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/expectation_raiser_test.rb b/vendor/gems/mocha-0.5.6/test/unit/expectation_raiser_test.rb
new file mode 100644
index 000000000..3b46d8fd8
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/expectation_raiser_test.rb
@@ -0,0 +1,28 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+
+require 'mocha/exception_raiser'
+
+class ExceptionRaiserTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_raise_exception_with_specified_class_and_default_message
+ exception_class = Class.new(StandardError)
+ raiser = ExceptionRaiser.new(exception_class, nil)
+ exception = assert_raises(exception_class) { raiser.evaluate }
+ assert_equal exception_class.to_s, exception.message
+ end
+
+ def test_should_raise_exception_with_specified_class_and_message
+ exception_class = Class.new(StandardError)
+ raiser = ExceptionRaiser.new(exception_class, 'message')
+ exception = assert_raises(exception_class) { raiser.evaluate }
+ assert_equal 'message', exception.message
+ end
+
+ def test_should_raise_interrupt_exception_with_default_message_so_it_works_in_ruby_1_8_6
+ raiser = ExceptionRaiser.new(Interrupt, nil)
+ assert_raises(Interrupt) { raiser.evaluate }
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/expectation_test.rb b/vendor/gems/mocha-0.5.6/test/unit/expectation_test.rb
new file mode 100644
index 000000000..cdb38eb9b
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/expectation_test.rb
@@ -0,0 +1,483 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'method_definer'
+require 'mocha/expectation'
+require 'mocha/sequence'
+require 'execution_point'
+require 'deprecation_disabler'
+
+class ExpectationTest < Test::Unit::TestCase
+
+ include Mocha
+ include DeprecationDisabler
+
+ def new_expectation
+ Expectation.new(nil, :expected_method)
+ end
+
+ def test_should_match_calls_to_same_method_with_any_parameters
+ assert new_expectation.match?(:expected_method, 1, 2, 3)
+ end
+
+ def test_should_match_calls_to_same_method_with_exactly_zero_parameters
+ expectation = new_expectation.with()
+ assert expectation.match?(:expected_method)
+ end
+
+ def test_should_not_match_calls_to_same_method_with_more_than_zero_parameters
+ expectation = new_expectation.with()
+ assert !expectation.match?(:expected_method, 1, 2, 3)
+ end
+
+ def test_should_match_calls_to_same_method_with_expected_parameter_values
+ expectation = new_expectation.with(1, 2, 3)
+ assert expectation.match?(:expected_method, 1, 2, 3)
+ end
+
+ def test_should_match_calls_to_same_method_with_parameters_constrained_as_expected
+ expectation = new_expectation.with() {|x, y, z| x + y == z}
+ assert expectation.match?(:expected_method, 1, 2, 3)
+ end
+
+ def test_should_not_match_calls_to_different_method_with_parameters_constrained_as_expected
+ expectation = new_expectation.with() {|x, y, z| x + y == z}
+ assert !expectation.match?(:different_method, 1, 2, 3)
+ end
+
+ def test_should_not_match_calls_to_different_methods_with_no_parameters
+ assert !new_expectation.match?(:unexpected_method)
+ end
+
+ def test_should_not_match_calls_to_same_method_with_too_few_parameters
+ expectation = new_expectation.with(1, 2, 3)
+ assert !expectation.match?(:unexpected_method, 1, 2)
+ end
+
+ def test_should_not_match_calls_to_same_method_with_too_many_parameters
+ expectation = new_expectation.with(1, 2)
+ assert !expectation.match?(:unexpected_method, 1, 2, 3)
+ end
+
+ def test_should_not_match_calls_to_same_method_with_unexpected_parameter_values
+ expectation = new_expectation.with(1, 2, 3)
+ assert !expectation.match?(:unexpected_method, 1, 0, 3)
+ end
+
+ def test_should_not_match_calls_to_same_method_with_parameters_not_constrained_as_expected
+ expectation = new_expectation.with() {|x, y, z| x + y == z}
+ assert !expectation.match?(:expected_method, 1, 0, 3)
+ end
+
+ def test_should_allow_invocations_until_expected_invocation_count_is_one_and_actual_invocation_count_would_be_two
+ expectation = new_expectation.times(1)
+ assert expectation.invocations_allowed?
+ expectation.invoke
+ assert !expectation.invocations_allowed?
+ end
+
+ def test_should_allow_invocations_until_expected_invocation_count_is_two_and_actual_invocation_count_would_be_three
+ expectation = new_expectation.times(2)
+ assert expectation.invocations_allowed?
+ expectation.invoke
+ assert expectation.invocations_allowed?
+ expectation.invoke
+ assert !expectation.invocations_allowed?
+ end
+
+ def test_should_allow_invocations_until_expected_invocation_count_is_a_range_from_two_to_three_and_actual_invocation_count_would_be_four
+ expectation = new_expectation.times(2..3)
+ assert expectation.invocations_allowed?
+ expectation.invoke
+ assert expectation.invocations_allowed?
+ expectation.invoke
+ assert expectation.invocations_allowed?
+ expectation.invoke
+ assert !expectation.invocations_allowed?
+ end
+
+ def test_should_store_provided_backtrace
+ backtrace = Object.new
+ expectation = Expectation.new(nil, :expected_method, backtrace)
+ assert_equal backtrace, expectation.backtrace
+ end
+
+ def test_should_default_backtrace_to_caller
+ execution_point = ExecutionPoint.current; expectation = Expectation.new(nil, :expected_method)
+ assert_equal execution_point, ExecutionPoint.new(expectation.backtrace)
+ end
+
+ def test_should_not_yield
+ yielded = false
+ new_expectation.invoke() { yielded = true }
+ assert_equal false, yielded
+ end
+
+ def test_should_yield_no_parameters
+ expectation = new_expectation().yields()
+ yielded_parameters = nil
+ expectation.invoke() { |*parameters| yielded_parameters = parameters }
+ assert_equal Array.new, yielded_parameters
+ end
+
+ def test_should_yield_with_specified_parameters
+ expectation = new_expectation().yields(1, 2, 3)
+ yielded_parameters = nil
+ expectation.invoke() { |*parameters| yielded_parameters = parameters }
+ assert_equal [1, 2, 3], yielded_parameters
+ end
+
+ def test_should_yield_different_parameters_on_consecutive_invocations
+ expectation = new_expectation().yields(1, 2, 3).yields(4, 5)
+ yielded_parameters = []
+ expectation.invoke() { |*parameters| yielded_parameters << parameters }
+ expectation.invoke() { |*parameters| yielded_parameters << parameters }
+ assert_equal [[1, 2, 3], [4, 5]], yielded_parameters
+ end
+
+ def test_should_yield_multiple_times_for_single_invocation
+ expectation = new_expectation().multiple_yields([1, 2, 3], [4, 5])
+ yielded_parameters = []
+ expectation.invoke() { |*parameters| yielded_parameters << parameters }
+ assert_equal [[1, 2, 3], [4, 5]], yielded_parameters
+ end
+
+ def test_should_yield_multiple_times_for_first_invocation_and_once_for_second_invocation
+ expectation = new_expectation().multiple_yields([1, 2, 3], [4, 5]).then.yields(6, 7)
+ yielded_parameters = []
+ expectation.invoke() { |*parameters| yielded_parameters << parameters }
+ expectation.invoke() { |*parameters| yielded_parameters << parameters }
+ assert_equal [[1, 2, 3], [4, 5], [6, 7]], yielded_parameters
+ end
+
+ def test_should_return_specified_value
+ expectation = new_expectation.returns(99)
+ assert_equal 99, expectation.invoke
+ end
+
+ def test_should_return_same_specified_value_multiple_times
+ expectation = new_expectation.returns(99)
+ assert_equal 99, expectation.invoke
+ assert_equal 99, expectation.invoke
+ end
+
+ def test_should_return_specified_values_on_consecutive_calls
+ expectation = new_expectation.returns(99, 100, 101)
+ assert_equal 99, expectation.invoke
+ assert_equal 100, expectation.invoke
+ assert_equal 101, expectation.invoke
+ end
+
+ def test_should_return_specified_values_on_consecutive_calls_even_if_values_are_modified
+ values = [99, 100, 101]
+ expectation = new_expectation.returns(*values)
+ values.shift
+ assert_equal 99, expectation.invoke
+ assert_equal 100, expectation.invoke
+ assert_equal 101, expectation.invoke
+ end
+
+ def test_should_return_nil_by_default
+ assert_nil new_expectation.invoke
+ end
+
+ def test_should_return_nil_if_no_value_specified
+ expectation = new_expectation.returns()
+ assert_nil expectation.invoke
+ end
+
+ def test_should_return_evaluated_proc
+ proc = lambda { 99 }
+ expectation = new_expectation.returns(proc)
+ result = nil
+ disable_deprecations { result = expectation.invoke }
+ assert_equal 99, result
+ end
+
+ def test_should_return_evaluated_proc_without_using_is_a_method
+ proc = lambda { 99 }
+ proc.define_instance_accessor(:called)
+ proc.called = false
+ proc.replace_instance_method(:is_a?) { self.called = true; true}
+ expectation = new_expectation.returns(proc)
+ disable_deprecations { expectation.invoke }
+ assert_equal false, proc.called
+ end
+
+ def test_should_raise_runtime_exception
+ expectation = new_expectation.raises
+ assert_raise(RuntimeError) { expectation.invoke }
+ end
+
+ def test_should_raise_custom_exception
+ exception = Class.new(Exception)
+ expectation = new_expectation.raises(exception)
+ assert_raise(exception) { expectation.invoke }
+ end
+
+ def test_should_raise_same_instance_of_custom_exception
+ exception_klass = Class.new(StandardError)
+ expected_exception = exception_klass.new
+ expectation = new_expectation.raises(expected_exception)
+ actual_exception = assert_raise(exception_klass) { expectation.invoke }
+ assert_same expected_exception, actual_exception
+ end
+
+ def test_should_use_the_default_exception_message
+ expectation = new_expectation.raises(Exception)
+ exception = assert_raise(Exception) { expectation.invoke }
+ assert_equal Exception.new.message, exception.message
+ end
+
+ def test_should_raise_custom_exception_with_message
+ exception_msg = "exception message"
+ expectation = new_expectation.raises(Exception, exception_msg)
+ exception = assert_raise(Exception) { expectation.invoke }
+ assert_equal exception_msg, exception.message
+ end
+
+ def test_should_return_values_then_raise_exception
+ expectation = new_expectation.returns(1, 2).then.raises()
+ assert_equal 1, expectation.invoke
+ assert_equal 2, expectation.invoke
+ assert_raise(RuntimeError) { expectation.invoke }
+ end
+
+ def test_should_raise_exception_then_return_values
+ expectation = new_expectation.raises().then.returns(1, 2)
+ assert_raise(RuntimeError) { expectation.invoke }
+ assert_equal 1, expectation.invoke
+ assert_equal 2, expectation.invoke
+ end
+
+ def test_should_not_raise_error_on_verify_if_expected_call_was_made
+ expectation = new_expectation
+ expectation.invoke
+ assert_nothing_raised(ExpectationError) {
+ expectation.verify
+ }
+ end
+
+ def test_should_raise_error_on_verify_if_call_expected_once_but_invoked_twice
+ expectation = new_expectation.once
+ expectation.invoke
+ expectation.invoke
+ assert_raises(ExpectationError) {
+ expectation.verify
+ }
+ end
+
+ def test_should_raise_error_on_verify_if_call_expected_once_but_not_invoked
+ expectation = new_expectation.once
+ assert_raises(ExpectationError) {
+ expectation.verify
+ }
+ end
+
+ def test_should_not_raise_error_on_verify_if_call_expected_once_and_invoked_once
+ expectation = new_expectation.once
+ expectation.invoke
+ assert_nothing_raised(ExpectationError) {
+ expectation.verify
+ }
+ end
+
+ def test_should_not_raise_error_on_verify_if_expected_call_was_made_at_least_once
+ expectation = new_expectation.at_least_once
+ 3.times {expectation.invoke}
+ assert_nothing_raised(ExpectationError) {
+ expectation.verify
+ }
+ end
+
+ def test_should_raise_error_on_verify_if_expected_call_was_not_made_at_least_once
+ expectation = new_expectation.with(1, 2, 3).at_least_once
+ e = assert_raise(ExpectationError) {
+ expectation.verify
+ }
+ assert_match(/expected calls: at least 1, actual calls: 0/i, e.message)
+ end
+
+ def test_should_not_raise_error_on_verify_if_expected_call_was_made_expected_number_of_times
+ expectation = new_expectation.times(2)
+ 2.times {expectation.invoke}
+ assert_nothing_raised(ExpectationError) {
+ expectation.verify
+ }
+ end
+
+ def test_should_expect_call_not_to_be_made
+ expectation = new_expectation
+ expectation.define_instance_accessor(:how_many_times)
+ expectation.replace_instance_method(:times) { |how_many_times| self.how_many_times = how_many_times }
+ expectation.never
+ assert_equal 0, expectation.how_many_times
+ end
+
+ def test_should_raise_error_on_verify_if_expected_call_was_made_too_few_times
+ expectation = new_expectation.times(2)
+ 1.times {expectation.invoke}
+ e = assert_raise(ExpectationError) {
+ expectation.verify
+ }
+ assert_match(/expected calls: 2, actual calls: 1/i, e.message)
+ end
+
+ def test_should_raise_error_on_verify_if_expected_call_was_made_too_many_times
+ expectation = new_expectation.times(2)
+ 3.times {expectation.invoke}
+ assert_raise(ExpectationError) {
+ expectation.verify
+ }
+ end
+
+ def test_should_yield_self_to_block
+ expectation = new_expectation
+ expectation.invoke
+ yielded_expectation = nil
+ expectation.verify { |x| yielded_expectation = x }
+ assert_equal expectation, yielded_expectation
+ end
+
+ def test_should_yield_to_block_before_raising_exception
+ yielded = false
+ assert_raise(ExpectationError) {
+ new_expectation.verify { |x| yielded = true }
+ }
+ assert yielded
+ end
+
+ def test_should_store_backtrace_from_point_where_expectation_was_created
+ execution_point = ExecutionPoint.current; expectation = Expectation.new(nil, :expected_method)
+ assert_equal execution_point, ExecutionPoint.new(expectation.backtrace)
+ end
+
+ def test_should_set_backtrace_on_assertion_failed_error_to_point_where_expectation_was_created
+ execution_point = ExecutionPoint.current; expectation = Expectation.new(nil, :expected_method)
+ error = assert_raise(ExpectationError) {
+ expectation.verify
+ }
+ assert_equal execution_point, ExecutionPoint.new(error.backtrace)
+ end
+
+ def test_should_display_expectation_in_exception_message
+ options = [:a, :b, {:c => 1, :d => 2}]
+ expectation = new_expectation.with(*options)
+ exception = assert_raise(ExpectationError) { expectation.verify }
+ assert exception.message.include?(expectation.method_signature)
+ end
+
+ class FakeMock
+
+ def initialize(name)
+ @name = name
+ end
+
+ def mocha_inspect
+ @name
+ end
+
+ end
+
+ def test_should_raise_error_with_message_indicating_which_method_was_expected_to_be_called_on_which_mock_object_with_which_parameters_and_in_what_sequences
+ mock = FakeMock.new('mock')
+ sequence_one = Sequence.new('one')
+ sequence_two = Sequence.new('two')
+ expectation = Expectation.new(mock, :expected_method).with(1, 2, {'a' => true, :b => false}, [1, 2, 3]).in_sequence(sequence_one, sequence_two)
+ e = assert_raise(ExpectationError) { expectation.verify }
+ assert_match "mock.expected_method(1, 2, {'a' => true, :b => false}, [1, 2, 3]); in sequence 'one'; in sequence 'two'", e.message
+ end
+
+ class FakeConstraint
+
+ def initialize(allows_invocation_now)
+ @allows_invocation_now = allows_invocation_now
+ end
+
+ def allows_invocation_now?
+ @allows_invocation_now
+ end
+
+ end
+
+ def test_should_be_in_correct_order_if_all_ordering_constraints_allow_invocation_now
+ constraint_one = FakeConstraint.new(allows_invocation_now = true)
+ constraint_two = FakeConstraint.new(allows_invocation_now = true)
+ expectation = Expectation.new(nil, :method_one)
+ expectation.add_ordering_constraint(constraint_one)
+ expectation.add_ordering_constraint(constraint_two)
+ assert expectation.in_correct_order?
+ end
+
+ def test_should_not_be_in_correct_order_if_one_ordering_constraint_does_not_allow_invocation_now
+ constraint_one = FakeConstraint.new(allows_invocation_now = true)
+ constraint_two = FakeConstraint.new(allows_invocation_now = false)
+ expectation = Expectation.new(nil, :method_one)
+ expectation.add_ordering_constraint(constraint_one)
+ expectation.add_ordering_constraint(constraint_two)
+ assert !expectation.in_correct_order?
+ end
+
+ def test_should_match_if_all_ordering_constraints_allow_invocation_now
+ constraint_one = FakeConstraint.new(allows_invocation_now = true)
+ constraint_two = FakeConstraint.new(allows_invocation_now = true)
+ expectation = Expectation.new(nil, :method_one)
+ expectation.add_ordering_constraint(constraint_one)
+ expectation.add_ordering_constraint(constraint_two)
+ assert expectation.match?(:method_one)
+ end
+
+ def test_should_not_match_if_one_ordering_constraints_does_not_allow_invocation_now
+ constraint_one = FakeConstraint.new(allows_invocation_now = true)
+ constraint_two = FakeConstraint.new(allows_invocation_now = false)
+ expectation = Expectation.new(nil, :method_one)
+ expectation.add_ordering_constraint(constraint_one)
+ expectation.add_ordering_constraint(constraint_two)
+ assert !expectation.match?(:method_one)
+ end
+
+ def test_should_not_be_satisfied_when_required_invocation_has_not_been_made
+ expectation = Expectation.new(nil, :method_one).times(1)
+ assert !expectation.satisfied?
+ end
+
+ def test_should_be_satisfied_when_required_invocation_has_been_made
+ expectation = Expectation.new(nil, :method_one).times(1)
+ expectation.invoke
+ assert expectation.satisfied?
+ end
+
+ def test_should_not_be_satisfied_when_minimum_number_of_invocations_has_not_been_made
+ expectation = Expectation.new(nil, :method_one).at_least(2)
+ expectation.invoke
+ assert !expectation.satisfied?
+ end
+
+ def test_should_be_satisfied_when_minimum_number_of_invocations_has_been_made
+ expectation = Expectation.new(nil, :method_one).at_least(2)
+ 2.times { expectation.invoke }
+ assert expectation.satisfied?
+ end
+
+ class FakeSequence
+
+ attr_reader :expectations
+
+ def initialize
+ @expectations = []
+ end
+
+ def constrain_as_next_in_sequence(expectation)
+ @expectations << expectation
+ end
+
+ end
+
+ def test_should_tell_sequences_to_constrain_expectation_as_next_in_sequence
+ sequence_one = FakeSequence.new
+ sequence_two = FakeSequence.new
+ expectation = Expectation.new(nil, :method_one)
+ assert_equal expectation, expectation.in_sequence(sequence_one, sequence_two)
+ assert_equal [expectation], sequence_one.expectations
+ assert_equal [expectation], sequence_two.expectations
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/hash_inspect_test.rb b/vendor/gems/mocha-0.5.6/test/unit/hash_inspect_test.rb
new file mode 100644
index 000000000..15ad41544
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/hash_inspect_test.rb
@@ -0,0 +1,16 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/inspect'
+
+class HashInspectTest < Test::Unit::TestCase
+
+ def test_should_keep_spacing_between_key_value
+ hash = {:a => true}
+ assert_equal '{:a => true}', hash.mocha_inspect
+ end
+
+ def test_should_use_mocha_inspect_on_each_item
+ hash = {:a => 'mocha'}
+ assert_equal "{:a => 'mocha'}", hash.mocha_inspect
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/infinite_range_test.rb b/vendor/gems/mocha-0.5.6/test/unit/infinite_range_test.rb
new file mode 100644
index 000000000..7b4c8a4cb
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/infinite_range_test.rb
@@ -0,0 +1,53 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/infinite_range'
+require 'date'
+
+class InfiniteRangeTest < Test::Unit::TestCase
+
+ def test_should_include_values_at_or_above_minimum
+ range = Range.at_least(10)
+ assert(range === 10)
+ assert(range === 11)
+ assert(range === 1000000)
+ end
+
+ def test_should_not_include_values_below_minimum
+ range = Range.at_least(10)
+ assert_false(range === 0)
+ assert_false(range === 9)
+ assert_false(range === -11)
+ end
+
+ def test_should_be_human_readable_description_for_at_least
+ assert_equal "at least 10", Range.at_least(10).mocha_inspect
+ end
+
+ def test_should_include_values_at_or_below_maximum
+ range = Range.at_most(10)
+ assert(range === 10)
+ assert(range === 0)
+ assert(range === -1000000)
+ end
+
+ def test_should_not_include_values_above_maximum
+ range = Range.at_most(10)
+ assert_false(range === 11)
+ assert_false(range === 1000000)
+ end
+
+ def test_should_be_human_readable_description_for_at_most
+ assert_equal "at most 10", Range.at_most(10).mocha_inspect
+ end
+
+ def test_should_be_same_as_standard_to_string
+ assert_equal((1..10).to_s, (1..10).mocha_inspect)
+ assert_equal((1...10).to_s, (1...10).mocha_inspect)
+ date_range = Range.new(Date.parse('2006-01-01'), Date.parse('2007-01-01'))
+ assert_equal date_range.to_s, date_range.mocha_inspect
+ end
+
+ def assert_false(condition)
+ assert(!condition)
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/metaclass_test.rb b/vendor/gems/mocha-0.5.6/test/unit/metaclass_test.rb
new file mode 100644
index 000000000..956bcb45b
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/metaclass_test.rb
@@ -0,0 +1,22 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/metaclass'
+
+class MetaclassTest < Test::Unit::TestCase
+
+ def test_should_return_objects_singleton_class
+ object = Object.new
+ assert_raises(NoMethodError) { object.success? }
+
+ object = Object.new
+ assert object.__metaclass__.ancestors.include?(Object)
+ assert object.__metaclass__.ancestors.include?(Kernel)
+ assert object.__metaclass__.is_a?(Class)
+
+ object.__metaclass__.class_eval { def success?; true; end }
+ assert object.success?
+
+ object = Object.new
+ assert_raises(NoMethodError) { object.success? }
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/method_matcher_test.rb b/vendor/gems/mocha-0.5.6/test/unit/method_matcher_test.rb
new file mode 100644
index 000000000..0167433e4
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/method_matcher_test.rb
@@ -0,0 +1,23 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/method_matcher'
+
+class MethodMatcherTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_match_if_actual_method_name_is_same_as_expected_method_name
+ method_matcher = MethodMatcher.new(:method_name)
+ assert method_matcher.match?(:method_name)
+ end
+
+ def test_should_not_match_if_actual_method_name_is_not_same_as_expected_method_name
+ method_matcher = MethodMatcher.new(:method_name)
+ assert !method_matcher.match?(:different_method_name)
+ end
+
+ def test_should_describe_what_method_is_expected
+ method_matcher = MethodMatcher.new(:method_name)
+ assert_equal "method_name", method_matcher.mocha_inspect
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/missing_expectation_test.rb b/vendor/gems/mocha-0.5.6/test/unit/missing_expectation_test.rb
new file mode 100644
index 000000000..9d3b45aa7
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/missing_expectation_test.rb
@@ -0,0 +1,42 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+
+require 'mocha/missing_expectation'
+require 'mocha/mock'
+
+class MissingExpectationTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_report_similar_expectations
+ mock = Mock.new
+ expectation_1 = mock.expects(:method_one).with(1)
+ expectation_2 = mock.expects(:method_one).with(1, 1)
+ expectation_3 = mock.expects(:method_two).with(2)
+
+ missing_expectation = MissingExpectation.new(mock, :method_one)
+ exception = assert_raise(ExpectationError) { missing_expectation.verify }
+
+ expected_message = [
+ "#{missing_expectation.error_message(0, 1)}",
+ "Similar expectations:",
+ "#{expectation_1.method_signature}",
+ "#{expectation_2.method_signature}"
+ ].join("\n")
+
+ assert_equal expected_message, exception.message
+ end
+
+ def test_should_not_report_similar_expectations_if_there_are_none
+ mock = Mock.new
+ mock.expects(:method_two).with(2)
+ mock.expects(:method_two).with(2, 2)
+
+ missing_expectation = MissingExpectation.new(mock, :method_one)
+ exception = assert_raise(ExpectationError) { missing_expectation.verify }
+
+ expected_message = "#{missing_expectation.error_message(0, 1)}"
+
+ assert_equal expected_message, exception.message
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/mock_test.rb b/vendor/gems/mocha-0.5.6/test/unit/mock_test.rb
new file mode 100644
index 000000000..f844bc81d
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/mock_test.rb
@@ -0,0 +1,323 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/mock'
+require 'mocha/expectation_error'
+require 'set'
+
+class MockTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_set_single_expectation
+ mock = Mock.new
+ mock.expects(:method1).returns(1)
+ assert_nothing_raised(ExpectationError) do
+ assert_equal 1, mock.method1
+ end
+ end
+
+ def test_should_build_and_store_expectations
+ mock = Mock.new
+ expectation = mock.expects(:method1)
+ assert_not_nil expectation
+ assert_equal [expectation], mock.expectations.to_a
+ end
+
+ def test_should_not_stub_everything_by_default
+ mock = Mock.new
+ assert_equal false, mock.everything_stubbed
+ end
+
+ def test_should_stub_everything
+ mock = Mock.new
+ mock.stub_everything
+ assert_equal true, mock.everything_stubbed
+ end
+
+ def test_should_display_object_id_for_mocha_inspect_if_mock_has_no_name
+ mock = Mock.new
+ assert_match Regexp.new("^#<Mock:0x[0-9A-Fa-f]{1,12}>$"), mock.mocha_inspect
+ end
+
+ def test_should_display_name_for_mocha_inspect_if_mock_has_name
+ mock = Mock.new('named_mock')
+ assert_equal "#<Mock:named_mock>", mock.mocha_inspect
+ end
+
+ def test_should_display_object_id_for_inspect_if_mock_has_no_name
+ mock = Mock.new
+ assert_match Regexp.new("^#<Mock:0x[0-9A-Fa-f]{1,12}>$"), mock.inspect
+ end
+
+ def test_should_display_name_for_inspect_if_mock_has_name
+ mock = Mock.new('named_mock')
+ assert_equal "#<Mock:named_mock>", mock.inspect
+ end
+
+ def test_should_be_able_to_extend_mock_object_with_module
+ mock = Mock.new
+ assert_nothing_raised(ExpectationError) { mock.extend(Module.new) }
+ end
+
+ def test_should_be_equal
+ mock = Mock.new
+ assert_equal true, mock.eql?(mock)
+ end
+
+ if RUBY_VERSION < '1.9'
+ OBJECT_METHODS = STANDARD_OBJECT_PUBLIC_INSTANCE_METHODS.reject { |m| m =~ /^__.*__$/ }
+ else
+ OBJECT_METHODS = STANDARD_OBJECT_PUBLIC_INSTANCE_METHODS.reject { |m| m =~ /^__.*__$/ || m == :object_id }
+ end
+
+ def test_should_be_able_to_mock_standard_object_methods
+ mock = Mock.new
+ OBJECT_METHODS.each { |method| mock.__expects__(method.to_sym).returns(method) }
+ OBJECT_METHODS.each { |method| assert_equal method, mock.__send__(method.to_sym) }
+ assert_nothing_raised(ExpectationError) { mock.verify }
+ end
+
+ def test_should_be_able_to_stub_standard_object_methods
+ mock = Mock.new
+ OBJECT_METHODS.each { |method| mock.__stubs__(method.to_sym).returns(method) }
+ OBJECT_METHODS.each { |method| assert_equal method, mock.__send__(method.to_sym) }
+ end
+
+ def test_should_create_and_add_expectations
+ mock = Mock.new
+ expectation1 = mock.expects(:method1)
+ expectation2 = mock.expects(:method2)
+ assert_equal [expectation1, expectation2].to_set, mock.expectations.to_set
+ end
+
+ def test_should_pass_backtrace_into_expectation
+ mock = Mock.new
+ backtrace = Object.new
+ expectation = mock.expects(:method1, backtrace)
+ assert_equal backtrace, expectation.backtrace
+ end
+
+ def test_should_pass_backtrace_into_stub
+ mock = Mock.new
+ backtrace = Object.new
+ stub = mock.stubs(:method1, backtrace)
+ assert_equal backtrace, stub.backtrace
+ end
+
+ def test_should_create_and_add_stubs
+ mock = Mock.new
+ stub1 = mock.stubs(:method1)
+ stub2 = mock.stubs(:method2)
+ assert_equal [stub1, stub2].to_set, mock.expectations.to_set
+ end
+
+ def test_should_invoke_expectation_and_return_result
+ mock = Mock.new
+ mock.expects(:my_method).returns(:result)
+ result = mock.my_method
+ assert_equal :result, result
+ end
+
+ def test_should_not_raise_error_if_stubbing_everything
+ mock = Mock.new
+ mock.stub_everything
+ result = nil
+ assert_nothing_raised(ExpectationError) do
+ result = mock.unexpected_method
+ end
+ assert_nil result
+ end
+
+ def test_should_raise_assertion_error_for_unexpected_method_call
+ mock = Mock.new
+ error = assert_raise(ExpectationError) do
+ mock.unexpected_method_called(:my_method, :argument1, :argument2)
+ end
+ assert_match(/my_method/, error.message)
+ assert_match(/argument1/, error.message)
+ assert_match(/argument2/, error.message)
+ end
+
+ def test_should_indicate_unexpected_method_called
+ mock = Mock.new
+ class << mock
+ attr_accessor :symbol, :arguments
+ def unexpected_method_called(symbol, *arguments)
+ self.symbol, self.arguments = symbol, arguments
+ end
+ end
+ mock.my_method(:argument1, :argument2)
+ assert_equal :my_method, mock.symbol
+ assert_equal [:argument1, :argument2], mock.arguments
+ end
+
+ def test_should_verify_that_all_expectations_have_been_fulfilled
+ mock = Mock.new
+ mock.expects(:method1)
+ mock.expects(:method2)
+ mock.method1
+ assert_raise(ExpectationError) do
+ mock.verify
+ end
+ end
+
+ def test_should_report_possible_expectations
+ mock = Mock.new
+ mock.expects(:expected_method).with(1)
+ exception = assert_raise(ExpectationError) { mock.expected_method(2) }
+ assert_equal "#{mock.mocha_inspect}.expected_method(2) - expected calls: 0, actual calls: 1\nSimilar expectations:\n#{mock.mocha_inspect}.expected_method(1)", exception.message
+ end
+
+ def test_should_pass_block_through_to_expectations_verify_method
+ mock = Mock.new
+ expected_expectation = mock.expects(:method1)
+ mock.method1
+ expectations = []
+ mock.verify() { |expectation| expectations << expectation }
+ assert_equal [expected_expectation], expectations
+ end
+
+ def test_should_yield_supplied_parameters_to_block
+ mock = Mock.new
+ parameters_for_yield = [1, 2, 3]
+ mock.expects(:method1).yields(*parameters_for_yield)
+ yielded_parameters = nil
+ mock.method1() { |*parameters| yielded_parameters = parameters }
+ assert_equal parameters_for_yield, yielded_parameters
+ end
+
+ def test_should_set_up_multiple_expectations_with_return_values
+ mock = Mock.new
+ mock.expects(:method1 => :result1, :method2 => :result2)
+ assert_equal :result1, mock.method1
+ assert_equal :result2, mock.method2
+ end
+
+ def test_should_set_up_multiple_stubs_with_return_values
+ mock = Mock.new
+ mock.stubs(:method1 => :result1, :method2 => :result2)
+ assert_equal :result1, mock.method1
+ assert_equal :result2, mock.method2
+ end
+
+ def test_should_keep_returning_specified_value_for_stubs
+ mock = Mock.new
+ mock.stubs(:method1).returns(1)
+ assert_equal 1, mock.method1
+ assert_equal 1, mock.method1
+ end
+
+ def test_should_keep_returning_specified_value_for_expects
+ mock = Mock.new
+ mock.expects(:method1).times(2).returns(1)
+ assert_equal 1, mock.method1
+ assert_equal 1, mock.method1
+ end
+
+ def test_should_match_most_recent_call_to_expects
+ mock = Mock.new
+ mock.expects(:method1).returns(0)
+ mock.expects(:method1).returns(1)
+ assert_equal 1, mock.method1
+ end
+
+ def test_should_match_most_recent_call_to_stubs
+ mock = Mock.new
+ mock.stubs(:method1).returns(0)
+ mock.stubs(:method1).returns(1)
+ assert_equal 1, mock.method1
+ end
+
+ def test_should_match_most_recent_call_to_stubs_or_expects
+ mock = Mock.new
+ mock.stubs(:method1).returns(0)
+ mock.expects(:method1).returns(1)
+ assert_equal 1, mock.method1
+ end
+
+ def test_should_match_most_recent_call_to_expects_or_stubs
+ mock = Mock.new
+ mock.expects(:method1).returns(0)
+ mock.stubs(:method1).returns(1)
+ assert_equal 1, mock.method1
+ end
+
+ def test_should_respond_to_expected_method
+ mock = Mock.new
+ mock.expects(:method1)
+ assert_equal true, mock.respond_to?(:method1)
+ end
+
+ def test_should_not_respond_to_unexpected_method
+ mock = Mock.new
+ assert_equal false, mock.respond_to?(:method1)
+ end
+
+ def test_should_respond_to_methods_which_the_responder_does_responds_to
+ instance = Class.new do
+ define_method(:respond_to?) { |symbol| true }
+ end.new
+ mock = Mock.new
+ mock.responds_like(instance)
+ assert_equal true, mock.respond_to?(:invoked_method)
+ end
+
+ def test_should_not_respond_to_methods_which_the_responder_does_not_responds_to
+ instance = Class.new do
+ define_method(:respond_to?) { |symbol| false }
+ end.new
+ mock = Mock.new
+ mock.responds_like(instance)
+ assert_equal false, mock.respond_to?(:invoked_method)
+ end
+
+ def test_should_return_itself_to_allow_method_chaining
+ mock = Mock.new
+ assert_same mock.responds_like(Object.new), mock
+ end
+
+ def test_should_not_raise_no_method_error_if_mock_is_not_restricted_to_respond_like_a_responder
+ instance = Class.new do
+ define_method(:respond_to?) { true }
+ end.new
+ mock = Mock.new
+ mock.stubs(:invoked_method)
+ assert_nothing_raised(NoMethodError) { mock.invoked_method }
+ end
+
+ def test_should_not_raise_no_method_error_if_responder_does_respond_to_invoked_method
+ instance = Class.new do
+ define_method(:respond_to?) { |symbol| true }
+ end.new
+ mock = Mock.new
+ mock.responds_like(instance)
+ mock.stubs(:invoked_method)
+ assert_nothing_raised(NoMethodError) { mock.invoked_method }
+ end
+
+ def test_should_raise_no_method_error_if_responder_does_not_respond_to_invoked_method
+ instance = Class.new do
+ define_method(:respond_to?) { |symbol| false }
+ define_method(:mocha_inspect) { 'mocha_inspect' }
+ end.new
+ mock = Mock.new
+ mock.responds_like(instance)
+ mock.stubs(:invoked_method)
+ assert_raises(NoMethodError) { mock.invoked_method }
+ end
+
+ def test_should_raise_no_method_error_with_message_indicating_that_mock_is_constrained_to_respond_like_responder
+ instance = Class.new do
+ define_method(:respond_to?) { |symbol| false }
+ define_method(:mocha_inspect) { 'mocha_inspect' }
+ end.new
+ mock = Mock.new
+ mock.responds_like(instance)
+ mock.stubs(:invoked_method)
+ begin
+ mock.invoked_method
+ rescue NoMethodError => e
+ assert_match(/which responds like mocha_inspect/, e.message)
+ end
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/multiple_yields_test.rb b/vendor/gems/mocha-0.5.6/test/unit/multiple_yields_test.rb
new file mode 100644
index 000000000..65724a8fb
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/multiple_yields_test.rb
@@ -0,0 +1,18 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+
+require 'mocha/multiple_yields'
+
+class MultipleYieldsTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_provide_parameters_for_multiple_yields_in_single_invocation
+ parameter_group = MultipleYields.new([1, 2, 3], [4, 5])
+ parameter_groups = []
+ parameter_group.each do |parameters|
+ parameter_groups << parameters
+ end
+ assert_equal [[1, 2, 3], [4, 5]], parameter_groups
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/no_yield_test.rb b/vendor/gems/mocha-0.5.6/test/unit/no_yield_test.rb
new file mode 100644
index 000000000..544d1ef25
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/no_yield_test.rb
@@ -0,0 +1,18 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+
+require 'mocha/no_yields'
+
+class NoYieldsTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_provide_parameters_for_no_yields_in_single_invocation
+ parameter_group = NoYields.new
+ parameter_groups = []
+ parameter_group.each do |parameters|
+ parameter_groups << parameters
+ end
+ assert_equal [], parameter_groups
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/object_inspect_test.rb b/vendor/gems/mocha-0.5.6/test/unit/object_inspect_test.rb
new file mode 100644
index 000000000..56d84a96d
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/object_inspect_test.rb
@@ -0,0 +1,37 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/inspect'
+require 'method_definer'
+
+class ObjectInspectTest < Test::Unit::TestCase
+
+ def test_should_return_default_string_representation_of_object_not_including_instance_variables
+ object = Object.new
+ class << object
+ attr_accessor :attribute
+ end
+ object.attribute = 'instance_variable'
+ assert_match Regexp.new("^#<Object:0x[0-9A-Fa-f]{1,8}.*>$"), object.mocha_inspect
+ assert_no_match(/instance_variable/, object.mocha_inspect)
+ end
+
+ def test_should_return_customized_string_representation_of_object
+ object = Object.new
+ class << object
+ define_method(:inspect) { 'custom_inspect' }
+ end
+ assert_equal 'custom_inspect', object.mocha_inspect
+ end
+
+ def test_should_use_underscored_id_instead_of_object_id_or_id_so_that_they_can_be_stubbed
+ object = Object.new
+ object.define_instance_accessor(:called)
+ object.called = false
+ object.replace_instance_method(:object_id) { self.called = true; 1 }
+ if RUBY_VERSION < '1.9'
+ object.replace_instance_method(:id) { self.called = true; 1 }
+ end
+ object.mocha_inspect
+ assert_equal false, object.called
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/object_test.rb b/vendor/gems/mocha-0.5.6/test/unit/object_test.rb
new file mode 100644
index 000000000..660b7d24f
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/object_test.rb
@@ -0,0 +1,165 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/mock'
+require 'method_definer'
+
+require 'mocha/object'
+
+class ObjectTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_build_mocha
+ instance = Object.new
+ mocha = instance.mocha
+ assert_not_nil mocha
+ assert mocha.is_a?(Mock)
+ end
+
+ def test_should_reuse_existing_mocha
+ instance = Object.new
+ mocha_1 = instance.mocha
+ mocha_2 = instance.mocha
+ assert_equal mocha_1, mocha_2
+ end
+
+ def test_should_reset_mocha
+ instance = Object.new
+ assert_nil instance.reset_mocha
+ end
+
+ def test_should_stub_instance_method
+ instance = Object.new
+ $stubba = Mock.new
+ $stubba.expects(:stub).with(Mocha::InstanceMethod.new(instance, :method1))
+ instance.expects(:method1)
+ $stubba.verify
+ end
+
+ def test_should_build_and_store_expectation
+ instance = Object.new
+ $stubba = Mock.new
+ $stubba.stubs(:stub)
+ expectation = instance.expects(:method1)
+ assert_equal [expectation], instance.mocha.expectations.to_a
+ end
+
+ def test_should_verify_expectations
+ instance = Object.new
+ $stubba = Mock.new
+ $stubba.stubs(:stub)
+ instance.expects(:method1).with(:value1, :value2)
+ assert_raise(ExpectationError) { instance.verify }
+ end
+
+ def test_should_pass_backtrace_into_expects
+ instance = Object.new
+ $stubba = Mock.new
+ $stubba.stubs(:stub)
+ mocha = Object.new
+ mocha.define_instance_accessor(:expects_parameters)
+ mocha.define_instance_method(:expects) { |*parameters| self.expects_parameters = parameters }
+ backtrace = Object.new
+ instance.define_instance_method(:mocha) { mocha }
+ instance.define_instance_method(:caller) { backtrace }
+ instance.expects(:method1)
+ assert_equal [:method1, backtrace], mocha.expects_parameters
+ end
+
+ def test_should_pass_backtrace_into_stubs
+ instance = Object.new
+ $stubba = Mock.new
+ $stubba.stubs(:stub)
+ mocha = Object.new
+ mocha.define_instance_accessor(:stubs_parameters)
+ mocha.define_instance_method(:stubs) { |*parameters| self.stubs_parameters = parameters }
+ backtrace = Object.new
+ instance.define_instance_method(:mocha) { mocha }
+ instance.define_instance_method(:caller) { backtrace }
+ instance.stubs(:method1)
+ assert_equal [:method1, backtrace], mocha.stubs_parameters
+ end
+
+ def test_should_build_any_instance_object
+ klass = Class.new
+ any_instance = klass.any_instance
+ assert_not_nil any_instance
+ assert any_instance.is_a?(Class::AnyInstance)
+ end
+
+ def test_should_return_same_any_instance_object
+ klass = Class.new
+ any_instance_1 = klass.any_instance
+ any_instance_2 = klass.any_instance
+ assert_equal any_instance_1, any_instance_2
+ end
+
+ def test_should_stub_class_method
+ klass = Class.new
+ $stubba = Mock.new
+ $stubba.expects(:stub).with(Mocha::ClassMethod.new(klass, :method1))
+ klass.expects(:method1)
+ $stubba.verify
+ end
+
+ def test_should_build_and_store_class_method_expectation
+ klass = Class.new
+ $stubba = Mock.new
+ $stubba.stubs(:stub)
+ expectation = klass.expects(:method1)
+ assert_equal [expectation], klass.mocha.expectations.to_a
+ end
+
+ def test_should_stub_module_method
+ mod = Module.new
+ $stubba = Mock.new
+ $stubba.expects(:stub).with(Mocha::ClassMethod.new(mod, :method1))
+ mod.expects(:method1)
+ $stubba.verify
+ end
+
+ def test_should_build_and_store_module_method_expectation
+ mod = Module.new
+ $stubba = Mock.new
+ $stubba.stubs(:stub)
+ expectation = mod.expects(:method1)
+ assert_equal [expectation], mod.mocha.expectations.to_a
+ end
+
+ def test_should_use_stubba_instance_method_for_object
+ assert_equal Mocha::InstanceMethod, Object.new.stubba_method
+ end
+
+ def test_should_use_stubba_class_method_for_module
+ assert_equal Mocha::ClassMethod, Module.new.stubba_method
+ end
+
+ def test_should_use_stubba_class_method_for_class
+ assert_equal Mocha::ClassMethod, Class.new.stubba_method
+ end
+
+ def test_should_use_stubba_class_method_for_any_instance
+ assert_equal Mocha::AnyInstanceMethod, Class::AnyInstance.new(nil).stubba_method
+ end
+
+ def test_should_stub_self_for_object
+ object = Object.new
+ assert_equal object, object.stubba_object
+ end
+
+ def test_should_stub_self_for_module
+ mod = Module.new
+ assert_equal mod, mod.stubba_object
+ end
+
+ def test_should_stub_self_for_class
+ klass = Class.new
+ assert_equal klass, klass.stubba_object
+ end
+
+ def test_should_stub_relevant_class_for_any_instance
+ klass = Class.new
+ any_instance = Class::AnyInstance.new(klass)
+ assert_equal klass, any_instance.stubba_object
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._all_of_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._all_of_test.rb
new file mode 100644
index 000000000..8494bfb37
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._all_of_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._any_of_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._any_of_test.rb
new file mode 100644
index 000000000..41d4c70da
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._any_of_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._anything_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._anything_test.rb
new file mode 100644
index 000000000..bbb511c34
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._anything_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_entries_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_entries_test.rb
new file mode 100644
index 000000000..d519eaa00
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_entries_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_entry_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_entry_test.rb
new file mode 100644
index 000000000..e38bb38b7
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_entry_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_key_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_key_test.rb
new file mode 100644
index 000000000..72858bd13
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_key_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_value_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_value_test.rb
new file mode 100644
index 000000000..85a2e1c06
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._has_value_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._includes_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._includes_test.rb
new file mode 100644
index 000000000..ca7d6d9ca
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._includes_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._instance_of_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._instance_of_test.rb
new file mode 100644
index 000000000..14618a7f4
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._instance_of_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._is_a_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._is_a_test.rb
new file mode 100644
index 000000000..51949f3fb
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._is_a_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._kind_of_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._kind_of_test.rb
new file mode 100644
index 000000000..773437881
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._kind_of_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._not_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._not_test.rb
new file mode 100644
index 000000000..d892eabbe
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._not_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._regexp_matches_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._regexp_matches_test.rb
new file mode 100644
index 000000000..2ceba479a
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._regexp_matches_test.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._stub_matcher.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._stub_matcher.rb
new file mode 100644
index 000000000..bc56613bf
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/._stub_matcher.rb
Binary files differ
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/all_of_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/all_of_test.rb
new file mode 100644
index 000000000..14028f52e
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/all_of_test.rb
@@ -0,0 +1,26 @@
+require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
+
+require 'mocha/parameter_matchers/all_of'
+require 'mocha/inspect'
+require 'stub_matcher'
+
+class AllOfTest < Test::Unit::TestCase
+
+ include Mocha::ParameterMatchers
+
+ def test_should_match_if_all_matchers_match
+ matcher = all_of(Stub::Matcher.new(true), Stub::Matcher.new(true), Stub::Matcher.new(true))
+ assert matcher.matches?(['any_old_value'])
+ end
+
+ def test_should_not_match_if_any_matcher_does_not_match
+ matcher = all_of(Stub::Matcher.new(true), Stub::Matcher.new(false), Stub::Matcher.new(true))
+ assert !matcher.matches?(['any_old_value'])
+ end
+
+ def test_should_describe_matcher
+ matcher = all_of(Stub::Matcher.new(true), Stub::Matcher.new(false), Stub::Matcher.new(true))
+ assert_equal 'all_of(matcher(true), matcher(false), matcher(true))', matcher.mocha_inspect
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/any_of_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/any_of_test.rb
new file mode 100644
index 000000000..503d6dc9d
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/any_of_test.rb
@@ -0,0 +1,26 @@
+require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
+
+require 'mocha/parameter_matchers/any_of'
+require 'mocha/inspect'
+require 'stub_matcher'
+
+class AnyOfTest < Test::Unit::TestCase
+
+ include Mocha::ParameterMatchers
+
+ def test_should_match_if_any_matchers_match
+ matcher = any_of(Stub::Matcher.new(false), Stub::Matcher.new(true), Stub::Matcher.new(false))
+ assert matcher.matches?(['any_old_value'])
+ end
+
+ def test_should_not_match_if_no_matchers_match
+ matcher = any_of(Stub::Matcher.new(false), Stub::Matcher.new(false), Stub::Matcher.new(false))
+ assert !matcher.matches?(['any_old_value'])
+ end
+
+ def test_should_describe_matcher
+ matcher = any_of(Stub::Matcher.new(false), Stub::Matcher.new(true), Stub::Matcher.new(false))
+ assert_equal 'any_of(matcher(false), matcher(true), matcher(false))', matcher.mocha_inspect
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/anything_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/anything_test.rb
new file mode 100644
index 000000000..42a88a16a
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/anything_test.rb
@@ -0,0 +1,21 @@
+require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
+
+require 'mocha/parameter_matchers/anything'
+require 'mocha/inspect'
+
+class AnythingTest < Test::Unit::TestCase
+
+ include Mocha::ParameterMatchers
+
+ def test_should_match_anything
+ matcher = anything
+ assert matcher.matches?([:something])
+ assert matcher.matches?([{'x' => 'y'}])
+ end
+
+ def test_should_describe_matcher
+ matcher = anything
+ assert_equal "anything", matcher.mocha_inspect
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_entries_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_entries_test.rb
new file mode 100644
index 000000000..cb85265f8
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_entries_test.rb
@@ -0,0 +1,30 @@
+require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
+
+require 'mocha/parameter_matchers/has_entries'
+require 'mocha/inspect'
+
+class HasEntriesTest < Test::Unit::TestCase
+
+ include Mocha::ParameterMatchers
+
+ def test_should_match_hash_including_specified_entries
+ matcher = has_entries(:key_1 => 'value_1', :key_2 => 'value_2')
+ assert matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2', :key_3 => 'value_3' }])
+ end
+
+ def test_should_not_match_hash_not_including_specified_entries
+ matcher = has_entries(:key_1 => 'value_2', :key_2 => 'value_2', :key_3 => 'value_3')
+ assert !matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+ end
+
+ def test_should_describe_matcher
+ matcher = has_entries(:key_1 => 'value_1', :key_2 => 'value_2')
+ description = matcher.mocha_inspect
+ matches = /has_entries\((.*)\)/.match(description)
+ assert_not_nil matches[0]
+ entries = eval(matches[1])
+ assert_equal 'value_1', entries[:key_1]
+ assert_equal 'value_2', entries[:key_2]
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_entry_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_entry_test.rb
new file mode 100644
index 000000000..3717b33b0
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_entry_test.rb
@@ -0,0 +1,40 @@
+require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
+
+require 'mocha/parameter_matchers/has_entry'
+require 'mocha/inspect'
+
+class HasEntryTest < Test::Unit::TestCase
+
+ include Mocha::ParameterMatchers
+
+ def test_should_match_hash_including_specified_key_value_pair
+ matcher = has_entry(:key_1, 'value_1')
+ assert matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+ end
+
+ def test_should_not_match_hash_not_including_specified_key_value_pair
+ matcher = has_entry(:key_1, 'value_2')
+ assert !matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+ end
+
+ def test_should_match_hash_including_specified_entry
+ matcher = has_entry(:key_1 => 'value_1')
+ assert matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+ end
+
+ def test_should_not_match_hash_not_including_specified_entry
+ matcher = has_entry(:key_1 => 'value_2')
+ assert !matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+ end
+
+ def test_should_describe_matcher_with_key_value_pair
+ matcher = has_entry(:key_1, 'value_1')
+ assert_equal "has_entry(:key_1, 'value_1')", matcher.mocha_inspect
+ end
+
+ def test_should_describe_matcher_with_entry
+ matcher = has_entry(:key_1 => 'value_1')
+ assert_equal "has_entry(:key_1, 'value_1')", matcher.mocha_inspect
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_key_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_key_test.rb
new file mode 100644
index 000000000..bc9f5065d
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_key_test.rb
@@ -0,0 +1,25 @@
+require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
+
+require 'mocha/parameter_matchers/has_key'
+require 'mocha/inspect'
+
+class HasKeyTest < Test::Unit::TestCase
+
+ include Mocha::ParameterMatchers
+
+ def test_should_match_hash_including_specified_key
+ matcher = has_key(:key_1)
+ assert matcher.matches?([{ :key_1 => 1, :key_2 => 2 }])
+ end
+
+ def test_should_not_match_hash_not_including_specified_key
+ matcher = has_key(:key_1)
+ assert !matcher.matches?([{ :key_2 => 2 }])
+ end
+
+ def test_should_describe_matcher
+ matcher = has_key(:key)
+ assert_equal 'has_key(:key)', matcher.mocha_inspect
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_value_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_value_test.rb
new file mode 100644
index 000000000..6c8957fd0
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/has_value_test.rb
@@ -0,0 +1,25 @@
+require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
+
+require 'mocha/parameter_matchers/has_value'
+require 'mocha/inspect'
+
+class HasValueTest < Test::Unit::TestCase
+
+ include Mocha::ParameterMatchers
+
+ def test_should_match_hash_including_specified_value
+ matcher = has_value('value_1')
+ assert matcher.matches?([{ :key_1 => 'value_1', :key_2 => 'value_2' }])
+ end
+
+ def test_should_not_match_hash_not_including_specified_value
+ matcher = has_value('value_1')
+ assert !matcher.matches?([{ :key_2 => 'value_2' }])
+ end
+
+ def test_should_describe_matcher
+ matcher = has_value('value_1')
+ assert_equal "has_value('value_1')", matcher.mocha_inspect
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/includes_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/includes_test.rb
new file mode 100644
index 000000000..70fb649d2
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/includes_test.rb
@@ -0,0 +1,25 @@
+require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
+
+require 'mocha/parameter_matchers/includes'
+require 'mocha/inspect'
+
+class IncludesTest < Test::Unit::TestCase
+
+ include Mocha::ParameterMatchers
+
+ def test_should_match_object_including_value
+ matcher = includes(:x)
+ assert matcher.matches?([[:x, :y, :z]])
+ end
+
+ def test_should_not_match_object_that_does_not_include_value
+ matcher = includes(:not_included)
+ assert !matcher.matches?([[:x, :y, :z]])
+ end
+
+ def test_should_describe_matcher
+ matcher = includes(:x)
+ assert_equal "includes(:x)", matcher.mocha_inspect
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/instance_of_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/instance_of_test.rb
new file mode 100644
index 000000000..415b79a48
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/instance_of_test.rb
@@ -0,0 +1,25 @@
+require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
+
+require 'mocha/parameter_matchers/instance_of'
+require 'mocha/inspect'
+
+class InstanceOfTest < Test::Unit::TestCase
+
+ include Mocha::ParameterMatchers
+
+ def test_should_match_object_that_is_an_instance_of_specified_class
+ matcher = instance_of(String)
+ assert matcher.matches?(['string'])
+ end
+
+ def test_should_not_match_object_that_is_not_an_instance_of_specified_class
+ matcher = instance_of(String)
+ assert !matcher.matches?([99])
+ end
+
+ def test_should_describe_matcher
+ matcher = instance_of(String)
+ assert_equal "instance_of(String)", matcher.mocha_inspect
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/is_a_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/is_a_test.rb
new file mode 100644
index 000000000..c9ef91965
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/is_a_test.rb
@@ -0,0 +1,25 @@
+require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
+
+require 'mocha/parameter_matchers/is_a'
+require 'mocha/inspect'
+
+class IsATest < Test::Unit::TestCase
+
+ include Mocha::ParameterMatchers
+
+ def test_should_match_object_that_is_a_specified_class
+ matcher = is_a(Integer)
+ assert matcher.matches?([99])
+ end
+
+ def test_should_not_match_object_that_is_not_a_specified_class
+ matcher = is_a(Integer)
+ assert !matcher.matches?(['string'])
+ end
+
+ def test_should_describe_matcher
+ matcher = is_a(Integer)
+ assert_equal "is_a(Integer)", matcher.mocha_inspect
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/kind_of_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/kind_of_test.rb
new file mode 100644
index 000000000..1167e5c9e
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/kind_of_test.rb
@@ -0,0 +1,25 @@
+require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
+
+require 'mocha/parameter_matchers/kind_of'
+require 'mocha/inspect'
+
+class KindOfTest < Test::Unit::TestCase
+
+ include Mocha::ParameterMatchers
+
+ def test_should_match_object_that_is_a_kind_of_specified_class
+ matcher = kind_of(Integer)
+ assert matcher.matches?([99])
+ end
+
+ def test_should_not_match_object_that_is_not_a_kind_of_specified_class
+ matcher = kind_of(Integer)
+ assert !matcher.matches?(['string'])
+ end
+
+ def test_should_describe_matcher
+ matcher = kind_of(Integer)
+ assert_equal "kind_of(Integer)", matcher.mocha_inspect
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/not_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/not_test.rb
new file mode 100644
index 000000000..4cb6790a9
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/not_test.rb
@@ -0,0 +1,26 @@
+require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
+
+require 'mocha/parameter_matchers/not'
+require 'mocha/inspect'
+require 'stub_matcher'
+
+class NotTest < Test::Unit::TestCase
+
+ include Mocha::ParameterMatchers
+
+ def test_should_match_if_matcher_does_not_match
+ matcher = Not(Stub::Matcher.new(false))
+ assert matcher.matches?(['any_old_value'])
+ end
+
+ def test_should_not_match_if_matcher_does_match
+ matcher = Not(Stub::Matcher.new(true))
+ assert !matcher.matches?(['any_old_value'])
+ end
+
+ def test_should_describe_matcher
+ matcher = Not(Stub::Matcher.new(true))
+ assert_equal 'Not(matcher(true))', matcher.mocha_inspect
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/regexp_matches_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/regexp_matches_test.rb
new file mode 100644
index 000000000..a8294bfe0
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/regexp_matches_test.rb
@@ -0,0 +1,25 @@
+require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
+
+require 'mocha/parameter_matchers/regexp_matches'
+require 'mocha/inspect'
+
+class MatchesTest < Test::Unit::TestCase
+
+ include Mocha::ParameterMatchers
+
+ def test_should_match_parameter_matching_regular_expression
+ matcher = regexp_matches(/oo/)
+ assert matcher.matches?(['foo'])
+ end
+
+ def test_should_not_match_parameter_not_matching_regular_expression
+ matcher = regexp_matches(/oo/)
+ assert !matcher.matches?(['bar'])
+ end
+
+ def test_should_describe_matcher
+ matcher = regexp_matches(/oo/)
+ assert_equal "regexp_matches(/oo/)", matcher.mocha_inspect
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/stub_matcher.rb b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/stub_matcher.rb
new file mode 100644
index 000000000..920ced23b
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameter_matchers/stub_matcher.rb
@@ -0,0 +1,23 @@
+module Stub
+
+ class Matcher
+
+ attr_accessor :value
+
+ def initialize(matches)
+ @matches = matches
+ end
+
+ def matches?(available_parameters)
+ value = available_parameters.shift
+ @value = value
+ @matches
+ end
+
+ def mocha_inspect
+ "matcher(#{@matches})"
+ end
+
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/parameters_matcher_test.rb b/vendor/gems/mocha-0.5.6/test/unit/parameters_matcher_test.rb
new file mode 100644
index 000000000..612805e45
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/parameters_matcher_test.rb
@@ -0,0 +1,121 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/parameters_matcher'
+
+class ParametersMatcherTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_match_any_actual_parameters_if_no_expected_parameters_specified
+ parameters_matcher = ParametersMatcher.new
+ assert parameters_matcher.match?(actual_parameters = [1, 2, 3])
+ end
+
+ def test_should_match_if_actual_parameters_are_same_as_expected_parameters
+ parameters_matcher = ParametersMatcher.new(expected_parameters = [4, 5, 6])
+ assert parameters_matcher.match?(actual_parameters = [4, 5, 6])
+ end
+
+ def test_should_not_match_if_actual_parameters_are_different_from_expected_parameters
+ parameters_matcher = ParametersMatcher.new(expected_parameters = [4, 5, 6])
+ assert !parameters_matcher.match?(actual_parameters = [1, 2, 3])
+ end
+
+ def test_should_not_match_if_there_are_less_actual_parameters_than_expected_parameters
+ parameters_matcher = ParametersMatcher.new(expected_parameters = [4, 5, 6])
+ assert !parameters_matcher.match?(actual_parameters = [4, 5])
+ end
+
+ def test_should_not_match_if_there_are_more_actual_parameters_than_expected_parameters
+ parameters_matcher = ParametersMatcher.new(expected_parameters = [4, 5])
+ assert !parameters_matcher.match?(actual_parameters = [4, 5, 6])
+ end
+
+ def test_should_not_match_if_not_all_required_parameters_are_supplied
+ optionals = ParameterMatchers::Optionally.new(6, 7)
+ parameters_matcher = ParametersMatcher.new(expected_parameters = [4, 5, optionals])
+ assert !parameters_matcher.match?(actual_parameters = [4])
+ end
+
+ def test_should_match_if_all_required_parameters_match_and_no_optional_parameters_are_supplied
+ optionals = ParameterMatchers::Optionally.new(6, 7)
+ parameters_matcher = ParametersMatcher.new(expected_parameters = [4, 5, optionals])
+ assert parameters_matcher.match?(actual_parameters = [4, 5])
+ end
+
+ def test_should_match_if_all_required_and_optional_parameters_match_and_some_optional_parameters_are_supplied
+ optionals = ParameterMatchers::Optionally.new(6, 7)
+ parameters_matcher = ParametersMatcher.new(expected_parameters = [4, 5, optionals])
+ assert parameters_matcher.match?(actual_parameters = [4, 5, 6])
+ end
+
+ def test_should_match_if_all_required_and_optional_parameters_match_and_all_optional_parameters_are_supplied
+ optionals = ParameterMatchers::Optionally.new(6, 7)
+ parameters_matcher = ParametersMatcher.new(expected_parameters = [4, 5, optionals])
+ assert parameters_matcher.match?(actual_parameters = [4, 5, 6, 7])
+ end
+
+ def test_should_not_match_if_all_required_and_optional_parameters_match_but_too_many_optional_parameters_are_supplied
+ optionals = ParameterMatchers::Optionally.new(6, 7)
+ parameters_matcher = ParametersMatcher.new(expected_parameters = [4, 5, optionals])
+ assert !parameters_matcher.match?(actual_parameters = [4, 5, 6, 7, 8])
+ end
+
+ def test_should_not_match_if_all_required_parameters_match_but_some_optional_parameters_do_not_match
+ optionals = ParameterMatchers::Optionally.new(6, 7)
+ parameters_matcher = ParametersMatcher.new(expected_parameters = [4, 5, optionals])
+ assert !parameters_matcher.match?(actual_parameters = [4, 5, 6, 0])
+ end
+
+ def test_should_not_match_if_some_required_parameters_do_not_match_although_all_optional_parameters_do_match
+ optionals = ParameterMatchers::Optionally.new(6, 7)
+ parameters_matcher = ParametersMatcher.new(expected_parameters = [4, 5, optionals])
+ assert !parameters_matcher.match?(actual_parameters = [4, 0, 6])
+ end
+
+ def test_should_not_match_if_all_required_parameters_match_but_no_optional_parameters_match
+ optionals = ParameterMatchers::Optionally.new(6, 7)
+ parameters_matcher = ParametersMatcher.new(expected_parameters = [4, 5, optionals])
+ assert !parameters_matcher.match?(actual_parameters = [4, 5, 0, 0])
+ end
+
+ def test_should_match_if_actual_parameters_satisfy_matching_block
+ parameters_matcher = ParametersMatcher.new { |x, y| x + y == 3 }
+ assert parameters_matcher.match?(actual_parameters = [1, 2])
+ end
+
+ def test_should_not_match_if_actual_parameters_do_not_satisfy_matching_block
+ parameters_matcher = ParametersMatcher.new { |x, y| x + y == 3 }
+ assert !parameters_matcher.match?(actual_parameters = [2, 3])
+ end
+
+ def test_should_remove_outer_array_braces
+ params = [1, 2, [3, 4]]
+ parameters_matcher = ParametersMatcher.new(params)
+ assert_equal '(1, 2, [3, 4])', parameters_matcher.mocha_inspect
+ end
+
+ def test_should_display_numeric_arguments_as_is
+ params = [1, 2, 3]
+ parameters_matcher = ParametersMatcher.new(params)
+ assert_equal '(1, 2, 3)', parameters_matcher.mocha_inspect
+ end
+
+ def test_should_remove_curly_braces_if_hash_is_only_argument
+ params = [{:a => 1, :z => 2}]
+ parameters_matcher = ParametersMatcher.new(params)
+ assert_nil parameters_matcher.mocha_inspect.index('{')
+ assert_nil parameters_matcher.mocha_inspect.index('}')
+ end
+
+ def test_should_not_remove_curly_braces_if_hash_is_not_the_only_argument
+ params = [1, {:a => 1}]
+ parameters_matcher = ParametersMatcher.new(params)
+ assert_equal '(1, {:a => 1})', parameters_matcher.mocha_inspect
+ end
+
+ def test_should_indicate_that_matcher_will_match_any_actual_parameters
+ parameters_matcher = ParametersMatcher.new
+ assert_equal '(any_parameters)', parameters_matcher.mocha_inspect
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/return_values_test.rb b/vendor/gems/mocha-0.5.6/test/unit/return_values_test.rb
new file mode 100644
index 000000000..01ddfbcd5
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/return_values_test.rb
@@ -0,0 +1,63 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+
+require 'mocha/return_values'
+
+class ReturnValuesTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_return_nil
+ values = ReturnValues.new
+ assert_nil values.next
+ end
+
+ def test_should_keep_returning_nil
+ values = ReturnValues.new
+ values.next
+ assert_nil values.next
+ assert_nil values.next
+ end
+
+ def test_should_return_evaluated_single_return_value
+ values = ReturnValues.new(SingleReturnValue.new('value'))
+ assert_equal 'value', values.next
+ end
+
+ def test_should_keep_returning_evaluated_single_return_value
+ values = ReturnValues.new(SingleReturnValue.new('value'))
+ values.next
+ assert_equal 'value', values.next
+ assert_equal 'value', values.next
+ end
+
+ def test_should_return_consecutive_evaluated_single_return_values
+ values = ReturnValues.new(SingleReturnValue.new('value_1'), SingleReturnValue.new('value_2'))
+ assert_equal 'value_1', values.next
+ assert_equal 'value_2', values.next
+ end
+
+ def test_should_keep_returning_last_of_consecutive_evaluated_single_return_values
+ values = ReturnValues.new(SingleReturnValue.new('value_1'), SingleReturnValue.new('value_2'))
+ values.next
+ values.next
+ assert_equal 'value_2', values.next
+ assert_equal 'value_2', values.next
+ end
+
+ def test_should_build_single_return_values_for_each_values
+ values = ReturnValues.build('value_1', 'value_2', 'value_3').values
+ assert_equal 'value_1', values[0].evaluate
+ assert_equal 'value_2', values[1].evaluate
+ assert_equal 'value_3', values[2].evaluate
+ end
+
+ def test_should_combine_two_sets_of_return_values
+ values_1 = ReturnValues.build('value_1')
+ values_2 = ReturnValues.build('value_2a', 'value_2b')
+ values = (values_1 + values_2).values
+ assert_equal 'value_1', values[0].evaluate
+ assert_equal 'value_2a', values[1].evaluate
+ assert_equal 'value_2b', values[2].evaluate
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/sequence_test.rb b/vendor/gems/mocha-0.5.6/test/unit/sequence_test.rb
new file mode 100644
index 000000000..544b3fe9c
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/sequence_test.rb
@@ -0,0 +1,104 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/sequence'
+require 'mocha/expectation'
+
+class SequenceTest < Test::Unit::TestCase
+
+ include Mocha
+
+ class FakeExpectation
+
+ attr_reader :ordering_constraints
+
+ def initialize(satisfied = false)
+ @satisfied = satisfied
+ @ordering_constraints = []
+ end
+
+ def add_ordering_constraint(ordering_constraint)
+ @ordering_constraints << ordering_constraint
+ end
+
+ def satisfied?
+ @satisfied
+ end
+
+ end
+
+ def test_should_be_satisfied_if_no_expectations_added
+ sequence = Sequence.new('name')
+ assert sequence.satisfied_to_index?(0)
+ end
+
+ def test_should_be_satisfied_if_one_unsatisfied_expectations_added_but_it_is_not_included_by_index
+ sequence = Sequence.new('name')
+ expectation = FakeExpectation.new(satisfied = false)
+ sequence.constrain_as_next_in_sequence(expectation)
+ assert sequence.satisfied_to_index?(0)
+ end
+
+ def test_should_not_be_satisfied_if_one_unsatisfied_expectations_added_and_it_is_included_by_index
+ sequence = Sequence.new('name')
+ expectation = FakeExpectation.new(satisfied = false)
+ sequence.constrain_as_next_in_sequence(expectation)
+ assert !sequence.satisfied_to_index?(1)
+ end
+
+ def test_should_be_satisfied_if_one_satisfied_expectations_added_and_it_is_included_by_index
+ sequence = Sequence.new('name')
+ expectation = FakeExpectation.new(satisfied = true)
+ sequence.constrain_as_next_in_sequence(expectation)
+ assert sequence.satisfied_to_index?(1)
+ end
+
+ def test_should_not_be_satisfied_if_one_satisfied_and_one_unsatisfied_expectation_added_and_both_are_included_by_index
+ sequence = Sequence.new('name')
+ expectation_one = FakeExpectation.new(satisfied = true)
+ expectation_two = FakeExpectation.new(satisfied = false)
+ sequence.constrain_as_next_in_sequence(expectation_one)
+ sequence.constrain_as_next_in_sequence(expectation_two)
+ assert !sequence.satisfied_to_index?(2)
+ end
+
+ def test_should_be_satisfied_if_two_satisfied_expectations_added_and_both_are_included_by_index
+ sequence = Sequence.new('name')
+ expectation_one = FakeExpectation.new(satisfied = true)
+ expectation_two = FakeExpectation.new(satisfied = true)
+ sequence.constrain_as_next_in_sequence(expectation_one)
+ sequence.constrain_as_next_in_sequence(expectation_two)
+ assert sequence.satisfied_to_index?(2)
+ end
+
+ def test_should_add_ordering_constraint_to_expectation
+ sequence = Sequence.new('name')
+ expectation = FakeExpectation.new
+ sequence.constrain_as_next_in_sequence(expectation)
+ assert_equal 1, expectation.ordering_constraints.length
+ end
+
+ def test_should_not_allow_invocation_of_second_method_when_first_n_sequence_has_not_been_invoked
+ sequence = Sequence.new('name')
+ expectation_one = FakeExpectation.new(satisfied = false)
+ expectation_two = FakeExpectation.new(satisfied = false)
+ sequence.constrain_as_next_in_sequence(expectation_one)
+ sequence.constrain_as_next_in_sequence(expectation_two)
+ assert !expectation_two.ordering_constraints[0].allows_invocation_now?
+ end
+
+ def test_should_allow_invocation_of_second_method_when_first_in_sequence_has_been_invoked
+ sequence = Sequence.new('name')
+ expectation_one = FakeExpectation.new(satisfied = true)
+ expectation_two = FakeExpectation.new(satisfied = false)
+ sequence.constrain_as_next_in_sequence(expectation_one)
+ sequence.constrain_as_next_in_sequence(expectation_two)
+ assert expectation_two.ordering_constraints[0].allows_invocation_now?
+ end
+
+ def test_should_describe_ordering_constraint_as_being_part_of_named_sequence
+ sequence = Sequence.new('wibble')
+ expectation = FakeExpectation.new
+ sequence.constrain_as_next_in_sequence(expectation)
+ assert_equal "in sequence 'wibble'", expectation.ordering_constraints[0].mocha_inspect
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/setup_and_teardown_test.rb b/vendor/gems/mocha-0.5.6/test/unit/setup_and_teardown_test.rb
new file mode 100644
index 000000000..83247888e
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/setup_and_teardown_test.rb
@@ -0,0 +1,76 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/mock'
+
+require 'mocha/setup_and_teardown'
+
+class SetupAndTeardownTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_instantiate_new_stubba
+ test_case = stubbed_test_case_class.new
+ test_case.setup_stubs
+
+ assert $stubba
+ assert $stubba.is_a?(Mocha::Central)
+ end
+
+ def test_should_verify_all_expectations
+ test_case = stubbed_test_case_class.new
+ stubba = Mock.new
+ stubba.expects(:verify_all)
+ $stubba = stubba
+
+ test_case.verify_stubs
+
+ stubba.verify
+ end
+
+ def test_should_yield_to_block_for_each_assertion
+ test_case = stubbed_test_case_class.new
+ $stubba = Mock.new
+ $stubba.stubs(:verify_all).yields
+ yielded = false
+
+ test_case.verify_stubs { yielded = true }
+
+ assert_equal true, yielded
+ end
+
+ def test_should_unstub_all_stubbed_methods
+ test_case = stubbed_test_case_class.new
+ stubba = Mock.new
+ stubba.expects(:unstub_all)
+ $stubba = stubba
+
+ test_case.teardown_stubs
+
+ stubba.verify
+ end
+
+ def test_should_set_stubba_to_nil
+ test_case = stubbed_test_case_class.new
+ $stubba = Mock.new
+ $stubba.stubs(:unstub_all)
+
+ test_case.teardown_stubs
+
+ assert_nil $stubba
+ end
+
+ def test_should_not_raise_exception_if_no_stubba_central_available
+ test_case = stubbed_test_case_class.new
+ $stubba = nil
+ assert_nothing_raised { test_case.teardown_stubs }
+ end
+
+ private
+
+ def stubbed_test_case_class
+ Class.new do
+ include Mocha::SetupAndTeardown
+ end
+ end
+
+end
+
diff --git a/vendor/gems/mocha-0.5.6/test/unit/single_return_value_test.rb b/vendor/gems/mocha-0.5.6/test/unit/single_return_value_test.rb
new file mode 100644
index 000000000..9d3d799b0
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/single_return_value_test.rb
@@ -0,0 +1,33 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+
+require 'mocha/single_return_value'
+require 'deprecation_disabler'
+
+class SingleReturnValueTest < Test::Unit::TestCase
+
+ include Mocha
+ include DeprecationDisabler
+
+ def test_should_return_value
+ value = SingleReturnValue.new('value')
+ assert_equal 'value', value.evaluate
+ end
+
+ def test_should_return_result_of_calling_proc
+ proc = lambda { 'value' }
+ value = SingleReturnValue.new(proc)
+ result = nil
+ disable_deprecations { result = value.evaluate }
+ assert_equal 'value', result
+ end
+
+ def test_should_indicate_deprecated_use_of_expectation_returns_method
+ proc = lambda {}
+ value = SingleReturnValue.new(proc)
+ Deprecation.messages = []
+ disable_deprecations { value.evaluate }
+ expected_message = "use of Expectation#returns with instance of Proc - see Expectation#returns RDoc for alternatives"
+ assert_equal [expected_message], Deprecation.messages
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/single_yield_test.rb b/vendor/gems/mocha-0.5.6/test/unit/single_yield_test.rb
new file mode 100644
index 000000000..12bd0a2fd
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/single_yield_test.rb
@@ -0,0 +1,18 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+
+require 'mocha/single_yield'
+
+class SingleYieldTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_provide_parameters_for_single_yield_in_single_invocation
+ parameter_group = SingleYield.new(1, 2, 3)
+ parameter_groups = []
+ parameter_group.each do |parameters|
+ parameter_groups << parameters
+ end
+ assert_equal [[1, 2, 3]], parameter_groups
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/string_inspect_test.rb b/vendor/gems/mocha-0.5.6/test/unit/string_inspect_test.rb
new file mode 100644
index 000000000..43b9c4e32
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/string_inspect_test.rb
@@ -0,0 +1,11 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/inspect'
+
+class StringInspectTest < Test::Unit::TestCase
+
+ def test_should_replace_escaped_quotes_with_single_quote
+ string = "my_string"
+ assert_equal "'my_string'", string.mocha_inspect
+ end
+
+end
diff --git a/vendor/gems/mocha-0.5.6/test/unit/stub_test.rb b/vendor/gems/mocha-0.5.6/test/unit/stub_test.rb
new file mode 100644
index 000000000..a225963b9
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/stub_test.rb
@@ -0,0 +1,24 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+require 'mocha/stub'
+
+class StubTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_always_verify_successfully
+ stub = Stub.new(nil, :expected_method)
+ assert stub.verify
+ stub.invoke
+ assert stub.verify
+ end
+
+ def test_should_match_successfully_for_any_number_of_invocations
+ stub = Stub.new(nil, :expected_method)
+ assert stub.match?(:expected_method)
+ stub.invoke
+ assert stub.match?(:expected_method)
+ stub.invoke
+ assert stub.match?(:expected_method)
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/mocha-0.5.6/test/unit/yield_parameters_test.rb b/vendor/gems/mocha-0.5.6/test/unit/yield_parameters_test.rb
new file mode 100644
index 000000000..4e93f1336
--- /dev/null
+++ b/vendor/gems/mocha-0.5.6/test/unit/yield_parameters_test.rb
@@ -0,0 +1,93 @@
+require File.join(File.dirname(__FILE__), "..", "test_helper")
+
+require 'mocha/yield_parameters'
+require 'mocha/no_yields'
+require 'mocha/single_yield'
+require 'mocha/multiple_yields'
+
+class YieldParametersTest < Test::Unit::TestCase
+
+ include Mocha
+
+ def test_should_return_null_yield_parameter_group_by_default
+ yield_parameters = YieldParameters.new
+ assert yield_parameters.next_invocation.is_a?(NoYields)
+ end
+
+ def test_should_return_single_yield_parameter_group
+ yield_parameters = YieldParameters.new
+ yield_parameters.add(1, 2, 3)
+ parameter_group = yield_parameters.next_invocation
+ assert parameter_group.is_a?(SingleYield)
+ assert_equal [1, 2, 3], parameter_group.parameters
+ end
+
+ def test_should_keep_returning_single_yield_parameter_group
+ yield_parameters = YieldParameters.new
+ yield_parameters.add(1, 2, 3)
+ yield_parameters.next_invocation
+ parameter_group = yield_parameters.next_invocation
+ assert parameter_group.is_a?(SingleYield)
+ assert_equal [1, 2, 3], parameter_group.parameters
+ parameter_group = yield_parameters.next_invocation
+ assert parameter_group.is_a?(SingleYield)
+ assert_equal [1, 2, 3], parameter_group.parameters
+ end
+
+ def test_should_return_consecutive_single_yield_parameter_groups
+ yield_parameters = YieldParameters.new
+ yield_parameters.add(1, 2, 3)
+ yield_parameters.add(4, 5)
+ parameter_group = yield_parameters.next_invocation
+ assert parameter_group.is_a?(SingleYield)
+ assert_equal [1, 2, 3], parameter_group.parameters
+ parameter_group = yield_parameters.next_invocation
+ assert parameter_group.is_a?(SingleYield)
+ assert_equal [4, 5], parameter_group.parameters
+ end
+
+ def test_should_return_multiple_yield_parameter_group
+ yield_parameters = YieldParameters.new
+ yield_parameters.multiple_add([1, 2, 3], [4, 5])
+ parameter_group = yield_parameters.next_invocation
+ assert parameter_group.is_a?(MultipleYields)
+ assert_equal [[1, 2, 3], [4, 5]], parameter_group.parameter_groups
+ end
+
+ def test_should_keep_returning_multiple_yield_parameter_group
+ yield_parameters = YieldParameters.new
+ yield_parameters.multiple_add([1, 2, 3], [4, 5])
+ yield_parameters.next_invocation
+ parameter_group = yield_parameters.next_invocation
+ assert parameter_group.is_a?(MultipleYields)
+ assert_equal [[1, 2, 3], [4, 5]], parameter_group.parameter_groups
+ parameter_group = yield_parameters.next_invocation
+ assert parameter_group.is_a?(MultipleYields)
+ assert_equal [[1, 2, 3], [4, 5]], parameter_group.parameter_groups
+ end
+
+ def test_should_return_consecutive_multiple_yield_parameter_groups
+ yield_parameters = YieldParameters.new
+ yield_parameters.multiple_add([1, 2, 3], [4, 5])
+ yield_parameters.multiple_add([6, 7], [8, 9, 0])
+ parameter_group = yield_parameters.next_invocation
+ assert parameter_group.is_a?(MultipleYields)
+ assert_equal [[1, 2, 3], [4, 5]], parameter_group.parameter_groups
+ parameter_group = yield_parameters.next_invocation
+ assert parameter_group.is_a?(MultipleYields)
+ assert_equal [[6, 7], [8, 9, 0]], parameter_group.parameter_groups
+ end
+
+ def test_should_return_consecutive_single_and_multiple_yield_parameter_groups
+ yield_parameters = YieldParameters.new
+ yield_parameters.add(1, 2, 3)
+ yield_parameters.multiple_add([4, 5, 6], [7, 8])
+ parameter_group = yield_parameters.next_invocation
+ assert parameter_group.is_a?(SingleYield)
+ assert_equal [1, 2, 3], parameter_group.parameters
+ parameter_group = yield_parameters.next_invocation
+ assert parameter_group.is_a?(MultipleYields)
+ assert_equal [[4, 5, 6], [7, 8]], parameter_group.parameter_groups
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/CHANGES b/vendor/gems/rspec/CHANGES
new file mode 100644
index 000000000..887c9d857
--- /dev/null
+++ b/vendor/gems/rspec/CHANGES
@@ -0,0 +1,1045 @@
+== Version 1.1.3
+
+Maintenance release.
+
+* Tightened up exceptions list in autotest/rails_spec. Closes #264.
+* Applied patch from Ryan Davis for ZenTest-3.9.0 compatibility
+* Applied patch from Kero to add step_upcoming to story listeners. Closes #253.
+* Fixed bug where the wrong named error was not always caught by "should raise_error"
+* Applied patch from Luis Lavena: No coloured output on Windows due missing RUBYOPT. Closes #244.
+* Applied patch from Craig Demyanovich to add support for "should_not render_template" to rspec_on_rails. Closes #241.
+* Added --pattern (-p for short) option to control what files get loaded. Defaults to '**/*_spec.rb'
+* Exit with non-0 exit code if examples *or tests* (in test/unit interop mode) fail. Closes #203.
+* Moved at_exit hook to a method in Spec::Runner which only runs if specs get loaded. Closes #242.
+* Applied patch from kakutani ensuring that base_view_path gets cleared after each view example. Closes #235.
+* More tweaks to regexp step names
+* Fixed focused specs in nested ExampleGroups. Closes #225.
+
+== Version 1.1.2
+
+Minor bug fixes/enhancements.
+
+* RSpec's Autotest subclasses compatible with ZenTest-3.8.0 (thanks to Ryan Davis for making it easier on Autotest subs).
+* Applied patch from idl to add spec/lib to rake stats. Closes #226.
+* calling setup_fixtures and teardown_fixtures for Rails >= r8570. Closes #219.
+* Applied patch from Josh Knowles using ActiveSupport's Inflector (when available) to make 'should have' read a bit better. Closes #197.
+* Fixed regression in 1.1 that caused failing examples to fail to generate their own names. Closes #209.
+* Applied doc patch from Jens Krämer for capturing content_for
+* Applied patch from Alexander Lang to clean up story steps after each story. Closes #198.
+* Applied patch from Josh Knowles to support 'string_or_response.should have_text(...)'. Closes #193.
+* Applied patch from Ian Dees to quiet the Story Runner backtrace. Closes #183.
+* Complete support for defining steps with regexp 'names'.
+
+== Version 1.1.1
+
+Bug fix release.
+
+* Fix regression in 1.1.0 that caused transactions to not get rolled back between examples.
+* Applied patch from Bob Cotton to reintroduce ExampleGroup.description_options. Closes LH[#186]
+
+== Version 1.1.0
+
+The "tell me a story and go nest yourself" release.
+
+* Applied patch from Mike Vincent to handle generators rails > 2.0.1. Closes LH[#181]
+* Formatter.pending signature changed so it gets passed an ExampleGroup instance instead of the name ( LH[#180])
+* Fixed LH[#180] Spec::Rails::Example::ModelExampleGroup and friends show up in rspec/rails output
+* Spec::Rails no longer loads ActiveRecord extensions if it's disabled in config/boot.rb
+* Applied LH[#178] small annoyances running specs with warnings enabled (Patch from Mikko Lehtonen)
+* Tighter integration with Rails fixtures. Take advantage of fixture caching to get performance improvements (Thanks to Pat Maddox, Nick Kallen, Jonathan Barnes, and Curtis)
+
+== Version 1.1.0-RC1
+
+Textmate Bundle users - this release adds a new RSpec bundle that highlights describe, it, before and after and
+provides navigation to descriptions and examples (rather than classes and methods). When you first install this,
+it is going to try to hijack all of your .rb files. All you need to do is open a .rb file that does not end with
+'spec.rb' and change the bundle selection from RSpec to Ruby. TextMate will do the right thing from then on.
+
+Shortcuts for tab-activated snippets all follow the TextMate convention of 2 or 3 letters of the first word, followed by the first letter of each subsequent word. So "should have_at_least" would be triggered by shhal.
+
+We reduced the scope for running spec directories, files, a single file or individual spec in TextMate to source.ruby.rspec. This allowed us to restore the standard Ruby shortcuts:
+
+CMD-R runs all the specs in one file
+CMD-SHIFT-R runs an individual spec
+CMD-OPT-R runs any files or directories selected in the TextMate drawer
+
+rspec_on_rails users - don't forget to run script/generate rspec
+
+* Added shared_examples_for method, which you can (should) use instead of describe Foo, :shared => true
+* Applied LH[#168] Fix describe Object, "description contains a # in it" (Patch from Martin Emde)
+* Applied LH[#15] Reverse loading of ActionView::Base helper modules (Patch from Mark Van Holstyn)
+* Applied LH[#149] Update contribute page to point towards lighthouse (Patch from Josh Knowles)
+* Applied LH[#142] verify_rcov fails with latest rcov (Patch from Kyle Hargraves)
+* Applied LH[#10] Allow stubs to yield and return values (Patch from Pat Maddox)
+* Fixed LH[#139] version.rb in trunk missing svn last changed number
+* Applied LH[#14] Adding support for by_at_least/by_at_most in Change matcher (Patch from Saimon Moore)
+* Applied LH[#12] Fix for TM when switching to alternate file (Patch from Trevor Squires)
+* Applied LH[#133] ExampleMatcher should match against before(:all) (Patch from Bob Cotton)
+* Applied LH[#134] Only load spec inside spec_helper.rb (Patch from Mark Van Holstyn)
+* RSpec now bails immediately if there are examples with identical names.
+* Applied LH[#132] Plain Text stories should support Given and Given: (Patch from Jarkko Laine)
+* Applied patch from Pat Maddox: Story Mediator - the glue that binds the plain text story parser with the rest of the system
+* Applied LH[#16] Have SimpleMatchers expose their description for specdocs (Patch from Bryan Helmkamp)
+* Stories now support --colour
+* Changed the DSL modules to Example (i.e. Spec::Example instead of Spec::DSL)
+* Applied [#15608] Story problem if parenthesis used in Given, When, Then or And (Patch from Sinclair Bain)
+* Applied [#15659] GivenScenario fails when it is a RailsStory (Patch from Nathan Sutton)
+* Fixed [#15639] rcov exclusion configuration. (Spec::Rails projects can configure rcov with spec/rcov.opts)
+* The rdoc formatter (--format rdoc) is gone. It was buggy and noone was using it.
+* Changed Spec::DSL::Behaviour to Spec::DSL::ExampleGroup
+* Changed Spec::DSL::SharedBehaviour to Spec::DSL::SharedExampleGroup
+* Applied [#14023] Small optimization for heavily proxied objects. (Patch from Ian Leitch)
+* Applied [#13943] ProfileFormatter (Top 10 slowest examples) (Patch from Ian Leitch)
+* Fixed [#15232] heckle is not working correctly in trunk (as of r2801)
+* Applied [#14399] Show pending reasons in HTML report (Patch from Bryan Helmkamp)
+* Discovered fixed: [#10263] mock "leak" when setting an expectation in a block passed to mock#should_receive
+* Fixed [#14671] Spec::DSL::ExampleRunner gives "NO NAME because of --dry-run" for every example for 'rake spec:doc'
+* Fixed [#14543] rspec_scaffold broken with Rails 2.0
+* Removed Patch [#10577] Rails with Oracle breaks 0.9.2 - was no longer necessary since we moved describe to the Main object (instead of Object)
+* Fixed [#14527] specs run twice on rails 1.2.4 and rspec/rspec_on_rails trunk
+* Applied [#14043] Change output ordering to show pending before errors (Patch from Mike Mangino)
+* Applied [#14095] Don't have ./script/generate rspec create previous_failures.txt (Patch from Bryan Helmkamp)
+* Applied [#14254] Improved error handling for Object#should and Object#should_not (Patch from Antti Tarvainen)
+* Applied [#14186] Remove dead code from message_expecation.rb (Patch from Antti Tarvainen)
+* Applied [#14183] Tiny improvement on mock_spec.rb (Patch from Antti Tarvainen)
+* Applied [#14208] Fix to Mock#method_missing raising NameErrors instead of MockExpectationErrors (Patch from Antti Tarvainen)
+* Applied [#14255] Fixed examples in mock_spec.rb and shared_behaviour_spec.rb (Patch from Antti Tarvainen)
+* Applied [#14362] partially mocking objects that define == can blow up (Patch from Pat Maddox)
+* test_ methods with an arity of 0 defined in a describe block or Example object will be run as an Example, providing a seamless transition from Test::Unit
+* Removed BehaviourRunner
+* Fixed [#13969] Spec Failures on Trunk w/ Autotest
+* Applied [#14156] False positives with should_not (Patch from Antti Tarvainen)
+* Applied [#14170] route_for and params_from internal specs fixed (Patch from Antti Tarvainen)
+* Fixed [#14166] Cannot build trunk
+* Applied [#14142] Fix for bug #11602: Nested #have_tag specifications fails on the wrong line number (Patch from Antti Tarvainen)
+* Removed warn_if_no_files argument and feature
+* Steps (Given/When/Then) with no blocks are treated as pending
+* Applied [#13913] Scenario should treat no code block as pending (Patch from Evan Light)
+* Fixed [#13370] Weird mock expectation error (Patch from Mike Mangino)
+* Applied [#13952] Fix for performance regression introduced in r2096 (Patch from Ian Leitch)
+* Applied [#13881] Dynamically include Helpers that are included on ActionView::Base (Patch from Brandon Keepers)
+* Applied [#13833] ActionView::Helpers::JavaScriptMacrosHelper removed after 1.2.3 (Patch from Yurii Rashkovskii)
+* Applied [#13814] RSpec on Rails w/ fixture-scenarios (Patch from Shintaro Kakutani)
+* Add ability to define Example subclass instead of using describe
+* Applied Patch from James Edward Gray II to improve syntax highlighting in TextMate
+* Fixed [#13579] NoMethodError not raised for missing helper methods
+* Fixed [#13713] form helper method 'select' can not be called when calling custom helper methods from specs
+* Example subclasses Test::Unit::TestCase
+* Added stub_everything method to create a stub that will return itself for any message it doesn't understand
+* Added stories directory with stories/all.rb and stories/helper.rb when you script/generate rspec
+* Applied [#13554] Add "And" so you can say Given... And... When... Then... And...
+* Applied [#11254] RSpec syntax coloring and function pop-up integration in TextMate (Patch from Wincent Colaiuta)
+* Applied [#13143] ActionView::Helpers::RecordIdentificationHelper should be included if present (Patch from Jay Levitt)
+* Applied [#13567] patch to allow stubs to yield consecutive values (Patch from Rupert Voelcker)
+* Applied [#13559] reverse version of route_for (Patch from Rupert Voelcker)
+* Added [#13532] /lib specs should get base EvalContext
+* Applied [#13451] Add a null_object option to mock_model (Patch from James Deville)
+* Applied [#11919] Making non-implemented specs easy in textmate (Patch from Scott Taylor)
+* Applied [#13274] ThrowSymbol recognized a NameError triggered by Kernel#method_missing as a thrown Symbol
+* Applied [#12722] the alternate file command does not work in rails views due to scope (Patch from Carl Porth)
+* Behaviour is now a Module that is used by Example class methods and SharedBehaviour
+* Added ExampleDefinition
+* Added story runner framework based on rbehave [#12628]
+* Applied [#13336] Helper directory incorrect for rake stats in statsetup task (Patch from Curtis Miller)
+* Applied [#13339] Add the ability for spec_parser to parse describes with :behaviour_type set (Patch from Will Leinweber and Dav Yaginuma)
+* Fixed [#13271] incorrect behaviour with expect_render and stub_render
+* Applied [#13129] Fix failing specs in spec_distributed (Patch from Bob Cotton)
+* Applied [#13118] Rinda support for Spec::Distributed (Patch from Bob Cotton)
+* Removed BehaviourEval
+* Removed Behaviour#inherit
+* Moved implementation of install_dependencies to example_rails_app
+* Renamed RSPEC_DEPS to VENDOR_DEPS
+* Added Example#not_implemented?
+* You can now stub!(:msg).with(specific args)
+* describe("A", Hash, "with one element") will generate description "A Hash with one element" (Tip from Ola Bini)
+* Applied [#13016] [DOC] Point out that view specs render, well, a view (Patch from Jay Levitt)
+* Applied [#13078] Develop rspec with autotest (Patch from Scott Taylor)
+* Fixed [#13065] Named routes throw a NoMethodError in Helper specs (Patches from James Deville and Mike Mangino)
+* Added (back) the verbose attribute in Spec::Rake::SpecTask
+* Changed documentation to point at the new http svn URL, which is more accessible.
+
+== Version 1.0.8
+
+Another bugfix release - this time to resolve the version mismatch
+
+== Version 1.0.7
+
+Quick bugfix release to ensure that you don't have to have the rspec gem installed
+in order to use autotest with rspec_on_rails.
+
+* Fixed [#13015] autotest gives failure in 'spec_command' after upgrade 1.0.5 to 1.0.6
+
+== Version 1.0.6
+
+The "holy cow, batman, it's been a long time since we released and there are a ton of bug
+fixes, patches and even new features" release.
+
+Warning: Spec::Rails users: In fixing 11508, we've removed the raise_controller_errors method. As long as you
+follow the upgrade instructions and run 'script/generate rspec' you'll be fine, but if you skip this
+step you need to manually go into spec_helper.rb and remove the call to that method (if present - it
+might not be if you haven't upgraded in a while).
+
+Warning: Implementors of custom formatters. Formatters will now be sent an Example object instead of just a
+String for #example_started, #example_passed and #example_failed. In certain scenarios
+(Spec::Ui with Spec::Distributed), the formatter must ask the Example for its sequence number instead of
+keeping track of a sequence number internal to the formatter. Most of you shouldn't need to upgrade
+your formatters though - the Example#to_s method returns the example name/description, so you should be
+able to use the passed Example instance as if it were a String.
+
+* Applied [#12986] Autotest Specs + Refactoring (Patch from Scott Tayler)
+* Added a #close method to formatters, which allows them to gracefully close streams.
+* Applied [#12935] Remove requirement that mocha must be installed as a gem when used as mocking framework. (Patch from Ryan Kinderman).
+* Fixed [#12893] RSpec's Autotest should work with rspec's trunk
+* Fixed [#12865] Partial mock error when object has an @options instance var
+* Applied [#12701] Allow checking of content captured with content_for in view specs (Patch from Jens Kr�mer)
+* Applied [#12817] Cannot include same shared behaviour when required with absolute paths (Patch from Ian Leitch)
+* Applied [#12719] rspec_on_rails should not include pagination helper (Patch from Matthijs Langenberg)
+* Fixed [#12714] helper spec not finding rails core helpers
+* Applied [#12611] should_not redirect_to implementation (Patch from Yurii Rashkovskii)
+* Applied [#12682] Not correctly aliasing original 'stub!' and 'should_receive' methods for ApplicationController (Patch from Matthijs Langenberg)
+* Disabled controller.should_receive(:render) and controller.stub!(:render). Use expect_render or stub_render instead.
+* Applied [#12484] Allow a Behaviour's Description to flow through to the Formatter (Patch from Bob Cotton)
+* Fixed [#12448] The spec:plugins rake task from rspec_on_rails should ignore specs from the rspec_on_rails plugin
+* Applied [#12300] rr integration (patch from Kyle Hargraves)
+* Implemented [#12284] mock_with :rr (integration with RR mock framework: http://rubyforge.org/projects/pivotalrb/)
+* Applied [#12237] (tiny) added full path to mate in switch_command (Patch from Carl Porth)
+* Formatters will now be sent an Example object instead of just a String for certain methods
+* All Spec::Rake::SpecTask attributes can now be procs, which allows for lazy evaluation.
+* Changed the Spec::Ui interfaces slightly. See examples.
+* Applied [#12174] mishandling of paths with spaces in spec_mate switch_command (Patch from Carl Porth)
+* Implemented [#8315] File "Go to..." functionality
+* Applied [#11917] Cleaner Spec::Ui error for failed Selenium connection (Patch from Ian Dees)
+* Applied [#11888] rspec_on_rails spews out warnings when assert_select is used with an XML response (Patch from Ian Leitch)
+* Applied [#12010] Nicer failure message formatting (Patch from Wincent Colaiuta)
+* Applied [#12156] smooth open mate patch (Patch from Ienaga Eiji)
+* Applied [#10577] Rails with Oracle breaks 0.9.2. (Patch from Sinclair Bain)
+* Fixed [#12079] auto-generated example name incomplete: should have 1 error on ....]
+* Applied [#12066] Docfix for mocks/mocks.page (Patch from Kyle Hargraves)
+* Fixed [#11891] script/generate rspec_controller fails to create appropriate views (from templates) on edge rails
+* Applied [#11921] Adds the correct controller_name from derived_controller_name() to the ViewExampleGroupController (Patch from Eloy Duran)
+* Fixed [#11903] config.include with behaviour_type 'hash' does not work
+* Examples without blocks and pending is now reported with a P instead of a *
+* Pending blocks that now pass are rendered blue
+* New behaviour for after: If an after block raises an error, the other ones will still run instead of bailing at the first.
+* Made it possible to run spec from RSpec.tmbundle with --drb against a Rails spec_server.
+* Applied [#11868] Add ability for pending to optionally hold a failing block and to fail when it passes (Patch from Bob Cotton)
+* Fixed [#11843] watir_behaviour missing from spec_ui gem
+* Added 'switch between source and spec file' command in Spec::Mate (based on code from Ruy Asan)
+* Applied [#11509] Documentation - RSpec requires hpricot
+* Applied [#11807] Daemonize spec_server and rake tasks to manage them. (patch from Kyosuke MOROHASHI)
+* Added pending(message) method
+* Fixed [#11777] should render_template doesn't check paths correctly
+* Fixed [#11749] Use of 'rescue => e' does not catch all exceptions
+* Fixed [#11793] should raise_error('with a message') does not work correctly
+* Fixed [#11774] Mocks should respond to :kind_of? in the same way they respond to :is_a?
+* Fixed [#11508] Exceptions are not raised for Controller Specs (removed experimental raise_controller_errors)
+* Applied [#11615] Partial mock methods give ambiguous failures when given a method name as a String (Patch from Jay Phillips)
+* Fixed [#11545] Rspec doesn't handle should_receive on ActiveRecord associations (Patch from Ian White)
+* Fixed [#11514] configuration.use_transactional_fixtures is ALWAYS true, regardless of assignment
+* Improved generated RESTful controller examples to cover both successful and unsuccessful POST and PUT
+* Changed TextMate snippets for controllers to pass controller class names to #describe rather than controller_name.
+* Changed TextMate snippets for mocks to use no_args() and any_args() instead of the deprecated Symbols.
+* Applied [#11500] Documentation: no rails integration specs in 1.0
+* Renamed SpecMate's shortcuts for running all examples and focused examples to avoid conflicts (CMD-d and CMD-i)
+* Added a TextMate snippet for custom matchers, lifted from Geoffrey Grosenbach's RSpec peepcode show.
+* The translator translates mock constraints to the new matchers that were introduced in 1.0.4
+* Documented environment variables for Spec::Rake::SpecTask. Renamed SPECOPTS and RCOVOPTS to SPEC_OPTS and RCOV_OPTS.
+* Fixed [#10534] Windows: undefined method 'controller_name'
+
+== Version 1.0.5
+Bug fixes. Autotest plugin tweaks.
+
+* Fixed [#11378] fix to 10814 broke drb (re-opened #10814)
+* Fixed [#11223] Unable to access flash from rails helper specs
+* Fixed [#11337] autotest runs specs redundantly
+* Fixed [#11258] windows: autotest won't run
+* Applied [#11253] Tweaks to autotest file mappings (Patch from Wincent Colaiuta)
+* Applied [#11252] Should be able to re-load file containing shared behaviours without raising an exception (Patch from Wincent Colaiuta)
+* Fixed [#11247] standalone autotest doesn't work because of unneeded autotest.rb
+* Applied [#11221] Autotest support does not work w/o Rails Gem installed (Patch from Josh Knowles)
+
+== Version 1.0.4
+The getting ready for JRuby release.
+
+* Fixed [#11181] behaviour_type scoping of config.before(:each) is not working
+* added mock argument constraint matchers (anything(), boolean(), an_instance_of(Type)) which work with rspec or mocha
+* added mock argument constraint matchers (any_args(), no_args()) which only work with rspec
+* deprecated rspec's symbol mock argument constraint matchers (:any_args, :no_args, :anything, :boolean, :numeric, :string)
+* Added tarball of rspec_on_rails to the release build to support folks working behind a firewall that blocks svn access.
+* Fixed [#11137] rspec incorrectly handles flash after resetting the session
+* Fixed [#11143] Views code for ActionController::Base#render broke between 1.0.0 and 1.0.3 on Rails Edge r6731
+* Added raise_controller_errors for controller examples in Spec::Rails
+
+== Version 1.0.3
+Bug fixes.
+
+* Fixed [#11104] Website uses old specify notation
+* Applied [#11101] StringHelpers.starts_with?(prefix) assumes a string parameter for _prefix_
+* Removed 'rescue nil' which was hiding errors in controller examples.
+* Fixed [#11075] controller specs fail when using mocha without integrated_views
+* Fixed problem with redirect_to failing incorrectly against edge rails.
+* Fixed [#11082] RspecResourceGenerator should be RspecScaffoldGenerator
+* Fixed [#10959] Focused Examples do not work for Behaviour defined with constant with modules
+
+== Version 1.0.2
+This is just to align the version numbers in rspec and rspec_on_rails.
+
+== Version 1.0.1
+This is a maintenance release with mostly cleaning up, and one minor enhancement -
+Modules are automatically included when described directly.
+
+* Renamed Spec::Rails' rspec_resource generator to rspec_scaffold.
+* Removed Spec::Rails' be_feed matcher since it's based on assert_select_feed which is not part of Rails (despite that docs for assert_select_encoded says it is).
+* describe(SomeModule) will include that module in the examples. Like for Spec::Rails helpers, but now also in core.
+* Header in HTML report will be yellow instead of red if there is one failed example
+* Applied [#10951] Odd instance variable name in rspec_model template (patch from Kyle Hargraves)
+* Improved integration with autotest (Patches from Ryan Davis and David Goodland)
+* Some small fixes to make all specs run on JRuby.
+
+== Version 1.0.0
+The stake in the ground release. This represents a commitment to the API as it is. No significant
+backwards compatibility changes in the API are expected after this release.
+
+* Fixed [#10923] have_text matcher does not support should_not
+* Fixed [#10673] should > and should >= broken
+* Applied [#10921] Allow verify_rcov to accept greater than threshold coverage %'s via configuration
+* Applied [#10920] Added support for not implemented examples (Patch from Chad Humphries and Ken Barker)
+* Patch to allow not implemented examples. This works by not providing a block to the example. (Patch from Chad Humphries, Ken Barker)
+* Yanked support for Rails 1.1.6 in Spec::Rails
+* RSpec.tmbundle uses CMD-SHIFT-R to run focused examples now.
+* Spec::Rails now bundles a spec:rcov task by default (suggestion from Kurt Schrader)
+* Fixed [#10814] Runner loads shared code, test cases require them again
+* Fixed [#10753] Global before and after
+* Fixed [#10774] Allow before and after to be specified in config II
+* Refactored Spec::Ui examples to use new global before and after blocks.
+* Added instructions about how to get Selenium working with Spec::Ui (spec_ui/examples/selenium/README.txt)
+* Fixed [#10805] selenium.rb missing from gem?
+* Added rdocs explaining how to deal with errors in Rails' controller actions
+* Applied [#10770] Finer grained includes.
+* Fixed [#10747] Helper methods defined in shared specs are not visible when shared spec is used
+* Fixed [#10748] Shared descriptions in separate files causes 'already exists' error
+* Applied [#10698] Running with --drb executes specs twice (patch from Ruy Asan)
+* Fixed [#10871] 0.9.4 - Focussed spec runner fails to run specs in descriptions with type and string when there is no leading space in the string
+
+== Version 0.9.4
+This release introduces massive improvements to Spec::Ui - the user interface functional testing
+extension to RSpec. There are also some minor bug fixes to the RSpec core.
+
+* Massive improvements to Spec::Ui. Complete support for all Watir's ie.xxx(how, what) methods. Inline screenshots and HTML.
+* Reactivated --timeout, which had mysteriously been deactivated in a recent release.
+* Fixed [#10669] Kernel#describe override does not cover Kernel#context
+* Applied [#10636] Added spec for OptionParser in Runner (Patch from Scott Taylor)
+* Added [#10516] should_include should be able to accept multiple items
+* Applied [#10631] redirect_to matcher doesn't respect request.host (Patch from Tim Lucas)
+* Each formatter now flushes their own IO. This is to avoid buffering of output.
+* Fixed [#10670] IVarProxy#delete raises exception when instance variable does not exist
+
+== Version 0.9.3
+This is a bugfix release.
+
+* Fixed [#10594] Failing Custom Matcher show NAME NOT GENERATED description
+* describe(SomeType, "#message") will not add a space: "SomeType#message" (likewise for '.')
+* describe(SomeType, "message") will have a decription with a space: "SomeType message"
+* Applied [#10566] prepend_before and prepend_after callbacks
+* Applied [#10567] Call setup and teardown using before and after callbacks
+
+== Version 0.9.2
+This is a quick maintenance release.
+
+* Added some website love
+* Fixed [#10542] reverse predicate matcher syntax
+* Added a spec:translate Rake task to make 0.9 translation easier with Spec:Rails
+* Better translation of should_redirect_to
+* Fixed --colour support for Windows. This is a regression that was introduced in 0.9.1
+* Applied [#10460] Make SpecRunner easier to instantiate without using commandline args
+
+== Version 0.9.1
+
+This release introduces #describe and #it (aliased as #context and #specify for
+backwards compatibility). This allows you to express specs like this:
+
+ describe SomeClass do # Creates a Behaviour
+ it "should do something" do # Creates an Example
+ end
+ end
+
+The command line features four new options that give you more control over what specs
+are being run and in what order. This can be used to verify that your specs are
+independent (by running in opposite order with --reverse). It can also be used to cut
+down feedback time by running the most recently modified specs first (--loadby mtime --reverse).
+
+Further, --example replaces the old --spec option, and it can now take a file name of
+spec names as an alternative to just a spec name. The --format failing_examples:file.txt
+option allows you to output an --example compatible file, which makes it possible to only
+rerun the specs that failed in the last run. Spec::Rails uses all of these four options
+by default to optimise your RSpec experience.
+
+There is now a simple configuration model. For Spec::Rails, you do something like this:
+
+ Spec::Runner.configure do |config|
+ config.use_transactional_fixtures = true
+ config.use_instantiated_fixtures = false
+ config.fixture_path = RAILS_ROOT + '/spec/fixtures'
+ end
+
+You can now use mocha or flexmock with RSpec if you prefer either to
+RSpec's own mock framework. Just put this:
+
+ Spec::Runner.configure do |config|
+ config.mock_with :mocha
+ end
+
+or this:
+
+ Spec::Runner.configure do |config|
+ config.mock_with :flexmock
+ end
+
+in a file that is loaded before your specs. You can also
+configure included modules and predicate_matchers:
+
+ Spec::Runner.configure do |config|
+ config.include SomeModule
+ config.predicate_matchers[:does_something?] = :do_something
+ end
+
+See Spec::DSL::Behaviour for more on predicate_matchers
+
+* Sugar FREE!
+* Added [10434 ] Please Make -s synonymous with -e for autotest compat. This is temporary until autotest uses -e instead of -s.
+* Fixed [#10133] custom predicate matchers
+* Applied [#10473] Add should exist (new matcher) - Patch from Bret Pettichord
+* Added another formatter: failing_behaviours. Writes the names of the failing behaviours for use with --example.
+* Applied [#10315] Patch to fix pre_commit bug 10313 - pre_commit_rails: doesn't always build correctly (Patch from Antii Tarvainen)
+* Applied [#10245] Patch to HTML escape the behavior name when using HTML Formatter (Patch from Josh Knowles)
+* Applied [#10410] redirect_to does not behave consistently with regards to query string parameter ordering (Patch from Nicholas Evans)
+* Applied [#9605] Patch for ER 9472, shared behaviour (Patch by Bob Cotton)
+* The '--format rdoc' option no longer causes a dry-run by default. --dry-run must be used explicitly.
+* It's possible to specify the output file in the --format option (See explanation in --help)
+* Several --format options may be specified to output several formats in one run.
+* The --out option is gone. Use --format html:path/to/my.html instead (or similar).
+* Spec::Runner::Formatter::BaseTextFormatter#initialize only takes one argument - an IO. dry_run and color are setters.
+* Made Spec::Ui *much* easier to install. It will be released separately. Check out trunk/spec_ui/examples
+* HTML reports now include a syntax highlighted snippet of the source code where the spec failed (needs the syntax gem)
+* Added [#10262] Better Helper testing of Erb evaluation block helpers
+* Added [#9735] support flexmock (thanks to Jim Weirich for his modifications to flexmock to support this)
+* Spec::Rails controller specs will no longer let mock exception ripple through to the response.
+* Fixed [#9260] IvarProxy does not act like a hash.
+* Applied [#9458] The rspec_scaffold generator does not take into account class nesting (Patch from Steve Tendon)
+* Applied [#9132] Rakefile spec:doc can fail without preparing database (Patch from Steve Ross)
+* Applied [#9678] Custom runner command line switch, and multi-threaded runner (Patch from Bob Cotton)
+* Applied [#9926] Rakefile - RSPEC_DEPS constant as an Array of Hashes instead of an Array of Arrays (Patch from Scott Taylor)
+* Applied [#9925] Changed ".rhtml" to "template" in REST spec generator (Patch from Scott Taylor)
+* Applied [#9852] Patch for RSpec's Website using Webgen 0.4.2 (Patch from Scott Taylor)
+* Fixed [#6523] Run rspec on rails without a db
+* Fixed [#9295] rake spec should run anything in the spec directory (not just rspec's standard dirs)
+* Added [#9786] infer controller and helper names from the described type
+* Fixed [#7795] form_tag renders action='/view_spec' in view specs
+* Fixed [#9767] rspec_on_rails should not define rescue_action on controllers
+* Fixed [#9421] --line doesn't work with behaviours that use class names
+* Fixed [#9760] rspec generators incompatible with changes to edge rails
+* Added [#9786] infer controller and helper names from the described type
+* Applied a simplified version of [#9282] Change to allow running specs from textmate with rspec installed as a rails plugin (and no rspec gem installed)
+* Applied [#9700] Make Spec::DSL::Example#name public / Add a --timeout switch. A great way to prevent specs from getting slow.
+* In Rails, script/generate rspec will generate a spec.opts file that optimises faster/more efficient running of specs.
+* Added [#9522] support using rspec's expectations with test/unit
+* Moved rspec_on_rails up to the project root, simplifying the download url
+* Fixed [#8103] RSpec not installing spec script correctly.
+* The --spec option is replaced by the --example option.
+* The --loadby option no longer supports a file argument. Use --example file_name instead.
+* The --example option can now take a file name as an argument. The file should contain example names.
+* Internal classes are named Behaviour/Example (rather than Context/Specification).
+* You can now use mocha by saying config.mock_with :mocha in a spec_helper
+* before_context_eval is replaced by before_eval.
+* Applied [#9509] allow spaced options in spec.opts
+* Applied [#9510] Added File for Ruby 1.8.6
+* Applied [#9511] Clarification to README file in spec/
+* Moved all of the Spec::Rails specs down to the plugins directory - now you can run the specs after you install.
+* Updated RSpec.tmbundle to the 0.9 syntax and replaced context/specify with describe/it.
+* Applied [#9232] ActionController::Base#render is sometimes protected (patch from Dan Manges)
+* Added --reverse option, allowing contexts/specs to be run in reverse order.
+* Added --loadby option, allowing better control over load order for spec files. mtime and file.txt supported.
+* Implemented [#8696] --order option (see --reverse and --loadby)
+* Added describe/it as aliases for context/specify - suggestion from Dan North.
+* Applied [#7637] [PATCH] add skip-migration option to rspec_scaffold generator
+* Added [#9167] string.should have_tag
+* Changed script/rails_spec_server to script/spec_server and added script/spec (w/ path to vendor/plugins/rspec)
+* Fixed [#8897] Error when mixing controller spec with/without integrated views and using template system other than rhtml
+* Updated sample app specs to 0.9 syntax
+* Updated generated specs to 0.9 syntax
+* Applied [#8994] trunk: generated names for be_ specs (Multiple patches from Yurii Rashkovskii)
+* Applied [#9983]: Allow before and after to be called in BehaviourEval. This is useful for shared examples.
+
+== Version 0.8.2
+
+Replaced assert_select fork with an assert_select wrapper for have_tag. This means that "should have_rjs" no longer supports :hide or :effect, but you can still use should_have_rjs for those.
+
+== Version 0.8.1
+
+Quick "in house" bug-fix
+
+== Version 0.8.0
+
+This release introduces a new approach to handling expectations using Expression Matchers.
+
+See Upgrade[http://rspec.rubyforge.org/upgrade.html], Spec::Expectations, Spec::Matchers and RELEASE-PLAN for more info.
+
+This release also improves the spec command line by adding DRb support and making it possible to
+store command line options in a file. This means a more flexible RSpec experience with Rails,
+Rake and editor plugins like TextMate.
+
+It also sports myriad new features, bug fixes, patches and general goodness:
+
+* Fixed [#8928] rspec_on_rails 0.8.0-RC1 controller tests make double call to setup_with_fixtures
+* Fixed [#8925] Documentation bug in 0.8.0RC1 rspec website
+* Applied [#8132] [PATCH] RSpec breaks "rake db:sessions:create" in a rails project that has the rspec_on_rails plugin (Patch from Erik Kastner)
+* Fixed [#8789] --line and --spec not working when the context has parenhesis in the name
+* Added [#8783] auto generate spec names from last expectation
+* --heckle now fails if the heckled class or module is not found.
+* Fixed [#8771] Spec::Mocks::BaseExpectation#with converts hash params to array of arrays with #collect
+* Fixed [#8750] should[_not]_include backwards compatibility between 0.8.0-RC1 and 0.7.5.1 broken
+* Fixed [#8646] Context Runner does not report on Non standard exceptions and return a 0 return code
+* RSpec on Rails' spec_helper.rb will only force RAILS_ENV to test if it was not specified on the command line.
+* Fixed [#5485] proc#should_raise and proc#should_not_raise output
+* Added [#8484] should_receive with blocks
+* Applied [#8218] heckle_runner.rb doesn't work with heckle >= 1.2.0 (Patch from Michal Kwiatkowski)
+* Fixed [#8240] Cryptic error message when no controller_name
+* Applied [#7461] [PATCH] Contexts don't call Module::included when they include a module
+* Removed unintended block of test/unit assertions in rspec_on_rails - they should all, in theory, now be accessible
+* Added mock_model method to RSpec on Rails, which stubs common methods. Based on http://metaclass.org/2006/12/22/making-a-mockery-of-activerecord
+* Fixed [#8165] Partial Mock Errors when respond_to? is true but the method is not in the object
+* Fixed [#7611] Partial Mocks override Subclass methods
+* Fixed [#8302] Strange side effect when mocking a class method
+* Applied [#8316] to_param should return a stringified key in resource generator's controller spec (Patch from Chris Anderson)
+* Applied [#8216] shortcut for creating object stub
+* Applied [#8008] Correct generated specs for view when calling resource generator (Patch from Jonathan Tron)
+* Fixed [#7754] Command-R fails to run spec in TextMate (added instruction from Luke Redpath to the website)
+* Fixed [#7826] RSpect.tmbundle web page out of date.
+* RSpec on Rails specs are now running against RoR 1.2.1 and 1.2.2
+* rspec_scaffold now generates specs for views
+* In a Rails app, RSpec core is only loaded when RAILS_ENV==test (init.rb)
+* Added support for target.should arbitrary_expectation_handler and target.should_not arbitrary_expectation_handler
+* Fixed [#7533] Spec suite fails and the process exits with a code 0
+* Fixed [#7565] Subsequent stub! calls for method fail to override the first call to method
+* Applied [#7524] Incorrect Documentation for 'pattern' in Rake task (patch from Stephen Duncan)
+* Fixed [#7409] default fixtures do not appear to run.
+* Fixed [#7507] "render..and return" doesn't return
+* Fixed [#7509] rcov/rspec incorrectly includes boot.rb (Patch from Courtenay)
+* Fixed [#7506] unnecessary complex output on failure of response.should be_redirect
+* Applied [#6098] Make scaffold_resource generator. Based on code from Pat Maddox.
+* The drbspec command is gone. Use spec --drb instead.
+* The drb option is gone from the Rake task. Pass --drb to spec_opts instead.
+* New -X/--drb option for running specs against a server like spec/rails' script/rails_spec_server
+* New -O/--options and -G/--generate flags for file-based options (handy for spec/rails)
+* Applied [#7339] Turn off caching in HTML reports
+* Applied [#7419] "c option for colorizing output does not work with rails_spec" (Patch from Shintaro Kakutani)
+* Applied [#7406] [PATCH] 0.7.5 rspec_on_rails loads fixtures into development database (Patch from Wilson Bilkovich)
+* Applied [#7387] Allow stubs to return consecutive values (Patch from Pat Maddox)
+* Applied [#7393] Fix for rake task (Patch from Pat Maddox)
+* Reinstated support for response.should_render (in addition to controller.should_render)
+
+== Version 0.7.5.1
+
+Bug fix release to allow downloads of rspec gem using rubygems 0.9.1.
+
+== Version 0.7.5
+This release adds support for Heckle - Seattle'rb's code mutation tool.
+There are also several bug fixes to the RSpec core and the RSpec on Rails plugin.
+
+* Removed svn:externals on rails versions and plugins
+* Applied [#7345] Adding context_setup and context_teardown, with specs and 100% rcov
+* Applied [#7320] [PATCH] Allow XHR requests in controller specs to render RJS templates
+* Applied [#7319] Migration code uses drop_column when it should use remove_column (patch from Pat Maddox)
+* Added support for Heckle
+* Applied [#7282] dump results even if spec is interrupted (patch from Kouhei Sutou)
+* Applied [#7277] model.should_have(n).errors_on(:attribute) (patch from Wilson Bilkovich)
+* Applied [#7270] RSpec render_partial colliding with simply_helpful (patch from David Goodlad)
+* Added [#7250] stubs should support throwing
+* Added [#7249] stubs should support yielding
+* Fixed [#6760] fatal error when accessing nested finders in rspec
+* Fixed [#7179] script/generate rspec_scaffold generates incorrect helper name
+* Added preliminary support for assert_select (response.should_have)
+* Fixed [#6971] and_yield does not work when the arity is -1
+* Fixed [#6898] Can we separate rspec from the plugins?
+* Added [#7025] should_change should accept a block
+* Applied [#6989] partials with locals (patch from Micah Martin)
+* Applied [#7023] Typo in team.page
+
+== Version 0.7.4
+
+This release features a complete redesign of the reports generated with --format html.
+As usual there are many bug fixes - mostly related to spec/rails.
+
+* Applied [#7010] Fixes :spacer_template does not work w/ view spec (patch from Shintaro Kakutani)
+* Applied [#6798] ensure two ':' in the first backtrace line for Emacs's 'next-error' command (patch from Kouhei Sutou)
+* Added Much nicer reports to generated website
+* Much nicer reports with --format --html (patch from Luke Redpath)
+* Applied [#6959] Calls to render and redirect in controllers should return true
+* Fixed [#6981] helper method is not available in partial template.
+* Added [#6978] mock should tell you the expected and actual args when receiving the right message with the wrong args
+* Added the possibility to tweak the output of the HtmlFormatter (by overriding extra_failure_content).
+* Fixed [#6936] View specs don't include ApplicationHelper by default
+* Fixed [#6903] Rendering a partial in a view makes the view spec blow up
+* Added callback library from Brian Takita
+* Added [#6925] support controller.should_render :action_name
+* Fixed [#6884] intermittent errors related to method binding
+* Fixed [#6870] rspec on edge rails spec:controller fixture loading fails
+* Using obj.inspect for all messages
+* Improved performance by getting rid of instance_exec (instance_eval is good enough because we never need to pass it args)
+
+== Version 0.7.3
+
+Almost normal bug fix/new feature release.
+
+A couple of things you need to change in your rails specs:
+# spec_helper.rb is a little different (see http://rspec.rubyforge.org/upgrade.html)
+# use controller.should_render before OR after the action (controller.should_have_rendered is deprecated)
+
+* Applied [#6577] messy mock backtrace when frozen to edge rails (patch from Jay Levitt)
+* Fixed [#6674] rspec_on_rails fails on @session deprecation warning
+* Fixed [#6780] routing() was failing...fix included - works for 1.1.6 and edge (1.2)
+* Fixed [#6835] bad message with arbitrary predicate
+* Added [#6731] Partial templates rendered
+* Fixed [#6713] helper methods not rendered in view tests?
+* Fixed [#6707] cannot run controller / helper tests via rails_spec or spec only works with rake
+* Applied [#6417] lambda {...}.should_change(receiver, :message) (patch from Wilson Bilkovich)
+* Eliminated dependency on ZenTest
+* Fixed [#6650] Reserved characters in the TextMate bundle break svn on Win32
+* Fixed [#6643] script/generate rspec_controller: invalid symbol generation for 'controller_name' for *modularized* controllers
+* The script/rails_spec command has been moved to bin/drbspec in RSpec core (installed by the gem)
+
+== Version 0.7.2
+
+This release introduces a brand new RSpec bundle for TextMate, plus some small bugfixes.
+
+* Packaged RSpec.tmbundle.tgz as part of the distro
+* Fixed [#6593] Add moving progress bar to HtmlFormatter using Javascript
+* Applied [#6265] should_raise should accept an Exception object
+* Fixed [#6616] Can't run Rails specs with RSpec.tmbundle
+* Fixed [#6411] Can't run Rails specs with ruby
+* Added [#6589] New -l --line option. This is useful for IDE/editor runners/extensions.
+* Fixed [#6615] controller.should_render_rjs should support :partial => 'path/to/template'
+
+== Version 0.7.1
+
+Bug fixes and a couple o' new features.
+
+* Fixed [#6575] Parse error in aliasing the partial mock original method (patch by Brian Takita)
+* Fixed [#6277] debris left by stubbing (trunk) [submitted by dastels] (fixed by fix to [#6575])
+* Fixed [#6575] Parse error in aliasing the partial mock original method
+* Fixed [#6555] should_have_tag does not match documentation
+* Fixed [#6567] SyntaxError should not stop entire run
+* Fixed [#6558] integrated views look for template even when redirected
+* Fixed [#6547] response.should be_redirect broken in 0.7.0
+* Applied [#6471] Easy way to spec routes
+* Applied [#6587] Rspec on Rails displays "Spec::Rails::ContextFactory" as context name
+* Applied [#6514] Document has trivial typos.
+* Added [#6560] controller.session should be available before the action
+* Added support for should_have_rjs :visual_effect
+* Different printing and colours for unmet expectations (red) and other exceptions (magenta)
+* Simplified method_missing on mock_methods to make it less invasive on partial mocks.
+
+== Version 0.7.0
+
+This is the "Grow up and eat your own dog food release". RSpec is now used on itself and
+we're no longer using Test::Unit to test it. Although, we are still extending Test::Unit
+for the rails plugin (indirectly - through ZenTest)
+
+IMPORTANT NOTE: THIS RELEASE IS NOT 100% BACKWARDS COMPATIBLE TO 0.6.x
+
+There are a few changes that will require that you change your existing specs.
+
+RSpec now handles equality exactly like ruby does:
+
+# actual.should_equal(expected) will pass if actual.equal?(expected) returns true
+# actual.should eql(expected) will pass if actual.eql?(expected) returns true
+# actual.should == expected will pass if actual == expected) returns true
+
+At the high level, eql? implies equivalence, while equal? implies object identity. For more
+information on how ruby deals w/ equality, you should do this:
+
+ri equal?
+
+or look at this:
+
+http://www.ruby-doc.org/core/classes/Object.html#M001057
+
+Also, we left in should_be as a synonym for should_equal, so the only specs that should break are the
+ones using should_equal (which used to use <code>==</code> instead of <code>.equal?</code>).
+
+Lastly, should_be used to handle true and false differently from any other values. We've removed
+this special handling, so now actual.should_be true will fail for any value other than true (it
+used to pass for any non-nil, non-false value), and actual.should_be false will fail for any
+value other than false (it used to pass for nil or false).
+
+Here's what you'll need to do to update your specs:
+# search for "should_equal" and replace with "should_eql"
+# run specs
+
+If any specs still fail, they are probably related to should be_true or should_be_false using
+non-boolean values. Those you'll just have to inspect manually and adjust appropriately (sorry!).
+
+--------------------------------------------------
+Specifying multiple return values in mocks now works like this:
+
+mock.should_receive(:message).and_return(1,2,3)
+
+It used to work like this:
+
+mock.should_receive(:message).and_return([1,2,3])
+
+but we decided that was counter intuitive and otherwise lame.
+
+Here's what you'll need to do to update your specs:
+# search for "and_return(["
+# get rid of the "[" and "]"
+
+--------------------------------------------------
+RSpec on Rails now supports the following (thanks to ZenTest upon which it is built):
+
+# Separate specs for models, views, controllers and helpers
+# Controller specs are completely decoupled from the views by default (though you can tell them to couple themselves if you prefer)
+# View specs are completely decoupled from app-specific controllers
+
+See http://rspec.rubyforge.org/documentation/rails/index.html for more information
+--------------------------------------------------
+As usual, there are also other new features and bug fixes:
+
+* Added lots of documentation on mocks/stubs and the rails plugin.
+* Added support for assigns[key] syntax for controller specs (to align w/ pre-existing syntax for view specs)
+* Added support for controller.should_redirect_to
+* RSpec on Rails automatically checks whether it's compatible with the installed RSpec
+* Applied [#6393] rspec_on_rails uses deprecated '@response' instead of the accessor
+* RSpec now has 100% spec coverage(!)
+* Added support for stubbing and partial mocking
+* Progress (....F..F.) is now coloured. Tweaked patch from KAKUTANI Shintaro.
+* Backtrace now excludes the rcov runner (/usr/local/bin/rcov)
+* Fixed [#5539] predicates do not work w/ rails
+* Added [#6091] support for Regexp matching messages sent to should_raise
+* Added [#6333] support for Regexp matching in mock arguments
+* Applied [#6283] refactoring of diff support to allow selectable formats and custom differs
+* Fixed [#5564] "ruby spec_file.rb" doesn't work the same way as "spec spec_file.rb"
+* Fixed [#6056] Multiple output of failing-spec notice
+* Fixed [#6233] Colours in specdoc
+* Applied [#6207] Allows --diff option to diff target and expected's #inspect output (Patch by Lachie Cox)
+* Fixed [#6203] Failure messages are misleading - consider using inspect.
+* Added [#6334] subject.should_have_xyz will try to call subject.has_xyz? - use this for hash.should_have_key(key)
+* Fixed [#6017] Rake task should ignore empty or non-existent spec-dirs
+
+== Version 0.6.4
+
+In addition to a number of bug fixes and patches, this release begins to formalize the support for
+RSpec on Rails.
+
+* Added Christopher Petrilli's TextMate bundle to vendor/textmate/RSpec.tmbundle
+* Fixed [#5909], once again supporting multi_word_predicates
+* Applied [#5873] - response.should_have_rjs (initial patch from Jake Howerton, based on ARTS by Kevin Clark)
+* Added generation of view specs for rspec_on_rails
+* Applied [#5815] active_record_subclass.should_have(3).records
+* Added support in "rake stats" for view specs (in spec/views)
+* Applied [#5801] QuickRef.pdf should say RSpec, not rSpec
+* Applied [#5728] rails_spec_runner fails on Windows (Patch from Lindsay Evans).
+* Applied [#5708] RSpec Rails plugin rspec_controller generator makes specs that do not parse.
+* Cleaned up RSpec on Rails so it doesn't pollute as much during bootstrapping.
+* Added support for response.should_have_tag and response.should_not_have_tag (works just like assert_tag in rails)
+* Added new -c, --colour, --color option for colourful (red/green) output. Inspired from Pat Eyler's Redgreen gem.
+* Added examples for Watir and Selenium under the gem's vendor directory.
+* Renamed rails_spec_runner to rails_spec_server (as referred to in the docs)
+* Added support for trying a plural for arbitrary predicates. E.g. Album.should_exist(:name => "Hey Jude") will call Album.exists?(:name => "Hey Jude")
+* Added support for should_have to work with methods taking args returning a collection. E.g. @dave.should_have(3).albums_i_have_that_this_guy_doesnt(@aslak)
+* Added [#5570] should_not_receive(:msg).with(:specific, "args")
+* Applied [#5065] to support using define_method rather than method_missing to capture expected messages on mocks. Thanks to Eero Saynatkari for the tip that made it work.
+* Restructured directories and Modules in order to separate rspec into three distinct Modules: Spec::Expectations, Spec::Runner and Spec::Mocks. This will allow us to more easily integrate other mock frameworks and/or allow test/unit users to take advantage of the expectation API.
+* Applied [#5620] support any boolean method and arbitrary comparisons (5.should_be < 6) (Patch from Mike Williams)
+
+== Version 0.6.3
+
+This release fixes some minor bugs related to RSpec on Rails
+Note that if you upgrade a rails app with this version of the rspec_on_rails plugin
+you should remove your lib/tasks/rspec.rake if it exists.
+
+* Backtraces from drb (and other standard ruby libraries) are now stripped from backtraces.
+* Applied [#5557] Put rspec.rake into the task directory of the RSpec on Rails plugin (Patch from Daniel Siemssen)
+* Applied [#5556] rails_spec_server loads environment.rb twice (Patch from Daniel Siemssen)
+
+== Version 0.6.2
+This release fixes a couple of regressions with the rake task that were introduced in the previous version (0.6.1)
+
+* Fixed [#5518] ruby -w: warnings in 0.6.1
+* Applied [#5525] fix rake task path to spec tool for gem-installed rspec (patch from Riley Lynch)
+* Fixed a teensey regression with the rake task - introduced in 0.6.1. The spec command is now quoted so it works on windows.
+
+== Version 0.6.1
+This is the "fix the most annoying bugs release" of RSpec. There are 9 bugfixes this time.
+Things that may break backwards compatibility:
+1) Spec::Rake::SpecTask no longer has the options attribute. Use ruby_opts, spec_opts and rcov_opts instead.
+
+* Fixed [#4891] RCOV task failing on windows
+* Fixed [#4896] Shouldn't modify user's $LOAD_PATH (Tip from Gavin Sinclair)
+* Fixed [#5369] ruby -w: warnings in RSpec 0.5.16 (Tip from Suraj Kurapati)
+* Applied [#5141] ExampleMatcher doesn't escape strings before matching (Patch from Nikolai Weibull).
+* Fixed [#5224] Move 'require diff-lcs' from test_helper.rb to diff_test.rb (Tip from Chris Roos)
+* Applied [#5449] Rake stats for specs (Patch from Nick Sieger)
+* Applied [#5468, #5058] Fix spec runner to correctly run controller specs (Patch from Daniel Siemssen)
+* Applied fixes to rails_spec_server to improve its ability to run several times. (Patch from Daniel Siemssen)
+* Changed RCov::VerifyTask to fail if the coverage is above the threshold. This is to ensure it gets bumped when coverage improves.
+
+== Version 0.6.0
+This release makes an official commitment to underscore_syntax (with no more support for dot.syntax)
+
+* Fixed bug (5292) that caused mock argument matching to fail
+* Converted ALL tests to use underscore syntax
+* Fixed all remaining problems with underscores revealed by converting all the tests to underscores
+* Enhanced sugar to support combinations of methods (i.e. once.and_return)
+* Simplified helper structure taking advantage of dot/underscore combos (i.e. should.be.an_instance_of, which can be expressed as should be_an_instance_of)
+* Added support for at_most in mocks
+* Added support for should_not_receive(:msg) (will be removing should_receive(:msg).never some time soon)
+* Added support for should_have_exactly(5).items_in_collection
+
+== Version 0.5.16
+This release improves Rails support and test2spec translation.
+
+* Fixed underscore problems that occurred when RSpec was used in Rails
+* Simplified the Rails support by packaging it as a plugin instead of a generator gem.
+* Fixed [#5063] 'rspec_on_rails' require line in spec_helper.rb
+* Added pre_commit rake task to reduce risk of regressions. Useful for RSpec developers and patchers.
+* Added failure_message to RSpec Rake task
+* test2spec now defines converted helper methods outside of the setup block (bug #5057).
+
+== Version 0.5.15
+This release removes a prematurely added feature that shouldn't have been added.
+
+* Removed support for differences that was added in 0.5.14. The functionality is not aligned with RSpec's vision.
+
+== Version 0.5.14
+This release introduces better ways to extend specs, improves some of the core API and
+a experimental support for faster rails specs.
+
+* Added proc methods for specifying differences (increments and decrements). See difference_test.rb
+* Methods can now be defined alongside specs. This obsoletes the need for defining methods in setup. (Patch #5002 from Brian Takita)
+* Sugar (underscores) now works correctly with should be_a_kind_of and should be_an_instance_of
+* Added support for include and inherit in contexts. (Patch #4971 from Brian Takita)
+* Added rails_spec and rails_spec_server for faster specs on rails (still buggy - help needed)
+* Fixed bug that caused should_render to break if given a :symbol (in Rails)
+* Added support for comparing exception message in should_raise and should_not_raise
+
+== Version 0.5.13
+This release fixes some subtle bugs in the mock API.
+
+* Use fully-qualified class name of Exceptions in failure message. Easier to debug that way.
+* Fixed a bug that caused mocks to yield a one-element array (rather than the element) when one yield arg specified.
+* Mocks not raise AmbiguousReturnError if an explicit return is used at the same time as an expectation block.
+* Blocks passed to yielding mocks can now raise without causing mock verification to fail.
+
+== Version 0.5.12
+This release adds diff support for failure messages, a HTML formatter plus some other
+minor enhancements.
+
+* Added HTML formatter.
+* Added fail_on_error option to spectask.
+* Added support for diffing, using the diff-lcs Rubygem (#2648).
+* Remove RSpec on Rails files from backtrace (#4694).
+* All of RSpec's own tests run successfully after translation with test2spec.
+* Added --verbose mode for test2spec - useful for debugging when classes fail to translate.
+* Output of various formatters is now flushed - to get more continuous output.
+
+== Version 0.5.11
+This release makes test2spec usable with Rails (with some manual steps).
+See http://rspec.rubyforge.org/tools/rails.html for more details
+
+* test2spec now correctly translates bodies of helper methods (non- test_*, setup and teardown ones).
+* Added more documentation about how to get test2spec to work with Rails.
+
+== Version 0.5.10
+This version features a second rewrite of test2spec - hopefully better than the previous one.
+
+* Improved test2spec's internals. It now transforms the syntax tree before writing out the code.
+
+== Version 0.5.9
+This release improves test2spec by allowing more control over the output
+
+* Added --template option to test2spec, which allows for custom output driven by ERB
+* Added --quiet option to test2spec
+* Removed unnecessary dependency on RubyToC
+
+== Version 0.5.8
+This release features a new Test::Unit to RSpec translation tool.
+Also note that the RubyGem of the previous release (0.5.7) was corrupt.
+We're close to being able to translate all of RSpec's own Test::Unit
+tests and have them run successfully!
+
+* Updated test2spec documentation.
+* Replaced old test2rspec with a new test2spec, which is based on ParseTree and RubyInline.
+
+== Version 0.5.7
+This release changes examples and documentation to recommend underscores rather than dots,
+and addresses some bugfixes and changes to the spec commandline.
+
+* spec DIR now works correctly, recursing down and slurping all *.rb files
+* All documentation and examples are now using '_' instead of '.'
+* Custom external formatters can now be specified via --require and --format.
+
+== Version 0.5.6
+This release fixes a bug in the Rails controller generator
+
+* The controller generator did not write correct source code (missing 'do'). Fixed.
+
+== Version 0.5.5
+This release adds initial support for Ruby on Rails in the rspec_generator gem.
+
+* [Rails] Reorganised Lachie's original code to be a generator packaged as a gem rather than a plugin.
+* [Rails] Imported code from http://lachie.info/svn/projects/rails_plugins/rspec_on_rails (Written by Lachie Cox)
+* Remove stack trace lines from TextMate's Ruby bundle
+* Better error message from spectask when no spec files are found.
+
+== Version 0.5.4
+The "the tutorial is ahead of the gem" release
+
+* Support for running a single spec with --spec
+* Exitcode is now 1 unless all specs pass, in which case it's 0.
+* -v, --version now both mean the same thing
+* For what was verbose output (-v), use --format specdoc or -f s
+* --format rdoc always runs in dry-run mode
+* Removed --doc and added --format and --dry-run
+* Refactored towards more pluggable formatters
+* Use webgen's execute tag when generating website (more accurate)
+* Fixed incorrect quoting of spec_opts in SpecTask
+* Added patch to enable underscored shoulds like 1.should_equal(1) - patch from Rich Kilmer
+* Removed most inherited instance method from Mock, making more methods mockable.
+* Made the RCovVerify task part of the standard toolset.
+* Documented Rake task and how to use it with Rcov
+* Implemented <ruby></ruby> tags for website (hooking into ERB, RedCloth and syntax)
+* RSpec Rake task now takes spec_opts and out params so it can be used for doc generation
+* RCov integration for RSpec Rake task (#4058)
+* Group all results instead of printing them several times (#4057)
+* Mocks can now yield
+* Various improvements to error reporting (including #4191)
+* backtrace excludes rspec code - use -b to include it
+* split examples into examples (passing) and failing_examples
+
+== Version 0.5.3
+The "hurry up, CoR is in two days" release.
+
+* Don't run rcov by default
+* Make separate task for running tests with RCov
+* Added Rake task to fail build if coverage drops below a certain threshold
+* Even more failure output cleanup (simplification)
+* Added duck_type constraint for mocks
+
+== Version 0.5.2
+This release has minor improvements to the commandline and fixes some gem warnings
+
+* Readded README to avoid RDoc warnings
+* Added --version switch to commandline
+* More changes to the mock API
+
+== Version 0.5.1
+This release is the first release of RSpec with a new website. It will look better soon.
+
+* Added initial documentation for API
+* Added website based on webgen
+* Modified test task to use rcov
+* Deleted unused code (thanks, rcov!)
+* Various changes to the mock API,
+* Various improvements to failure reporting
+
+== Version 0.5.0
+This release introduces a new API and obsolesces previous versions.
+
+* Moved source code to separate subfolders
+* Added new DSL runner based on instance_exec
+* Added spike for testdox/rdoc generation
+* merge Astels' and Chelimsky's work on ShouldHelper
+* this would be 0.5.0 if I updated the documentation
+* it breaks all of your existing specifications. We're not sorry.
+
+== Version 0.3.2
+
+The "srbaker is an idiot" release.
+
+* also forgot to update the path to the actual Subversion repository
+* this should be it
+
+== Version 0.3.1
+
+This is just 0.3.0, but with the TUTORIAL added to the documentation list.
+
+* forgot to include TUTORIAL in the documentation
+
+== Version 0.3.0
+
+It's been a while since last release, lots of new stuff is available. For instance:
+
+* improvements to the runners
+* addition of should_raise expectation (thanks to Brian Takita)
+* some documentation improvements
+* RSpec usable as a DSL
+
+== Version 0.2.0
+
+This release provides a tutorial for new users wishing to get started with
+RSpec, and many improvements.
+
+* improved reporting in the spec runner output
+* update the examples to the new mock api
+* added TUTORIAL, a getting started document for new users of RSpec
+
+== Version 0.1.7
+
+This release improves installation and documentation, mock integration and error reporting.
+
+* Comparison errors now print the class name too.
+* Mocks now take an optional +options+ parameter to specify behaviour.
+* Removed __expects in favour of should_receive
+* Added line number reporting in mock error messages for unreceived message expectations.
+* Added should_match and should_not_match.
+* Added a +mock+ method to Spec::Context which will create mocks that autoverify (no need to call __verify).
+* Mocks now require names in the constructor to ensure sensible error messages.
+* Made 'spec' executable and updated usage instructions in README accordingly.
+* Made more parts of the Spec::Context API private to avoid accidental usage.
+* Added more RDoc to Spec::Context.
+
+== Version 0.1.6
+
+More should methods.
+
+* Added should_match and should_not_match.
+
+== Version 0.1.5
+
+Included examples and tests in gem.
+
+== Version 0.1.4
+
+More tests on block based Mock expectations.
+
+== Version 0.1.3
+
+Improved mocking:
+
+* block based Mock expectations.
+
+== Version 0.1.2
+
+This release adds some improvements to the mock API and minor syntax improvements
+
+* Added Mock.should_expect for a more consistent DSL.
+* Added MockExpectation.and_returns for a better DSL.
+* Made Mock behave as a null object after a call to Mock.ignore_missing
+* Internal syntax improvements.
+* Improved exception trace by adding exception class name to error message.
+* Renamed some tests for better consistency.
+
+== Version 0.1.1
+
+This release adds some shoulds and improves error reporting
+
+* Added should be_same_as and should_not be_same_as.
+* Improved error reporting for comparison expectations.
+
+== Version 0.1.0
+
+This is the first preview release of RSpec, a Behaviour-Driven Development library for Ruby
+
+* Added Rake script with tasks for gems, rdoc etc.
+* Added an XForge task to make release go easier.
diff --git a/vendor/gems/rspec/MIT-LICENSE b/vendor/gems/rspec/MIT-LICENSE
new file mode 100644
index 000000000..1d11ea59e
--- /dev/null
+++ b/vendor/gems/rspec/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2005-2007 The RSpec Development Team
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/gems/rspec/README b/vendor/gems/rspec/README
new file mode 100644
index 000000000..0683b0deb
--- /dev/null
+++ b/vendor/gems/rspec/README
@@ -0,0 +1,71 @@
+== RSpec
+
+RSpec is a Behaviour Driven Development framework with tools to express User Stories
+with Executable Scenarios and Executable Examples at the code level.
+
+RSpec ships with several modules:
+
+Spec::Story provides a framework for expressing User Stories
+
+Spec::Example provides a framework for expressing code Examples
+
+Spec::Matchers provides Expression Matchers for use with Spec::Expectations
+and Spec::Mocks.
+
+Spec::Expectations supports setting expectations on your objects so you
+can do things like:
+
+ result.should equal(expected_result)
+
+Spec::Mocks supports creating Mock Objects, Stubs, and adding Mock/Stub
+behaviour to your existing objects.
+
+== Installation
+
+The simplest approach is to install the gem:
+
+ gem install -r rspec #mac users must sudo
+
+== Building the RSpec gem
+If you prefer to build the gem locally, check out source from svn://rubyforge.org/var/svn/rspec/trunk. Then
+do the following:
+
+ rake gem
+ gem install pkg/rspec-0.x.x.gem (you may have to sudo)
+
+== Running RSpec's specs
+In order to run RSpec's full suite of specs (rake pre_commit) you must install the following gems:
+
+* rake # Runs the build script
+* rcov # Verifies that the code is 100% covered by specs
+* webby # Generates the static HTML website
+* syntax # Required to highlight ruby code
+* diff-lcs # Required if you use the --diff switch
+* win32console # Required by the --colour switch if you're on Windows
+* meta_project # Required in order to make releases at RubyForge
+* heckle # Required if you use the --heckle switch
+* hpricot # Used for parsing HTML from the HTML output formatter in RSpec's own specs
+
+Once those are all installed, you should be able to run the suite with the following steps:
+
+* svn co svn://rubyforge.org/var/svn/rspec/trunk rspec
+* cd rspec
+* rake install_dependencies
+* cd example_rails_app
+* export RSPEC_RAILS_VERSION=1.2.3
+* rake rspec:generate_mysql_config
+* mysql -u root < db/mysql_setup.sql
+* cd ..
+* rake pre_commit
+
+Note that RSpec itself - once built - doesn't have any dependencies outside the Ruby core
+and stdlib - with a few exceptions:
+
+* The spec command line uses diff-lcs when --diff is specified.
+* The spec command line uses heckle when --heckle is specified.
+* The Spec::Rake::SpecTask needs RCov if RCov is enabled in the task.
+
+See http://rspec.rubyforge.org for further documentation.
+
+== Contributing
+
diff --git a/vendor/gems/rspec/Rakefile b/vendor/gems/rspec/Rakefile
new file mode 100644
index 000000000..c60d5d466
--- /dev/null
+++ b/vendor/gems/rspec/Rakefile
@@ -0,0 +1,279 @@
+$:.unshift('lib')
+require 'rubygems'
+require 'rake/gempackagetask'
+require 'rake/contrib/rubyforgepublisher'
+require 'rake/clean'
+require 'rake/rdoctask'
+require 'rake/testtask'
+require 'spec/version'
+dir = File.dirname(__FILE__)
+$LOAD_PATH.unshift(File.expand_path("#{dir}/pre_commit/lib"))
+require "pre_commit"
+
+# Some of the tasks are in separate files since they are also part of the website documentation
+load File.dirname(__FILE__) + '/rake_tasks/examples.rake'
+load File.dirname(__FILE__) + '/rake_tasks/examples_with_rcov.rake'
+load File.dirname(__FILE__) + '/rake_tasks/failing_examples_with_html.rake'
+load File.dirname(__FILE__) + '/rake_tasks/verify_rcov.rake'
+
+PKG_NAME = "rspec"
+PKG_VERSION = Spec::VERSION::STRING
+PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
+PKG_FILES = FileList[
+ '[A-Z]*',
+ 'lib/**/*.rb',
+ 'spec/**/*',
+ 'examples/**/*',
+ 'failing_examples/**/*',
+ 'plugins/**/*',
+ 'stories/**/*',
+ 'pre_commit/**/*',
+ 'rake_tasks/**/*'
+]
+
+task :default => [:verify_rcov]
+task :verify_rcov => [:spec, :stories]
+
+desc "Run all specs"
+Spec::Rake::SpecTask.new do |t|
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ t.spec_opts = ['--options', 'spec/spec.opts']
+ unless ENV['NO_RCOV']
+ t.rcov = true
+ t.rcov_dir = '../doc/output/coverage'
+ t.rcov_opts = ['--exclude', 'spec\/spec,bin\/spec,examples,\/var\/lib\/gems,\/Library\/Ruby,\.autotest']
+ end
+end
+
+desc "Run all stories"
+task :stories do
+ html = 'story_server/prototype/rspec_stories.html'
+ ruby "stories/all.rb --colour --format plain --format html:#{html}"
+ unless IO.read(html) =~ /<span class="param">/m
+ raise 'highlighted parameters are broken in story HTML'
+ end
+end
+
+desc "Run all specs and store html output in doc/output/report.html"
+Spec::Rake::SpecTask.new('spec_html') do |t|
+ t.spec_files = FileList['spec/**/*_spec.rb', '../../RSpec.tmbundle/Support/spec/*_spec.rb']
+ t.spec_opts = ['--format html:../doc/output/report.html','--backtrace']
+end
+
+desc "Run all failing examples"
+Spec::Rake::SpecTask.new('failing_examples') do |t|
+ t.spec_files = FileList['failing_examples/**/*_spec.rb']
+end
+
+desc 'Generate RDoc'
+rd = Rake::RDocTask.new do |rdoc|
+ rdoc.rdoc_dir = '../doc/output/rdoc'
+ rdoc.options << '--title' << 'RSpec' << '--line-numbers' << '--inline-source' << '--main' << 'README'
+ rdoc.rdoc_files.include('README', 'CHANGES', 'MIT-LICENSE', 'UPGRADE', 'lib/**/*.rb')
+end
+
+spec = Gem::Specification.new do |s|
+ s.name = PKG_NAME
+ s.version = PKG_VERSION
+ s.summary = Spec::VERSION::DESCRIPTION
+ s.description = <<-EOF
+ RSpec is a behaviour driven development (BDD) framework for Ruby. RSpec was
+ created in response to Dave Astels' article _A New Look at Test Driven Development_
+ which can be read at: http://daveastels.com/index.php?p=5 RSpec is intended to
+ provide the features discussed in Dave's article.
+ EOF
+
+ s.files = PKG_FILES.to_a
+ s.require_path = 'lib'
+
+ s.has_rdoc = true
+ s.rdoc_options = rd.options
+ s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$|^EXAMPLES.rd$/ }.to_a
+
+ s.bindir = 'bin'
+ s.executables = ['spec', 'spec_translator']
+ s.default_executable = 'spec'
+ s.author = "RSpec Development Team"
+ s.email = "rspec-devel@rubyforge.org"
+ s.homepage = "http://rspec.rubyforge.org"
+ s.platform = Gem::Platform::RUBY
+ s.rubyforge_project = "rspec"
+end
+
+Rake::GemPackageTask.new(spec) do |pkg|
+ pkg.need_zip = true
+ pkg.need_tar = true
+end
+
+def egrep(pattern)
+ Dir['**/*.rb'].each do |fn|
+ count = 0
+ open(fn) do |f|
+ while line = f.gets
+ count += 1
+ if line =~ pattern
+ puts "#{fn}:#{count}:#{line}"
+ end
+ end
+ end
+ end
+end
+
+desc "Look for TODO and FIXME tags in the code"
+task :todo do
+ egrep /(FIXME|TODO|TBD)/
+end
+
+task :clobber do
+ core.clobber
+end
+
+task :release => [:clobber, :verify_committed, :verify_user, :spec, :publish_packages, :tag, :publish_news]
+
+desc "Verifies that there is no uncommitted code"
+task :verify_committed do
+ IO.popen('svn stat') do |io|
+ io.each_line do |line|
+ raise "\n!!! Do a svn commit first !!!\n\n" if line =~ /^\s*M\s*/
+ end
+ end
+end
+
+desc "Creates a tag in svn"
+task :tag do
+ from = `svn info #{File.dirname(__FILE__)}`.match(/URL: (.*)\/rspec/n)[1]
+ to = from.gsub(/trunk/, "tags/#{Spec::VERSION::TAG}")
+ current = from.gsub(/trunk/, "tags/CURRENT")
+
+ puts "Creating tag in SVN"
+ tag_cmd = "svn cp #{from} #{to} -m \"Tag release #{Spec::VERSION::FULL_VERSION}\""
+ `#{tag_cmd}` ; raise "ERROR: #{tag_cmd}" unless $? == 0
+
+ puts "Removing CURRENT"
+ remove_current_cmd = "svn rm #{current} -m \"Remove tags/CURRENT\""
+ `#{remove_current_cmd}` ; raise "ERROR: #{remove_current_cmd}" unless $? == 0
+
+ puts "Re-Creating CURRENT"
+ create_current_cmd = "svn cp #{to} #{current} -m \"Copy #{Spec::VERSION::TAG} to tags/CURRENT\""
+ `#{create_current_cmd}` ; "ERROR: #{create_current_cmd}" unless $? == 0
+end
+
+desc "Run this task before you commit. You should see 'OK TO COMMIT'"
+task(:pre_commit) {core.pre_commit}
+
+desc "Build the website, but do not publish it"
+task(:website) {core.website}
+
+task(:rdoc_rails) {core.rdoc_rails}
+
+task :verify_user do
+ raise "RUBYFORGE_USER environment variable not set!" unless ENV['RUBYFORGE_USER']
+end
+
+desc "Upload Website to RubyForge"
+task :publish_website => [:verify_user, :website] do
+ unless Spec::VERSION::RELEASE_CANDIDATE
+ publisher = Rake::SshDirPublisher.new(
+ "rspec-website@rubyforge.org",
+ "/var/www/gforge-projects/#{PKG_NAME}",
+ "../doc/output"
+ )
+ publisher.upload
+ else
+ puts "** Not publishing packages to RubyForge - this is a prerelease"
+ end
+end
+
+desc "Upload Website archive to RubyForge"
+task :archive_website => [:verify_user, :website] do
+ publisher = Rake::SshDirPublisher.new(
+ "rspec-website@rubyforge.org",
+ "/var/www/gforge-projects/#{PKG_NAME}/#{Spec::VERSION::TAG}",
+ "../doc/output"
+ )
+ publisher.upload
+end
+
+desc "Package the Rails plugin"
+task :package_rspec_on_rails do
+ mkdir 'pkg' rescue nil
+ rm_rf 'pkg/rspec_on_rails' rescue nil
+ `svn export ../rspec_on_rails pkg/rspec_on_rails-#{PKG_VERSION}`
+ Dir.chdir 'pkg' do
+ `tar cvzf rspec_on_rails-#{PKG_VERSION}.tgz rspec_on_rails-#{PKG_VERSION}`
+ end
+end
+task :pkg => :package_rspec_on_rails
+
+desc "Package the RSpec.tmbundle"
+task :package_tmbundle do
+ mkdir 'pkg' rescue nil
+ rm_rf 'pkg/RSpec.tmbundle' rescue nil
+ `svn export ../RSpec.tmbundle pkg/RSpec.tmbundle`
+ Dir.chdir 'pkg' do
+ `tar cvzf RSpec-#{PKG_VERSION}.tmbundle.tgz RSpec.tmbundle`
+ end
+end
+task :pkg => :package_tmbundle
+
+desc "Publish gem+tgz+zip on RubyForge. You must make sure lib/version.rb is aligned with the CHANGELOG file"
+task :publish_packages => [:verify_user, :package] do
+ release_files = FileList[
+ "pkg/#{PKG_FILE_NAME}.gem",
+ "pkg/#{PKG_FILE_NAME}.tgz",
+ "pkg/rspec_on_rails-#{PKG_VERSION}.tgz",
+ "pkg/#{PKG_FILE_NAME}.zip",
+ "pkg/RSpec-#{PKG_VERSION}.tmbundle.tgz"
+ ]
+ unless Spec::VERSION::RELEASE_CANDIDATE
+ require 'meta_project'
+ require 'rake/contrib/xforge'
+
+ Rake::XForge::Release.new(MetaProject::Project::XForge::RubyForge.new(PKG_NAME)) do |xf|
+ # Never hardcode user name and password in the Rakefile!
+ xf.user_name = ENV['RUBYFORGE_USER']
+ xf.files = release_files.to_a
+ xf.release_name = "RSpec #{PKG_VERSION}"
+ end
+ else
+ puts "SINCE THIS IS A PRERELEASE, FILES ARE UPLOADED WITH SSH, NOT TO THE RUBYFORGE FILE SECTION"
+ puts "YOU MUST TYPE THE PASSWORD #{release_files.length} TIMES..."
+
+ host = "rspec-website@rubyforge.org"
+ remote_dir = "/var/www/gforge-projects/#{PKG_NAME}"
+
+ publisher = Rake::SshFilePublisher.new(
+ host,
+ remote_dir,
+ File.dirname(__FILE__),
+ *release_files
+ )
+ publisher.upload
+
+ puts "UPLADED THE FOLLOWING FILES:"
+ release_files.each do |file|
+ name = file.match(/pkg\/(.*)/)[1]
+ puts "* http://rspec.rubyforge.org/#{name}"
+ end
+
+ puts "They are not linked to anywhere, so don't forget to tell people!"
+ end
+end
+
+desc "Publish news on RubyForge"
+task :publish_news => [:verify_user] do
+ unless Spec::VERSION::RELEASE_CANDIDATE
+ require 'meta_project'
+ require 'rake/contrib/xforge'
+ Rake::XForge::NewsPublisher.new(MetaProject::Project::XForge::RubyForge.new(PKG_NAME)) do |news|
+ # Never hardcode user name and password in the Rakefile!
+ news.user_name = ENV['RUBYFORGE_USER']
+ end
+ else
+ puts "** Not publishing news to RubyForge - this is a prerelease"
+ end
+end
+
+def core
+ PreCommit::Core.new(self)
+end
diff --git a/vendor/gems/rspec/TODO b/vendor/gems/rspec/TODO
new file mode 100644
index 000000000..250bb66c2
--- /dev/null
+++ b/vendor/gems/rspec/TODO
@@ -0,0 +1,2 @@
+=== Before releasing 1.1.0:
+
diff --git a/vendor/gems/rspec/UPGRADE b/vendor/gems/rspec/UPGRADE
new file mode 100644
index 000000000..0a2c6f528
--- /dev/null
+++ b/vendor/gems/rspec/UPGRADE
@@ -0,0 +1,31 @@
+= Upgrading existing code to RSpec-0.9
+
+== General (see below for Spec::Rails specifics)
+
+=== New Syntax for should and should_not
+
+* Use translator (should get 90% of your code)
+* Manually fix "parenthesis" warnings
+
+=== Change before_context_eval to before_eval
+
+before_context_eval is an un-published hook used by
+Spec::Rails to create specialized behaviour contexts.
+Most of you don't need to change this, but for those
+who have exploited it, you'll need to change it to
+before_eval.
+
+== Spec::Rails
+
+=== spec_helper.rb
+
+We've added a new way to configure Spec::Runner to do
+things like use_transactional_fixtures and use_instantiated_fixtures.
+You'll need to update spec/spec_helper.rb accordingly. You can either
+just re-generate it:
+
+ script/generate rspec
+
+Or modify spec_helper.rb based on the template, which can be found at:
+
+ vendor/plugins/rspec_on_rails/generators/rspec/templates/spec_helper.rb \ No newline at end of file
diff --git a/spec/bin/spec b/vendor/gems/rspec/bin/spec
index aaf320f34..283176d76 100755
--- a/spec/bin/spec
+++ b/vendor/gems/rspec/bin/spec
@@ -1,4 +1,4 @@
#!/usr/bin/env ruby
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
require 'spec'
-::Spec::Runner::CommandLine.run(ARGV, STDERR, STDOUT, true, true)
+exit ::Spec::Runner::CommandLine.run(rspec_options)
diff --git a/vendor/gems/rspec/bin/spec_translator b/vendor/gems/rspec/bin/spec_translator
new file mode 100755
index 000000000..abd50b743
--- /dev/null
+++ b/vendor/gems/rspec/bin/spec_translator
@@ -0,0 +1,8 @@
+#!/usr/bin/env ruby
+raise "\n\nUsage: spec_translator from_dir to_dir\n\n" if ARGV.size != 2
+$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
+require 'spec/translator'
+t = ::Spec::Translator.new
+from = ARGV[0]
+to = ARGV[1]
+t.translate(from, to)
diff --git a/vendor/gems/rspec/examples/pure/autogenerated_docstrings_example.rb b/vendor/gems/rspec/examples/pure/autogenerated_docstrings_example.rb
new file mode 100644
index 000000000..a4928ef4a
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/autogenerated_docstrings_example.rb
@@ -0,0 +1,19 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+# Run spec w/ -fs to see the output of this file
+
+describe "Examples with no descriptions" do
+
+ # description is auto-generated as "should equal(5)" based on the last #should
+ it do
+ 3.should equal(3)
+ 5.should equal(5)
+ end
+
+ it { 3.should be < 5 }
+
+ it { ["a"].should include("a") }
+
+ it { [1,2,3].should respond_to(:size) }
+
+end
diff --git a/vendor/gems/rspec/examples/pure/before_and_after_example.rb b/vendor/gems/rspec/examples/pure/before_and_after_example.rb
new file mode 100644
index 000000000..7db6274ef
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/before_and_after_example.rb
@@ -0,0 +1,40 @@
+require File.dirname(__FILE__) + '/spec_helper'
+$global = 0
+
+describe "State created in before(:all)" do
+ before :all do
+ @sideeffect = 1
+ $global +=1
+ end
+
+ before :each do
+ @isolated = 1
+ end
+
+ it "should be accessible from example" do
+ @sideeffect.should == 1
+ $global.should == 1
+ @isolated.should == 1
+
+ @sideeffect += 1
+ @isolated += 1
+ end
+
+ it "should not have sideffects" do
+ @sideeffect.should == 1
+ $global.should == 2
+ @isolated.should == 1
+
+ @sideeffect += 1
+ @isolated += 1
+ end
+
+ after :each do
+ $global += 1
+ end
+
+ after :all do
+ $global.should == 3
+ $global = 0
+ end
+end
diff --git a/vendor/gems/rspec/examples/pure/behave_as_example.rb b/vendor/gems/rspec/examples/pure/behave_as_example.rb
new file mode 100755
index 000000000..e95d1469a
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/behave_as_example.rb
@@ -0,0 +1,45 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+def behave_as_electric_musician
+ respond_to(:read_notes, :turn_down_amp)
+end
+
+def behave_as_musician
+ respond_to(:read_notes)
+end
+
+module BehaveAsExample
+
+ class BluesGuitarist
+ def read_notes; end
+ def turn_down_amp; end
+ end
+
+ class RockGuitarist
+ def read_notes; end
+ def turn_down_amp; end
+ end
+
+ class ClassicGuitarist
+ def read_notes; end
+ end
+
+ describe BluesGuitarist do
+ it "should behave as guitarist" do
+ BluesGuitarist.new.should behave_as_electric_musician
+ end
+ end
+
+ describe RockGuitarist do
+ it "should behave as guitarist" do
+ RockGuitarist.new.should behave_as_electric_musician
+ end
+ end
+
+ describe ClassicGuitarist do
+ it "should not behave as guitarist" do
+ ClassicGuitarist.new.should behave_as_musician
+ end
+ end
+
+end
diff --git a/vendor/gems/rspec/examples/pure/custom_expectation_matchers.rb b/vendor/gems/rspec/examples/pure/custom_expectation_matchers.rb
new file mode 100644
index 000000000..075bb542d
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/custom_expectation_matchers.rb
@@ -0,0 +1,54 @@
+module AnimalSpecHelper
+ class Eat
+ def initialize(food)
+ @food = food
+ end
+
+ def matches?(animal)
+ @animal = animal
+ @animal.eats?(@food)
+ end
+
+ def failure_message
+ "expected #{@animal} to eat #{@food}, but it does not"
+ end
+
+ def negative_failure_message
+ "expected #{@animal} not to eat #{@food}, but it does"
+ end
+ end
+
+ def eat(food)
+ Eat.new(food)
+ end
+end
+
+module Animals
+ class Animal
+ def eats?(food)
+ return foods_i_eat.include?(food)
+ end
+ end
+
+ class Mouse < Animal
+ def foods_i_eat
+ [:cheese]
+ end
+ end
+
+ describe Mouse do
+ include AnimalSpecHelper
+ before(:each) do
+ @mouse = Animals::Mouse.new
+ end
+
+ it "should eat cheese" do
+ @mouse.should eat(:cheese)
+ end
+
+ it "should not eat cat" do
+ @mouse.should_not eat(:cat)
+ end
+ end
+
+end
diff --git a/vendor/gems/rspec/examples/pure/custom_formatter.rb b/vendor/gems/rspec/examples/pure/custom_formatter.rb
new file mode 100644
index 000000000..c449fdc2e
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/custom_formatter.rb
@@ -0,0 +1,12 @@
+require File.dirname(__FILE__) + '/spec_helper'
+require 'spec/runner/formatter/progress_bar_formatter'
+
+# Example of a formatter with custom bactrace printing. Run me with:
+# ruby bin/spec failing_examples -r examples/custom_formatter.rb -f CustomFormatter
+class CustomFormatter < Spec::Runner::Formatter::ProgressBarFormatter
+ def backtrace_line(line)
+ line.gsub(/([^:]*\.rb):(\d*)/) do
+ "<a href=\"file://#{File.expand_path($1)}\">#{$1}:#{$2}</a> "
+ end
+ end
+end
diff --git a/vendor/gems/rspec/examples/pure/dynamic_spec.rb b/vendor/gems/rspec/examples/pure/dynamic_spec.rb
new file mode 100644
index 000000000..15d473d61
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/dynamic_spec.rb
@@ -0,0 +1,9 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+describe "Some integers" do
+ (1..10).each do |n|
+ it "The root of #{n} square should be #{n}" do
+ Math.sqrt(n*n).should == n
+ end
+ end
+end
diff --git a/vendor/gems/rspec/examples/pure/file_accessor.rb b/vendor/gems/rspec/examples/pure/file_accessor.rb
new file mode 100644
index 000000000..ff6fb743c
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/file_accessor.rb
@@ -0,0 +1,19 @@
+require File.dirname(__FILE__) + '/spec_helper'
+class FileAccessor
+ def open_and_handle_with(pathname, processor)
+ pathname.open do |io|
+ processor.process(io)
+ end
+ end
+end
+
+if __FILE__ == $0
+ require File.dirname(__FILE__) + '/io_processor'
+ require 'pathname'
+
+ accessor = FileAccessor.new
+ io_processor = IoProcessor.new
+ file = Pathname.new ARGV[0]
+
+ accessor.open_and_handle_with(file, io_processor)
+end
diff --git a/vendor/gems/rspec/examples/pure/file_accessor_spec.rb b/vendor/gems/rspec/examples/pure/file_accessor_spec.rb
new file mode 100644
index 000000000..628d4c0b0
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/file_accessor_spec.rb
@@ -0,0 +1,38 @@
+require File.dirname(__FILE__) + '/spec_helper'
+require File.dirname(__FILE__) + '/file_accessor'
+require 'stringio'
+
+describe "A FileAccessor" do
+ # This sequence diagram illustrates what this spec specifies.
+ #
+ # +--------------+ +----------+ +-------------+
+ # | FileAccessor | | Pathname | | IoProcessor |
+ # +--------------+ +----------+ +-------------+
+ # | | |
+ # open_and_handle_with | | |
+ # -------------------->| | open | |
+ # | |--------------->| | |
+ # | | io | | |
+ # | |<...............| | |
+ # | | | process(io) |
+ # | |---------------------------------->| |
+ # | | | | |
+ # | |<..................................| |
+ # | | |
+ #
+ it "should open a file and pass it to the processor's process method" do
+ # This is the primary actor
+ accessor = FileAccessor.new
+
+ # These are the primary actor's neighbours, which we mock.
+ file = mock "Pathname"
+ io_processor = mock "IoProcessor"
+
+ io = StringIO.new "whatever"
+ file.should_receive(:open).and_yield io
+ io_processor.should_receive(:process).with(io)
+
+ accessor.open_and_handle_with(file, io_processor)
+ end
+
+end
diff --git a/vendor/gems/rspec/examples/pure/greeter_spec.rb b/vendor/gems/rspec/examples/pure/greeter_spec.rb
new file mode 100644
index 000000000..ec7669dcc
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/greeter_spec.rb
@@ -0,0 +1,31 @@
+require File.dirname(__FILE__) + '/spec_helper'
+# greeter.rb
+#
+# Based on http://glu.ttono.us/articles/2006/12/19/tormenting-your-tests-with-heckle
+#
+# Run with:
+#
+# spec greeter_spec.rb --heckle Greeter
+#
+class Greeter
+ def initialize(person = nil)
+ @person = person
+ end
+
+ def greet
+ @person.nil? ? "Hi there!" : "Hi #{@person}!"
+ end
+end
+
+describe "Greeter" do
+ it "should say Hi to person" do
+ greeter = Greeter.new("Kevin")
+ greeter.greet.should == "Hi Kevin!"
+ end
+
+ it "should say Hi to nobody" do
+ greeter = Greeter.new
+ # Uncomment the next line to make Heckle happy
+ #greeter.greet.should == "Hi there!"
+ end
+end
diff --git a/vendor/gems/rspec/examples/pure/helper_method_example.rb b/vendor/gems/rspec/examples/pure/helper_method_example.rb
new file mode 100644
index 000000000..d97f19e65
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/helper_method_example.rb
@@ -0,0 +1,14 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+module HelperMethodExample
+ describe "an example group with helper a method" do
+ def helper_method
+ "received call"
+ end
+
+ it "should make that method available to specs" do
+ helper_method.should == "received call"
+ end
+ end
+end
+
diff --git a/vendor/gems/rspec/examples/pure/io_processor.rb b/vendor/gems/rspec/examples/pure/io_processor.rb
new file mode 100644
index 000000000..6b15147b6
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/io_processor.rb
@@ -0,0 +1,8 @@
+class DataTooShort < StandardError; end
+
+class IoProcessor
+ # Does some fancy stuff unless the length of +io+ is shorter than 32
+ def process(io)
+ raise DataTooShort if io.read.length < 32
+ end
+end
diff --git a/vendor/gems/rspec/examples/pure/io_processor_spec.rb b/vendor/gems/rspec/examples/pure/io_processor_spec.rb
new file mode 100644
index 000000000..5cab7bf31
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/io_processor_spec.rb
@@ -0,0 +1,21 @@
+require File.dirname(__FILE__) + '/spec_helper'
+require File.dirname(__FILE__) + '/io_processor'
+require 'stringio'
+
+describe "An IoProcessor" do
+ before(:each) do
+ @processor = IoProcessor.new
+ end
+
+ it "should raise nothing when the file is exactly 32 bytes" do
+ lambda {
+ @processor.process(StringIO.new("z"*32))
+ }.should_not raise_error
+ end
+
+ it "should raise an exception when the file length is less than 32 bytes" do
+ lambda {
+ @processor.process(StringIO.new("z"*31))
+ }.should raise_error(DataTooShort)
+ end
+end
diff --git a/vendor/gems/rspec/examples/pure/legacy_spec.rb b/vendor/gems/rspec/examples/pure/legacy_spec.rb
new file mode 100644
index 000000000..c86369515
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/legacy_spec.rb
@@ -0,0 +1,11 @@
+require File.dirname(__FILE__) + '/spec_helper'
+context "A legacy spec" do
+ setup do
+ end
+
+ specify "should work fine" do
+ end
+
+ teardown do
+ end
+end
diff --git a/vendor/gems/rspec/examples/pure/mocking_example.rb b/vendor/gems/rspec/examples/pure/mocking_example.rb
new file mode 100644
index 000000000..6adbef59d
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/mocking_example.rb
@@ -0,0 +1,27 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+describe "A consumer of a mock" do
+ it "should be able to send messages to the mock" do
+ mock = mock("poke me")
+ mock.should_receive(:poke)
+ mock.poke
+ end
+end
+
+describe "a mock" do
+ it "should be able to mock the same message twice w/ different args" do
+ mock = mock("mock")
+ mock.should_receive(:msg).with(:arg1).and_return(:val1)
+ mock.should_receive(:msg).with(:arg2).and_return(:val2)
+ mock.msg(:arg1).should eql(:val1)
+ mock.msg(:arg2).should eql(:val2)
+ end
+
+ it "should be able to mock the same message twice w/ different args in reverse order" do
+ mock = mock("mock")
+ mock.should_receive(:msg).with(:arg1).and_return(:val1)
+ mock.should_receive(:msg).with(:arg2).and_return(:val2)
+ mock.msg(:arg2).should eql(:val2)
+ mock.msg(:arg1).should eql(:val1)
+ end
+end
diff --git a/vendor/gems/rspec/examples/pure/multi_threaded_behaviour_runner.rb b/vendor/gems/rspec/examples/pure/multi_threaded_behaviour_runner.rb
new file mode 100644
index 000000000..36edcd497
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/multi_threaded_behaviour_runner.rb
@@ -0,0 +1,28 @@
+class MultiThreadedExampleGroupRunner < Spec::Runner::ExampleGroupRunner
+ def initialize(options, arg)
+ super(options)
+ # configure these
+ @thread_count = 4
+ @thread_wait = 0
+ end
+
+ def run
+ @threads = []
+ q = Queue.new
+ example_groups.each { |b| q << b}
+ success = true
+ @thread_count.times do
+ @threads << Thread.new(q) do |queue|
+ while not queue.empty?
+ example_group = queue.pop
+ success &= example_group.suite.run(nil)
+ end
+ end
+ sleep @thread_wait
+ end
+ @threads.each {|t| t.join}
+ success
+ end
+end
+
+MultiThreadedBehaviourRunner = MultiThreadedExampleGroupRunner \ No newline at end of file
diff --git a/vendor/gems/rspec/examples/pure/nested_classes_example.rb b/vendor/gems/rspec/examples/pure/nested_classes_example.rb
new file mode 100644
index 000000000..abe43b0a6
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/nested_classes_example.rb
@@ -0,0 +1,36 @@
+require File.dirname(__FILE__) + '/spec_helper'
+require File.dirname(__FILE__) + '/stack'
+
+class StackExamples < Spec::ExampleGroup
+ describe(Stack)
+ before(:each) do
+ @stack = Stack.new
+ end
+end
+
+class EmptyStackExamples < StackExamples
+ describe("when empty")
+ it "should be empty" do
+ @stack.should be_empty
+ end
+end
+
+class AlmostFullStackExamples < StackExamples
+ describe("when almost full")
+ before(:each) do
+ (1..9).each {|n| @stack.push n}
+ end
+ it "should be full" do
+ @stack.should_not be_full
+ end
+end
+
+class FullStackExamples < StackExamples
+ describe("when full")
+ before(:each) do
+ (1..10).each {|n| @stack.push n}
+ end
+ it "should be full" do
+ @stack.should be_full
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/examples/pure/partial_mock_example.rb b/vendor/gems/rspec/examples/pure/partial_mock_example.rb
new file mode 100644
index 000000000..841ec8847
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/partial_mock_example.rb
@@ -0,0 +1,28 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+class MockableClass
+ def self.find id
+ return :original_return
+ end
+end
+
+describe "A partial mock" do
+
+ it "should work at the class level" do
+ MockableClass.should_receive(:find).with(1).and_return {:stub_return}
+ MockableClass.find(1).should equal(:stub_return)
+ end
+
+ it "should revert to the original after each spec" do
+ MockableClass.find(1).should equal(:original_return)
+ end
+
+ it "can be mocked w/ ordering" do
+ MockableClass.should_receive(:msg_1).ordered
+ MockableClass.should_receive(:msg_2).ordered
+ MockableClass.should_receive(:msg_3).ordered
+ MockableClass.msg_1
+ MockableClass.msg_2
+ MockableClass.msg_3
+ end
+end
diff --git a/vendor/gems/rspec/examples/pure/pending_example.rb b/vendor/gems/rspec/examples/pure/pending_example.rb
new file mode 100644
index 000000000..13f3d00c4
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/pending_example.rb
@@ -0,0 +1,20 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+describe "pending example (using pending method)" do
+ it %Q|should be reported as "PENDING: for some reason"| do
+ pending("for some reason")
+ end
+end
+
+describe "pending example (with no block)" do
+ it %Q|should be reported as "PENDING: Not Yet Implemented"|
+end
+
+describe "pending example (with block for pending)" do
+ it %Q|should have a failing block, passed to pending, reported as "PENDING: for some reason"| do
+ pending("for some reason") do
+ raise "some reason"
+ end
+ end
+end
+
diff --git a/vendor/gems/rspec/examples/pure/predicate_example.rb b/vendor/gems/rspec/examples/pure/predicate_example.rb
new file mode 100644
index 000000000..1202bb670
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/predicate_example.rb
@@ -0,0 +1,27 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+class BddFramework
+ def intuitive?
+ true
+ end
+
+ def adopted_quickly?
+ true
+ end
+end
+
+describe "BDD framework" do
+
+ before(:each) do
+ @bdd_framework = BddFramework.new
+ end
+
+ it "should be adopted quickly" do
+ @bdd_framework.should be_adopted_quickly
+ end
+
+ it "should be intuitive" do
+ @bdd_framework.should be_intuitive
+ end
+
+end
diff --git a/vendor/gems/rspec/examples/pure/priority.txt b/vendor/gems/rspec/examples/pure/priority.txt
new file mode 100644
index 000000000..5b00064e2
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/priority.txt
@@ -0,0 +1 @@
+examples/custom_expectation_matchers.rb \ No newline at end of file
diff --git a/vendor/gems/rspec/examples/pure/shared_example_group_example.rb b/vendor/gems/rspec/examples/pure/shared_example_group_example.rb
new file mode 100644
index 000000000..fb81af1ec
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/shared_example_group_example.rb
@@ -0,0 +1,81 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+module SharedExampleGroupExample
+ class OneThing
+ def what_things_do
+ "stuff"
+ end
+ end
+
+ class AnotherThing
+ def what_things_do
+ "stuff"
+ end
+ end
+
+ class YetAnotherThing
+ def what_things_do
+ "stuff"
+ end
+ end
+
+ # A SharedExampleGroup is an example group that doesn't get run.
+ # You can create one like this:
+ share_examples_for "most things" do
+ def helper_method
+ "helper method"
+ end
+
+ it "should do what things do" do
+ @thing.what_things_do.should == "stuff"
+ end
+ end
+
+ # A SharedExampleGroup is also module. If you create one like this
+ # it gets assigned to the constant AllThings
+ share_as :MostThings do
+ def helper_method
+ "helper method"
+ end
+
+ it "should do what things do" do
+ @thing.what_things_do.should == "stuff"
+ end
+ end
+
+ describe OneThing do
+ # Now you can include the shared example group like this, which
+ # feels more like what you might say ...
+ it_should_behave_like "most things"
+
+ before(:each) { @thing = OneThing.new }
+
+ it "should have access to helper methods defined in the shared example group" do
+ helper_method.should == "helper method"
+ end
+ end
+
+ describe AnotherThing do
+ # ... or you can include the example group like this, which
+ # feels more like the programming language we love.
+ it_should_behave_like MostThings
+
+ before(:each) { @thing = AnotherThing.new }
+
+ it "should have access to helper methods defined in the shared example group" do
+ helper_method.should == "helper method"
+ end
+ end
+
+ describe YetAnotherThing do
+ # ... or you can include the example group like this, which
+ # feels more like the programming language we love.
+ include MostThings
+
+ before(:each) { @thing = AnotherThing.new }
+
+ it "should have access to helper methods defined in the shared example group" do
+ helper_method.should == "helper method"
+ end
+ end
+end
diff --git a/vendor/gems/rspec/examples/pure/shared_stack_examples.rb b/vendor/gems/rspec/examples/pure/shared_stack_examples.rb
new file mode 100644
index 000000000..7a0816250
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/shared_stack_examples.rb
@@ -0,0 +1,38 @@
+require File.join(File.dirname(__FILE__), *%w[spec_helper])
+
+shared_examples_for "non-empty Stack" do
+
+ it { @stack.should_not be_empty }
+
+ it "should return the top item when sent #peek" do
+ @stack.peek.should == @last_item_added
+ end
+
+ it "should NOT remove the top item when sent #peek" do
+ @stack.peek.should == @last_item_added
+ @stack.peek.should == @last_item_added
+ end
+
+ it "should return the top item when sent #pop" do
+ @stack.pop.should == @last_item_added
+ end
+
+ it "should remove the top item when sent #pop" do
+ @stack.pop.should == @last_item_added
+ unless @stack.empty?
+ @stack.pop.should_not == @last_item_added
+ end
+ end
+
+end
+
+shared_examples_for "non-full Stack" do
+
+ it { @stack.should_not be_full }
+
+ it "should add to the top when sent #push" do
+ @stack.push "newly added top item"
+ @stack.peek.should == "newly added top item"
+ end
+
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/examples/pure/spec_helper.rb b/vendor/gems/rspec/examples/pure/spec_helper.rb
new file mode 100644
index 000000000..1e880796c
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/spec_helper.rb
@@ -0,0 +1,3 @@
+lib_path = File.expand_path("#{File.dirname(__FILE__)}/../../lib")
+$LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
+require 'spec'
diff --git a/vendor/gems/rspec/examples/pure/stack.rb b/vendor/gems/rspec/examples/pure/stack.rb
new file mode 100644
index 000000000..407173f7b
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/stack.rb
@@ -0,0 +1,36 @@
+class StackUnderflowError < RuntimeError
+end
+
+class StackOverflowError < RuntimeError
+end
+
+class Stack
+
+ def initialize
+ @items = []
+ end
+
+ def push object
+ raise StackOverflowError if @items.length == 10
+ @items.push object
+ end
+
+ def pop
+ raise StackUnderflowError if @items.empty?
+ @items.delete @items.last
+ end
+
+ def peek
+ raise StackUnderflowError if @items.empty?
+ @items.last
+ end
+
+ def empty?
+ @items.empty?
+ end
+
+ def full?
+ @items.length == 10
+ end
+
+end
diff --git a/vendor/gems/rspec/examples/pure/stack_spec.rb b/vendor/gems/rspec/examples/pure/stack_spec.rb
new file mode 100644
index 000000000..2a769da00
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/stack_spec.rb
@@ -0,0 +1,63 @@
+require File.dirname(__FILE__) + '/spec_helper'
+require File.dirname(__FILE__) + "/stack"
+require File.dirname(__FILE__) + '/shared_stack_examples'
+
+describe Stack, " (empty)" do
+ before(:each) do
+ @stack = Stack.new
+ end
+
+ # NOTE that this one auto-generates the description "should be empty"
+ it { @stack.should be_empty }
+
+ it_should_behave_like "non-full Stack"
+
+ it "should complain when sent #peek" do
+ lambda { @stack.peek }.should raise_error(StackUnderflowError)
+ end
+
+ it "should complain when sent #pop" do
+ lambda { @stack.pop }.should raise_error(StackUnderflowError)
+ end
+end
+
+describe Stack, " (with one item)" do
+ before(:each) do
+ @stack = Stack.new
+ @stack.push 3
+ @last_item_added = 3
+ end
+
+ it_should_behave_like "non-empty Stack"
+ it_should_behave_like "non-full Stack"
+
+end
+
+describe Stack, " (with one item less than capacity)" do
+ before(:each) do
+ @stack = Stack.new
+ (1..9).each { |i| @stack.push i }
+ @last_item_added = 9
+ end
+
+ it_should_behave_like "non-empty Stack"
+ it_should_behave_like "non-full Stack"
+end
+
+describe Stack, " (full)" do
+ before(:each) do
+ @stack = Stack.new
+ (1..10).each { |i| @stack.push i }
+ @last_item_added = 10
+ end
+
+ # NOTE that this one auto-generates the description "should be full"
+ it { @stack.should be_full }
+
+ it_should_behave_like "non-empty Stack"
+
+ it "should complain on #push" do
+ lambda { @stack.push Object.new }.should raise_error(StackOverflowError)
+ end
+
+end
diff --git a/vendor/gems/rspec/examples/pure/stack_spec_with_nested_example_groups.rb b/vendor/gems/rspec/examples/pure/stack_spec_with_nested_example_groups.rb
new file mode 100644
index 000000000..05f6ad464
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/stack_spec_with_nested_example_groups.rb
@@ -0,0 +1,67 @@
+require File.dirname(__FILE__) + '/spec_helper'
+require File.dirname(__FILE__) + '/stack'
+require File.dirname(__FILE__) + '/shared_stack_examples'
+
+describe Stack do
+
+ before(:each) do
+ @stack = Stack.new
+ end
+
+ describe "(empty)" do
+
+ it { @stack.should be_empty }
+
+ it_should_behave_like "non-full Stack"
+
+ it "should complain when sent #peek" do
+ lambda { @stack.peek }.should raise_error(StackUnderflowError)
+ end
+
+ it "should complain when sent #pop" do
+ lambda { @stack.pop }.should raise_error(StackUnderflowError)
+ end
+
+ end
+
+ describe "(with one item)" do
+
+ before(:each) do
+ @stack.push 3
+ @last_item_added = 3
+ end
+
+ it_should_behave_like "non-empty Stack"
+ it_should_behave_like "non-full Stack"
+
+ end
+
+ describe "(with one item less than capacity)" do
+
+ before(:each) do
+ (1..9).each { |i| @stack.push i }
+ @last_item_added = 9
+ end
+
+ it_should_behave_like "non-empty Stack"
+ it_should_behave_like "non-full Stack"
+ end
+
+ describe "(full)" do
+
+ before(:each) do
+ (1..10).each { |i| @stack.push i }
+ @last_item_added = 10
+ end
+
+ it { @stack.should be_full }
+
+ it_should_behave_like "non-empty Stack"
+
+ it "should complain on #push" do
+ lambda { @stack.push Object.new }.should raise_error(StackOverflowError)
+ end
+
+ end
+
+end
diff --git a/vendor/gems/rspec/examples/pure/stubbing_example.rb b/vendor/gems/rspec/examples/pure/stubbing_example.rb
new file mode 100644
index 000000000..31354aec6
--- /dev/null
+++ b/vendor/gems/rspec/examples/pure/stubbing_example.rb
@@ -0,0 +1,69 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+describe "A consumer of a stub" do
+ it "should be able to stub methods on any Object" do
+ obj = Object.new
+ obj.stub!(:foobar).and_return {:return_value}
+ obj.foobar.should equal(:return_value)
+ end
+end
+
+class StubbableClass
+ def self.find id
+ return :original_return
+ end
+end
+
+describe "A stubbed method on a class" do
+ it "should return the stubbed value" do
+ StubbableClass.stub!(:find).and_return(:stub_return)
+ StubbableClass.find(1).should equal(:stub_return)
+ end
+
+ it "should revert to the original method after each spec" do
+ StubbableClass.find(1).should equal(:original_return)
+ end
+
+ it "can stub! and mock the same message" do
+ StubbableClass.stub!(:msg).and_return(:stub_value)
+ StubbableClass.should_receive(:msg).with(:arg).and_return(:mock_value)
+
+ StubbableClass.msg.should equal(:stub_value)
+ StubbableClass.msg(:other_arg).should equal(:stub_value)
+ StubbableClass.msg(:arg).should equal(:mock_value)
+ StubbableClass.msg(:another_arg).should equal(:stub_value)
+ StubbableClass.msg(:yet_another_arg).should equal(:stub_value)
+ StubbableClass.msg.should equal(:stub_value)
+ end
+end
+
+describe "A mock" do
+ it "can stub!" do
+ mock = mock("stubbing mock")
+ mock.stub!(:msg).and_return(:value)
+ (1..10).each {mock.msg.should equal(:value)}
+ end
+
+ it "can stub! and mock" do
+ mock = mock("stubbing mock")
+ mock.stub!(:stub_message).and_return(:stub_value)
+ mock.should_receive(:mock_message).once.and_return(:mock_value)
+ (1..10).each {mock.stub_message.should equal(:stub_value)}
+ mock.mock_message.should equal(:mock_value)
+ (1..10).each {mock.stub_message.should equal(:stub_value)}
+ end
+
+ it "can stub! and mock the same message" do
+ mock = mock("stubbing mock")
+ mock.stub!(:msg).and_return(:stub_value)
+ mock.should_receive(:msg).with(:arg).and_return(:mock_value)
+ mock.msg.should equal(:stub_value)
+ mock.msg(:other_arg).should equal(:stub_value)
+ mock.msg(:arg).should equal(:mock_value)
+ mock.msg(:another_arg).should equal(:stub_value)
+ mock.msg(:yet_another_arg).should equal(:stub_value)
+ mock.msg.should equal(:stub_value)
+ end
+end
+
+
diff --git a/vendor/gems/rspec/examples/stories/adder.rb b/vendor/gems/rspec/examples/stories/adder.rb
new file mode 100644
index 000000000..0b027b0ff
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/adder.rb
@@ -0,0 +1,13 @@
+class Adder
+ def initialize
+ @addends = []
+ end
+
+ def <<(val)
+ @addends << val
+ end
+
+ def sum
+ @addends.inject(0) { |sum_so_far, val| sum_so_far + val }
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/examples/stories/addition b/vendor/gems/rspec/examples/stories/addition
new file mode 100644
index 000000000..58f092990
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/addition
@@ -0,0 +1,34 @@
+This is a story about a calculator. The text up here above the Story: declaration
+won't be processed, so you can write whatever you wish!
+
+Story: simple addition
+
+ As an accountant
+ I want to add numbers
+ So that I can count beans
+
+ Scenario: add one plus one
+ Given an addend of 1
+ And an addend of 1
+
+ When the addends are addeds
+
+ Then the sum should be 3
+ And the corks should be popped
+
+ Scenario: add two plus five
+ Given an addend of 2
+ And an addend of 5
+
+ When the addends are added
+
+ Then the sum should be 7
+ Then it should snow
+
+ Scenario: add three more
+ GivenScenario add two plus five
+ And an addend of 3
+
+ When the addends are added
+
+ Then the sum should be 10
diff --git a/vendor/gems/rspec/examples/stories/addition.rb b/vendor/gems/rspec/examples/stories/addition.rb
new file mode 100644
index 000000000..e43f5cf39
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/addition.rb
@@ -0,0 +1,9 @@
+require File.join(File.dirname(__FILE__), "helper")
+require File.join(File.dirname(__FILE__), "adder")
+
+# with_steps_for :addition, :more_addition do
+with_steps_for :addition, :more_addition do
+ # Then("the corks should be popped") { }
+ run File.expand_path(__FILE__).gsub(".rb","")
+end
+
diff --git a/vendor/gems/rspec/examples/stories/calculator.rb b/vendor/gems/rspec/examples/stories/calculator.rb
new file mode 100644
index 000000000..390437c55
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/calculator.rb
@@ -0,0 +1,65 @@
+$:.push File.join(File.dirname(__FILE__), *%w[.. .. lib])
+require 'spec'
+
+class AdditionMatchers < Spec::Story::StepGroup
+ steps do |add|
+ add.given("an addend of $addend") do |addend|
+ @adder ||= Adder.new
+ @adder << addend.to_i
+ end
+ end
+end
+
+steps = AdditionMatchers.new do |add|
+ add.then("the sum should be $sum") do |sum|
+ @sum.should == sum.to_i
+ end
+end
+
+steps.when("they are added") do
+ @sum = @adder.sum
+end
+
+# This Story uses steps (see above) instead of blocks
+# passed to Given, When and Then
+
+Story "addition", %{
+ As an accountant
+ I want to add numbers
+ So that I can count some beans
+}, :steps => steps do
+ Scenario "2 + 3" do
+ Given "an addend of 2"
+ And "an addend of 3"
+ When "they are added"
+ Then "the sum should be 5"
+ end
+
+ # This scenario uses GivenScenario, which silently runs
+ # all the steps in a previous scenario.
+
+ Scenario "add 4 more" do
+ GivenScenario "2 + 3"
+ Given "an addend of 4"
+ When "they are added"
+ Then "the sum should be 9"
+ end
+end
+
+# And the class that makes the story pass
+
+class Adder
+ def << addend
+ addends << addend
+ end
+
+ def sum
+ @addends.inject(0) do |result, addend|
+ result + addend.to_i
+ end
+ end
+
+ def addends
+ @addends ||= []
+ end
+end
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/README.txt b/vendor/gems/rspec/examples/stories/game-of-life/README.txt
new file mode 100644
index 000000000..9624ad411
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/README.txt
@@ -0,0 +1,21 @@
+John Conway's Game of Life
+
+The Rules
+---------
+The Game of Life was invented by John Conway (as you might have gathered).
+The game is played on a field of cells, each of which has eight neighbors (adjacent cells).
+A cell is either occupied (by an organism) or not.
+The rules for deriving a generation from the previous one are these:
+
+Survival
+--------
+If an occupied cell has 2 or 3 neighbors, the organism survives to the next generation.
+
+Death
+-----
+If an occupied cell has 0, 1, 4, 5, 6, 7, or 8 occupied neighbors, the organism dies
+(0, 1: of loneliness; 4 thru 8: of overcrowding).
+
+Birth
+-----
+If an unoccupied cell has 3 occupied neighbors, it becomes occupied.
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/everything.rb b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/everything.rb
new file mode 100644
index 000000000..90a281da5
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/everything.rb
@@ -0,0 +1,6 @@
+$:.unshift File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'lib')
+$:.unshift File.join(File.dirname(__FILE__), '..')
+
+require 'spec'
+require 'behaviour/examples/examples'
+require 'behaviour/stories/stories'
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/examples/examples.rb b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/examples/examples.rb
new file mode 100644
index 000000000..1cadfb3c1
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/examples/examples.rb
@@ -0,0 +1,3 @@
+require 'spec'
+require 'behaviour/examples/game_behaviour'
+require 'behaviour/examples/grid_behaviour'
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/examples/game_behaviour.rb b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/examples/game_behaviour.rb
new file mode 100644
index 000000000..ff5b357f0
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/examples/game_behaviour.rb
@@ -0,0 +1,35 @@
+require 'life'
+
+describe Game do
+ it 'should have a grid' do
+ # given
+ game = Game.new(5, 5)
+
+ # then
+ game.grid.should be_kind_of(Grid)
+ end
+
+ it 'should create a cell' do
+ # given
+ game = Game.new(2, 2)
+ expected_grid = Grid.from_string( 'X. ..' )
+
+ # when
+ game.create_at(0, 0)
+
+ # then
+ game.grid.should == expected_grid
+ end
+
+ it 'should destroy a cell' do
+ # given
+ game = Game.new(2,2)
+ game.grid = Grid.from_string('X. ..')
+
+ # when
+ game.destroy_at(0,0)
+
+ # then
+ game.grid.should == Grid.from_string('.. ..')
+ end
+end
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/examples/grid_behaviour.rb b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/examples/grid_behaviour.rb
new file mode 100644
index 000000000..5be3af519
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/examples/grid_behaviour.rb
@@ -0,0 +1,66 @@
+describe Grid do
+ it 'should be empty when created' do
+ # given
+ expected_contents = [
+ [0, 0, 0],
+ [0, 0, 0]
+ ]
+ grid = Grid.new(2, 3)
+
+ # when
+ contents = grid.contents
+
+ # then
+ contents.should == expected_contents
+ end
+
+ it 'should compare equal based on its contents' do
+ # given
+ grid1 = Grid.new(2, 3)
+ grid2 = Grid.new(2, 3)
+
+ # then
+ grid1.should == grid2
+ end
+
+ it 'should be able to replace its contents' do
+ # given
+ grid = Grid.new(2,2)
+ new_contents = [[0,1,0], [1,0,1]]
+
+ # when
+ grid.contents = new_contents
+
+ # then
+ grid.contents.should == new_contents
+ grid.rows.should == 2
+ grid.columns.should == 3
+ end
+
+ it 'should add an organism' do
+ # given
+ grid = Grid.new(2, 2)
+ expected = Grid.new(2, 2)
+ expected.contents = [[1,0],[0,0]]
+
+ # when
+ grid.create_at(0,0)
+
+ # then
+ grid.should == expected
+ end
+
+ it 'should create itself from a string' do
+ # given
+ expected = Grid.new 3, 3
+ expected.create_at(0,0)
+ expected.create_at(1,0)
+ expected.create_at(2,2)
+
+ # when
+ actual = Grid.from_string "X.. X.. ..X"
+
+ # then
+ actual.should == expected
+ end
+end
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/CellsWithLessThanTwoNeighboursDie.story b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/CellsWithLessThanTwoNeighboursDie.story
new file mode 100644
index 000000000..8374e86c5
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/CellsWithLessThanTwoNeighboursDie.story
@@ -0,0 +1,21 @@
+Story: cells with less than two neighbours die
+
+As a game producer
+I want cells with less than two neighbours to die
+So that I can illustrate how the game works to people with money
+
+Scenario: cells with zero or one neighbour die
+
+Given the grid looks like
+........
+.XX.XX..
+.XX.....
+....X...
+........
+When the next step occurs
+Then the grid should look like
+........
+.XX.....
+.XX.....
+........
+........
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/CellsWithMoreThanThreeNeighboursDie.story b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/CellsWithMoreThanThreeNeighboursDie.story
new file mode 100644
index 000000000..0d30b59be
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/CellsWithMoreThanThreeNeighboursDie.story
@@ -0,0 +1,21 @@
+Story: cells with more than three neighbours die
+
+As a game producer
+I want cells with more than three neighbours to die
+So that I can show the people with money how we are getting on
+
+Scenario: blink
+
+Given the grid looks like
+.....
+...XX
+...XX
+.XX..
+.XX..
+When the next step occurs
+Then the grid should look like
+.....
+...XX
+....X
+.X...
+.XX..
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/EmptySpacesWithThreeNeighboursCreateACell.story b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/EmptySpacesWithThreeNeighboursCreateACell.story
new file mode 100644
index 000000000..cbc248e73
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/EmptySpacesWithThreeNeighboursCreateACell.story
@@ -0,0 +1,42 @@
+Story: Empty spaces with three neighbours create a cell
+
+As a game producer
+I want empty cells with three neighbours to die
+So that I have a minimum feature set to ship
+
+Scenario: the glider
+
+Given the grid looks like
+...X..
+..X...
+..XXX.
+......
+......
+When the next step occurs
+Then the grid should look like
+......
+..X.X.
+..XX..
+...X..
+......
+When the next step occurs
+Then the grid should look like
+......
+..X...
+..X.X.
+..XX..
+......
+When the next step occurs
+Then the grid should look like
+......
+...X..
+.XX...
+..XX..
+......
+When the next step occurs
+Then the grid should look like
+......
+..X...
+.X....
+.XXX..
+......
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/ICanCreateACell.story b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/ICanCreateACell.story
new file mode 100644
index 000000000..88895cb69
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/ICanCreateACell.story
@@ -0,0 +1,42 @@
+Story: I can create a cell
+
+As a game producer
+I want to create a cell
+So that I can show the grid to people
+
+Scenario: nothing to see here
+
+Given a 3 x 3 game
+Then the grid should look like
+...
+...
+...
+
+Scenario: all on its lonesome
+
+Given a 3 x 3 game
+When I create a cell at 1, 1
+Then the grid should look like
+...
+.X.
+...
+
+Scenario: the grid has three cells
+
+Given a 3 x 3 game
+When I create a cell at 0, 0
+and I create a cell at 0, 1
+and I create a cell at 2, 2
+Then the grid should look like
+XX.
+...
+..X
+
+Scenario: more cells more more
+
+Given the grid has three cells
+When I create a celll at 3, 1
+Then the grid should look like
+XX.
+..X
+..X
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/ICanKillACell.story b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/ICanKillACell.story
new file mode 100644
index 000000000..a9cf1ac64
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/ICanKillACell.story
@@ -0,0 +1,17 @@
+Story: I can kill a cell
+
+As a game producer
+I want to kill a cell
+So that when I make a mistake I dont have to start again
+
+Scenario: bang youre dead
+
+Given the grid looks like
+XX.
+.X.
+..X
+When I destroy the cell at 0, 1
+Then the grid should look like
+X..
+.X.
+..X
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/TheGridWraps.story b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/TheGridWraps.story
new file mode 100644
index 000000000..aeeede77d
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/TheGridWraps.story
@@ -0,0 +1,53 @@
+Story: The grid wraps
+
+As a game player
+I want the grid to wrap
+So that untidy stuff at the edges is avoided
+
+Scenario: crowded in the corners
+
+Given the grid looks like
+X.X
+...
+X.X
+When the next step is taken
+Then the grid should look like
+X.X
+...
+X.X
+
+
+Scenario: the glider returns
+
+Given the glider
+......
+..X...
+.X....
+.XXX..
+......
+When the next step is taken
+and the next step is taken
+and the next step is taken
+and the next step is taken
+Then the grid should look like
+......
+......
+.X....
+X.....
+XXX...
+When the next step is taken
+Then the grid should look like
+.X....
+......
+......
+X.X...
+XX....
+When the next step is taken
+Then the grid should look like
+XX....
+......
+......
+X.....
+X.X...
+
+
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/create_a_cell.rb b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/create_a_cell.rb
new file mode 100644
index 000000000..81f86baba
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/create_a_cell.rb
@@ -0,0 +1,52 @@
+require File.join(File.dirname(__FILE__), *%w[helper])
+
+Story "I can create a cell",
+ %(As a game producer
+ I want to create a cell
+ So that I can show the grid to people), :steps_for => :life do
+
+ Scenario "nothing to see here" do
+ Given "a game with dimensions", 3, 3 do |rows,cols|
+ @game = Game.new(rows,cols)
+ end
+
+ Then "the grid should look like", %(
+ ...
+ ...
+ ...
+ )
+ end
+
+ Scenario "all on its lonesome" do
+ Given "a game with dimensions", 2, 2
+ When "I create a cell at", 1, 1 do |row,col|
+ @game.create_at(row,col)
+ end
+ Then "the grid should look like", %(
+ ..
+ .X
+ )
+ end
+
+ Scenario "the grid has three cells" do
+ Given "a game with dimensions", 3, 3
+ When "I create a cell at", 0, 0
+ When "I create a cell at", 0, 1
+ When "I create a cell at", 2, 2
+ Then "the grid should look like", %(
+ XX.
+ ...
+ ..X
+ )
+ end
+
+ Scenario "more cells more more" do
+ GivenScenario "the grid has three cells"
+ When "I create a cell at", 2, 0
+ Then "the grid should look like", %(
+ XX.
+ ...
+ X.X
+ )
+ end
+end
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/helper.rb b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/helper.rb
new file mode 100644
index 000000000..70ed21ec5
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/helper.rb
@@ -0,0 +1,6 @@
+dir = File.dirname(__FILE__)
+$LOAD_PATH.unshift(File.expand_path("#{dir}/../../../../../../rspec/lib"))
+require 'spec'
+$LOAD_PATH.unshift(File.expand_path("#{dir}/../../"))
+require "#{dir}/../../life"
+require File.join(File.dirname(__FILE__), *%w[steps]) \ No newline at end of file
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/kill_a_cell.rb b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/kill_a_cell.rb
new file mode 100644
index 000000000..7ae2d912d
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/kill_a_cell.rb
@@ -0,0 +1,26 @@
+require File.join(File.dirname(__FILE__), *%w[helper])
+
+Story 'I can kill a cell',
+ %(As a game producer
+ I want to kill a cell
+ So that when I make a mistake I don't have to start again), :steps_for => :life do
+
+ Scenario "bang, you're dead" do
+
+ Given 'a game that looks like', %(
+ XX.
+ .X.
+ ..X
+ ) do |dots|
+ @game = Game.from_string dots
+ end
+ When 'I destroy the cell at', 0, 1 do |row,col|
+ @game.destroy_at(row,col)
+ end
+ Then 'the grid should look like', %(
+ X..
+ .X.
+ ..X
+ )
+ end
+end
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/steps.rb b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/steps.rb
new file mode 100644
index 000000000..793590d70
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/steps.rb
@@ -0,0 +1,5 @@
+steps_for :life do
+ Then "the grid should look like" do |dots|
+ @game.grid.should == Grid.from_string(dots)
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/stories.rb b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/stories.rb
new file mode 100644
index 000000000..e60fe01de
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/stories.rb
@@ -0,0 +1,3 @@
+require File.join(File.dirname(__FILE__), *%w[helper])
+require 'behaviour/stories/create_a_cell'
+require 'behaviour/stories/kill_a_cell'
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/stories.txt b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/stories.txt
new file mode 100644
index 000000000..d8f809be3
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/behaviour/stories/stories.txt
@@ -0,0 +1,22 @@
+Story: Show the game field
+ As a game player
+ I want to see the field
+ so that I can observe the progress of the organisms
+
+Scenario: an empty field
+ Given a new game starts
+ When the game displays the field
+ Then the field should be empty
+
+
+
+
+
+StoryBuilder story = stories.createStory().called("a story")
+ .asA("person")
+ .iWant("to do something")
+ .soThat("I can rule the world");
+story.addScenario().called("happy path").as()
+ .given("some context")
+ .when("some event happens")
+ .then("expect some outcome");
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/life.rb b/vendor/gems/rspec/examples/stories/game-of-life/life.rb
new file mode 100644
index 000000000..88263bd00
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/life.rb
@@ -0,0 +1,3 @@
+$: << File.dirname(__FILE__)
+require 'life/game'
+require 'life/grid'
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/life/game.rb b/vendor/gems/rspec/examples/stories/game-of-life/life/game.rb
new file mode 100644
index 000000000..5411b01bf
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/life/game.rb
@@ -0,0 +1,23 @@
+class Game
+ attr_accessor :grid
+ def initialize(rows,cols)
+ @grid = Grid.new(rows, cols)
+ end
+
+ def create_at(row,col)
+ @grid.create_at(row,col)
+ end
+
+ def destroy_at(row,col)
+ @grid.destroy_at(row, col)
+ end
+
+ def self.from_string(dots)
+ grid = Grid.from_string(dots)
+ game = new(grid.rows, grid.columns)
+ game.instance_eval do
+ @grid = grid
+ end
+ return game
+ end
+end
diff --git a/vendor/gems/rspec/examples/stories/game-of-life/life/grid.rb b/vendor/gems/rspec/examples/stories/game-of-life/life/grid.rb
new file mode 100644
index 000000000..aca23087c
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/game-of-life/life/grid.rb
@@ -0,0 +1,43 @@
+class Grid
+
+ attr_accessor :contents
+
+ def initialize(rows, cols)
+ @contents = []
+ rows.times do @contents << [0] * cols end
+ end
+
+ def rows
+ @contents.size
+ end
+
+ def columns
+ @contents[0].size
+ end
+
+ def ==(other)
+ self.contents == other.contents
+ end
+
+ def create_at(row,col)
+ @contents[row][col] = 1
+ end
+
+ def destroy_at(row,col)
+ @contents[row][col] = 0
+ end
+
+ def self.from_string(str)
+ row_strings = str.split(' ')
+ grid = new(row_strings.size, row_strings[0].size)
+
+ row_strings.each_with_index do |row, row_index|
+ row_chars = row.split(//)
+ row_chars.each_with_index do |col_char, col_index|
+ grid.create_at(row_index, col_index) if col_char == 'X'
+ end
+ end
+ return grid
+ end
+
+end
diff --git a/vendor/gems/rspec/examples/stories/helper.rb b/vendor/gems/rspec/examples/stories/helper.rb
new file mode 100644
index 000000000..2e825b278
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/helper.rb
@@ -0,0 +1,9 @@
+$:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
+require 'spec/story'
+
+# won't have to do this once plain_text_story_runner is moved into the library
+# require File.join(File.dirname(__FILE__), "plain_text_story_runner")
+
+Dir[File.join(File.dirname(__FILE__), "steps/*.rb")].each do |file|
+ require file
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/examples/stories/steps/addition_steps.rb b/vendor/gems/rspec/examples/stories/steps/addition_steps.rb
new file mode 100644
index 000000000..3f27095a9
--- /dev/null
+++ b/vendor/gems/rspec/examples/stories/steps/addition_steps.rb
@@ -0,0 +1,18 @@
+require File.expand_path("#{File.dirname(__FILE__)}/../helper")
+
+# This creates steps for :addition
+steps_for(:addition) do
+ Given("an addend of $addend") do |addend|
+ @adder ||= Adder.new
+ @adder << addend.to_i
+ end
+end
+
+# This appends to them
+steps_for(:addition) do
+ When("the addends are added") { @sum = @adder.sum }
+end
+
+steps_for(:more_addition) do
+ Then("the sum should be $sum") { |sum| @sum.should == sum.to_i }
+end
diff --git a/vendor/gems/rspec/failing_examples/README.txt b/vendor/gems/rspec/failing_examples/README.txt
new file mode 100644
index 000000000..38c667d92
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/README.txt
@@ -0,0 +1,7 @@
+"Why have failing examples?", you might ask.
+
+They allow us to see failure messages. RSpec wants to provide meaningful and helpful failure messages. The failures in this directory not only provide you a way of seeing the failure messages, but they provide RSpec's own specs a way of describing what they should look like and ensuring they stay correct.
+
+To see the types of messages you can expect, stand in this directory and run:
+
+../bin/spec ./*.rb \ No newline at end of file
diff --git a/vendor/gems/rspec/failing_examples/diffing_spec.rb b/vendor/gems/rspec/failing_examples/diffing_spec.rb
new file mode 100644
index 000000000..85e13e8c0
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/diffing_spec.rb
@@ -0,0 +1,36 @@
+describe "Running specs with --diff" do
+ it "should print diff of different strings" do
+ uk = <<-EOF
+RSpec is a
+behaviour driven development
+framework for Ruby
+EOF
+ usa = <<-EOF
+RSpec is a
+behavior driven development
+framework for Ruby
+EOF
+ usa.should == uk
+ end
+
+ class Animal
+ def initialize(name,species)
+ @name,@species = name,species
+ end
+
+ def inspect
+ <<-EOA
+<Animal
+name=#{@name},
+species=#{@species}
+>
+ EOA
+ end
+ end
+
+ it "should print diff of different objects' pretty representation" do
+ expected = Animal.new "bob", "giraffe"
+ actual = Animal.new "bob", "tortoise"
+ expected.should eql(actual)
+ end
+end
diff --git a/vendor/gems/rspec/failing_examples/failing_autogenerated_docstrings_example.rb b/vendor/gems/rspec/failing_examples/failing_autogenerated_docstrings_example.rb
new file mode 100644
index 000000000..8a7d2490e
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/failing_autogenerated_docstrings_example.rb
@@ -0,0 +1,19 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+# Run spec w/ -fs to see the output of this file
+
+describe "Failing examples with no descriptions" do
+
+ # description is auto-generated as "should equal(5)" based on the last #should
+ it do
+ 3.should equal(2)
+ 5.should equal(5)
+ end
+
+ it { 3.should be > 5 }
+
+ it { ["a"].should include("b") }
+
+ it { [1,2,3].should_not respond_to(:size) }
+
+end
diff --git a/vendor/gems/rspec/failing_examples/failure_in_setup.rb b/vendor/gems/rspec/failing_examples/failure_in_setup.rb
new file mode 100644
index 000000000..2a807a99a
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/failure_in_setup.rb
@@ -0,0 +1,10 @@
+describe "This example" do
+
+ before(:each) do
+ NonExistentClass.new
+ end
+
+ it "should be listed as failing in setup" do
+ end
+
+end
diff --git a/vendor/gems/rspec/failing_examples/failure_in_teardown.rb b/vendor/gems/rspec/failing_examples/failure_in_teardown.rb
new file mode 100644
index 000000000..6458ea2b8
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/failure_in_teardown.rb
@@ -0,0 +1,10 @@
+describe "This example" do
+
+ it "should be listed as failing in teardown" do
+ end
+
+ after(:each) do
+ NonExistentClass.new
+ end
+
+end
diff --git a/vendor/gems/rspec/failing_examples/mocking_example.rb b/vendor/gems/rspec/failing_examples/mocking_example.rb
new file mode 100644
index 000000000..caf2db036
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/mocking_example.rb
@@ -0,0 +1,40 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+describe "Mocker" do
+
+ it "should be able to call mock()" do
+ mock = mock("poke me")
+ mock.should_receive(:poke)
+ mock.poke
+ end
+
+ it "should fail when expected message not received" do
+ mock = mock("poke me")
+ mock.should_receive(:poke)
+ end
+
+ it "should fail when messages are received out of order" do
+ mock = mock("one two three")
+ mock.should_receive(:one).ordered
+ mock.should_receive(:two).ordered
+ mock.should_receive(:three).ordered
+ mock.one
+ mock.three
+ mock.two
+ end
+
+ it "should get yelled at when sending unexpected messages" do
+ mock = mock("don't talk to me")
+ mock.should_not_receive(:any_message_at_all)
+ mock.any_message_at_all
+ end
+
+ it "has a bug we need to fix" do
+ pending "here is the bug" do
+ # Actually, no. It's fixed. This will fail because it passes :-)
+ mock = mock("Bug")
+ mock.should_receive(:hello)
+ mock.hello
+ end
+ end
+end
diff --git a/vendor/gems/rspec/failing_examples/mocking_with_flexmock.rb b/vendor/gems/rspec/failing_examples/mocking_with_flexmock.rb
new file mode 100644
index 000000000..6e79ece0e
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/mocking_with_flexmock.rb
@@ -0,0 +1,26 @@
+# stub frameworks like to gum up Object, so this is deliberately
+# set NOT to run so that you don't accidentally run it when you
+# run this dir.
+
+# To run it, stand in this directory and say:
+#
+# RUN_FLEXMOCK_EXAMPLE=true ruby ../bin/spec mocking_with_flexmock.rb
+
+if ENV['RUN_FLEXMOCK_EXAMPLE']
+ Spec::Runner.configure do |config|
+ config.mock_with :flexmock
+ end
+
+ describe "Flexmocks" do
+ it "should fail when the expected message is received with wrong arguments" do
+ m = flexmock("now flex!")
+ m.should_receive(:msg).with("arg").once
+ m.msg("other arg")
+ end
+
+ it "should fail when the expected message is not received at all" do
+ m = flexmock("now flex!")
+ m.should_receive(:msg).with("arg").once
+ end
+ end
+end
diff --git a/vendor/gems/rspec/failing_examples/mocking_with_mocha.rb b/vendor/gems/rspec/failing_examples/mocking_with_mocha.rb
new file mode 100644
index 000000000..f14a1a3e5
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/mocking_with_mocha.rb
@@ -0,0 +1,25 @@
+# stub frameworks like to gum up Object, so this is deliberately
+# set NOT to run so that you don't accidentally run it when you
+# run this dir.
+
+# To run it, stand in this directory and say:
+#
+# RUN_MOCHA_EXAMPLE=true ruby ../bin/spec mocking_with_mocha.rb
+
+if ENV['RUN_MOCHA_EXAMPLE']
+ Spec::Runner.configure do |config|
+ config.mock_with :mocha
+ end
+ describe "Mocha framework" do
+ it "should should be made available by saying config.mock_with :mocha" do
+ m = mock()
+ m.expects(:msg).with("arg")
+ m.msg
+ end
+ it "should should be made available by saying config.mock_with :mocha" do
+ o = Object.new
+ o.expects(:msg).with("arg")
+ o.msg
+ end
+ end
+end
diff --git a/vendor/gems/rspec/failing_examples/mocking_with_rr.rb b/vendor/gems/rspec/failing_examples/mocking_with_rr.rb
new file mode 100644
index 000000000..0d2b4fe04
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/mocking_with_rr.rb
@@ -0,0 +1,27 @@
+# stub frameworks like to gum up Object, so this is deliberately
+# set NOT to run so that you don't accidentally run it when you
+# run this dir.
+
+# To run it, stand in this directory and say:
+#
+# RUN_RR_EXAMPLE=true ruby ../bin/spec mocking_with_rr.rb
+
+if ENV['RUN_RR_EXAMPLE']
+ Spec::Runner.configure do |config|
+ config.mock_with :rr
+ end
+ describe "RR framework" do
+ it "should should be made available by saying config.mock_with :rr" do
+ o = Object.new
+ mock(o).msg("arg")
+ o.msg
+ end
+ it "should should be made available by saying config.mock_with :rr" do
+ o = Object.new
+ mock(o) do |m|
+ m.msg("arg")
+ end
+ o.msg
+ end
+ end
+end
diff --git a/vendor/gems/rspec/failing_examples/partial_mock_example.rb b/vendor/gems/rspec/failing_examples/partial_mock_example.rb
new file mode 100644
index 000000000..6d0554055
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/partial_mock_example.rb
@@ -0,0 +1,20 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+class MockableClass
+ def self.find id
+ return :original_return
+ end
+end
+
+describe "A partial mock" do
+
+ it "should work at the class level (but fail here due to the type mismatch)" do
+ MockableClass.should_receive(:find).with(1).and_return {:stub_return}
+ MockableClass.find("1").should equal(:stub_return)
+ end
+
+ it "should revert to the original after each spec" do
+ MockableClass.find(1).should equal(:original_return)
+ end
+
+end
diff --git a/vendor/gems/rspec/failing_examples/predicate_example.rb b/vendor/gems/rspec/failing_examples/predicate_example.rb
new file mode 100644
index 000000000..53b6367e2
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/predicate_example.rb
@@ -0,0 +1,29 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+class BddFramework
+ def intuitive?
+ true
+ end
+
+ def adopted_quickly?
+ #this will cause failures because it reallly SHOULD be adopted quickly
+ false
+ end
+end
+
+describe "BDD framework" do
+
+ before(:each) do
+ @bdd_framework = BddFramework.new
+ end
+
+ it "should be adopted quickly" do
+ #this will fail because it reallly SHOULD be adopted quickly
+ @bdd_framework.should be_adopted_quickly
+ end
+
+ it "should be intuitive" do
+ @bdd_framework.should be_intuitive
+ end
+
+end
diff --git a/vendor/gems/rspec/failing_examples/raising_example.rb b/vendor/gems/rspec/failing_examples/raising_example.rb
new file mode 100644
index 000000000..e40b51ec8
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/raising_example.rb
@@ -0,0 +1,47 @@
+describe "This example" do
+
+ it "should show that a NoMethodError is raised but an Exception was expected" do
+ proc { ''.nonexistent_method }.should raise_error
+ end
+
+ it "should pass" do
+ proc { ''.nonexistent_method }.should raise_error(NoMethodError)
+ end
+
+ it "should show that a NoMethodError is raised but a SyntaxError was expected" do
+ proc { ''.nonexistent_method }.should raise_error(SyntaxError)
+ end
+
+ it "should show that nothing is raised when SyntaxError was expected" do
+ proc { }.should raise_error(SyntaxError)
+ end
+
+ it "should show that a NoMethodError is raised but a Exception was expected" do
+ proc { ''.nonexistent_method }.should_not raise_error
+ end
+
+ it "should show that a NoMethodError is raised" do
+ proc { ''.nonexistent_method }.should_not raise_error(NoMethodError)
+ end
+
+ it "should also pass" do
+ proc { ''.nonexistent_method }.should_not raise_error(SyntaxError)
+ end
+
+ it "should show that a NoMethodError is raised when nothing expected" do
+ proc { ''.nonexistent_method }.should_not raise_error(Exception)
+ end
+
+ it "should show that the wrong message was received" do
+ proc { raise StandardError.new("what is an enterprise?") }.should raise_error(StandardError, "not this")
+ end
+
+ it "should show that the unexpected error/message was thrown" do
+ proc { raise StandardError.new("abc") }.should_not raise_error(StandardError, "abc")
+ end
+
+ it "should pass too" do
+ proc { raise StandardError.new("abc") }.should_not raise_error(StandardError, "xyz")
+ end
+
+end
diff --git a/vendor/gems/rspec/failing_examples/spec_helper.rb b/vendor/gems/rspec/failing_examples/spec_helper.rb
new file mode 100644
index 000000000..f8d657554
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/spec_helper.rb
@@ -0,0 +1,3 @@
+lib_path = File.expand_path("#{File.dirname(__FILE__)}/../lib")
+$LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
+require "spec"
diff --git a/vendor/gems/rspec/failing_examples/syntax_error_example.rb b/vendor/gems/rspec/failing_examples/syntax_error_example.rb
new file mode 100644
index 000000000..c9bb90774
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/syntax_error_example.rb
@@ -0,0 +1,7 @@
+describe "when passing a block to a matcher" do
+ it "you should use {} instead of do/end" do
+ Object.new.should satisfy do
+ "this block is being passed to #should instead of #satisfy - use {} instead"
+ end
+ end
+end
diff --git a/vendor/gems/rspec/failing_examples/team_spec.rb b/vendor/gems/rspec/failing_examples/team_spec.rb
new file mode 100644
index 000000000..41a44e551
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/team_spec.rb
@@ -0,0 +1,44 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+
+class Team
+ attr_reader :players
+ def initialize
+ @players = Players.new
+ end
+end
+
+class Players
+ def initialize
+ @players = []
+ end
+ def size
+ @players.size
+ end
+ def include? player
+ raise "player must be a string" unless player.is_a?(String)
+ @players.include? player
+ end
+end
+
+describe "A new team" do
+
+ before(:each) do
+ @team = Team.new
+ end
+
+ it "should have 3 players (failing example)" do
+ @team.should have(3).players
+ end
+
+ it "should include some player (failing example)" do
+ @team.players.should include("Some Player")
+ end
+
+ it "should include 5 (failing example)" do
+ @team.players.should include(5)
+ end
+
+ it "should have no players"
+
+end
diff --git a/vendor/gems/rspec/failing_examples/timeout_behaviour.rb b/vendor/gems/rspec/failing_examples/timeout_behaviour.rb
new file mode 100644
index 000000000..18221365f
--- /dev/null
+++ b/vendor/gems/rspec/failing_examples/timeout_behaviour.rb
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+describe "Something really slow" do
+ it "should be failed by RSpec when it takes longer than --timeout" do
+ sleep(2)
+ end
+end
diff --git a/vendor/gems/rspec/lib/autotest/discover.rb b/vendor/gems/rspec/lib/autotest/discover.rb
new file mode 100644
index 000000000..81914c3b7
--- /dev/null
+++ b/vendor/gems/rspec/lib/autotest/discover.rb
@@ -0,0 +1,3 @@
+Autotest.add_discovery do
+ "rspec" if File.exist?('spec')
+end
diff --git a/vendor/gems/rspec/lib/autotest/rspec.rb b/vendor/gems/rspec/lib/autotest/rspec.rb
new file mode 100644
index 000000000..9c97d2e0d
--- /dev/null
+++ b/vendor/gems/rspec/lib/autotest/rspec.rb
@@ -0,0 +1,74 @@
+require 'autotest'
+
+Autotest.add_hook :initialize do |at|
+ at.clear_mappings
+ # watch out: Ruby bug (1.8.6):
+ # %r(/) != /\//
+ at.add_mapping(%r%^spec/.*\.rb$%) { |filename, _|
+ filename
+ }
+ at.add_mapping(%r%^lib/(.*)\.rb$%) { |_, m|
+ ["spec/#{m[1]}_spec.rb"]
+ }
+ at.add_mapping(%r%^spec/(spec_helper|shared/.*)\.rb$%) {
+ at.files_matching %r%^spec/.*_spec\.rb$%
+ }
+end
+
+class RspecCommandError < StandardError; end
+
+class Autotest::Rspec < Autotest
+
+ def initialize
+ super
+
+ self.failed_results_re = /^\d+\)\n(?:\e\[\d*m)?(?:.*?Error in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n(.*?)\n\n/m
+ self.completed_re = /\Z/ # FIX: some sort of summary line at the end?
+ end
+
+ def consolidate_failures(failed)
+ filters = Hash.new { |h,k| h[k] = [] }
+ failed.each do |spec, failed_trace|
+ if f = test_files_for(failed).find { |f| failed_trace =~ Regexp.new(f) } then
+ filters[f] << spec
+ break
+ end
+ end
+ return filters
+ end
+
+ def make_test_cmd(files_to_test)
+ return "#{ruby} -S #{spec_command} #{add_options_if_present} #{files_to_test.keys.flatten.join(' ')}"
+ end
+
+ def add_options_if_present
+ File.exist?("spec/spec.opts") ? "-O spec/spec.opts " : ""
+ end
+
+ # Finds the proper spec command to use. Precendence is set in the
+ # lazily-evaluated method spec_commands. Alias + Override that in
+ # ~/.autotest to provide a different spec command then the default
+ # paths provided.
+ def spec_command(separator=File::ALT_SEPARATOR)
+ unless defined? @spec_command then
+ @spec_command = spec_commands.find { |cmd| File.exists? cmd }
+
+ raise RspecCommandError, "No spec command could be found!" unless @spec_command
+
+ @spec_command.gsub! File::SEPARATOR, separator if separator
+ end
+ @spec_command
+ end
+
+ # Autotest will look for spec commands in the following
+ # locations, in this order:
+ #
+ # * bin/spec
+ # * default spec bin/loader installed in Rubygems
+ def spec_commands
+ [
+ File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'spec')),
+ File.join(Config::CONFIG['bindir'], 'spec')
+ ]
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec.rb b/vendor/gems/rspec/lib/spec.rb
new file mode 100644
index 000000000..c143aa885
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec.rb
@@ -0,0 +1,30 @@
+require 'spec/version'
+require 'spec/matchers'
+require 'spec/expectations'
+require 'spec/example'
+require 'spec/extensions'
+require 'spec/runner'
+
+if Object.const_defined?(:Test); \
+ require 'spec/interop/test'; \
+end
+
+module Spec
+ class << self
+ def run?
+ @run || rspec_options.examples_run?
+ end
+
+ def run; \
+ return true if run?; \
+ result = rspec_options.run_examples; \
+ @run = true; \
+ result; \
+ end
+ attr_writer :run
+
+ def exit?; \
+ !Object.const_defined?(:Test) || Test::Unit.run?; \
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/lib/spec/example.rb b/vendor/gems/rspec/lib/spec/example.rb
new file mode 100644
index 000000000..39ff76b99
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/example.rb
@@ -0,0 +1,12 @@
+require 'timeout'
+require 'forwardable'
+require 'spec/example/pending'
+require 'spec/example/module_reopening_fix'
+require 'spec/example/example_group_methods'
+require 'spec/example/example_methods'
+require 'spec/example/example_group'
+require 'spec/example/shared_example_group'
+require 'spec/example/example_group_factory'
+require 'spec/example/errors'
+require 'spec/example/configuration'
+require 'spec/example/example_matcher'
diff --git a/spec/lib/spec/dsl/configuration.rb b/vendor/gems/rspec/lib/spec/example/configuration.rb
index 709574ded..674184727 100755
--- a/spec/lib/spec/dsl/configuration.rb
+++ b/vendor/gems/rspec/lib/spec/example/configuration.rb
@@ -1,7 +1,6 @@
module Spec
- module DSL
+ module Example
class Configuration
-
# Chooses what mock framework to use. Example:
#
# Spec::Runner.configure do |config|
@@ -36,49 +35,35 @@ module Spec
@mock_framework ||= mock_framework_path("rspec")
end
- # Declares modules to be included in all behaviours (<tt>describe</tt> blocks).
+ # Declares modules to be included in all example groups (<tt>describe</tt> blocks).
#
# config.include(My::Bottle, My::Cup)
#
- # If you want to restrict the inclusion to a subset of all the behaviours then
+ # If you want to restrict the inclusion to a subset of all the example groups then
# specify this in a Hash as the last argument:
#
- # config.include(My::Pony, My::Horse, :behaviour_type => :farm)
+ # config.include(My::Pony, My::Horse, :type => :farm)
#
- # Only behaviours that have that type will get the modules included:
+ # Only example groups that have that type will get the modules included:
#
- # describe "Downtown", :behaviour_type => :city do
+ # describe "Downtown", :type => :city do
# # Will *not* get My::Pony and My::Horse included
# end
#
- # describe "Old Mac Donald", :behaviour_type => :farm do
+ # describe "Old Mac Donald", :type => :farm do
# # *Will* get My::Pony and My::Horse included
# end
#
def include(*args)
args << {} unless Hash === args.last
modules, options = args_and_options(*args)
- required_behaviour_type = options[:behaviour_type]
- required_behaviour_type = required_behaviour_type.to_sym unless required_behaviour_type.nil?
- @modules ||= {}
- @modules[required_behaviour_type] ||= []
- @modules[required_behaviour_type] += modules
- end
-
- def modules_for(required_behaviour_type) #:nodoc:
- @modules ||= {}
- modules = @modules[nil] || [] # general ones
- modules << @modules[required_behaviour_type.to_sym] unless required_behaviour_type.nil?
- modules.uniq.compact
- end
-
- # This is just for cleanup in RSpec's own examples
- def exclude(*modules) #:nodoc:
- @modules.each do |behaviour_type, mods|
- modules.each{|m| mods.delete(m)}
+ required_example_group = get_type_from_options(options)
+ required_example_group = required_example_group.to_sym if required_example_group
+ modules.each do |mod|
+ ExampleGroupFactory.get(required_example_group).send(:include, mod)
end
end
-
+
# Defines global predicate matchers. Example:
#
# config.predicate_matchers[:swim] = :can_swim?
@@ -91,45 +76,69 @@ module Spec
@predicate_matchers ||= {}
end
- # Prepends a global <tt>before</tt> block to all behaviours.
+ # Prepends a global <tt>before</tt> block to all example groups.
# See #append_before for filtering semantics.
def prepend_before(*args, &proc)
- Behaviour.prepend_before(*args, &proc)
+ scope, options = scope_and_options(*args)
+ example_group = ExampleGroupFactory.get(
+ get_type_from_options(options)
+ )
+ example_group.prepend_before(scope, &proc)
end
- # Appends a global <tt>before</tt> block to all behaviours.
+ # Appends a global <tt>before</tt> block to all example groups.
#
- # If you want to restrict the block to a subset of all the behaviours then
+ # If you want to restrict the block to a subset of all the example groups then
# specify this in a Hash as the last argument:
#
- # config.prepend_before(:all, :behaviour_type => :farm)
+ # config.prepend_before(:all, :type => :farm)
#
# or
#
- # config.prepend_before(:behaviour_type => :farm)
+ # config.prepend_before(:type => :farm)
#
def append_before(*args, &proc)
- Behaviour.append_before(*args, &proc)
+ scope, options = scope_and_options(*args)
+ example_group = ExampleGroupFactory.get(
+ get_type_from_options(options)
+ )
+ example_group.append_before(scope, &proc)
end
alias_method :before, :append_before
- # Prepends a global <tt>after</tt> block to all behaviours.
+ # Prepends a global <tt>after</tt> block to all example groups.
# See #append_before for filtering semantics.
def prepend_after(*args, &proc)
- Behaviour.prepend_after(*args, &proc)
+ scope, options = scope_and_options(*args)
+ example_group = ExampleGroupFactory.get(
+ get_type_from_options(options)
+ )
+ example_group.prepend_after(scope, &proc)
end
alias_method :after, :prepend_after
- # Appends a global <tt>after</tt> block to all behaviours.
+ # Appends a global <tt>after</tt> block to all example groups.
# See #append_before for filtering semantics.
def append_after(*args, &proc)
- Behaviour.append_after(*args, &proc)
+ scope, options = scope_and_options(*args)
+ example_group = ExampleGroupFactory.get(
+ get_type_from_options(options)
+ )
+ example_group.append_after(scope, &proc)
end
private
+
+ def scope_and_options(*args)
+ args, options = args_and_options(*args)
+ scope = (args[0] || :each), options
+ end
+
+ def get_type_from_options(options)
+ options[:type] || options[:behaviour_type]
+ end
def mock_framework_path(framework_name)
File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "plugins", "mock_frameworks", framework_name))
end
-
end
end
end
diff --git a/spec/lib/spec/dsl/errors.rb b/vendor/gems/rspec/lib/spec/example/errors.rb
index ba7046a89..c6cb22453 100644
--- a/spec/lib/spec/dsl/errors.rb
+++ b/vendor/gems/rspec/lib/spec/example/errors.rb
@@ -1,9 +1,9 @@
module Spec
- module DSL
+ module Example
class ExamplePendingError < StandardError
end
- class PendingFixedError < StandardError
+ class PendingExampleFixedError < StandardError
end
end
end
diff --git a/vendor/gems/rspec/lib/spec/example/example_group.rb b/vendor/gems/rspec/lib/spec/example/example_group.rb
new file mode 100644
index 000000000..d6e156f93
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/example/example_group.rb
@@ -0,0 +1,16 @@
+module Spec
+ module Example
+ # The superclass for all regular RSpec examples.
+ class ExampleGroup
+ extend Spec::Example::ExampleGroupMethods
+ include Spec::Example::ExampleMethods
+
+ def initialize(defined_description, &implementation)
+ @_defined_description = defined_description
+ @_implementation = implementation
+ end
+ end
+ end
+end
+
+Spec::ExampleGroup = Spec::Example::ExampleGroup
diff --git a/vendor/gems/rspec/lib/spec/example/example_group_factory.rb b/vendor/gems/rspec/lib/spec/example/example_group_factory.rb
new file mode 100755
index 000000000..0414a3b96
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/example/example_group_factory.rb
@@ -0,0 +1,62 @@
+module Spec
+ module Example
+ class ExampleGroupFactory
+ class << self
+ def reset
+ @example_group_types = nil
+ default(ExampleGroup)
+ end
+
+ # Registers an example group class +klass+ with the symbol
+ # +type+. For example:
+ #
+ # Spec::Example::ExampleGroupFactory.register(:farm, Spec::Farm::Example::FarmExampleGroup)
+ #
+ # This will cause Main#describe from a file living in
+ # <tt>spec/farm</tt> to create example group instances of type
+ # Spec::Farm::Example::FarmExampleGroup.
+ def register(id, example_group_class)
+ @example_group_types[id] = example_group_class
+ end
+
+ # Sets the default ExampleGroup class
+ def default(example_group_class)
+ old = @example_group_types
+ @example_group_types = Hash.new(example_group_class)
+ @example_group_types.merge(old) if old
+ end
+
+ def get(id=nil)
+ if @example_group_types.values.include?(id)
+ id
+ else
+ @example_group_types[id]
+ end
+ end
+
+ def create_example_group(*args, &block)
+ opts = Hash === args.last ? args.last : {}
+ if opts[:shared]
+ SharedExampleGroup.new(*args, &block)
+ else
+ superclass = determine_superclass(opts)
+ superclass.describe(*args, &block)
+ end
+ end
+
+ protected
+
+ def determine_superclass(opts)
+ id = if opts[:type]
+ opts[:type]
+ elsif opts[:spec_path] =~ /spec(\\|\/)(#{@example_group_types.keys.join('|')})/
+ $2 == '' ? nil : $2.to_sym
+ end
+ get(id)
+ end
+
+ end
+ self.reset
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/example/example_group_methods.rb b/vendor/gems/rspec/lib/spec/example/example_group_methods.rb
new file mode 100644
index 000000000..a348bc74b
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/example/example_group_methods.rb
@@ -0,0 +1,424 @@
+module Spec
+ module Example
+
+ module ExampleGroupMethods
+ class << self
+ def description_text(*args)
+ args.inject("") do |result, arg|
+ result << " " unless (result == "" || arg.to_s =~ /^(\s|\.|#)/)
+ result << arg.to_s
+ end
+ end
+ end
+
+ attr_reader :description_text, :description_args, :description_options, :spec_path, :registration_binding_block
+
+ def inherited(klass)
+ super
+ klass.register {}
+ Spec::Runner.register_at_exit_hook
+ end
+
+ # Makes the describe/it syntax available from a class. For example:
+ #
+ # class StackSpec < Spec::ExampleGroup
+ # describe Stack, "with no elements"
+ #
+ # before
+ # @stack = Stack.new
+ # end
+ #
+ # it "should raise on pop" do
+ # lambda{ @stack.pop }.should raise_error
+ # end
+ # end
+ #
+ def describe(*args, &example_group_block)
+ if example_group_block
+ self.subclass("Subclass") do
+ describe(*args)
+ module_eval(&example_group_block)
+ end
+ else
+ set_description(*args)
+ before_eval
+ self
+ end
+ end
+
+ # Use this to pull in examples from shared example groups.
+ # See Spec::Runner for information about shared example groups.
+ def it_should_behave_like(shared_example_group)
+ case shared_example_group
+ when SharedExampleGroup
+ include shared_example_group
+ else
+ example_group = SharedExampleGroup.find_shared_example_group(shared_example_group)
+ unless example_group
+ raise RuntimeError.new("Shared Example Group '#{shared_example_group}' can not be found")
+ end
+ include(example_group)
+ end
+ end
+
+ # :call-seq:
+ # predicate_matchers[matcher_name] = method_on_object
+ # predicate_matchers[matcher_name] = [method1_on_object, method2_on_object]
+ #
+ # Dynamically generates a custom matcher that will match
+ # a predicate on your class. RSpec provides a couple of these
+ # out of the box:
+ #
+ # exist (or state expectations)
+ # File.should exist("path/to/file")
+ #
+ # an_instance_of (for mock argument constraints)
+ # mock.should_receive(:message).with(an_instance_of(String))
+ #
+ # == Examples
+ #
+ # class Fish
+ # def can_swim?
+ # true
+ # end
+ # end
+ #
+ # describe Fish do
+ # predicate_matchers[:swim] = :can_swim?
+ # it "should swim" do
+ # Fish.new.should swim
+ # end
+ # end
+ def predicate_matchers
+ @predicate_matchers ||= {:an_instance_of => :is_a?}
+ end
+
+ # Creates an instance of Spec::Example::Example and adds
+ # it to a collection of examples of the current example group.
+ def it(description=nil, &implementation)
+ e = new(description, &implementation)
+ example_objects << e
+ e
+ end
+
+ alias_method :specify, :it
+
+ # Use this to temporarily disable an example.
+ def xit(description=nil, opts={}, &block)
+ Kernel.warn("Example disabled: #{description}")
+ end
+
+ def run
+ examples = examples_to_run
+ return true if examples.empty?
+ reporter.add_example_group(self)
+ return dry_run(examples) if dry_run?
+
+ plugin_mock_framework
+ define_methods_from_predicate_matchers
+
+ success, before_all_instance_variables = run_before_all
+ success, after_all_instance_variables = execute_examples(success, before_all_instance_variables, examples)
+ success = run_after_all(success, after_all_instance_variables)
+ end
+
+ def description
+ result = ExampleGroupMethods.description_text(*description_parts)
+ if result.nil? || result == ""
+ return to_s
+ else
+ result
+ end
+ end
+
+ def described_type
+ description_parts.find {|part| part.is_a?(Module)}
+ end
+
+ def description_parts #:nodoc:
+ parts = []
+ execute_in_class_hierarchy do |example_group|
+ parts << example_group.description_args
+ end
+ parts.flatten.compact
+ end
+
+ def set_description(*args)
+ args, options = args_and_options(*args)
+ @description_args = args
+ @description_options = options
+ @description_text = ExampleGroupMethods.description_text(*args)
+ @spec_path = File.expand_path(options[:spec_path]) if options[:spec_path]
+ if described_type.class == Module
+ include described_type
+ end
+ self
+ end
+
+ def examples #:nodoc:
+ examples = example_objects.dup
+ add_method_examples(examples)
+ rspec_options.reverse ? examples.reverse : examples
+ end
+
+ def number_of_examples #:nodoc:
+ examples.length
+ end
+
+ # Registers a block to be executed before each example.
+ # This method prepends +block+ to existing before blocks.
+ def prepend_before(*args, &block)
+ scope, options = scope_and_options(*args)
+ parts = before_parts_from_scope(scope)
+ parts.unshift(block)
+ end
+
+ # Registers a block to be executed before each example.
+ # This method appends +block+ to existing before blocks.
+ def append_before(*args, &block)
+ scope, options = scope_and_options(*args)
+ parts = before_parts_from_scope(scope)
+ parts << block
+ end
+ alias_method :before, :append_before
+
+ # Registers a block to be executed after each example.
+ # This method prepends +block+ to existing after blocks.
+ def prepend_after(*args, &block)
+ scope, options = scope_and_options(*args)
+ parts = after_parts_from_scope(scope)
+ parts.unshift(block)
+ end
+ alias_method :after, :prepend_after
+
+ # Registers a block to be executed after each example.
+ # This method appends +block+ to existing after blocks.
+ def append_after(*args, &block)
+ scope, options = scope_and_options(*args)
+ parts = after_parts_from_scope(scope)
+ parts << block
+ end
+
+ def remove_after(scope, &block)
+ after_each_parts.delete(block)
+ end
+
+ # Deprecated. Use before(:each)
+ def setup(&block)
+ before(:each, &block)
+ end
+
+ # Deprecated. Use after(:each)
+ def teardown(&block)
+ after(:each, &block)
+ end
+
+ def before_all_parts # :nodoc:
+ @before_all_parts ||= []
+ end
+
+ def after_all_parts # :nodoc:
+ @after_all_parts ||= []
+ end
+
+ def before_each_parts # :nodoc:
+ @before_each_parts ||= []
+ end
+
+ def after_each_parts # :nodoc:
+ @after_each_parts ||= []
+ end
+
+ # Only used from RSpec's own examples
+ def reset # :nodoc:
+ @before_all_parts = nil
+ @after_all_parts = nil
+ @before_each_parts = nil
+ @after_each_parts = nil
+ end
+
+ def register(&registration_binding_block)
+ @registration_binding_block = registration_binding_block
+ rspec_options.add_example_group self
+ end
+
+ def unregister #:nodoc:
+ rspec_options.remove_example_group self
+ end
+
+ def registration_backtrace
+ eval("caller", registration_binding_block.binding)
+ end
+
+ def run_before_each(example)
+ execute_in_class_hierarchy do |example_group|
+ example.eval_each_fail_fast(example_group.before_each_parts)
+ end
+ end
+
+ def run_after_each(example)
+ execute_in_class_hierarchy(:superclass_first) do |example_group|
+ example.eval_each_fail_slow(example_group.after_each_parts)
+ end
+ end
+
+ private
+ def dry_run(examples)
+ examples.each do |example|
+ rspec_options.reporter.example_started(example)
+ rspec_options.reporter.example_finished(example)
+ end
+ return true
+ end
+
+ def run_before_all
+ before_all = new("before(:all)")
+ begin
+ execute_in_class_hierarchy do |example_group|
+ before_all.eval_each_fail_fast(example_group.before_all_parts)
+ end
+ return [true, before_all.instance_variable_hash]
+ rescue Exception => e
+ reporter.failure(before_all, e)
+ return [false, before_all.instance_variable_hash]
+ end
+ end
+
+ def execute_examples(success, instance_variables, examples)
+ return [success, instance_variables] unless success
+
+ after_all_instance_variables = instance_variables
+ examples.each do |example_group_instance|
+ success &= example_group_instance.execute(rspec_options, instance_variables)
+ after_all_instance_variables = example_group_instance.instance_variable_hash
+ end
+ return [success, after_all_instance_variables]
+ end
+
+ def run_after_all(success, instance_variables)
+ after_all = new("after(:all)")
+ after_all.set_instance_variables_from_hash(instance_variables)
+ execute_in_class_hierarchy(:superclass_first) do |example_group|
+ after_all.eval_each_fail_slow(example_group.after_all_parts)
+ end
+ return success
+ rescue Exception => e
+ reporter.failure(after_all, e)
+ return false
+ end
+
+ def examples_to_run
+ all_examples = examples
+ return all_examples unless specified_examples?
+ all_examples.reject do |example|
+ matcher = ExampleMatcher.new(description.to_s, example.description)
+ !matcher.matches?(specified_examples)
+ end
+ end
+
+ def specified_examples?
+ specified_examples && !specified_examples.empty?
+ end
+
+ def specified_examples
+ rspec_options.examples
+ end
+
+ def reporter
+ rspec_options.reporter
+ end
+
+ def dry_run?
+ rspec_options.dry_run
+ end
+
+ def example_objects
+ @example_objects ||= []
+ end
+
+ def execute_in_class_hierarchy(superclass_last=false)
+ classes = []
+ current_class = self
+ while is_example_group?(current_class)
+ superclass_last ? classes << current_class : classes.unshift(current_class)
+ current_class = current_class.superclass
+ end
+ superclass_last ? classes << ExampleMethods : classes.unshift(ExampleMethods)
+
+ classes.each do |example_group|
+ yield example_group
+ end
+ end
+
+ def is_example_group?(klass)
+ Module === klass && klass.kind_of?(ExampleGroupMethods)
+ end
+
+ def plugin_mock_framework
+ case mock_framework = Spec::Runner.configuration.mock_framework
+ when Module
+ include mock_framework
+ else
+ require Spec::Runner.configuration.mock_framework
+ include Spec::Plugins::MockFramework
+ end
+ end
+
+ def define_methods_from_predicate_matchers # :nodoc:
+ all_predicate_matchers = predicate_matchers.merge(
+ Spec::Runner.configuration.predicate_matchers
+ )
+ all_predicate_matchers.each_pair do |matcher_method, method_on_object|
+ define_method matcher_method do |*args|
+ eval("be_#{method_on_object.to_s.gsub('?','')}(*args)")
+ end
+ end
+ end
+
+ def scope_and_options(*args)
+ args, options = args_and_options(*args)
+ scope = (args[0] || :each), options
+ end
+
+ def before_parts_from_scope(scope)
+ case scope
+ when :each; before_each_parts
+ when :all; before_all_parts
+ end
+ end
+
+ def after_parts_from_scope(scope)
+ case scope
+ when :each; after_each_parts
+ when :all; after_all_parts
+ end
+ end
+
+ def before_eval
+ end
+
+ def add_method_examples(examples)
+ instance_methods.sort.each do |method_name|
+ if example_method?(method_name)
+ examples << new(method_name) do
+ __send__(method_name)
+ end
+ end
+ end
+ end
+
+ def example_method?(method_name)
+ should_method?(method_name)
+ end
+
+ def should_method?(method_name)
+ !(method_name =~ /^should(_not)?$/) &&
+ method_name =~ /^should/ && (
+ instance_method(method_name).arity == 0 ||
+ instance_method(method_name).arity == -1
+ )
+ end
+ end
+
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/example/example_matcher.rb b/vendor/gems/rspec/lib/spec/example/example_matcher.rb
new file mode 100755
index 000000000..435eabf52
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/example/example_matcher.rb
@@ -0,0 +1,42 @@
+module Spec
+ module Example
+ class ExampleMatcher
+ def initialize(example_group_description, example_name)
+ @example_group_description = example_group_description
+ @example_name = example_name
+ end
+
+ def matches?(specified_examples)
+ specified_examples.each do |specified_example|
+ return true if matches_literal_example?(specified_example) || matches_example_not_considering_modules?(specified_example)
+ end
+ false
+ end
+
+ protected
+ def matches_literal_example?(specified_example)
+ specified_example =~ /(^#{example_group_regex} #{example_regexp}$|^#{example_group_regex}$|^#{example_group_with_before_all_regexp}$|^#{example_regexp}$)/
+ end
+
+ def matches_example_not_considering_modules?(specified_example)
+ specified_example =~ /(^#{example_group_regex_not_considering_modules} #{example_regexp}$|^#{example_group_regex_not_considering_modules}$|^#{example_regexp}$)/
+ end
+
+ def example_group_regex
+ Regexp.escape(@example_group_description)
+ end
+
+ def example_group_with_before_all_regexp
+ Regexp.escape("#{@example_group_description} before(:all)")
+ end
+
+ def example_group_regex_not_considering_modules
+ Regexp.escape(@example_group_description.split('::').last)
+ end
+
+ def example_regexp
+ Regexp.escape(@example_name)
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/example/example_methods.rb b/vendor/gems/rspec/lib/spec/example/example_methods.rb
new file mode 100644
index 000000000..babd31dfa
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/example/example_methods.rb
@@ -0,0 +1,106 @@
+module Spec
+ module Example
+ module ExampleMethods
+ extend ExampleGroupMethods
+ extend ModuleReopeningFix
+
+ PENDING_EXAMPLE_BLOCK = lambda {
+ raise Spec::Example::ExamplePendingError.new("Not Yet Implemented")
+ }
+
+ def execute(options, instance_variables)
+ options.reporter.example_started(self)
+ set_instance_variables_from_hash(instance_variables)
+
+ execution_error = nil
+ Timeout.timeout(options.timeout) do
+ begin
+ before_example
+ run_with_description_capturing
+ rescue Exception => e
+ execution_error ||= e
+ end
+ begin
+ after_example
+ rescue Exception => e
+ execution_error ||= e
+ end
+ end
+
+ options.reporter.example_finished(self, execution_error)
+ success = execution_error.nil? || ExamplePendingError === execution_error
+ end
+
+ def instance_variable_hash
+ instance_variables.inject({}) do |variable_hash, variable_name|
+ variable_hash[variable_name] = instance_variable_get(variable_name)
+ variable_hash
+ end
+ end
+
+ def violated(message="")
+ raise Spec::Expectations::ExpectationNotMetError.new(message)
+ end
+
+ def eval_each_fail_fast(procs) #:nodoc:
+ procs.each do |proc|
+ instance_eval(&proc)
+ end
+ end
+
+ def eval_each_fail_slow(procs) #:nodoc:
+ first_exception = nil
+ procs.each do |proc|
+ begin
+ instance_eval(&proc)
+ rescue Exception => e
+ first_exception ||= e
+ end
+ end
+ raise first_exception if first_exception
+ end
+
+ def description
+ @_defined_description || @_matcher_description || "NO NAME"
+ end
+
+ def set_instance_variables_from_hash(ivars)
+ ivars.each do |variable_name, value|
+ # Ruby 1.9 requires variable.to_s on the next line
+ unless ['@_implementation', '@_defined_description', '@_matcher_description', '@method_name'].include?(variable_name.to_s)
+ instance_variable_set variable_name, value
+ end
+ end
+ end
+
+ def run_with_description_capturing
+ begin
+ return instance_eval(&(@_implementation || PENDING_EXAMPLE_BLOCK))
+ ensure
+ @_matcher_description = Spec::Matchers.generated_description
+ Spec::Matchers.clear_generated_description
+ end
+ end
+
+ def implementation_backtrace
+ eval("caller", @_implementation)
+ end
+
+ protected
+ include Matchers
+ include Pending
+
+ def before_example
+ setup_mocks_for_rspec
+ self.class.run_before_each(self)
+ end
+
+ def after_example
+ self.class.run_after_each(self)
+ verify_mocks_for_rspec
+ ensure
+ teardown_mocks_for_rspec
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/example/module_reopening_fix.rb b/vendor/gems/rspec/lib/spec/example/module_reopening_fix.rb
new file mode 100644
index 000000000..dc01dd666
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/example/module_reopening_fix.rb
@@ -0,0 +1,21 @@
+module Spec
+ module Example
+ # This is a fix for ...Something in Ruby 1.8.6??... (Someone fill in here please - Aslak)
+ module ModuleReopeningFix
+ def child_modules
+ @child_modules ||= []
+ end
+
+ def included(mod)
+ child_modules << mod
+ end
+
+ def include(mod)
+ super
+ child_modules.each do |child_module|
+ child_module.__send__(:include, mod)
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/lib/spec/example/pending.rb b/vendor/gems/rspec/lib/spec/example/pending.rb
new file mode 100644
index 000000000..b1f27c866
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/example/pending.rb
@@ -0,0 +1,18 @@
+module Spec
+ module Example
+ module Pending
+ def pending(message = "TODO")
+ if block_given?
+ begin
+ yield
+ rescue Exception => e
+ raise Spec::Example::ExamplePendingError.new(message)
+ end
+ raise Spec::Example::PendingExampleFixedError.new("Expected pending '#{message}' to fail. No Error was raised.")
+ else
+ raise Spec::Example::ExamplePendingError.new(message)
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/example/shared_example_group.rb b/vendor/gems/rspec/lib/spec/example/shared_example_group.rb
new file mode 100644
index 000000000..a6fd6211c
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/example/shared_example_group.rb
@@ -0,0 +1,58 @@
+module Spec
+ module Example
+ class SharedExampleGroup < Module
+ class << self
+ def add_shared_example_group(new_example_group)
+ guard_against_redefining_existing_example_group(new_example_group)
+ shared_example_groups << new_example_group
+ end
+
+ def find_shared_example_group(example_group_description)
+ shared_example_groups.find do |b|
+ b.description == example_group_description
+ end
+ end
+
+ def shared_example_groups
+ # TODO - this needs to be global, or at least accessible from
+ # from subclasses of Example in a centralized place. I'm not loving
+ # this as a solution, but it works for now.
+ $shared_example_groups ||= []
+ end
+
+ private
+ def guard_against_redefining_existing_example_group(new_example_group)
+ existing_example_group = find_shared_example_group(new_example_group.description)
+ return unless existing_example_group
+ return if new_example_group.equal?(existing_example_group)
+ return if spec_path(new_example_group) == spec_path(existing_example_group)
+ raise ArgumentError.new("Shared Example '#{existing_example_group.description}' already exists")
+ end
+
+ def spec_path(example_group)
+ File.expand_path(example_group.spec_path)
+ end
+ end
+ include ExampleGroupMethods
+ public :include
+
+ def initialize(*args, &example_group_block)
+ describe(*args)
+ @example_group_block = example_group_block
+ self.class.add_shared_example_group(self)
+ end
+
+ def included(mod) # :nodoc:
+ mod.module_eval(&@example_group_block)
+ end
+
+ def execute_in_class_hierarchy(superclass_last=false)
+ classes = [self]
+ superclass_last ? classes << ExampleMethods : classes.unshift(ExampleMethods)
+ classes.each do |example_group|
+ yield example_group
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/spec/expectations.rb b/vendor/gems/rspec/lib/spec/expectations.rb
index 65ea47425..65ea47425 100644
--- a/spec/lib/spec/expectations.rb
+++ b/vendor/gems/rspec/lib/spec/expectations.rb
diff --git a/spec/lib/spec/expectations/differs/default.rb b/vendor/gems/rspec/lib/spec/expectations/differs/default.rb
index 87e59b3a6..a5eb1bb89 100644
--- a/spec/lib/spec/expectations/differs/default.rb
+++ b/vendor/gems/rspec/lib/spec/expectations/differs/default.rb
@@ -12,12 +12,8 @@ module Spec
# TODO add some rdoc
class Default
- def initialize(format=:unified,context_lines=nil,colour=nil)
-
- context_lines ||= 3
- colour ||= false
-
- @format,@context_lines,@colour = format,context_lines,colour
+ def initialize(options)
+ @options = options
end
# This is snagged from diff/lcs/ldiff.rb (which is a commandline tool)
@@ -31,17 +27,17 @@ module Spec
file_length_difference = 0
diffs.each do |piece|
begin
- hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, @context_lines,
+ hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, context_lines,
file_length_difference)
file_length_difference = hunk.file_length_difference
next unless oldhunk
# Hunks may overlap, which is why we need to be careful when our
# diff includes lines of context. Otherwise, we might print
# redundant lines.
- if (@context_lines > 0) and hunk.overlaps?(oldhunk)
+ if (context_lines > 0) and hunk.overlaps?(oldhunk)
hunk.unshift(oldhunk)
else
- output << oldhunk.diff(@format)
+ output << oldhunk.diff(format)
end
ensure
oldhunk = hunk
@@ -49,12 +45,21 @@ module Spec
end
end
#Handle the last remaining hunk
- output << oldhunk.diff(@format) << "\n"
+ output << oldhunk.diff(format) << "\n"
end
def diff_as_object(target,expected)
diff_as_string(PP.pp(target,""), PP.pp(expected,""))
end
+
+ protected
+ def format
+ @options.diff_format
+ end
+
+ def context_lines
+ @options.context_lines
+ end
end
end
end
diff --git a/vendor/gems/rspec/lib/spec/expectations/errors.rb b/vendor/gems/rspec/lib/spec/expectations/errors.rb
new file mode 100644
index 000000000..1fabd105d
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/expectations/errors.rb
@@ -0,0 +1,12 @@
+module Spec
+ module Expectations
+ # If Test::Unit is loaed, we'll use its error as baseclass, so that Test::Unit
+ # will report unmet RSpec expectations as failures rather than errors.
+ superclass = ['Test::Unit::AssertionFailedError', '::StandardError'].map do |c|
+ eval(c) rescue nil
+ end.compact.first
+
+ class ExpectationNotMetError < superclass
+ end
+ end
+end
diff --git a/spec/lib/spec/expectations/extensions.rb b/vendor/gems/rspec/lib/spec/expectations/extensions.rb
index 60c9b9e7d..60c9b9e7d 100644
--- a/spec/lib/spec/expectations/extensions.rb
+++ b/vendor/gems/rspec/lib/spec/expectations/extensions.rb
diff --git a/spec/lib/spec/expectations/extensions/object.rb b/vendor/gems/rspec/lib/spec/expectations/extensions/object.rb
index f59af722e..a3925bbee 100644
--- a/spec/lib/spec/expectations/extensions/object.rb
+++ b/vendor/gems/rspec/lib/spec/expectations/extensions/object.rb
@@ -3,7 +3,6 @@ module Spec
# rspec adds #should and #should_not to every Object (and,
# implicitly, every Class).
module ObjectExpectations
-
# :call-seq:
# should(matcher)
# should == expected
@@ -28,9 +27,12 @@ module Spec
#
# NOTE that this does NOT support receiver.should != expected.
# Instead, use receiver.should_not == expected
- def should(matcher=nil, &block)
- return ExpectationMatcherHandler.handle_matcher(self, matcher, &block) if matcher
- Spec::Matchers::PositiveOperatorMatcher.new(self)
+ def should(matcher = :default_parameter, &block)
+ if :default_parameter == matcher
+ Spec::Matchers::PositiveOperatorMatcher.new(self)
+ else
+ ExpectationMatcherHandler.handle_matcher(self, matcher, &block)
+ end
end
# :call-seq:
@@ -52,9 +54,12 @@ module Spec
# => Passes unless (receiver =~ regexp)
#
# See Spec::Matchers for more information about matchers
- def should_not(matcher=nil, &block)
- return NegativeExpectationMatcherHandler.handle_matcher(self, matcher, &block) if matcher
- Spec::Matchers::NegativeOperatorMatcher.new(self)
+ def should_not(matcher = :default_parameter, &block)
+ if :default_parameter == matcher
+ Spec::Matchers::NegativeOperatorMatcher.new(self)
+ else
+ NegativeExpectationMatcherHandler.handle_matcher(self, matcher, &block)
+ end
end
end
diff --git a/spec/lib/spec/expectations/extensions/string_and_symbol.rb b/vendor/gems/rspec/lib/spec/expectations/extensions/string_and_symbol.rb
index 29cfbddfa..29cfbddfa 100644
--- a/spec/lib/spec/expectations/extensions/string_and_symbol.rb
+++ b/vendor/gems/rspec/lib/spec/expectations/extensions/string_and_symbol.rb
diff --git a/spec/lib/spec/expectations/handler.rb b/vendor/gems/rspec/lib/spec/expectations/handler.rb
index 4caa321e4..e6dce0846 100644
--- a/spec/lib/spec/expectations/handler.rb
+++ b/vendor/gems/rspec/lib/spec/expectations/handler.rb
@@ -1,18 +1,23 @@
module Spec
module Expectations
+ class InvalidMatcherError < ArgumentError; end
module MatcherHandlerHelper
- def describe(matcher)
+ def describe_matcher(matcher)
matcher.respond_to?(:description) ? matcher.description : "[#{matcher.class.name} does not provide a description]"
end
end
- class ExpectationMatcherHandler
+ class ExpectationMatcherHandler
class << self
include MatcherHandlerHelper
def handle_matcher(actual, matcher, &block)
+ unless matcher.respond_to?(:matches?)
+ raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
+ end
+
match = matcher.matches?(actual, &block)
- ::Spec::Matchers.generated_description = "should #{describe(matcher)}"
+ ::Spec::Matchers.generated_description = "should #{describe_matcher(matcher)}"
Spec::Expectations.fail_with(matcher.failure_message) unless match
end
end
@@ -22,6 +27,10 @@ module Spec
class << self
include MatcherHandlerHelper
def handle_matcher(actual, matcher, &block)
+ unless matcher.respond_to?(:matches?)
+ raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
+ end
+
unless matcher.respond_to?(:negative_failure_message)
Spec::Expectations.fail_with(
<<-EOF
@@ -32,7 +41,7 @@ EOF
)
end
match = matcher.matches?(actual, &block)
- ::Spec::Matchers.generated_description = "should not #{describe(matcher)}"
+ ::Spec::Matchers.generated_description = "should not #{describe_matcher(matcher)}"
Spec::Expectations.fail_with(matcher.negative_failure_message) if match
end
end
diff --git a/vendor/gems/rspec/lib/spec/extensions.rb b/vendor/gems/rspec/lib/spec/extensions.rb
new file mode 100755
index 000000000..9a313d0e7
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/extensions.rb
@@ -0,0 +1,3 @@
+require 'spec/extensions/object'
+require 'spec/extensions/class'
+require 'spec/extensions/main'
diff --git a/vendor/gems/rspec/lib/spec/extensions/class.rb b/vendor/gems/rspec/lib/spec/extensions/class.rb
new file mode 100644
index 000000000..30730f87e
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/extensions/class.rb
@@ -0,0 +1,24 @@
+class Class
+ # Creates a new subclass of self, with a name "under" our own name.
+ # Example:
+ #
+ # x = Foo::Bar.subclass('Zap'){}
+ # x.name # => Foo::Bar::Zap_1
+ # x.superclass.name # => Foo::Bar
+ def subclass(base_name, &body)
+ klass = Class.new(self)
+ class_name = "#{base_name}_#{class_count!}"
+ instance_eval do
+ const_set(class_name, klass)
+ end
+ klass.instance_eval(&body)
+ klass
+ end
+
+ private
+ def class_count!
+ @class_count ||= 0
+ @class_count += 1
+ @class_count
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/lib/spec/extensions/main.rb b/vendor/gems/rspec/lib/spec/extensions/main.rb
new file mode 100644
index 000000000..281cbf879
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/extensions/main.rb
@@ -0,0 +1,102 @@
+module Spec
+ module Extensions
+ module Main
+ # Creates and returns a class that includes the ExampleGroupMethods
+ # module. Which ExampleGroup type is created depends on the directory of the file
+ # calling this method. For example, Spec::Rails will use different
+ # classes for specs living in <tt>spec/models</tt>,
+ # <tt>spec/helpers</tt>, <tt>spec/views</tt> and
+ # <tt>spec/controllers</tt>.
+ #
+ # It is also possible to override autodiscovery of the example group
+ # type with an options Hash as the last argument:
+ #
+ # describe "name", :type => :something_special do ...
+ #
+ # The reason for using different behaviour classes is to have different
+ # matcher methods available from within the <tt>describe</tt> block.
+ #
+ # See Spec::Example::ExampleFactory#register for details about how to
+ # register special implementations.
+ #
+ def describe(*args, &block)
+ raise ArgumentError if args.empty?
+ raise ArgumentError unless block
+ args << {} unless Hash === args.last
+ args.last[:spec_path] = caller(0)[1]
+ Spec::Example::ExampleGroupFactory.create_example_group(*args, &block)
+ end
+ alias :context :describe
+
+ # Creates an example group that can be shared by other example groups
+ #
+ # == Examples
+ #
+ # share_examples_for "All Editions" do
+ # it "all editions behaviour" ...
+ # end
+ #
+ # describe SmallEdition do
+ # it_should_behave_like "All Editions"
+ #
+ # it "should do small edition stuff" do
+ # ...
+ # end
+ # end
+ def share_examples_for(name, &block)
+ describe(name, :shared => true, &block)
+ end
+
+ alias :shared_examples_for :share_examples_for
+
+ # Creates a Shared Example Group and assigns it to a constant
+ #
+ # share_as :AllEditions do
+ # it "should do all editions stuff" ...
+ # end
+ #
+ # describe SmallEdition do
+ # it_should_behave_like AllEditions
+ #
+ # it "should do small edition stuff" do
+ # ...
+ # end
+ # end
+ #
+ # And, for those of you who prefer to use something more like Ruby, you
+ # can just include the module directly
+ #
+ # describe SmallEdition do
+ # include AllEditions
+ #
+ # it "should do small edition stuff" do
+ # ...
+ # end
+ # end
+ def share_as(name, &block)
+ begin
+ Object.const_set(name, share_examples_for(name, &block))
+ rescue NameError => e
+ raise NameError.new(e.message + "\nThe first argument to share_as must be a legal name for a constant\n")
+ end
+ end
+
+ private
+
+ def rspec_options
+ $rspec_options ||= begin; \
+ parser = ::Spec::Runner::OptionParser.new(STDERR, STDOUT); \
+ parser.order!(ARGV); \
+ $rspec_options = parser.options; \
+ end
+ $rspec_options
+ end
+
+ def init_rspec_options(options)
+ $rspec_options = options if $rspec_options.nil?
+ end
+ end
+ end
+end
+
+include Spec::Extensions::Main \ No newline at end of file
diff --git a/spec/lib/spec/extensions/object.rb b/vendor/gems/rspec/lib/spec/extensions/object.rb
index 6218aa770..e9f6364e2 100755
--- a/spec/lib/spec/extensions/object.rb
+++ b/vendor/gems/rspec/lib/spec/extensions/object.rb
@@ -3,4 +3,8 @@ class Object
options = Hash === args.last ? args.pop : {}
return args, options
end
-end
+
+ def metaclass
+ class << self; self; end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/interop/test.rb b/vendor/gems/rspec/lib/spec/interop/test.rb
new file mode 100644
index 000000000..afa16137b
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/interop/test.rb
@@ -0,0 +1,12 @@
+require 'test/unit'
+require 'test/unit/testresult'
+
+require 'spec/interop/test/unit/testcase'
+require 'spec/interop/test/unit/testsuite_adapter'
+require 'spec/interop/test/unit/autorunner'
+require 'spec/interop/test/unit/testresult'
+require 'spec/interop/test/unit/ui/console/testrunner'
+
+Spec::Example::ExampleGroupFactory.default(Test::Unit::TestCase)
+
+Test::Unit.run = true
diff --git a/vendor/gems/rspec/lib/spec/interop/test/unit/autorunner.rb b/vendor/gems/rspec/lib/spec/interop/test/unit/autorunner.rb
new file mode 100644
index 000000000..3944e6995
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/interop/test/unit/autorunner.rb
@@ -0,0 +1,6 @@
+class Test::Unit::AutoRunner
+ remove_method :process_args
+ def process_args(argv)
+ true
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/interop/test/unit/testcase.rb b/vendor/gems/rspec/lib/spec/interop/test/unit/testcase.rb
new file mode 100644
index 000000000..b32a820c1
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/interop/test/unit/testcase.rb
@@ -0,0 +1,61 @@
+require 'test/unit/testcase'
+
+module Test
+ module Unit
+ # This extension of the standard Test::Unit::TestCase makes RSpec
+ # available from within, so that you can do things like:
+ #
+ # require 'test/unit'
+ # require 'spec'
+ #
+ # class MyTest < Test::Unit::TestCase
+ # it "should work with Test::Unit assertions" do
+ # assert_equal 4, 2+1
+ # end
+ #
+ # def test_should_work_with_rspec_expectations
+ # (3+1).should == 5
+ # end
+ # end
+ #
+ # See also Spec::Example::ExampleGroup
+ class TestCase
+ extend Spec::Example::ExampleGroupMethods
+ include Spec::Example::ExampleMethods
+
+ before(:each) {setup}
+ after(:each) {teardown}
+
+ class << self
+ def suite
+ Test::Unit::TestSuiteAdapter.new(self)
+ end
+
+ def example_method?(method_name)
+ should_method?(method_name) || test_method?(method_name)
+ end
+
+ def test_method?(method_name)
+ method_name =~ /^test[_A-Z]./ && (
+ instance_method(method_name).arity == 0 ||
+ instance_method(method_name).arity == -1
+ )
+ end
+ end
+
+ def initialize(defined_description, &implementation)
+ @_defined_description = defined_description
+ @_implementation = implementation
+
+ @_result = ::Test::Unit::TestResult.new
+ # @method_name is important to set here because it "complies" with Test::Unit's interface.
+ # Some Test::Unit extensions depend on @method_name being present.
+ @method_name = @_defined_description
+ end
+
+ def run(ignore_this_argument=nil)
+ super()
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/interop/test/unit/testresult.rb b/vendor/gems/rspec/lib/spec/interop/test/unit/testresult.rb
new file mode 100644
index 000000000..1386dc728
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/interop/test/unit/testresult.rb
@@ -0,0 +1,6 @@
+class Test::Unit::TestResult
+ alias_method :tu_passed?, :passed?
+ def passed?
+ return tu_passed? & ::Spec.run
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/lib/spec/interop/test/unit/testsuite_adapter.rb b/vendor/gems/rspec/lib/spec/interop/test/unit/testsuite_adapter.rb
new file mode 100644
index 000000000..7c0ed092d
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/interop/test/unit/testsuite_adapter.rb
@@ -0,0 +1,34 @@
+module Test
+ module Unit
+ class TestSuiteAdapter < TestSuite
+ attr_reader :example_group, :examples
+ alias_method :tests, :examples
+ def initialize(example_group)
+ @example_group = example_group
+ @examples = example_group.examples
+ end
+
+ def name
+ example_group.description
+ end
+
+ def run(*args)
+ return true unless args.empty?
+ example_group.run
+ end
+
+ def size
+ example_group.number_of_examples
+ end
+
+ def delete(example)
+ examples.delete example
+ end
+
+ def empty?
+ examples.empty?
+ end
+ end
+ end
+end
+
diff --git a/vendor/gems/rspec/lib/spec/interop/test/unit/ui/console/testrunner.rb b/vendor/gems/rspec/lib/spec/interop/test/unit/ui/console/testrunner.rb
new file mode 100644
index 000000000..8e9995e02
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/interop/test/unit/ui/console/testrunner.rb
@@ -0,0 +1,61 @@
+require 'test/unit/ui/console/testrunner'
+
+module Test
+ module Unit
+ module UI
+ module Console
+ class TestRunner
+
+ alias_method :started_without_rspec, :started
+ def started_with_rspec(result)
+ @result = result
+ @need_to_output_started = true
+ end
+ alias_method :started, :started_with_rspec
+
+ alias_method :test_started_without_rspec, :test_started
+ def test_started_with_rspec(name)
+ if @need_to_output_started
+ if @rspec_io
+ @rspec_io.rewind
+ output(@rspec_io.read)
+ end
+ output("Started")
+ @need_to_output_started = false
+ end
+ test_started_without_rspec(name)
+ end
+ alias_method :test_started, :test_started_with_rspec
+
+ alias_method :test_finished_without_rspec, :test_finished
+ def test_finished_with_rspec(name)
+ test_finished_without_rspec(name)
+ @ran_test = true
+ end
+ alias_method :test_finished, :test_finished_with_rspec
+
+ alias_method :finished_without_rspec, :finished
+ def finished_with_rspec(elapsed_time)
+ @ran_test ||= false
+ if @ran_test
+ finished_without_rspec(elapsed_time)
+ end
+ end
+ alias_method :finished, :finished_with_rspec
+
+ alias_method :setup_mediator_without_rspec, :setup_mediator
+ def setup_mediator_with_rspec
+ orig_io = @io
+ @io = StringIO.new
+ setup_mediator_without_rspec
+ ensure
+ @rspec_io = @io
+ @io = orig_io
+ end
+ alias_method :setup_mediator, :setup_mediator_with_rspec
+
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/spec/matchers.rb b/vendor/gems/rspec/lib/spec/matchers.rb
index fd208d628..afae5ae5f 100644
--- a/spec/lib/spec/matchers.rb
+++ b/vendor/gems/rspec/lib/spec/matchers.rb
@@ -1,8 +1,10 @@
+require 'spec/matchers/simple_matcher'
require 'spec/matchers/be'
require 'spec/matchers/be_close'
require 'spec/matchers/change'
require 'spec/matchers/eql'
require 'spec/matchers/equal'
+require 'spec/matchers/exist'
require 'spec/matchers/has'
require 'spec/matchers/have'
require 'spec/matchers/include'
@@ -132,27 +134,15 @@ module Spec
#
module Matchers
module ModuleMethods
- def description_generated(callback)
- description_generated_callbacks << callback
- end
-
- def unregister_description_generated(callback)
- description_generated_callbacks.delete(callback)
- end
-
- def generated_description=(name)
- description_generated_callbacks.each do |callback|
- callback.call(name)
- end
- end
+ attr_accessor :generated_description
- private
- def description_generated_callbacks
- @description_generated_callbacks ||= []
+ def clear_generated_description
+ self.generated_description = nil
end
end
+
extend ModuleMethods
-
+
def method_missing(sym, *args, &block) # :nodoc:
return Matchers::Be.new(sym, *args) if sym.starts_with?("be_")
return Matchers::Has.new(sym, *args) if sym.starts_with?("have_")
diff --git a/spec/lib/spec/matchers/be.rb b/vendor/gems/rspec/lib/spec/matchers/be.rb
index 0eb1629a6..2b25b11f4 100644
--- a/spec/lib/spec/matchers/be.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/be.rb
@@ -3,14 +3,17 @@ module Spec
class Be #:nodoc:
def initialize(*args)
- @expected = parse_expected(args.shift)
+ if args.empty?
+ @expected = :satisfy_if
+ else
+ @expected = parse_expected(args.shift)
+ end
@args = args
@comparison = ""
end
def matches?(actual)
@actual = actual
- return true if match_or_compare unless handling_predicate?
if handling_predicate?
begin
return @result = actual.__send__(predicate, *@args)
@@ -28,8 +31,9 @@ module Spec
rescue
raise predicate_error
end
+ else
+ return match_or_compare
end
- return false
end
def failure_message
@@ -43,6 +47,7 @@ module Spec
end
def expected
+ return "if to be satisfied" if @expected == :satisfy_if
return true if @expected == :true
return false if @expected == :false
return "nil" if @expected == :nil
@@ -50,6 +55,7 @@ module Spec
end
def match_or_compare
+ return @actual ? true : false if @expected == :satisfy_if
return @actual == true if @expected == :true
return @actual == false if @expected == :false
return @actual.nil? if @expected == :nil
@@ -63,6 +69,7 @@ module Spec
end
def ==(expected)
+ @prefix = "be "
@double_equal = true
@comparison = "== "
@expected = expected
@@ -70,6 +77,7 @@ module Spec
end
def ===(expected)
+ @prefix = "be "
@triple_equal = true
@comparison = "=== "
@expected = expected
@@ -77,6 +85,7 @@ module Spec
end
def <(expected)
+ @prefix = "be "
@less_than = true
@comparison = "< "
@expected = expected
@@ -84,6 +93,7 @@ module Spec
end
def <=(expected)
+ @prefix = "be "
@less_than_or_equal = true
@comparison = "<= "
@expected = expected
@@ -91,6 +101,7 @@ module Spec
end
def >=(expected)
+ @prefix = "be "
@greater_than_or_equal = true
@comparison = ">= "
@expected = expected
@@ -98,6 +109,7 @@ module Spec
end
def >(expected)
+ @prefix = "be "
@greater_than = true
@comparison = "> "
@expected = expected
@@ -112,11 +124,14 @@ module Spec
def parse_expected(expected)
if Symbol === expected
@handling_predicate = true
- ["be_an_","be_a_","be_"].each do |@prefix|
- return "#{expected.to_s.sub(@prefix,"")}".to_sym if expected.starts_with?(@prefix)
+ ["be_an_","be_a_","be_"].each do |prefix|
+ if expected.starts_with?(prefix)
+ @prefix = prefix
+ return "#{expected.to_s.sub(@prefix,"")}".to_sym
+ end
end
end
- @prefix = "be "
+ @prefix = ""
return expected
end
@@ -169,6 +184,7 @@ module Spec
end
# :call-seq:
+ # should be
# should be_true
# should be_false
# should be_nil
@@ -177,7 +193,8 @@ module Spec
# should_not be_arbitrary_predicate(*args)
#
# Given true, false, or nil, will pass if actual is
- # true, false or nil (respectively).
+ # true, false or nil (respectively). Given no args means
+ # the caller should satisfy an if condition (to be or not to be).
#
# Predicates are any Ruby method that ends in a "?" and returns true or false.
# Given be_ followed by arbitrary_predicate (without the "?"), RSpec will match
@@ -189,6 +206,7 @@ module Spec
#
# == Examples
#
+ # target.should be
# target.should be_true
# target.should be_false
# target.should be_nil
diff --git a/spec/lib/spec/matchers/be_close.rb b/vendor/gems/rspec/lib/spec/matchers/be_close.rb
index 7763eb97e..7763eb97e 100644
--- a/spec/lib/spec/matchers/be_close.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/be_close.rb
diff --git a/spec/lib/spec/matchers/change.rb b/vendor/gems/rspec/lib/spec/matchers/change.rb
index 41a718aca..784e516ed 100644
--- a/spec/lib/spec/matchers/change.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/change.rb
@@ -21,6 +21,8 @@ EOF
return false if @from && (@from != @before)
return false if @to && (@to != @after)
return (@before + @amount == @after) if @amount
+ return ((@after - @before) >= @minimum) if @minimum
+ return ((@after - @before) <= @maximum) if @maximum
return @before != @after
end
@@ -37,6 +39,10 @@ EOF
"#{result} should have initially been #{@from.inspect}, but was #{@before.inspect}"
elsif @amount
"#{result} should have been changed by #{@amount.inspect}, but was changed by #{actual_delta.inspect}"
+ elsif @minimum
+ "#{result} should have been changed by at least #{@minimum.inspect}, but was changed by #{actual_delta.inspect}"
+ elsif @maximum
+ "#{result} should have been changed by at most #{@maximum.inspect}, but was changed by #{actual_delta.inspect}"
else
"#{result} should have changed, but is still #{@before.inspect}"
end
@@ -59,6 +65,16 @@ EOF
self
end
+ def by_at_least(minimum)
+ @minimum = minimum
+ self
+ end
+
+ def by_at_most(maximum)
+ @maximum = maximum
+ self
+ end
+
def to(to)
@to = to
self
@@ -88,6 +104,14 @@ EOF
# team.add_player(player)
# }.should change(roster, :count).by(1)
#
+ # lambda {
+ # team.add_player(player)
+ # }.should change(roster, :count).by_at_least(1)
+ #
+ # lambda {
+ # team.add_player(player)
+ # }.should change(roster, :count).by_at_most(1)
+ #
# string = "string"
# lambda {
# string.reverse
@@ -109,7 +133,7 @@ EOF
#
# == Warning
# +should_not+ +change+ only supports the form with no subsequent calls to
- # +be+, +to+ or +from+.
+ # +by+, +by_at_least+, +by_at_most+, +to+ or +from+.
#
# blocks passed to +should+ +change+ and +should_not+ +change+
# must use the <tt>{}</tt> form (<tt>do/end</tt> is not supported)
diff --git a/spec/lib/spec/matchers/eql.rb b/vendor/gems/rspec/lib/spec/matchers/eql.rb
index 280ca5454..280ca5454 100644
--- a/spec/lib/spec/matchers/eql.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/eql.rb
diff --git a/spec/lib/spec/matchers/equal.rb b/vendor/gems/rspec/lib/spec/matchers/equal.rb
index 4bfc74951..4bfc74951 100644
--- a/spec/lib/spec/matchers/equal.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/equal.rb
diff --git a/vendor/gems/rspec/lib/spec/matchers/exist.rb b/vendor/gems/rspec/lib/spec/matchers/exist.rb
new file mode 100644
index 000000000..a5a911132
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/matchers/exist.rb
@@ -0,0 +1,17 @@
+module Spec
+ module Matchers
+ class Exist
+ def matches? actual
+ @actual = actual
+ @actual.exist?
+ end
+ def failure_message
+ "expected #{@actual.inspect} to exist, but it doesn't."
+ end
+ def negative_failure_message
+ "expected #{@actual.inspect} to not exist, but it does."
+ end
+ end
+ def exist; Exist.new; end
+ end
+end
diff --git a/spec/lib/spec/matchers/has.rb b/vendor/gems/rspec/lib/spec/matchers/has.rb
index cc5a250b8..cc5a250b8 100644
--- a/spec/lib/spec/matchers/has.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/has.rb
diff --git a/spec/lib/spec/matchers/have.rb b/vendor/gems/rspec/lib/spec/matchers/have.rb
index f28b86ad3..47454e3be 100644
--- a/spec/lib/spec/matchers/have.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/have.rb
@@ -17,6 +17,7 @@ module Spec
def method_missing(sym, *args, &block)
@collection_name = sym
+ @plural_collection_name = Inflector.pluralize(sym.to_s) if Object.const_defined?(:Inflector)
@args = args
@block = block
self
@@ -25,6 +26,8 @@ module Spec
def matches?(collection_owner)
if collection_owner.respond_to?(@collection_name)
collection = collection_owner.send(@collection_name, *@args, &@block)
+ elsif (@plural_collection_name && collection_owner.respond_to?(@plural_collection_name))
+ collection = collection_owner.send(@plural_collection_name, *@args, &@block)
elsif (collection_owner.respond_to?(:length) || collection_owner.respond_to?(:size))
collection = collection_owner
else
diff --git a/spec/lib/spec/matchers/include.rb b/vendor/gems/rspec/lib/spec/matchers/include.rb
index 5476f97d8..5476f97d8 100644
--- a/spec/lib/spec/matchers/include.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/include.rb
diff --git a/spec/lib/spec/matchers/match.rb b/vendor/gems/rspec/lib/spec/matchers/match.rb
index 61ab52429..61ab52429 100644
--- a/spec/lib/spec/matchers/match.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/match.rb
diff --git a/spec/lib/spec/matchers/operator_matcher.rb b/vendor/gems/rspec/lib/spec/matchers/operator_matcher.rb
index 2d47ea85a..dd23a0994 100755
--- a/spec/lib/spec/matchers/operator_matcher.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/operator_matcher.rb
@@ -1,6 +1,7 @@
module Spec
module Matchers
class BaseOperatorMatcher
+ attr_reader :generated_description
def initialize(target)
@target = target
diff --git a/spec/lib/spec/matchers/raise_error.rb b/vendor/gems/rspec/lib/spec/matchers/raise_error.rb
index b45dcf65c..65eb4ddda 100644
--- a/spec/lib/spec/matchers/raise_error.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/raise_error.rb
@@ -21,27 +21,31 @@ module Spec
if @expected_message.nil?
@raised_expected_error = true
else
- case @expected_message
- when Regexp
- if @expected_message =~ @actual_error.message
- @raised_expected_error = true
- else
- @raised_other = true
- end
- else
- if @expected_message == @actual_error.message
- @raised_expected_error = true
- else
- @raised_other = true
- end
- end
+ verify_message
end
- rescue => @actual_error
+ rescue Exception => @actual_error
@raised_other = true
ensure
return @raised_expected_error
end
end
+
+ def verify_message
+ case @expected_message
+ when Regexp
+ if @expected_message =~ @actual_error.message
+ @raised_expected_error = true
+ else
+ @raised_other = true
+ end
+ else
+ if @expected_message == @actual_error.message
+ @raised_expected_error = true
+ else
+ @raised_other = true
+ end
+ end
+ end
def failure_message
return "expected #{expected_error}#{actual_error}" if @raised_other || !@raised_expected_error
diff --git a/spec/lib/spec/matchers/respond_to.rb b/vendor/gems/rspec/lib/spec/matchers/respond_to.rb
index 3d23422aa..3d23422aa 100644
--- a/spec/lib/spec/matchers/respond_to.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/respond_to.rb
diff --git a/spec/lib/spec/matchers/satisfy.rb b/vendor/gems/rspec/lib/spec/matchers/satisfy.rb
index 6c0ca95bc..6c0ca95bc 100644
--- a/spec/lib/spec/matchers/satisfy.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/satisfy.rb
diff --git a/vendor/gems/rspec/lib/spec/matchers/simple_matcher.rb b/vendor/gems/rspec/lib/spec/matchers/simple_matcher.rb
new file mode 100644
index 000000000..ac547d06a
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/matchers/simple_matcher.rb
@@ -0,0 +1,29 @@
+module Spec
+ module Matchers
+ class SimpleMatcher
+ attr_reader :description
+
+ def initialize(description, &match_block)
+ @description = description
+ @match_block = match_block
+ end
+
+ def matches?(actual)
+ @actual = actual
+ return @match_block.call(@actual)
+ end
+
+ def failure_message()
+ return %[expected #{@description.inspect} but got #{@actual.inspect}]
+ end
+
+ def negative_failure_message()
+ return %[expected not to get #{@description.inspect}, but got #{@actual.inspect}]
+ end
+ end
+
+ def simple_matcher(message, &match_block)
+ SimpleMatcher.new(message, &match_block)
+ end
+ end
+end \ No newline at end of file
diff --git a/spec/lib/spec/matchers/throw_symbol.rb b/vendor/gems/rspec/lib/spec/matchers/throw_symbol.rb
index 6d047bc39..c74d84436 100644
--- a/spec/lib/spec/matchers/throw_symbol.rb
+++ b/vendor/gems/rspec/lib/spec/matchers/throw_symbol.rb
@@ -4,12 +4,14 @@ module Spec
class ThrowSymbol #:nodoc:
def initialize(expected=nil)
@expected = expected
+ @actual = nil
end
def matches?(proc)
begin
proc.call
rescue NameError => e
+ raise e unless e.message =~ /uncaught throw/
@actual = e.name.to_sym
ensure
if @expected.nil?
diff --git a/spec/lib/spec/mocks.rb b/vendor/gems/rspec/lib/spec/mocks.rb
index 66cbafb3c..9f9cd215b 100644
--- a/spec/lib/spec/mocks.rb
+++ b/vendor/gems/rspec/lib/spec/mocks.rb
@@ -170,7 +170,9 @@ module Spec
# #error can be an instantiated object or a class
# #if it is a class, it must be instantiable with no args
# my_mock.should_receive(:sym).and_throw(:sym)
- # my_mock.should_receive(:sym).and_yield([array,of,values,to,yield])
+ # my_mock.should_receive(:sym).and_yield(values,to,yield)
+ # my_mock.should_receive(:sym).and_yield(values,to,yield).and_yield(some,other,values,this,time)
+ # # for methods that yield to a block multiple times
#
# Any of these responses can be applied to a stub as well, but stubs do
# not support any qualifiers about the message received (i.e. you can't specify arguments
@@ -180,7 +182,8 @@ module Spec
# my_mock.stub!(:sym).and_return(value1, value2, value3)
# my_mock.stub!(:sym).and_raise(error)
# my_mock.stub!(:sym).and_throw(:sym)
- # my_mock.stub!(:sym).and_yield([array,of,values,to,yield])
+ # my_mock.stub!(:sym).and_yield(values,to,yield)
+ # my_mock.stub!(:sym).and_yield(values,to,yield).and_yield(some,other,values,this,time)
#
# == Arbitrary Handling
#
diff --git a/spec/lib/spec/mocks/argument_constraint_matchers.rb b/vendor/gems/rspec/lib/spec/mocks/argument_constraint_matchers.rb
index 0e4777082..0e4777082 100644
--- a/spec/lib/spec/mocks/argument_constraint_matchers.rb
+++ b/vendor/gems/rspec/lib/spec/mocks/argument_constraint_matchers.rb
diff --git a/spec/lib/spec/mocks/argument_expectation.rb b/vendor/gems/rspec/lib/spec/mocks/argument_expectation.rb
index 5da069b87..34a1d4d03 100644
--- a/spec/lib/spec/mocks/argument_expectation.rb
+++ b/vendor/gems/rspec/lib/spec/mocks/argument_expectation.rb
@@ -138,7 +138,7 @@ module Spec
end
def warn_deprecated(deprecated_method, instead)
- STDERR.puts "The #{deprecated_method} constraint is deprecated. Use #{instead} instead."
+ Kernel.warn "The #{deprecated_method} constraint is deprecated. Use #{instead} instead."
end
def convert_constraint(constraint)
diff --git a/spec/lib/spec/mocks/error_generator.rb b/vendor/gems/rspec/lib/spec/mocks/error_generator.rb
index 01d8f720d..01d8f720d 100644
--- a/spec/lib/spec/mocks/error_generator.rb
+++ b/vendor/gems/rspec/lib/spec/mocks/error_generator.rb
diff --git a/spec/lib/spec/mocks/errors.rb b/vendor/gems/rspec/lib/spec/mocks/errors.rb
index 68fdfe006..68fdfe006 100644
--- a/spec/lib/spec/mocks/errors.rb
+++ b/vendor/gems/rspec/lib/spec/mocks/errors.rb
diff --git a/spec/lib/spec/mocks/extensions/object.rb b/vendor/gems/rspec/lib/spec/mocks/extensions/object.rb
index 4b7531066..4b7531066 100644
--- a/spec/lib/spec/mocks/extensions/object.rb
+++ b/vendor/gems/rspec/lib/spec/mocks/extensions/object.rb
diff --git a/spec/lib/spec/mocks/message_expectation.rb b/vendor/gems/rspec/lib/spec/mocks/message_expectation.rb
index 74ade3c58..6bd2f1c32 100644
--- a/spec/lib/spec/mocks/message_expectation.rb
+++ b/vendor/gems/rspec/lib/spec/mocks/message_expectation.rb
@@ -10,8 +10,8 @@ module Spec
@expected_from = expected_from
@sym = sym
@method_block = method_block
- @return_block = lambda {}
- @received_count = 0
+ @return_block = nil
+ @actual_received_count = 0
@expected_received_count = expected_received_count
@args_expectation = ArgumentExpectation.new([AnyArgsConstraint.new])
@consecutive = false
@@ -20,7 +20,7 @@ module Spec
@order_group = expectation_ordering
@at_least = nil
@at_most = nil
- @args_to_yield = nil
+ @args_to_yield = []
end
def expected_args
@@ -29,17 +29,18 @@ module Spec
def and_return(*values, &return_block)
Kernel::raise AmbiguousReturnError unless @method_block.nil?
- if values.size == 0
- value = nil
- elsif values.size == 1
- value = values[0]
+ case values.size
+ when 0 then value = nil
+ when 1 then value = values[0]
else
value = values
@consecutive = true
- @expected_received_count = values.size if @expected_received_count != :any &&
+ @expected_received_count = values.size if !ignoring_args? &&
@expected_received_count < values.size
end
@return_block = block_given? ? return_block : lambda { value }
+ # Ruby 1.9 - see where this is used below
+ @ignore_args = !block_given?
end
# :call-seq:
@@ -62,7 +63,8 @@ module Spec
end
def and_yield(*args)
- @args_to_yield = args
+ @args_to_yield << args
+ self
end
def matches(sym, args)
@@ -73,25 +75,26 @@ module Spec
@order_group.handle_order_constraint self
begin
- if @exception_to_raise.class == Class
- @exception_instance_to_raise = @exception_to_raise.new
- else
- @exception_instance_to_raise = @exception_to_raise
- end
Kernel::raise @exception_to_raise unless @exception_to_raise.nil?
Kernel::throw @symbol_to_throw unless @symbol_to_throw.nil?
-
+
if !@method_block.nil?
- return invoke_method_block(args)
- elsif !@args_to_yield.nil?
- return invoke_with_yield(block)
- elsif @consecutive
- return invoke_consecutive_return_block(args, block)
+ default_return_val = invoke_method_block(args)
+ elsif @args_to_yield.size > 0
+ default_return_val = invoke_with_yield(block)
else
+ default_return_val = nil
+ end
+
+ if @consecutive
+ return invoke_consecutive_return_block(args, block)
+ elsif @return_block
return invoke_return_block(args, block)
+ else
+ return default_return_val
end
ensure
- @received_count += 1
+ @actual_received_count += 1
end
end
@@ -109,25 +112,32 @@ module Spec
if block.nil?
@error_generator.raise_missing_block_error @args_to_yield
end
- if block.arity > -1 && @args_to_yield.length != block.arity
- @error_generator.raise_wrong_arity_error @args_to_yield, block.arity
+ @args_to_yield.each do |args_to_yield_this_time|
+ if block.arity > -1 && args_to_yield_this_time.length != block.arity
+ @error_generator.raise_wrong_arity_error args_to_yield_this_time, block.arity
+ end
+ block.call(*args_to_yield_this_time)
end
- block.call(*@args_to_yield)
end
def invoke_consecutive_return_block(args, block)
args << block unless block.nil?
value = @return_block.call(*args)
- index = [@received_count, value.size-1].min
+ index = [@actual_received_count, value.size-1].min
value[index]
end
def invoke_return_block(args, block)
args << block unless block.nil?
- value = @return_block.call(*args)
-
- value
+ # Ruby 1.9 - when we set @return_block to return values
+ # regardless of arguments, any arguments will result in
+ # a "wrong number of arguments" error
+ if @ignore_args
+ @return_block.call()
+ else
+ @return_block.call(*args)
+ end
end
end
@@ -138,17 +148,33 @@ module Spec
end
def verify_messages_received
- return if @expected_received_count == :any
- return if (@at_least) && (@received_count >= @expected_received_count)
- return if (@at_most) && (@received_count <= @expected_received_count)
- return if @expected_received_count == @received_count
+ return if ignoring_args? || matches_exact_count? ||
+ matches_at_least_count? || matches_at_most_count?
- begin
- @error_generator.raise_expectation_error(@sym, @expected_received_count, @received_count, *@args_expectation.args)
- rescue => error
- error.backtrace.insert(0, @expected_from)
- Kernel::raise error
- end
+ generate_error
+ rescue Spec::Mocks::MockExpectationError => error
+ error.backtrace.insert(0, @expected_from)
+ Kernel::raise error
+ end
+
+ def ignoring_args?
+ @expected_received_count == :any
+ end
+
+ def matches_at_least_count?
+ @at_least && @actual_received_count >= @expected_received_count
+ end
+
+ def matches_at_most_count?
+ @at_most && @actual_received_count <= @expected_received_count
+ end
+
+ def matches_exact_count?
+ @expected_received_count == @actual_received_count
+ end
+
+ def generate_error
+ @error_generator.raise_expectation_error(@sym, @expected_received_count, @actual_received_count, *@args_expectation.args)
end
def with(*args, &block)
@@ -215,9 +241,14 @@ module Spec
def set_expected_received_count(relativity, n)
@at_least = (relativity == :at_least)
@at_most = (relativity == :at_most)
- @expected_received_count = 1 if n == :once
- @expected_received_count = 2 if n == :twice
- @expected_received_count = n if n.kind_of? Numeric
+ @expected_received_count = case n
+ when Numeric
+ n
+ when :once
+ 1
+ when :twice
+ 2
+ end
end
end
@@ -232,11 +263,5 @@ module Spec
end
end
- class MethodStub < BaseExpectation
- def initialize(message, expectation_ordering, expected_from, sym, method_block)
- super(message, expectation_ordering, expected_from, sym, method_block, 0)
- @expected_received_count = :any
- end
- end
end
end
diff --git a/spec/lib/spec/mocks/methods.rb b/vendor/gems/rspec/lib/spec/mocks/methods.rb
index 3d898cf31..d9fa324d3 100644
--- a/spec/lib/spec/mocks/methods.rb
+++ b/vendor/gems/rspec/lib/spec/mocks/methods.rb
@@ -9,8 +9,8 @@ module Spec
__mock_proxy.add_negative_message_expectation(caller(1)[0], sym.to_sym, &block)
end
- def stub!(sym)
- __mock_proxy.add_stub(caller(1)[0], sym.to_sym)
+ def stub!(sym, opts={})
+ __mock_proxy.add_stub(caller(1)[0], sym.to_sym, opts)
end
def received_message?(sym, *args, &block) #:nodoc:
diff --git a/vendor/gems/rspec/lib/spec/mocks/mock.rb b/vendor/gems/rspec/lib/spec/mocks/mock.rb
new file mode 100644
index 000000000..f029b1b8f
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/mocks/mock.rb
@@ -0,0 +1,50 @@
+module Spec
+ module Mocks
+ class Mock
+ include Methods
+
+ # Creates a new mock with a +name+ (that will be used in error messages only)
+ # == Options:
+ # * <tt>:null_object</tt> - if true, the mock object acts as a forgiving null object allowing any message to be sent to it.
+ def initialize(name, stubs_and_options={})
+ @name = name
+ @options = parse_options(stubs_and_options)
+ assign_stubs(stubs_and_options)
+ end
+
+ # This allows for comparing the mock to other objects that proxy
+ # such as ActiveRecords belongs_to proxy objects
+ # By making the other object run the comparison, we're sure the call gets delegated to the proxy target
+ # This is an unfortunate side effect from ActiveRecord, but this should be safe unless the RHS redefines == in a nonsensical manner
+ def ==(other)
+ other == __mock_proxy
+ end
+
+ def method_missing(sym, *args, &block)
+ __mock_proxy.instance_eval {@messages_received << [sym, args, block]}
+ begin
+ return self if __mock_proxy.null_object?
+ super(sym, *args, &block)
+ rescue NameError
+ __mock_proxy.raise_unexpected_message_error sym, *args
+ end
+ end
+
+ def inspect
+ "#<#{self.class}:#{sprintf '0x%x', self.object_id} @name=#{@name.inspect}>"
+ end
+
+ private
+
+ def parse_options(options)
+ options.has_key?(:null_object) ? {:null_object => options.delete(:null_object)} : {}
+ end
+
+ def assign_stubs(stubs)
+ stubs.each_pair do |message, response|
+ stub!(message).and_return(response)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/spec/mocks/order_group.rb b/vendor/gems/rspec/lib/spec/mocks/order_group.rb
index 9983207eb..9983207eb 100644
--- a/spec/lib/spec/mocks/order_group.rb
+++ b/vendor/gems/rspec/lib/spec/mocks/order_group.rb
diff --git a/spec/lib/spec/mocks/proxy.rb b/vendor/gems/rspec/lib/spec/mocks/proxy.rb
index 6c79d1068..03db3b113 100644
--- a/spec/lib/spec/mocks/proxy.rb
+++ b/vendor/gems/rspec/lib/spec/mocks/proxy.rb
@@ -22,29 +22,27 @@ module Spec
end
def add_message_expectation(expected_from, sym, opts={}, &block)
- __add sym, block
+ __add sym
@expectations << MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil, 1, opts)
@expectations.last
end
def add_negative_message_expectation(expected_from, sym, &block)
- __add sym, block
+ __add sym
@expectations << NegativeMessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil)
@expectations.last
end
- def add_stub(expected_from, sym)
- __add sym, nil
- @stubs.unshift MethodStub.new(@error_generator, @expectation_ordering, expected_from, sym, nil)
+ def add_stub(expected_from, sym, opts={})
+ __add sym
+ @stubs.unshift MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, nil, :any, opts)
@stubs.first
end
def verify #:nodoc:
- begin
- verify_expectations
- ensure
- reset
- end
+ verify_expectations
+ ensure
+ reset
end
def reset
@@ -55,8 +53,7 @@ module Spec
end
def received_message?(sym, *args, &block)
- return true if @messages_received.find {|array| array == [sym, args, block]}
- return false
+ @messages_received.any? {|array| array == [sym, args, block]}
end
def has_negative_expectation?(sym)
@@ -66,7 +63,7 @@ module Spec
def message_received(sym, *args, &block)
if expectation = find_matching_expectation(sym, *args)
expectation.invoke(args, block)
- elsif stub = find_matching_method_stub(sym)
+ elsif stub = find_matching_method_stub(sym, *args)
stub.invoke([], block)
elsif expectation = find_almost_matching_expectation(sym, *args)
raise_unexpected_message_args_error(expectation, *args) unless has_negative_expectation?(sym) unless null_object?
@@ -85,14 +82,17 @@ module Spec
private
- def __add(sym, block)
+ def __add(sym)
$rspec_mocks.add(@target) unless $rspec_mocks.nil?
define_expected_method(sym)
end
def define_expected_method(sym)
- if target_responds_to?(sym) && !@proxied_methods.include?(sym)
- metaclass.__send__(:alias_method, munge(sym), sym) if metaclass.instance_methods.include?(sym.to_s)
+ if target_responds_to?(sym) && !metaclass.method_defined?(munge(sym))
+ munged_sym = munge(sym)
+ metaclass.instance_eval do
+ alias_method munged_sym, sym if method_defined?(sym.to_s)
+ end
@proxied_methods << sym
end
@@ -141,11 +141,14 @@ module Spec
def reset_proxied_methods
@proxied_methods.each do |sym|
- if metaclass.instance_methods.include?(munge(sym).to_s)
- metaclass.__send__(:alias_method, sym, munge(sym))
- metaclass.__send__(:undef_method, munge(sym))
- else
- metaclass.__send__(:undef_method, sym)
+ munged_sym = munge(sym)
+ metaclass.instance_eval do
+ if method_defined?(munged_sym.to_s)
+ alias_method sym, munged_sym
+ undef_method munged_sym
+ else
+ undef_method sym
+ end
end
end
end
@@ -158,8 +161,8 @@ module Spec
@expectations.find {|expectation| expectation.matches_name_but_not_args(sym, args)}
end
- def find_matching_method_stub(sym)
- @stubs.find {|stub| stub.matches(sym, [])}
+ def find_matching_method_stub(sym, *args)
+ @stubs.find {|stub| stub.matches(sym, args)}
end
end
diff --git a/spec/lib/spec/mocks/space.rb b/vendor/gems/rspec/lib/spec/mocks/space.rb
index e04bc5ccb..3e13224c7 100644
--- a/spec/lib/spec/mocks/space.rb
+++ b/vendor/gems/rspec/lib/spec/mocks/space.rb
@@ -2,7 +2,7 @@ module Spec
module Mocks
class Space
def add(obj)
- mocks << obj unless mocks.include?(obj)
+ mocks << obj unless mocks.detect {|m| m.equal? obj}
end
def verify_all
diff --git a/vendor/gems/rspec/lib/spec/mocks/spec_methods.rb b/vendor/gems/rspec/lib/spec/mocks/spec_methods.rb
new file mode 100644
index 000000000..d92a4cedd
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/mocks/spec_methods.rb
@@ -0,0 +1,38 @@
+module Spec
+ module Mocks
+ module ExampleMethods
+ include Spec::Mocks::ArgumentConstraintMatchers
+
+ # Shortcut for creating an instance of Spec::Mocks::Mock.
+ #
+ # +name+ is used for failure reporting, so you should use the
+ # role that the mock is playing in the example.
+ #
+ # +stubs_and_options+ lets you assign options and stub values
+ # at the same time. The only option available is :null_object.
+ # Anything else is treated as a stub value.
+ #
+ # == Examples
+ #
+ # stub_thing = mock("thing", :a => "A")
+ # stub_thing.a == "A" => true
+ #
+ # stub_person = stub("thing", :name => "Joe", :email => "joe@domain.com")
+ # stub_person.name => "Joe"
+ # stub_person.email => "joe@domain.com"
+ def mock(name, stubs_and_options={})
+ Spec::Mocks::Mock.new(name, stubs_and_options)
+ end
+
+ alias :stub :mock
+
+ # Shortcut for creating a mock object that will return itself in response
+ # to any message it receives that it hasn't been explicitly instructed
+ # to respond to.
+ def stub_everything(name = 'stub')
+ mock(name, :null_object => true)
+ end
+
+ end
+ end
+end
diff --git a/spec/lib/spec/rake/spectask.rb b/vendor/gems/rspec/lib/spec/rake/spectask.rb
index f8c6809a9..781c151a4 100644
--- a/spec/lib/spec/rake/spectask.rb
+++ b/vendor/gems/rspec/lib/spec/rake/spectask.rb
@@ -8,7 +8,7 @@ require 'rake/tasklib'
module Spec
module Rake
- # A Rake task that runs a set of RSpec contexts.
+ # A Rake task that runs a set of specs.
#
# Example:
#
@@ -44,6 +44,17 @@ module Spec
# Each attribute of this task may be a proc. This allows for lazy evaluation,
# which is sometimes handy if you want to defer the evaluation of an attribute value
# until the task is run (as opposed to when it is defined).
+ #
+ # This task can also be used to run existing Test::Unit tests and get RSpec
+ # output, for example like this:
+ #
+ # require 'rubygems'
+ # require 'spec/rake/spectask'
+ # Spec::Rake::SpecTask.new do |t|
+ # t.ruby_opts = ['-rtest/unit']
+ # t.spec_files = FileList['test/**/*_test.rb']
+ # end
+ #
class SpecTask < ::Rake::TaskLib
class << self
def attr_accessor(*names)
@@ -106,6 +117,10 @@ module Spec
# used, then the list of spec files is the union of the two.
# Setting the SPEC environment variable overrides this.
attr_accessor :spec_files
+
+ # Use verbose output. If this is set to true, the task will print
+ # the executed spec command to stdout. Defaults to false.
+ attr_accessor :verbose
# Defines a new task, using the name +name+.
def initialize(name=:spec)
@@ -150,7 +165,7 @@ module Spec
cmd << " "
cmd << rcov_option_list
cmd << %[ -o "#{rcov_dir}" ] if rcov
- cmd << %Q|"#{spec_script}"|
+ #cmd << %Q|"#{spec_script}"|
cmd << " "
cmd << "-- " if rcov
cmd << spec_file_list.collect { |fn| %["#{fn}"] }.join(' ')
@@ -161,6 +176,9 @@ module Spec
cmd << %Q| > "#{out}"|
STDERR.puts "The Spec::Rake::SpecTask#out attribute is DEPRECATED and will be removed in a future version. Use --format FORMAT:WHERE instead."
end
+ if verbose
+ puts cmd
+ end
unless system(cmd)
STDERR.puts failure_message if failure_message
raise("Command #{cmd} failed") if fail_on_error
diff --git a/spec/lib/spec/rake/verify_rcov.rb b/vendor/gems/rspec/lib/spec/rake/verify_rcov.rb
index 9715744e9..3328f9e9a 100644
--- a/spec/lib/spec/rake/verify_rcov.rb
+++ b/vendor/gems/rspec/lib/spec/rake/verify_rcov.rb
@@ -38,7 +38,7 @@ module RCov
total_coverage = nil
File.open(index_html).each_line do |line|
- if line =~ /<tt.*>(\d+\.\d+)%<\/tt>&nbsp;<\/td>/
+ if line =~ /<tt class='coverage_total'>(\d+\.\d+)%<\/tt>/
total_coverage = eval($1)
break
end
diff --git a/spec/lib/spec/runner.rb b/vendor/gems/rspec/lib/spec/runner.rb
index 9d801adc3..97ef95bd2 100644
--- a/spec/lib/spec/runner.rb
+++ b/vendor/gems/rspec/lib/spec/runner.rb
@@ -1,22 +1,20 @@
-require 'spec/runner/formatter'
-require 'spec/runner/behaviour_runner'
require 'spec/runner/options'
require 'spec/runner/option_parser'
+require 'spec/runner/example_group_runner'
require 'spec/runner/command_line'
require 'spec/runner/drb_command_line'
require 'spec/runner/backtrace_tweaker'
require 'spec/runner/reporter'
-require 'spec/runner/extensions/object'
-require 'spec/runner/extensions/kernel'
require 'spec/runner/spec_parser'
+require 'spec/runner/class_and_arguments_parser'
module Spec
- # == Behaviours and Examples
+ # == ExampleGroups and Examples
#
- # Rather than expressing examples in classes, RSpec uses a custom domain specific language to
- # describe Behaviours and Examples of those behaviours.
+ # Rather than expressing examples in classes, RSpec uses a custom DSLL (DSL light) to
+ # describe groups of examples.
#
- # A Behaviour is the equivalent of a fixture in xUnit-speak. It is a metaphor for the context
+ # A ExampleGroup is the equivalent of a fixture in xUnit-speak. It is a metaphor for the context
# in which you will run your executable example - a set of known objects in a known starting state.
# We begin be describing
#
@@ -32,7 +30,7 @@ module Spec
#
# end
#
- # We use the before block to set up the Behaviour (given), and then the #it method to
+ # We use the before block to set up the Example (given), and then the #it method to
# hold the example code that expresses the event (when) and the expected outcome (then).
#
# == Helper Methods
@@ -47,7 +45,7 @@ module Spec
#
# == Setup and Teardown
#
- # You can use before and after within a Behaviour. Both methods take an optional
+ # You can use before and after within a Example. Both methods take an optional
# scope argument so you can run the block before :each example or before :all examples
#
# describe "..." do
@@ -125,11 +123,11 @@ module Spec
# end
# end
#
- # == Shared behaviour
+ # == Shared Example Groups
#
- # You can define a shared behaviour, that may be used on other behaviours
+ # You can define a shared Example Group, that may be used on other groups
#
- # describe "All Editions", :shared => true do
+ # share_examples_for "All Editions" do
# it "all editions behaviour" ...
# end
#
@@ -140,10 +138,35 @@ module Spec
# ...
# end
# end
+ #
+ # You can also assign the shared group to a module and include that
+ #
+ # share_as :AllEditions do
+ # it "should do all editions stuff" ...
+ # end
+ #
+ # describe SmallEdition do
+ # it_should_behave_like AllEditions
+ #
+ # it "should do small edition stuff" do
+ # ...
+ # end
+ # end
+ #
+ # And, for those of you who prefer to use something more like Ruby, you
+ # can just include the module directly
+ #
+ # describe SmallEdition do
+ # include AllEditions
+ #
+ # it "should do small edition stuff" do
+ # ...
+ # end
+ # end
module Runner
class << self
def configuration # :nodoc:
- @configuration ||= Spec::DSL::Configuration.new
+ @configuration ||= Spec::Example::Configuration.new
end
# Use this to configure various configurable aspects of
@@ -154,12 +177,26 @@ module Spec
# end
#
# The yielded <tt>configuration</tt> object is a
- # Spec::DSL::Configuration instance. See its RDoc
+ # Spec::Example::Configuration instance. See its RDoc
# for details about what you can do with it.
#
def configure
- yield configuration if @configuration.nil?
+ yield configuration
end
+
+ def register_at_exit_hook # :nodoc:
+ $spec_runner_at_exit_hook_registered ||= nil
+ unless $spec_runner_at_exit_hook_registered
+ at_exit do
+ unless $! || Spec.run?; \
+ success = Spec.run; \
+ exit success if Spec.exit?; \
+ end
+ end
+ $spec_runner_at_exit_hook_registered = true
+ end
+ end
+
end
end
end
diff --git a/spec/lib/spec/runner/backtrace_tweaker.rb b/vendor/gems/rspec/lib/spec/runner/backtrace_tweaker.rb
index aacc2c8b8..5fd2fb99f 100644
--- a/spec/lib/spec/runner/backtrace_tweaker.rb
+++ b/vendor/gems/rspec/lib/spec/runner/backtrace_tweaker.rb
@@ -7,7 +7,7 @@ module Spec
end
class NoisyBacktraceTweaker < BacktraceTweaker
- def tweak_backtrace(error, spec_name)
+ def tweak_backtrace(error)
return if error.backtrace.nil?
error.backtrace.each do |line|
clean_up_double_slashes(line)
@@ -19,7 +19,7 @@ module Spec
class QuietBacktraceTweaker < BacktraceTweaker
unless defined?(IGNORE_PATTERNS)
root_dir = File.expand_path(File.join(__FILE__, '..', '..', '..', '..'))
- spec_files = Dir["#{root_dir}/lib/spec/*"].map do |path|
+ spec_files = Dir["#{root_dir}/lib/*"].map do |path|
subpath = path[root_dir.length..-1]
/#{subpath}/
end
@@ -38,7 +38,7 @@ module Spec
]
end
- def tweak_backtrace(error, spec_name)
+ def tweak_backtrace(error)
return if error.backtrace.nil?
error.backtrace.collect! do |line|
clean_up_double_slashes(line)
diff --git a/vendor/gems/rspec/lib/spec/runner/class_and_arguments_parser.rb b/vendor/gems/rspec/lib/spec/runner/class_and_arguments_parser.rb
new file mode 100644
index 000000000..65dc4519c
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/runner/class_and_arguments_parser.rb
@@ -0,0 +1,16 @@
+module Spec
+ module Runner
+ class ClassAndArgumentsParser
+ class << self
+ def parse(s)
+ if s =~ /([a-zA-Z_]+(?:::[a-zA-Z_]+)*):?(.*)/
+ arg = $2 == "" ? nil : $2
+ [$1, arg]
+ else
+ raise "Couldn't parse #{s.inspect}"
+ end
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/lib/spec/runner/command_line.rb b/vendor/gems/rspec/lib/spec/runner/command_line.rb
new file mode 100644
index 000000000..9849c4853
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/runner/command_line.rb
@@ -0,0 +1,28 @@
+require 'spec/runner/option_parser'
+
+module Spec
+ module Runner
+ # Facade to run specs without having to fork a new ruby process (using `spec ...`)
+ class CommandLine
+ class << self
+ # Runs specs. +argv+ is the commandline args as per the spec commandline API, +err+
+ # and +out+ are the streams output will be written to.
+ def run(instance_rspec_options)
+ # NOTE - this call to init_rspec_options is not spec'd, but neither is any of this
+ # swapping of $rspec_options. That is all here to enable rspec to run against itself
+ # and maintain coverage in a single process. Therefore, DO NOT mess with this stuff
+ # unless you know what you are doing!
+ init_rspec_options(instance_rspec_options)
+ orig_rspec_options = rspec_options
+ begin
+ $rspec_options = instance_rspec_options
+ return $rspec_options.run_examples
+ ensure
+ ::Spec.run = true
+ $rspec_options = orig_rspec_options
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/spec/runner/drb_command_line.rb b/vendor/gems/rspec/lib/spec/runner/drb_command_line.rb
index 7e745fb71..6c340cfea 100644
--- a/spec/lib/spec/runner/drb_command_line.rb
+++ b/vendor/gems/rspec/lib/spec/runner/drb_command_line.rb
@@ -6,14 +6,13 @@ module Spec
class DrbCommandLine
# Runs specs on a DRB server. Note that this API is similar to that of
# CommandLine - making it possible for clients to use both interchangeably.
- def self.run(argv, stderr, stdout, exit=true, warn_if_no_files=true)
+ def self.run(options)
begin
DRb.start_service
spec_server = DRbObject.new_with_uri("druby://localhost:8989")
- spec_server.run(argv, stderr, stdout)
- rescue DRb::DRbConnError
- stderr.puts "No server is running"
- exit 1 if exit
+ spec_server.run(options.argv, options.error_stream, options.output_stream)
+ rescue DRb::DRbConnError => e
+ options.error_stream.puts "No server is running"
end
end
end
diff --git a/vendor/gems/rspec/lib/spec/runner/example_group_runner.rb b/vendor/gems/rspec/lib/spec/runner/example_group_runner.rb
new file mode 100644
index 000000000..7275c6a88
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/runner/example_group_runner.rb
@@ -0,0 +1,59 @@
+module Spec
+ module Runner
+ class ExampleGroupRunner
+ def initialize(options)
+ @options = options
+ end
+
+ def load_files(files)
+ # It's important that loading files (or choosing not to) stays the
+ # responsibility of the ExampleGroupRunner. Some implementations (like)
+ # the one using DRb may choose *not* to load files, but instead tell
+ # someone else to do it over the wire.
+ files.each do |file|
+ load file
+ end
+ end
+
+ def run
+ prepare
+ success = true
+ example_groups.each do |example_group|
+ success = success & example_group.run
+ end
+ return success
+ ensure
+ finish
+ end
+
+ protected
+ def prepare
+ reporter.start(number_of_examples)
+ example_groups.reverse! if reverse
+ end
+
+ def finish
+ reporter.end
+ reporter.dump
+ end
+
+ def reporter
+ @options.reporter
+ end
+
+ def reverse
+ @options.reverse
+ end
+
+ def example_groups
+ @options.example_groups
+ end
+
+ def number_of_examples
+ @options.number_of_examples
+ end
+ end
+ # TODO: BT - Deprecate BehaviourRunner?
+ BehaviourRunner = ExampleGroupRunner
+ end
+end \ No newline at end of file
diff --git a/spec/lib/spec/runner/formatter/base_formatter.rb b/vendor/gems/rspec/lib/spec/runner/formatter/base_formatter.rb
index 7cc43ef0e..c8647cf50 100644
--- a/spec/lib/spec/runner/formatter/base_formatter.rb
+++ b/vendor/gems/rspec/lib/spec/runner/formatter/base_formatter.rb
@@ -3,7 +3,9 @@ module Spec
module Formatter
# Baseclass for formatters that implements all required methods as no-ops.
class BaseFormatter
- def initialize(where)
+ attr_accessor :example_group, :options, :where
+ def initialize(options, where)
+ @options = options
@where = where
end
@@ -12,16 +14,17 @@ module Spec
# formatters that need to provide progress on feedback (graphical ones)
#
# This method will only be invoked once, and the next one to be invoked
- # is #add_behaviour
+ # is #add_example_group
def start(example_count)
end
- # This method is invoked at the beginning of the execution of each behaviour.
- # +name+ is the name of the behaviour and +first+ is true if it is the
- # first behaviour - otherwise it's false.
+ # This method is invoked at the beginning of the execution of each example_group.
+ # +name+ is the name of the example_group and +first+ is true if it is the
+ # first example_group - otherwise it's false.
#
# The next method to be invoked after this is #example_failed or #example_finished
- def add_behaviour(name)
+ def add_example_group(example_group)
+ @example_group = example_group
end
# This method is invoked when an +example+ starts.
@@ -41,10 +44,9 @@ module Spec
# This method is invoked when an example is not yet implemented (i.e. has not
# been provided a block), or when an ExamplePendingError is raised.
- # +name+ is the name of the example.
# +message+ is the message from the ExamplePendingError, if it exists, or the
# default value of "Not Yet Implemented"
- def example_pending(behaviour_name, example_name, message)
+ def example_pending(example_group_description, example, message)
end
# This method is invoked after all of the examples have executed. The next method
diff --git a/spec/lib/spec/runner/formatter/base_text_formatter.rb b/vendor/gems/rspec/lib/spec/runner/formatter/base_text_formatter.rb
index c3cf01b76..859b2641d 100644
--- a/spec/lib/spec/runner/formatter/base_text_formatter.rb
+++ b/vendor/gems/rspec/lib/spec/runner/formatter/base_text_formatter.rb
@@ -1,3 +1,5 @@
+require 'spec/runner/formatter/base_formatter'
+
module Spec
module Runner
module Formatter
@@ -5,13 +7,12 @@ module Spec
# non-text based ones too - just ignore the +output+ constructor
# argument.
class BaseTextFormatter < BaseFormatter
- attr_writer :dry_run
-
+ attr_reader :output, :pending_examples
# Creates a new instance that will write to +where+. If +where+ is a
# String, output will be written to the File with that name, otherwise
# +where+ is exected to be an IO (or an object that responds to #puts and #write).
- def initialize(where)
- super(where)
+ def initialize(options, where)
+ super
if where.is_a?(String)
@output = File.open(where, 'w')
elsif where == STDOUT
@@ -22,21 +23,13 @@ module Spec
else
@output = where
end
- @colour = false
- @dry_run = false
- @snippet_extractor = SnippetExtractor.new
@pending_examples = []
end
- def example_pending(behaviour_name, example_name, message)
- @pending_examples << ["#{behaviour_name} #{example_name}", message]
+ def example_pending(example_group_description, example, message)
+ @pending_examples << ["#{example_group_description} #{example.description}", message]
end
- def colour=(colour)
- @colour = colour
- begin ; require 'Win32/Console/ANSI' if @colour && PLATFORM =~ /win32/ ; rescue LoadError ; raise "You must gem install win32console to use colour on Windows" ; end
- end
-
def dump_failure(counter, failure)
@output.puts
@output.puts "#{counter.to_s})"
@@ -56,7 +49,7 @@ module Spec
end
def dump_summary(duration, example_count, failure_count, pending_count)
- return if @dry_run
+ return if dry_run?
@output.puts
@output.puts "Finished in #{duration} seconds"
@output.puts
@@ -74,7 +67,6 @@ module Spec
@output.puts red(summary)
end
@output.flush
- dump_pending
end
def dump_pending
@@ -100,13 +92,21 @@ module Spec
end
protected
-
+
+ def colour?
+ @options.colour ? true : false
+ end
+
+ def dry_run?
+ @options.dry_run ? true : false
+ end
+
def backtrace_line(line)
line.sub(/\A([^:]+:\d+)$/, '\\1:')
end
def colour(text, colour_code)
- return text unless @colour && output_to_tty?
+ return text unless colour? && output_to_tty?
"#{colour_code}#{text}\e[0m"
end
diff --git a/vendor/gems/rspec/lib/spec/runner/formatter/failing_example_groups_formatter.rb b/vendor/gems/rspec/lib/spec/runner/formatter/failing_example_groups_formatter.rb
new file mode 100644
index 000000000..5a4607983
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/runner/formatter/failing_example_groups_formatter.rb
@@ -0,0 +1,31 @@
+require 'spec/runner/formatter/base_text_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ class FailingExampleGroupsFormatter < BaseTextFormatter
+ def add_example_group(example_group)
+ super
+ @example_group_description_parts = example_group.description_parts
+ end
+
+ def example_failed(example, counter, failure)
+ if @example_group_description_parts
+ description_parts = @example_group_description_parts.collect do |description|
+ description =~ /(.*) \(druby.*\)$/ ? $1 : description
+ end
+ @output.puts ::Spec::Example::ExampleGroupMethods.description_text(*description_parts)
+ @output.flush
+ @example_group_description_parts = nil
+ end
+ end
+
+ def dump_failure(counter, failure)
+ end
+
+ def dump_summary(duration, example_count, failure_count, pending_count)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/spec/runner/formatter/failing_examples_formatter.rb b/vendor/gems/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb
index 9728deaf0..e3a271c8b 100644
--- a/spec/lib/spec/runner/formatter/failing_examples_formatter.rb
+++ b/vendor/gems/rspec/lib/spec/runner/formatter/failing_examples_formatter.rb
@@ -1,13 +1,11 @@
+require 'spec/runner/formatter/base_text_formatter'
+
module Spec
module Runner
module Formatter
class FailingExamplesFormatter < BaseTextFormatter
- def add_behaviour(behaviour_name)
- @behaviour_name = behaviour_name
- end
-
def example_failed(example, counter, failure)
- @output.puts "#{@behaviour_name} #{example.description}"
+ @output.puts "#{example_group.description} #{example.description}"
@output.flush
end
diff --git a/spec/lib/spec/runner/formatter/html_formatter.rb b/vendor/gems/rspec/lib/spec/runner/formatter/html_formatter.rb
index d9c422e55..ad153c8dc 100644
--- a/spec/lib/spec/runner/formatter/html_formatter.rb
+++ b/vendor/gems/rspec/lib/spec/runner/formatter/html_formatter.rb
@@ -1,4 +1,5 @@
require 'erb'
+require 'spec/runner/formatter/base_text_formatter'
module Spec
module Runner
@@ -6,15 +7,15 @@ module Spec
class HtmlFormatter < BaseTextFormatter
include ERB::Util # for the #h method
- def initialize(output)
+ def initialize(options, output)
super
- @current_behaviour_number = 0
+ @current_example_group_number = 0
@current_example_number = 0
end
- # The number of the currently running behaviour
- def current_behaviour_number
- @current_behaviour_number
+ # The number of the currently running example_group
+ def current_example_group_number
+ @current_example_group_number
end
# The number of the currently running example (a global counter)
@@ -30,17 +31,18 @@ module Spec
@output.flush
end
- def add_behaviour(name)
- @behaviour_red = false
- @behaviour_red = false
- @current_behaviour_number += 1
- unless current_behaviour_number == 1
+ def add_example_group(example_group)
+ super
+ @example_group_red = false
+ @example_group_red = false
+ @current_example_group_number += 1
+ unless current_example_group_number == 1
@output.puts " </dl>"
@output.puts "</div>"
end
- @output.puts "<div class=\"behaviour\">"
+ @output.puts "<div class=\"example_group\">"
@output.puts " <dl>"
- @output.puts " <dt id=\"behaviour_#{current_behaviour_number}\">#{h(name)}</dt>"
+ @output.puts " <dt id=\"example_group_#{current_example_group_number}\">#{h(example_group.description)}</dt>"
@output.flush
end
@@ -51,7 +53,7 @@ module Spec
end
def example_started(example)
- @current_example_number = example.number
+ @current_example_number += 1
end
def example_passed(example)
@@ -65,8 +67,8 @@ module Spec
failure_style = failure.pending_fixed? ? 'pending_fixed' : 'failed'
@output.puts " <script type=\"text/javascript\">makeRed('rspec-header');</script>" unless @header_red
@header_red = true
- @output.puts " <script type=\"text/javascript\">makeRed('behaviour_#{current_behaviour_number}');</script>" unless @behaviour_red
- @behaviour_red = true
+ @output.puts " <script type=\"text/javascript\">makeRed('example_group_#{current_example_group_number}');</script>" unless @example_group_red
+ @example_group_red = true
move_progress
@output.puts " <dd class=\"spec #{failure_style}\">"
@output.puts " <span class=\"failed_spec_name\">#{h(example.description)}</span>"
@@ -79,11 +81,11 @@ module Spec
@output.flush
end
- def example_pending(behaviour_name, example_name, message)
+ def example_pending(example_group_description, example, message)
@output.puts " <script type=\"text/javascript\">makeYellow('rspec-header');</script>" unless @header_red
- @output.puts " <script type=\"text/javascript\">makeYellow('behaviour_#{current_behaviour_number}');</script>" unless @behaviour_red
+ @output.puts " <script type=\"text/javascript\">makeYellow('example_group_#{current_example_group_number}');</script>" unless @example_group_red
move_progress
- @output.puts " <dd class=\"spec not_implemented\"><span class=\"not_implemented_spec_name\">#{h(example_name)}</span></dd>"
+ @output.puts " <dd class=\"spec not_implemented\"><span class=\"not_implemented_spec_name\">#{h(example.description)} (PENDING: #{h(message)})</span></dd>"
@output.flush
end
@@ -91,20 +93,29 @@ module Spec
# could output links to images or other files produced during the specs.
#
def extra_failure_content(failure)
+ require 'spec/runner/formatter/snippet_extractor'
+ @snippet_extractor ||= SnippetExtractor.new
" <pre class=\"ruby\"><code>#{@snippet_extractor.snippet(failure.exception)}</code></pre>"
end
def move_progress
- percent_done = @example_count == 0 ? 100.0 : ((current_example_number + 1).to_f / @example_count.to_f * 1000).to_i / 10.0
@output.puts " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>"
@output.flush
end
+ def percent_done
+ result = 100.0
+ if @example_count != 0
+ result = ((current_example_number).to_f / @example_count.to_f * 1000).to_i / 10.0
+ end
+ result
+ end
+
def dump_failure(counter, failure)
end
def dump_summary(duration, example_count, failure_count, pending_count)
- if @dry_run
+ if dry_run?
totals = "This was a dry-run"
else
totals = "#{example_count} example#{'s' unless example_count == 1}, #{failure_count} failure#{'s' unless failure_count == 1}"
@@ -121,15 +132,14 @@ module Spec
def html_header
<<-EOF
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE html
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>RSpec results</title>
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Expires" content="-1" />
<meta http-equiv="Pragma" content="no-cache" />
<style type="text/css">
@@ -225,7 +235,7 @@ EOF
font-size: 1.2em;
}
-.behaviour {
+.example_group {
margin: 0 10px 5px;
background: #fff;
}
diff --git a/vendor/gems/rspec/lib/spec/runner/formatter/profile_formatter.rb b/vendor/gems/rspec/lib/spec/runner/formatter/profile_formatter.rb
new file mode 100644
index 000000000..3784f3ac7
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/runner/formatter/profile_formatter.rb
@@ -0,0 +1,47 @@
+require 'spec/runner/formatter/progress_bar_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ class ProfileFormatter < ProgressBarFormatter
+
+ def initialize(options, where)
+ super
+ @example_times = []
+ end
+
+ def start(count)
+ @output.puts "Profiling enabled."
+ end
+
+ def example_started(example)
+ @time = Time.now
+ end
+
+ def example_passed(example)
+ super
+ @example_times << [
+ example_group.description,
+ example.description,
+ Time.now - @time
+ ]
+ end
+
+ def start_dump
+ super
+ @output.puts "\n\nTop 10 slowest examples:\n"
+
+ @example_times = @example_times.sort_by do |description, example, time|
+ time
+ end.reverse
+
+ @example_times[0..9].each do |description, example, time|
+ @output.print red(sprintf("%.7f", time))
+ @output.puts " #{description} #{example}"
+ end
+ @output.flush
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/spec/runner/formatter/progress_bar_formatter.rb b/vendor/gems/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb
index 624f06e7c..8d0e50432 100644
--- a/spec/lib/spec/runner/formatter/progress_bar_formatter.rb
+++ b/vendor/gems/rspec/lib/spec/runner/formatter/progress_bar_formatter.rb
@@ -1,10 +1,9 @@
+require 'spec/runner/formatter/base_text_formatter'
+
module Spec
module Runner
module Formatter
class ProgressBarFormatter < BaseTextFormatter
- def add_behaviour(name)
- end
-
def example_failed(example, counter, failure)
@output.print colourise('F', failure)
@output.flush
@@ -15,7 +14,7 @@ module Spec
@output.flush
end
- def example_pending(behaviour_name, example_name, message)
+ def example_pending(example_group_description, example, message)
super
@output.print yellow('P')
@output.flush
diff --git a/spec/lib/spec/runner/formatter/snippet_extractor.rb b/vendor/gems/rspec/lib/spec/runner/formatter/snippet_extractor.rb
index 41119fe46..41119fe46 100644
--- a/spec/lib/spec/runner/formatter/snippet_extractor.rb
+++ b/vendor/gems/rspec/lib/spec/runner/formatter/snippet_extractor.rb
diff --git a/vendor/gems/rspec/lib/spec/runner/formatter/specdoc_formatter.rb b/vendor/gems/rspec/lib/spec/runner/formatter/specdoc_formatter.rb
new file mode 100644
index 000000000..f426dc948
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/runner/formatter/specdoc_formatter.rb
@@ -0,0 +1,39 @@
+require 'spec/runner/formatter/base_text_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ class SpecdocFormatter < BaseTextFormatter
+ def add_example_group(example_group)
+ super
+ output.puts
+ output.puts example_group.description
+ output.flush
+ end
+
+ def example_failed(example, counter, failure)
+ message = if failure.expectation_not_met?
+ "- #{example.description} (FAILED - #{counter})"
+ else
+ "- #{example.description} (ERROR - #{counter})"
+ end
+
+ output.puts(failure.expectation_not_met? ? red(message) : magenta(message))
+ output.flush
+ end
+
+ def example_passed(example)
+ message = "- #{example.description}"
+ output.puts green(message)
+ output.flush
+ end
+
+ def example_pending(example_group_description, example, message)
+ super
+ output.puts yellow("- #{example.description} (PENDING: #{message})")
+ output.flush
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/runner/formatter/story/html_formatter.rb b/vendor/gems/rspec/lib/spec/runner/formatter/story/html_formatter.rb
new file mode 100644
index 000000000..5a8134683
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/runner/formatter/story/html_formatter.rb
@@ -0,0 +1,128 @@
+require 'erb'
+require 'spec/runner/formatter/base_text_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ module Story
+ class HtmlFormatter < BaseTextFormatter
+ include ERB::Util
+
+ def run_started(count)
+ @output.puts <<-EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <title>Stories</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Expires" content="-1" />
+ <meta http-equiv="Pragma" content="no-cache" />
+ <script src="javascripts/prototype.js" type="text/javascript"></script>
+ <script src="javascripts/scriptaculous.js" type="text/javascript"></script>
+ <script src="javascripts/rspec.js" type="text/javascript"></script>
+ <link href="stylesheets/rspec.css" rel="stylesheet" type="text/css" />
+ </head>
+ <body>
+ <div id="container">
+EOF
+ end
+
+ def collected_steps(steps)
+ unless steps.empty?
+ @output.puts " <ul id=\"stock_steps\" style=\"display: none;\">"
+ steps.each do |step|
+ @output.puts " <li>#{step}</li>"
+ end
+ @output.puts " </ul>"
+ end
+ end
+
+ def run_ended
+ @output.puts <<-EOF
+ </div>
+ </body>
+</head>
+EOF
+ end
+
+ def story_started(title, narrative)
+ @output.puts <<-EOF
+ <dl class="story passed">
+ <dt>Story: #{h title}</dt>
+ <dd>
+ <p>
+ #{h(narrative).split("\n").join("<br />")}
+ </p>
+EOF
+ end
+
+ def story_ended(title, narrative)
+ @output.puts <<-EOF
+ </dd>
+ </dl>
+EOF
+ end
+
+ def scenario_started(story_title, scenario_name)
+ @output.puts <<-EOF
+ <dl class="passed">
+ <dt>Scenario: #{h scenario_name}</dt>
+ <dd>
+ <ul class="steps">
+EOF
+ end
+
+ def scenario_ended
+ @output.puts <<-EOF
+ </ul>
+ </dd>
+ </dl>
+EOF
+ end
+
+ def found_scenario(type, description)
+ end
+
+ def scenario_succeeded(story_title, scenario_name)
+ scenario_ended
+ end
+
+ def scenario_pending(story_title, scenario_name, reason)
+ scenario_ended
+ end
+
+ def scenario_failed(story_title, scenario_name, err)
+ scenario_ended
+ end
+
+ def step_upcoming(type, description, *args)
+ end
+
+ def step_succeeded(type, description, *args)
+ print_step('passed', type, description, *args) # TODO: uses succeeded CSS class
+ end
+
+ def step_pending(type, description, *args)
+ print_step('pending', type, description, *args)
+ end
+
+ def step_failed(type, description, *args)
+ print_step('failed', type, description, *args)
+ end
+
+ def print_step(klass, type, description, *args)
+ spans = args.map { |arg| "<span class=\"param\">#{arg}</span>" }
+ desc_string = description.step_name
+ arg_regexp = description.arg_regexp
+ i = -1
+ inner = type.to_s.capitalize + ' ' + desc_string.gsub(arg_regexp) { |param| spans[i+=1] }
+ @output.puts " <li class=\"#{klass}\">#{inner}</li>"
+ end
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb b/vendor/gems/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb
new file mode 100644
index 000000000..ad7a2fa73
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/runner/formatter/story/plain_text_formatter.rb
@@ -0,0 +1,131 @@
+require 'spec/runner/formatter/base_text_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ module Story
+ class PlainTextFormatter < BaseTextFormatter
+ def initialize(options, where)
+ super
+ @successful_scenario_count = 0
+ @pending_scenario_count = 0
+ @failed_scenarios = []
+ @pending_steps = []
+ @previous_type = nil
+ end
+
+ def run_started(count)
+ @count = count
+ @output.puts "Running #@count scenarios\n\n"
+ end
+
+ def story_started(title, narrative)
+ @current_story_title = title
+ @output.puts "Story: #{title}\n\n"
+ narrative.each_line do |line|
+ @output.print " "
+ @output.print line
+ end
+ end
+
+ def story_ended(title, narrative)
+ @output.puts
+ @output.puts
+ end
+
+ def scenario_started(story_title, scenario_name)
+ @current_scenario_name = scenario_name
+ @scenario_already_failed = false
+ @output.print "\n\n Scenario: #{scenario_name}"
+ @scenario_ok = true
+ end
+
+ def scenario_succeeded(story_title, scenario_name)
+ @successful_scenario_count += 1
+ end
+
+ def scenario_failed(story_title, scenario_name, err)
+ @options.backtrace_tweaker.tweak_backtrace(err)
+ @failed_scenarios << [story_title, scenario_name, err] unless @scenario_already_failed
+ @scenario_already_failed = true
+ end
+
+ def scenario_pending(story_title, scenario_name, msg)
+ @pending_scenario_count += 1 unless @scenario_already_failed
+ @scenario_already_failed = true
+ end
+
+ def run_ended
+ @output.puts "#@count scenarios: #@successful_scenario_count succeeded, #{@failed_scenarios.size} failed, #@pending_scenario_count pending"
+ unless @pending_steps.empty?
+ @output.puts "\nPending Steps:"
+ @pending_steps.each_with_index do |pending, i|
+ story_name, scenario_name, msg = pending
+ @output.puts "#{i+1}) #{story_name} (#{scenario_name}): #{msg}"
+ end
+ end
+ unless @failed_scenarios.empty?
+ @output.print "\nFAILURES:"
+ @failed_scenarios.each_with_index do |failure, i|
+ title, scenario_name, err = failure
+ @output.print %[
+ #{i+1}) #{title} (#{scenario_name}) FAILED
+ #{err.class}: #{err.message}
+ #{err.backtrace.join("\n")}
+]
+ end
+ end
+ end
+
+ def step_upcoming(type, description, *args)
+ end
+
+ def step_succeeded(type, description, *args)
+ found_step(type, description, false, *args)
+ end
+
+ def step_pending(type, description, *args)
+ found_step(type, description, false, *args)
+ @pending_steps << [@current_story_title, @current_scenario_name, description]
+ @output.print " (PENDING)"
+ @scenario_ok = false
+ end
+
+ def step_failed(type, description, *args)
+ found_step(type, description, true, *args)
+ @output.print red(@scenario_ok ? " (FAILED)" : " (SKIPPED)")
+ @scenario_ok = false
+ end
+
+ def collected_steps(steps)
+ end
+
+ def method_missing(sym, *args, &block) #:nodoc:
+ # noop - ignore unknown messages
+ end
+
+ private
+
+ def found_step(type, description, failed, *args)
+ desc_string = description.step_name
+ arg_regexp = description.arg_regexp
+ text = if(type == @previous_type)
+ "\n And "
+ else
+ "\n\n #{type.to_s.capitalize} "
+ end
+ i = -1
+ text << desc_string.gsub(arg_regexp) { |param| args[i+=1] }
+ @output.print(failed ? red(text) : green(text))
+
+ if type == :'given scenario'
+ @previous_type = :given
+ else
+ @previous_type = type
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/runner/formatter/text_mate_formatter.rb b/vendor/gems/rspec/lib/spec/runner/formatter/text_mate_formatter.rb
new file mode 100644
index 000000000..4c0a9c7de
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/runner/formatter/text_mate_formatter.rb
@@ -0,0 +1,16 @@
+require 'spec/runner/formatter/html_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ # Formats backtraces so they're clickable by TextMate
+ class TextMateFormatter < HtmlFormatter
+ def backtrace_line(line)
+ line.gsub(/([^:]*\.rb):(\d*)/) do
+ "<a href=\"txmt://open?url=file://#{File.expand_path($1)}&line=#{$2}\">#{$1}:#{$2}</a> "
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/spec/runner/heckle_runner.rb b/vendor/gems/rspec/lib/spec/runner/heckle_runner.rb
index b6de4ef73..7695fe794 100644
--- a/spec/lib/spec/runner/heckle_runner.rb
+++ b/vendor/gems/rspec/lib/spec/runner/heckle_runner.rb
@@ -13,9 +13,9 @@ module Spec
@heckle_class = heckle_class
end
- # Runs all the contexts held by +behaviour_runner+ once for each of the
+ # Runs all the example groups held by +rspec_options+ once for each of the
# methods in the matched classes.
- def heckle_with(behaviour_runner)
+ def heckle_with
if @filter =~ /(.*)[#\.](.*)/
heckle_method($1, $2)
else
@@ -25,7 +25,7 @@ module Spec
def heckle_method(class_name, method_name)
verify_constant(class_name)
- heckle = @heckle_class.new(class_name, method_name, behaviour_runner)
+ heckle = @heckle_class.new(class_name, method_name, rspec_options)
heckle.validate
end
@@ -39,7 +39,7 @@ module Spec
classes.each do |klass|
klass.instance_methods(false).each do |method_name|
- heckle = @heckle_class.new(klass.name, method_name, behaviour_runner)
+ heckle = @heckle_class.new(klass.name, method_name, rspec_options)
heckle.validate
end
end
@@ -57,16 +57,16 @@ module Spec
#Supports Heckle 1.2 and prior (earlier versions used Heckle::Base)
class Heckler < (Heckle.const_defined?(:Base) ? Heckle::Base : Heckle)
- def initialize(klass_name, method_name, behaviour_runner)
+ def initialize(klass_name, method_name, rspec_options)
super(klass_name, method_name)
- @behaviour_runner = behaviour_runner
+ @rspec_options = rspec_options
end
def tests_pass?
- paths = [] # We can pass an empty array of paths - our specs are already loaded.
- failure_count = @behaviour_runner.run(paths, false)
- failure_count == 0
+ success = @rspec_options.run_examples
+ success
end
+
end
end
end
diff --git a/spec/lib/spec/runner/heckle_runner_unsupported.rb b/vendor/gems/rspec/lib/spec/runner/heckle_runner_unsupported.rb
index 02aa37953..02aa37953 100644
--- a/spec/lib/spec/runner/heckle_runner_unsupported.rb
+++ b/vendor/gems/rspec/lib/spec/runner/heckle_runner_unsupported.rb
diff --git a/vendor/gems/rspec/lib/spec/runner/option_parser.rb b/vendor/gems/rspec/lib/spec/runner/option_parser.rb
new file mode 100644
index 000000000..4bc84c812
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/runner/option_parser.rb
@@ -0,0 +1,201 @@
+require 'optparse'
+require 'stringio'
+
+module Spec
+ module Runner
+ class OptionParser < ::OptionParser
+ class << self
+ def parse(args, err, out)
+ parser = new(err, out)
+ parser.parse(args)
+ parser.options
+ end
+ end
+
+ attr_reader :options
+
+ OPTIONS = {
+ :pattern => ["-p", "--pattern [PATTERN]","Limit files loaded to those matching this pattern. Defaults to '**/*_spec.rb'",
+ "Separate multiple patterns with commas.",
+ "Applies only to directories named on the command line (files",
+ "named explicitly on the command line will be loaded regardless)."],
+ :diff => ["-D", "--diff [FORMAT]", "Show diff of objects that are expected to be equal when they are not",
+ "Builtin formats: unified|u|context|c",
+ "You can also specify a custom differ class",
+ "(in which case you should also specify --require)"],
+ :colour => ["-c", "--colour", "--color", "Show coloured (red/green) output"],
+ :example => ["-e", "--example [NAME|FILE_NAME]", "Execute example(s) with matching name(s). If the argument is",
+ "the path to an existing file (typically generated by a previous",
+ "run using --format failing_examples:file.txt), then the examples",
+ "on each line of thatfile will be executed. If the file is empty,",
+ "all examples will be run (as if --example was not specified).",
+ " ",
+ "If the argument is not an existing file, then it is treated as",
+ "an example name directly, causing RSpec to run just the example",
+ "matching that name"],
+ :specification => ["-s", "--specification [NAME]", "DEPRECATED - use -e instead", "(This will be removed when autotest works with -e)"],
+ :line => ["-l", "--line LINE_NUMBER", Integer, "Execute behaviout or specification at given line.",
+ "(does not work for dynamically generated specs)"],
+ :format => ["-f", "--format FORMAT[:WHERE]", "Specifies what format to use for output. Specify WHERE to tell",
+ "the formatter where to write the output. All built-in formats",
+ "expect WHERE to be a file name, and will write to STDOUT if it's",
+ "not specified. The --format option may be specified several times",
+ "if you want several outputs",
+ " ",
+ "Builtin formats for examples: ",
+ "progress|p : Text progress",
+ "profile|o : Text progress with profiling of 10 slowest examples",
+ "specdoc|s : Example doc as text",
+ "html|h : A nice HTML report",
+ "failing_examples|e : Write all failing examples - input for --example",
+ "failing_example_groups|g : Write all failing example groups - input for --example",
+ " ",
+ "Builtin formats for stories: ",
+ "plain|p : Plain Text",
+ "html|h : A nice HTML report",
+ " ",
+ "FORMAT can also be the name of a custom formatter class",
+ "(in which case you should also specify --require to load it)"],
+ :require => ["-r", "--require FILE", "Require FILE before running specs",
+ "Useful for loading custom formatters or other extensions.",
+ "If this option is used it must come before the others"],
+ :backtrace => ["-b", "--backtrace", "Output full backtrace"],
+ :loadby => ["-L", "--loadby STRATEGY", "Specify the strategy by which spec files should be loaded.",
+ "STRATEGY can currently only be 'mtime' (File modification time)",
+ "By default, spec files are loaded in alphabetical order if --loadby",
+ "is not specified."],
+ :reverse => ["-R", "--reverse", "Run examples in reverse order"],
+ :timeout => ["-t", "--timeout FLOAT", "Interrupt and fail each example that doesn't complete in the",
+ "specified time"],
+ :heckle => ["-H", "--heckle CODE", "If all examples pass, this will mutate the classes and methods",
+ "identified by CODE little by little and run all the examples again",
+ "for each mutation. The intent is that for each mutation, at least",
+ "one example *should* fail, and RSpec will tell you if this is not the",
+ "case. CODE should be either Some::Module, Some::Class or",
+ "Some::Fabulous#method}"],
+ :dry_run => ["-d", "--dry-run", "Invokes formatters without executing the examples."],
+ :options_file => ["-O", "--options PATH", "Read options from a file"],
+ :generate_options => ["-G", "--generate-options PATH", "Generate an options file for --options"],
+ :runner => ["-U", "--runner RUNNER", "Use a custom Runner."],
+ :drb => ["-X", "--drb", "Run examples via DRb. (For example against script/spec_server)"],
+ :version => ["-v", "--version", "Show version"],
+ :help => ["-h", "--help", "You're looking at it"]
+ }
+
+ def initialize(err, out)
+ super()
+ @error_stream = err
+ @out_stream = out
+ @options = Options.new(@error_stream, @out_stream)
+
+ @file_factory = File
+
+ self.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]"
+ self.separator ""
+ on(*OPTIONS[:pattern]) {|pattern| @options.filename_pattern = pattern}
+ on(*OPTIONS[:diff]) {|diff| @options.parse_diff(diff)}
+ on(*OPTIONS[:colour]) {@options.colour = true}
+ on(*OPTIONS[:example]) {|example| @options.parse_example(example)}
+ on(*OPTIONS[:specification]) {|example| @options.parse_example(example)}
+ on(*OPTIONS[:line]) {|line_number| @options.line_number = line_number.to_i}
+ on(*OPTIONS[:format]) {|format| @options.parse_format(format)}
+ on(*OPTIONS[:require]) {|requires| invoke_requires(requires)}
+ on(*OPTIONS[:backtrace]) {@options.backtrace_tweaker = NoisyBacktraceTweaker.new}
+ on(*OPTIONS[:loadby]) {|loadby| @options.loadby = loadby}
+ on(*OPTIONS[:reverse]) {@options.reverse = true}
+ on(*OPTIONS[:timeout]) {|timeout| @options.timeout = timeout.to_f}
+ on(*OPTIONS[:heckle]) {|heckle| @options.load_heckle_runner(heckle)}
+ on(*OPTIONS[:dry_run]) {@options.dry_run = true}
+ on(*OPTIONS[:options_file]) {|options_file| parse_options_file(options_file)}
+ on(*OPTIONS[:generate_options]) do |options_file|
+ end
+ on(*OPTIONS[:runner]) do |runner|
+ @options.user_input_for_runner = runner
+ end
+ on(*OPTIONS[:drb]) {}
+ on(*OPTIONS[:version]) {parse_version}
+ on_tail(*OPTIONS[:help]) {parse_help}
+ end
+
+ def order!(argv, &blk)
+ @argv = argv
+ @options.argv = @argv.dup
+ return if parse_generate_options
+ return if parse_drb
+
+ super(@argv) do |file|
+ @options.files << file
+ blk.call(file) if blk
+ end
+
+ @options
+ end
+
+ protected
+ def invoke_requires(requires)
+ requires.split(",").each do |file|
+ require file
+ end
+ end
+
+ def parse_options_file(options_file)
+ option_file_args = IO.readlines(options_file).map {|l| l.chomp.split " "}.flatten
+ @argv.push(*option_file_args)
+ end
+
+ def parse_generate_options
+ # Remove the --generate-options option and the argument before writing to file
+ options_file = nil
+ ['-G', '--generate-options'].each do |option|
+ if index = @argv.index(option)
+ @argv.delete_at(index)
+ options_file = @argv.delete_at(index)
+ end
+ end
+
+ if options_file
+ write_generated_options(options_file)
+ return true
+ else
+ return false
+ end
+ end
+
+ def write_generated_options(options_file)
+ File.open(options_file, 'w') do |io|
+ io.puts @argv.join("\n")
+ end
+ @out_stream.puts "\nOptions written to #{options_file}. You can now use these options with:"
+ @out_stream.puts "spec --options #{options_file}"
+ @options.examples_should_not_be_run
+ end
+
+ def parse_drb
+ is_drb = false
+ argv = @options.argv
+ is_drb ||= argv.delete(OPTIONS[:drb][0])
+ is_drb ||= argv.delete(OPTIONS[:drb][1])
+ return nil unless is_drb
+ @options.examples_should_not_be_run
+ DrbCommandLine.run(
+ self.class.parse(argv, @error_stream, @out_stream)
+ )
+ true
+ end
+
+ def parse_version
+ @out_stream.puts ::Spec::VERSION::DESCRIPTION
+ exit if stdout?
+ end
+
+ def parse_help
+ @out_stream.puts self
+ exit if stdout?
+ end
+
+ def stdout?
+ @out_stream == $stdout
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/runner/options.rb b/vendor/gems/rspec/lib/spec/runner/options.rb
new file mode 100644
index 000000000..108749c42
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/runner/options.rb
@@ -0,0 +1,286 @@
+module Spec
+ module Runner
+ class Options
+ FILE_SORTERS = {
+ 'mtime' => lambda {|file_a, file_b| File.mtime(file_b) <=> File.mtime(file_a)}
+ }
+
+ EXAMPLE_FORMATTERS = { # Load these lazily for better speed
+ 'specdoc' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'],
+ 's' => ['spec/runner/formatter/specdoc_formatter', 'Formatter::SpecdocFormatter'],
+ 'html' => ['spec/runner/formatter/html_formatter', 'Formatter::HtmlFormatter'],
+ 'h' => ['spec/runner/formatter/html_formatter', 'Formatter::HtmlFormatter'],
+ 'progress' => ['spec/runner/formatter/progress_bar_formatter', 'Formatter::ProgressBarFormatter'],
+ 'p' => ['spec/runner/formatter/progress_bar_formatter', 'Formatter::ProgressBarFormatter'],
+ 'failing_examples' => ['spec/runner/formatter/failing_examples_formatter', 'Formatter::FailingExamplesFormatter'],
+ 'e' => ['spec/runner/formatter/failing_examples_formatter', 'Formatter::FailingExamplesFormatter'],
+'failing_example_groups' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'],
+ 'g' => ['spec/runner/formatter/failing_example_groups_formatter', 'Formatter::FailingExampleGroupsFormatter'],
+ 'profile' => ['spec/runner/formatter/profile_formatter', 'Formatter::ProfileFormatter'],
+ 'o' => ['spec/runner/formatter/profile_formatter', 'Formatter::ProfileFormatter'],
+ 'textmate' => ['spec/runner/formatter/text_mate_formatter', 'Formatter::TextMateFormatter']
+ }
+
+ STORY_FORMATTERS = {
+ 'plain' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'],
+ 'p' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'],
+ 'html' => ['spec/runner/formatter/story/html_formatter', 'Formatter::Story::HtmlFormatter'],
+ 'h' => ['spec/runner/formatter/story/html_formatter', 'Formatter::Story::HtmlFormatter']
+ }
+
+ attr_accessor(
+ :filename_pattern,
+ :backtrace_tweaker,
+ :context_lines,
+ :diff_format,
+ :dry_run,
+ :profile,
+ :examples,
+ :heckle_runner,
+ :line_number,
+ :loadby,
+ :reporter,
+ :reverse,
+ :timeout,
+ :verbose,
+ :user_input_for_runner,
+ :error_stream,
+ :output_stream,
+ # TODO: BT - Figure out a better name
+ :argv
+ )
+ attr_reader :colour, :differ_class, :files, :example_groups
+
+ def initialize(error_stream, output_stream)
+ @error_stream = error_stream
+ @output_stream = output_stream
+ @filename_pattern = "**/*_spec.rb"
+ @backtrace_tweaker = QuietBacktraceTweaker.new
+ @examples = []
+ @colour = false
+ @profile = false
+ @dry_run = false
+ @reporter = Reporter.new(self)
+ @context_lines = 3
+ @diff_format = :unified
+ @files = []
+ @example_groups = []
+ @examples_run = false
+ @examples_should_be_run = nil
+ @user_input_for_runner = nil
+ end
+
+ def add_example_group(example_group)
+ @example_groups << example_group
+ end
+
+ def remove_example_group(example_group)
+ @example_groups.delete(example_group)
+ end
+
+ def run_examples
+ return true unless examples_should_be_run?
+ runner = custom_runner || ExampleGroupRunner.new(self)
+
+ runner.load_files(files_to_load)
+ if example_groups.empty?
+ true
+ else
+ set_spec_from_line_number if line_number
+ success = runner.run
+ @examples_run = true
+ heckle if heckle_runner
+ success
+ end
+ end
+
+ def examples_run?
+ @examples_run
+ end
+
+ def examples_should_not_be_run
+ @examples_should_be_run = false
+ end
+
+ def colour=(colour)
+ @colour = colour
+ if @colour && RUBY_PLATFORM =~ /win32/ ;\
+ begin ;\
+ require 'rubygems' ;\
+ require 'Win32/Console/ANSI' ;\
+ rescue LoadError ;\
+ warn "You must 'gem install win32console' to use colour on Windows" ;\
+ @colour = false ;\
+ end
+ end
+ end
+
+ def parse_diff(format)
+ case format
+ when :context, 'context', 'c'
+ @diff_format = :context
+ default_differ
+ when :unified, 'unified', 'u', '', nil
+ @diff_format = :unified
+ default_differ
+ else
+ @diff_format = :custom
+ self.differ_class = load_class(format, 'differ', '--diff')
+ end
+ end
+
+ def parse_example(example)
+ if(File.file?(example))
+ @examples = File.open(example).read.split("\n")
+ else
+ @examples = [example]
+ end
+ end
+
+ def parse_format(format_arg)
+ format, where = ClassAndArgumentsParser.parse(format_arg)
+ unless where
+ raise "When using several --format options only one of them can be without a file" if @out_used
+ where = @output_stream
+ @out_used = true
+ end
+ @format_options ||= []
+ @format_options << [format, where]
+ end
+
+ def formatters
+ @format_options ||= [['progress', @output_stream]]
+ @formatters ||= load_formatters(@format_options, EXAMPLE_FORMATTERS)
+ end
+
+ def story_formatters
+ @format_options ||= [['plain', @output_stream]]
+ @formatters ||= load_formatters(@format_options, STORY_FORMATTERS)
+ end
+
+ def load_formatters(format_options, formatters)
+ format_options.map do |format, where|
+ formatter_type = if formatters[format]
+ require formatters[format][0]
+ eval(formatters[format][1], binding, __FILE__, __LINE__)
+ else
+ load_class(format, 'formatter', '--format')
+ end
+ formatter_type.new(self, where)
+ end
+ end
+
+ def load_heckle_runner(heckle)
+ suffix = [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM} ? '_unsupported' : ''
+ require "spec/runner/heckle_runner#{suffix}"
+ @heckle_runner = HeckleRunner.new(heckle)
+ end
+
+ def number_of_examples
+ @example_groups.inject(0) do |sum, example_group|
+ sum + example_group.number_of_examples
+ end
+ end
+
+ def files_to_load
+ result = []
+ sorted_files.each do |file|
+ if File.directory?(file)
+ filename_pattern.split(",").each do |pattern|
+ result += Dir[File.expand_path("#{file}/#{pattern.strip}")]
+ end
+ elsif File.file?(file)
+ result << file
+ else
+ raise "File or directory not found: #{file}"
+ end
+ end
+ result
+ end
+
+ protected
+ def examples_should_be_run?
+ return @examples_should_be_run unless @examples_should_be_run.nil?
+ @examples_should_be_run = true
+ end
+
+ def differ_class=(klass)
+ return unless klass
+ @differ_class = klass
+ Spec::Expectations.differ = self.differ_class.new(self)
+ end
+
+ def load_class(name, kind, option)
+ if name =~ /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/
+ arg = $2 == "" ? nil : $2
+ [$1, arg]
+ else
+ m = "#{name.inspect} is not a valid class name"
+ @error_stream.puts m
+ raise m
+ end
+ begin
+ eval(name, binding, __FILE__, __LINE__)
+ rescue NameError => e
+ @error_stream.puts "Couldn't find #{kind} class #{name}"
+ @error_stream.puts "Make sure the --require option is specified *before* #{option}"
+ if $_spec_spec ; raise e ; else exit(1) ; end
+ end
+ end
+
+ def custom_runner
+ return nil unless custom_runner?
+ klass_name, arg = ClassAndArgumentsParser.parse(user_input_for_runner)
+ runner_type = load_class(klass_name, 'behaviour runner', '--runner')
+ return runner_type.new(self, arg)
+ end
+
+ def custom_runner?
+ return user_input_for_runner ? true : false
+ end
+
+ def heckle
+ returns = self.heckle_runner.heckle_with
+ self.heckle_runner = nil
+ returns
+ end
+
+ def sorted_files
+ return sorter ? files.sort(&sorter) : files
+ end
+
+ def sorter
+ FILE_SORTERS[loadby]
+ end
+
+ def default_differ
+ require 'spec/expectations/differs/default'
+ self.differ_class = Spec::Expectations::Differs::Default
+ end
+
+ def set_spec_from_line_number
+ if examples.empty?
+ if files.length == 1
+ if File.directory?(files[0])
+ error_stream.puts "You must specify one file, not a directory when using the --line option"
+ exit(1) if stderr?
+ else
+ example = SpecParser.new.spec_name_for(files[0], line_number)
+ @examples = [example]
+ end
+ else
+ error_stream.puts "Only one file can be specified when using the --line option: #{files.inspect}"
+ exit(3) if stderr?
+ end
+ else
+ error_stream.puts "You cannot use both --line and --example"
+ exit(4) if stderr?
+ end
+ end
+
+ def stderr?
+ @error_stream == $stderr
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/runner/reporter.rb b/vendor/gems/rspec/lib/spec/runner/reporter.rb
new file mode 100644
index 000000000..cfc511baf
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/runner/reporter.rb
@@ -0,0 +1,143 @@
+module Spec
+ module Runner
+ class Reporter
+ attr_reader :options, :example_groups
+
+ def initialize(options)
+ @options = options
+ @options.reporter = self
+ clear
+ end
+
+ def add_example_group(example_group)
+ formatters.each do |f|
+ f.add_example_group(example_group)
+ end
+ example_groups << example_group
+ end
+
+ def example_started(example)
+ formatters.each{|f| f.example_started(example)}
+ end
+
+ def example_finished(example, error=nil)
+ @examples << example
+
+ if error.nil?
+ example_passed(example)
+ elsif Spec::Example::ExamplePendingError === error
+ example_pending(example_groups.last, example, error.message)
+ else
+ example_failed(example, error)
+ end
+ end
+
+ def failure(example, error)
+ backtrace_tweaker.tweak_backtrace(error)
+ example_name = "#{example_groups.last.description} #{example.description}"
+ failure = Failure.new(example_name, error)
+ @failures << failure
+ formatters.each do |f|
+ f.example_failed(example, @failures.length, failure)
+ end
+ end
+ alias_method :example_failed, :failure
+
+ def start(number_of_examples)
+ clear
+ @start_time = Time.new
+ formatters.each{|f| f.start(number_of_examples)}
+ end
+
+ def end
+ @end_time = Time.new
+ end
+
+ # Dumps the summary and returns the total number of failures
+ def dump
+ formatters.each{|f| f.start_dump}
+ dump_pending
+ dump_failures
+ formatters.each do |f|
+ f.dump_summary(duration, @examples.length, @failures.length, @pending_count)
+ f.close
+ end
+ @failures.length
+ end
+
+ private
+
+ def formatters
+ @options.formatters
+ end
+
+ def backtrace_tweaker
+ @options.backtrace_tweaker
+ end
+
+ def clear
+ @example_groups = []
+ @failures = []
+ @pending_count = 0
+ @examples = []
+ @start_time = nil
+ @end_time = nil
+ end
+
+ def dump_failures
+ return if @failures.empty?
+ @failures.inject(1) do |index, failure|
+ formatters.each{|f| f.dump_failure(index, failure)}
+ index + 1
+ end
+ end
+ def dump_pending
+ formatters.each{|f| f.dump_pending}
+ end
+
+ def duration
+ return @end_time - @start_time unless (@end_time.nil? or @start_time.nil?)
+ return "0.0"
+ end
+
+ def example_passed(example)
+ formatters.each{|f| f.example_passed(example)}
+ end
+
+ def example_pending(example_group, example, message="Not Yet Implemented")
+ @pending_count += 1
+ formatters.each do |f|
+ f.example_pending(example_group.description, example, message)
+ end
+ end
+
+ class Failure
+ attr_reader :exception
+
+ def initialize(example_name, exception)
+ @example_name = example_name
+ @exception = exception
+ end
+
+ def header
+ if expectation_not_met?
+ "'#{@example_name}' FAILED"
+ elsif pending_fixed?
+ "'#{@example_name}' FIXED"
+ else
+ "#{@exception.class.name} in '#{@example_name}'"
+ end
+ end
+
+ def pending_fixed?
+ @exception.is_a?(Spec::Example::PendingExampleFixedError)
+ end
+
+ def expectation_not_met?
+ @exception.is_a?(Spec::Expectations::ExpectationNotMetError)
+ end
+
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/runner/spec_parser.rb b/vendor/gems/rspec/lib/spec/runner/spec_parser.rb
new file mode 100644
index 000000000..8beb384e9
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/runner/spec_parser.rb
@@ -0,0 +1,71 @@
+module Spec
+ module Runner
+ # Parses a spec file and finds the nearest example for a given line number.
+ class SpecParser
+ attr_reader :best_match
+
+ def initialize
+ @best_match = {}
+ end
+
+ def spec_name_for(file, line_number)
+ best_match.clear
+ file = File.expand_path(file)
+ rspec_options.example_groups.each do |example_group|
+ consider_example_groups_for_best_match example_group, file, line_number
+
+ example_group.examples.each do |example|
+ consider_example_for_best_match example, example_group, file, line_number
+ end
+ end
+ if best_match[:example_group]
+ if best_match[:example]
+ "#{best_match[:example_group].description} #{best_match[:example].description}"
+ else
+ best_match[:example_group].description
+ end
+ else
+ nil
+ end
+ end
+
+ protected
+
+ def consider_example_groups_for_best_match(example_group, file, line_number)
+ parsed_backtrace = parse_backtrace(example_group.registration_backtrace)
+ parsed_backtrace.each do |example_file, example_line|
+ if is_best_match?(file, line_number, example_file, example_line)
+ best_match.clear
+ best_match[:example_group] = example_group
+ best_match[:line] = example_line
+ end
+ end
+ end
+
+ def consider_example_for_best_match(example, example_group, file, line_number)
+ parsed_backtrace = parse_backtrace(example.implementation_backtrace)
+ parsed_backtrace.each do |example_file, example_line|
+ if is_best_match?(file, line_number, example_file, example_line)
+ best_match.clear
+ best_match[:example_group] = example_group
+ best_match[:example] = example
+ best_match[:line] = example_line
+ end
+ end
+ end
+
+ def is_best_match?(file, line_number, example_file, example_line)
+ file == File.expand_path(example_file) &&
+ example_line <= line_number &&
+ example_line > best_match[:line].to_i
+ end
+
+ def parse_backtrace(backtrace)
+ backtrace.collect do |trace_line|
+ split_line = trace_line.split(':')
+ [split_line[0], Integer(split_line[1])]
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/story.rb b/vendor/gems/rspec/lib/spec/story.rb
new file mode 100644
index 000000000..bc6960a28
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story.rb
@@ -0,0 +1,10 @@
+require 'spec'
+require 'spec/story/extensions'
+require 'spec/story/given_scenario'
+require 'spec/story/runner'
+require 'spec/story/scenario'
+require 'spec/story/step'
+require 'spec/story/step_group'
+require 'spec/story/step_mother'
+require 'spec/story/story'
+require 'spec/story/world'
diff --git a/vendor/gems/rspec/lib/spec/story/extensions.rb b/vendor/gems/rspec/lib/spec/story/extensions.rb
new file mode 100644
index 000000000..dc7dd1140
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/extensions.rb
@@ -0,0 +1,3 @@
+require 'spec/story/extensions/main'
+require 'spec/story/extensions/string'
+require 'spec/story/extensions/regexp'
diff --git a/vendor/gems/rspec/lib/spec/story/extensions/main.rb b/vendor/gems/rspec/lib/spec/story/extensions/main.rb
new file mode 100644
index 000000000..6336b630c
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/extensions/main.rb
@@ -0,0 +1,86 @@
+module Spec
+ module Story
+ module Extensions
+ module Main
+ def Story(title, narrative, params = {}, &body)
+ ::Spec::Story::Runner.story_runner.Story(title, narrative, params, &body)
+ end
+
+ # Calling this deprecated is silly, since it hasn't been released yet. But, for
+ # those who are reading this - this will be deleted before the 1.1 release.
+ def run_story(*args, &block)
+ runner = Spec::Story::Runner::PlainTextStoryRunner.new(*args)
+ runner.instance_eval(&block) if block
+ runner.run
+ end
+
+ # Creates (or appends to an existing) a namespaced group of steps for use in Stories
+ #
+ # == Examples
+ #
+ # # Creating a new group
+ # steps_for :forms do
+ # When("user enters $value in the $field field") do ... end
+ # When("user submits the $form form") do ... end
+ # end
+ def steps_for(tag, &block)
+ steps = rspec_story_steps[tag]
+ steps.instance_eval(&block) if block
+ steps
+ end
+
+ # Creates a context for running a Plain Text Story with specific groups of Steps.
+ # Also supports adding arbitrary steps that will only be accessible to
+ # the Story being run.
+ #
+ # == Examples
+ #
+ # # Run a Story with one group of steps
+ # with_steps_for :checking_accounts do
+ # run File.dirname(__FILE__) + "/withdraw_cash"
+ # end
+ #
+ # # Run a Story, adding steps that are only available for this Story
+ # with_steps_for :accounts do
+ # Given "user is logged in as account administrator"
+ # run File.dirname(__FILE__) + "/reconcile_accounts"
+ # end
+ #
+ # # Run a Story with steps from two groups
+ # with_steps_for :checking_accounts, :savings_accounts do
+ # run File.dirname(__FILE__) + "/transfer_money"
+ # end
+ #
+ # # Run a Story with a specific Story extension
+ # with_steps_for :login, :navigation do
+ # run File.dirname(__FILE__) + "/user_changes_password", :type => RailsStory
+ # end
+ def with_steps_for(*tags, &block)
+ steps = Spec::Story::StepGroup.new do
+ extend StoryRunnerStepGroupAdapter
+ end
+ tags.each {|tag| steps << rspec_story_steps[tag]}
+ steps.instance_eval(&block) if block
+ steps
+ end
+
+ private
+
+ module StoryRunnerStepGroupAdapter
+ def run(path, options={})
+ runner = Spec::Story::Runner::PlainTextStoryRunner.new(path, options)
+ runner.steps << self
+ runner.run
+ end
+ end
+
+ def rspec_story_steps # :nodoc:
+ $rspec_story_steps ||= Spec::Story::StepGroupHash.new
+ end
+
+ end
+ end
+ end
+end
+
+include Spec::Story::Extensions::Main \ No newline at end of file
diff --git a/vendor/gems/rspec/lib/spec/story/extensions/regexp.rb b/vendor/gems/rspec/lib/spec/story/extensions/regexp.rb
new file mode 100644
index 000000000..7955b4c33
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/extensions/regexp.rb
@@ -0,0 +1,9 @@
+class Regexp
+ def step_name
+ self.source
+ end
+
+ def arg_regexp
+ ::Spec::Story::Step::PARAM_OR_GROUP_PATTERN
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/lib/spec/story/extensions/string.rb b/vendor/gems/rspec/lib/spec/story/extensions/string.rb
new file mode 100644
index 000000000..896578def
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/extensions/string.rb
@@ -0,0 +1,9 @@
+class String
+ def step_name
+ self
+ end
+
+ def arg_regexp
+ ::Spec::Story::Step::PARAM_PATTERN
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/lib/spec/story/given_scenario.rb b/vendor/gems/rspec/lib/spec/story/given_scenario.rb
new file mode 100644
index 000000000..88c51f981
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/given_scenario.rb
@@ -0,0 +1,14 @@
+module Spec
+ module Story
+ class GivenScenario
+ def initialize(name)
+ @name = name
+ end
+
+ def perform(instance, ignore_name)
+ scenario = Runner::StoryRunner.scenario_from_current_story(@name)
+ Runner::ScenarioRunner.new.run(scenario, instance)
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/story/runner.rb b/vendor/gems/rspec/lib/spec/story/runner.rb
new file mode 100644
index 000000000..1f6dd9e7a
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/runner.rb
@@ -0,0 +1,56 @@
+require 'spec/story/runner/scenario_collector.rb'
+require 'spec/story/runner/scenario_runner.rb'
+require 'spec/story/runner/story_runner.rb'
+require 'spec/story/runner/story_parser.rb'
+require 'spec/story/runner/story_mediator.rb'
+require 'spec/story/runner/plain_text_story_runner.rb'
+
+module Spec
+ module Story
+ module Runner
+ class << self
+ def run_options # :nodoc:
+ @run_options ||= ::Spec::Runner::OptionParser.parse(ARGV, $stderr, $stdout)
+ end
+
+ def story_runner # :nodoc:
+ unless @story_runner
+ @story_runner = StoryRunner.new(scenario_runner, world_creator)
+ run_options.story_formatters.each do |formatter|
+ register_listener(formatter)
+ end
+ Runner.register_exit_hook
+ end
+ @story_runner
+ end
+
+ def scenario_runner # :nodoc:
+ @scenario_runner ||= ScenarioRunner.new
+ end
+
+ def world_creator # :nodoc:
+ @world_creator ||= World
+ end
+
+ # Use this to register a customer output formatter.
+ def register_listener(listener)
+ story_runner.add_listener(listener) # run_started, story_started, story_ended, #run_ended
+ world_creator.add_listener(listener) # found_scenario, step_succeeded, step_failed, step_failed
+ scenario_runner.add_listener(listener) # scenario_started, scenario_succeeded, scenario_pending, scenario_failed
+ end
+
+ def register_exit_hook # :nodoc:
+ at_exit do
+ Runner.story_runner.run_stories unless $!
+ end
+ # TODO exit with non-zero status if run fails
+ end
+
+ def dry_run
+ run_options.dry_run
+ end
+
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/story/runner/plain_text_story_runner.rb b/vendor/gems/rspec/lib/spec/story/runner/plain_text_story_runner.rb
new file mode 100644
index 000000000..8d34ea2d2
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/runner/plain_text_story_runner.rb
@@ -0,0 +1,48 @@
+module Spec
+ module Story
+ module Runner
+ class PlainTextStoryRunner
+ # You can initialize a PlainTextStoryRunner with the path to the
+ # story file or a block, in which you can define the path using load.
+ #
+ # == Examples
+ #
+ # PlainTextStoryRunner.new('path/to/file')
+ #
+ # PlainTextStoryRunner.new do |runner|
+ # runner.load 'path/to/file'
+ # end
+ def initialize(*args)
+ @options = Hash === args.last ? args.pop : {}
+ @story_file = args.empty? ? nil : args.shift
+ yield self if block_given?
+ end
+
+ def []=(key, value)
+ @options[key] = value
+ end
+
+ def load(path)
+ @story_file = path
+ end
+
+ def run
+ raise "You must set a path to the file with the story. See the RDoc." if @story_file.nil?
+ mediator = Spec::Story::Runner::StoryMediator.new(steps, Spec::Story::Runner.story_runner, @options)
+ parser = Spec::Story::Runner::StoryParser.new(mediator)
+
+ story_text = File.read(@story_file)
+ parser.parse(story_text.split("\n"))
+
+ mediator.run_stories
+ end
+
+ def steps
+ @step_group ||= Spec::Story::StepGroup.new
+ yield @step_group if block_given?
+ @step_group
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/story/runner/scenario_collector.rb b/vendor/gems/rspec/lib/spec/story/runner/scenario_collector.rb
new file mode 100644
index 000000000..78339fd22
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/runner/scenario_collector.rb
@@ -0,0 +1,18 @@
+module Spec
+ module Story
+ module Runner
+ class ScenarioCollector
+ attr_accessor :scenarios
+
+ def initialize(story)
+ @story = story
+ @scenarios = []
+ end
+
+ def Scenario(name, &body)
+ @scenarios << Scenario.new(@story, name, &body)
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/story/runner/scenario_runner.rb b/vendor/gems/rspec/lib/spec/story/runner/scenario_runner.rb
new file mode 100644
index 000000000..aee52e412
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/runner/scenario_runner.rb
@@ -0,0 +1,46 @@
+module Spec
+ module Story
+ module Runner
+ class ScenarioRunner
+ def initialize
+ @listeners = []
+ end
+
+ def run(scenario, world)
+ @listeners.each { |l| l.scenario_started(scenario.story.title, scenario.name) }
+ run_story_ignoring_scenarios(scenario.story, world)
+
+ world.start_collecting_errors
+ world.instance_eval(&scenario.body)
+ if world.errors.empty?
+ @listeners.each { |l| l.scenario_succeeded(scenario.story.title, scenario.name) }
+ else
+ if Spec::Example::ExamplePendingError === (e = world.errors.first)
+ @listeners.each { |l| l.scenario_pending(scenario.story.title, scenario.name, e.message) }
+ else
+ @listeners.each { |l| l.scenario_failed(scenario.story.title, scenario.name, e) }
+ end
+ end
+ end
+
+ def add_listener(listener)
+ @listeners << listener
+ end
+
+ private
+
+ def run_story_ignoring_scenarios(story, world)
+ class << world
+ def Scenario(name, &block)
+ # do nothing
+ end
+ end
+ story.run_in(world)
+ class << world
+ remove_method(:Scenario)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/story/runner/story_mediator.rb b/vendor/gems/rspec/lib/spec/story/runner/story_mediator.rb
new file mode 100644
index 000000000..1f4744b9f
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/runner/story_mediator.rb
@@ -0,0 +1,123 @@
+ module Spec
+ module Story
+ module Runner
+
+ class StoryMediator
+ def initialize(step_group, runner, options={})
+ @step_group = step_group
+ @stories = []
+ @runner = runner
+ @options = options
+ end
+
+ def stories
+ @stories.collect { |p| p.to_proc }
+ end
+
+ def create_story(title, narrative)
+ @stories << Story.new(title, narrative, @step_group, @options)
+ end
+
+ def create_scenario(title)
+ current_story.add_scenario Scenario.new(title)
+ end
+
+ def create_given(name)
+ current_scenario.add_step Step.new('Given', name)
+ end
+
+ def create_given_scenario(name)
+ current_scenario.add_step Step.new('GivenScenario', name)
+ end
+
+ def create_when(name)
+ current_scenario.add_step Step.new('When', name)
+ end
+
+ def create_then(name)
+ current_scenario.add_step Step.new('Then', name)
+ end
+
+ def run_stories
+ stories.each { |story| @runner.instance_eval(&story) }
+ end
+
+ private
+ def current_story
+ @stories.last
+ end
+
+ def current_scenario
+ current_story.current_scenario
+ end
+
+ class Story
+ def initialize(title, narrative, step_group, options)
+ @title = title
+ @narrative = narrative
+ @scenarios = []
+ @step_group = step_group
+ @options = options
+ end
+
+ def to_proc
+ title = @title
+ narrative = @narrative
+ scenarios = @scenarios.collect { |scenario| scenario.to_proc }
+ options = @options.merge(:steps => @step_group)
+ lambda do
+ Story title, narrative, options do
+ scenarios.each { |scenario| instance_eval(&scenario) }
+ end
+ end
+ end
+
+ def add_scenario(scenario)
+ @scenarios << scenario
+ end
+
+ def current_scenario
+ @scenarios.last
+ end
+ end
+
+ class Scenario
+ def initialize(name)
+ @name = name
+ @steps = []
+ end
+
+ def to_proc
+ name = @name
+ steps = @steps.collect { |step| step.to_proc }
+ lambda do
+ Scenario name do
+ steps.each { |step| instance_eval(&step) }
+ end
+ end
+ end
+
+ def add_step(step)
+ @steps << step
+ end
+ end
+
+ class Step
+ def initialize(type, name)
+ @type = type
+ @name = name
+ end
+
+ def to_proc
+ type = @type
+ name = @name
+ lambda do
+ send(type, name)
+ end
+ end
+ end
+ end
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/story/runner/story_parser.rb b/vendor/gems/rspec/lib/spec/story/runner/story_parser.rb
new file mode 100644
index 000000000..d454df8cb
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/runner/story_parser.rb
@@ -0,0 +1,227 @@
+module Spec
+ module Story
+ module Runner
+
+ class IllegalStepError < StandardError
+ def initialize(state, event)
+ super("Illegal attempt to create a #{event} after a #{state}")
+ end
+ end
+
+ class StoryParser
+ def initialize(story_mediator)
+ @story_mediator = story_mediator
+ @current_story_lines = []
+ transition_to(:starting_state)
+ end
+
+ def parse(lines)
+ lines.reject! {|line| line == ""}
+ until lines.empty?
+ process_line(lines.shift)
+ end
+ @state.eof
+ end
+
+ def process_line(line)
+ line.strip!
+ case line
+ when /^Story: / then @state.story(line)
+ when /^Scenario: / then @state.scenario(line)
+ when /^Given:? / then @state.given(line)
+ when /^GivenScenario:? / then @state.given_scenario(line)
+ when /^When:? / then @state.event(line)
+ when /^Then:? / then @state.outcome(line)
+ when /^And:? / then @state.one_more_of_the_same(line)
+ else @state.other(line)
+ end
+ end
+
+ def init_story(title)
+ @current_story_lines.clear
+ add_story_line(title)
+ end
+
+ def add_story_line(line)
+ @current_story_lines << line
+ end
+
+ def create_story()
+ unless @current_story_lines.empty?
+ @story_mediator.create_story(@current_story_lines[0].gsub("Story: ",""), @current_story_lines[1..-1].join("\n"))
+ @current_story_lines.clear
+ end
+ end
+
+ def create_scenario(title)
+ @story_mediator.create_scenario(title.gsub("Scenario: ",""))
+ end
+
+ def create_given(name)
+ @story_mediator.create_given(name)
+ end
+
+ def create_given_scenario(name)
+ @story_mediator.create_given_scenario(name)
+ end
+
+ def create_when(name)
+ @story_mediator.create_when(name)
+ end
+
+ def create_then(name)
+ @story_mediator.create_then(name)
+ end
+
+ def transition_to(key)
+ @state = states[key]
+ end
+
+ def states
+ @states ||= {
+ :starting_state => StartingState.new(self),
+ :story_state => StoryState.new(self),
+ :scenario_state => ScenarioState.new(self),
+ :given_state => GivenState.new(self),
+ :when_state => WhenState.new(self),
+ :then_state => ThenState.new(self)
+ }
+ end
+
+ class State
+ def initialize(parser)
+ @parser = parser
+ end
+
+ def story(line)
+ @parser.init_story(line)
+ @parser.transition_to(:story_state)
+ end
+
+ def scenario(line)
+ @parser.create_scenario(line)
+ @parser.transition_to(:scenario_state)
+ end
+
+ def given(line)
+ @parser.create_given(remove_tag_from(:given, line))
+ @parser.transition_to(:given_state)
+ end
+
+ def given_scenario(line)
+ @parser.create_given_scenario(remove_tag_from(:givenscenario, line))
+ @parser.transition_to(:given_state)
+ end
+
+ def event(line)
+ @parser.create_when(remove_tag_from(:when, line))
+ @parser.transition_to(:when_state)
+ end
+
+ def outcome(line)
+ @parser.create_then(remove_tag_from(:then, line))
+ @parser.transition_to(:then_state)
+ end
+
+ def remove_tag_from(tag, line)
+ tokens = line.split
+ # validation of tag can go here
+ tokens[0].downcase.match(/#{tag.to_s}:?/) ?
+ (tokens[1..-1].join(' ')) : line
+ end
+
+ def eof
+ end
+
+ def other(line)
+ # no-op - supports header text before the first story in a file
+ end
+ end
+
+ class StartingState < State
+ def initialize(parser)
+ @parser = parser
+ end
+ end
+
+ class StoryState < State
+ def one_more_of_the_same(line)
+ other(line)
+ end
+
+ def story(line)
+ @parser.create_story
+ @parser.add_story_line(line)
+ end
+
+ def scenario(line)
+ @parser.create_story
+ @parser.create_scenario(line)
+ @parser.transition_to(:scenario_state)
+ end
+
+ def given(line)
+ other(line)
+ end
+
+ def event(line)
+ other(line)
+ end
+
+ def outcome(line)
+ other(line)
+ end
+
+ def other(line)
+ @parser.add_story_line(line)
+ end
+
+ def eof
+ @parser.create_story
+ end
+ end
+
+ class ScenarioState < State
+ def one_more_of_the_same(line)
+ raise IllegalStepError.new("Scenario", "And")
+ end
+
+ def scenario(line)
+ @parser.create_scenario(line)
+ end
+ end
+
+ class GivenState < State
+ def one_more_of_the_same(line)
+ @parser.create_given(remove_tag_from(:and, line))
+ end
+
+ def given(line)
+ @parser.create_given(remove_tag_from(:given, line))
+ end
+ end
+
+ class WhenState < State
+ def one_more_of_the_same(line)
+ @parser.create_when(remove_tag_from(:and ,line))
+ end
+
+ def event(line)
+ @parser.create_when(remove_tag_from(:when ,line))
+ end
+ end
+
+ class ThenState < State
+ def one_more_of_the_same(line)
+ @parser.create_then(remove_tag_from(:and ,line))
+ end
+
+ def outcome(line)
+ @parser.create_then(remove_tag_from(:then ,line))
+ end
+ end
+
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/story/runner/story_runner.rb b/vendor/gems/rspec/lib/spec/story/runner/story_runner.rb
new file mode 100644
index 000000000..f9eeb9ac1
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/runner/story_runner.rb
@@ -0,0 +1,68 @@
+module Spec
+ module Story
+ module Runner
+ class StoryRunner
+ class << self
+ attr_accessor :current_story_runner
+
+ def scenario_from_current_story(scenario_name)
+ current_story_runner.scenario_from_current_story(scenario_name)
+ end
+ end
+
+ attr_accessor :stories, :scenarios, :current_story
+
+ def initialize(scenario_runner, world_creator = World)
+ StoryRunner.current_story_runner = self
+ @scenario_runner = scenario_runner
+ @world_creator = world_creator
+ @stories = []
+ @scenarios_by_story = {}
+ @scenarios = []
+ @listeners = []
+ end
+
+ def Story(title, narrative, params = {}, &body)
+ story = Story.new(title, narrative, params, &body)
+ @stories << story
+
+ # collect scenarios
+ collector = ScenarioCollector.new(story)
+ story.run_in(collector)
+ @scenarios += collector.scenarios
+ @scenarios_by_story[story.title] = collector.scenarios
+ end
+
+ def run_stories
+ return if @stories.empty?
+ @listeners.each { |l| l.run_started(scenarios.size) }
+ @stories.each do |story|
+ story.assign_steps_to(World)
+ @current_story = story
+ @listeners.each { |l| l.story_started(story.title, story.narrative) }
+ scenarios = @scenarios_by_story[story.title]
+ scenarios.each do |scenario|
+ type = story[:type] || Object
+ args = story[:args] || []
+ world = @world_creator.create(type, *args)
+ @scenario_runner.run(scenario, world)
+ end
+ @listeners.each { |l| l.story_ended(story.title, story.narrative) }
+ World.step_mother.clear
+ end
+ unique_steps = (World.step_names.collect {|n| Regexp === n ? n.source : n.to_s}).uniq.sort
+ @listeners.each { |l| l.collected_steps(unique_steps) }
+ @listeners.each { |l| l.run_ended }
+ end
+
+ def add_listener(listener)
+ @listeners << listener
+ end
+
+ def scenario_from_current_story(scenario_name)
+ @scenarios_by_story[@current_story.title].find {|s| s.name == scenario_name }
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/story/scenario.rb b/vendor/gems/rspec/lib/spec/story/scenario.rb
new file mode 100644
index 000000000..d83b3eeb8
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/scenario.rb
@@ -0,0 +1,14 @@
+
+module Spec
+ module Story
+ class Scenario
+ attr_accessor :name, :body, :story
+
+ def initialize(story, name, &body)
+ @story = story
+ @name = name
+ @body = body
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/story/step.rb b/vendor/gems/rspec/lib/spec/story/step.rb
new file mode 100644
index 000000000..ee9ede057
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/step.rb
@@ -0,0 +1,58 @@
+module Spec
+ module Story
+ class Step
+ PARAM_PATTERN = /(\$\w*)/
+ PARAM_OR_GROUP_PATTERN = /(\$\w*)|\(.*?\)/
+
+ attr_reader :name
+ def initialize(name, &block)
+ @name = name
+ assign_expression(name)
+ init_module(name, &block)
+ end
+
+ def perform(instance, *args)
+ instance.extend(@mod)
+ instance.__send__(sanitize(@name), *args)
+ end
+
+ def init_module(name, &block)
+ sanitized_name = sanitize(name)
+ @mod = Module.new do
+ define_method(sanitized_name, &block)
+ end
+ end
+
+ def sanitize(a_string_or_regexp)
+ return a_string_or_regexp.source if Regexp == a_string_or_regexp
+ a_string_or_regexp.to_s
+ end
+
+
+ def matches?(name)
+ !(matches = name.match(@expression)).nil?
+ end
+
+ def parse_args(name)
+ name.match(@expression)[1..-1]
+ end
+
+ private
+
+ def assign_expression(string_or_regexp)
+ if String === string_or_regexp
+ expression = string_or_regexp.dup
+ expression.gsub! '(', '\('
+ expression.gsub! ')', '\)'
+ elsif Regexp === string_or_regexp
+ expression = string_or_regexp.source
+ end
+ while expression =~ PARAM_PATTERN
+ expression.gsub!($1, "(.*?)")
+ end
+ @expression = Regexp.new("^#{expression}$")
+ end
+
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/lib/spec/story/step_group.rb b/vendor/gems/rspec/lib/spec/story/step_group.rb
new file mode 100644
index 000000000..cae558c40
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/step_group.rb
@@ -0,0 +1,89 @@
+module Spec
+ module Story
+
+ class StepGroupHash < Hash
+ def initialize
+ super do |h,k|
+ h[k] = Spec::Story::StepGroup.new
+ end
+ end
+ end
+
+ class StepGroup
+ def self.steps(&block)
+ @step_group ||= StepGroup.new(false)
+ @step_group.instance_eval(&block) if block
+ @step_group
+ end
+
+ def initialize(init_defaults=true, &block)
+ @hash_of_lists_of_steps = Hash.new {|h, k| h[k] = []}
+ if init_defaults
+ self.class.steps.add_to(self)
+ end
+ instance_eval(&block) if block
+ end
+
+ def find(type, name)
+ @hash_of_lists_of_steps[type].each do |step|
+ return step if step.matches?(name)
+ end
+ return nil
+ end
+
+ def GivenScenario(name, &block)
+ create_matcher(:given_scenario, name, &block)
+ end
+
+ def Given(name, &block)
+ create_matcher(:given, name, &block)
+ end
+
+ def When(name, &block)
+ create_matcher(:when, name, &block)
+ end
+
+ def Then(name, &block)
+ create_matcher(:then, name, &block)
+ end
+
+ alias :given_scenario :GivenScenario
+ alias :given :Given
+ alias :when :When
+ alias :then :Then
+
+ def add(type, steps)
+ (@hash_of_lists_of_steps[type] << steps).flatten!
+ end
+
+ def clear
+ @hash_of_lists_of_steps.clear
+ end
+
+ def empty?
+ [:given_scenario, :given, :when, :then].each do |type|
+ return false unless @hash_of_lists_of_steps[type].empty?
+ end
+ return true
+ end
+
+ def add_to(other_step_matchers)
+ [:given_scenario, :given, :when, :then].each do |type|
+ other_step_matchers.add(type, @hash_of_lists_of_steps[type])
+ end
+ end
+
+ def <<(other_step_matchers)
+ other_step_matchers.add_to(self) if other_step_matchers.respond_to?(:add_to)
+ end
+
+ # TODO - make me private
+ def create_matcher(type, name, &block)
+ matcher = Step.new(name, &block)
+ @hash_of_lists_of_steps[type] << matcher
+ matcher
+ end
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/story/step_mother.rb b/vendor/gems/rspec/lib/spec/story/step_mother.rb
new file mode 100644
index 000000000..a2e84e310
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/step_mother.rb
@@ -0,0 +1,37 @@
+module Spec
+ module Story
+ class StepMother
+ def initialize
+ @steps = StepGroup.new
+ end
+
+ def use(new_step_group)
+ @steps << new_step_group
+ end
+
+ def store(type, step)
+ @steps.add(type, step)
+ end
+
+ def find(type, name)
+ if @steps.find(type, name).nil?
+ @steps.add(type,
+ Step.new(name) do
+ raise Spec::Example::ExamplePendingError.new("Unimplemented step: #{name}")
+ end
+ )
+ end
+ @steps.find(type, name)
+ end
+
+ def clear
+ @steps.clear
+ end
+
+ def empty?
+ @steps.empty?
+ end
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/story/story.rb b/vendor/gems/rspec/lib/spec/story/story.rb
new file mode 100644
index 000000000..112e9414b
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/story.rb
@@ -0,0 +1,42 @@
+module Spec
+ module Story
+ class Story
+ attr_reader :title, :narrative
+
+ def initialize(title, narrative, params = {}, &body)
+ @body = body
+ @title = title
+ @narrative = narrative
+ @params = params
+ end
+
+ def [](key)
+ @params[key]
+ end
+
+ def run_in(obj)
+ obj.instance_eval(&@body)
+ end
+
+ def assign_steps_to(assignee)
+ if @params[:steps]
+ assignee.use(@params[:steps])
+ else
+ case keys = @params[:steps_for]
+ when Symbol
+ keys = [keys]
+ when nil
+ keys = []
+ end
+ keys.each do |key|
+ assignee.use(steps_for(key))
+ end
+ end
+ end
+
+ def steps_for(key)
+ $rspec_story_steps[key]
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/lib/spec/story/world.rb b/vendor/gems/rspec/lib/spec/story/world.rb
new file mode 100644
index 000000000..93b6e1d15
--- /dev/null
+++ b/vendor/gems/rspec/lib/spec/story/world.rb
@@ -0,0 +1,125 @@
+require 'rubygems'
+require 'spec/expectations'
+require 'spec/matchers'
+require 'spec/example/pending'
+
+module Spec
+ module Story
+=begin
+ A World represents the actual instance a scenario will run in.
+
+ The runner ensures any instance variables and methods defined anywhere
+ in a story block are available to all the scenarios. This includes
+ variables that are created or referenced inside Given, When and Then
+ blocks.
+=end
+ module World
+ include ::Spec::Example::Pending
+ include ::Spec::Matchers
+ # store steps and listeners in the singleton metaclass.
+ # This serves both to keep them out of the way of runtime Worlds
+ # and to make them available to all instances.
+ class << self
+ def create(cls = Object, *args)
+ cls.new(*args).extend(World)
+ end
+
+ def listeners
+ @listeners ||= []
+ end
+
+ def add_listener(listener)
+ listeners() << listener
+ end
+
+ def step_mother
+ @step_mother ||= StepMother.new
+ end
+
+ def use(steps)
+ step_mother.use(steps)
+ end
+
+ def step_names
+ @step_names ||= []
+ end
+
+ def run_given_scenario_with_suspended_listeners(world, type, name, scenario)
+ current_listeners = Array.new(listeners)
+ begin
+ listeners.each { |l| l.found_scenario(type, name) }
+ @listeners.clear
+ scenario.perform(world, name) unless ::Spec::Story::Runner.dry_run
+ ensure
+ @listeners.replace(current_listeners)
+ end
+ end
+
+ def store_and_call(world, type, name, *args, &block)
+ if block_given?
+ step_mother.store(type, Step.new(name, &block))
+ end
+ step = step_mother.find(type, name)
+
+ step_name = step.name
+ step_names << step_name
+
+ # It's important to have access to the parsed args here, so
+ # we can give them to the listeners. The HTML reporter needs
+ # the args so it can style them. See the generated output in
+ # story_server/prototype/rspec_stories.html (generated by rake stories)
+ args = step.parse_args(name) if args.empty?
+ begin
+ listeners.each { |l| l.step_upcoming(type, step_name, *args) }
+ step.perform(world, *args) unless ::Spec::Story::Runner.dry_run
+ listeners.each { |l| l.step_succeeded(type, step_name, *args) }
+ rescue Exception => e
+ case e
+ when Spec::Example::ExamplePendingError
+ @listeners.each { |l| l.step_pending(type, step_name, *args) }
+ else
+ @listeners.each { |l| l.step_failed(type, step_name, *args) }
+ end
+ errors << e
+ end
+ end
+
+ def errors
+ @errors ||= []
+ end
+ end # end of class << self
+
+ def start_collecting_errors
+ errors.clear
+ end
+
+ def errors
+ World.errors
+ end
+
+ def GivenScenario(name)
+ World.run_given_scenario_with_suspended_listeners(self, :'given scenario', name, GivenScenario.new(name))
+ @__previous_step = :given
+ end
+
+ def Given(name, *args, &block)
+ World.store_and_call self, :given, name, *args, &block
+ @__previous_step = :given
+ end
+
+ def When(name, *args, &block)
+ World.store_and_call self, :when, name, *args, &block
+ @__previous_step = :when
+ end
+
+ def Then(name, *args, &block)
+ World.store_and_call self, :then, name, *args, &block
+ @__previous_step = :then
+ end
+
+ def And(name, *args, &block)
+ World.store_and_call self, @__previous_step, name, *args, &block
+ end
+ end
+ end
+end
diff --git a/spec/lib/spec/translator.rb b/vendor/gems/rspec/lib/spec/translator.rb
index c1e07eda4..c1e07eda4 100644
--- a/spec/lib/spec/translator.rb
+++ b/vendor/gems/rspec/lib/spec/translator.rb
diff --git a/spec/lib/spec/version.rb b/vendor/gems/rspec/lib/spec/version.rb
index 5b1db9b37..26c15e919 100644
--- a/spec/lib/spec/version.rb
+++ b/vendor/gems/rspec/lib/spec/version.rb
@@ -1,23 +1,22 @@
-module Spec
- module VERSION
- unless defined? MAJOR
- MAJOR = 1
- MINOR = 0
- TINY = 8
- RELEASE_CANDIDATE = nil
-
- # RANDOM_TOKEN: 0.510454315029681
- REV = "$LastChangedRevision: 2338 $".match(/LastChangedRevision: (\d+)/)[1]
-
- STRING = [MAJOR, MINOR, TINY].join('.')
- TAG = "REL_#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('_')}".upcase.gsub(/\.|-/, '_')
- FULL_VERSION = "#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('.')} (r#{REV})"
-
- NAME = "RSpec"
- URL = "http://rspec.rubyforge.org/"
-
- DESCRIPTION = "#{NAME}-#{FULL_VERSION} - BDD for Ruby\n#{URL}"
- end
- end
-end
-
+module Spec
+ module VERSION
+ unless defined? MAJOR
+ MAJOR = 1
+ MINOR = 1
+ TINY = 3
+ RELEASE_CANDIDATE = nil
+
+ BUILD_TIME_UTC = 20080131122909
+
+ STRING = [MAJOR, MINOR, TINY].join('.')
+ TAG = "REL_#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('_')}".upcase.gsub(/\.|-/, '_')
+ FULL_VERSION = "#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('.')} (build #{BUILD_TIME_UTC})"
+
+ NAME = "RSpec"
+ URL = "http://rspec.rubyforge.org/"
+
+ DESCRIPTION = "#{NAME}-#{FULL_VERSION} - BDD for Ruby\n#{URL}"
+ end
+ end
+end
+
diff --git a/spec/plugins/mock_frameworks/flexmock.rb b/vendor/gems/rspec/plugins/mock_frameworks/flexmock.rb
index 6875a5222..6875a5222 100644
--- a/spec/plugins/mock_frameworks/flexmock.rb
+++ b/vendor/gems/rspec/plugins/mock_frameworks/flexmock.rb
diff --git a/spec/plugins/mock_frameworks/mocha.rb b/vendor/gems/rspec/plugins/mock_frameworks/mocha.rb
index 69d11636c..69d11636c 100644
--- a/spec/plugins/mock_frameworks/mocha.rb
+++ b/vendor/gems/rspec/plugins/mock_frameworks/mocha.rb
diff --git a/spec/plugins/mock_frameworks/rr.rb b/vendor/gems/rspec/plugins/mock_frameworks/rr.rb
index c019c18a1..c019c18a1 100644
--- a/spec/plugins/mock_frameworks/rr.rb
+++ b/vendor/gems/rspec/plugins/mock_frameworks/rr.rb
diff --git a/spec/plugins/mock_frameworks/rspec.rb b/vendor/gems/rspec/plugins/mock_frameworks/rspec.rb
index e606c3089..ce215ace2 100644
--- a/spec/plugins/mock_frameworks/rspec.rb
+++ b/vendor/gems/rspec/plugins/mock_frameworks/rspec.rb
@@ -3,7 +3,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "lib", "s
module Spec
module Plugins
module MockFramework
- include Spec::Mocks::SpecMethods
+ include Spec::Mocks::ExampleMethods
def setup_mocks_for_rspec
$rspec_mocks ||= Spec::Mocks::Space.new
end
diff --git a/vendor/gems/rspec/pre_commit/lib/pre_commit.rb b/vendor/gems/rspec/pre_commit/lib/pre_commit.rb
new file mode 100644
index 000000000..2f3480834
--- /dev/null
+++ b/vendor/gems/rspec/pre_commit/lib/pre_commit.rb
@@ -0,0 +1,4 @@
+require "pre_commit/pre_commit"
+require "pre_commit/rspec"
+require "pre_commit/core"
+require "pre_commit/rspec_on_rails"
diff --git a/vendor/gems/rspec/pre_commit/lib/pre_commit/core.rb b/vendor/gems/rspec/pre_commit/lib/pre_commit/core.rb
new file mode 100644
index 000000000..420cc0c75
--- /dev/null
+++ b/vendor/gems/rspec/pre_commit/lib/pre_commit/core.rb
@@ -0,0 +1,50 @@
+class PreCommit::Core < PreCommit
+ def pre_commit
+ rake_invoke :examples
+ website
+ end
+
+ def website(run_webby=true)
+ clobber
+ rake_invoke :verify_rcov
+ rake_invoke :spec_html
+ webby
+ rake_invoke :failing_examples_with_html
+ rdoc
+ rdoc_rails
+ end
+
+ def clobber
+ rm_rf '../doc/output'
+ rm_rf 'translated_specs'
+ end
+
+ def webby
+ Dir.chdir '../doc' do
+ output = silent_sh('rake rebuild 2>&1')
+ if shell_error?(output)
+ raise "ERROR while generating web site: #{output}"
+ end
+
+ spec_page = File.expand_path('output/documentation/tools/spec.html')
+ spec_page_content = File.open(spec_page).read
+ unless spec_page_content =~/\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\./m
+ raise "#{'!'*400}\nIt seems like the output in the generated documentation is broken (no dots: ......)\n. Look in #{spec_page}"
+ end
+ end
+ end
+
+ def rdoc
+ Dir.chdir '../rspec' do
+ rake = (PLATFORM == "i386-mswin32") ? "rake.cmd" : "rake"
+ `#{rake} rdoc`
+ end
+ end
+
+ def rdoc_rails
+ Dir.chdir '../rspec_on_rails' do
+ rake = (PLATFORM == "i386-mswin32") ? "rake.cmd" : "rake"
+ `#{rake} rdoc`
+ end
+ end
+end
diff --git a/vendor/gems/rspec/pre_commit/lib/pre_commit/pre_commit.rb b/vendor/gems/rspec/pre_commit/lib/pre_commit/pre_commit.rb
new file mode 100644
index 000000000..80f958b91
--- /dev/null
+++ b/vendor/gems/rspec/pre_commit/lib/pre_commit/pre_commit.rb
@@ -0,0 +1,54 @@
+class PreCommit
+ attr_reader :actor
+ def initialize(actor)
+ @actor = actor
+ end
+
+ protected
+ def rake_invoke(task_name)
+ Rake::Task[task_name].invoke
+ end
+
+ def rake_sh(task_name, env_hash={})
+ env = env_hash.collect{|key, value| "#{key}=#{value}"}.join(' ')
+ rake = (PLATFORM == "i386-mswin32") ? "rake.bat" : "rake"
+ cmd = "#{rake} #{task_name} #{env} --trace"
+ output = silent_sh(cmd)
+ puts output
+ if shell_error?(output)
+ raise "ERROR while running rake: #{cmd}"
+ end
+ end
+
+ def silent_sh(cmd, &block)
+ output = nil
+ IO.popen(cmd) do |io|
+ output = io.read
+ output.each_line do |line|
+ block.call(line) if block
+ end
+ end
+ output
+ end
+
+ def shell_error?(output)
+ output =~ /ERROR/n || error_code?
+ end
+
+ def error_code?
+ $?.exitstatus != 0
+ end
+
+ def root_dir
+ dir = File.dirname(__FILE__)
+ File.expand_path("#{dir}/../../../..")
+ end
+
+ def method_missing(method_name, *args, &block)
+ if actor.respond_to?(method_name)
+ actor.send(method_name, *args, &block)
+ else
+ super
+ end
+ end
+end
diff --git a/vendor/gems/rspec/pre_commit/lib/pre_commit/rspec.rb b/vendor/gems/rspec/pre_commit/lib/pre_commit/rspec.rb
new file mode 100644
index 000000000..5078c72d0
--- /dev/null
+++ b/vendor/gems/rspec/pre_commit/lib/pre_commit/rspec.rb
@@ -0,0 +1,111 @@
+class PreCommit::Rspec < PreCommit
+ def pre_commit
+ check_for_gem_dependencies
+ fix_cr_lf
+ touch_revision_storing_files
+ pre_commit_core
+ pre_commit_textmate_bundle
+ pre_commit_rails
+ ok_to_commit
+ end
+
+ def check_for_gem_dependencies
+ require "rubygems"
+ gem 'rake'
+ gem 'webby'
+ gem 'coderay'
+ gem 'RedCloth'
+ gem 'syntax'
+ gem 'diff-lcs'
+ gem 'heckle' unless PLATFORM == "i386-mswin32"
+ gem 'hpricot'
+ end
+
+ def fix_cr_lf
+ files = FileList['**/*.rb'].
+ exclude('example_rails_app/vendor/**').
+ exclude('rspec/translated_specs/**')
+ $\="\n"
+ files.each do |f|
+ raw_content = File.read(f)
+ fixed_content = ""
+ raw_content.each_line do |line|
+ fixed_content << line
+ end
+ unless raw_content == fixed_content
+ File.open(f, "w") do |io|
+ io.print fixed_content
+ end
+ end
+ end
+ end
+
+ # TODO - move me up to the project root
+ def touch_revision_storing_files
+ files = [
+ 'rspec/lib/spec/version.rb',
+ 'rspec_on_rails/lib/spec/rails/version.rb'
+ ]
+ build_time_utc = Time.now.utc.strftime('%Y%m%d%H%M%S')
+ files.each do |path|
+ abs_path = File.join(root_dir, path)
+ content = File.open(abs_path).read
+ touched_content = content.gsub(/BUILD_TIME_UTC = (\d*)/, "BUILD_TIME_UTC = #{build_time_utc}")
+ File.open(abs_path, 'w') do |io|
+ io.write touched_content
+ end
+ end
+ end
+
+ def pre_commit_core
+ Dir.chdir 'rspec' do
+ rake = (PLATFORM == "i386-mswin32") ? "rake.bat" : "rake"
+ system("#{rake} pre_commit --verbose --trace")
+ raise "RSpec Core pre_commit failed" if error_code?
+ end
+ end
+
+ def pre_commit_textmate_bundle
+ Dir.chdir 'RSpec.tmbundle/Support' do
+ rake = (PLATFORM == "i386-mswin32") ? "rake.bat" : "rake"
+ system("#{rake} spec --verbose --trace")
+ raise "RSpec Textmate Bundle specs failed" if error_code?
+ end
+ end
+
+ def install_dependencies
+ Dir.chdir 'example_rails_app' do
+ rake_sh("-f Multirails.rake install_dependencies")
+ end
+ end
+
+ def update_dependencies
+ Dir.chdir 'example_rails_app' do
+ rake_sh("-f Multirails.rake update_dependencies")
+ end
+ end
+
+ def pre_commit_rails
+ Dir.chdir 'example_rails_app' do
+ rake = (PLATFORM == "i386-mswin32") ? "rake.cmd" : "rake"
+ cmd = "#{rake} -f Multirails.rake pre_commit --trace"
+ system(cmd)
+ if error_code?
+ message = <<-EOF
+ ############################################################
+ RSpec on Rails Plugin pre_commit failed. For more info:
+
+ cd example_rails_app
+ #{cmd}
+
+ ############################################################
+ EOF
+ raise message.gsub(/^ /, '')
+ end
+ end
+ end
+
+ def ok_to_commit
+ puts "OK TO COMMIT"
+ end
+end
diff --git a/vendor/gems/rspec/pre_commit/lib/pre_commit/rspec_on_rails.rb b/vendor/gems/rspec/pre_commit/lib/pre_commit/rspec_on_rails.rb
new file mode 100644
index 000000000..787953763
--- /dev/null
+++ b/vendor/gems/rspec/pre_commit/lib/pre_commit/rspec_on_rails.rb
@@ -0,0 +1,313 @@
+class PreCommit::RspecOnRails < PreCommit
+ def pre_commit
+ install_plugins
+ check_dependencies
+ used_railses = []
+ VENDOR_DEPS.each do |dependency|
+ rails_dir = File.expand_path(dependency[:checkout_path])
+ rails_version = rails_version_from_dir(rails_dir)
+ begin
+ rspec_pre_commit(rails_version, false)
+ used_railses << rails_version
+ rescue Exception => e
+ unless rails_version == 'edge'
+ raise e
+ end
+ end
+ end
+ uninstall_plugins
+ puts "All specs passed against the following released versions of Rails: #{used_railses.join(", ")}"
+ unless used_railses.include?('edge')
+ puts "There were errors running pre_commit against edge"
+ end
+ end
+
+ def rails_version_from_dir(rails_dir)
+ File.basename(rails_dir)
+ end
+
+ def rspec_pre_commit(rails_version=ENV['RSPEC_RAILS_VERSION'],uninstall=true)
+ puts "#####################################################"
+ puts "running pre_commit against rails #{rails_version}"
+ puts "#####################################################"
+ ENV['RSPEC_RAILS_VERSION'] = rails_version
+ cleanup(uninstall)
+ ensure_db_config
+ clobber_sqlite_data
+ install_plugins
+ generate_rspec
+
+ generate_login_controller
+ create_purchase
+
+ rake_sh "spec"
+ rake_sh "spec:plugins:rspec_on_rails"
+
+ # TODO - why is this necessary? Shouldn't the specs leave
+ # a clean DB?
+ rake_sh "db:test:prepare"
+ sh "ruby vendor/plugins/rspec_on_rails/stories/all.rb"
+ cleanup(uninstall)
+ end
+
+ def cleanup(uninstall=true)
+ revert_routes
+ rm_generated_login_controller_files
+ destroy_purchase
+ uninstall_plugins if uninstall
+ end
+
+ def revert_routes
+ output = silent_sh("cp config/routes.rb.bak config/routes.rb")
+ raise "Error reverting routes.rb" if shell_error?(output)
+ end
+
+ def create_purchase
+ generate_purchase
+ migrate_up
+ end
+
+ def install_plugins
+ install_rspec_on_rails_plugin
+ install_rspec_plugin
+ end
+
+ def install_rspec_on_rails_plugin
+ rm_rf 'vendor/plugins/rspec_on_rails'
+ copy '../rspec_on_rails', 'vendor/plugins/'
+ end
+
+ def install_rspec_plugin
+ rm_rf 'vendor/plugins/rspec'
+ copy '../rspec', 'vendor/plugins/'
+ end
+
+ def uninstall_plugins
+ rm_rf 'vendor/plugins/rspec_on_rails'
+ rm_rf 'vendor/plugins/rspec'
+ rm_rf 'script/spec'
+ rm_rf 'script/spec_server'
+ rm_rf 'spec/spec_helper.rb'
+ rm_rf 'spec/spec.opts'
+ rm_rf 'spec/rcov.opts'
+ end
+
+ def copy(source, target)
+ output = silent_sh("cp -R #{File.expand_path(source)} #{File.expand_path(target)}")
+ raise "Error installing rspec" if shell_error?(output)
+ end
+
+ def generate_rspec
+ result = silent_sh("ruby script/generate rspec --force")
+ if error_code? || result =~ /^Missing/
+ raise "Failed to generate rspec environment:\n#{result}"
+ end
+ end
+
+ def ensure_db_config
+ config_path = 'config/database.yml'
+ unless File.exists?(config_path)
+ message = <<-EOF
+ #####################################################
+ Could not find #{config_path}
+
+ You can get rake to generate this file for you using either of:
+ rake rspec:generate_mysql_config
+ rake rspec:generate_sqlite3_config
+
+ If you use mysql, you'll need to create dev and test
+ databases and users for each. To do this, standing
+ in rspec_on_rails, log into mysql as root and then...
+ mysql> source db/mysql_setup.sql;
+
+ There is also a teardown script that will remove
+ the databases and users:
+ mysql> source db/mysql_teardown.sql;
+ #####################################################
+ EOF
+ raise message.gsub(/^ /, '')
+ end
+ end
+
+ def generate_mysql_config
+ copy 'config/database.mysql.yml', 'config/database.yml'
+ end
+
+ def generate_sqlite3_config
+ copy 'config/database.sqlite3.yml', 'config/database.yml'
+ end
+
+ def clobber_db_config
+ rm 'config/database.yml'
+ end
+
+ def clobber_sqlite_data
+ rm_rf 'db/*.db'
+ end
+
+ def generate_purchase
+ generator = "ruby script/generate rspec_scaffold purchase order_id:integer created_at:datetime amount:decimal keyword:string description:text --force"
+ notice = <<-EOF
+ #####################################################
+ #{generator}
+ #####################################################
+ EOF
+ puts notice.gsub(/^ /, '')
+ result = silent_sh(generator)
+ if error_code? || result =~ /not/
+ raise "rspec_scaffold failed. #{result}"
+ end
+ end
+
+ def purchase_migration_version
+ "005"
+ end
+
+ def migrate_up
+ rake_sh "db:migrate"
+ end
+
+ def destroy_purchase
+ migrate_down
+ rm_generated_purchase_files
+ end
+
+ def migrate_down
+ notice = <<-EOF
+ #####################################################
+ Migrating down and reverting config/routes.rb
+ #####################################################
+ EOF
+ puts notice.gsub(/^ /, '')
+ rake_sh "db:migrate", 'VERSION' => (purchase_migration_version.to_i - 1)
+ output = silent_sh("cp config/routes.rb.bak config/routes.rb")
+ raise "revert failed: #{output}" if error_code?
+ end
+
+ def rm_generated_purchase_files
+ puts "#####################################################"
+ puts "Removing generated files:"
+ generated_files = %W{
+ app/helpers/purchases_helper.rb
+ app/models/purchase.rb
+ app/controllers/purchases_controller.rb
+ app/views/purchases
+ db/migrate/#{purchase_migration_version}_create_purchases.rb
+ spec/models/purchase_spec.rb
+ spec/helpers/purchases_helper_spec.rb
+ spec/controllers/purchases_controller_spec.rb
+ spec/controllers/purchases_routing_spec.rb
+ spec/fixtures/purchases.yml
+ spec/views/purchases
+ }
+ generated_files.each do |file|
+ rm_rf file
+ end
+ puts "#####################################################"
+ end
+
+ def generate_login_controller
+ generator = "ruby script/generate rspec_controller login signup login logout --force"
+ notice = <<-EOF
+ #####################################################
+ #{generator}
+ #####################################################
+ EOF
+ puts notice.gsub(/^ /, '')
+ result = silent_sh(generator)
+ if error_code? || result =~ /not/
+ raise "rspec_scaffold failed. #{result}"
+ end
+ end
+
+ def rm_generated_login_controller_files
+ puts "#####################################################"
+ puts "Removing generated files:"
+ generated_files = %W{
+ app/helpers/login_helper.rb
+ app/controllers/login_controller.rb
+ app/views/login
+ spec/helpers/login_helper_spec.rb
+ spec/controllers/login_controller_spec.rb
+ spec/views/login
+ }
+ generated_files.each do |file|
+ rm_rf file
+ end
+ puts "#####################################################"
+ end
+
+ def install_dependencies
+ VENDOR_DEPS.each do |dep|
+ puts "\nChecking for #{dep[:name]} ..."
+ dest = dep[:checkout_path]
+ if File.exists?(dest)
+ puts "#{dep[:name]} already installed"
+ else
+ cmd = "svn co #{dep[:url]} #{dest}"
+ puts "Installing #{dep[:name]}"
+ puts "This may take a while."
+ puts cmd
+ system(cmd)
+ puts "Done!"
+ end
+ end
+ puts
+ end
+
+ def check_dependencies
+ VENDOR_DEPS.each do |dep|
+ unless File.exist?(dep[:checkout_path])
+ raise "There is no checkout of #{dep[:checkout_path]}. Please run rake install_dependencies"
+ end
+ # Verify that the current working copy is right
+ if `svn info #{dep[:checkout_path]}` =~ /^URL: (.*)/
+ actual_url = $1
+ if actual_url != dep[:url]
+ raise "Your working copy in #{dep[:checkout_path]} points to \n#{actual_url}\nIt has moved to\n#{dep[:url]}\nPlease delete the working copy and run rake install_dependencies"
+ end
+ end
+ end
+ end
+
+ def update_dependencies
+ check_dependencies
+ VENDOR_DEPS.each do |dep|
+ next if dep[:tagged?] #
+ puts "\nUpdating #{dep[:name]} ..."
+ dest = dep[:checkout_path]
+ system("svn cleanup #{dest}")
+ cmd = "svn up #{dest}"
+ puts cmd
+ system(cmd)
+ puts "Done!"
+ end
+ end
+
+ VENDOR_DEPS = [
+ {
+ :checkout_path => "vendor/rails/2.0.2",
+ :name => "rails 2.0.2",
+ :url => "http://dev.rubyonrails.org/svn/rails/tags/rel_2-0-2",
+ :tagged? => true
+ },
+ {
+ :checkout_path => "vendor/rails/1.2.6",
+ :name => "rails 1.2.6",
+ :url => "http://dev.rubyonrails.org/svn/rails/tags/rel_1-2-6",
+ :tagged? => true
+ },
+ {
+ :checkout_path => "vendor/rails/1.2.3",
+ :name => "rails 1.2.3",
+ :url => "http://dev.rubyonrails.org/svn/rails/tags/rel_1-2-3",
+ :tagged? => true
+ },
+ {
+ :checkout_path => "vendor/rails/edge",
+ :name => "edge rails",
+ :url => "http://svn.rubyonrails.org/rails/trunk",
+ :tagged? => false
+ }
+ ]
+end
diff --git a/vendor/gems/rspec/pre_commit/spec/pre_commit/pre_commit_spec.rb b/vendor/gems/rspec/pre_commit/spec/pre_commit/pre_commit_spec.rb
new file mode 100644
index 000000000..5d1c8f9b9
--- /dev/null
+++ b/vendor/gems/rspec/pre_commit/spec/pre_commit/pre_commit_spec.rb
@@ -0,0 +1,15 @@
+require File.dirname(__FILE__) + '/../spec_helper.rb'
+
+##
+# This is not a complete specification of PreCommit, but
+# just a collection of bug fix regression tests.
+describe "The helper method PreCommit#silent_sh" do
+ before do
+ @pre_commit = PreCommit.new(nil)
+ end
+
+ # bug in r1802
+ it "should return the command output" do
+ @pre_commit.send(:silent_sh, "echo foo").should ==("foo\n")
+ end
+end
diff --git a/vendor/gems/rspec/pre_commit/spec/pre_commit/rspec_on_rails_spec.rb b/vendor/gems/rspec/pre_commit/spec/pre_commit/rspec_on_rails_spec.rb
new file mode 100644
index 000000000..1932fff86
--- /dev/null
+++ b/vendor/gems/rspec/pre_commit/spec/pre_commit/rspec_on_rails_spec.rb
@@ -0,0 +1,36 @@
+require File.dirname(__FILE__) + '/../spec_helper.rb'
+require 'fileutils'
+
+include FileUtils
+
+##
+# This is not a complete specification of PreCommit.RSpecOnRails, but
+# just a collection of bug fix regression tests.
+describe "RSpecOnRails pre_commit" do
+ before do
+ @original_dir = File.expand_path(FileUtils.pwd)
+ @rails_app_dir = File.expand_path(File.dirname(__FILE__) + "/../../../example_rails_app/")
+
+ Dir.chdir(@rails_app_dir)
+ rm_rf('vendor/plugins/rspec_on_rails')
+ system("svn export ../rspec_on_rails vendor/plugins/rspec_on_rails")
+
+ @pre_commit = PreCommit::RspecOnRails.new(nil)
+ end
+
+ after do
+ rm('db/migrate/888_create_purchases.rb', :force => true)
+ @pre_commit.destroy_purchase
+ Dir.chdir(@original_dir)
+ end
+
+ # bug in r1802
+ it "should fail noisily if there is a migration name conflict" do
+ touch('db/migrate/888_create_purchases.rb')
+ lambda { @pre_commit.generate_purchase }.should raise_error
+ end
+
+ it "should not fail if tests run ok" do
+ lambda { @pre_commit.generate_purchase }.should_not raise_error
+ end
+end
diff --git a/vendor/gems/rspec/pre_commit/spec/spec_helper.rb b/vendor/gems/rspec/pre_commit/spec/spec_helper.rb
new file mode 100644
index 000000000..b7e5f3d44
--- /dev/null
+++ b/vendor/gems/rspec/pre_commit/spec/spec_helper.rb
@@ -0,0 +1,3 @@
+$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
+require 'pre_commit'
+
diff --git a/vendor/gems/rspec/pre_commit/spec/spec_suite.rb b/vendor/gems/rspec/pre_commit/spec/spec_suite.rb
new file mode 100644
index 000000000..a8c7c07ac
--- /dev/null
+++ b/vendor/gems/rspec/pre_commit/spec/spec_suite.rb
@@ -0,0 +1,11 @@
+class SpecSuite
+ def run
+ system("ruby rspec/spec/rspec_suite.rb") || raise("Rspec Suite FAILED")
+ system("ruby rspec_on_rails/spec/rails_suite.rb") || raise("Rails Suite FAILED")
+ system("ruby cached_example_rails_app/spec/rails_app_suite.rb") || raise("Rails App Suite FAILED")
+ end
+end
+
+if $0 == __FILE__
+ SpecSuite.new.run
+end
diff --git a/vendor/gems/rspec/rake_tasks/examples.rake b/vendor/gems/rspec/rake_tasks/examples.rake
new file mode 100644
index 000000000..32d0ad0e6
--- /dev/null
+++ b/vendor/gems/rspec/rake_tasks/examples.rake
@@ -0,0 +1,7 @@
+require 'rake'
+require 'spec/rake/spectask'
+
+desc "Run all examples"
+Spec::Rake::SpecTask.new('examples') do |t|
+ t.spec_files = FileList['examples/**/*.rb']
+end
diff --git a/vendor/gems/rspec/rake_tasks/examples_with_rcov.rake b/vendor/gems/rspec/rake_tasks/examples_with_rcov.rake
new file mode 100644
index 000000000..4bf35c6b8
--- /dev/null
+++ b/vendor/gems/rspec/rake_tasks/examples_with_rcov.rake
@@ -0,0 +1,9 @@
+require 'rake'
+require 'spec/rake/spectask'
+
+desc "Run all examples with RCov"
+Spec::Rake::SpecTask.new('examples_with_rcov') do |t|
+ t.spec_files = FileList['examples/**/*.rb']
+ t.rcov = true
+ t.rcov_opts = ['--exclude', 'examples']
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/rake_tasks/failing_examples_with_html.rake b/vendor/gems/rspec/rake_tasks/failing_examples_with_html.rake
new file mode 100644
index 000000000..34549583d
--- /dev/null
+++ b/vendor/gems/rspec/rake_tasks/failing_examples_with_html.rake
@@ -0,0 +1,9 @@
+require 'rake'
+require 'spec/rake/spectask'
+
+desc "Generate HTML report for failing examples"
+Spec::Rake::SpecTask.new('failing_examples_with_html') do |t|
+ t.spec_files = FileList['failing_examples/**/*.rb']
+ t.spec_opts = ["--format", "html:../doc/output/documentation/tools/failing_examples.html", "--diff"]
+ t.fail_on_error = false
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/rake_tasks/verify_rcov.rake b/vendor/gems/rspec/rake_tasks/verify_rcov.rake
new file mode 100644
index 000000000..a90a266df
--- /dev/null
+++ b/vendor/gems/rspec/rake_tasks/verify_rcov.rake
@@ -0,0 +1,7 @@
+require 'rake'
+require 'spec/rake/verify_rcov'
+
+RCov::VerifyTask.new(:verify_rcov => :spec) do |t|
+ t.threshold = 100.0 # Make sure you have rcov 0.7 or higher!
+ t.index_html = '../doc/output/coverage/index.html'
+end
diff --git a/vendor/gems/rspec/spec/README.jruby b/vendor/gems/rspec/spec/README.jruby
new file mode 100644
index 000000000..7eddb5671
--- /dev/null
+++ b/vendor/gems/rspec/spec/README.jruby
@@ -0,0 +1,15 @@
+= Running specs on JRuby =
+
+svn co http://svn.codehaus.org/jruby/trunk jruby
+cd jruby/jruby
+ant clean
+ant
+# put JRuby's bin dir on your PATH
+jruby -S gem install rake --no-ri --no-rdoc
+jruby -S gem install diff-lcs
+jruby -S gem install syntax
+cd ../testsuites/rspec
+mkdir target
+jruby -S rake checkout_code
+cd target/rspec
+jruby bin/spec spec -c
diff --git a/vendor/gems/rspec/spec/autotest/discover_spec.rb b/vendor/gems/rspec/spec/autotest/discover_spec.rb
new file mode 100644
index 000000000..da5cb1445
--- /dev/null
+++ b/vendor/gems/rspec/spec/autotest/discover_spec.rb
@@ -0,0 +1,19 @@
+require File.dirname(__FILE__) + "/../autotest_helper"
+
+module DiscoveryHelper
+ def load_discovery
+ require File.dirname(__FILE__) + "/../../lib/autotest/discover"
+ end
+end
+
+
+class Autotest
+ describe Rspec, "discovery" do
+ include DiscoveryHelper
+
+ it "should add the rspec autotest plugin" do
+ Autotest.should_receive(:add_discovery).and_yield
+ load_discovery
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/autotest/rspec_spec.rb b/vendor/gems/rspec/spec/autotest/rspec_spec.rb
new file mode 100644
index 000000000..67ee7fbef
--- /dev/null
+++ b/vendor/gems/rspec/spec/autotest/rspec_spec.rb
@@ -0,0 +1,195 @@
+require File.dirname(__FILE__) + "/../autotest_helper"
+
+class Autotest
+
+ module AutotestHelper
+ def rspec_output
+ <<-HERE
+.............PPF
+
+1)
+'false should be false' FAILED
+expected: true,
+ got: false (using ==)
+./spec/autotest/rspec_spec.rb:203:
+
+Finished in 0.158674 seconds
+
+16 examples, 1 failure, 2 pending
+
+Pending:
+Autotest::Rspec handling failed results should return an array of failed examples and errors (TODO)
+Autotest::Rspec tests/specs for a given file should find all the specs for a given file (TODO)
+HERE
+ end
+
+
+ def common_setup
+ @proc = mock Proc
+ @kernel = mock Kernel
+ @kernel.stub!(:proc).and_return @proc
+
+ File.stub!(:exists).and_return true
+ @windows_alt_separator = "\\"
+ @posix_separator = '/'
+
+ @rspec_output = rspec_output
+ end
+ end
+
+ describe Rspec, "rspec_commands" do
+ it "should contain the various commands, ordered by preference" do
+ Rspec.new.spec_commands.should == [
+ File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec"),
+ "#{Config::CONFIG['bindir']}/spec"
+ ]
+ end
+ end
+
+ describe Rspec, "selection of rspec command" do
+ include AutotestHelper
+
+ before :each do
+ common_setup
+ @rspec_autotest = Rspec.new
+ end
+
+ it "should try to find the spec command if it exists in ./bin and use it above everything else" do
+ File.stub!(:exists?).and_return true
+
+ spec_path = File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec")
+ File.should_receive(:exists?).with(spec_path).and_return true
+ @rspec_autotest.spec_command.should == spec_path
+ end
+
+ it "should otherwise select the default spec command in gem_dir/bin/spec" do
+ @rspec_autotest.stub!(:spec_commands).and_return ["/foo/spec"]
+ Config::CONFIG.stub!(:[]).and_return "/foo"
+ File.should_receive(:exists?).with("/foo/spec").and_return(true)
+
+ @rspec_autotest.spec_command.should == "/foo/spec"
+ end
+
+ it "should raise an error if no spec command is found at all" do
+ File.stub!(:exists?).and_return false
+
+ lambda {
+ @rspec_autotest.spec_command
+ }.should raise_error(RspecCommandError, "No spec command could be found!")
+ end
+
+ end
+
+ describe Rspec, "selection of rspec command (windows compatibility issues)" do
+ include AutotestHelper
+
+ before :each do
+ common_setup
+ end
+
+ it "should use the ALT_SEPARATOR if it is non-nil" do
+ @rspec_autotest = Rspec.new
+ spec_command = File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec")
+ @rspec_autotest.stub!(:spec_commands).and_return [spec_command]
+ @rspec_autotest.spec_command(@windows_alt_separator).should == spec_command.gsub('/', @windows_alt_separator)
+ end
+
+ it "should not use the ALT_SEPATOR if it is nil" do
+ @windows_alt_separator = nil
+ @rspec_autotest = Rspec.new
+ spec_command = File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec")
+ @rspec_autotest.stub!(:spec_commands).and_return [spec_command]
+ @rspec_autotest.spec_command.should == spec_command
+ end
+ end
+
+ describe Rspec, "adding spec.opts --options" do
+ before :each do
+ @rspec_autotest = Rspec.new
+ end
+
+ it "should return the command line option to add spec.opts if the options file exists" do
+ File.stub!(:exist?).and_return true
+ @rspec_autotest.add_options_if_present.should == "-O spec/spec.opts "
+ end
+
+ it "should return an empty string if no spec.opts exists" do
+ File.stub!(:exist?).and_return false
+ Rspec.new.add_options_if_present.should == ""
+ end
+ end
+
+ describe Rspec do
+ before :each do
+ @rspec_autotest = Rspec.new
+ @rspec_autotest.stub!(:ruby).and_return "ruby"
+ @rspec_autotest.stub!(:add_options_if_present).and_return "-O spec/spec.opts"
+
+ @ruby = @rspec_autotest.ruby
+ @spec_command = @rspec_autotest.spec_command
+ @options = @rspec_autotest.add_options_if_present
+ @files_to_test = {
+ :spec => ["file_one", "file_two"]
+ }
+ # this is not the inner representation of Autotest!
+ @rspec_autotest.stub!(:files_to_test).and_return @files_to_test
+ @files_to_test.stub!(:keys).and_return @files_to_test[:spec]
+ @to_test = @files_to_test.keys.flatten.join ' '
+ end
+
+ it "should make the apropriate test command" do
+ @rspec_autotest.make_test_cmd(@files_to_test).should == "#{@ruby} -S #{@spec_command} #{@options} #{@to_test}"
+ end
+ end
+
+ describe Rspec, "mappings" do
+
+ before(:each) do
+ @lib_file = "lib/something.rb"
+ @spec_file = "spec/something_spec.rb"
+ @rspec_autotest = Rspec.new
+ @rspec_autotest.hook :initialize
+ end
+
+ it "should find the spec file for a given lib file" do
+ @rspec_autotest.should map_specs([@spec_file]).to(@lib_file)
+ end
+
+ it "should find the spec file if given a spec file" do
+ @rspec_autotest.should map_specs([@spec_file]).to(@spec_file)
+ end
+
+ it "should only find the file if the file is being tracked (in @file)" do
+ @rspec_autotest.should map_specs([]).to("lib/untracked_file")
+ end
+ end
+
+ describe Rspec, "consolidating failures" do
+ include AutotestHelper
+
+ before :each do
+ common_setup
+ @rspec_autotest = Rspec.new
+
+ @spec_file = "./spec/autotest/rspec_spec.rb"
+ @rspec_autotest.instance_variable_set("@files", {@spec_file => Time.now})
+ @rspec_autotest.stub!(:find_files_to_test).and_return true
+ end
+
+ it "should return no failures if no failures were given in the output" do
+ @rspec_autotest.consolidate_failures([[]]).should == {}
+ end
+
+ it "should return a hash with the spec filename => spec name for each failure or error" do
+ @rspec_autotest.stub!(:test_files_for).and_return "./spec/autotest/rspec_spec.rb"
+ foo = [
+ [
+ "false should be false",
+ "expected: true,\n got: false (using ==)\n./spec/autotest/rspec_spec.rb:203:"
+ ]
+ ]
+ @rspec_autotest.consolidate_failures(foo).should == {@spec_file => ["false should be false"]}
+ end
+
+ end
+end
diff --git a/vendor/gems/rspec/spec/autotest_helper.rb b/vendor/gems/rspec/spec/autotest_helper.rb
new file mode 100644
index 000000000..1b6c6002b
--- /dev/null
+++ b/vendor/gems/rspec/spec/autotest_helper.rb
@@ -0,0 +1,6 @@
+require "rubygems"
+require 'autotest'
+dir = File.dirname(__FILE__)
+require "#{dir}/spec_helper"
+require File.expand_path("#{dir}/../lib/autotest/rspec")
+require "#{dir}/autotest_matchers"
diff --git a/vendor/gems/rspec/spec/autotest_matchers.rb b/vendor/gems/rspec/spec/autotest_matchers.rb
new file mode 100644
index 000000000..5e23452e2
--- /dev/null
+++ b/vendor/gems/rspec/spec/autotest_matchers.rb
@@ -0,0 +1,47 @@
+module Spec
+ module Matchers
+ class AutotestMappingMatcher
+ def initialize(specs)
+ @specs = specs
+ end
+
+ def to(file)
+ @file = file
+ self
+ end
+
+ def matches?(autotest)
+ @autotest = prepare autotest
+ @actual = autotest.test_files_for(@file)
+ @actual == @specs
+ end
+
+ def failure_message
+ "expected #{@autotest.class} to map #{@specs.inspect} to #{@file.inspect}\ngot #{@actual.inspect}"
+ end
+
+ private
+ def prepare autotest
+ stub_found_files autotest
+ stub_find_order autotest
+ autotest
+ end
+
+ def stub_found_files autotest
+ found_files = @specs.inject({}){|h,f| h[f] = Time.at(0)}
+ autotest.stub!(:find_files).and_return(found_files)
+ end
+
+ def stub_find_order autotest
+ find_order = @specs.dup << @file
+ autotest.instance_eval { @find_order = find_order }
+ end
+
+ end
+
+ def map_specs(specs)
+ AutotestMappingMatcher.new(specs)
+ end
+
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/rspec_suite.rb b/vendor/gems/rspec/spec/rspec_suite.rb
new file mode 100644
index 000000000..abd016a6d
--- /dev/null
+++ b/vendor/gems/rspec/spec/rspec_suite.rb
@@ -0,0 +1,7 @@
+if __FILE__ == $0
+ dir = File.dirname(__FILE__)
+ Dir["#{dir}/**/*_spec.rb"].reverse.each do |file|
+# puts "require '#{file}'"
+ require file
+ end
+end
diff --git a/vendor/gems/rspec/spec/ruby_forker.rb b/vendor/gems/rspec/spec/ruby_forker.rb
new file mode 100644
index 000000000..6ab038750
--- /dev/null
+++ b/vendor/gems/rspec/spec/ruby_forker.rb
@@ -0,0 +1,13 @@
+require 'rbconfig'
+
+module RubyForker
+ # Forks a ruby interpreter with same type as ourself.
+ # juby will fork jruby, ruby will fork ruby etc.
+ def ruby(args, stderr=nil)
+ config = ::Config::CONFIG
+ interpreter = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT']
+ cmd = "#{interpreter} #{args}"
+ cmd << " 2> #{stderr}" unless stderr.nil?
+ `#{cmd}`
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec.opts b/vendor/gems/rspec/spec/spec.opts
new file mode 100644
index 000000000..48e51f93b
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec.opts
@@ -0,0 +1,6 @@
+--colour
+--format
+profile
+--timeout
+20
+--diff \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/example/configuration_spec.rb b/vendor/gems/rspec/spec/spec/example/configuration_spec.rb
new file mode 100755
index 000000000..5b4a6049e
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/configuration_spec.rb
@@ -0,0 +1,282 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Example
+
+ describe Configuration do
+ before(:each) do
+ @config = Configuration.new
+ @example_group = mock("example_group")
+ end
+
+ describe "#mock_with" do
+
+ it "should default mock framework to rspec" do
+ @config.mock_framework.should =~ /\/plugins\/mock_frameworks\/rspec$/
+ end
+
+ it "should let you set rspec mocking explicitly" do
+ @config.mock_with(:rspec)
+ @config.mock_framework.should =~ /\/plugins\/mock_frameworks\/rspec$/
+ end
+
+ it "should let you set mocha" do
+ @config.mock_with(:mocha)
+ @config.mock_framework.should =~ /\/plugins\/mock_frameworks\/mocha$/
+ end
+
+ it "should let you set flexmock" do
+ @config.mock_with(:flexmock)
+ @config.mock_framework.should =~ /\/plugins\/mock_frameworks\/flexmock$/
+ end
+
+ it "should let you set rr" do
+ @config.mock_with(:rr)
+ @config.mock_framework.should =~ /\/plugins\/mock_frameworks\/rr$/
+ end
+
+ it "should let you set an arbitrary adapter module" do
+ adapter = Module.new
+ @config.mock_with(adapter)
+ @config.mock_framework.should == adapter
+ end
+ end
+
+ describe "#include" do
+
+ before do
+ @original_configuration = Spec::Runner.configuration
+ spec_configuration = @config
+ Spec::Runner.instance_eval {@configuration = spec_configuration}
+ @example_group_class = Class.new(ExampleGroup) do
+ class << self
+ def this_class_has_special_methods
+ end
+ end
+ end
+ ExampleGroupFactory.register(:foobar, @example_group_class)
+ end
+
+ after do
+ original_configuration = @original_configuration
+ Spec::Runner.instance_eval {@configuration = original_configuration}
+ ExampleGroupFactory.reset
+ end
+
+ it "should include the submitted module in ExampleGroup subclasses" do
+ mod = Module.new
+ @config.include mod
+ Class.new(@example_group_class).included_modules.should include(mod)
+ end
+
+ it "should let you define modules to be included for a specific type" do
+ mod = Module.new
+ @config.include mod, :type => :foobar
+ Class.new(@example_group_class).included_modules.should include(mod)
+ end
+
+ it "should not include modules in a type they are not intended for" do
+ mod = Module.new
+ @other_example_group_class = Class.new(ExampleGroup)
+ ExampleGroupFactory.register(:baz, @other_example_group_class)
+
+ @config.include mod, :type => :foobar
+
+ Class.new(@other_example_group_class).included_modules.should_not include(mod)
+ end
+
+ end
+
+ end
+
+ describe Configuration do
+
+ before(:each) do
+ @config = Configuration.new
+ @special_example_group = Class.new(ExampleGroup)
+ @special_child_example_group = Class.new(@special_example_group)
+ @nonspecial_example_group = Class.new(ExampleGroup)
+ ExampleGroupFactory.register(:special, @special_example_group)
+ ExampleGroupFactory.register(:special_child, @special_child_example_group)
+ ExampleGroupFactory.register(:non_special, @nonspecial_example_group)
+ @example_group = @special_child_example_group.describe "Special Example Group"
+ @unselected_example_group = Class.new(@nonspecial_example_group).describe "Non Special Example Group"
+ end
+
+ after(:each) do
+ ExampleGroupFactory.reset
+ end
+
+ describe "#prepend_before" do
+ it "prepends the before block on all instances of the passed in type" do
+ order = []
+ @config.prepend_before(:all) do
+ order << :prepend__before_all
+ end
+ @config.prepend_before(:all, :type => :special) do
+ order << :special_prepend__before_all
+ end
+ @config.prepend_before(:all, :type => :special_child) do
+ order << :special_child_prepend__before_all
+ end
+ @config.prepend_before(:each) do
+ order << :prepend__before_each
+ end
+ @config.prepend_before(:each, :type => :special) do
+ order << :special_prepend__before_each
+ end
+ @config.prepend_before(:each, :type => :special_child) do
+ order << :special_child_prepend__before_each
+ end
+ @config.prepend_before(:all, :type => :non_special) do
+ order << :special_prepend__before_all
+ end
+ @config.prepend_before(:each, :type => :non_special) do
+ order << :special_prepend__before_each
+ end
+ @example_group.it "calls prepend_before" do
+ end
+
+ @example_group.run
+ order.should == [
+ :prepend__before_all,
+ :special_prepend__before_all,
+ :special_child_prepend__before_all,
+ :prepend__before_each,
+ :special_prepend__before_each,
+ :special_child_prepend__before_each
+ ]
+ end
+ end
+
+ describe "#append_before" do
+
+ it "calls append_before on the type" do
+ order = []
+ @config.append_before(:all) do
+ order << :append_before_all
+ end
+ @config.append_before(:all, :type => :special) do
+ order << :special_append_before_all
+ end
+ @config.append_before(:all, :type => :special_child) do
+ order << :special_child_append_before_all
+ end
+ @config.append_before(:each) do
+ order << :append_before_each
+ end
+ @config.append_before(:each, :type => :special) do
+ order << :special_append_before_each
+ end
+ @config.append_before(:each, :type => :special_child) do
+ order << :special_child_append_before_each
+ end
+ @config.append_before(:all, :type => :non_special) do
+ order << :special_append_before_all
+ end
+ @config.append_before(:each, :type => :non_special) do
+ order << :special_append_before_each
+ end
+ @example_group.it "calls append_before" do
+ end
+
+ @example_group.run
+ order.should == [
+ :append_before_all,
+ :special_append_before_all,
+ :special_child_append_before_all,
+ :append_before_each,
+ :special_append_before_each,
+ :special_child_append_before_each
+ ]
+ end
+ end
+
+ describe "#prepend_after" do
+
+ it "prepends the after block on all instances of the passed in type" do
+ order = []
+ @config.prepend_after(:all) do
+ order << :prepend__after_all
+ end
+ @config.prepend_after(:all, :type => :special) do
+ order << :special_prepend__after_all
+ end
+ @config.prepend_after(:all, :type => :special) do
+ order << :special_child_prepend__after_all
+ end
+ @config.prepend_after(:each) do
+ order << :prepend__after_each
+ end
+ @config.prepend_after(:each, :type => :special) do
+ order << :special_prepend__after_each
+ end
+ @config.prepend_after(:each, :type => :special) do
+ order << :special_child_prepend__after_each
+ end
+ @config.prepend_after(:all, :type => :non_special) do
+ order << :special_prepend__after_all
+ end
+ @config.prepend_after(:each, :type => :non_special) do
+ order << :special_prepend__after_each
+ end
+ @example_group.it "calls prepend_after" do
+ end
+
+ @example_group.run
+ order.should == [
+ :special_child_prepend__after_each,
+ :special_prepend__after_each,
+ :prepend__after_each,
+ :special_child_prepend__after_all,
+ :special_prepend__after_all,
+ :prepend__after_all
+ ]
+ end
+ end
+
+ describe "#append_after" do
+
+ it "calls append_after on the type" do
+ order = []
+ @config.append_after(:all) do
+ order << :append__after_all
+ end
+ @config.append_after(:all, :type => :special) do
+ order << :special_append__after_all
+ end
+ @config.append_after(:all, :type => :special_child) do
+ order << :special_child_append__after_all
+ end
+ @config.append_after(:each) do
+ order << :append__after_each
+ end
+ @config.append_after(:each, :type => :special) do
+ order << :special_append__after_each
+ end
+ @config.append_after(:each, :type => :special_child) do
+ order << :special_child_append__after_each
+ end
+ @config.append_after(:all, :type => :non_special) do
+ order << :non_special_append_after_all
+ end
+ @config.append_after(:each, :type => :non_special) do
+ order << :non_special_append_after_each
+ end
+ @example_group.it "calls append_after" do
+ end
+
+ @example_group.run
+ order.should == [
+ :special_child_append__after_each,
+ :special_append__after_each,
+ :append__after_each,
+ :special_child_append__after_all,
+ :special_append__after_all,
+ :append__after_all
+ ]
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/example/example_group_class_definition_spec.rb b/vendor/gems/rspec/spec/spec/example/example_group_class_definition_spec.rb
new file mode 100644
index 000000000..0b00e1397
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/example_group_class_definition_spec.rb
@@ -0,0 +1,48 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Example
+ class ExampleGroupSubclass < ExampleGroup
+ class << self
+ attr_accessor :examples_ran
+ end
+
+ @@klass_variable_set = true
+ CONSTANT = :foobar
+
+ before do
+ @instance_variable = :hello
+ end
+
+ it "should run" do
+ self.class.examples_ran = true
+ end
+
+ it "should have access to instance variables" do
+ @instance_variable.should == :hello
+ end
+
+ it "should have access to class variables" do
+ @@klass_variable_set.should == true
+ end
+
+ it "should have access to constants" do
+ CONSTANT.should == :foobar
+ end
+
+ it "should have access to methods defined in the Example Group" do
+ a_method.should == 22
+ end
+
+ def a_method
+ 22
+ end
+ end
+
+ describe ExampleGroupSubclass do
+ it "should run" do
+ ExampleGroupSubclass.examples_ran.should be_true
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/example/example_group_factory_spec.rb b/vendor/gems/rspec/spec/spec/example/example_group_factory_spec.rb
new file mode 100644
index 000000000..3b50011f7
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/example_group_factory_spec.rb
@@ -0,0 +1,129 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Example
+ describe ExampleGroupFactory, "with :foobar registered as custom type" do
+
+ before do
+ @example_group = Class.new(ExampleGroup)
+ ExampleGroupFactory.register(:foobar, @example_group)
+ end
+
+ after do
+ ExampleGroupFactory.reset
+ end
+
+ it "should #get the default ExampleGroup type when passed nil" do
+ ExampleGroupFactory.get(nil).should == ExampleGroup
+ end
+
+ it "should #get the default ExampleGroup for unregistered non-nil values" do
+ ExampleGroupFactory.get(:does_not_exist).should == ExampleGroup
+ end
+
+ it "should #get custom type for :foobar" do
+ ExampleGroupFactory.get(:foobar).should == @example_group
+ end
+
+ it "should #get the actual type when that is passed in" do
+ ExampleGroupFactory.get(@example_group).should == @example_group
+ end
+
+ end
+
+ describe ExampleGroupFactory, "#create_example_group" do
+ it "should create a uniquely named class" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group("example_group") {}
+ example_group.name.should =~ /Spec::Example::ExampleGroup::Subclass_\d+/
+ end
+
+ it "should create a Spec::Example::Example subclass by default" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group("example_group") {}
+ example_group.superclass.should == Spec::Example::ExampleGroup
+ end
+
+ it "should create a Spec::Example::Example when :type => :default" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "example_group", :type => :default
+ ) {}
+ example_group.superclass.should == Spec::Example::ExampleGroup
+ end
+
+ it "should create a Spec::Example::Example when :type => :default" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "example_group", :type => :default
+ ) {}
+ example_group.superclass.should == Spec::Example::ExampleGroup
+ end
+
+ it "should create specified type when :type => :something_other_than_default" do
+ klass = Class.new(ExampleGroup) do
+ def initialize(*args, &block); end
+ end
+ Spec::Example::ExampleGroupFactory.register(:something_other_than_default, klass)
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "example_group", :type => :something_other_than_default
+ ) {}
+ example_group.superclass.should == klass
+ end
+
+ it "should create a type indicated by :spec_path" do
+ klass = Class.new(ExampleGroup) do
+ def initialize(*args, &block); end
+ end
+ Spec::Example::ExampleGroupFactory.register(:something_other_than_default, klass)
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "example_group", :spec_path => "./spec/something_other_than_default/some_spec.rb"
+ ) {}
+ example_group.superclass.should == klass
+ end
+
+ it "should create a type indicated by :spec_path (with spec_path generated by caller on windows)" do
+ klass = Class.new(ExampleGroup) do
+ def initialize(*args, &block); end
+ end
+ Spec::Example::ExampleGroupFactory.register(:something_other_than_default, klass)
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "example_group", :spec_path => "./spec\\something_other_than_default\\some_spec.rb"
+ ) {}
+ example_group.superclass.should == klass
+ end
+
+ it "should create and register a Spec::Example::Example if :shared => true" do
+ shared_example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :spec_path => '/blah/spec/models/blah.rb', :type => :controller, :shared => true
+ ) {}
+ shared_example_group.should be_an_instance_of(Spec::Example::SharedExampleGroup)
+ SharedExampleGroup.shared_example_groups.should include(shared_example_group)
+ end
+
+ it "should favor the :type over the :spec_path" do
+ klass = Class.new(ExampleGroup) do
+ def initialize(*args, &block); end
+ end
+ Spec::Example::ExampleGroupFactory.register(:something_other_than_default, klass)
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group(
+ "name", :spec_path => '/blah/spec/models/blah.rb', :type => :something_other_than_default
+ ) {}
+ example_group.superclass.should == klass
+ end
+
+ it "should register ExampleGroup by default" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group("The ExampleGroup") do
+ end
+ rspec_options.example_groups.should include(example_group)
+ end
+
+ it "should enable unregistering of ExampleGroups" do
+ example_group = Spec::Example::ExampleGroupFactory.create_example_group("The ExampleGroup") do
+ unregister
+ end
+ rspec_options.example_groups.should_not include(example_group)
+ end
+
+ after(:each) do
+ Spec::Example::ExampleGroupFactory.reset
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/example/example_group_methods_spec.rb b/vendor/gems/rspec/spec/spec/example/example_group_methods_spec.rb
new file mode 100644
index 000000000..2b6d660fe
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/example_group_methods_spec.rb
@@ -0,0 +1,489 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Example
+ describe 'ExampleGroupMethods' do
+ it_should_behave_like "sandboxed rspec_options"
+ attr_reader :example_group, :result, :reporter
+ before(:each) do
+ options.formatters << mock("formatter", :null_object => true)
+ options.backtrace_tweaker = mock("backtrace_tweaker", :null_object => true)
+ @reporter = FakeReporter.new(@options)
+ options.reporter = reporter
+ @example_group = Class.new(ExampleGroup) do
+ describe("ExampleGroup")
+ it "does nothing"
+ end
+ class << example_group
+ public :include
+ end
+ @result = nil
+ end
+
+ after(:each) do
+ ExampleGroup.reset
+ end
+
+ describe "#describe" do
+ attr_reader :child_example_group
+ before do
+ @child_example_group = @example_group.describe("Another ExampleGroup") do
+ it "should pass" do
+ true.should be_true
+ end
+ end
+ end
+
+ it "should create a subclass of the ExampleGroup when passed a block" do
+ child_example_group.superclass.should == @example_group
+ @options.example_groups.should include(child_example_group)
+ end
+
+ it "should not inherit examples" do
+ child_example_group.examples.length.should == 1
+ end
+ end
+
+ describe "#it" do
+ it "should should create an example instance" do
+ lambda {
+ @example_group.it("")
+ }.should change { @example_group.examples.length }.by(1)
+ end
+ end
+
+ describe "#xit" do
+ before(:each) do
+ Kernel.stub!(:warn)
+ end
+
+ it "should NOT should create an example instance" do
+ lambda {
+ @example_group.xit("")
+ }.should_not change(@example_group.examples, :length)
+ end
+
+ it "should warn that it is disabled" do
+ Kernel.should_receive(:warn).with("Example disabled: foo")
+ @example_group.xit("foo")
+ end
+ end
+
+ describe "#examples" do
+ it "should have Examples" do
+ example_group = Class.new(ExampleGroup) do
+ describe('example')
+ it "should pass" do
+ 1.should == 1
+ end
+ end
+ example_group.examples.length.should == 1
+ example_group.examples.first.description.should == "should pass"
+ end
+
+ it "should not include methods that begin with test (only when TU interop is loaded)" do
+ example_group = Class.new(ExampleGroup) do
+ describe('example')
+ def test_any_args(*args)
+ true.should be_true
+ end
+ def test_something
+ 1.should == 1
+ end
+ def test
+ raise "This is not a real test"
+ end
+ def testify
+ raise "This is not a real test"
+ end
+ end
+ example_group.examples.length.should == 0
+ example_group.run.should be_true
+ end
+
+ it "should include methods that begin with should and has an arity of 0 in suite" do
+ example_group = Class.new(ExampleGroup) do
+ describe('example')
+ def shouldCamelCase
+ true.should be_true
+ end
+ def should_any_args(*args)
+ true.should be_true
+ end
+ def should_something
+ 1.should == 1
+ end
+ def should_not_something
+ 1.should_not == 2
+ end
+ def should
+ raise "This is not a real example"
+ end
+ def should_not
+ raise "This is not a real example"
+ end
+ end
+ example_group = example_group.dup
+ example_group.examples.length.should == 4
+ descriptions = example_group.examples.collect {|example| example.description}.sort
+ descriptions.should include("shouldCamelCase")
+ descriptions.should include("should_any_args")
+ descriptions.should include("should_something")
+ descriptions.should include("should_not_something")
+ end
+
+ it "should not include methods that begin with test_ and has an arity > 0 in suite" do
+ example_group = Class.new(ExampleGroup) do
+ describe('example')
+ def test_invalid(foo)
+ 1.should == 1
+ end
+ def testInvalidCamelCase(foo)
+ 1.should == 1
+ end
+ end
+ example_group.examples.length.should == 0
+ end
+
+ it "should not include methods that begin with should_ and has an arity > 0 in suite" do
+ example_group = Class.new(ExampleGroup) do
+ describe('example')
+ def should_invalid(foo)
+ 1.should == 2
+ end
+ def shouldInvalidCamelCase(foo)
+ 1.should == 3
+ end
+ def should_not_invalid(foo)
+ 1.should == 4
+ end
+ def should_valid
+ 1.should == 1
+ end
+ end
+ example_group.examples.length.should == 1
+ example_group.run.should be_true
+ end
+
+ it "should run should_methods" do
+ example_group = Class.new(ExampleGroup) do
+ def should_valid
+ 1.should == 2
+ end
+ end
+ example_group.examples.length.should == 1
+ example_group.run.should be_false
+ end
+ end
+
+ describe "#set_description" do
+ attr_reader :example_group
+ before do
+ class << example_group
+ public :set_description
+ end
+ end
+
+ describe "#set_description(String)" do
+ before(:each) do
+ example_group.set_description("abc")
+ end
+
+ specify ".description should return the String passed into .set_description" do
+ example_group.description.should == "abc"
+ end
+
+ specify ".described_type should provide nil as its type" do
+ example_group.described_type.should be_nil
+ end
+ end
+
+ describe "#set_description(Type)" do
+ before(:each) do
+ example_group.set_description(ExampleGroup)
+ end
+
+ specify ".description should return a String representation of that type (fully qualified) as its name" do
+ example_group.description.should == "Spec::Example::ExampleGroup"
+ end
+
+ specify ".described_type should return the passed in type" do
+ example_group.described_type.should == Spec::Example::ExampleGroup
+ end
+ end
+
+ describe "#set_description(String, Type)" do
+ before(:each) do
+ example_group.set_description("behaving", ExampleGroup)
+ end
+
+ specify ".description should return String then space then Type" do
+ example_group.description.should == "behaving Spec::Example::ExampleGroup"
+ end
+
+ specify ".described_type should return the passed in type" do
+ example_group.described_type.should == Spec::Example::ExampleGroup
+ end
+ end
+
+ describe "#set_description(Type, String not starting with a space)" do
+ before(:each) do
+ example_group.set_description(ExampleGroup, "behaving")
+ end
+
+ specify ".description should return the Type then space then String" do
+ example_group.description.should == "Spec::Example::ExampleGroup behaving"
+ end
+ end
+
+ describe "#set_description(Type, String starting with .)" do
+ before(:each) do
+ example_group.set_description(ExampleGroup, ".behaving")
+ end
+
+ specify ".description should return the Type then String" do
+ example_group.description.should == "Spec::Example::ExampleGroup.behaving"
+ end
+ end
+
+ describe "#set_description(Type, String containing .)" do
+ before(:each) do
+ example_group.set_description(ExampleGroup, "calling a.b")
+ end
+
+ specify ".description should return the Type then space then String" do
+ example_group.description.should == "Spec::Example::ExampleGroup calling a.b"
+ end
+ end
+
+ describe "#set_description(Type, String starting with .)" do
+ before(:each) do
+ example_group.set_description(ExampleGroup, ".behaving")
+ end
+
+ specify "should return the Type then String" do
+ example_group.description.should == "Spec::Example::ExampleGroup.behaving"
+ end
+ end
+
+ describe "#set_description(Type, String containing .)" do
+ before(:each) do
+ example_group.set_description(ExampleGroup, "is #1")
+ end
+
+ specify ".description should return the Type then space then String" do
+ example_group.description.should == "Spec::Example::ExampleGroup is #1"
+ end
+ end
+
+ describe "#set_description(String, Type, String)" do
+ before(:each) do
+ example_group.set_description("A", Hash, "with one entry")
+ end
+
+ specify ".description should return the first String then space then Type then second String" do
+ example_group.description.should == "A Hash with one entry"
+ end
+ end
+
+ describe "#set_description(Hash representing options)" do
+ before(:each) do
+ example_group.set_description(:a => "b", :spec_path => "blah")
+ end
+
+ it ".spec_path should expand the passed in :spec_path option passed into the constructor" do
+ example_group.spec_path.should == File.expand_path("blah")
+ end
+
+ it ".description_options should return all the options passed in" do
+ example_group.description_options.should == {:a => "b", :spec_path => "blah"}
+ end
+
+ end
+ end
+
+ describe "#description" do
+ it "should return the same description instance for each call" do
+ example_group.description.should eql(example_group.description)
+ end
+
+ it "should not add a space when description_text begins with #" do
+ child_example_group = Class.new(example_group) do
+ describe("#foobar", "Does something")
+ end
+ child_example_group.description.should == "ExampleGroup#foobar Does something"
+ end
+
+ it "should not add a space when description_text begins with ." do
+ child_example_group = Class.new(example_group) do
+ describe(".foobar", "Does something")
+ end
+ child_example_group.description.should == "ExampleGroup.foobar Does something"
+ end
+
+ it "should return the class name if nil" do
+ example_group.set_description(nil)
+ example_group.description.should =~ /Class:/
+ end
+
+ it "should return the class name if nil" do
+ example_group.set_description("")
+ example_group.description.should =~ /Class:/
+ end
+ end
+
+ describe "#description_parts" do
+ it "should return an Array of the current class description args" do
+ example_group.description_parts.should == [example_group.description]
+ end
+
+ it "should return an Array of the description args from each class in the hierarchy" do
+ child_example_group = Class.new(example_group)
+ child_example_group.describe("Child", ExampleGroup)
+ child_example_group.description.should_not be_empty
+
+ grand_child_example_group = Class.new(child_example_group)
+ grand_child_example_group.describe("GrandChild", ExampleGroup)
+ grand_child_example_group.description.should_not be_empty
+
+ grand_child_example_group.description_parts.should == [
+ "ExampleGroup",
+ "Child",
+ Spec::Example::ExampleGroup,
+ "GrandChild",
+ Spec::Example::ExampleGroup
+ ]
+ end
+ end
+
+ describe "#described_type" do
+ it "should return passed in type" do
+ child_example_group = Class.new(example_group) do
+ describe Object
+ end
+ child_example_group.described_type.should == Object
+ end
+
+ it "should return #described_type of superclass when no passed in type" do
+ parent_example_group = Class.new(ExampleGroup) do
+ describe Object, "#foobar"
+ end
+ child_example_group = Class.new(parent_example_group) do
+ describe "not a type"
+ end
+ child_example_group.described_type.should == Object
+ end
+ end
+
+ describe "#remove_after" do
+ it "should unregister a given after(:each) block" do
+ after_all_ran = false
+ @example_group.it("example") {}
+ proc = Proc.new { after_all_ran = true }
+ ExampleGroup.after(:each, &proc)
+ @example_group.run
+ after_all_ran.should be_true
+
+ after_all_ran = false
+ ExampleGroup.remove_after(:each, &proc)
+ @example_group.run
+ after_all_ran.should be_false
+ end
+ end
+
+ describe "#include" do
+ it "should have accessible class methods from included module" do
+ mod1_method_called = false
+ mod1 = Module.new do
+ class_methods = Module.new do
+ define_method :mod1_method do
+ mod1_method_called = true
+ end
+ end
+
+ metaclass.class_eval do
+ define_method(:included) do |receiver|
+ receiver.extend class_methods
+ end
+ end
+ end
+
+ mod2_method_called = false
+ mod2 = Module.new do
+ class_methods = Module.new do
+ define_method :mod2_method do
+ mod2_method_called = true
+ end
+ end
+
+ metaclass.class_eval do
+ define_method(:included) do |receiver|
+ receiver.extend class_methods
+ end
+ end
+ end
+
+ @example_group.include mod1, mod2
+
+ @example_group.mod1_method
+ @example_group.mod2_method
+ mod1_method_called.should be_true
+ mod2_method_called.should be_true
+ end
+ end
+
+ describe "#number_of_examples" do
+ it "should count number of specs" do
+ proc do
+ @example_group.it("one") {}
+ @example_group.it("two") {}
+ @example_group.it("three") {}
+ @example_group.it("four") {}
+ end.should change {@example_group.number_of_examples}.by(4)
+ end
+ end
+
+ describe "#class_eval" do
+ it "should allow constants to be defined" do
+ example_group = Class.new(ExampleGroup) do
+ describe('example')
+ FOO = 1
+ it "should reference FOO" do
+ FOO.should == 1
+ end
+ end
+ example_group.run
+ Object.const_defined?(:FOO).should == false
+ end
+ end
+
+ describe '#register' do
+ it "should add ExampleGroup to set of ExampleGroups to be run" do
+ options.example_groups.delete(example_group)
+ options.example_groups.should_not include(example_group)
+
+ example_group.register {}
+ options.example_groups.should include(example_group)
+ end
+ end
+
+ describe '#unregister' do
+ before do
+ options.example_groups.should include(example_group)
+ end
+
+ it "should remove ExampleGroup from set of ExampleGroups to be run" do
+ example_group.unregister
+ options.example_groups.should_not include(example_group)
+ end
+ end
+
+ describe "#registration_backtrace" do
+ it "returns the backtrace of where the ExampleGroup was registered" do
+ example_group = Class.new(ExampleGroup)
+ example_group.registration_backtrace.join("\n").should include("#{__FILE__}:#{__LINE__-1}")
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/example/example_group_spec.rb b/vendor/gems/rspec/spec/spec/example/example_group_spec.rb
new file mode 100644
index 000000000..93e558a97
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/example_group_spec.rb
@@ -0,0 +1,711 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Example
+ class ExampleModuleScopingSpec < ExampleGroup
+ describe ExampleGroup, "via a class definition"
+
+ module Foo
+ module Bar
+ def self.loaded?
+ true
+ end
+ end
+ end
+ include Foo
+
+ it "should understand module scoping" do
+ Bar.should be_loaded
+ end
+
+ @@foo = 1
+
+ it "should allow class variables to be defined" do
+ @@foo.should == 1
+ end
+ end
+
+ class ExampleClassVariablePollutionSpec < ExampleGroup
+ describe ExampleGroup, "via a class definition without a class variable"
+
+ it "should not retain class variables from other Example classes" do
+ proc do
+ @@foo
+ end.should raise_error
+ end
+ end
+
+ describe ExampleGroup, "#pending" do
+ it "should raise a Pending error when its block fails" do
+ block_ran = false
+ lambda {
+ pending("something") do
+ block_ran = true
+ raise "something wrong with my example"
+ end
+ }.should raise_error(Spec::Example::ExamplePendingError, "something")
+ block_ran.should == true
+ end
+
+ it "should raise Spec::Example::PendingExampleFixedError when its block does not fail" do
+ block_ran = false
+ lambda {
+ pending("something") do
+ block_ran = true
+ end
+ }.should raise_error(Spec::Example::PendingExampleFixedError, "Expected pending 'something' to fail. No Error was raised.")
+ block_ran.should == true
+ end
+ end
+
+ describe ExampleGroup, "#run with failure in example", :shared => true do
+ it "should add an example failure to the TestResult" do
+ example_group.run.should be_false
+ end
+ end
+
+ describe ExampleGroup, "#run" do
+ it_should_behave_like "sandboxed rspec_options"
+ attr_reader :example_group, :formatter, :reporter
+ before :each do
+ @formatter = mock("formatter", :null_object => true)
+ options.formatters << formatter
+ options.backtrace_tweaker = mock("backtrace_tweaker", :null_object => true)
+ @reporter = FakeReporter.new(options)
+ options.reporter = reporter
+ @example_group = Class.new(ExampleGroup) do
+ describe("example")
+ it "does nothing" do
+ end
+ end
+ class << example_group
+ public :include
+ end
+ end
+
+ after :each do
+ ExampleGroup.reset
+ end
+
+ it "should not run when there are no examples" do
+ example_group = Class.new(ExampleGroup) do
+ describe("Foobar")
+ end
+ example_group.examples.should be_empty
+
+ reporter = mock("Reporter")
+ reporter.should_not_receive(:add_example_group)
+ example_group.run
+ end
+
+ describe "when before_each fails" do
+ before(:each) do
+ $example_ran = $after_each_ran = false
+ @example_group = describe("Foobar") do
+ before(:each) {raise}
+ it "should not be run" do
+ $example_ran = true
+ end
+ after(:each) do
+ $after_each_ran = true
+ end
+ end
+ end
+
+ it "should not run example block" do
+ example_group.run
+ $example_ran.should be_false
+ end
+
+ it "should run after_each" do
+ example_group.run
+ $after_each_ran.should be_true
+ end
+
+ it "should report failure location when in before_each" do
+ reporter.should_receive(:example_finished) do |example_group, error|
+ error.message.should eql("in before_each")
+ end
+ example_group.run
+ end
+ end
+
+ describe ExampleGroup, "#run on dry run" do
+ before do
+ @options.dry_run = true
+ end
+
+ it "should not run before(:all) or after(:all)" do
+ before_all_ran = false
+ after_all_ran = false
+ ExampleGroup.before(:all) { before_all_ran = true }
+ ExampleGroup.after(:all) { after_all_ran = true }
+ example_group.it("should") {}
+ example_group.run
+ before_all_ran.should be_false
+ after_all_ran.should be_false
+ end
+
+ it "should not run example" do
+ example_ran = false
+ example_group.it("should") {example_ran = true}
+ example_group.run
+ example_ran.should be_false
+ end
+ end
+
+ describe ExampleGroup, "#run with specified examples" do
+ attr_reader :examples_that_were_run
+ before do
+ @examples_that_were_run = []
+ end
+
+ describe "when specified_examples matches entire ExampleGroup" do
+ before do
+ examples_that_were_run = @examples_that_were_run
+ @example_group = Class.new(ExampleGroup) do
+ describe("the ExampleGroup")
+ it("should be run") do
+ examples_that_were_run << 'should be run'
+ end
+
+ it("should also be run") do
+ examples_that_were_run << 'should also be run'
+ end
+ end
+ options.examples = ["the ExampleGroup"]
+ end
+
+ it "should not run the Examples in the ExampleGroup" do
+ example_group.run
+ examples_that_were_run.should == ['should be run', 'should also be run']
+ end
+ end
+
+ describe ExampleGroup, "#run when specified_examples matches only Example description" do
+ before do
+ examples_that_were_run = @examples_that_were_run
+ @example_group = Class.new(ExampleGroup) do
+ describe("example")
+ it("should be run") do
+ examples_that_were_run << 'should be run'
+ end
+ end
+ options.examples = ["should be run"]
+ end
+
+ it "should not run the example" do
+ example_group.run
+ examples_that_were_run.should == ['should be run']
+ end
+ end
+
+ describe ExampleGroup, "#run when specified_examples does not match an Example description" do
+ before do
+ examples_that_were_run = @examples_that_were_run
+ @example_group = Class.new(ExampleGroup) do
+ describe("example")
+ it("should be something else") do
+ examples_that_were_run << 'should be something else'
+ end
+ end
+ options.examples = ["does not match anything"]
+ end
+
+ it "should not run the example" do
+ example_group.run
+ examples_that_were_run.should == []
+ end
+ end
+
+ describe ExampleGroup, "#run when specified_examples matches an Example description" do
+ before do
+ examples_that_were_run = @examples_that_were_run
+ @example_group = Class.new(ExampleGroup) do
+ describe("example")
+ it("should be run") do
+ examples_that_were_run << 'should be run'
+ end
+ it("should not be run") do
+ examples_that_were_run << 'should not be run'
+ end
+ end
+ options.examples = ["should be run"]
+ end
+
+ it "should run only the example, when there in only one" do
+ example_group.run
+ examples_that_were_run.should == ["should be run"]
+ end
+
+ it "should run only the one example" do
+ example_group.run
+ examples_that_were_run.should == ["should be run"] end
+ end
+ end
+
+ describe ExampleGroup, "#run with success" do
+ before do
+ @special_example_group = Class.new(ExampleGroup)
+ ExampleGroupFactory.register(:special, @special_example_group)
+ @not_special_example_group = Class.new(ExampleGroup)
+ ExampleGroupFactory.register(:not_special, @not_special_example_group)
+ end
+
+ after do
+ ExampleGroupFactory.reset
+ end
+
+ it "should send reporter add_example_group" do
+ example_group.run
+ reporter.example_groups.should == [example_group]
+ end
+
+ it "should run example on run" do
+ example_ran = false
+ example_group.it("should") {example_ran = true}
+ example_group.run
+ example_ran.should be_true
+ end
+
+ it "should run before(:all) block only once" do
+ before_all_run_count_run_count = 0
+ example_group.before(:all) {before_all_run_count_run_count += 1}
+ example_group.it("test") {true}
+ example_group.it("test2") {true}
+ example_group.run
+ before_all_run_count_run_count.should == 1
+ end
+
+ it "should run after(:all) block only once" do
+ after_all_run_count = 0
+ example_group.after(:all) {after_all_run_count += 1}
+ example_group.it("test") {true}
+ example_group.it("test2") {true}
+ example_group.run
+ after_all_run_count.should == 1
+ @reporter.rspec_verify
+ end
+
+ it "after(:all) should have access to all instance variables defined in before(:all)" do
+ context_instance_value_in = "Hello there"
+ context_instance_value_out = ""
+ example_group.before(:all) { @instance_var = context_instance_value_in }
+ example_group.after(:all) { context_instance_value_out = @instance_var }
+ example_group.it("test") {true}
+ example_group.run
+ context_instance_value_in.should == context_instance_value_out
+ end
+
+ it "should copy instance variables from before(:all)'s execution context into spec's execution context" do
+ context_instance_value_in = "Hello there"
+ context_instance_value_out = ""
+ example_group.before(:all) { @instance_var = context_instance_value_in }
+ example_group.it("test") {context_instance_value_out = @instance_var}
+ example_group.run
+ context_instance_value_in.should == context_instance_value_out
+ end
+
+ it "should not add global before callbacks for untargetted example_group" do
+ fiddle = []
+
+ ExampleGroup.before(:all) { fiddle << "Example.before(:all)" }
+ ExampleGroup.prepend_before(:all) { fiddle << "Example.prepend_before(:all)" }
+ @special_example_group.before(:each) { fiddle << "Example.before(:each, :type => :special)" }
+ @special_example_group.prepend_before(:each) { fiddle << "Example.prepend_before(:each, :type => :special)" }
+ @special_example_group.before(:all) { fiddle << "Example.before(:all, :type => :special)" }
+ @special_example_group.prepend_before(:all) { fiddle << "Example.prepend_before(:all, :type => :special)" }
+
+ example_group = Class.new(ExampleGroup) do
+ describe("I'm not special", :type => :not_special)
+ it "does nothing"
+ end
+ example_group.run
+ fiddle.should == [
+ 'Example.prepend_before(:all)',
+ 'Example.before(:all)',
+ ]
+ end
+
+ it "should add global before callbacks for targetted example_groups" do
+ fiddle = []
+
+ ExampleGroup.before(:all) { fiddle << "Example.before(:all)" }
+ ExampleGroup.prepend_before(:all) { fiddle << "Example.prepend_before(:all)" }
+ @special_example_group.before(:each) { fiddle << "special.before(:each, :type => :special)" }
+ @special_example_group.prepend_before(:each) { fiddle << "special.prepend_before(:each, :type => :special)" }
+ @special_example_group.before(:all) { fiddle << "special.before(:all, :type => :special)" }
+ @special_example_group.prepend_before(:all) { fiddle << "special.prepend_before(:all, :type => :special)" }
+ @special_example_group.append_before(:each) { fiddle << "special.append_before(:each, :type => :special)" }
+
+ example_group = Class.new(@special_example_group).describe("I'm a special example_group") {}
+ example_group.it("test") {true}
+ example_group.run
+ fiddle.should == [
+ 'Example.prepend_before(:all)',
+ 'Example.before(:all)',
+ 'special.prepend_before(:all, :type => :special)',
+ 'special.before(:all, :type => :special)',
+ 'special.prepend_before(:each, :type => :special)',
+ 'special.before(:each, :type => :special)',
+ 'special.append_before(:each, :type => :special)',
+ ]
+ end
+
+ it "should order before callbacks from global to local" do
+ fiddle = []
+ ExampleGroup.prepend_before(:all) { fiddle << "Example.prepend_before(:all)" }
+ ExampleGroup.before(:all) { fiddle << "Example.before(:all)" }
+ example_group.prepend_before(:all) { fiddle << "prepend_before(:all)" }
+ example_group.before(:all) { fiddle << "before(:all)" }
+ example_group.prepend_before(:each) { fiddle << "prepend_before(:each)" }
+ example_group.before(:each) { fiddle << "before(:each)" }
+ example_group.run
+ fiddle.should == [
+ 'Example.prepend_before(:all)',
+ 'Example.before(:all)',
+ 'prepend_before(:all)',
+ 'before(:all)',
+ 'prepend_before(:each)',
+ 'before(:each)'
+ ]
+ end
+
+ it "should order after callbacks from local to global" do
+ fiddle = []
+ example_group.after(:each) { fiddle << "after(:each)" }
+ example_group.append_after(:each) { fiddle << "append_after(:each)" }
+ example_group.after(:all) { fiddle << "after(:all)" }
+ example_group.append_after(:all) { fiddle << "append_after(:all)" }
+ ExampleGroup.after(:all) { fiddle << "Example.after(:all)" }
+ ExampleGroup.append_after(:all) { fiddle << "Example.append_after(:all)" }
+ example_group.run
+ fiddle.should == [
+ 'after(:each)',
+ 'append_after(:each)',
+ 'after(:all)',
+ 'append_after(:all)',
+ 'Example.after(:all)',
+ 'Example.append_after(:all)'
+ ]
+ end
+
+ it "should have accessible instance methods from included module" do
+ mod1_method_called = false
+ mod1 = Module.new do
+ define_method :mod1_method do
+ mod1_method_called = true
+ end
+ end
+
+ mod2_method_called = false
+ mod2 = Module.new do
+ define_method :mod2_method do
+ mod2_method_called = true
+ end
+ end
+
+ example_group.include mod1, mod2
+
+ example_group.it("test") do
+ mod1_method
+ mod2_method
+ end
+ example_group.run
+ mod1_method_called.should be_true
+ mod2_method_called.should be_true
+ end
+
+ it "should include targetted modules included using configuration" do
+ mod1 = Module.new
+ mod2 = Module.new
+ mod3 = Module.new
+ Spec::Runner.configuration.include(mod1, mod2)
+ Spec::Runner.configuration.include(mod3, :type => :not_special)
+
+ example_group = Class.new(@special_example_group).describe("I'm special", :type => :special) do
+ it "does nothing"
+ end
+ example_group.run
+
+ example_group.included_modules.should include(mod1)
+ example_group.included_modules.should include(mod2)
+ example_group.included_modules.should_not include(mod3)
+ end
+
+ it "should include any predicate_matchers included using configuration" do
+ $included_predicate_matcher_found = false
+ Spec::Runner.configuration.predicate_matchers[:do_something] = :does_something?
+ example_group = Class.new(ExampleGroup) do
+ describe('example')
+ it "should respond to do_something" do
+ $included_predicate_matcher_found = respond_to?(:do_something)
+ end
+ end
+ example_group.run
+ $included_predicate_matcher_found.should be(true)
+ end
+
+ it "should use a mock framework set up in config" do
+ mod = Module.new do
+ class << self
+ def included(mod)
+ $included_module = mod
+ end
+ end
+
+ def teardown_mocks_for_rspec
+ $torn_down = true
+ end
+ end
+
+ begin
+ $included_module = nil
+ $torn_down = true
+ Spec::Runner.configuration.mock_with mod
+
+ example_group = Class.new(ExampleGroup) do
+ describe('example')
+ it "does nothing"
+ end
+ example_group.run
+
+ $included_module.should_not be_nil
+ $torn_down.should == true
+ ensure
+ Spec::Runner.configuration.mock_with :rspec
+ end
+ end
+ end
+
+ describe ExampleGroup, "#run with pending example that has a failing assertion" do
+ before do
+ example_group.it("should be pending") do
+ pending("Example fails") {false.should be_true}
+ end
+ end
+
+ it "should send example_pending to formatter" do
+ @formatter.should_receive(:example_pending).with("example", "should be pending", "Example fails")
+ example_group.run
+ end
+ end
+
+ describe ExampleGroup, "#run with pending example that does not have a failing assertion" do
+ it_should_behave_like "Spec::Example::ExampleGroup#run with failure in example"
+
+ before do
+ example_group.it("should be pending") do
+ pending("Example passes") {true.should be_true}
+ end
+ end
+
+ it "should send example_pending to formatter" do
+ @formatter.should_receive(:example_pending).with("example", "should be pending", "Example passes")
+ example_group.run
+ end
+ end
+
+ describe ExampleGroup, "#run when before(:all) fails" do
+ it_should_behave_like "Spec::Example::ExampleGroup#run with failure in example"
+
+ before do
+ ExampleGroup.before(:all) { raise NonStandardError, "before(:all) failure" }
+ end
+
+ it "should not run any example" do
+ spec_ran = false
+ example_group.it("test") {spec_ran = true}
+ example_group.run
+ spec_ran.should be_false
+ end
+
+ it "should run ExampleGroup after(:all)" do
+ after_all_ran = false
+ ExampleGroup.after(:all) { after_all_ran = true }
+ example_group.run
+ after_all_ran.should be_true
+ end
+
+ it "should run example_group after(:all)" do
+ after_all_ran = false
+ example_group.after(:all) { after_all_ran = true }
+ example_group.run
+ after_all_ran.should be_true
+ end
+
+ it "should supply before(:all) as description" do
+ @reporter.should_receive(:failure) do |example, error|
+ example.description.should eql("before(:all)")
+ error.message.should eql("before(:all) failure")
+ end
+
+ example_group.it("test") {true}
+ example_group.run
+ end
+ end
+
+ describe ExampleGroup, "#run when before(:each) fails" do
+ it_should_behave_like "Spec::Example::ExampleGroup#run with failure in example"
+
+ before do
+ ExampleGroup.before(:each) { raise NonStandardError }
+ end
+
+ it "should run after(:all)" do
+ after_all_ran = false
+ ExampleGroup.after(:all) { after_all_ran = true }
+ example_group.run
+ after_all_ran.should be_true
+ end
+ end
+
+ describe ExampleGroup, "#run when any example fails" do
+ it_should_behave_like "Spec::Example::ExampleGroup#run with failure in example"
+
+ before do
+ example_group.it("should") { raise NonStandardError }
+ end
+
+ it "should run after(:all)" do
+ after_all_ran = false
+ ExampleGroup.after(:all) { after_all_ran = true }
+ example_group.run
+ after_all_ran.should be_true
+ end
+ end
+
+ describe ExampleGroup, "#run when first after(:each) block fails" do
+ it_should_behave_like "Spec::Example::ExampleGroup#run with failure in example"
+
+ before do
+ class << example_group
+ attr_accessor :first_after_ran, :second_after_ran
+ end
+ example_group.first_after_ran = false
+ example_group.second_after_ran = false
+
+ example_group.after(:each) do
+ self.class.second_after_ran = true
+ end
+ example_group.after(:each) do
+ self.class.first_after_ran = true
+ raise "first"
+ end
+ end
+
+ it "should run second after(:each) block" do
+ reporter.should_receive(:example_finished) do |example, error|
+ example.should equal(example)
+ error.message.should eql("first")
+ end
+ example_group.run
+ example_group.first_after_ran.should be_true
+ example_group.second_after_ran.should be_true
+ end
+ end
+
+ describe ExampleGroup, "#run when first before(:each) block fails" do
+ it_should_behave_like "Spec::Example::ExampleGroup#run with failure in example"
+
+ before do
+ class << example_group
+ attr_accessor :first_before_ran, :second_before_ran
+ end
+ example_group.first_before_ran = false
+ example_group.second_before_ran = false
+
+ example_group.before(:each) do
+ self.class.first_before_ran = true
+ raise "first"
+ end
+ example_group.before(:each) do
+ self.class.second_before_ran = true
+ end
+ end
+
+ it "should not run second before(:each)" do
+ reporter.should_receive(:example_finished) do |name, error|
+ error.message.should eql("first")
+ end
+ example_group.run
+ example_group.first_before_ran.should be_true
+ example_group.second_before_ran.should be_false
+ end
+ end
+
+ describe ExampleGroup, "#run when failure in after(:all)" do
+ it_should_behave_like "Spec::Example::ExampleGroup#run with failure in example"
+
+ before do
+ ExampleGroup.after(:all) { raise NonStandardError, "in after(:all)" }
+ end
+
+ it "should return false" do
+ example_group.run.should be_false
+ end
+ end
+ end
+
+ class ExampleSubclass < ExampleGroup
+ end
+
+ describe ExampleGroup, "subclasses" do
+ after do
+ ExampleGroupFactory.reset
+ end
+
+ it "should have access to the described_type" do
+ example_group = Class.new(ExampleSubclass) do
+ describe(Array)
+ end
+ example_group.send(:described_type).should == Array
+ end
+
+ it "should concat descriptions when nested" do
+ example_group = Class.new(ExampleSubclass) do
+ describe(Array)
+ $nested_group = describe("when empty") do
+ end
+ end
+ $nested_group.description.to_s.should == "Array when empty"
+ end
+ end
+
+ describe Enumerable do
+ def each(&block)
+ ["4", "2", "1"].each(&block)
+ end
+
+ it "should be included in examples because it is a module" do
+ map{|e| e.to_i}.should == [4,2,1]
+ end
+ end
+
+ describe "An", Enumerable, "as a second argument" do
+ def each(&block)
+ ["4", "2", "1"].each(&block)
+ end
+
+ it "should be included in examples because it is a module" do
+ map{|e| e.to_i}.should == [4,2,1]
+ end
+ end
+
+ describe Enumerable do
+ describe "as the parent of nested example groups" do
+ it "should be included in examples because it is a module" do
+ pending("need to make sure nested groups know the described type") do
+ map{|e| e.to_i}.should == [4,2,1]
+ end
+ end
+ end
+ end
+
+ describe String do
+ it"should not be included in examples because it is not a module" do
+ lambda{self.map}.should raise_error(NoMethodError, /undefined method `map' for/)
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/example/example_matcher_spec.rb b/vendor/gems/rspec/spec/spec/example/example_matcher_spec.rb
new file mode 100644
index 000000000..ea0dfe019
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/example_matcher_spec.rb
@@ -0,0 +1,96 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Example
+ module ExampleMatcherSpecHelper
+ class MatchDescription
+ def initialize(description)
+ @description = description
+ end
+
+ def matches?(matcher)
+ matcher.matches?(@description)
+ end
+
+ def failure_message
+ "expected matcher.matches?(#{@description.inspect}) to return true, got false"
+ end
+
+ def negative_failure_message
+ "expected matcher.matches?(#{@description.inspect}) to return false, got true"
+ end
+ end
+ def match_description(description)
+ MatchDescription.new(description)
+ end
+ end
+
+ describe ExampleMatcher, "#matches?" do
+ include ExampleMatcherSpecHelper
+
+ it "should match correct example_group and example" do
+ matcher = ExampleMatcher.new("example_group", "example")
+ matcher.should match_description("example_group example")
+ end
+
+ it "should not match wrong example" do
+ matcher = ExampleMatcher.new("example_group", "other example")
+ matcher.should_not match_description("example_group example")
+ end
+
+ it "should not match wrong example_group" do
+ matcher = ExampleMatcher.new("other example_group", "example")
+ matcher.should_not match_description("example_group example")
+ end
+
+ it "should match example only" do
+ matcher = ExampleMatcher.new("example_group", "example")
+ matcher.should match_description("example")
+ end
+
+ it "should match example_group only" do
+ matcher = ExampleMatcher.new("example_group", "example")
+ matcher.should match_description("example_group")
+ end
+
+ it "should match example_group ending with before(:all)" do
+ matcher = ExampleMatcher.new("example_group", "example")
+ matcher.should match_description("example_group before(:all)")
+ end
+
+ it "should escape regexp chars" do
+ matcher = ExampleMatcher.new("(con|text)", "[example]")
+ matcher.should_not match_description("con p")
+ end
+
+ it "should match when example_group is modularized" do
+ matcher = ExampleMatcher.new("MyModule::MyClass", "example")
+ matcher.should match_description("MyClass example")
+ end
+ end
+
+ describe ExampleMatcher, "#matches? normal case" do
+ it "matches when passed in example matches" do
+ matcher = ExampleMatcher.new("Foo", "bar")
+ matcher.matches?(["no match", "Foo bar"]).should == true
+ end
+
+ it "does not match when no passed in examples match" do
+ matcher = ExampleMatcher.new("Foo", "bar")
+ matcher.matches?(["no match1", "no match2"]).should == false
+ end
+ end
+
+ describe ExampleMatcher, "#matches? where description has '::' in it" do
+ it "matches when passed in example matches" do
+ matcher = ExampleMatcher.new("Foo::Bar", "baz")
+ matcher.matches?(["no match", "Foo::Bar baz"]).should == true
+ end
+
+ it "does not match when no passed in examples match" do
+ matcher = ExampleMatcher.new("Foo::Bar", "baz")
+ matcher.matches?(["no match1", "no match2"]).should == false
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/example/example_methods_spec.rb b/vendor/gems/rspec/spec/spec/example/example_methods_spec.rb
new file mode 100644
index 000000000..c18522808
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/example_methods_spec.rb
@@ -0,0 +1,104 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Example
+ module ModuleThatIsReopened
+ end
+
+ module ExampleMethods
+ include ModuleThatIsReopened
+ end
+
+ module ModuleThatIsReopened
+ def module_that_is_reopened_method
+ end
+ end
+
+ describe ExampleMethods do
+ describe "with an included module that is reopened" do
+ it "should have repoened methods" do
+ method(:module_that_is_reopened_method).should_not be_nil
+ end
+ end
+
+ describe "lifecycle" do
+ before do
+ @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new)
+ @options.formatters << mock("formatter", :null_object => true)
+ @options.backtrace_tweaker = mock("backtrace_tweaker", :null_object => true)
+ @reporter = FakeReporter.new(@options)
+ @options.reporter = @reporter
+
+ ExampleMethods.before_all_parts.should == []
+ ExampleMethods.before_each_parts.should == []
+ ExampleMethods.after_each_parts.should == []
+ ExampleMethods.after_all_parts.should == []
+ def ExampleMethods.count
+ @count ||= 0
+ @count = @count + 1
+ @count
+ end
+ end
+
+ after do
+ ExampleMethods.instance_variable_set("@before_all_parts", [])
+ ExampleMethods.instance_variable_set("@before_each_parts", [])
+ ExampleMethods.instance_variable_set("@after_each_parts", [])
+ ExampleMethods.instance_variable_set("@after_all_parts", [])
+ end
+
+ it "should pass before and after callbacks to all ExampleGroup subclasses" do
+ ExampleMethods.before(:all) do
+ ExampleMethods.count.should == 1
+ end
+
+ ExampleMethods.before(:each) do
+ ExampleMethods.count.should == 2
+ end
+
+ ExampleMethods.after(:each) do
+ ExampleMethods.count.should == 3
+ end
+
+ ExampleMethods.after(:all) do
+ ExampleMethods.count.should == 4
+ end
+
+ @example_group = Class.new(ExampleGroup) do
+ it "should use ExampleMethods callbacks" do
+ end
+ end
+ @example_group.run
+ ExampleMethods.count.should == 5
+ end
+
+ describe "run_with_description_capturing" do
+ before(:each) do
+ @example_group = Class.new(ExampleGroup) do end
+ @example = @example_group.new("foo", &(lambda { 2.should == 2 }))
+ @example.run_with_description_capturing
+ end
+
+ it "should provide the generated description" do
+ @example.instance_eval { @_matcher_description }.should == "should == 2"
+ end
+
+ it "should clear the global generated_description" do
+ Spec::Matchers.generated_description.should == nil
+ end
+ end
+ end
+
+ describe "#implementation_backtrace" do
+ it "returns the backtrace of where the implementation was defined" do
+ example_group = Class.new(ExampleGroup) do
+ it "should use ExampleMethods callbacks" do
+ end
+ end
+ example = example_group.examples.first
+ example.implementation_backtrace.join("\n").should include("#{__FILE__}:#{__LINE__-4}")
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/example/example_runner_spec.rb b/vendor/gems/rspec/spec/spec/example/example_runner_spec.rb
new file mode 100644
index 000000000..1b5abdf0f
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/example_runner_spec.rb
@@ -0,0 +1,194 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Example
+ # describe "Spec::Example::ExampleRunner", "#run", :shared => true do
+ # before(:each) do
+ # @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new)
+ # @reporter = ::Spec::Runner::Reporter.new(@options)
+ # @options.reporter = @reporter
+ # @example_group_class = Class.new(ExampleGroup) do
+ # plugin_mock_framework
+ # describe("Some Examples")
+ # end
+ # end
+ #
+ # def create_runner(example_definition)
+ # example = @example_group_class.new(example_definition)
+ # runner = ExampleGroup.new(@options, example)
+ # runner.stub!(:verify_mocks)
+ # runner.stub!(:teardown_mocks)
+ # runner
+ # end
+ # end
+ #
+ # describe ExampleRunner, "#run with blank passing example" do
+ # it_should_behave_like "Spec::Example::ExampleRunner#run"
+ #
+ # before do
+ # @e = @example_group_class.it("example") {}
+ # @runner = create_runner(@e)
+ # end
+ #
+ # it "should send reporter example_started" do
+ # @reporter.should_receive(:example_started).with(equal(@e))
+ # @runner.run
+ # end
+ #
+ # it "should report its name for dry run" do
+ # @options.dry_run = true
+ # @reporter.should_receive(:example_finished).with(equal(@e), nil)
+ # @runner.run
+ # end
+ #
+ # it "should report success" do
+ # @reporter.should_receive(:example_finished).with(equal(@e), nil)
+ # @runner.run
+ # end
+ # end
+ #
+ # describe ExampleRunner, "#run with a failing example" do
+ # predicate_matchers[:is_a] = [:is_a?]
+ # it_should_behave_like "Spec::Example::ExampleRunner#run"
+ #
+ # before do
+ # @e = @example_group_class.it("example") do
+ # (2+2).should == 5
+ # end
+ # @runner = create_runner(@e)
+ # end
+ #
+ # it "should report failure due to failure" do
+ # @reporter.should_receive(:example_finished).with(
+ # equal(@e),
+ # is_a(Spec::Expectations::ExpectationNotMetError)
+ # )
+ # @runner.run
+ # end
+ # end
+ #
+ # describe ExampleRunner, "#run with a erroring example" do
+ # it_should_behave_like "Spec::Example::ExampleRunner#run"
+ #
+ # before do
+ # @error = error = NonStandardError.new("in body")
+ # @example_definition = @example_group_class.it("example") do
+ # raise(error)
+ # end
+ # @runner = create_runner(@example_definition)
+ # end
+ #
+ # it "should report failure due to error" do
+ # @reporter.should_receive(:example_finished).with(
+ # equal(@example_definition),
+ # @error
+ # )
+ # @runner.run
+ # end
+ #
+ # it "should run after_each block" do
+ # @example_group_class.after(:each) do
+ # raise("in after_each")
+ # end
+ # @reporter.should_receive(:example_finished) do |example_definition, error|
+ # example_definition.should equal(@example_definition)
+ # error.message.should eql("in body")
+ # end
+ # @runner.run
+ # end
+ # end
+ #
+ # describe ExampleRunner, "#run where after_each fails" do
+ # it_should_behave_like "Spec::Example::ExampleRunner#run"
+ #
+ # before do
+ # @example_ran = example_ran = false
+ # @example_definition = @example_group_class.it("should not run") do
+ # example_ran = true
+ # end
+ # @runner = create_runner(@example_definition)
+ # @example_group_class.after(:each) { raise(NonStandardError.new("in after_each")) }
+ # end
+ #
+ # it "should report failure location when in after_each" do
+ # @reporter.should_receive(:example_finished) do |example_definition, error|
+ # example_definition.should equal(@example_definition)
+ # error.message.should eql("in after_each")
+ # end
+ # @runner.run
+ # end
+ # end
+ #
+ # describe ExampleRunner, "#run with use cases" do
+ # predicate_matchers[:is_a] = [:is_a?]
+ # it_should_behave_like "Spec::Example::ExampleRunner#run"
+ #
+ # it "should report NO NAME when told to use generated description with --dry-run" do
+ # @options.dry_run = true
+ # example_definition = @example_group_class.it() do
+ # 5.should == 5
+ # end
+ # runner = create_runner(example_definition)
+ #
+ # @reporter.should_receive(:example_finished) do |example_definition, error|
+ # example_definition.description.should == "NO NAME (Because of --dry-run)"
+ # end
+ # runner.run
+ # end
+ #
+ # it "should report given name if present with --dry-run" do
+ # @options.dry_run = true
+ # example_definition = @example_group_class.it("example name") do
+ # 5.should == 5
+ # end
+ # runner = create_runner(example_definition)
+ #
+ # @reporter.should_receive(:example_finished) do |example_definition, error|
+ # example_definition.description.should == "example name"
+ # end
+ # runner.run
+ # end
+ #
+ # it "should report NO NAME when told to use generated description with no expectations" do
+ # example_definition = @example_group_class.it() {}
+ # runner = create_runner(example_definition)
+ # @reporter.should_receive(:example_finished) do |example, error|
+ # example.description.should == "NO NAME (Because there were no expectations)"
+ # end
+ # runner.run
+ # end
+ #
+ # it "should report NO NAME when told to use generated description and matcher fails" do
+ # example_definition = @example_group_class.it() do
+ # 5.should "" # Has no matches? method..
+ # end
+ # runner = create_runner(example_definition)
+ #
+ # @reporter.should_receive(:example_finished) do |example, error|
+ # example_definition.description.should == "NO NAME (Because of Error raised in matcher)"
+ # end
+ # runner.run
+ # end
+ #
+ # it "should report generated description when told to and it is available" do
+ # example_definition = @example_group_class.it() {
+ # 5.should == 5
+ # }
+ # runner = create_runner(example_definition)
+ #
+ # @reporter.should_receive(:example_finished) do |example_definition, error|
+ # example_definition.description.should == "should == 5"
+ # end
+ # runner.run
+ # end
+ #
+ # it "should unregister description_generated callback (lest a memory leak should build up)" do
+ # example_definition = @example_group_class.it("something")
+ # runner = create_runner(example_definition)
+ #
+ # Spec::Matchers.should_receive(:example_finished)
+ # runner.run
+ # end
+ # end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/example/example_spec.rb b/vendor/gems/rspec/spec/spec/example/example_spec.rb
new file mode 100644
index 000000000..c8125b447
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/example_spec.rb
@@ -0,0 +1,53 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Example
+ # describe Example do
+ # before(:each) do
+ # @example = Example.new "example" do
+ # foo
+ # end
+ # end
+ #
+ # it "should tell you its docstring" do
+ # @example.description.should == "example"
+ # end
+ #
+ # it "should execute its block in the context provided" do
+ # context = Class.new do
+ # def foo
+ # "foo"
+ # end
+ # end.new
+ # @example.run_in(context).should == "foo"
+ # end
+ # end
+ #
+ # describe Example, "#description" do
+ # it "should default to NO NAME when not passed anything when there are no matchers" do
+ # example = Example.new {}
+ # example.run_in(Object.new)
+ # example.description.should == "NO NAME"
+ # end
+ #
+ # it "should default to NO NAME description (Because of --dry-run) when passed nil and there are no matchers" do
+ # example = Example.new(nil) {}
+ # example.run_in(Object.new)
+ # example.description.should == "NO NAME"
+ # end
+ #
+ # it "should allow description to be overridden" do
+ # example = Example.new("Test description")
+ # example.description.should == "Test description"
+ # end
+ #
+ # it "should use description generated from matcher when there is no passed in description" do
+ # example = Example.new(nil) do
+ # 1.should == 1
+ # end
+ # example.run_in(Object.new)
+ # example.description.should == "should == 1"
+ # end
+ # end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/example/nested_example_group_spec.rb b/vendor/gems/rspec/spec/spec/example/nested_example_group_spec.rb
new file mode 100644
index 000000000..35e8a9890
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/nested_example_group_spec.rb
@@ -0,0 +1,59 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Example
+ describe 'Nested Example Groups' do
+ parent = self
+
+ def count
+ @count ||= 0
+ @count = @count + 1
+ @count
+ end
+
+ before(:all) do
+ count.should == 1
+ end
+
+ before(:all) do
+ count.should == 2
+ end
+
+ before(:each) do
+ count.should == 3
+ end
+
+ before(:each) do
+ count.should == 4
+ end
+
+ it "should run before(:all), before(:each), example, after(:each), after(:all) in order" do
+ count.should == 5
+ end
+
+ after(:each) do
+ count.should == 7
+ end
+
+ after(:each) do
+ count.should == 6
+ end
+
+ after(:all) do
+ count.should == 9
+ end
+
+ after(:all) do
+ count.should == 8
+ end
+
+ describe 'nested example group' do
+ self.superclass.should == parent
+
+ it "should run all before and after callbacks" do
+ count.should == 5
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/example/pending_module_spec.rb b/vendor/gems/rspec/spec/spec/example/pending_module_spec.rb
new file mode 100644
index 000000000..c3ab0126b
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/pending_module_spec.rb
@@ -0,0 +1,31 @@
+module Spec
+ module Example
+ describe Pending do
+
+ it 'should raise an ExamplePendingError if no block is supplied' do
+ lambda {
+ include Pending
+ pending "TODO"
+ }.should raise_error(ExamplePendingError, /TODO/)
+ end
+
+ it 'should raise an ExamplePendingError if a supplied block fails as expected' do
+ lambda {
+ include Pending
+ pending "TODO" do
+ raise "oops"
+ end
+ }.should raise_error(ExamplePendingError, /TODO/)
+ end
+
+ it 'should raise a PendingExampleFixedError if a supplied block starts working' do
+ lambda {
+ include Pending
+ pending "TODO" do
+ # success!
+ end
+ }.should raise_error(PendingExampleFixedError, /TODO/)
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/example/predicate_matcher_spec.rb b/vendor/gems/rspec/spec/spec/example/predicate_matcher_spec.rb
new file mode 100755
index 000000000..7c4638b4b
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/predicate_matcher_spec.rb
@@ -0,0 +1,21 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Example
+ class Fish
+ def can_swim?(distance_in_yards)
+ distance_in_yards < 1000
+ end
+ end
+
+ describe "predicate_matcher[method_on_object] = matcher_method" do
+ predicate_matchers[:swim] = :can_swim?
+ it "should match matcher_method if method_on_object returns true" do
+ swim(100).matches?(Fish.new).should be_true
+ end
+ it "should not match matcher_method if method_on_object returns false" do
+ swim(10000).matches?(Fish.new).should be_false
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/example/shared_example_group_spec.rb b/vendor/gems/rspec/spec/spec/example/shared_example_group_spec.rb
new file mode 100644
index 000000000..803536ab5
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/shared_example_group_spec.rb
@@ -0,0 +1,265 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Example
+ describe ExampleGroup, "with :shared => true" do
+ it_should_behave_like "sandboxed rspec_options"
+ attr_reader :formatter, :example_group
+ before(:each) do
+ @formatter = Spec::Mocks::Mock.new("formatter", :null_object => true)
+ options.formatters << formatter
+ @example_group = Class.new(ExampleGroup).describe("example_group")
+ class << example_group
+ public :include
+ end
+ end
+
+ after(:each) do
+ @formatter.rspec_verify
+ @example_group = nil
+ $shared_example_groups.clear unless $shared_example_groups.nil?
+ end
+
+ def make_shared_example_group(name, opts=nil, &block)
+ example_group = SharedExampleGroup.new(name, :shared => true, &block)
+ SharedExampleGroup.add_shared_example_group(example_group)
+ example_group
+ end
+
+ def non_shared_example_group()
+ @non_shared_example_group ||= Class.new(ExampleGroup).describe("example_group")
+ end
+
+ it "should accept an optional options hash" do
+ lambda { Class.new(ExampleGroup).describe("context") }.should_not raise_error(Exception)
+ lambda { Class.new(ExampleGroup).describe("context", :shared => true) }.should_not raise_error(Exception)
+ end
+
+ it "should return all shared example_groups" do
+ b1 = make_shared_example_group("b1", :shared => true) {}
+ b2 = make_shared_example_group("b2", :shared => true) {}
+
+ b1.should_not be(nil)
+ b2.should_not be(nil)
+
+ SharedExampleGroup.find_shared_example_group("b1").should equal(b1)
+ SharedExampleGroup.find_shared_example_group("b2").should equal(b2)
+ end
+
+ it "should register as shared example_group" do
+ example_group = make_shared_example_group("example_group") {}
+ SharedExampleGroup.shared_example_groups.should include(example_group)
+ end
+
+ it "should not be shared when not configured as shared" do
+ example_group = non_shared_example_group
+ SharedExampleGroup.shared_example_groups.should_not include(example_group)
+ end
+
+ it "should complain when adding a second shared example_group with the same description" do
+ describe "shared example_group", :shared => true do
+ end
+ lambda do
+ describe "shared example_group", :shared => true do
+ end
+ end.should raise_error(ArgumentError)
+ end
+
+ it "should NOT complain when adding the same shared example_group instance again" do
+ shared_example_group = Class.new(ExampleGroup).describe("shared example_group", :shared => true)
+ SharedExampleGroup.add_shared_example_group(shared_example_group)
+ SharedExampleGroup.add_shared_example_group(shared_example_group)
+ end
+
+ it "should NOT complain when adding the same shared example_group again (i.e. file gets reloaded)" do
+ lambda do
+ 2.times do
+ describe "shared example_group which gets loaded twice", :shared => true do
+ end
+ end
+ end.should_not raise_error(ArgumentError)
+ end
+
+ it "should NOT complain when adding the same shared example_group in same file with different absolute path" do
+ shared_example_group_1 = Class.new(ExampleGroup).describe(
+ "shared example_group",
+ :shared => true,
+ :spec_path => "/my/spec/a/../shared.rb"
+ )
+ shared_example_group_2 = Class.new(ExampleGroup).describe(
+ "shared example_group",
+ :shared => true,
+ :spec_path => "/my/spec/b/../shared.rb"
+ )
+
+ SharedExampleGroup.add_shared_example_group(shared_example_group_1)
+ SharedExampleGroup.add_shared_example_group(shared_example_group_2)
+ end
+
+ it "should complain when adding a different shared example_group with the same name in a different file with the same basename" do
+ shared_example_group_1 = Class.new(ExampleGroup).describe(
+ "shared example_group",
+ :shared => true,
+ :spec_path => "/my/spec/a/shared.rb"
+ )
+ shared_example_group_2 = Class.new(ExampleGroup).describe(
+ "shared example_group",
+ :shared => true,
+ :spec_path => "/my/spec/b/shared.rb"
+ )
+
+ SharedExampleGroup.add_shared_example_group(shared_example_group_1)
+ lambda do
+ SharedExampleGroup.add_shared_example_group(shared_example_group_2)
+ end.should raise_error(ArgumentError, /already exists/)
+ end
+
+ it "should add examples to current example_group using it_should_behave_like" do
+ shared_example_group = make_shared_example_group("shared example_group") do
+ it("shared example") {}
+ it("shared example 2") {}
+ end
+
+ example_group.it("example") {}
+ example_group.number_of_examples.should == 1
+ example_group.it_should_behave_like("shared example_group")
+ example_group.number_of_examples.should == 3
+ end
+
+ it "should add examples to current example_group using include" do
+ shared_example_group = describe "all things", :shared => true do
+ it "should do stuff" do end
+ end
+
+ example_group = describe "one thing" do
+ include shared_example_group
+ end
+
+ example_group.number_of_examples.should == 1
+ end
+
+ it "should add examples to current example_group using it_should_behave_like with a module" do
+ AllThings = describe "all things", :shared => true do
+ it "should do stuff" do end
+ end
+
+ example_group = describe "one thing" do
+ it_should_behave_like AllThings
+ end
+
+ example_group.number_of_examples.should == 1
+ end
+
+ it "should run shared examples" do
+ shared_example_ran = false
+ shared_example_group = make_shared_example_group("shared example_group") do
+ it("shared example") { shared_example_ran = true }
+ end
+
+ example_ran = false
+
+ example_group.it_should_behave_like("shared example_group")
+ example_group.it("example") {example_ran = true}
+ example_group.run
+ example_ran.should be_true
+ shared_example_ran.should be_true
+ end
+
+ it "should run setup and teardown from shared example_group" do
+ shared_setup_ran = false
+ shared_teardown_ran = false
+ shared_example_group = make_shared_example_group("shared example_group") do
+ before { shared_setup_ran = true }
+ after { shared_teardown_ran = true }
+ it("shared example") { shared_example_ran = true }
+ end
+
+ example_ran = false
+
+ example_group.it_should_behave_like("shared example_group")
+ example_group.it("example") {example_ran = true}
+ example_group.run
+ example_ran.should be_true
+ shared_setup_ran.should be_true
+ shared_teardown_ran.should be_true
+ end
+
+ it "should run before(:all) and after(:all) only once from shared example_group" do
+ shared_before_all_run_count = 0
+ shared_after_all_run_count = 0
+ shared_example_group = make_shared_example_group("shared example_group") do
+ before(:all) { shared_before_all_run_count += 1}
+ after(:all) { shared_after_all_run_count += 1}
+ it("shared example") { shared_example_ran = true }
+ end
+
+ example_ran = false
+
+ example_group.it_should_behave_like("shared example_group")
+ example_group.it("example") {example_ran = true}
+ example_group.run
+ example_ran.should be_true
+ shared_before_all_run_count.should == 1
+ shared_after_all_run_count.should == 1
+ end
+
+ it "should include modules, included into shared example_group, into current example_group" do
+ @formatter.should_receive(:add_example_group).with(any_args)
+
+ shared_example_group = make_shared_example_group("shared example_group") do
+ it("shared example") { shared_example_ran = true }
+ end
+
+ mod1_method_called = false
+ mod1 = Module.new do
+ define_method :mod1_method do
+ mod1_method_called = true
+ end
+ end
+
+ mod2_method_called = false
+ mod2 = Module.new do
+ define_method :mod2_method do
+ mod2_method_called = true
+ end
+ end
+
+ shared_example_group.include mod2
+
+ example_group.it_should_behave_like("shared example_group")
+ example_group.include mod1
+
+ example_group.it("test") do
+ mod1_method
+ mod2_method
+ end
+ example_group.run
+ mod1_method_called.should be_true
+ mod2_method_called.should be_true
+ end
+
+ it "should make methods defined in the shared example_group available in consuming example_group" do
+ shared_example_group = make_shared_example_group("shared example_group xyz") do
+ def a_shared_helper_method
+ "this got defined in a shared example_group"
+ end
+ end
+ example_group.it_should_behave_like("shared example_group xyz")
+ success = false
+ example_group.it("should access a_shared_helper_method") do
+ a_shared_helper_method
+ success = true
+ end
+ example_group.run
+ success.should be_true
+ end
+
+ it "should raise when named shared example_group can not be found" do
+ lambda {
+ example_group.it_should_behave_like("non-existent shared example group")
+ violated
+ }.should raise_error("Shared Example Group 'non-existent shared example group' can not be found")
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/example/subclassing_example_group_spec.rb b/vendor/gems/rspec/spec/spec/example/subclassing_example_group_spec.rb
new file mode 100644
index 000000000..888f2ceb3
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/example/subclassing_example_group_spec.rb
@@ -0,0 +1,25 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Example
+ class GrandParentExampleGroup < Spec::Example::ExampleGroup
+ describe "Grandparent ExampleGroup"
+ end
+
+ class ParentExampleGroup < GrandParentExampleGroup
+ describe "Parent ExampleGroup"
+ it "should bar" do
+ end
+ end
+
+ class ChildExampleGroup < ParentExampleGroup
+ describe "Child ExampleGroup"
+ it "should bam" do
+ end
+ end
+
+ describe ChildExampleGroup do
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/expectations/differs/default_spec.rb b/vendor/gems/rspec/spec/spec/expectations/differs/default_spec.rb
new file mode 100644
index 000000000..ea720846b
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/expectations/differs/default_spec.rb
@@ -0,0 +1,109 @@
+require File.dirname(__FILE__) + '/../../../spec_helper.rb'
+
+module Spec
+ module Fixtures
+ class Animal
+ def initialize(name,species)
+ @name,@species = name,species
+ end
+
+ def inspect
+ <<-EOA
+<Animal
+ name=#{@name},
+ species=#{@species}
+>
+ EOA
+ end
+ end
+ end
+end
+
+describe "Diff" do
+ before(:each) do
+ @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new)
+ @differ = Spec::Expectations::Differs::Default.new(@options)
+ end
+
+ it "should output unified diff of two strings" do
+ expected="foo\nbar\nzap\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nline\n"
+ actual="foo\nzap\nbar\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nanother\nline\n"
+ expected_diff="\n\n@@ -1,6 +1,6 @@\n foo\n-bar\n zap\n+bar\n this\n is\n soo\n@@ -9,5 +9,6 @@\n equal\n insert\n a\n+another\n line\n"
+ diff = @differ.diff_as_string(expected, actual)
+ diff.should eql(expected_diff)
+ end
+
+ it "should output unified diff message of two arrays" do
+ expected = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'charlie', :width, 'quite wide' ]
+ actual = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'tango' , :width, 'very wide' ]
+
+ expected_diff = <<'EOD'
+
+
+@@ -5,7 +5,7 @@
+ :metasyntactic,
+ "variable",
+ :delta,
+- "charlie",
++ "tango",
+ :width,
+- "quite wide"]
++ "very wide"]
+EOD
+
+
+ diff = @differ.diff_as_object(expected,actual)
+ diff.should == expected_diff
+ end
+
+ it "should output unified diff message of two objects" do
+ expected = Spec::Fixtures::Animal.new "bob", "giraffe"
+ actual = Spec::Fixtures::Animal.new "bob", "tortoise"
+
+ expected_diff = <<'EOD'
+
+@@ -1,5 +1,5 @@
+ <Animal
+ name=bob,
+- species=giraffe
++ species=tortoise
+ >
+EOD
+
+ diff = @differ.diff_as_object(expected,actual)
+ diff.should == expected_diff
+ end
+
+end
+
+
+describe "Diff in context format" do
+ before(:each) do
+ @options = Spec::Runner::Options.new(StringIO.new, StringIO.new)
+ @options.diff_format = :context
+ @differ = Spec::Expectations::Differs::Default.new(@options)
+ end
+
+ it "should output unified diff message of two objects" do
+ expected = Spec::Fixtures::Animal.new "bob", "giraffe"
+ actual = Spec::Fixtures::Animal.new "bob", "tortoise"
+
+ expected_diff = <<'EOD'
+
+***************
+*** 1,5 ****
+ <Animal
+ name=bob,
+! species=giraffe
+ >
+--- 1,5 ----
+ <Animal
+ name=bob,
+! species=tortoise
+ >
+EOD
+
+ diff = @differ.diff_as_object(expected,actual)
+ diff.should == expected_diff
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/expectations/extensions/object_spec.rb b/vendor/gems/rspec/spec/spec/expectations/extensions/object_spec.rb
new file mode 100644
index 000000000..0d9335bdb
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/expectations/extensions/object_spec.rb
@@ -0,0 +1,107 @@
+require File.dirname(__FILE__) + '/../../../spec_helper.rb'
+
+describe Object, "#should" do
+ before(:each) do
+ @target = "target"
+ @matcher = mock("matcher")
+ @matcher.stub!(:matches?).and_return(true)
+ @matcher.stub!(:failure_message)
+ end
+
+ it "should accept and interact with a matcher" do
+ @matcher.should_receive(:matches?).with(@target).and_return(true)
+ @target.should @matcher
+ end
+
+ it "should ask for a failure_message when matches? returns false" do
+ @matcher.should_receive(:matches?).with(@target).and_return(false)
+ @matcher.should_receive(:failure_message).and_return("the failure message")
+ lambda {
+ @target.should @matcher
+ }.should fail_with("the failure message")
+ end
+
+ it "should raise error if it receives false directly" do
+ lambda {
+ @target.should false
+ }.should raise_error(Spec::Expectations::InvalidMatcherError)
+ end
+
+ it "should raise error if it receives false (evaluated)" do
+ lambda {
+ @target.should eql?("foo")
+ }.should raise_error(Spec::Expectations::InvalidMatcherError)
+ end
+
+ it "should raise error if it receives true" do
+ lambda {
+ @target.should true
+ }.should raise_error(Spec::Expectations::InvalidMatcherError)
+ end
+
+ it "should raise error if it receives nil" do
+ lambda {
+ @target.should nil
+ }.should raise_error(Spec::Expectations::InvalidMatcherError)
+ end
+
+ it "should raise error if it receives no argument and it is not used as a left side of an operator" do
+ pending "Is it even possible to catch this?"
+ lambda {
+ @target.should
+ }.should raise_error(Spec::Expectations::InvalidMatcherError)
+ end
+end
+
+describe Object, "#should_not" do
+ before(:each) do
+ @target = "target"
+ @matcher = mock("matcher")
+ end
+
+ it "should accept and interact with a matcher" do
+ @matcher.should_receive(:matches?).with(@target).and_return(false)
+ @matcher.stub!(:negative_failure_message)
+
+ @target.should_not @matcher
+ end
+
+ it "should ask for a negative_failure_message when matches? returns true" do
+ @matcher.should_receive(:matches?).with(@target).and_return(true)
+ @matcher.should_receive(:negative_failure_message).and_return("the negative failure message")
+ lambda {
+ @target.should_not @matcher
+ }.should fail_with("the negative failure message")
+ end
+
+ it "should raise error if it receives false directly" do
+ lambda {
+ @target.should_not false
+ }.should raise_error(Spec::Expectations::InvalidMatcherError)
+ end
+
+ it "should raise error if it receives false (evaluated)" do
+ lambda {
+ @target.should_not eql?("foo")
+ }.should raise_error(Spec::Expectations::InvalidMatcherError)
+ end
+
+ it "should raise error if it receives true" do
+ lambda {
+ @target.should_not true
+ }.should raise_error(Spec::Expectations::InvalidMatcherError)
+ end
+
+ it "should raise error if it receives nil" do
+ lambda {
+ @target.should_not nil
+ }.should raise_error(Spec::Expectations::InvalidMatcherError)
+ end
+
+ it "should raise error if it receives no argument and it is not used as a left side of an operator" do
+ pending "Is it even possible to catch this?"
+ lambda {
+ @target.should_not
+ }.should raise_error(Spec::Expectations::InvalidMatcherError)
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/expectations/fail_with_spec.rb b/vendor/gems/rspec/spec/spec/expectations/fail_with_spec.rb
new file mode 100644
index 000000000..4c369ce3a
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/expectations/fail_with_spec.rb
@@ -0,0 +1,71 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe Spec::Expectations, "#fail_with with no diff" do
+ before(:each) do
+ @old_differ = Spec::Expectations.differ
+ Spec::Expectations.differ = nil
+ end
+
+ it "should handle just a message" do
+ lambda {
+ Spec::Expectations.fail_with "the message"
+ }.should fail_with("the message")
+ end
+
+ it "should handle an Array" do
+ lambda {
+ Spec::Expectations.fail_with ["the message","expected","actual"]
+ }.should fail_with("the message")
+ end
+
+ after(:each) do
+ Spec::Expectations.differ = @old_differ
+ end
+end
+
+describe Spec::Expectations, "#fail_with with diff" do
+ before(:each) do
+ @old_differ = Spec::Expectations.differ
+ @differ = mock("differ")
+ Spec::Expectations.differ = @differ
+ end
+
+ it "should not call differ if no expected/actual" do
+ lambda {
+ Spec::Expectations.fail_with "the message"
+ }.should fail_with("the message")
+ end
+
+ it "should call differ if expected/actual are presented separately" do
+ @differ.should_receive(:diff_as_string).and_return("diff")
+ lambda {
+ Spec::Expectations.fail_with "the message", "expected", "actual"
+ }.should fail_with("the message\nDiff:diff")
+ end
+
+ it "should call differ if expected/actual are not strings" do
+ @differ.should_receive(:diff_as_object).and_return("diff")
+ lambda {
+ Spec::Expectations.fail_with "the message", :expected, :actual
+ }.should fail_with("the message\nDiff:diff")
+ end
+
+ it "should not call differ if expected or actual are procs" do
+ @differ.should_not_receive(:diff_as_string)
+ @differ.should_not_receive(:diff_as_object)
+ lambda {
+ Spec::Expectations.fail_with "the message", lambda {}, lambda {}
+ }.should fail_with("the message")
+ end
+
+ it "should call differ if expected/actual are presented in an Array with message" do
+ @differ.should_receive(:diff_as_string).with("actual","expected").and_return("diff")
+ lambda {
+ Spec::Expectations.fail_with(["the message", "expected", "actual"])
+ }.should fail_with(/the message\nDiff:diff/)
+ end
+
+ after(:each) do
+ Spec::Expectations.differ = @old_differ
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/extensions/main_spec.rb b/vendor/gems/rspec/spec/spec/extensions/main_spec.rb
new file mode 100644
index 000000000..aabb616e9
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/extensions/main_spec.rb
@@ -0,0 +1,76 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Extensions
+ describe Main do
+ it_should_behave_like "sandboxed rspec_options"
+ before(:each) do
+ @main = Class.new do; include Main; end
+ end
+
+ after(:each) do
+ $rspec_story_steps = @original_rspec_story_steps
+ end
+
+ it "should create an Options object" do
+ @main.send(:rspec_options).should be_instance_of(Spec::Runner::Options)
+ @main.send(:rspec_options).should === $rspec_options
+ end
+
+ specify {@main.should respond_to(:describe)}
+ specify {@main.should respond_to(:context)}
+
+ it "should raise when no block given to describe" do
+ lambda { @main.describe "foo" }.should raise_error(ArgumentError)
+ end
+
+ it "should raise when no description given to describe" do
+ lambda { @main.describe do; end }.should raise_error(ArgumentError)
+ end
+
+ it "should registered ExampleGroups by default" do
+ example_group = @main.describe("The ExampleGroup") do end
+ rspec_options.example_groups.should include(example_group)
+ end
+
+ it "should not run unregistered ExampleGroups" do
+ example_group = @main.describe("The ExampleGroup") do
+ unregister
+ end
+
+ rspec_options.example_groups.should_not include(example_group)
+ end
+
+ it "should create a shared ExampleGroup with share_examples_for" do
+ group = @main.share_examples_for "all things" do end
+ group.should be_an_instance_of(Spec::Example::SharedExampleGroup)
+ end
+
+ describe "#share_as" do
+ before(:each) do
+ $share_as_examples_example_module_number ||= 1
+ $share_as_examples_example_module_number += 1
+ t = Time.new.to_i
+ @group_name = "Group#{$share_as_examples_example_module_number}"
+ end
+
+ it "should create a shared ExampleGroup" do
+ group = @main.share_as @group_name do end
+ group.should be_an_instance_of(Spec::Example::SharedExampleGroup)
+ end
+
+ it "should create a constant that points to a Module" do
+ group = @main.share_as @group_name do end
+ Object.const_get(@group_name).should equal(group)
+ end
+
+ it "should bark if you pass it something not-constantizable" do
+ lambda do
+ @group = @main.share_as "Non Constant" do end
+ end.should raise_error(NameError, /The first argument to share_as must be a legal name for a constant/)
+ end
+
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/interop/test/unit/resources/spec_that_fails.rb b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/spec_that_fails.rb
new file mode 100644
index 000000000..d6f5564bf
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/spec_that_fails.rb
@@ -0,0 +1,10 @@
+rspec_lib = File.dirname(__FILE__) + "/../../../../../../lib"
+$:.unshift rspec_lib unless $:.include?(rspec_lib)
+require 'test/unit'
+require 'spec'
+
+describe "example group with failures" do
+ it "should fail" do
+ false.should be_true
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/interop/test/unit/resources/spec_that_passes.rb b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/spec_that_passes.rb
new file mode 100644
index 000000000..ccd2488bc
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/spec_that_passes.rb
@@ -0,0 +1,10 @@
+rspec_lib = File.dirname(__FILE__) + "/../../../../../../lib"
+$:.unshift rspec_lib unless $:.include?(rspec_lib)
+require 'test/unit'
+require 'spec'
+
+describe "example group with passing examples" do
+ it "should pass" do
+ true.should be_true
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/interop/test/unit/resources/spec_with_errors.rb b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/spec_with_errors.rb
new file mode 100644
index 000000000..71427dbaa
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/spec_with_errors.rb
@@ -0,0 +1,10 @@
+rspec_lib = File.dirname(__FILE__) + "/../../../../../../lib"
+$:.unshift rspec_lib unless $:.include?(rspec_lib)
+require 'test/unit'
+require 'spec'
+
+describe "example group with errors" do
+ it "should raise errors" do
+ raise "error raised in example group with errors"
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/interop/test/unit/resources/test_case_that_fails.rb b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/test_case_that_fails.rb
new file mode 100644
index 000000000..3fb6515a8
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/test_case_that_fails.rb
@@ -0,0 +1,10 @@
+rspec_lib = File.dirname(__FILE__) + "/../../../../../../lib"
+$:.unshift rspec_lib unless $:.include?(rspec_lib)
+require 'test/unit'
+require 'spec'
+
+class TestCaseThatFails < Test::Unit::TestCase
+ def test_that_fails
+ false.should be_true
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/interop/test/unit/resources/test_case_that_passes.rb b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/test_case_that_passes.rb
new file mode 100644
index 000000000..69239c0b5
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/test_case_that_passes.rb
@@ -0,0 +1,10 @@
+rspec_lib = File.dirname(__FILE__) + "/../../../../../../lib"
+$:.unshift rspec_lib unless $:.include?(rspec_lib)
+require 'test/unit'
+require 'spec'
+
+class TestCaseThatPasses < Test::Unit::TestCase
+ def test_that_passes
+ true.should be_true
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/interop/test/unit/resources/test_case_with_errors.rb b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/test_case_with_errors.rb
new file mode 100644
index 000000000..35dcb6b2e
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/test_case_with_errors.rb
@@ -0,0 +1,10 @@
+rspec_lib = File.dirname(__FILE__) + "/../../../../../../lib"
+$:.unshift rspec_lib unless $:.include?(rspec_lib)
+require 'test/unit'
+require 'spec'
+
+class TestCaseWithErrors < Test::Unit::TestCase
+ def test_with_error
+ raise "error raised in TestCaseWithErrors"
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/interop/test/unit/resources/testsuite_adapter_spec_with_test_unit.rb b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/testsuite_adapter_spec_with_test_unit.rb
new file mode 100644
index 000000000..0c2167a99
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/interop/test/unit/resources/testsuite_adapter_spec_with_test_unit.rb
@@ -0,0 +1,38 @@
+rspec_lib = File.dirname(__FILE__) + "/../../../../../../lib"
+$:.unshift rspec_lib unless $:.include?(rspec_lib)
+require "test/unit"
+require "spec"
+
+module Test
+ module Unit
+ describe TestSuiteAdapter do
+ def create_adapter(group)
+ TestSuiteAdapter.new(group)
+ end
+
+ describe "#size" do
+ it "should return the number of examples in the example group" do
+ group = Class.new(Spec::ExampleGroup) do
+ describe("some examples")
+ it("bar") {}
+ it("baz") {}
+ end
+ adapter = create_adapter(group)
+ adapter.size.should == 2
+ end
+ end
+
+ describe "#delete" do
+ it "should do nothing" do
+ group = Class.new(Spec::ExampleGroup) do
+ describe("Some Examples")
+ it("does something") {}
+ end
+ adapter = create_adapter(group)
+ adapter.delete(adapter.examples.first)
+ adapter.should be_empty
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/interop/test/unit/spec_spec.rb b/vendor/gems/rspec/spec/spec/interop/test/unit/spec_spec.rb
new file mode 100644
index 000000000..8a1e1300c
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/interop/test/unit/spec_spec.rb
@@ -0,0 +1,45 @@
+require File.dirname(__FILE__) + '/test_unit_spec_helper'
+
+describe "ExampleGroup with test/unit/interop" do
+ include TestUnitSpecHelper
+
+ before(:each) do
+ @dir = File.dirname(__FILE__) + "/resources"
+ end
+
+ describe "with passing examples" do
+ it "should output 0 failures" do
+ output = ruby("#{@dir}/spec_that_passes.rb")
+ output.should include("1 example, 0 failures")
+ end
+
+ it "should return an exit code of 0" do
+ ruby("#{@dir}/spec_that_passes.rb")
+ $?.should == 0
+ end
+ end
+
+ describe "with failing examples" do
+ it "should output 1 failure" do
+ output = ruby("#{@dir}/spec_that_fails.rb")
+ output.should include("1 example, 1 failure")
+ end
+
+ it "should return an exit code of 256" do
+ ruby("#{@dir}/spec_that_fails.rb")
+ $?.should == 256
+ end
+ end
+
+ describe "with example that raises an error" do
+ it "should output 1 failure" do
+ output = ruby("#{@dir}/spec_with_errors.rb")
+ output.should include("1 example, 1 failure")
+ end
+
+ it "should return an exit code of 256" do
+ ruby("#{@dir}/spec_with_errors.rb")
+ $?.should == 256
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/interop/test/unit/test_unit_spec_helper.rb b/vendor/gems/rspec/spec/spec/interop/test/unit/test_unit_spec_helper.rb
new file mode 100644
index 000000000..04d5d2713
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/interop/test/unit/test_unit_spec_helper.rb
@@ -0,0 +1,14 @@
+require File.dirname(__FILE__) + '/../../../../spec_helper'
+require File.dirname(__FILE__) + '/../../../../ruby_forker'
+
+module TestUnitSpecHelper
+ include RubyForker
+
+ def run_script(file_name)
+ output = ruby(file_name)
+ if !$?.success? || output.include?("FAILED") || output.include?("Error")
+ raise output
+ end
+ output
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/interop/test/unit/testcase_spec.rb b/vendor/gems/rspec/spec/spec/interop/test/unit/testcase_spec.rb
new file mode 100644
index 000000000..f40111a58
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/interop/test/unit/testcase_spec.rb
@@ -0,0 +1,45 @@
+require File.dirname(__FILE__) + '/test_unit_spec_helper'
+
+describe "Test::Unit::TestCase" do
+ include TestUnitSpecHelper
+
+ before(:each) do
+ @dir = File.dirname(__FILE__) + "/resources"
+ end
+
+ describe "with passing test case" do
+ it "should output 0 failures" do
+ output = ruby("#{@dir}/test_case_that_passes.rb")
+ output.should include("1 example, 0 failures")
+ end
+
+ it "should return an exit code of 0" do
+ ruby("#{@dir}/test_case_that_passes.rb")
+ $?.should == 0
+ end
+ end
+
+ describe "with failing test case" do
+ it "should output 1 failure" do
+ output = ruby("#{@dir}/test_case_that_fails.rb")
+ output.should include("1 example, 1 failure")
+ end
+
+ it "should return an exit code of 256" do
+ ruby("#{@dir}/test_case_that_fails.rb")
+ $?.should == 256
+ end
+ end
+
+ describe "with test case that raises an error" do
+ it "should output 1 failure" do
+ output = ruby("#{@dir}/test_case_with_errors.rb")
+ output.should include("1 example, 1 failure")
+ end
+
+ it "should return an exit code of 256" do
+ ruby("#{@dir}/test_case_with_errors.rb")
+ $?.should == 256
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/interop/test/unit/testsuite_adapter_spec.rb b/vendor/gems/rspec/spec/spec/interop/test/unit/testsuite_adapter_spec.rb
new file mode 100644
index 000000000..722126bc9
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/interop/test/unit/testsuite_adapter_spec.rb
@@ -0,0 +1,9 @@
+require File.dirname(__FILE__) + '/test_unit_spec_helper'
+
+describe "TestSuiteAdapter" do
+ include TestUnitSpecHelper
+ it "should pass" do
+ dir = File.dirname(__FILE__)
+ run_script "#{dir}/resources/testsuite_adapter_spec_with_test_unit.rb"
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/matchers/be_close_spec.rb b/vendor/gems/rspec/spec/spec/matchers/be_close_spec.rb
new file mode 100644
index 000000000..d8452d408
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/be_close_spec.rb
@@ -0,0 +1,39 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+module Spec
+ module Matchers
+ describe BeClose do
+ it "should match when value == target" do
+ BeClose.new(5.0, 0.5).matches?(5.0).should be_true
+ end
+ it "should match when value < (target + delta)" do
+ BeClose.new(5.0, 0.5).matches?(5.49).should be_true
+ end
+ it "should match when value > (target - delta)" do
+ BeClose.new(5.0, 0.5).matches?(4.51).should be_true
+ end
+ it "should not match when value == (target - delta)" do
+ BeClose.new(5.0, 0.5).matches?(4.5).should be_false
+ end
+ it "should not match when value < (target - delta)" do
+ BeClose.new(5.0, 0.5).matches?(4.49).should be_false
+ end
+ it "should not match when value == (target + delta)" do
+ BeClose.new(5.0, 0.5).matches?(5.5).should be_false
+ end
+ it "should not match when value > (target + delta)" do
+ BeClose.new(5.0, 0.5).matches?(5.51).should be_false
+ end
+ it "should provide a useful failure message" do
+ #given
+ matcher = BeClose.new(5.0, 0.5)
+ #when
+ matcher.matches?(5.51)
+ #then
+ matcher.failure_message.should == "expected 5.0 +/- (< 0.5), got 5.51"
+ end
+ it "should describe itself" do
+ BeClose.new(5.0, 0.5).description.should == "be close to 5.0 (within +- 0.5)"
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/be_spec.rb b/vendor/gems/rspec/spec/spec/matchers/be_spec.rb
new file mode 100644
index 000000000..d40036c79
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/be_spec.rb
@@ -0,0 +1,224 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "should be_predicate" do
+ it "should pass when actual returns true for :predicate?" do
+ actual = stub("actual", :happy? => true)
+ actual.should be_happy
+ end
+
+ it "should pass when actual returns true for :predicates? (present tense)" do
+ actual = stub("actual", :exists? => true)
+ actual.should be_exist
+ end
+
+ it "should fail when actual returns false for :predicate?" do
+ actual = stub("actual", :happy? => false)
+ lambda {
+ actual.should be_happy
+ }.should fail_with("expected happy? to return true, got false")
+ end
+
+ it "should fail when actual does not respond to :predicate?" do
+ lambda {
+ Object.new.should be_happy
+ }.should raise_error(NameError)
+ end
+end
+
+describe "should_not be_predicate" do
+ it "should pass when actual returns false for :sym?" do
+ actual = stub("actual", :happy? => false)
+ actual.should_not be_happy
+ end
+
+ it "should fail when actual returns true for :sym?" do
+ actual = stub("actual", :happy? => true)
+ lambda {
+ actual.should_not be_happy
+ }.should fail_with("expected happy? to return false, got true")
+ end
+
+ it "should fail when actual does not respond to :sym?" do
+ lambda {
+ Object.new.should_not be_happy
+ }.should raise_error(NameError)
+ end
+end
+
+describe "should be_predicate(*args)" do
+ it "should pass when actual returns true for :predicate?(*args)" do
+ actual = mock("actual")
+ actual.should_receive(:older_than?).with(3).and_return(true)
+ actual.should be_older_than(3)
+ end
+
+ it "should fail when actual returns false for :predicate?(*args)" do
+ actual = mock("actual")
+ actual.should_receive(:older_than?).with(3).and_return(false)
+ lambda {
+ actual.should be_older_than(3)
+ }.should fail_with("expected older_than?(3) to return true, got false")
+ end
+
+ it "should fail when actual does not respond to :predicate?" do
+ lambda {
+ Object.new.should be_older_than(3)
+ }.should raise_error(NameError)
+ end
+end
+
+describe "should_not be_predicate(*args)" do
+ it "should pass when actual returns false for :predicate?(*args)" do
+ actual = mock("actual")
+ actual.should_receive(:older_than?).with(3).and_return(false)
+ actual.should_not be_older_than(3)
+ end
+
+ it "should fail when actual returns true for :predicate?(*args)" do
+ actual = mock("actual")
+ actual.should_receive(:older_than?).with(3).and_return(true)
+ lambda {
+ actual.should_not be_older_than(3)
+ }.should fail_with("expected older_than?(3) to return false, got true")
+ end
+
+ it "should fail when actual does not respond to :predicate?" do
+ lambda {
+ Object.new.should_not be_older_than(3)
+ }.should raise_error(NameError)
+ end
+end
+
+describe "should be_true" do
+ it "should pass when actual equal(true)" do
+ true.should be_true
+ end
+
+ it "should fail when actual equal(false)" do
+ lambda {
+ false.should be_true
+ }.should fail_with("expected true, got false")
+ end
+end
+
+describe "should be_false" do
+ it "should pass when actual equal(false)" do
+ false.should be_false
+ end
+
+ it "should fail when actual equal(true)" do
+ lambda {
+ true.should be_false
+ }.should fail_with("expected false, got true")
+ end
+end
+
+describe "should be_nil" do
+ it "should pass when actual is nil" do
+ nil.should be_nil
+ end
+
+ it "should fail when actual is not nil" do
+ lambda {
+ :not_nil.should be_nil
+ }.should fail_with("expected nil, got :not_nil")
+ end
+end
+
+describe "should_not be_nil" do
+ it "should pass when actual is not nil" do
+ :not_nil.should_not be_nil
+ end
+
+ it "should fail when actual is nil" do
+ lambda {
+ nil.should_not be_nil
+ }.should fail_with("expected not nil, got nil")
+ end
+end
+
+describe "should be <" do
+ it "should pass when < operator returns true" do
+ 3.should be < 4
+ end
+
+ it "should fail when < operator returns false" do
+ lambda { 3.should be < 3 }.should fail_with("expected < 3, got 3")
+ end
+end
+
+describe "should be <=" do
+ it "should pass when <= operator returns true" do
+ 3.should be <= 4
+ 4.should be <= 4
+ end
+
+ it "should fail when <= operator returns false" do
+ lambda { 3.should be <= 2 }.should fail_with("expected <= 2, got 3")
+ end
+end
+
+describe "should be >=" do
+ it "should pass when >= operator returns true" do
+ 4.should be >= 4
+ 5.should be >= 4
+ end
+
+ it "should fail when >= operator returns false" do
+ lambda { 3.should be >= 4 }.should fail_with("expected >= 4, got 3")
+ end
+end
+
+describe "should be >" do
+ it "should pass when > operator returns true" do
+ 5.should be > 4
+ end
+
+ it "should fail when > operator returns false" do
+ lambda { 3.should be > 4 }.should fail_with("expected > 4, got 3")
+ end
+end
+
+describe "should be ==" do
+ it "should pass when == operator returns true" do
+ 5.should be == 5
+ end
+
+ it "should fail when == operator returns false" do
+ lambda { 3.should be == 4 }.should fail_with("expected == 4, got 3")
+ end
+end
+
+describe "should be ===" do
+ it "should pass when === operator returns true" do
+ Hash.should be === Hash.new
+ end
+
+ it "should fail when === operator returns false" do
+ lambda { Hash.should be === "not a hash" }.should fail_with(%[expected === "not a hash", got Hash])
+ end
+end
+
+describe "should be" do
+ it "should pass if actual is true or a set value" do
+ true.should be
+ 1.should be
+ end
+
+ it "should fail if actual is false" do
+ lambda {false.should be}.should fail_with("expected if to be satisfied, got false")
+ end
+
+ it "should fail if actual is nil" do
+ lambda {nil.should be}.should fail_with("expected if to be satisfied, got nil")
+ end
+end
+
+describe "should be(value)" do
+ it "should pass if actual.equal?(value)" do
+ 5.should be(5)
+ end
+ it "should fail if !actual.equal?(value)" do
+ lambda { 5.should be(6) }.should fail_with("expected 6, got 5")
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/change_spec.rb b/vendor/gems/rspec/spec/spec/matchers/change_spec.rb
new file mode 100644
index 000000000..d95aa6da4
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/change_spec.rb
@@ -0,0 +1,319 @@
+#Based on patch from Wilson Bilkovich
+
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+class SomethingExpected
+ attr_accessor :some_value
+end
+
+describe "should change(actual, message)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 5
+ end
+
+ it "should pass when actual is modified by the block" do
+ lambda {@instance.some_value = 6}.should change(@instance, :some_value)
+ end
+
+ it "should fail when actual is not modified by the block" do
+ lambda do
+ lambda {}.should change(@instance, :some_value)
+ end.should fail_with("some_value should have changed, but is still 5")
+ end
+end
+
+describe "should_not change(actual, message)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 5
+ end
+
+ it "should pass when actual is not modified by the block" do
+ lambda { }.should_not change(@instance, :some_value)
+ end
+
+ it "should fail when actual is not modified by the block" do
+ lambda do
+ lambda {@instance.some_value = 6}.should_not change(@instance, :some_value)
+ end.should fail_with("some_value should not have changed, but did change from 5 to 6")
+ end
+end
+
+describe "should change { block }" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 5
+ end
+
+ it "should pass when actual is modified by the block" do
+ lambda {@instance.some_value = 6}.should change { @instance.some_value }
+ end
+
+ it "should fail when actual is not modified by the block" do
+ lambda do
+ lambda {}.should change{ @instance.some_value }
+ end.should fail_with("result should have changed, but is still 5")
+ end
+
+ it "should warn if passed a block using do/end" do
+ lambda do
+ lambda {}.should change do
+ end
+ end.should raise_error(Spec::Matchers::MatcherError, /block passed to should or should_not/)
+ end
+end
+
+describe "should_not change { block }" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 5
+ end
+
+ it "should pass when actual is modified by the block" do
+ lambda {}.should_not change{ @instance.some_value }
+ end
+
+ it "should fail when actual is not modified by the block" do
+ lambda do
+ lambda {@instance.some_value = 6}.should_not change { @instance.some_value }
+ end.should fail_with("result should not have changed, but did change from 5 to 6")
+ end
+
+ it "should warn if passed a block using do/end" do
+ lambda do
+ lambda {}.should_not change do
+ end
+ end.should raise_error(Spec::Matchers::MatcherError, /block passed to should or should_not/)
+ end
+end
+
+describe "should change(actual, message).by(expected)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 5
+ end
+
+ it "should pass when attribute is changed by expected amount" do
+ lambda { @instance.some_value += 1 }.should change(@instance, :some_value).by(1)
+ end
+
+ it "should fail when the attribute is changed by unexpected amount" do
+ lambda do
+ lambda { @instance.some_value += 2 }.should change(@instance, :some_value).by(1)
+ end.should fail_with("some_value should have been changed by 1, but was changed by 2")
+ end
+
+ it "should fail when the attribute is changed by unexpected amount in the opposite direction" do
+ lambda do
+ lambda { @instance.some_value -= 1 }.should change(@instance, :some_value).by(1)
+ end.should fail_with("some_value should have been changed by 1, but was changed by -1")
+ end
+end
+
+describe "should change{ block }.by(expected)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 5
+ end
+
+ it "should pass when attribute is changed by expected amount" do
+ lambda { @instance.some_value += 1 }.should change{@instance.some_value}.by(1)
+ end
+
+ it "should fail when the attribute is changed by unexpected amount" do
+ lambda do
+ lambda { @instance.some_value += 2 }.should change{@instance.some_value}.by(1)
+ end.should fail_with("result should have been changed by 1, but was changed by 2")
+ end
+
+ it "should fail when the attribute is changed by unexpected amount in the opposite direction" do
+ lambda do
+ lambda { @instance.some_value -= 1 }.should change{@instance.some_value}.by(1)
+ end.should fail_with("result should have been changed by 1, but was changed by -1")
+ end
+end
+
+describe "should change(actual, message).by_at_least(expected)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 5
+ end
+
+ it "should pass when attribute is changed by greater than the expected amount" do
+ lambda { @instance.some_value += 2 }.should change(@instance, :some_value).by_at_least(1)
+ end
+
+ it "should pass when attribute is changed by the expected amount" do
+ lambda { @instance.some_value += 2 }.should change(@instance, :some_value).by_at_least(2)
+ end
+
+ it "should fail when the attribute is changed by less than the expected amount" do
+ lambda do
+ lambda { @instance.some_value += 1 }.should change(@instance, :some_value).by_at_least(2)
+ end.should fail_with("some_value should have been changed by at least 2, but was changed by 1")
+ end
+
+end
+
+describe "should change{ block }.by_at_least(expected)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 5
+ end
+
+ it "should pass when attribute is changed by greater than expected amount" do
+ lambda { @instance.some_value += 2 }.should change{@instance.some_value}.by_at_least(1)
+ end
+
+ it "should pass when attribute is changed by the expected amount" do
+ lambda { @instance.some_value += 2 }.should change{@instance.some_value}.by_at_least(2)
+ end
+
+ it "should fail when the attribute is changed by less than the unexpected amount" do
+ lambda do
+ lambda { @instance.some_value += 1 }.should change{@instance.some_value}.by_at_least(2)
+ end.should fail_with("result should have been changed by at least 2, but was changed by 1")
+ end
+end
+
+
+describe "should change(actual, message).by_at_most(expected)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 5
+ end
+
+ it "should pass when attribute is changed by less than the expected amount" do
+ lambda { @instance.some_value += 2 }.should change(@instance, :some_value).by_at_most(3)
+ end
+
+ it "should pass when attribute is changed by the expected amount" do
+ lambda { @instance.some_value += 2 }.should change(@instance, :some_value).by_at_most(2)
+ end
+
+ it "should fail when the attribute is changed by greater than the expected amount" do
+ lambda do
+ lambda { @instance.some_value += 2 }.should change(@instance, :some_value).by_at_most(1)
+ end.should fail_with("some_value should have been changed by at most 1, but was changed by 2")
+ end
+
+end
+
+describe "should change{ block }.by_at_most(expected)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 5
+ end
+
+ it "should pass when attribute is changed by less than expected amount" do
+ lambda { @instance.some_value += 2 }.should change{@instance.some_value}.by_at_most(3)
+ end
+
+ it "should pass when attribute is changed by the expected amount" do
+ lambda { @instance.some_value += 2 }.should change{@instance.some_value}.by_at_most(2)
+ end
+
+ it "should fail when the attribute is changed by greater than the unexpected amount" do
+ lambda do
+ lambda { @instance.some_value += 2 }.should change{@instance.some_value}.by_at_most(1)
+ end.should fail_with("result should have been changed by at most 1, but was changed by 2")
+ end
+end
+
+describe "should change(actual, message).from(old)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 'string'
+ end
+
+ it "should pass when attribute is == to expected value before executing block" do
+ lambda { @instance.some_value = "astring" }.should change(@instance, :some_value).from("string")
+ end
+
+ it "should fail when attribute is not == to expected value before executing block" do
+ lambda do
+ lambda { @instance.some_value = "knot" }.should change(@instance, :some_value).from("cat")
+ end.should fail_with("some_value should have initially been \"cat\", but was \"string\"")
+ end
+end
+
+describe "should change{ block }.from(old)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 'string'
+ end
+
+ it "should pass when attribute is == to expected value before executing block" do
+ lambda { @instance.some_value = "astring" }.should change{@instance.some_value}.from("string")
+ end
+
+ it "should fail when attribute is not == to expected value before executing block" do
+ lambda do
+ lambda { @instance.some_value = "knot" }.should change{@instance.some_value}.from("cat")
+ end.should fail_with("result should have initially been \"cat\", but was \"string\"")
+ end
+end
+
+describe "should change(actual, message).to(new)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 'string'
+ end
+
+ it "should pass when attribute is == to expected value after executing block" do
+ lambda { @instance.some_value = "cat" }.should change(@instance, :some_value).to("cat")
+ end
+
+ it "should fail when attribute is not == to expected value after executing block" do
+ lambda do
+ lambda { @instance.some_value = "cat" }.should change(@instance, :some_value).from("string").to("dog")
+ end.should fail_with("some_value should have been changed to \"dog\", but is now \"cat\"")
+ end
+end
+
+describe "should change{ block }.to(new)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 'string'
+ end
+
+ it "should pass when attribute is == to expected value after executing block" do
+ lambda { @instance.some_value = "cat" }.should change{@instance.some_value}.to("cat")
+ end
+
+ it "should fail when attribute is not == to expected value after executing block" do
+ lambda do
+ lambda { @instance.some_value = "cat" }.should change{@instance.some_value}.from("string").to("dog")
+ end.should fail_with("result should have been changed to \"dog\", but is now \"cat\"")
+ end
+end
+
+describe "should change(actual, message).from(old).to(new)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 'string'
+ end
+
+ it "should pass when #to comes before #from" do
+ lambda { @instance.some_value = "cat" }.should change(@instance, :some_value).to("cat").from("string")
+ end
+
+ it "should pass when #from comes before #to" do
+ lambda { @instance.some_value = "cat" }.should change(@instance, :some_value).from("string").to("cat")
+ end
+end
+
+describe "should change{ block }.from(old).to(new)" do
+ before(:each) do
+ @instance = SomethingExpected.new
+ @instance.some_value = 'string'
+ end
+
+ it "should pass when #to comes before #from" do
+ lambda { @instance.some_value = "cat" }.should change{@instance.some_value}.to("cat").from("string")
+ end
+
+ it "should pass when #from comes before #to" do
+ lambda { @instance.some_value = "cat" }.should change{@instance.some_value}.from("string").to("cat")
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/description_generation_spec.rb b/vendor/gems/rspec/spec/spec/matchers/description_generation_spec.rb
new file mode 100644
index 000000000..c494e2165
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/description_generation_spec.rb
@@ -0,0 +1,153 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "Matchers should be able to generate their own descriptions" do
+ after(:each) do
+ Spec::Matchers.clear_generated_description
+ end
+
+ it "should == expected" do
+ "this".should == "this"
+ Spec::Matchers.generated_description.should == "should == \"this\""
+ end
+
+ it "should not == expected" do
+ "this".should_not == "that"
+ Spec::Matchers.generated_description.should == "should not == \"that\""
+ end
+
+ it "should be empty (arbitrary predicate)" do
+ [].should be_empty
+ Spec::Matchers.generated_description.should == "should be empty"
+ end
+
+ it "should not be empty (arbitrary predicate)" do
+ [1].should_not be_empty
+ Spec::Matchers.generated_description.should == "should not be empty"
+ end
+
+ it "should be true" do
+ true.should be_true
+ Spec::Matchers.generated_description.should == "should be true"
+ end
+
+ it "should be false" do
+ false.should be_false
+ Spec::Matchers.generated_description.should == "should be false"
+ end
+
+ it "should be nil" do
+ nil.should be_nil
+ Spec::Matchers.generated_description.should == "should be nil"
+ end
+
+ it "should be > n" do
+ 5.should be > 3
+ Spec::Matchers.generated_description.should == "should be > 3"
+ end
+
+ it "should be predicate arg1, arg2 and arg3" do
+ 5.0.should be_between(0,10)
+ Spec::Matchers.generated_description.should == "should be between 0 and 10"
+ end
+
+ it "should be_few_words predicate should be transformed to 'be few words'" do
+ 5.should be_kind_of(Fixnum)
+ Spec::Matchers.generated_description.should == "should be kind of Fixnum"
+ end
+
+ it "should preserve a proper prefix for be predicate" do
+ 5.should be_a_kind_of(Fixnum)
+ Spec::Matchers.generated_description.should == "should be a kind of Fixnum"
+ 5.should be_an_instance_of(Fixnum)
+ Spec::Matchers.generated_description.should == "should be an instance of Fixnum"
+ end
+
+ it "should equal" do
+ expected = "expected"
+ expected.should equal(expected)
+ Spec::Matchers.generated_description.should == "should equal \"expected\""
+ end
+
+ it "should_not equal" do
+ 5.should_not equal(37)
+ Spec::Matchers.generated_description.should == "should not equal 37"
+ end
+
+ it "should eql" do
+ "string".should eql("string")
+ Spec::Matchers.generated_description.should == "should eql \"string\""
+ end
+
+ it "should not eql" do
+ "a".should_not eql(:a)
+ Spec::Matchers.generated_description.should == "should not eql :a"
+ end
+
+ it "should have_key" do
+ {:a => "a"}.should have_key(:a)
+ Spec::Matchers.generated_description.should == "should have key :a"
+ end
+
+ it "should have n items" do
+ team.should have(3).players
+ Spec::Matchers.generated_description.should == "should have 3 players"
+ end
+
+ it "should have at least n items" do
+ team.should have_at_least(2).players
+ Spec::Matchers.generated_description.should == "should have at least 2 players"
+ end
+
+ it "should have at most n items" do
+ team.should have_at_most(4).players
+ Spec::Matchers.generated_description.should == "should have at most 4 players"
+ end
+
+ it "should include" do
+ [1,2,3].should include(3)
+ Spec::Matchers.generated_description.should == "should include 3"
+ end
+
+ it "should match" do
+ "this string".should match(/this string/)
+ Spec::Matchers.generated_description.should == "should match /this string/"
+ end
+
+ it "should raise_error" do
+ lambda { raise }.should raise_error
+ Spec::Matchers.generated_description.should == "should raise Exception"
+ end
+
+ it "should raise_error with type" do
+ lambda { raise }.should raise_error(RuntimeError)
+ Spec::Matchers.generated_description.should == "should raise RuntimeError"
+ end
+
+ it "should raise_error with type and message" do
+ lambda { raise "there was an error" }.should raise_error(RuntimeError, "there was an error")
+ Spec::Matchers.generated_description.should == "should raise RuntimeError with \"there was an error\""
+ end
+
+ it "should respond_to" do
+ [].should respond_to(:insert)
+ Spec::Matchers.generated_description.should == "should respond to #insert"
+ end
+
+ it "should throw symbol" do
+ lambda { throw :what_a_mess }.should throw_symbol
+ Spec::Matchers.generated_description.should == "should throw a Symbol"
+ end
+
+ it "should throw symbol (with named symbol)" do
+ lambda { throw :what_a_mess }.should throw_symbol(:what_a_mess)
+ Spec::Matchers.generated_description.should == "should throw :what_a_mess"
+ end
+
+ def team
+ Class.new do
+ def players
+ [1,2,3]
+ end
+ end.new
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/eql_spec.rb b/vendor/gems/rspec/spec/spec/matchers/eql_spec.rb
new file mode 100644
index 000000000..3f265d700
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/eql_spec.rb
@@ -0,0 +1,28 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Matchers
+ describe Eql do
+ it "should match when actual.eql?(expected)" do
+ Eql.new(1).matches?(1).should be_true
+ end
+ it "should not match when !actual.eql?(expected)" do
+ Eql.new(1).matches?(2).should be_false
+ end
+ it "should describe itself" do
+ matcher = Eql.new(1)
+ matcher.description.should == "eql 1"
+ end
+ it "should provide message, expected and actual on #failure_message" do
+ matcher = Eql.new("1")
+ matcher.matches?(1)
+ matcher.failure_message.should == ["expected \"1\", got 1 (using .eql?)", "1", 1]
+ end
+ it "should provide message, expected and actual on #negative_failure_message" do
+ matcher = Eql.new(1)
+ matcher.matches?(1)
+ matcher.negative_failure_message.should == ["expected 1 not to equal 1 (using .eql?)", 1, 1]
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/equal_spec.rb b/vendor/gems/rspec/spec/spec/matchers/equal_spec.rb
new file mode 100644
index 000000000..7667bdc38
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/equal_spec.rb
@@ -0,0 +1,28 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Matchers
+ describe Equal do
+ it "should match when actual.equal?(expected)" do
+ Equal.new(1).matches?(1).should be_true
+ end
+ it "should not match when !actual.equal?(expected)" do
+ Equal.new("1").matches?("1").should be_false
+ end
+ it "should describe itself" do
+ matcher = Equal.new(1)
+ matcher.description.should == "equal 1"
+ end
+ it "should provide message, expected and actual on #failure_message" do
+ matcher = Equal.new("1")
+ matcher.matches?(1)
+ matcher.failure_message.should == ["expected \"1\", got 1 (using .equal?)", "1", 1]
+ end
+ it "should provide message, expected and actual on #negative_failure_message" do
+ matcher = Equal.new(1)
+ matcher.matches?(1)
+ matcher.negative_failure_message.should == ["expected 1 not to equal 1 (using .equal?)", 1, 1]
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/exist_spec.rb b/vendor/gems/rspec/spec/spec/matchers/exist_spec.rb
new file mode 100644
index 000000000..0a509726e
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/exist_spec.rb
@@ -0,0 +1,57 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+class Substance
+ def initialize exists, description
+ @exists = exists
+ @description = description
+ end
+ def exist?
+ @exists
+ end
+ def inspect
+ @description
+ end
+end
+
+class SubstanceTester
+ include Spec::Matchers
+ def initialize substance
+ @substance = substance
+ end
+ def should_exist
+ @substance.should exist
+ end
+end
+
+describe "should exist," do
+
+ before(:each) do
+ @real = Substance.new true, 'something real'
+ @imaginary = Substance.new false, 'something imaginary'
+ end
+
+ describe "within an example group" do
+
+ it "should pass if target exists" do
+ @real.should exist
+ end
+
+ it "should fail if target does not exist" do
+ lambda { @imaginary.should exist }.should fail
+ end
+
+ it "should pass if target doesn't exist" do
+ lambda { @real.should_not exist }.should fail
+ end
+ end
+
+ describe "outside of an example group" do
+
+ it "should pass if target exists" do
+ real_tester = SubstanceTester.new @real
+ real_tester.should_exist
+ end
+
+ end
+
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/handler_spec.rb b/vendor/gems/rspec/spec/spec/matchers/handler_spec.rb
new file mode 100644
index 000000000..ad4fe6f85
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/handler_spec.rb
@@ -0,0 +1,129 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module ExampleExpectations
+
+ class ArbitraryMatcher
+ def initialize(*args, &block)
+ if args.last.is_a? Hash
+ @expected = args.last[:expected]
+ end
+ if block_given?
+ @expected = block.call
+ end
+ @block = block
+ end
+
+ def matches?(target)
+ @target = target
+ return @expected == target
+ end
+
+ def with(new_value)
+ @expected = new_value
+ self
+ end
+
+ def failure_message
+ "expected #{@expected}, got #{@target}"
+ end
+
+ def negative_failure_message
+ "expected not #{@expected}, got #{@target}"
+ end
+ end
+
+ class PositiveOnlyMatcher < ArbitraryMatcher
+ undef negative_failure_message rescue nil
+ end
+
+ def arbitrary_matcher(*args, &block)
+ ArbitraryMatcher.new(*args, &block)
+ end
+
+ def positive_only_matcher(*args, &block)
+ PositiveOnlyMatcher.new(*args, &block)
+ end
+
+end
+
+module Spec
+ module Expectations
+ describe ExpectationMatcherHandler, ".handle_matcher" do
+ it "should ask the matcher if it matches" do
+ matcher = mock("matcher")
+ actual = Object.new
+ matcher.should_receive(:matches?).with(actual).and_return(true)
+ ExpectationMatcherHandler.handle_matcher(actual, matcher)
+ end
+
+ it "should explain when the matcher parameter is not a matcher" do
+ begin
+ nonmatcher = mock("nonmatcher")
+ actual = Object.new
+ ExpectationMatcherHandler.handle_matcher(actual, nonmatcher)
+ rescue Spec::Expectations::InvalidMatcherError => e
+ end
+
+ e.message.should =~ /^Expected a matcher, got /
+ end
+ end
+
+ describe NegativeExpectationMatcherHandler, ".handle_matcher" do
+ it "should explain when matcher does not support should_not" do
+ matcher = mock("matcher")
+ matcher.stub!(:matches?)
+ actual = Object.new
+ lambda {
+ NegativeExpectationMatcherHandler.handle_matcher(actual, matcher)
+ }.should fail_with(/Matcher does not support should_not.\n/)
+ end
+
+ it "should ask the matcher if it matches" do
+ matcher = mock("matcher")
+ actual = Object.new
+ matcher.stub!(:negative_failure_message)
+ matcher.should_receive(:matches?).with(actual).and_return(false)
+ NegativeExpectationMatcherHandler.handle_matcher(actual, matcher)
+ end
+
+ it "should explain when the matcher parameter is not a matcher" do
+ begin
+ nonmatcher = mock("nonmatcher")
+ actual = Object.new
+ NegativeExpectationMatcherHandler.handle_matcher(actual, nonmatcher)
+ rescue Spec::Expectations::InvalidMatcherError => e
+ end
+
+ e.message.should =~ /^Expected a matcher, got /
+ end
+ end
+
+ describe ExpectationMatcherHandler do
+ include ExampleExpectations
+
+ it "should handle submitted args" do
+ 5.should arbitrary_matcher(:expected => 5)
+ 5.should arbitrary_matcher(:expected => "wrong").with(5)
+ lambda { 5.should arbitrary_matcher(:expected => 4) }.should fail_with("expected 4, got 5")
+ lambda { 5.should arbitrary_matcher(:expected => 5).with(4) }.should fail_with("expected 4, got 5")
+ 5.should_not arbitrary_matcher(:expected => 4)
+ 5.should_not arbitrary_matcher(:expected => 5).with(4)
+ lambda { 5.should_not arbitrary_matcher(:expected => 5) }.should fail_with("expected not 5, got 5")
+ lambda { 5.should_not arbitrary_matcher(:expected => 4).with(5) }.should fail_with("expected not 5, got 5")
+ end
+
+ it "should handle the submitted block" do
+ 5.should arbitrary_matcher { 5 }
+ 5.should arbitrary_matcher(:expected => 4) { 5 }
+ 5.should arbitrary_matcher(:expected => 4).with(5) { 3 }
+ end
+
+ it "should explain when matcher does not support should_not" do
+ lambda {
+ 5.should_not positive_only_matcher(:expected => 5)
+ }.should fail_with(/Matcher does not support should_not.\n/)
+ end
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/has_spec.rb b/vendor/gems/rspec/spec/spec/matchers/has_spec.rb
new file mode 100644
index 000000000..47f048ebf
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/has_spec.rb
@@ -0,0 +1,37 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "should have_sym(*args)" do
+ it "should pass if #has_sym?(*args) returns true" do
+ {:a => "A"}.should have_key(:a)
+ end
+
+ it "should fail if #has_sym?(*args) returns false" do
+ lambda {
+ {:b => "B"}.should have_key(:a)
+ }.should fail_with("expected #has_key?(:a) to return true, got false")
+ end
+
+ it "should fail if target does not respond to #has_sym?" do
+ lambda {
+ Object.new.should have_key(:a)
+ }.should raise_error(NoMethodError)
+ end
+end
+
+describe "should_not have_sym(*args)" do
+ it "should pass if #has_sym?(*args) returns false" do
+ {:a => "A"}.should_not have_key(:b)
+ end
+
+ it "should fail if #has_sym?(*args) returns true" do
+ lambda {
+ {:a => "A"}.should_not have_key(:a)
+ }.should fail_with("expected #has_key?(:a) to return false, got true")
+ end
+
+ it "should fail if target does not respond to #has_sym?" do
+ lambda {
+ Object.new.should have_key(:a)
+ }.should raise_error(NoMethodError)
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/have_spec.rb b/vendor/gems/rspec/spec/spec/matchers/have_spec.rb
new file mode 100644
index 000000000..27083c294
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/have_spec.rb
@@ -0,0 +1,291 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module HaveSpecHelper
+ def create_collection_owner_with(n)
+ owner = Spec::Expectations::Helper::CollectionOwner.new
+ (1..n).each do |n|
+ owner.add_to_collection_with_length_method(n)
+ owner.add_to_collection_with_size_method(n)
+ end
+ owner
+ end
+end
+
+describe "should have(n).items" do
+ include HaveSpecHelper
+
+ it "should pass if target has a collection of items with n members" do
+ owner = create_collection_owner_with(3)
+ owner.should have(3).items_in_collection_with_length_method
+ owner.should have(3).items_in_collection_with_size_method
+ end
+
+ it "should convert :no to 0" do
+ owner = create_collection_owner_with(0)
+ owner.should have(:no).items_in_collection_with_length_method
+ owner.should have(:no).items_in_collection_with_size_method
+ end
+
+ it "should fail if target has a collection of items with < n members" do
+ owner = create_collection_owner_with(3)
+ lambda {
+ owner.should have(4).items_in_collection_with_length_method
+ }.should fail_with("expected 4 items_in_collection_with_length_method, got 3")
+ lambda {
+ owner.should have(4).items_in_collection_with_size_method
+ }.should fail_with("expected 4 items_in_collection_with_size_method, got 3")
+ end
+
+ it "should fail if target has a collection of items with > n members" do
+ owner = create_collection_owner_with(3)
+ lambda {
+ owner.should have(2).items_in_collection_with_length_method
+ }.should fail_with("expected 2 items_in_collection_with_length_method, got 3")
+ lambda {
+ owner.should have(2).items_in_collection_with_size_method
+ }.should fail_with("expected 2 items_in_collection_with_size_method, got 3")
+ end
+end
+
+describe 'should have(1).item when Inflector is defined' do
+ include HaveSpecHelper
+
+ before do
+ unless Object.const_defined?(:Inflector)
+ class Inflector
+ def self.pluralize(string)
+ string.to_s + 's'
+ end
+ end
+ end
+ end
+
+ it 'should pluralize the collection name' do
+ owner = create_collection_owner_with(1)
+ owner.should have(1).item
+ end
+end
+
+describe "should have(n).items where result responds to items but returns something other than a collection" do
+ it "should provide a meaningful error" do
+ owner = Class.new do
+ def items
+ Object.new
+ end
+ end.new
+ lambda do
+ owner.should have(3).items
+ end.should raise_error("expected items to be a collection but it does not respond to #length or #size")
+ end
+end
+
+describe "should_not have(n).items" do
+ include HaveSpecHelper
+
+ it "should pass if target has a collection of items with < n members" do
+ owner = create_collection_owner_with(3)
+ owner.should_not have(4).items_in_collection_with_length_method
+ owner.should_not have(4).items_in_collection_with_size_method
+ end
+
+ it "should pass if target has a collection of items with > n members" do
+ owner = create_collection_owner_with(3)
+ owner.should_not have(2).items_in_collection_with_length_method
+ owner.should_not have(2).items_in_collection_with_size_method
+ end
+
+ it "should fail if target has a collection of items with n members" do
+ owner = create_collection_owner_with(3)
+ lambda {
+ owner.should_not have(3).items_in_collection_with_length_method
+ }.should fail_with("expected target not to have 3 items_in_collection_with_length_method, got 3")
+ lambda {
+ owner.should_not have(3).items_in_collection_with_size_method
+ }.should fail_with("expected target not to have 3 items_in_collection_with_size_method, got 3")
+ end
+end
+
+describe "should have_exactly(n).items" do
+ include HaveSpecHelper
+
+ it "should pass if target has a collection of items with n members" do
+ owner = create_collection_owner_with(3)
+ owner.should have_exactly(3).items_in_collection_with_length_method
+ owner.should have_exactly(3).items_in_collection_with_size_method
+ end
+
+ it "should convert :no to 0" do
+ owner = create_collection_owner_with(0)
+ owner.should have_exactly(:no).items_in_collection_with_length_method
+ owner.should have_exactly(:no).items_in_collection_with_size_method
+ end
+
+ it "should fail if target has a collection of items with < n members" do
+ owner = create_collection_owner_with(3)
+ lambda {
+ owner.should have_exactly(4).items_in_collection_with_length_method
+ }.should fail_with("expected 4 items_in_collection_with_length_method, got 3")
+ lambda {
+ owner.should have_exactly(4).items_in_collection_with_size_method
+ }.should fail_with("expected 4 items_in_collection_with_size_method, got 3")
+ end
+
+ it "should fail if target has a collection of items with > n members" do
+ owner = create_collection_owner_with(3)
+ lambda {
+ owner.should have_exactly(2).items_in_collection_with_length_method
+ }.should fail_with("expected 2 items_in_collection_with_length_method, got 3")
+ lambda {
+ owner.should have_exactly(2).items_in_collection_with_size_method
+ }.should fail_with("expected 2 items_in_collection_with_size_method, got 3")
+ end
+end
+
+describe "should have_at_least(n).items" do
+ include HaveSpecHelper
+
+ it "should pass if target has a collection of items with n members" do
+ owner = create_collection_owner_with(3)
+ owner.should have_at_least(3).items_in_collection_with_length_method
+ owner.should have_at_least(3).items_in_collection_with_size_method
+ end
+
+ it "should pass if target has a collection of items with > n members" do
+ owner = create_collection_owner_with(3)
+ owner.should have_at_least(2).items_in_collection_with_length_method
+ owner.should have_at_least(2).items_in_collection_with_size_method
+ end
+
+ it "should fail if target has a collection of items with < n members" do
+ owner = create_collection_owner_with(3)
+ lambda {
+ owner.should have_at_least(4).items_in_collection_with_length_method
+ }.should fail_with("expected at least 4 items_in_collection_with_length_method, got 3")
+ lambda {
+ owner.should have_at_least(4).items_in_collection_with_size_method
+ }.should fail_with("expected at least 4 items_in_collection_with_size_method, got 3")
+ end
+
+ it "should provide educational negative failure messages" do
+ #given
+ owner = create_collection_owner_with(3)
+ length_matcher = have_at_least(3).items_in_collection_with_length_method
+ size_matcher = have_at_least(3).items_in_collection_with_size_method
+
+ #when
+ length_matcher.matches?(owner)
+ size_matcher.matches?(owner)
+
+ #then
+ length_matcher.negative_failure_message.should == <<-EOF
+Isn't life confusing enough?
+Instead of having to figure out the meaning of this:
+ should_not have_at_least(3).items_in_collection_with_length_method
+We recommend that you use this instead:
+ should have_at_most(2).items_in_collection_with_length_method
+EOF
+
+ size_matcher.negative_failure_message.should == <<-EOF
+Isn't life confusing enough?
+Instead of having to figure out the meaning of this:
+ should_not have_at_least(3).items_in_collection_with_size_method
+We recommend that you use this instead:
+ should have_at_most(2).items_in_collection_with_size_method
+EOF
+ end
+end
+
+describe "should have_at_most(n).items" do
+ include HaveSpecHelper
+
+ it "should pass if target has a collection of items with n members" do
+ owner = create_collection_owner_with(3)
+ owner.should have_at_most(3).items_in_collection_with_length_method
+ owner.should have_at_most(3).items_in_collection_with_size_method
+ end
+
+ it "should fail if target has a collection of items with > n members" do
+ owner = create_collection_owner_with(3)
+ lambda {
+ owner.should have_at_most(2).items_in_collection_with_length_method
+ }.should fail_with("expected at most 2 items_in_collection_with_length_method, got 3")
+ lambda {
+ owner.should have_at_most(2).items_in_collection_with_size_method
+ }.should fail_with("expected at most 2 items_in_collection_with_size_method, got 3")
+ end
+
+ it "should pass if target has a collection of items with < n members" do
+ owner = create_collection_owner_with(3)
+ owner.should have_at_most(4).items_in_collection_with_length_method
+ owner.should have_at_most(4).items_in_collection_with_size_method
+ end
+
+ it "should provide educational negative failure messages" do
+ #given
+ owner = create_collection_owner_with(3)
+ length_matcher = have_at_most(3).items_in_collection_with_length_method
+ size_matcher = have_at_most(3).items_in_collection_with_size_method
+
+ #when
+ length_matcher.matches?(owner)
+ size_matcher.matches?(owner)
+
+ #then
+ length_matcher.negative_failure_message.should == <<-EOF
+Isn't life confusing enough?
+Instead of having to figure out the meaning of this:
+ should_not have_at_most(3).items_in_collection_with_length_method
+We recommend that you use this instead:
+ should have_at_least(4).items_in_collection_with_length_method
+EOF
+
+ size_matcher.negative_failure_message.should == <<-EOF
+Isn't life confusing enough?
+Instead of having to figure out the meaning of this:
+ should_not have_at_most(3).items_in_collection_with_size_method
+We recommend that you use this instead:
+ should have_at_least(4).items_in_collection_with_size_method
+EOF
+ end
+end
+
+describe "have(n).items(args, block)" do
+ it "should pass args to target" do
+ target = mock("target")
+ target.should_receive(:items).with("arg1","arg2").and_return([1,2,3])
+ target.should have(3).items("arg1","arg2")
+ end
+
+ it "should pass block to target" do
+ target = mock("target")
+ block = lambda { 5 }
+ target.should_receive(:items).with("arg1","arg2", block).and_return([1,2,3])
+ target.should have(3).items("arg1","arg2", block)
+ end
+end
+
+describe "have(n).items where target IS a collection" do
+ it "should reference the number of items IN the collection" do
+ [1,2,3].should have(3).items
+ end
+
+ it "should fail when the number of items IN the collection is not as expected" do
+ lambda { [1,2,3].should have(7).items }.should fail_with("expected 7 items, got 3")
+ end
+end
+
+describe "have(n).characters where target IS a String" do
+ it "should pass if the length is correct" do
+ "this string".should have(11).characters
+ end
+
+ it "should fail if the length is incorrect" do
+ lambda { "this string".should have(12).characters }.should fail_with("expected 12 characters, got 11")
+ end
+end
+
+describe "have(n).things on an object which is not a collection nor contains one" do
+ it "should fail" do
+ lambda { Object.new.should have(2).things }.should raise_error(NoMethodError, /undefined method `things' for #<Object:/)
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/include_spec.rb b/vendor/gems/rspec/spec/spec/matchers/include_spec.rb
new file mode 100644
index 000000000..f1057f3fd
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/include_spec.rb
@@ -0,0 +1,45 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "should include(expected)" do
+ it "should pass if target includes expected" do
+ [1,2,3].should include(3)
+ "abc".should include("a")
+ end
+
+ it "should fail if target does not include expected" do
+ lambda {
+ [1,2,3].should include(4)
+ }.should fail_with("expected [1, 2, 3] to include 4")
+ lambda {
+ "abc".should include("d")
+ }.should fail_with("expected \"abc\" to include \"d\"")
+ end
+end
+
+describe "should include(with, multiple, args)" do
+ it "should pass if target includes all items" do
+ [1,2,3].should include(1,2,3)
+ end
+
+ it "should fail if target does not include any one of the items" do
+ lambda {
+ [1,2,3].should include(1,2,4)
+ }.should fail_with("expected [1, 2, 3] to include 1, 2 and 4")
+ end
+end
+
+describe "should_not include(expected)" do
+ it "should pass if target does not include expected" do
+ [1,2,3].should_not include(4)
+ "abc".should_not include("d")
+ end
+
+ it "should fail if target includes expected" do
+ lambda {
+ [1,2,3].should_not include(3)
+ }.should fail_with("expected [1, 2, 3] not to include 3")
+ lambda {
+ "abc".should_not include("c")
+ }.should fail_with("expected \"abc\" not to include \"c\"")
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/match_spec.rb b/vendor/gems/rspec/spec/spec/matchers/match_spec.rb
new file mode 100644
index 000000000..f69f7efad
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/match_spec.rb
@@ -0,0 +1,37 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "should match(expected)" do
+ it "should pass when target (String) matches expected (Regexp)" do
+ "string".should match(/tri/)
+ end
+
+ it "should fail when target (String) does not match expected (Regexp)" do
+ lambda {
+ "string".should match(/rings/)
+ }.should fail
+ end
+
+ it "should provide message, expected and actual on failure" do
+ matcher = match(/rings/)
+ matcher.matches?("string")
+ matcher.failure_message.should == ["expected \"string\" to match /rings/", /rings/, "string"]
+ end
+end
+
+describe "should_not match(expected)" do
+ it "should pass when target (String) matches does not match (Regexp)" do
+ "string".should_not match(/rings/)
+ end
+
+ it "should fail when target (String) matches expected (Regexp)" do
+ lambda {
+ "string".should_not match(/tri/)
+ }.should fail
+ end
+
+ it "should provide message, expected and actual on failure" do
+ matcher = match(/tri/)
+ matcher.matches?("string")
+ matcher.negative_failure_message.should == ["expected \"string\" not to match /tri/", /tri/, "string"]
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/matcher_methods_spec.rb b/vendor/gems/rspec/spec/spec/matchers/matcher_methods_spec.rb
new file mode 100644
index 000000000..80cc9855a
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/matcher_methods_spec.rb
@@ -0,0 +1,78 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Matchers
+ context %Q{The Spec::Matchers module gets included in the execution context of every spec.
+This module should provide the following methods, each of which returns a Matcher object.} do
+ it "be_true" do
+ be_true.should be_an_instance_of(Be)
+ end
+ it "be_false" do
+ be_false.should be_an_instance_of(Be)
+ end
+ it "be_nil" do
+ be_nil.should be_an_instance_of(Be)
+ end
+ it "be_arbitrary_predicate" do
+ be_arbitrary_predicate.should be_an_instance_of(Be)
+ end
+ it "be_close" do
+ be_close(1,2).should be_an_instance_of(BeClose)
+ end
+ it "change" do
+ change("target", :message).should be_an_instance_of(Change)
+ end
+ it "eql" do
+ eql(:expected).should be_an_instance_of(Eql)
+ end
+ it "equal" do
+ equal(:expected).should be_an_instance_of(Equal)
+ end
+ it "have" do
+ have(0).should be_an_instance_of(Have)
+ end
+ it "have_exactly" do
+ have_exactly(0).should be_an_instance_of(Have)
+ end
+ it "have_at_least" do
+ have_at_least(0).should be_an_instance_of(Have)
+ end
+ it "have_at_most" do
+ have_at_most(0).should be_an_instance_of(Have)
+ end
+ it "include" do
+ include(:value).should be_an_instance_of(Include)
+ end
+ it "match" do
+ match(:value).should be_an_instance_of(Match)
+ end
+ it "raise_error" do
+ raise_error.should be_an_instance_of(RaiseError)
+ raise_error(NoMethodError).should be_an_instance_of(RaiseError)
+ raise_error(NoMethodError, "message").should be_an_instance_of(RaiseError)
+ end
+ it "satisfy" do
+ satisfy{}.should be_an_instance_of(Satisfy)
+ end
+ it "throw_symbol" do
+ throw_symbol.should be_an_instance_of(ThrowSymbol)
+ throw_symbol(:sym).should be_an_instance_of(ThrowSymbol)
+ end
+ it "respond_to" do
+ respond_to(:sym).should be_an_instance_of(RespondTo)
+ end
+ end
+
+ describe "Spec::Matchers#method_missing" do
+ it "should convert be_xyz to Be(:be_xyz)" do
+ Be.should_receive(:new).with(:be_whatever)
+ be_whatever
+ end
+
+ it "should convert have_xyz to Has(:have_xyz)" do
+ Has.should_receive(:new).with(:have_whatever)
+ have_whatever
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/mock_constraint_matchers_spec.rb b/vendor/gems/rspec/spec/spec/matchers/mock_constraint_matchers_spec.rb
new file mode 100644
index 000000000..1292918c7
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/mock_constraint_matchers_spec.rb
@@ -0,0 +1,24 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "The anything() mock argument constraint matcher" do
+ specify { anything.should == Object.new }
+ specify { anything.should == Class }
+ specify { anything.should == 1 }
+ specify { anything.should == "a string" }
+ specify { anything.should == :a_symbol }
+end
+
+describe "The boolean() mock argument constraint matcher" do
+ specify { boolean.should == true }
+ specify { boolean.should == false }
+ specify { boolean.should_not == Object.new }
+ specify { boolean.should_not == Class }
+ specify { boolean.should_not == 1 }
+ specify { boolean.should_not == "a string" }
+ specify { boolean.should_not == :a_symbol }
+end
+
+describe "The an_instance_of() mock argument constraint matcher" do
+ # NOTE - this is implemented as a predicate_matcher - see example_group_methods.rb
+ specify { an_instance_of(String).should == "string" }
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/operator_matcher_spec.rb b/vendor/gems/rspec/spec/spec/matchers/operator_matcher_spec.rb
new file mode 100644
index 000000000..1985df0d9
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/operator_matcher_spec.rb
@@ -0,0 +1,158 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+require 'spec/expectations/differs/default'
+
+describe "should ==" do
+
+ it "should delegate message to target" do
+ subject = "apple"
+ subject.should_receive(:==).with("apple").and_return(true)
+ subject.should == "apple"
+ end
+
+ it "should fail when target.==(actual) returns false" do
+ subject = "apple"
+ Spec::Expectations.should_receive(:fail_with).with(%[expected: "orange",\n got: "apple" (using ==)], "orange", "apple")
+ subject.should == "orange"
+ end
+
+end
+
+describe "should_not ==" do
+
+ it "should delegate message to target" do
+ subject = "orange"
+ subject.should_receive(:==).with("apple").and_return(false)
+ subject.should_not == "apple"
+ end
+
+ it "should fail when target.==(actual) returns false" do
+ subject = "apple"
+ Spec::Expectations.should_receive(:fail_with).with(%[expected not: == "apple",\n got: "apple"], "apple", "apple")
+ subject.should_not == "apple"
+ end
+
+end
+
+describe "should ===" do
+
+ it "should delegate message to target" do
+ subject = "apple"
+ subject.should_receive(:===).with("apple").and_return(true)
+ subject.should === "apple"
+ end
+
+ it "should fail when target.===(actual) returns false" do
+ subject = "apple"
+ subject.should_receive(:===).with("orange").and_return(false)
+ Spec::Expectations.should_receive(:fail_with).with(%[expected: "orange",\n got: "apple" (using ===)], "orange", "apple")
+ subject.should === "orange"
+ end
+
+end
+
+describe "should_not ===" do
+
+ it "should delegate message to target" do
+ subject = "orange"
+ subject.should_receive(:===).with("apple").and_return(false)
+ subject.should_not === "apple"
+ end
+
+ it "should fail when target.===(actual) returns false" do
+ subject = "apple"
+ subject.should_receive(:===).with("apple").and_return(true)
+ Spec::Expectations.should_receive(:fail_with).with(%[expected not: === "apple",\n got: "apple"], "apple", "apple")
+ subject.should_not === "apple"
+ end
+
+end
+
+describe "should =~" do
+
+ it "should delegate message to target" do
+ subject = "foo"
+ subject.should_receive(:=~).with(/oo/).and_return(true)
+ subject.should =~ /oo/
+ end
+
+ it "should fail when target.=~(actual) returns false" do
+ subject = "fu"
+ subject.should_receive(:=~).with(/oo/).and_return(false)
+ Spec::Expectations.should_receive(:fail_with).with(%[expected: /oo/,\n got: "fu" (using =~)], /oo/, "fu")
+ subject.should =~ /oo/
+ end
+
+end
+
+describe "should_not =~" do
+
+ it "should delegate message to target" do
+ subject = "fu"
+ subject.should_receive(:=~).with(/oo/).and_return(false)
+ subject.should_not =~ /oo/
+ end
+
+ it "should fail when target.=~(actual) returns false" do
+ subject = "foo"
+ subject.should_receive(:=~).with(/oo/).and_return(true)
+ Spec::Expectations.should_receive(:fail_with).with(%[expected not: =~ /oo/,\n got: "foo"], /oo/, "foo")
+ subject.should_not =~ /oo/
+ end
+
+end
+
+describe "should >" do
+
+ it "should pass if > passes" do
+ 4.should > 3
+ end
+
+ it "should fail if > fails" do
+ Spec::Expectations.should_receive(:fail_with).with(%[expected: > 5,\n got: 4], 5, 4)
+ 4.should > 5
+ end
+
+end
+
+describe "should >=" do
+
+ it "should pass if >= passes" do
+ 4.should > 3
+ 4.should >= 4
+ end
+
+ it "should fail if > fails" do
+ Spec::Expectations.should_receive(:fail_with).with(%[expected: >= 5,\n got: 4], 5, 4)
+ 4.should >= 5
+ end
+
+end
+
+describe "should <" do
+
+ it "should pass if < passes" do
+ 4.should < 5
+ end
+
+ it "should fail if > fails" do
+ Spec::Expectations.should_receive(:fail_with).with(%[expected: < 3,\n got: 4], 3, 4)
+ 4.should < 3
+ end
+
+end
+
+describe "should <=" do
+
+ it "should pass if <= passes" do
+ 4.should <= 5
+ 4.should <= 4
+ end
+
+ it "should fail if > fails" do
+ Spec::Expectations.should_receive(:fail_with).with(%[expected: <= 3,\n got: 4], 3, 4)
+ 4.should <= 3
+ end
+
+end
+
diff --git a/vendor/gems/rspec/spec/spec/matchers/raise_error_spec.rb b/vendor/gems/rspec/spec/spec/matchers/raise_error_spec.rb
new file mode 100644
index 000000000..7cabf81e8
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/raise_error_spec.rb
@@ -0,0 +1,191 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "should raise_error" do
+ it "should pass if anything is raised" do
+ lambda {raise}.should raise_error
+ end
+
+ it "should fail if nothing is raised" do
+ lambda {
+ lambda {}.should raise_error
+ }.should fail_with("expected Exception but nothing was raised")
+ end
+end
+
+describe "should_not raise_error" do
+ it "should pass if nothing is raised" do
+ lambda {}.should_not raise_error
+ end
+
+ it "should fail if anything is raised" do
+ lambda {
+ lambda {raise}.should_not raise_error
+ }.should fail_with("expected no Exception, got RuntimeError")
+ end
+end
+
+describe "should raise_error(message)" do
+ it "should pass if RuntimeError is raised with the right message" do
+ lambda {raise 'blah'}.should raise_error('blah')
+ end
+ it "should pass if any other error is raised with the right message" do
+ lambda {raise NameError.new('blah')}.should raise_error('blah')
+ end
+ it "should fail if RuntimeError error is raised with the wrong message" do
+ lambda do
+ lambda {raise 'blarg'}.should raise_error('blah')
+ end.should fail_with("expected Exception with \"blah\", got #<RuntimeError: blarg>")
+ end
+ it "should fail if any other error is raised with the wrong message" do
+ lambda do
+ lambda {raise NameError.new('blarg')}.should raise_error('blah')
+ end.should fail_with("expected Exception with \"blah\", got #<NameError: blarg>")
+ end
+end
+
+describe "should_not raise_error(message)" do
+ it "should pass if RuntimeError error is raised with the different message" do
+ lambda {raise 'blarg'}.should_not raise_error('blah')
+ end
+ it "should pass if any other error is raised with the wrong message" do
+ lambda {raise NameError.new('blarg')}.should_not raise_error('blah')
+ end
+ it "should fail if RuntimeError is raised with message" do
+ lambda do
+ lambda {raise 'blah'}.should_not raise_error('blah')
+ end.should fail_with(%Q|expected no Exception with "blah", got #<RuntimeError: blah>|)
+ end
+ it "should fail if any other error is raised with message" do
+ lambda do
+ lambda {raise NameError.new('blah')}.should_not raise_error('blah')
+ end.should fail_with(%Q|expected no Exception with "blah", got #<NameError: blah>|)
+ end
+end
+
+describe "should raise_error(NamedError)" do
+ it "should pass if named error is raised" do
+ lambda { non_existent_method }.should raise_error(NameError)
+ end
+
+ it "should fail if nothing is raised" do
+ lambda {
+ lambda { }.should raise_error(NameError)
+ }.should fail_with("expected NameError but nothing was raised")
+ end
+
+ it "should fail if another error is raised (NameError)" do
+ lambda {
+ lambda { raise }.should raise_error(NameError)
+ }.should fail_with("expected NameError, got RuntimeError")
+ end
+
+ it "should fail if another error is raised (NameError)" do
+ lambda {
+ lambda { load "non/existent/file" }.should raise_error(NameError)
+ }.should fail_with(/expected NameError, got #<LoadError/)
+ end
+end
+
+describe "should_not raise_error(NamedError)" do
+ it "should pass if nothing is raised" do
+ lambda { }.should_not raise_error(NameError)
+ end
+
+ it "should pass if another error is raised" do
+ lambda { raise }.should_not raise_error(NameError)
+ end
+
+ it "should fail if named error is raised" do
+ lambda {
+ lambda { non_existent_method }.should_not raise_error(NameError)
+ }.should fail_with(/expected no NameError, got #<NameError: undefined/)
+ end
+end
+
+describe "should raise_error(NamedError, error_message) with String" do
+ it "should pass if named error is raised with same message" do
+ lambda { raise "example message" }.should raise_error(RuntimeError, "example message")
+ end
+
+ it "should fail if nothing is raised" do
+ lambda {
+ lambda {}.should raise_error(RuntimeError, "example message")
+ }.should fail_with("expected RuntimeError with \"example message\" but nothing was raised")
+ end
+
+ it "should fail if incorrect error is raised" do
+ lambda {
+ lambda { raise }.should raise_error(NameError, "example message")
+ }.should fail_with("expected NameError with \"example message\", got RuntimeError")
+ end
+
+ it "should fail if correct error is raised with incorrect message" do
+ lambda {
+ lambda { raise RuntimeError.new("not the example message") }.should raise_error(RuntimeError, "example message")
+ }.should fail_with(/expected RuntimeError with \"example message\", got #<RuntimeError: not the example message/)
+ end
+end
+
+describe "should_not raise_error(NamedError, error_message) with String" do
+ it "should pass if nothing is raised" do
+ lambda {}.should_not raise_error(RuntimeError, "example message")
+ end
+
+ it "should pass if a different error is raised" do
+ lambda { raise }.should_not raise_error(NameError, "example message")
+ end
+
+ it "should pass if same error is raised with different message" do
+ lambda { raise RuntimeError.new("not the example message") }.should_not raise_error(RuntimeError, "example message")
+ end
+
+ it "should fail if named error is raised with same message" do
+ lambda {
+ lambda { raise "example message" }.should_not raise_error(RuntimeError, "example message")
+ }.should fail_with("expected no RuntimeError with \"example message\", got #<RuntimeError: example message>")
+ end
+end
+
+describe "should raise_error(NamedError, error_message) with Regexp" do
+ it "should pass if named error is raised with matching message" do
+ lambda { raise "example message" }.should raise_error(RuntimeError, /ample mess/)
+ end
+
+ it "should fail if nothing is raised" do
+ lambda {
+ lambda {}.should raise_error(RuntimeError, /ample mess/)
+ }.should fail_with("expected RuntimeError with message matching /ample mess/ but nothing was raised")
+ end
+
+ it "should fail if incorrect error is raised" do
+ lambda {
+ lambda { raise }.should raise_error(NameError, /ample mess/)
+ }.should fail_with("expected NameError with message matching /ample mess/, got RuntimeError")
+ end
+
+ it "should fail if correct error is raised with incorrect message" do
+ lambda {
+ lambda { raise RuntimeError.new("not the example message") }.should raise_error(RuntimeError, /less than ample mess/)
+ }.should fail_with("expected RuntimeError with message matching /less than ample mess/, got #<RuntimeError: not the example message>")
+ end
+end
+
+describe "should_not raise_error(NamedError, error_message) with Regexp" do
+ it "should pass if nothing is raised" do
+ lambda {}.should_not raise_error(RuntimeError, /ample mess/)
+ end
+
+ it "should pass if a different error is raised" do
+ lambda { raise }.should_not raise_error(NameError, /ample mess/)
+ end
+
+ it "should pass if same error is raised with non-matching message" do
+ lambda { raise RuntimeError.new("non matching message") }.should_not raise_error(RuntimeError, /ample mess/)
+ end
+
+ it "should fail if named error is raised with matching message" do
+ lambda {
+ lambda { raise "example message" }.should_not raise_error(RuntimeError, /ample mess/)
+ }.should fail_with("expected no RuntimeError with message matching /ample mess/, got #<RuntimeError: example message>")
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/respond_to_spec.rb b/vendor/gems/rspec/spec/spec/matchers/respond_to_spec.rb
new file mode 100644
index 000000000..2cdbbcd63
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/respond_to_spec.rb
@@ -0,0 +1,54 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "should respond_to(:sym)" do
+
+ it "should pass if target responds to :sym" do
+ Object.new.should respond_to(:methods)
+ end
+
+ it "should fail target does not respond to :sym" do
+ lambda {
+ Object.new.should respond_to(:some_method)
+ }.should fail_with("expected target to respond to :some_method")
+ end
+
+end
+
+describe "should respond_to(message1, message2)" do
+
+ it "should pass if target responds to both messages" do
+ Object.new.should respond_to('methods', 'inspect')
+ end
+
+ it "should fail target does not respond to first message" do
+ lambda {
+ Object.new.should respond_to('method_one', 'inspect')
+ }.should fail_with('expected target to respond to "method_one"')
+ end
+
+ it "should fail target does not respond to second message" do
+ lambda {
+ Object.new.should respond_to('inspect', 'method_one')
+ }.should fail_with('expected target to respond to "method_one"')
+ end
+
+ it "should fail target does not respond to either message" do
+ lambda {
+ Object.new.should respond_to('method_one', 'method_two')
+ }.should fail_with('expected target to respond to "method_one", "method_two"')
+ end
+end
+
+describe "should_not respond_to(:sym)" do
+
+ it "should pass if target does not respond to :sym" do
+ Object.new.should_not respond_to(:some_method)
+ end
+
+ it "should fail target responds to :sym" do
+ lambda {
+ Object.new.should_not respond_to(:methods)
+ }.should fail_with("expected target not to respond to :methods")
+ end
+
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/satisfy_spec.rb b/vendor/gems/rspec/spec/spec/matchers/satisfy_spec.rb
new file mode 100644
index 000000000..7e8d6f972
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/satisfy_spec.rb
@@ -0,0 +1,36 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "should satisfy { block }" do
+ it "should pass if block returns true" do
+ true.should satisfy { |val| val }
+ true.should satisfy do |val|
+ val
+ end
+ end
+
+ it "should fail if block returns false" do
+ lambda {
+ false.should satisfy { |val| val }
+ }.should fail_with("expected false to satisfy block")
+ lambda do
+ false.should satisfy do |val|
+ val
+ end
+ end.should fail_with("expected false to satisfy block")
+ end
+end
+
+describe "should_not satisfy { block }" do
+ it "should pass if block returns false" do
+ false.should_not satisfy { |val| val }
+ false.should_not satisfy do |val|
+ val
+ end
+ end
+
+ it "should fail if block returns true" do
+ lambda {
+ true.should_not satisfy { |val| val }
+ }.should fail_with("expected true not to satisfy block")
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/matchers/simple_matcher_spec.rb b/vendor/gems/rspec/spec/spec/matchers/simple_matcher_spec.rb
new file mode 100644
index 000000000..b731af92d
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/simple_matcher_spec.rb
@@ -0,0 +1,31 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Matchers
+ describe SimpleMatcher do
+ it "should match pass match arg to block" do
+ actual = nil
+ matcher = simple_matcher("message") do |given| actual = given end
+ matcher.matches?("foo")
+ actual.should == "foo"
+ end
+
+ it "should provide a stock failure message" do
+ matcher = simple_matcher("thing") do end
+ matcher.matches?("other")
+ matcher.failure_message.should =~ /expected \"thing\" but got \"other\"/
+ end
+
+ it "should provide a stock negative failure message" do
+ matcher = simple_matcher("thing") do end
+ matcher.matches?("other")
+ matcher.negative_failure_message.should =~ /expected not to get \"thing\", but got \"other\"/
+ end
+
+ it "should provide a description" do
+ matcher = simple_matcher("thing") do end
+ matcher.description.should =="thing"
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/matchers/throw_symbol_spec.rb b/vendor/gems/rspec/spec/spec/matchers/throw_symbol_spec.rb
new file mode 100644
index 000000000..74595659a
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/matchers/throw_symbol_spec.rb
@@ -0,0 +1,54 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Matchers
+ describe ThrowSymbol, "(constructed with no Symbol)" do
+ before(:each) { @matcher = ThrowSymbol.new }
+
+ it "should match if any Symbol is thrown" do
+ @matcher.matches?(lambda{ throw :sym }).should be_true
+ end
+ it "should not match if no Symbol is thrown" do
+ @matcher.matches?(lambda{ }).should be_false
+ end
+ it "should provide a failure message" do
+ @matcher.matches?(lambda{})
+ @matcher.failure_message.should == "expected a Symbol but nothing was thrown"
+ end
+ it "should provide a negative failure message" do
+ @matcher.matches?(lambda{ throw :sym})
+ @matcher.negative_failure_message.should == "expected no Symbol, got :sym"
+ end
+ end
+
+ describe ThrowSymbol, "(constructed with a Symbol)" do
+ before(:each) { @matcher = ThrowSymbol.new(:sym) }
+
+ it "should match if correct Symbol is thrown" do
+ @matcher.matches?(lambda{ throw :sym }).should be_true
+ end
+ it "should not match if no Symbol is thrown" do
+ @matcher.matches?(lambda{ }).should be_false
+ end
+ it "should not match if correct Symbol is thrown" do
+ @matcher.matches?(lambda{ throw :other_sym }).should be_false
+ @matcher.failure_message.should == "expected :sym, got :other_sym"
+ end
+ it "should provide a failure message when no Symbol is thrown" do
+ @matcher.matches?(lambda{})
+ @matcher.failure_message.should == "expected :sym but nothing was thrown"
+ end
+ it "should provide a failure message when wrong Symbol is thrown" do
+ @matcher.matches?(lambda{ throw :other_sym })
+ @matcher.failure_message.should == "expected :sym, got :other_sym"
+ end
+ it "should provide a negative failure message" do
+ @matcher.matches?(lambda{ throw :sym })
+ @matcher.negative_failure_message.should == "expected :sym not to be thrown"
+ end
+ it "should only match NameErrors raised by uncaught throws" do
+ @matcher.matches?(lambda{ sym }).should be_false
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/any_number_of_times_spec.rb b/vendor/gems/rspec/spec/spec/mocks/any_number_of_times_spec.rb
new file mode 100644
index 000000000..3f50dcfc5
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/any_number_of_times_spec.rb
@@ -0,0 +1,29 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+
+ describe "AnyNumberOfTimes" do
+ before(:each) do
+ @mock = Mock.new("test mock")
+ end
+
+ it "should pass if any number of times method is called many times" do
+ @mock.should_receive(:random_call).any_number_of_times
+ (1..10).each do
+ @mock.random_call
+ end
+ end
+
+ it "should pass if any number of times method is called once" do
+ @mock.should_receive(:random_call).any_number_of_times
+ @mock.random_call
+ end
+
+ it "should pass if any number of times method is not called" do
+ @mock.should_receive(:random_call).any_number_of_times
+ end
+ end
+
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/argument_expectation_spec.rb b/vendor/gems/rspec/spec/spec/mocks/argument_expectation_spec.rb
new file mode 100644
index 000000000..2bebbdd4f
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/argument_expectation_spec.rb
@@ -0,0 +1,23 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+ describe ArgumentExpectation do
+ it "should consider an object that responds to #matches? and #description to be a matcher" do
+ argument_expecatation = Spec::Mocks::ArgumentExpectation.new([])
+ obj = mock("matcher")
+ obj.should_receive(:respond_to?).with(:matches?).and_return(true)
+ obj.should_receive(:respond_to?).with(:description).and_return(true)
+ argument_expecatation.is_matcher?(obj).should be_true
+ end
+
+ it "should NOT consider an object that only responds to #matches? to be a matcher" do
+ argument_expecatation = Spec::Mocks::ArgumentExpectation.new([])
+ obj = mock("matcher")
+ obj.should_receive(:respond_to?).with(:matches?).and_return(true)
+ obj.should_receive(:respond_to?).with(:description).and_return(false)
+ argument_expecatation.is_matcher?(obj).should be_false
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/at_least_spec.rb b/vendor/gems/rspec/spec/spec/mocks/at_least_spec.rb
new file mode 100644
index 000000000..01b133dc3
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/at_least_spec.rb
@@ -0,0 +1,97 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+ describe "at_least" do
+ before(:each) do
+ @mock = Mock.new("test mock")
+ end
+
+ it "should fail if method is never called" do
+ @mock.should_receive(:random_call).at_least(4).times
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should fail when called less than n times" do
+ @mock.should_receive(:random_call).at_least(4).times
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should fail when at least once method is never called" do
+ @mock.should_receive(:random_call).at_least(:once)
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should fail when at least twice method is called once" do
+ @mock.should_receive(:random_call).at_least(:twice)
+ @mock.random_call
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should fail when at least twice method is never called" do
+ @mock.should_receive(:random_call).at_least(:twice)
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should pass when at least n times method is called exactly n times" do
+ @mock.should_receive(:random_call).at_least(4).times
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ @mock.rspec_verify
+ end
+
+ it "should pass when at least n times method is called n plus 1 times" do
+ @mock.should_receive(:random_call).at_least(4).times
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ @mock.rspec_verify
+ end
+
+ it "should pass when at least once method is called once" do
+ @mock.should_receive(:random_call).at_least(:once)
+ @mock.random_call
+ @mock.rspec_verify
+ end
+
+ it "should pass when at least once method is called twice" do
+ @mock.should_receive(:random_call).at_least(:once)
+ @mock.random_call
+ @mock.random_call
+ @mock.rspec_verify
+ end
+
+ it "should pass when at least twice method is called three times" do
+ @mock.should_receive(:random_call).at_least(:twice)
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ @mock.rspec_verify
+ end
+
+ it "should pass when at least twice method is called twice" do
+ @mock.should_receive(:random_call).at_least(:twice)
+ @mock.random_call
+ @mock.random_call
+ @mock.rspec_verify
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/at_most_spec.rb b/vendor/gems/rspec/spec/spec/mocks/at_most_spec.rb
new file mode 100644
index 000000000..f3c5e2150
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/at_most_spec.rb
@@ -0,0 +1,93 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+ describe "at_most" do
+ before(:each) do
+ @mock = Mock.new("test mock")
+ end
+
+ it "should fail when at most n times method is called n plus 1 times" do
+ @mock.should_receive(:random_call).at_most(4).times
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should fail when at most once method is called twice" do
+ @mock.should_receive(:random_call).at_most(:once)
+ @mock.random_call
+ @mock.random_call
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should fail when at most twice method is called three times" do
+ @mock.should_receive(:random_call).at_most(:twice)
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should pass when at most n times method is called exactly n times" do
+ @mock.should_receive(:random_call).at_most(4).times
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ @mock.rspec_verify
+ end
+
+ it "should pass when at most n times method is called less than n times" do
+ @mock.should_receive(:random_call).at_most(4).times
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ @mock.rspec_verify
+ end
+
+ it "should pass when at most n times method is never called" do
+ @mock.should_receive(:random_call).at_most(4).times
+ @mock.rspec_verify
+ end
+
+ it "should pass when at most once method is called once" do
+ @mock.should_receive(:random_call).at_most(:once)
+ @mock.random_call
+ @mock.rspec_verify
+ end
+
+ it "should pass when at most once method is never called" do
+ @mock.should_receive(:random_call).at_most(:once)
+ @mock.rspec_verify
+ end
+
+ it "should pass when at most twice method is called once" do
+ @mock.should_receive(:random_call).at_most(:twice)
+ @mock.random_call
+ @mock.rspec_verify
+ end
+
+ it "should pass when at most twice method is called twice" do
+ @mock.should_receive(:random_call).at_most(:twice)
+ @mock.random_call
+ @mock.random_call
+ @mock.rspec_verify
+ end
+
+ it "should pass when at most twice method is never called" do
+ @mock.should_receive(:random_call).at_most(:twice)
+ @mock.rspec_verify
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/bug_report_10260_spec.rb b/vendor/gems/rspec/spec/spec/mocks/bug_report_10260_spec.rb
new file mode 100644
index 000000000..2f7b5803d
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/bug_report_10260_spec.rb
@@ -0,0 +1,8 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "An RSpec Mock" do
+ it "should hide internals in its inspect representation" do
+ m = mock('cup')
+ m.inspect.should =~ /#<Spec::Mocks::Mock:0x[a-f0-9.]+ @name="cup">/
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/bug_report_10263.rb b/vendor/gems/rspec/spec/spec/mocks/bug_report_10263.rb
new file mode 100644
index 000000000..e32192257
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/bug_report_10263.rb
@@ -0,0 +1,24 @@
+describe "Mock" do
+ before do
+ @mock = mock("test mock")
+ end
+
+ specify "when one example has an expectation (non-mock) inside the block passed to the mock" do
+ @mock.should_receive(:msg) do |b|
+ b.should be_true #this call exposes the problem
+ end
+ @mock.msg(false) rescue nil
+ end
+
+ specify "then the next example should behave as expected instead of saying" do
+ @mock.should_receive(:foobar)
+ @mock.foobar
+ @mock.rspec_verify
+ begin
+ @mock.foobar
+ rescue Exception => e
+ e.message.should == "Mock 'test mock' received unexpected message :foobar with (no args)"
+ end
+ end
+end
+
diff --git a/vendor/gems/rspec/spec/spec/mocks/bug_report_11545_spec.rb b/vendor/gems/rspec/spec/spec/mocks/bug_report_11545_spec.rb
new file mode 100644
index 000000000..8a334afa5
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/bug_report_11545_spec.rb
@@ -0,0 +1,31 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+class LiarLiarPantsOnFire
+ def respond_to?(sym)
+ true
+ end
+
+ def self.respond_to?(sym)
+ true
+ end
+end
+
+describe 'should_receive' do
+ before(:each) do
+ @liar = LiarLiarPantsOnFire.new
+ end
+
+ it "should work when object lies about responding to a method" do
+ @liar.should_receive(:something)
+ @liar.something
+ end
+
+ it 'should work when class lies about responding to a method' do
+ LiarLiarPantsOnFire.should_receive(:something)
+ LiarLiarPantsOnFire.something
+ end
+
+ it 'should cleanup after itself' do
+ LiarLiarPantsOnFire.metaclass.instance_methods.should_not include("something")
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/bug_report_15719_spec.rb b/vendor/gems/rspec/spec/spec/mocks/bug_report_15719_spec.rb
new file mode 100644
index 000000000..82d49ea97
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/bug_report_15719_spec.rb
@@ -0,0 +1,30 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+ describe "mock failure" do
+
+ it "should tell you when it receives the right message with the wrong args" do
+ m = mock("foo")
+ m.should_receive(:bar).with("message")
+ lambda {
+ m.bar("different message")
+ }.should raise_error(Spec::Mocks::MockExpectationError, %Q{Mock 'foo' expected :bar with ("message") but received it with ("different message")})
+ m.bar("message") # allows the spec to pass
+ end
+
+ it "should tell you when it receives the right message with the wrong args if you stub the method" do
+ pending("fix bug 15719")
+ # NOTE - for whatever reason, if you use a the block style of pending here,
+ # rcov gets unhappy. Don't know why yet.
+ m = mock("foo")
+ m.stub!(:bar)
+ m.should_receive(:bar).with("message")
+ lambda {
+ m.bar("different message")
+ }.should raise_error(Spec::Mocks::MockExpectationError, %Q{Mock 'foo' expected :bar with ("message") but received it with ("different message")})
+ m.bar("message") # allows the spec to pass
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/mocks/bug_report_7611_spec.rb b/vendor/gems/rspec/spec/spec/mocks/bug_report_7611_spec.rb
new file mode 100644
index 000000000..6c9705bcc
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/bug_report_7611_spec.rb
@@ -0,0 +1,19 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Bug7611
+ class Foo
+ end
+
+ class Bar < Foo
+ end
+
+ describe "A Partial Mock" do
+ it "should respect subclasses" do
+ Foo.stub!(:new).and_return(Object.new)
+ end
+
+ it "should" do
+ Bar.new.class.should == Bar
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/bug_report_7805_spec.rb b/vendor/gems/rspec/spec/spec/mocks/bug_report_7805_spec.rb
new file mode 100644
index 000000000..f7edfac17
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/bug_report_7805_spec.rb
@@ -0,0 +1,22 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Bug7805
+ #This is really a duplicate of 8302
+
+ describe "Stubs should correctly restore module methods" do
+ it "1 - stub the open method" do
+ File.stub!(:open).and_return("something")
+ File.open.should == "something"
+ end
+ it "2 - use File.open to create example.txt" do
+ filename = "#{File.dirname(__FILE__)}/example-#{Time.new.to_i}.txt"
+ File.exist?(filename).should be_false
+ file = File.open(filename,'w')
+ file.close
+ File.exist?(filename).should be_true
+ File.delete(filename)
+ File.exist?(filename).should be_false
+ end
+ end
+
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/bug_report_8165_spec.rb b/vendor/gems/rspec/spec/spec/mocks/bug_report_8165_spec.rb
new file mode 100644
index 000000000..7edc3c076
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/bug_report_8165_spec.rb
@@ -0,0 +1,31 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "An object where respond_to? is true and does not have method" do
+ # When should_receive(:sym) is sent to any object, the Proxy sends
+ # respond_to?(:sym) to that object to see if the method should be proxied.
+ #
+ # If respond_to? itself is proxied, then when the Proxy sends respond_to?
+ # to the object, the proxy is invoked and responds yes (if so set in the spec).
+ # When the object does NOT actually respond to :sym, an exception is thrown
+ # when trying to proxy it.
+ #
+ # The fix was to keep track of whether :respond_to? had been proxied and, if
+ # so, call the munged copy of :respond_to? on the object.
+
+ it "should not raise an exception for Object" do
+ obj = Object.new
+ obj.should_receive(:respond_to?).with(:foobar).and_return(true)
+ obj.should_receive(:foobar).and_return(:baz)
+ obj.respond_to?(:foobar).should be_true
+ obj.foobar.should == :baz
+ end
+
+ it "should not raise an exception for mock" do
+ obj = mock("obj")
+ obj.should_receive(:respond_to?).with(:foobar).and_return(true)
+ obj.should_receive(:foobar).and_return(:baz)
+ obj.respond_to?(:foobar).should be_true
+ obj.foobar.should == :baz
+ end
+
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/bug_report_8302_spec.rb b/vendor/gems/rspec/spec/spec/mocks/bug_report_8302_spec.rb
new file mode 100644
index 000000000..a41df43d8
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/bug_report_8302_spec.rb
@@ -0,0 +1,26 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Bug8302
+ class Foo
+ def Foo.class_method(arg)
+ end
+
+ def instance_bar(arg)
+ end
+ end
+
+ describe "Bug report 8302:" do
+ it "class method is not restored correctly when proxied" do
+ Foo.should_not_receive(:class_method).with(Array.new)
+ Foo.rspec_verify
+ Foo.class_method(Array.new)
+ end
+
+ it "instance method is not restored correctly when proxied" do
+ foo = Foo.new
+ foo.should_not_receive(:instance_bar).with(Array.new)
+ foo.rspec_verify
+ foo.instance_bar(Array.new)
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/failing_mock_argument_constraints_spec.rb b/vendor/gems/rspec/spec/spec/mocks/failing_mock_argument_constraints_spec.rb
new file mode 100644
index 000000000..db6dcea34
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/failing_mock_argument_constraints_spec.rb
@@ -0,0 +1,115 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+ describe "failing MockArgumentConstraints" do
+ before(:each) do
+ @mock = mock("test mock")
+ @reporter = Mock.new("reporter", :null_object => true)
+ end
+
+ after(:each) do
+ @mock.rspec_reset
+ end
+
+ it "should reject non boolean" do
+ @mock.should_receive(:random_call).with(boolean())
+ lambda do
+ @mock.random_call("false")
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should reject non numeric" do
+ @mock.should_receive(:random_call).with(an_instance_of(Numeric))
+ lambda do
+ @mock.random_call("1")
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should reject non string" do
+ @mock.should_receive(:random_call).with(an_instance_of(String))
+ lambda do
+ @mock.random_call(123)
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should reject goose when expecting a duck" do
+ @mock.should_receive(:random_call).with(duck_type(:abs, :div))
+ lambda { @mock.random_call("I don't respond to :abs or :div") }.should raise_error(MockExpectationError)
+ end
+
+ it "should fail if regexp does not match submitted string" do
+ @mock.should_receive(:random_call).with(/bcd/)
+ lambda { @mock.random_call("abc") }.should raise_error(MockExpectationError)
+ end
+
+ it "should fail if regexp does not match submitted regexp" do
+ @mock.should_receive(:random_call).with(/bcd/)
+ lambda { @mock.random_call(/bcde/) }.should raise_error(MockExpectationError)
+ end
+
+ it "should fail for a hash w/ wrong values" do
+ @mock.should_receive(:random_call).with(:a => "b", :c => "d")
+ lambda do
+ @mock.random_call(:a => "b", :c => "e")
+ end.should raise_error(MockExpectationError, /Mock 'test mock' expected :random_call with \(\{(:a=>\"b\", :c=>\"d\"|:c=>\"d\", :a=>\"b\")\}\) but received it with \(\{(:a=>\"b\", :c=>\"e\"|:c=>\"e\", :a=>\"b\")\}\)/)
+ end
+
+ it "should fail for a hash w/ wrong keys" do
+ @mock.should_receive(:random_call).with(:a => "b", :c => "d")
+ lambda do
+ @mock.random_call("a" => "b", "c" => "d")
+ end.should raise_error(MockExpectationError, /Mock 'test mock' expected :random_call with \(\{(:a=>\"b\", :c=>\"d\"|:c=>\"d\", :a=>\"b\")\}\) but received it with \(\{(\"a\"=>\"b\", \"c\"=>\"d\"|\"c\"=>\"d\", \"a\"=>\"b\")\}\)/)
+ end
+
+ it "should match against a Matcher" do
+ lambda do
+ @mock.should_receive(:msg).with(equal(3))
+ @mock.msg(37)
+ end.should raise_error(MockExpectationError, "Mock 'test mock' expected :msg with (equal 3) but received it with (37)")
+ end
+
+ it "should fail no_args with one arg" do
+ lambda do
+ @mock.should_receive(:msg).with(no_args)
+ @mock.msg(37)
+ end.should raise_error(MockExpectationError, "Mock 'test mock' expected :msg with (no args) but received it with (37)")
+ end
+ end
+
+ describe "failing deprecated MockArgumentConstraints" do
+ before(:each) do
+ @mock = mock("test mock")
+ @reporter = Mock.new("reporter", :null_object => true)
+ Kernel.stub!(:warn)
+ end
+
+ after(:each) do
+ @mock.rspec_reset
+ end
+
+ it "should reject non boolean" do
+ @mock.should_receive(:random_call).with(:boolean)
+ lambda do
+ @mock.random_call("false")
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should reject non numeric" do
+ @mock.should_receive(:random_call).with(:numeric)
+ lambda do
+ @mock.random_call("1")
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should reject non string" do
+ @mock.should_receive(:random_call).with(:string)
+ lambda do
+ @mock.random_call(123)
+ end.should raise_error(MockExpectationError)
+ end
+
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/mock_ordering_spec.rb b/vendor/gems/rspec/spec/spec/mocks/mock_ordering_spec.rb
new file mode 100644
index 000000000..919da2970
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/mock_ordering_spec.rb
@@ -0,0 +1,84 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Mocks
+
+ describe "Mock ordering" do
+
+ before do
+ @mock = mock("test mock")
+ end
+
+ after do
+ @mock.rspec_reset
+ end
+
+ it "should pass two calls in order" do
+ @mock.should_receive(:one).ordered
+ @mock.should_receive(:two).ordered
+ @mock.one
+ @mock.two
+ @mock.rspec_verify
+ end
+
+ it "should pass three calls in order" do
+ @mock.should_receive(:one).ordered
+ @mock.should_receive(:two).ordered
+ @mock.should_receive(:three).ordered
+ @mock.one
+ @mock.two
+ @mock.three
+ @mock.rspec_verify
+ end
+
+ it "should fail if second call comes first" do
+ @mock.should_receive(:one).ordered
+ @mock.should_receive(:two).ordered
+ lambda do
+ @mock.two
+ end.should raise_error(MockExpectationError, "Mock 'test mock' received :two out of order")
+ end
+
+ it "should fail if third call comes first" do
+ @mock.should_receive(:one).ordered
+ @mock.should_receive(:two).ordered
+ @mock.should_receive(:three).ordered
+ @mock.one
+ lambda do
+ @mock.three
+ end.should raise_error(MockExpectationError, "Mock 'test mock' received :three out of order")
+ end
+
+ it "should fail if third call comes second" do
+ @mock.should_receive(:one).ordered
+ @mock.should_receive(:two).ordered
+ @mock.should_receive(:three).ordered
+ @mock.one
+ lambda do
+ @mock.three
+ end.should raise_error(MockExpectationError, "Mock 'test mock' received :three out of order")
+ end
+
+ it "should ignore order of non ordered calls" do
+ @mock.should_receive(:ignored_0)
+ @mock.should_receive(:ordered_1).ordered
+ @mock.should_receive(:ignored_1)
+ @mock.should_receive(:ordered_2).ordered
+ @mock.should_receive(:ignored_2)
+ @mock.should_receive(:ignored_3)
+ @mock.should_receive(:ordered_3).ordered
+ @mock.should_receive(:ignored_4)
+ @mock.ignored_3
+ @mock.ordered_1
+ @mock.ignored_0
+ @mock.ordered_2
+ @mock.ignored_4
+ @mock.ignored_2
+ @mock.ordered_3
+ @mock.ignored_1
+ @mock.rspec_verify
+ end
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/mock_space_spec.rb b/vendor/gems/rspec/spec/spec/mocks/mock_space_spec.rb
new file mode 100644
index 000000000..23ffd01bc
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/mock_space_spec.rb
@@ -0,0 +1,54 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+require 'spec/mocks'
+
+module Spec
+ module Mocks
+ describe Space do
+ before :each do
+ @space = Space.new
+ klazz = Class.new do
+ def rspec_verify
+ @verified = true
+ end
+ def verified?
+ @verified
+ end
+ def rspec_reset
+ @reset = true
+ end
+ def reset?
+ @reset
+ end
+ end
+ @m1 = klazz.new
+ @m2 = klazz.new
+ end
+ it "should verify all mocks within" do
+ @space.add(@m1)
+ @space.add(@m2)
+ @space.verify_all
+ @m1.should be_verified
+ @m2.should be_verified
+ end
+ it "should reset all mocks within" do
+ @space.add(m1 = mock("mock1"))
+ @space.add(m2 = mock("mock2"))
+ m1.should_receive(:rspec_reset)
+ m2.should_receive(:rspec_reset)
+ @space.reset_all
+ end
+ it "should clear internal mocks on reset_all" do
+ @space.add(m = mock("mock"))
+ @space.reset_all
+ @space.instance_eval { mocks.empty? }.should be_true
+ end
+ it "should only add an instance once" do
+ @space.add(m1 = mock("mock1"))
+ @space.add(m1)
+ m1.should_receive(:rspec_verify)
+ @space.verify_all
+ end
+ end
+ end
+end
+
diff --git a/vendor/gems/rspec/spec/spec/mocks/mock_spec.rb b/vendor/gems/rspec/spec/spec/mocks/mock_spec.rb
new file mode 100644
index 000000000..85a71e327
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/mock_spec.rb
@@ -0,0 +1,475 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Mocks
+ describe Mock do
+
+ before(:each) do
+ @mock = mock("test mock")
+ end
+
+ after(:each) do
+ @mock.rspec_reset
+ end
+
+ it "should report line number of expectation of unreceived message" do
+ expected_error_line = __LINE__; @mock.should_receive(:wont_happen).with("x", 3)
+ begin
+ @mock.rspec_verify
+ violated
+ rescue MockExpectationError => e
+ # NOTE - this regexp ended w/ $, but jruby adds extra info at the end of the line
+ e.backtrace[0].should match(/#{File.basename(__FILE__)}:#{expected_error_line}/)
+ end
+ end
+
+ it "should pass when not receiving message specified as not to be received" do
+ @mock.should_not_receive(:not_expected)
+ @mock.rspec_verify
+ end
+
+ it "should pass when receiving message specified as not to be received with different args" do
+ @mock.should_not_receive(:message).with("unwanted text")
+ @mock.should_receive(:message).with("other text")
+ @mock.message "other text"
+ @mock.rspec_verify
+ end
+
+ it "should fail when receiving message specified as not to be received" do
+ @mock.should_not_receive(:not_expected)
+ @mock.not_expected
+ lambda {
+ @mock.rspec_verify
+ violated
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (any args) 0 times, but received it once")
+ end
+
+ it "should fail when receiving message specified as not to be received with args" do
+ @mock.should_not_receive(:not_expected).with("unexpected text")
+ @mock.not_expected("unexpected text")
+ lambda {
+ @mock.rspec_verify
+ violated
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (\"unexpected text\") 0 times, but received it once")
+ end
+
+ it "should pass when receiving message specified as not to be received with wrong args" do
+ @mock.should_not_receive(:not_expected).with("unexpected text")
+ @mock.not_expected "really unexpected text"
+ @mock.rspec_verify
+ end
+
+ it "should allow block to calculate return values" do
+ @mock.should_receive(:something).with("a","b","c").and_return { |a,b,c| c+b+a }
+ @mock.something("a","b","c").should == "cba"
+ @mock.rspec_verify
+ end
+
+ it "should allow parameter as return value" do
+ @mock.should_receive(:something).with("a","b","c").and_return("booh")
+ @mock.something("a","b","c").should == "booh"
+ @mock.rspec_verify
+ end
+
+ it "should return nil if no return value set" do
+ @mock.should_receive(:something).with("a","b","c")
+ @mock.something("a","b","c").should be_nil
+ @mock.rspec_verify
+ end
+
+ it "should raise exception if args dont match when method called" do
+ @mock.should_receive(:something).with("a","b","c").and_return("booh")
+ lambda {
+ @mock.something("a","d","c")
+ violated
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (\"a\", \"b\", \"c\") but received it with (\"a\", \"d\", \"c\")")
+ end
+
+ it "should fail if unexpected method called" do
+ lambda {
+ @mock.something("a","b","c")
+ violated
+ }.should raise_error(MockExpectationError, "Mock 'test mock' received unexpected message :something with (\"a\", \"b\", \"c\")")
+ end
+
+ it "should use block for expectation if provided" do
+ @mock.should_receive(:something) do | a, b |
+ a.should == "a"
+ b.should == "b"
+ "booh"
+ end
+ @mock.something("a", "b").should == "booh"
+ @mock.rspec_verify
+ end
+
+ it "should fail if expectation block fails" do
+ @mock.should_receive(:something) {| bool | bool.should be_true}
+ lambda {
+ @mock.something false
+ }.should raise_error(MockExpectationError, /Mock 'test mock' received :something but passed block failed with: expected true, got false/)
+ end
+
+ it "should fail right away when method defined as never is received" do
+ pending "Used to pass (false positive). Which one is wrong, the spec or the actual behavior?"
+
+ @mock.should_receive(:not_expected).never
+ lambda {
+ @mock.not_expected
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected 0 times, but received it 1 times")
+ end
+
+ it "should eventually fail when method defined as never is received" do
+ @mock.should_receive(:not_expected).never
+ @mock.not_expected
+
+ lambda {
+ @mock.rspec_verify
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (any args) 0 times, but received it once")
+ end
+
+ it "should raise when told to" do
+ @mock.should_receive(:something).and_raise(RuntimeError)
+ lambda do
+ @mock.something
+ end.should raise_error(RuntimeError)
+ end
+
+ it "should raise passed an Exception instance" do
+ error = RuntimeError.new("error message")
+ @mock.should_receive(:something).and_raise(error)
+ lambda {
+ @mock.something
+ }.should raise_error(RuntimeError, "error message")
+ end
+
+ it "should raise RuntimeError with passed message" do
+ @mock.should_receive(:something).and_raise("error message")
+ lambda {
+ @mock.something
+ }.should raise_error(RuntimeError, "error message")
+ end
+
+ it "should not raise when told to if args dont match" do
+ @mock.should_receive(:something).with(2).and_raise(RuntimeError)
+ lambda {
+ @mock.something 1
+ }.should raise_error(MockExpectationError)
+ end
+
+ it "should throw when told to" do
+ @mock.should_receive(:something).and_throw(:blech)
+ lambda {
+ @mock.something
+ }.should throw_symbol(:blech)
+ end
+
+ it "should raise when explicit return and block constrained" do
+ lambda {
+ @mock.should_receive(:fruit) do |colour|
+ :strawberry
+ end.and_return :apple
+ }.should raise_error(AmbiguousReturnError)
+ end
+
+ it "should ignore args on any args" do
+ @mock.should_receive(:something).at_least(:once).with(any_args)
+ @mock.something
+ @mock.something 1
+ @mock.something "a", 2
+ @mock.something [], {}, "joe", 7
+ @mock.rspec_verify
+ end
+
+ it "should fail on no args if any args received" do
+ @mock.should_receive(:something).with(no_args())
+ lambda {
+ @mock.something 1
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (no args) but received it with (1)")
+ end
+
+ it "should fail when args are expected but none are received" do
+ @mock.should_receive(:something).with(1)
+ lambda {
+ @mock.something
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (1) but received it with (no args)")
+ end
+
+ it "should yield 0 args to blocks that take a variable number of arguments" do
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield
+ a = nil
+ @mock.yield_back {|*a|}
+ a.should == []
+ @mock.rspec_verify
+ end
+
+ it "should yield 0 args multiple times to blocks that take a variable number of arguments" do
+ @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield.
+ and_yield
+ a = nil
+ b = []
+ @mock.yield_back {|*a| b << a}
+ b.should == [ [], [] ]
+ @mock.rspec_verify
+ end
+
+ it "should yield one arg to blocks that take a variable number of arguments" do
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99)
+ a = nil
+ @mock.yield_back {|*a|}
+ a.should == [99]
+ @mock.rspec_verify
+ end
+
+ it "should yield one arg 3 times consecutively to blocks that take a variable number of arguments" do
+ @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield(99).
+ and_yield(43).
+ and_yield("something fruity")
+ a = nil
+ b = []
+ @mock.yield_back {|*a| b << a}
+ b.should == [[99], [43], ["something fruity"]]
+ @mock.rspec_verify
+ end
+
+ it "should yield many args to blocks that take a variable number of arguments" do
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99, 27, "go")
+ a = nil
+ @mock.yield_back {|*a|}
+ a.should == [99, 27, "go"]
+ @mock.rspec_verify
+ end
+
+ it "should yield many args 3 times consecutively to blocks that take a variable number of arguments" do
+ @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield(99, :green, "go").
+ and_yield("wait", :amber).
+ and_yield("stop", 12, :red)
+ a = nil
+ b = []
+ @mock.yield_back {|*a| b << a}
+ b.should == [[99, :green, "go"], ["wait", :amber], ["stop", 12, :red]]
+ @mock.rspec_verify
+ end
+
+ it "should yield single value" do
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99)
+ a = nil
+ @mock.yield_back {|a|}
+ a.should == 99
+ @mock.rspec_verify
+ end
+
+ it "should yield single value 3 times consecutively" do
+ @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield(99).
+ and_yield(43).
+ and_yield("something fruity")
+ a = nil
+ b = []
+ @mock.yield_back {|a| b << a}
+ b.should == [99, 43, "something fruity"]
+ @mock.rspec_verify
+ end
+
+ it "should yield two values" do
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
+ a, b = nil
+ @mock.yield_back {|a,b|}
+ a.should == 'wha'
+ b.should == 'zup'
+ @mock.rspec_verify
+ end
+
+ it "should yield two values 3 times consecutively" do
+ @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield('wha', 'zup').
+ and_yield('not', 'down').
+ and_yield(14, 65)
+ a, b = nil
+ c = []
+ @mock.yield_back {|a,b| c << [a, b]}
+ c.should == [['wha', 'zup'], ['not', 'down'], [14, 65]]
+ @mock.rspec_verify
+ end
+
+ it "should fail when calling yielding method with wrong arity" do
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
+ lambda {
+ @mock.yield_back {|a|}
+ }.should raise_error(MockExpectationError, "Mock 'test mock' yielded |\"wha\", \"zup\"| to block with arity of 1")
+ end
+
+ it "should fail when calling yielding method consecutively with wrong arity" do
+ @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield('wha', 'zup').
+ and_yield('down').
+ and_yield(14, 65)
+ lambda {
+ a, b = nil
+ c = []
+ @mock.yield_back {|a,b| c << [a, b]}
+ }.should raise_error(MockExpectationError, "Mock 'test mock' yielded |\"down\"| to block with arity of 2")
+ end
+
+ it "should fail when calling yielding method without block" do
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
+ lambda {
+ @mock.yield_back
+ }.should raise_error(MockExpectationError, "Mock 'test mock' asked to yield |[\"wha\", \"zup\"]| but no block was passed")
+ end
+
+ it "should be able to mock send" do
+ @mock.should_receive(:send).with(any_args)
+ @mock.send 'hi'
+ @mock.rspec_verify
+ end
+
+ it "should be able to raise from method calling yielding mock" do
+ @mock.should_receive(:yield_me).and_yield 44
+
+ lambda {
+ @mock.yield_me do |x|
+ raise "Bang"
+ end
+ }.should raise_error(StandardError, "Bang")
+
+ @mock.rspec_verify
+ end
+
+ it "should clear expectations after verify" do
+ @mock.should_receive(:foobar)
+ @mock.foobar
+ @mock.rspec_verify
+ lambda {
+ @mock.foobar
+ }.should raise_error(MockExpectationError, "Mock 'test mock' received unexpected message :foobar with (no args)")
+ end
+
+ it "should restore objects to their original state on rspec_reset" do
+ mock = mock("this is a mock")
+ mock.should_receive(:blah)
+ mock.rspec_reset
+ mock.rspec_verify #should throw if reset didn't work
+ end
+
+ it "should work even after method_missing starts raising NameErrors instead of NoMethodErrors" do
+ # Object#method_missing throws either NameErrors or NoMethodErrors.
+ #
+ # On a fresh ruby program Object#method_missing:
+ # * raises a NoMethodError when called directly
+ # * raises a NameError when called indirectly
+ #
+ # Once Object#method_missing has been called at least once (on any object)
+ # it starts behaving differently:
+ # * raises a NameError when called directly
+ # * raises a NameError when called indirectly
+ #
+ # There was a bug in Mock#method_missing that relied on the fact
+ # that calling Object#method_missing directly raises a NoMethodError.
+ # This example tests that the bug doesn't exist anymore.
+
+
+ # Ensures that method_missing always raises NameErrors.
+ a_method_that_doesnt_exist rescue
+
+
+ @mock.should_receive(:foobar)
+ @mock.foobar
+ @mock.rspec_verify
+
+ lambda { @mock.foobar }.should_not raise_error(NameError)
+ lambda { @mock.foobar }.should raise_error(MockExpectationError)
+ end
+
+ it "should temporarily replace a method stub on a mock" do
+ @mock.stub!(:msg).and_return(:stub_value)
+ @mock.should_receive(:msg).with(:arg).and_return(:mock_value)
+ @mock.msg(:arg).should equal(:mock_value)
+ @mock.msg.should equal(:stub_value)
+ @mock.msg.should equal(:stub_value)
+ @mock.rspec_verify
+ end
+
+ it "should temporarily replace a method stub on a non-mock" do
+ non_mock = Object.new
+ non_mock.stub!(:msg).and_return(:stub_value)
+ non_mock.should_receive(:msg).with(:arg).and_return(:mock_value)
+ non_mock.msg(:arg).should equal(:mock_value)
+ non_mock.msg.should equal(:stub_value)
+ non_mock.msg.should equal(:stub_value)
+ non_mock.rspec_verify
+ end
+
+ it "should assign stub return values" do
+ mock = Mock.new('name', :message => :response)
+ mock.message.should == :response
+ end
+ end
+
+ describe "a mock message receiving a block" do
+ before(:each) do
+ @mock = mock("mock")
+ @calls = 0
+ end
+
+ def add_call
+ @calls = @calls + 1
+ end
+
+ it "should call the block after #should_receive" do
+ @mock.should_receive(:foo) { add_call }
+
+ @mock.foo
+
+ @calls.should == 1
+ end
+
+ it "should call the block after #once" do
+ @mock.should_receive(:foo).once { add_call }
+
+ @mock.foo
+
+ @calls.should == 1
+ end
+
+ it "should call the block after #twice" do
+ @mock.should_receive(:foo).twice { add_call }
+
+ @mock.foo
+ @mock.foo
+
+ @calls.should == 2
+ end
+
+ it "should call the block after #times" do
+ @mock.should_receive(:foo).exactly(10).times { add_call }
+
+ (1..10).each { @mock.foo }
+
+ @calls.should == 10
+ end
+
+ it "should call the block after #any_number_of_times" do
+ @mock.should_receive(:foo).any_number_of_times { add_call }
+
+ (1..7).each { @mock.foo }
+
+ @calls.should == 7
+ end
+
+ it "should call the block after #with" do
+ @mock.should_receive(:foo).with(:arg) { add_call }
+
+ @mock.foo(:arg)
+
+ @calls.should == 1
+ end
+
+ it "should call the block after #ordered" do
+ @mock.should_receive(:foo).ordered { add_call }
+ @mock.should_receive(:bar).ordered { add_call }
+
+ @mock.foo
+ @mock.bar
+
+ @calls.should == 2
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/multiple_return_value_spec.rb b/vendor/gems/rspec/spec/spec/mocks/multiple_return_value_spec.rb
new file mode 100644
index 000000000..3e26b73f4
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/multiple_return_value_spec.rb
@@ -0,0 +1,113 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Mocks
+ describe "a Mock expectation with multiple return values and no specified count" do
+ before(:each) do
+ @mock = Mock.new("mock")
+ @return_values = ["1",2,Object.new]
+ @mock.should_receive(:message).and_return(@return_values[0],@return_values[1],@return_values[2])
+ end
+
+ it "should return values in order to consecutive calls" do
+ @mock.message.should == @return_values[0]
+ @mock.message.should == @return_values[1]
+ @mock.message.should == @return_values[2]
+ @mock.rspec_verify
+ end
+
+ it "should complain when there are too few calls" do
+ third = Object.new
+ @mock.message.should == @return_values[0]
+ @mock.message.should == @return_values[1]
+ lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (any args) 3 times, but received it twice")
+ end
+
+ it "should complain when there are too many calls" do
+ third = Object.new
+ @mock.message.should == @return_values[0]
+ @mock.message.should == @return_values[1]
+ @mock.message.should == @return_values[2]
+ @mock.message.should == @return_values[2]
+ lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (any args) 3 times, but received it 4 times")
+ end
+ end
+
+ describe "a Mock expectation with multiple return values with a specified count equal to the number of values" do
+ before(:each) do
+ @mock = Mock.new("mock")
+ @return_values = ["1",2,Object.new]
+ @mock.should_receive(:message).exactly(3).times.and_return(@return_values[0],@return_values[1],@return_values[2])
+ end
+
+ it "should return values in order to consecutive calls" do
+ @mock.message.should == @return_values[0]
+ @mock.message.should == @return_values[1]
+ @mock.message.should == @return_values[2]
+ @mock.rspec_verify
+ end
+
+ it "should complain when there are too few calls" do
+ third = Object.new
+ @mock.message.should == @return_values[0]
+ @mock.message.should == @return_values[1]
+ lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (any args) 3 times, but received it twice")
+ end
+
+ it "should complain when there are too many calls" do
+ third = Object.new
+ @mock.message.should == @return_values[0]
+ @mock.message.should == @return_values[1]
+ @mock.message.should == @return_values[2]
+ @mock.message.should == @return_values[2]
+ lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (any args) 3 times, but received it 4 times")
+ end
+ end
+
+ describe "a Mock expectation with multiple return values specifying at_least less than the number of values" do
+ before(:each) do
+ @mock = Mock.new("mock")
+ @mock.should_receive(:message).at_least(:twice).with(no_args).and_return(11, 22)
+ end
+
+ it "should use last return value for subsequent calls" do
+ @mock.message.should equal(11)
+ @mock.message.should equal(22)
+ @mock.message.should equal(22)
+ @mock.rspec_verify
+ end
+
+ it "should fail when called less than the specified number" do
+ @mock.message.should equal(11)
+ lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (no args) twice, but received it once")
+ end
+ end
+ describe "a Mock expectation with multiple return values with a specified count larger than the number of values" do
+ before(:each) do
+ @mock = Mock.new("mock")
+ @mock.should_receive(:message).exactly(3).times.and_return(11, 22)
+ end
+
+ it "should use last return value for subsequent calls" do
+ @mock.message.should equal(11)
+ @mock.message.should equal(22)
+ @mock.message.should equal(22)
+ @mock.rspec_verify
+ end
+
+ it "should fail when called less than the specified number" do
+ @mock.message.should equal(11)
+ lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (any args) 3 times, but received it once")
+ end
+
+ it "should fail when called greater than the specified number" do
+ @mock.message.should equal(11)
+ @mock.message.should equal(22)
+ @mock.message.should equal(22)
+ @mock.message.should equal(22)
+ lambda { @mock.rspec_verify }.should raise_error(MockExpectationError, "Mock 'mock' expected :message with (any args) 3 times, but received it 4 times")
+ end
+ end
+ end
+end
+
diff --git a/vendor/gems/rspec/spec/spec/mocks/null_object_mock_spec.rb b/vendor/gems/rspec/spec/spec/mocks/null_object_mock_spec.rb
new file mode 100644
index 000000000..57e8ca31c
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/null_object_mock_spec.rb
@@ -0,0 +1,40 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+ describe "a mock acting as a NullObject" do
+ before(:each) do
+ @mock = Mock.new("null_object", :null_object => true)
+ end
+
+ it "should allow explicit expectation" do
+ @mock.should_receive(:something)
+ @mock.something
+ end
+
+ it "should fail verification when explicit exception not met" do
+ lambda do
+ @mock.should_receive(:something)
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should ignore unexpected methods" do
+ @mock.random_call("a", "d", "c")
+ @mock.rspec_verify
+ end
+
+ it "should expected message with different args first" do
+ @mock.should_receive(:message).with(:expected_arg)
+ @mock.message(:unexpected_arg)
+ @mock.message(:expected_arg)
+ end
+
+ it "should expected message with different args second" do
+ @mock.should_receive(:message).with(:expected_arg)
+ @mock.message(:expected_arg)
+ @mock.message(:unexpected_arg)
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/once_counts_spec.rb b/vendor/gems/rspec/spec/spec/mocks/once_counts_spec.rb
new file mode 100644
index 000000000..2c15d5c2e
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/once_counts_spec.rb
@@ -0,0 +1,53 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+ describe "OnceCounts" do
+ before(:each) do
+ @mock = mock("test mock")
+ end
+
+ it "once should fail when called once with wrong args" do
+ @mock.should_receive(:random_call).once.with("a", "b", "c")
+ lambda do
+ @mock.random_call("d", "e", "f")
+ end.should raise_error(MockExpectationError)
+ @mock.rspec_reset
+ end
+
+ it "once should fail when called twice" do
+ @mock.should_receive(:random_call).once
+ @mock.random_call
+ @mock.random_call
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "once should fail when not called" do
+ @mock.should_receive(:random_call).once
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "once should pass when called once" do
+ @mock.should_receive(:random_call).once
+ @mock.random_call
+ @mock.rspec_verify
+ end
+
+ it "once should pass when called once with specified args" do
+ @mock.should_receive(:random_call).once.with("a", "b", "c")
+ @mock.random_call("a", "b", "c")
+ @mock.rspec_verify
+ end
+
+ it "once should pass when called once with unspecified args" do
+ @mock.should_receive(:random_call).once
+ @mock.random_call("a", "b", "c")
+ @mock.rspec_verify
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/options_hash_spec.rb b/vendor/gems/rspec/spec/spec/mocks/options_hash_spec.rb
new file mode 100644
index 000000000..0bfab26d7
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/options_hash_spec.rb
@@ -0,0 +1,45 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+ describe "calling :should_receive with an options hash" do
+ it_should_behave_like "sandboxed rspec_options"
+ attr_reader :reporter, :example_group
+ before do
+ @reporter = ::Spec::Runner::Reporter.new(options)
+ @example_group = Class.new(::Spec::Example::ExampleGroup) do
+ plugin_mock_framework
+ describe("Some Examples")
+ end
+ reporter.add_example_group example_group
+ end
+
+ it "should report the file and line submitted with :expected_from" do
+ example_definition = example_group.it "spec" do
+ mock = Spec::Mocks::Mock.new("a mock")
+ mock.should_receive(:message, :expected_from => "/path/to/blah.ext:37")
+ mock.rspec_verify
+ end
+ example = example_group.new(example_definition)
+
+ reporter.should_receive(:example_finished) do |spec, error|
+ error.backtrace.detect {|line| line =~ /\/path\/to\/blah.ext:37/}.should_not be_nil
+ end
+ example.execute(options, {})
+ end
+
+ it "should use the message supplied with :message" do
+ example_definition = @example_group.it "spec" do
+ mock = Spec::Mocks::Mock.new("a mock")
+ mock.should_receive(:message, :message => "recebi nada")
+ mock.rspec_verify
+ end
+ example = @example_group.new(example_definition)
+ @reporter.should_receive(:example_finished) do |spec, error|
+ error.message.should == "recebi nada"
+ end
+ example.execute(@options, {})
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/partial_mock_spec.rb b/vendor/gems/rspec/spec/spec/mocks/partial_mock_spec.rb
new file mode 100644
index 000000000..d7e5944c4
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/partial_mock_spec.rb
@@ -0,0 +1,106 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+ describe "using a Partial Mock," do
+ before(:each) do
+ @object = Object.new
+ end
+
+ it "should name the class in the failure message" do
+ @object.should_receive(:foo)
+ lambda do
+ @object.rspec_verify
+ end.should raise_error(Spec::Mocks::MockExpectationError, /Object/)
+ end
+
+ it "should not conflict with @options in the object" do
+ @object.instance_eval { @options = Object.new }
+ @object.should_receive(:blah)
+ @object.blah
+ end
+
+ it "should_not_receive should mock out the method" do
+ @object.should_not_receive(:fuhbar)
+ @object.fuhbar
+ lambda do
+ @object.rspec_verify
+ end.should raise_error(Spec::Mocks::MockExpectationError)
+ end
+
+ it "should_not_receive should return a negative message expectation" do
+ @object.should_not_receive(:foobar).should be_kind_of(NegativeMessageExpectation)
+ end
+
+ it "should_receive should mock out the method" do
+ @object.should_receive(:foobar).with(:test_param).and_return(1)
+ @object.foobar(:test_param).should equal(1)
+ end
+
+ it "should_receive should handle a hash" do
+ @object.should_receive(:foobar).with(:key => "value").and_return(1)
+ @object.foobar(:key => "value").should equal(1)
+ end
+
+ it "should_receive should handle an inner hash" do
+ hash = {:a => {:key => "value"}}
+ @object.should_receive(:foobar).with(:key => "value").and_return(1)
+ @object.foobar(hash[:a]).should equal(1)
+ end
+
+ it "should_receive should return a message expectation" do
+ @object.should_receive(:foobar).should be_kind_of(MessageExpectation)
+ @object.foobar
+ end
+
+ it "should_receive should verify method was called" do
+ @object.should_receive(:foobar).with(:test_param).and_return(1)
+ lambda do
+ @object.rspec_verify
+ end.should raise_error(Spec::Mocks::MockExpectationError)
+ end
+
+ it "should_receive should also take a String argument" do
+ @object.should_receive('foobar')
+ @object.foobar
+ end
+
+ it "should_not_receive should also take a String argument" do
+ @object.should_not_receive('foobar')
+ @object.foobar
+ lambda do
+ @object.rspec_verify
+ end.should raise_error(Spec::Mocks::MockExpectationError)
+ end
+
+ it "should use report nil in the error message" do
+ @this_will_resolve_to_nil.should_receive(:foobar)
+ lambda do
+ @this_will_resolve_to_nil.rspec_verify
+ end.should raise_error(Spec::Mocks::MockExpectationError, /NilClass.*expected :foobar with/)
+ end
+ end
+
+ describe "Partially mocking an object that defines ==, after another mock has been defined" do
+ before(:each) do
+ stub("existing mock", :foo => :foo)
+ end
+
+ class PartiallyMockedEquals
+ attr_reader :val
+ def initialize(val)
+ @val = val
+ end
+
+ def ==(other)
+ @val == other.val
+ end
+ end
+
+ it "should not raise an error when stubbing the object" do
+ o = PartiallyMockedEquals.new :foo
+ lambda { o.stub!(:bar) }.should_not raise_error(NoMethodError)
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb b/vendor/gems/rspec/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb
new file mode 100644
index 000000000..c857d8380
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb
@@ -0,0 +1,66 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+module Mocks
+describe "PartialMockUsingMocksDirectly" do
+ before(:each) do
+
+ klass=Class.new
+ klass.class_eval do
+ def existing_method
+ :original_value
+ end
+ end
+ @obj = klass.new
+
+ end
+
+ # See http://rubyforge.org/tracker/index.php?func=detail&aid=10263&group_id=797&atid=3149
+ # specify "should clear expectations on verify" do
+ # @obj.should_receive(:msg)
+ # @obj.msg
+ # @obj.rspec_verify
+ # lambda do
+ # @obj.msg
+ # end.should raise_error(NoMethodError)
+ #
+ # end
+ it "should fail when expected message is not received" do
+ @obj.should_receive(:msg)
+ lambda do
+ @obj.rspec_verify
+ end.should raise_error(MockExpectationError)
+
+ end
+ it "should fail when message is received with incorrect args" do
+ @obj.should_receive(:msg).with(:correct_arg)
+ lambda do
+ @obj.msg(:incorrect_arg)
+ end.should raise_error(MockExpectationError)
+ @obj.msg(:correct_arg)
+
+ end
+ it "should pass when expected message is received" do
+ @obj.should_receive(:msg)
+ @obj.msg
+ @obj.rspec_verify
+
+ end
+ it "should pass when message is received with correct args" do
+ @obj.should_receive(:msg).with(:correct_arg)
+ @obj.msg(:correct_arg)
+ @obj.rspec_verify
+
+ end
+ it "should revert to original method if existed" do
+ @obj.existing_method.should equal(:original_value)
+ @obj.should_receive(:existing_method).and_return(:mock_value)
+ @obj.existing_method.should equal(:mock_value)
+ @obj.rspec_verify
+ @obj.existing_method.should equal(:original_value)
+
+ end
+
+end
+end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/passing_mock_argument_constraints_spec.rb b/vendor/gems/rspec/spec/spec/mocks/passing_mock_argument_constraints_spec.rb
new file mode 100644
index 000000000..6de0a58f4
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/passing_mock_argument_constraints_spec.rb
@@ -0,0 +1,154 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+ describe "mock argument constraints", :shared => true do
+ before(:each) do
+ @mock = Mock.new("test mock")
+ Kernel.stub!(:warn)
+ end
+
+ after(:each) do
+ @mock.rspec_verify
+ end
+ end
+
+ describe Methods, "handling argument constraints with DEPRECATED symbols" do
+ it_should_behave_like "mock argument constraints"
+
+ it "should accept true as boolean" do
+ @mock.should_receive(:random_call).with(:boolean)
+ @mock.random_call(true)
+ end
+
+ it "should accept false as boolean" do
+ @mock.should_receive(:random_call).with(:boolean)
+ @mock.random_call(false)
+ end
+
+ it "should accept fixnum as numeric" do
+ @mock.should_receive(:random_call).with(:numeric)
+ @mock.random_call(1)
+ end
+
+ it "should accept float as numeric" do
+ @mock.should_receive(:random_call).with(:numeric)
+ @mock.random_call(1.5)
+ end
+
+ it "should accept string as anything" do
+ @mock.should_receive(:random_call).with("a", :anything, "c")
+ @mock.random_call("a", "whatever", "c")
+ end
+
+ it "should match string" do
+ @mock.should_receive(:random_call).with(:string)
+ @mock.random_call("a string")
+ end
+
+ it "should match no args against any_args" do
+ @mock.should_receive(:random_call).with(:any_args)
+ @mock.random_call("a string")
+ end
+
+ it "should match no args against no_args" do
+ @mock.should_receive(:random_call).with(:no_args)
+ @mock.random_call
+ end
+ end
+
+ describe Methods, "handling argument constraints" do
+ it_should_behave_like "mock argument constraints"
+
+ it "should accept true as boolean()" do
+ @mock.should_receive(:random_call).with(boolean())
+ @mock.random_call(true)
+ end
+
+ it "should accept false as boolean()" do
+ @mock.should_receive(:random_call).with(boolean())
+ @mock.random_call(false)
+ end
+
+ it "should accept fixnum as an_instance_of(Numeric)" do
+ @mock.should_receive(:random_call).with(an_instance_of(Numeric))
+ @mock.random_call(1)
+ end
+
+ it "should accept float as an_instance_of(Numeric)" do
+ @mock.should_receive(:random_call).with(an_instance_of(Numeric))
+ @mock.random_call(1.5)
+ end
+
+ it "should accept string as anything()" do
+ @mock.should_receive(:random_call).with("a", anything(), "c")
+ @mock.random_call("a", "whatever", "c")
+ end
+
+ it "should match duck type with one method" do
+ @mock.should_receive(:random_call).with(duck_type(:length))
+ @mock.random_call([])
+ end
+
+ it "should match duck type with two methods" do
+ @mock.should_receive(:random_call).with(duck_type(:abs, :div))
+ @mock.random_call(1)
+ end
+
+ it "should match no args against any_args()" do
+ @mock.should_receive(:random_call).with(any_args)
+ @mock.random_call()
+ end
+
+ it "should match one arg against any_args()" do
+ @mock.should_receive(:random_call).with(any_args)
+ @mock.random_call("a string")
+ end
+
+ it "should match no args against no_args()" do
+ @mock.should_receive(:random_call).with(no_args)
+ @mock.random_call()
+ end
+ end
+
+ describe Methods, "handling non-constraint arguments" do
+
+ it "should match non special symbol (can be removed when deprecated symbols are removed)" do
+ @mock.should_receive(:random_call).with(:some_symbol)
+ @mock.random_call(:some_symbol)
+ end
+
+ it "should match string against regexp" do
+ @mock.should_receive(:random_call).with(/bcd/)
+ @mock.random_call("abcde")
+ end
+
+ it "should match regexp against regexp" do
+ @mock.should_receive(:random_call).with(/bcd/)
+ @mock.random_call(/bcd/)
+ end
+
+ it "should match against a hash submitted and received by value" do
+ @mock.should_receive(:random_call).with(:a => "a", :b => "b")
+ @mock.random_call(:a => "a", :b => "b")
+ end
+
+ it "should match against a hash submitted by reference and received by value" do
+ opts = {:a => "a", :b => "b"}
+ @mock.should_receive(:random_call).with(opts)
+ @mock.random_call(:a => "a", :b => "b")
+ end
+
+ it "should match against a hash submitted by value and received by reference" do
+ opts = {:a => "a", :b => "b"}
+ @mock.should_receive(:random_call).with(:a => "a", :b => "b")
+ @mock.random_call(opts)
+ end
+
+ it "should match against a Matcher" do
+ @mock.should_receive(:msg).with(equal(37))
+ @mock.msg(37)
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/precise_counts_spec.rb b/vendor/gems/rspec/spec/spec/mocks/precise_counts_spec.rb
new file mode 100644
index 000000000..ba3898943
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/precise_counts_spec.rb
@@ -0,0 +1,52 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+ describe "PreciseCounts" do
+ before(:each) do
+ @mock = mock("test mock")
+ end
+
+ it "should fail when exactly n times method is called less than n times" do
+ @mock.should_receive(:random_call).exactly(3).times
+ @mock.random_call
+ @mock.random_call
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should fail when exactly n times method is never called" do
+ @mock.should_receive(:random_call).exactly(3).times
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "should pass if exactly n times method is called exactly n times" do
+ @mock.should_receive(:random_call).exactly(3).times
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ @mock.rspec_verify
+ end
+
+ it "should pass multiple calls with different args and counts" do
+ @mock.should_receive(:random_call).twice.with(1)
+ @mock.should_receive(:random_call).once.with(2)
+ @mock.random_call(1)
+ @mock.random_call(2)
+ @mock.random_call(1)
+ @mock.rspec_verify
+ end
+
+ it "should pass mutiple calls with different args" do
+ @mock.should_receive(:random_call).once.with(1)
+ @mock.should_receive(:random_call).once.with(2)
+ @mock.random_call(1)
+ @mock.random_call(2)
+ @mock.rspec_verify
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/record_messages_spec.rb b/vendor/gems/rspec/spec/spec/mocks/record_messages_spec.rb
new file mode 100644
index 000000000..ec247726d
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/record_messages_spec.rb
@@ -0,0 +1,26 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Mocks
+ describe "a mock" do
+ before(:each) do
+ @mock = mock("mock", :null_object => true)
+ end
+ it "should answer false for received_message? when no messages received" do
+ @mock.received_message?(:message).should be_false
+ end
+ it "should answer true for received_message? when message received" do
+ @mock.message
+ @mock.received_message?(:message).should be_true
+ end
+ it "should answer true for received_message? when message received with correct args" do
+ @mock.message 1,2,3
+ @mock.received_message?(:message, 1,2,3).should be_true
+ end
+ it "should answer false for received_message? when message received with incorrect args" do
+ @mock.message 1,2,3
+ @mock.received_message?(:message, 1,2).should be_false
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/stub_spec.rb b/vendor/gems/rspec/spec/spec/mocks/stub_spec.rb
new file mode 100644
index 000000000..d6e23d71e
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/stub_spec.rb
@@ -0,0 +1,181 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+ describe "A method stub" do
+ before(:each) do
+ @class = Class.new do
+ def self.existing_class_method
+ :original_value
+ end
+
+ def existing_instance_method
+ :original_value
+ end
+ end
+ @instance = @class.new
+ end
+
+ it "should return expected value when expected message is received" do
+ @instance.stub!(:msg).and_return(:return_value)
+ @instance.msg.should equal(:return_value)
+ @instance.rspec_verify
+ end
+
+ it "should ignore when expected message is received" do
+ @instance.stub!(:msg)
+ @instance.msg
+ lambda do
+ @instance.rspec_verify
+ end.should_not raise_error
+ end
+
+ it "should ignore when message is received with args" do
+ @instance.stub!(:msg)
+ @instance.msg(:an_arg)
+ lambda do
+ @instance.rspec_verify
+ end.should_not raise_error
+ end
+
+ it "should ignore when expected message is not received" do
+ @instance.stub!(:msg)
+ lambda do
+ @instance.rspec_verify
+ end.should_not raise_error
+ end
+
+ it "should clear itself when verified" do
+ @instance.stub!(:this_should_go).and_return(:blah)
+ @instance.this_should_go.should == :blah
+ @instance.rspec_verify
+ lambda do
+ @instance.this_should_go
+ end.should raise_error(NameError)
+ end
+
+ it "should return values in order to consecutive calls" do
+ return_values = ["1",2,Object.new]
+ @instance.stub!(:msg).and_return(return_values[0],return_values[1],return_values[2])
+ @instance.msg.should == return_values[0]
+ @instance.msg.should == return_values[1]
+ @instance.msg.should == return_values[2]
+ end
+
+ it "should keep returning last value in consecutive calls" do
+ return_values = ["1",2,Object.new]
+ @instance.stub!(:msg).and_return(return_values[0],return_values[1],return_values[2])
+ @instance.msg.should == return_values[0]
+ @instance.msg.should == return_values[1]
+ @instance.msg.should == return_values[2]
+ @instance.msg.should == return_values[2]
+ @instance.msg.should == return_values[2]
+ end
+
+ it "should revert to original instance method if there is one" do
+ @instance.existing_instance_method.should equal(:original_value)
+ @instance.stub!(:existing_instance_method).and_return(:mock_value)
+ @instance.existing_instance_method.should equal(:mock_value)
+ @instance.rspec_verify
+ @instance.existing_instance_method.should equal(:original_value)
+ end
+
+ it "should revert to original class method if there is one" do
+ @class.existing_class_method.should equal(:original_value)
+ @class.stub!(:existing_class_method).and_return(:mock_value)
+ @class.existing_class_method.should equal(:mock_value)
+ @class.rspec_verify
+ @class.existing_class_method.should equal(:original_value)
+ end
+
+ it "should yield a specified object" do
+ @instance.stub!(:method_that_yields).and_yield(:yielded_obj)
+ current_value = :value_before
+ @instance.method_that_yields {|val| current_value = val}
+ current_value.should == :yielded_obj
+ @instance.rspec_verify
+ end
+
+ it "should yield multiple times with multiple calls to and_yield" do
+ @instance.stub!(:method_that_yields_multiple_times).and_yield(:yielded_value).
+ and_yield(:another_value)
+ current_value = []
+ @instance.method_that_yields_multiple_times {|val| current_value << val}
+ current_value.should == [:yielded_value, :another_value]
+ @instance.rspec_verify
+ end
+
+ it "should yield a specified object and return another specified object" do
+ yielded_obj = mock("my mock")
+ yielded_obj.should_receive(:foo).with(:bar)
+ @instance.stub!(:method_that_yields_and_returns).and_yield(yielded_obj).and_return(:baz)
+ @instance.method_that_yields_and_returns { |o| o.foo :bar }.should == :baz
+ end
+
+ it "should throw when told to" do
+ @mock.stub!(:something).and_throw(:up)
+ lambda do
+ @mock.something
+ end.should throw_symbol(:up)
+ end
+
+ it "should override a pre-existing stub" do
+ @stub.stub!(:existing_instance_method).and_return(:updated_stub_value)
+ @stub.existing_instance_method.should == :updated_stub_value
+ end
+
+ it "should limit " do
+ @stub.stub!(:foo).with("bar")
+ @stub.should_receive(:foo).with("baz")
+ @stub.foo("bar")
+ @stub.foo("baz")
+ end
+ end
+
+ describe "A method stub with args" do
+ before(:each) do
+ @stub = Object.new
+ @stub.stub!(:foo).with("bar")
+ end
+
+ it "should not complain if not called" do
+ end
+
+ it "should not complain if called with arg" do
+ @stub.foo("bar")
+ end
+
+ it "should complain if called with no arg" do
+ lambda do
+ @stub.foo
+ end.should raise_error
+ end
+
+ it "should complain if called with other arg" do
+ lambda do
+ @stub.foo("other")
+ end.should raise_error
+ end
+
+ it "should not complain if also mocked w/ different args" do
+ @stub.should_receive(:foo).with("baz")
+ @stub.foo("bar")
+ @stub.foo("baz")
+ end
+
+ it "should complain if also mocked w/ different args AND called w/ a 3rd set of args" do
+ @stub.should_receive(:foo).with("baz")
+ @stub.foo("bar")
+ @stub.foo("baz")
+ lambda do
+ @stub.foo("other")
+ end.should raise_error
+ end
+
+ it "should support options" do
+ @stub.stub!(:foo, :expected_from => "bar")
+ end
+ end
+
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/mocks/twice_counts_spec.rb b/vendor/gems/rspec/spec/spec/mocks/twice_counts_spec.rb
new file mode 100644
index 000000000..d07e45736
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/mocks/twice_counts_spec.rb
@@ -0,0 +1,67 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Mocks
+ describe "TwiceCounts" do
+ before(:each) do
+ @mock = mock("test mock")
+ end
+
+ it "twice should fail when call count is higher than expected" do
+ @mock.should_receive(:random_call).twice
+ @mock.random_call
+ @mock.random_call
+ @mock.random_call
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "twice should fail when call count is lower than expected" do
+ @mock.should_receive(:random_call).twice
+ @mock.random_call
+ lambda do
+ @mock.rspec_verify
+ end.should raise_error(MockExpectationError)
+ end
+
+ it "twice should fail when called twice with wrong args on the first call" do
+ @mock.should_receive(:random_call).twice.with("1", 1)
+ lambda do
+ @mock.random_call(1, "1")
+ end.should raise_error(MockExpectationError)
+ @mock.rspec_reset
+ end
+
+ it "twice should fail when called twice with wrong args on the second call" do
+ @mock.should_receive(:random_call).twice.with("1", 1)
+ @mock.random_call("1", 1)
+ lambda do
+ @mock.random_call(1, "1")
+ end.should raise_error(MockExpectationError)
+ @mock.rspec_reset
+ end
+
+ it "twice should pass when called twice" do
+ @mock.should_receive(:random_call).twice
+ @mock.random_call
+ @mock.random_call
+ @mock.rspec_verify
+ end
+
+ it "twice should pass when called twice with specified args" do
+ @mock.should_receive(:random_call).twice.with("1", 1)
+ @mock.random_call("1", 1)
+ @mock.random_call("1", 1)
+ @mock.rspec_verify
+ end
+
+ it "twice should pass when called twice with unspecified args" do
+ @mock.should_receive(:random_call).twice
+ @mock.random_call("1")
+ @mock.random_call(1)
+ @mock.rspec_verify
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/package/bin_spec_spec.rb b/vendor/gems/rspec/spec/spec/package/bin_spec_spec.rb
new file mode 100644
index 000000000..44bfd96a0
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/package/bin_spec_spec.rb
@@ -0,0 +1,14 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/../../ruby_forker'
+
+describe "The bin/spec script" do
+ include RubyForker
+
+ it "should have no warnings" do
+ pending "Hangs on JRuby" if PLATFORM =~ /java/
+ spec_path = "#{File.dirname(__FILE__)}/../../../bin/spec"
+
+ output = ruby "-w #{spec_path} --help 2>&1"
+ output.should_not =~ /warning/n
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/class_and_argument_parser_spec.rb b/vendor/gems/rspec/spec/spec/runner/class_and_argument_parser_spec.rb
new file mode 100644
index 000000000..b4e9e7f53
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/class_and_argument_parser_spec.rb
@@ -0,0 +1,23 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Runner
+ describe ClassAndArgumentsParser, ".parse" do
+
+ it "should use a single : to separate class names from arguments" do
+ ClassAndArgumentsParser.parse('Foo').should == ['Foo', nil]
+ ClassAndArgumentsParser.parse('Foo:arg').should == ['Foo', 'arg']
+ ClassAndArgumentsParser.parse('Foo::Bar::Zap:arg').should == ['Foo::Bar::Zap', 'arg']
+ ClassAndArgumentsParser.parse('Foo:arg1,arg2').should == ['Foo', 'arg1,arg2']
+ ClassAndArgumentsParser.parse('Foo::Bar::Zap:arg1,arg2').should == ['Foo::Bar::Zap', 'arg1,arg2']
+ ClassAndArgumentsParser.parse('Foo::Bar::Zap:drb://foo,drb://bar').should == ['Foo::Bar::Zap', 'drb://foo,drb://bar']
+ end
+
+ it "should raise an error when passed an empty string" do
+ lambda do
+ ClassAndArgumentsParser.parse('')
+ end.should raise_error("Couldn't parse \"\"")
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/command_line_spec.rb b/vendor/gems/rspec/spec/spec/runner/command_line_spec.rb
new file mode 100644
index 000000000..3c3be8cea
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/command_line_spec.rb
@@ -0,0 +1,147 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Runner
+ describe CommandLine, ".run" do
+ it_should_behave_like "sandboxed rspec_options"
+ attr_reader :options, :err, :out
+ before do
+ @err = options.error_stream
+ @out = options.output_stream
+ end
+
+ it "should run directory" do
+ file = File.dirname(__FILE__) + '/../../../examples/pure'
+ Spec::Runner::CommandLine.run(OptionParser.parse([file,"-p","**/*.rb"], @err, @out))
+
+ @out.rewind
+ @out.read.should =~ /\d+ examples, 0 failures, 3 pending/n
+ end
+
+ it "should run file" do
+ file = File.dirname(__FILE__) + '/../../../failing_examples/predicate_example.rb'
+ Spec::Runner::CommandLine.run(OptionParser.parse([file], @err, @out))
+
+ @out.rewind
+ @out.read.should =~ /2 examples, 1 failure/n
+ end
+
+ it "should raise when file does not exist" do
+ file = File.dirname(__FILE__) + '/doesntexist'
+
+ lambda {
+ Spec::Runner::CommandLine.run(OptionParser.parse([file], @err, @out))
+ }.should raise_error
+ end
+
+ it "should return true when in --generate-options mode" do
+ # NOTE - this used to say /dev/null but jruby hangs on that for some reason
+ Spec::Runner::CommandLine.run(
+ OptionParser.parse(['--generate-options', '/tmp/foo'], @err, @out)
+ ).should be_true
+ end
+
+ it "should dump even if Interrupt exception is occurred" do
+ example_group = Class.new(::Spec::Example::ExampleGroup) do
+ describe("example_group")
+ it "no error" do
+ end
+
+ it "should interrupt" do
+ raise Interrupt, "I'm interrupting"
+ end
+ end
+
+ options = ::Spec::Runner::Options.new(@err, @out)
+ ::Spec::Runner::Options.should_receive(:new).with(@err, @out).and_return(options)
+ options.reporter.should_receive(:dump)
+ options.add_example_group(example_group)
+
+ Spec::Runner::CommandLine.run(OptionParser.parse([], @err, @out))
+ end
+
+ it "should heckle when options have heckle_runner" do
+ example_group = Class.new(::Spec::Example::ExampleGroup).describe("example_group") do
+ it "no error" do
+ end
+ end
+ options = ::Spec::Runner::Options.new(@err, @out)
+ ::Spec::Runner::Options.should_receive(:new).with(@err, @out).and_return(options)
+ options.add_example_group example_group
+
+ heckle_runner = mock("heckle_runner")
+ heckle_runner.should_receive(:heckle_with)
+ $rspec_mocks.__send__(:mocks).delete(heckle_runner)
+
+ options.heckle_runner = heckle_runner
+ options.add_example_group(example_group)
+
+ Spec::Runner::CommandLine.run(OptionParser.parse([], @err, @out))
+ heckle_runner.rspec_verify
+ end
+
+ it "should run examples backwards if options.reverse is true" do
+ options = ::Spec::Runner::Options.new(@err, @out)
+ ::Spec::Runner::Options.should_receive(:new).with(@err, @out).and_return(options)
+ options.reverse = true
+
+ b1 = Class.new(Spec::Example::ExampleGroup)
+ b2 = Class.new(Spec::Example::ExampleGroup)
+
+ b2.should_receive(:run).ordered
+ b1.should_receive(:run).ordered
+
+ options.add_example_group(b1)
+ options.add_example_group(b2)
+
+ Spec::Runner::CommandLine.run(OptionParser.parse([], @err, @out))
+ end
+
+ it "should pass its ExampleGroup to the reporter" do
+ example_group = Class.new(::Spec::Example::ExampleGroup).describe("example_group") do
+ it "should" do
+ end
+ end
+ options = ::Spec::Runner::Options.new(@err, @out)
+ options.add_example_group(example_group)
+
+ ::Spec::Runner::Options.should_receive(:new).with(@err, @out).and_return(options)
+ options.reporter.should_receive(:add_example_group).with(example_group)
+
+ Spec::Runner::CommandLine.run(OptionParser.parse([], @err, @out))
+ end
+
+ it "runs only selected Examples when options.examples is set" do
+ options = ::Spec::Runner::Options.new(@err, @out)
+ ::Spec::Runner::Options.should_receive(:new).with(@err, @out).and_return(options)
+
+ options.examples << "example_group should"
+ should_has_run = false
+ should_not_has_run = false
+ example_group = Class.new(::Spec::Example::ExampleGroup).describe("example_group") do
+ it "should" do
+ should_has_run = true
+ end
+ it "should not" do
+ should_not_has_run = true
+ end
+ end
+
+ options.reporter.should_receive(:add_example_group).with(example_group)
+
+ options.add_example_group example_group
+ Spec::Runner::CommandLine.run(OptionParser.parse([], @err, @out))
+
+ should_has_run.should be_true
+ should_not_has_run.should be_false
+ end
+
+ it "sets Spec.run to true" do
+ ::Spec.run = false
+ ::Spec.should_not be_run
+ Spec::Runner::CommandLine.run(OptionParser.parse([], @err, @out))
+ ::Spec.should be_run
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/runner/drb_command_line_spec.rb b/vendor/gems/rspec/spec/spec/runner/drb_command_line_spec.rb
new file mode 100644
index 000000000..760ec37a9
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/drb_command_line_spec.rb
@@ -0,0 +1,92 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Runner
+ describe DrbCommandLine, "without running local server" do
+ unless Config::CONFIG['ruby_install_name'] == 'jruby'
+ it "should print error when there is no running local server" do
+ err = StringIO.new
+ out = StringIO.new
+ DrbCommandLine.run(OptionParser.parse(['--version'], err, out))
+
+ err.rewind
+ err.read.should =~ /No server is running/
+ end
+ end
+ end
+
+ class DrbCommandLineSpec < ::Spec::Example::ExampleGroup
+ describe DrbCommandLine, "with local server"
+
+ class CommandLineForSpec
+ def self.run(argv, stderr, stdout)
+ exit Spec::Runner::CommandLine.run(OptionParser.parse(argv, stderr, stdout))
+ end
+ end
+
+ unless Config::CONFIG['ruby_install_name'] == 'jruby'
+ before(:all) do
+ DRb.start_service("druby://localhost:8989", CommandLineForSpec)
+ @@drb_example_file_counter = 0
+ end
+
+ before(:each) do
+ create_dummy_spec_file
+ @@drb_example_file_counter = @@drb_example_file_counter + 1
+ end
+
+ after(:each) do
+ File.delete(@dummy_spec_filename)
+ end
+
+ after(:all) do
+ DRb.stop_service
+ end
+
+ it "should run against local server" do
+ out = run_spec_via_druby(['--version'])
+ out.should =~ /RSpec/n
+ end
+
+ it "should output green colorized text when running with --colour option" do
+ out = run_spec_via_druby(["--colour", @dummy_spec_filename])
+ out.should =~ /\e\[32m/n
+ end
+
+ it "should output red colorized text when running with -c option" do
+ out = run_spec_via_druby(["-c", @dummy_spec_filename])
+ out.should =~ /\e\[31m/n
+ end
+
+ def create_dummy_spec_file
+ @dummy_spec_filename = File.expand_path(File.dirname(__FILE__)) + "/_dummy_spec#{@@drb_example_file_counter}.rb"
+ File.open(@dummy_spec_filename, 'w') do |f|
+ f.write %{
+ describe "DUMMY CONTEXT for 'DrbCommandLine with -c option'" do
+ it "should be output with green bar" do
+ true.should be_true
+ end
+
+ it "should be output with red bar" do
+ violated("I want to see a red bar!")
+ end
+ end
+ }
+ end
+ end
+
+ def run_spec_via_druby(argv)
+ err, out = StringIO.new, StringIO.new
+ out.instance_eval do
+ def tty?; true end
+ end
+ options = ::Spec::Runner::Options.new(err, out)
+ options.argv = argv
+ Spec::Runner::DrbCommandLine.run(options)
+ out.rewind; out.read
+ end
+ end
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/empty_file.txt b/vendor/gems/rspec/spec/spec/runner/empty_file.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/empty_file.txt
diff --git a/vendor/gems/rspec/spec/spec/runner/examples.txt b/vendor/gems/rspec/spec/spec/runner/examples.txt
new file mode 100644
index 000000000..2fcbd355d
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/examples.txt
@@ -0,0 +1,2 @@
+Sir, if you were my husband, I would poison your drink.
+Madam, if you were my wife, I would drink it. \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/runner/execution_context_spec.rb b/vendor/gems/rspec/spec/spec/runner/execution_context_spec.rb
new file mode 100644
index 000000000..82e7447c1
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/execution_context_spec.rb
@@ -0,0 +1,31 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "ExecutionContext" do
+
+ it "should provide duck_type()" do
+ dt = duck_type(:length)
+ dt.should be_an_instance_of(Spec::Mocks::DuckTypeArgConstraint)
+ dt.matches?([]).should be_true
+ end
+
+ it "should violate when violated()" do
+ lambda do
+ violated
+ end.should raise_error(Spec::Expectations::ExpectationNotMetError)
+ end
+
+ it "should provide mock()" do
+ mock("thing").should be_an_instance_of(Spec::Mocks::Mock)
+ end
+
+ it "should provide stub()" do
+ thing_stub = stub("thing").should be_an_instance_of(Spec::Mocks::Mock)
+ end
+
+ it "should add method stubs to stub()" do
+ thing_stub = stub("thing", :a => "A", :b => "B")
+ thing_stub.a.should == "A"
+ thing_stub.b.should == "B"
+ end
+
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/failed.txt b/vendor/gems/rspec/spec/spec/runner/failed.txt
new file mode 100644
index 000000000..07c5442cf
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/failed.txt
@@ -0,0 +1,3 @@
+heckler_spec.rb
+command_line_spec.rb
+reporter_spec.rb \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb b/vendor/gems/rspec/spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb
new file mode 100644
index 000000000..a08b6e86d
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb
@@ -0,0 +1,44 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require 'spec/runner/formatter/failing_example_groups_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ describe FailingExampleGroupsFormatter do
+ attr_reader :example_group, :formatter, :io
+
+ before(:each) do
+ @io = StringIO.new
+ options = mock('options')
+ @formatter = FailingExampleGroupsFormatter.new(options, io)
+ @example_group = Class.new(::Spec::Example::ExampleGroup)
+ end
+
+ it "should add example name for each failure" do
+ formatter.add_example_group(Class.new(ExampleGroup).describe("b 1"))
+ formatter.example_failed("e 1", nil, Reporter::Failure.new(nil, RuntimeError.new))
+ formatter.add_example_group(Class.new(ExampleGroup).describe("b 2"))
+ formatter.example_failed("e 2", nil, Reporter::Failure.new(nil, RuntimeError.new))
+ formatter.example_failed("e 3", nil, Reporter::Failure.new(nil, RuntimeError.new))
+ io.string.should == "b 1\nb 2\n"
+ end
+
+ it "should delimit ExampleGroup superclass descriptions with :" do
+ parent_example_group = Class.new(example_group).describe("Parent")
+ child_example_group = Class.new(parent_example_group).describe("#child_method")
+ grand_child_example_group = Class.new(child_example_group).describe("GrandChild")
+
+ formatter.add_example_group(grand_child_example_group)
+ formatter.example_failed("failure", nil, Reporter::Failure.new(nil, RuntimeError.new))
+ io.string.should == "Parent#child_method GrandChild\n"
+ end
+
+ it "should remove druby url, which is used by Spec::Distributed" do
+ @formatter.add_example_group(Class.new(ExampleGroup).describe("something something (druby://99.99.99.99:99)"))
+ @formatter.example_failed("e 1", nil, Reporter::Failure.new(nil, RuntimeError.new))
+ io.string.should == "something something\n"
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/failing_examples_formatter_spec.rb b/vendor/gems/rspec/spec/spec/runner/formatter/failing_examples_formatter_spec.rb
new file mode 100644
index 000000000..fda64f95f
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/failing_examples_formatter_spec.rb
@@ -0,0 +1,33 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require 'spec/runner/formatter/failing_examples_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ describe FailingExamplesFormatter do
+ before(:each) do
+ @io = StringIO.new
+ options = mock('options')
+ @formatter = FailingExamplesFormatter.new(options, @io)
+ end
+
+ it "should add example name for each failure" do
+ example_group_1 = Class.new(ExampleGroup).describe("A")
+ example_group_2 = Class.new(example_group_1).describe("B")
+
+ @formatter.add_example_group(example_group_1)
+ @formatter.example_failed(example_group_1.it("a1"){}, nil, Reporter::Failure.new(nil, RuntimeError.new))
+ @formatter.add_example_group(example_group_2)
+ @formatter.example_failed(example_group_2.it("b2"){}, nil, Reporter::Failure.new(nil, RuntimeError.new))
+ @formatter.example_failed(example_group_2.it("b3"){}, nil, Reporter::Failure.new(nil, RuntimeError.new))
+ @io.string.should eql(<<-EOF
+A a1
+A B b2
+A B b3
+EOF
+)
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.4.html b/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.4.html
new file mode 100644
index 000000000..9cc458fdb
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.4.html
@@ -0,0 +1,365 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>RSpec results</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Expires" content="-1" />
+ <meta http-equiv="Pragma" content="no-cache" />
+ <style type="text/css">
+ body {
+ margin: 0;
+ padding: 0;
+ background: #fff;
+ font-size: 80%;
+ }
+ </style>
+</head>
+<body>
+<div class="rspec-report">
+ <script type="text/javascript">
+ // <![CDATA[
+function moveProgressBar(percentDone) {
+ document.getElementById("rspec-header").style.width = percentDone +"%";
+}
+function makeRed(element_id) {
+ document.getElementById(element_id).style.background = '#C40D0D';
+ document.getElementById(element_id).style.color = '#FFFFFF';
+}
+
+function makeYellow(element_id) {
+ if (element_id == "rspec-header" && document.getElementById(element_id).style.background != '#C40D0D')
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+ else
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+}
+
+ // ]]>
+ </script>
+ <style type="text/css">
+#rspec-header {
+ background: #65C400; color: #fff;
+}
+
+.rspec-report h1 {
+ margin: 0px 10px 0px 10px;
+ padding: 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ font-size: 1.8em;
+}
+
+#summary {
+ margin: 0; padding: 5px 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ text-align: right;
+ position: absolute;
+ top: 0px;
+ right: 0px;
+}
+
+#summary p {
+ margin: 0 0 0 2px;
+}
+
+#summary #totals {
+ font-size: 1.2em;
+}
+
+.example_group {
+ margin: 0 10px 5px;
+ background: #fff;
+}
+
+dl {
+ margin: 0; padding: 0 0 5px;
+ font: normal 11px "Lucida Grande", Helvetica, sans-serif;
+}
+
+dt {
+ padding: 3px;
+ background: #65C400;
+ color: #fff;
+ font-weight: bold;
+}
+
+dd {
+ margin: 5px 0 5px 5px;
+ padding: 3px 3px 3px 18px;
+}
+
+dd.spec.passed {
+ border-left: 5px solid #65C400;
+ border-bottom: 1px solid #65C400;
+ background: #DBFFB4; color: #3D7700;
+}
+
+dd.spec.failed {
+ border-left: 5px solid #C20000;
+ border-bottom: 1px solid #C20000;
+ color: #C20000; background: #FFFBD3;
+}
+
+dd.spec.not_implemented {
+ border-left: 5px solid #FAF834;
+ border-bottom: 1px solid #FAF834;
+ background: #FCFB98; color: #131313;
+}
+
+dd.spec.pending_fixed {
+ border-left: 5px solid #0000C2;
+ border-bottom: 1px solid #0000C2;
+ color: #0000C2; background: #D3FBFF;
+}
+
+.backtrace {
+ color: #000;
+ font-size: 12px;
+}
+
+a {
+ color: #BE5C00;
+}
+
+/* Ruby code, style similar to vibrant ink */
+.ruby {
+ font-size: 12px;
+ font-family: monospace;
+ color: white;
+ background-color: black;
+ padding: 0.1em 0 0.2em 0;
+}
+
+.ruby .keyword { color: #FF6600; }
+.ruby .constant { color: #339999; }
+.ruby .attribute { color: white; }
+.ruby .global { color: white; }
+.ruby .module { color: white; }
+.ruby .class { color: white; }
+.ruby .string { color: #66FF00; }
+.ruby .ident { color: white; }
+.ruby .method { color: #FFCC00; }
+.ruby .number { color: white; }
+.ruby .char { color: white; }
+.ruby .comment { color: #9933CC; }
+.ruby .symbol { color: white; }
+.ruby .regex { color: #44B4CC; }
+.ruby .punct { color: white; }
+.ruby .escape { color: white; }
+.ruby .interp { color: white; }
+.ruby .expr { color: white; }
+
+.ruby .offending { background-color: gray; }
+.ruby .linenum {
+ width: 75px;
+ padding: 0.1em 1em 0.2em 0;
+ color: #000000;
+ background-color: #FFFBD3;
+}
+
+ </style>
+
+<div id="rspec-header">
+ <h1>RSpec Results</h1>
+
+ <div id="summary">
+ <p id="totals">&nbsp;</p>
+ <p id="duration">&nbsp;</p>
+ </div>
+</div>
+
+<div class="results">
+<div class="example_group">
+ <dl>
+ <dt id="example_group_1">Mocker</dt>
+ <script type="text/javascript">moveProgressBar('5.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to call mock()</span></dd>
+ <script type="text/javascript">makeRed('rspec-header');</script>
+ <script type="text/javascript">makeRed('example_group_1');</script>
+ <script type="text/javascript">moveProgressBar('11.7');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when expected message not received</span>
+ <div class="failure" id="failure_1">
+ <div class="message"><pre>Mock 'poke me' expected :poke with (any args) once, but received it 0 times</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:13:
+./spec/spec/runner/formatter/html_formatter_spec.rb:24:
+./spec/spec/runner/formatter/html_formatter_spec.rb:20:</pre></div>
+ <pre class="ruby"><code><span class="linenum">11</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should fail when expected message not received</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="linenum">12</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">poke me</span><span class="punct">&quot;)</span>
+<span class="offending"><span class="linenum">13</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_receive</span><span class="punct">(</span><span class="symbol">:poke</span><span class="punct">)</span></span>
+<span class="linenum">14</span> <span class="keyword">end</span>
+<span class="linenum">15</span> </code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('17.6');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when messages are received out of order</span>
+ <div class="failure" id="failure_2">
+ <div class="message"><pre>Mock 'one two three' received :three out of order</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:22:
+./spec/spec/runner/formatter/html_formatter_spec.rb:24:
+./spec/spec/runner/formatter/html_formatter_spec.rb:20:</pre></div>
+ <pre class="ruby"><code><span class="linenum">20</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_receive</span><span class="punct">(</span><span class="symbol">:three</span><span class="punct">).</span><span class="ident">ordered</span>
+<span class="linenum">21</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">one</span>
+<span class="offending"><span class="linenum">22</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">three</span></span>
+<span class="linenum">23</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">two</span>
+<span class="linenum">24</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('23.5');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should get yelled at when sending unexpected messages</span>
+ <div class="failure" id="failure_3">
+ <div class="message"><pre>Mock 'don't talk to me' expected :any_message_at_all with (any args) 0 times, but received it once</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:28:
+./spec/spec/runner/formatter/html_formatter_spec.rb:24:
+./spec/spec/runner/formatter/html_formatter_spec.rb:20:</pre></div>
+ <pre class="ruby"><code><span class="linenum">26</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should get yelled at when sending unexpected messages</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="linenum">27</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">don't talk to me</span><span class="punct">&quot;)</span>
+<span class="offending"><span class="linenum">28</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_not_receive</span><span class="punct">(</span><span class="symbol">:any_message_at_all</span><span class="punct">)</span></span>
+<span class="linenum">29</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">any_message_at_all</span>
+<span class="linenum">30</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('29.4');</script>
+ <dd class="spec pending_fixed">
+ <span class="failed_spec_name">has a bug we need to fix</span>
+ <div class="failure" id="failure_4">
+ <div class="message"><pre>Expected pending 'here is the bug' to fail. No Error was raised.</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:33:
+./spec/spec/runner/formatter/html_formatter_spec.rb:24:
+./spec/spec/runner/formatter/html_formatter_spec.rb:20:</pre></div>
+ <pre class="ruby"><code><span class="linenum">31</span>
+<span class="linenum">32</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">has a bug we need to fix</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="offending"><span class="linenum">33</span> <span class="ident">pending</span> <span class="punct">&quot;</span><span class="string">here is the bug</span><span class="punct">&quot;</span> <span class="keyword">do</span></span>
+<span class="linenum">34</span> <span class="comment"># Actually, no. It's fixed. This will fail because it passes :-)</span>
+<span class="linenum">35</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">Bug</span><span class="punct">&quot;)</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_2">Running specs with --diff</dt>
+ <script type="text/javascript">makeRed('example_group_2');</script>
+ <script type="text/javascript">moveProgressBar('35.2');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different strings</span>
+ <div class="failure" id="failure_5">
+ <div class="message"><pre>expected: &quot;RSpec is a\nbehaviour driven development\nframework for Ruby\n&quot;,
+ got: &quot;RSpec is a\nbehavior driven development\nframework for Ruby\n&quot; (using ==)
+Diff:
+@@ -1,4 +1,4 @@
+ RSpec is a
+-behavior driven development
++behaviour driven development
+ framework for Ruby
+</pre></div>
+ <div class="backtrace"><pre>./failing_examples/diffing_spec.rb:13:
+./spec/spec/runner/formatter/html_formatter_spec.rb:24:
+./spec/spec/runner/formatter/html_formatter_spec.rb:20:</pre></div>
+ <pre class="ruby"><code><span class="linenum">11</span><span class="ident">framework</span> <span class="keyword">for</span> <span class="constant">Ruby</span>
+<span class="linenum">12</span><span class="constant">EOF</span>
+<span class="offending"><span class="linenum">13</span> <span class="ident">usa</span><span class="punct">.</span><span class="ident">should</span> <span class="punct">==</span> <span class="ident">uk</span></span>
+<span class="linenum">14</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('41.1');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different objects' pretty representation</span>
+ <div class="failure" id="failure_6">
+ <div class="message"><pre>expected &lt;Animal
+name=bob,
+species=tortoise
+&gt;
+, got &lt;Animal
+name=bob,
+species=giraffe
+&gt;
+ (using .eql?)
+Diff:
+@@ -1,5 +1,5 @@
+ &lt;Animal
+ name=bob,
+-species=giraffe
++species=tortoise
+ &gt;
+</pre></div>
+ <div class="backtrace"><pre>./failing_examples/diffing_spec.rb:34:
+./spec/spec/runner/formatter/html_formatter_spec.rb:24:
+./spec/spec/runner/formatter/html_formatter_spec.rb:20:</pre></div>
+ <pre class="ruby"><code><span class="linenum">32</span> <span class="ident">expected</span> <span class="punct">=</span> <span class="constant">Animal</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">&quot;</span><span class="string">bob</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">giraffe</span><span class="punct">&quot;</span>
+<span class="linenum">33</span> <span class="ident">actual</span> <span class="punct">=</span> <span class="constant">Animal</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">&quot;</span><span class="string">bob</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">tortoise</span><span class="punct">&quot;</span>
+<span class="offending"><span class="linenum">34</span> <span class="ident">expected</span><span class="punct">.</span><span class="ident">should</span> <span class="ident">eql</span><span class="punct">(</span><span class="ident">actual</span><span class="punct">)</span></span>
+<span class="linenum">35</span> <span class="keyword">end</span>
+<span class="linenum">36</span><span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_3">A consumer of a stub</dt>
+ <script type="text/javascript">moveProgressBar('47.0');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to stub methods on any Object</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_4">A stubbed method on a class</dt>
+ <script type="text/javascript">moveProgressBar('52.9');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should return the stubbed value</span></dd>
+ <script type="text/javascript">moveProgressBar('58.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should revert to the original method after each spec</span></dd>
+ <script type="text/javascript">moveProgressBar('64.7');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_5">A mock</dt>
+ <script type="text/javascript">moveProgressBar('70.5');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub!</span></dd>
+ <script type="text/javascript">moveProgressBar('76.4');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock</span></dd>
+ <script type="text/javascript">moveProgressBar('82.3');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_6">pending example (using pending method)</dt>
+ <script type="text/javascript">makeYellow('example_group_6');</script>
+ <script type="text/javascript">moveProgressBar('88.2');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_7">pending example (with no block)</dt>
+ <script type="text/javascript">makeYellow('example_group_7');</script>
+ <script type="text/javascript">moveProgressBar('94.1');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: Not Yet Implemented&quot; (PENDING: Not Yet Implemented)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_8">pending example (with block for pending)</dt>
+ <script type="text/javascript">makeYellow('example_group_8');</script>
+ <script type="text/javascript">moveProgressBar('100.0');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should have a failing block, passed to pending, reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>x seconds</strong>";</script>
+<script type="text/javascript">document.getElementById('totals').innerHTML = "17 examples, 6 failures, 3 pending";</script>
+</div>
+</div>
+</body>
+</html>
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html b/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html
new file mode 100644
index 000000000..8bf1ed9cd
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html
@@ -0,0 +1,387 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>RSpec results</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Expires" content="-1" />
+ <meta http-equiv="Pragma" content="no-cache" />
+ <style type="text/css">
+ body {
+ margin: 0;
+ padding: 0;
+ background: #fff;
+ font-size: 80%;
+ }
+ </style>
+</head>
+<body>
+<div class="rspec-report">
+ <script type="text/javascript">
+ // <![CDATA[
+function moveProgressBar(percentDone) {
+ document.getElementById("rspec-header").style.width = percentDone +"%";
+}
+function makeRed(element_id) {
+ document.getElementById(element_id).style.background = '#C40D0D';
+ document.getElementById(element_id).style.color = '#FFFFFF';
+}
+
+function makeYellow(element_id) {
+ if (element_id == "rspec-header" && document.getElementById(element_id).style.background != '#C40D0D')
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+ else
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+}
+
+ // ]]>
+ </script>
+ <style type="text/css">
+#rspec-header {
+ background: #65C400; color: #fff;
+}
+
+.rspec-report h1 {
+ margin: 0px 10px 0px 10px;
+ padding: 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ font-size: 1.8em;
+}
+
+#summary {
+ margin: 0; padding: 5px 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ text-align: right;
+ position: absolute;
+ top: 0px;
+ right: 0px;
+}
+
+#summary p {
+ margin: 0 0 0 2px;
+}
+
+#summary #totals {
+ font-size: 1.2em;
+}
+
+.example_group {
+ margin: 0 10px 5px;
+ background: #fff;
+}
+
+dl {
+ margin: 0; padding: 0 0 5px;
+ font: normal 11px "Lucida Grande", Helvetica, sans-serif;
+}
+
+dt {
+ padding: 3px;
+ background: #65C400;
+ color: #fff;
+ font-weight: bold;
+}
+
+dd {
+ margin: 5px 0 5px 5px;
+ padding: 3px 3px 3px 18px;
+}
+
+dd.spec.passed {
+ border-left: 5px solid #65C400;
+ border-bottom: 1px solid #65C400;
+ background: #DBFFB4; color: #3D7700;
+}
+
+dd.spec.failed {
+ border-left: 5px solid #C20000;
+ border-bottom: 1px solid #C20000;
+ color: #C20000; background: #FFFBD3;
+}
+
+dd.spec.not_implemented {
+ border-left: 5px solid #FAF834;
+ border-bottom: 1px solid #FAF834;
+ background: #FCFB98; color: #131313;
+}
+
+dd.spec.pending_fixed {
+ border-left: 5px solid #0000C2;
+ border-bottom: 1px solid #0000C2;
+ color: #0000C2; background: #D3FBFF;
+}
+
+.backtrace {
+ color: #000;
+ font-size: 12px;
+}
+
+a {
+ color: #BE5C00;
+}
+
+/* Ruby code, style similar to vibrant ink */
+.ruby {
+ font-size: 12px;
+ font-family: monospace;
+ color: white;
+ background-color: black;
+ padding: 0.1em 0 0.2em 0;
+}
+
+.ruby .keyword { color: #FF6600; }
+.ruby .constant { color: #339999; }
+.ruby .attribute { color: white; }
+.ruby .global { color: white; }
+.ruby .module { color: white; }
+.ruby .class { color: white; }
+.ruby .string { color: #66FF00; }
+.ruby .ident { color: white; }
+.ruby .method { color: #FFCC00; }
+.ruby .number { color: white; }
+.ruby .char { color: white; }
+.ruby .comment { color: #9933CC; }
+.ruby .symbol { color: white; }
+.ruby .regex { color: #44B4CC; }
+.ruby .punct { color: white; }
+.ruby .escape { color: white; }
+.ruby .interp { color: white; }
+.ruby .expr { color: white; }
+
+.ruby .offending { background-color: gray; }
+.ruby .linenum {
+ width: 75px;
+ padding: 0.1em 1em 0.2em 0;
+ color: #000000;
+ background-color: #FFFBD3;
+}
+
+ </style>
+
+<div id="rspec-header">
+ <h1>RSpec Results</h1>
+
+ <div id="summary">
+ <p id="totals">&nbsp;</p>
+ <p id="duration">&nbsp;</p>
+ </div>
+</div>
+
+<div class="results">
+<div class="example_group">
+ <dl>
+ <dt id="example_group_1">Mocker</dt>
+ <script type="text/javascript">moveProgressBar('5.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to call mock()</span></dd>
+ <script type="text/javascript">makeRed('rspec-header');</script>
+ <script type="text/javascript">makeRed('example_group_1');</script>
+ <script type="text/javascript">moveProgressBar('11.7');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when expected message not received</span>
+ <div class="failure" id="failure_1">
+ <div class="message"><pre>Mock 'poke me' expected :poke with (any args) once, but received it 0 times</pre></div>
+ <div class="backtrace"><pre>/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:13:in `should_receive'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:24:in `run'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `instance_eval'</pre></div>
+ <pre class="ruby"><code><span class="linenum">11</span> it "should fail when expected message not received" do
+<span class="linenum">12</span> mock = mock("poke me")
+<span class="offending"><span class="linenum">13</span> mock.should_receive(:poke)</span>
+<span class="linenum">14</span> end
+<span class="linenum">15</span>
+<span class="linenum">16</span><span class="comment"># gem install syntax to get syntax highlighting</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('17.6');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when messages are received out of order</span>
+ <div class="failure" id="failure_2">
+ <div class="message"><pre>Mock 'one two three' received :three out of order</pre></div>
+ <div class="backtrace"><pre>/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:22:in `three'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:16:in `instance_eval'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:24:in `run'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `instance_eval'</pre></div>
+ <pre class="ruby"><code><span class="linenum">20</span> mock.should_receive(:three).ordered
+<span class="linenum">21</span> mock.one
+<span class="offending"><span class="linenum">22</span> mock.three</span>
+<span class="linenum">23</span> mock.two
+<span class="linenum">24</span> end
+<span class="linenum">25</span><span class="comment"># gem install syntax to get syntax highlighting</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('23.5');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should get yelled at when sending unexpected messages</span>
+ <div class="failure" id="failure_3">
+ <div class="message"><pre>Mock 'don't talk to me' expected :any_message_at_all with (any args) 0 times, but received it once</pre></div>
+ <div class="backtrace"><pre>/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:28:in `should_not_receive'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:24:in `run'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `instance_eval'</pre></div>
+ <pre class="ruby"><code><span class="linenum">26</span> it "should get yelled at when sending unexpected messages" do
+<span class="linenum">27</span> mock = mock("don't talk to me")
+<span class="offending"><span class="linenum">28</span> mock.should_not_receive(:any_message_at_all)</span>
+<span class="linenum">29</span> mock.any_message_at_all
+<span class="linenum">30</span> end
+<span class="linenum">31</span><span class="comment"># gem install syntax to get syntax highlighting</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('29.4');</script>
+ <dd class="spec pending_fixed">
+ <span class="failed_spec_name">has a bug we need to fix</span>
+ <div class="failure" id="failure_4">
+ <div class="message"><pre>Expected pending 'here is the bug' to fail. No Error was raised.</pre></div>
+ <div class="backtrace"><pre>/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:33:in `pending'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:33:in `instance_eval'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:24:in `run'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `instance_eval'</pre></div>
+ <pre class="ruby"><code><span class="linenum">31</span>
+<span class="linenum">32</span> it "has a bug we need to fix" do
+<span class="offending"><span class="linenum">33</span> pending "here is the bug" do</span>
+<span class="linenum">34</span> # Actually, no. It's fixed. This will fail because it passes :-)
+<span class="linenum">35</span> mock = mock("Bug")
+<span class="linenum">36</span><span class="comment"># gem install syntax to get syntax highlighting</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_2">Running specs with --diff</dt>
+ <script type="text/javascript">makeRed('example_group_2');</script>
+ <script type="text/javascript">moveProgressBar('35.2');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different strings</span>
+ <div class="failure" id="failure_5">
+ <div class="message"><pre>expected: &quot;RSpec is a\nbehaviour driven development\nframework for Ruby\n&quot;,
+ got: &quot;RSpec is a\nbehavior driven development\nframework for Ruby\n&quot; (using ==)
+Diff:
+@@ -1,4 +1,4 @@
+ RSpec is a
+-behavior driven development
++behaviour driven development
+ framework for Ruby
+</pre></div>
+ <div class="backtrace"><pre>/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/diffing_spec.rb:13:in `=='
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:24:in `run'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `instance_eval'</pre></div>
+ <pre class="ruby"><code><span class="linenum">11</span>framework for Ruby
+<span class="linenum">12</span>EOF
+<span class="offending"><span class="linenum">13</span> usa.should == uk</span>
+<span class="linenum">14</span> end
+<span class="linenum">15</span>
+<span class="linenum">16</span><span class="comment"># gem install syntax to get syntax highlighting</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('41.1');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different objects' pretty representation</span>
+ <div class="failure" id="failure_6">
+ <div class="message"><pre>expected &lt;Animal
+name=bob,
+species=tortoise
+&gt;
+, got &lt;Animal
+name=bob,
+species=giraffe
+&gt;
+ (using .eql?)
+Diff:
+@@ -1,5 +1,5 @@
+ &lt;Animal
+ name=bob,
+-species=giraffe
++species=tortoise
+ &gt;
+</pre></div>
+ <div class="backtrace"><pre>/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/diffing_spec.rb:34:in `should'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/diffing_spec.rb:31:in `instance_eval'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:24:in `run'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/spec/spec/runner/formatter/html_formatter_spec.rb:20:in `instance_eval'</pre></div>
+ <pre class="ruby"><code><span class="linenum">32</span> expected = Animal.new "bob", "giraffe"
+<span class="linenum">33</span> actual = Animal.new "bob", "tortoise"
+<span class="offending"><span class="linenum">34</span> expected.should eql(actual)</span>
+<span class="linenum">35</span> end
+<span class="linenum">36</span>end
+<span class="linenum">37</span><span class="comment"># gem install syntax to get syntax highlighting</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_3">A consumer of a stub</dt>
+ <script type="text/javascript">moveProgressBar('47.0');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to stub methods on any Object</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_4">A stubbed method on a class</dt>
+ <script type="text/javascript">moveProgressBar('52.9');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should return the stubbed value</span></dd>
+ <script type="text/javascript">moveProgressBar('58.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should revert to the original method after each spec</span></dd>
+ <script type="text/javascript">moveProgressBar('64.7');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_5">A mock</dt>
+ <script type="text/javascript">moveProgressBar('70.5');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub!</span></dd>
+ <script type="text/javascript">moveProgressBar('76.4');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock</span></dd>
+ <script type="text/javascript">moveProgressBar('82.3');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_6">pending example (using pending method)</dt>
+ <script type="text/javascript">makeYellow('example_group_6');</script>
+ <script type="text/javascript">moveProgressBar('88.2');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_7">pending example (with no block)</dt>
+ <script type="text/javascript">makeYellow('example_group_7');</script>
+ <script type="text/javascript">moveProgressBar('94.1');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: Not Yet Implemented&quot; (PENDING: Not Yet Implemented)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_8">pending example (with block for pending)</dt>
+ <script type="text/javascript">makeYellow('example_group_8');</script>
+ <script type="text/javascript">moveProgressBar('100.0');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should have a failing block, passed to pending, reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>x seconds</strong>";</script>
+<script type="text/javascript">document.getElementById('totals').innerHTML = "17 examples, 6 failures, 3 pending";</script>
+</div>
+</div>
+</body>
+</html>
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.5.html b/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.5.html
new file mode 100644
index 000000000..cda7226bf
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.5.html
@@ -0,0 +1,371 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>RSpec results</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Expires" content="-1" />
+ <meta http-equiv="Pragma" content="no-cache" />
+ <style type="text/css">
+ body {
+ margin: 0;
+ padding: 0;
+ background: #fff;
+ font-size: 80%;
+ }
+ </style>
+</head>
+<body>
+<div class="rspec-report">
+ <script type="text/javascript">
+ // <![CDATA[
+function moveProgressBar(percentDone) {
+ document.getElementById("rspec-header").style.width = percentDone +"%";
+}
+function makeRed(element_id) {
+ document.getElementById(element_id).style.background = '#C40D0D';
+ document.getElementById(element_id).style.color = '#FFFFFF';
+}
+
+function makeYellow(element_id) {
+ if (element_id == "rspec-header" && document.getElementById(element_id).style.background != '#C40D0D')
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+ else
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+}
+
+ // ]]>
+ </script>
+ <style type="text/css">
+#rspec-header {
+ background: #65C400; color: #fff;
+}
+
+.rspec-report h1 {
+ margin: 0px 10px 0px 10px;
+ padding: 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ font-size: 1.8em;
+}
+
+#summary {
+ margin: 0; padding: 5px 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ text-align: right;
+ position: absolute;
+ top: 0px;
+ right: 0px;
+}
+
+#summary p {
+ margin: 0 0 0 2px;
+}
+
+#summary #totals {
+ font-size: 1.2em;
+}
+
+.example_group {
+ margin: 0 10px 5px;
+ background: #fff;
+}
+
+dl {
+ margin: 0; padding: 0 0 5px;
+ font: normal 11px "Lucida Grande", Helvetica, sans-serif;
+}
+
+dt {
+ padding: 3px;
+ background: #65C400;
+ color: #fff;
+ font-weight: bold;
+}
+
+dd {
+ margin: 5px 0 5px 5px;
+ padding: 3px 3px 3px 18px;
+}
+
+dd.spec.passed {
+ border-left: 5px solid #65C400;
+ border-bottom: 1px solid #65C400;
+ background: #DBFFB4; color: #3D7700;
+}
+
+dd.spec.failed {
+ border-left: 5px solid #C20000;
+ border-bottom: 1px solid #C20000;
+ color: #C20000; background: #FFFBD3;
+}
+
+dd.spec.not_implemented {
+ border-left: 5px solid #FAF834;
+ border-bottom: 1px solid #FAF834;
+ background: #FCFB98; color: #131313;
+}
+
+dd.spec.pending_fixed {
+ border-left: 5px solid #0000C2;
+ border-bottom: 1px solid #0000C2;
+ color: #0000C2; background: #D3FBFF;
+}
+
+.backtrace {
+ color: #000;
+ font-size: 12px;
+}
+
+a {
+ color: #BE5C00;
+}
+
+/* Ruby code, style similar to vibrant ink */
+.ruby {
+ font-size: 12px;
+ font-family: monospace;
+ color: white;
+ background-color: black;
+ padding: 0.1em 0 0.2em 0;
+}
+
+.ruby .keyword { color: #FF6600; }
+.ruby .constant { color: #339999; }
+.ruby .attribute { color: white; }
+.ruby .global { color: white; }
+.ruby .module { color: white; }
+.ruby .class { color: white; }
+.ruby .string { color: #66FF00; }
+.ruby .ident { color: white; }
+.ruby .method { color: #FFCC00; }
+.ruby .number { color: white; }
+.ruby .char { color: white; }
+.ruby .comment { color: #9933CC; }
+.ruby .symbol { color: white; }
+.ruby .regex { color: #44B4CC; }
+.ruby .punct { color: white; }
+.ruby .escape { color: white; }
+.ruby .interp { color: white; }
+.ruby .expr { color: white; }
+
+.ruby .offending { background-color: gray; }
+.ruby .linenum {
+ width: 75px;
+ padding: 0.1em 1em 0.2em 0;
+ color: #000000;
+ background-color: #FFFBD3;
+}
+
+ </style>
+
+<div id="rspec-header">
+ <h1>RSpec Results</h1>
+
+ <div id="summary">
+ <p id="totals">&nbsp;</p>
+ <p id="duration">&nbsp;</p>
+ </div>
+</div>
+
+<div class="results">
+<div class="example_group">
+ <dl>
+ <dt id="example_group_1">Mocker</dt>
+ <script type="text/javascript">moveProgressBar('5.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to call mock()</span></dd>
+ <script type="text/javascript">makeRed('rspec-header');</script>
+ <script type="text/javascript">makeRed('example_group_1');</script>
+ <script type="text/javascript">moveProgressBar('11.7');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when expected message not received</span>
+ <div class="failure" id="failure_1">
+ <div class="message"><pre>Mock 'poke me' expected :poke with (any args) once, but received it 0 times</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:13:
+./spec/spec/runner/formatter/html_formatter_spec.rb:17:
+./spec/spec/runner/formatter/html_formatter_spec.rb:13:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:13:</pre></div>
+ <pre class="ruby"><code><span class="linenum">11</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should fail when expected message not received</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="linenum">12</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">poke me</span><span class="punct">&quot;)</span>
+<span class="offending"><span class="linenum">13</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_receive</span><span class="punct">(</span><span class="symbol">:poke</span><span class="punct">)</span></span>
+<span class="linenum">14</span> <span class="keyword">end</span>
+<span class="linenum">15</span> </code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('17.6');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when messages are received out of order</span>
+ <div class="failure" id="failure_2">
+ <div class="message"><pre>Mock 'one two three' received :three out of order</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:22:
+./spec/spec/runner/formatter/html_formatter_spec.rb:17:
+./spec/spec/runner/formatter/html_formatter_spec.rb:13:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:13:</pre></div>
+ <pre class="ruby"><code><span class="linenum">20</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_receive</span><span class="punct">(</span><span class="symbol">:three</span><span class="punct">).</span><span class="ident">ordered</span>
+<span class="linenum">21</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">one</span>
+<span class="offending"><span class="linenum">22</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">three</span></span>
+<span class="linenum">23</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">two</span>
+<span class="linenum">24</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('23.5');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should get yelled at when sending unexpected messages</span>
+ <div class="failure" id="failure_3">
+ <div class="message"><pre>Mock 'don't talk to me' expected :any_message_at_all with (any args) 0 times, but received it once</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:28:
+./spec/spec/runner/formatter/html_formatter_spec.rb:17:
+./spec/spec/runner/formatter/html_formatter_spec.rb:13:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:13:</pre></div>
+ <pre class="ruby"><code><span class="linenum">26</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should get yelled at when sending unexpected messages</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="linenum">27</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">don't talk to me</span><span class="punct">&quot;)</span>
+<span class="offending"><span class="linenum">28</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_not_receive</span><span class="punct">(</span><span class="symbol">:any_message_at_all</span><span class="punct">)</span></span>
+<span class="linenum">29</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">any_message_at_all</span>
+<span class="linenum">30</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('29.4');</script>
+ <dd class="spec pending_fixed">
+ <span class="failed_spec_name">has a bug we need to fix</span>
+ <div class="failure" id="failure_4">
+ <div class="message"><pre>Expected pending 'here is the bug' to fail. No Error was raised.</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:33:
+./spec/spec/runner/formatter/html_formatter_spec.rb:17:
+./spec/spec/runner/formatter/html_formatter_spec.rb:13:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:13:</pre></div>
+ <pre class="ruby"><code><span class="linenum">31</span>
+<span class="linenum">32</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">has a bug we need to fix</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="offending"><span class="linenum">33</span> <span class="ident">pending</span> <span class="punct">&quot;</span><span class="string">here is the bug</span><span class="punct">&quot;</span> <span class="keyword">do</span></span>
+<span class="linenum">34</span> <span class="comment"># Actually, no. It's fixed. This will fail because it passes :-)</span>
+<span class="linenum">35</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">Bug</span><span class="punct">&quot;)</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_2">Running specs with --diff</dt>
+ <script type="text/javascript">makeRed('example_group_2');</script>
+ <script type="text/javascript">moveProgressBar('35.2');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different strings</span>
+ <div class="failure" id="failure_5">
+ <div class="message"><pre>expected: &quot;RSpec is a\nbehaviour driven development\nframework for Ruby\n&quot;,
+ got: &quot;RSpec is a\nbehavior driven development\nframework for Ruby\n&quot; (using ==)
+Diff:
+@@ -1,4 +1,4 @@
+ RSpec is a
+-behavior driven development
++behaviour driven development
+ framework for Ruby
+</pre></div>
+ <div class="backtrace"><pre>./failing_examples/diffing_spec.rb:13:
+./spec/spec/runner/formatter/html_formatter_spec.rb:17:
+./spec/spec/runner/formatter/html_formatter_spec.rb:13:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:13:</pre></div>
+ <pre class="ruby"><code><span class="linenum">11</span><span class="ident">framework</span> <span class="keyword">for</span> <span class="constant">Ruby</span>
+<span class="linenum">12</span><span class="constant">EOF</span>
+<span class="offending"><span class="linenum">13</span> <span class="ident">usa</span><span class="punct">.</span><span class="ident">should</span> <span class="punct">==</span> <span class="ident">uk</span></span>
+<span class="linenum">14</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('41.1');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different objects' pretty representation</span>
+ <div class="failure" id="failure_6">
+ <div class="message"><pre>expected &lt;Animal
+name=bob,
+species=tortoise
+&gt;
+, got &lt;Animal
+name=bob,
+species=giraffe
+&gt;
+ (using .eql?)
+Diff:
+@@ -1,5 +1,5 @@
+ &lt;Animal
+ name=bob,
+-species=giraffe
++species=tortoise
+ &gt;
+</pre></div>
+ <div class="backtrace"><pre>./failing_examples/diffing_spec.rb:34:
+./spec/spec/runner/formatter/html_formatter_spec.rb:17:
+./spec/spec/runner/formatter/html_formatter_spec.rb:13:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:13:</pre></div>
+ <pre class="ruby"><code><span class="linenum">32</span> <span class="ident">expected</span> <span class="punct">=</span> <span class="constant">Animal</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">&quot;</span><span class="string">bob</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">giraffe</span><span class="punct">&quot;</span>
+<span class="linenum">33</span> <span class="ident">actual</span> <span class="punct">=</span> <span class="constant">Animal</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">&quot;</span><span class="string">bob</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">tortoise</span><span class="punct">&quot;</span>
+<span class="offending"><span class="linenum">34</span> <span class="ident">expected</span><span class="punct">.</span><span class="ident">should</span> <span class="ident">eql</span><span class="punct">(</span><span class="ident">actual</span><span class="punct">)</span></span>
+<span class="linenum">35</span> <span class="keyword">end</span>
+<span class="linenum">36</span><span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_3">A consumer of a stub</dt>
+ <script type="text/javascript">moveProgressBar('47.0');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to stub methods on any Object</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_4">A stubbed method on a class</dt>
+ <script type="text/javascript">moveProgressBar('52.9');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should return the stubbed value</span></dd>
+ <script type="text/javascript">moveProgressBar('58.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should revert to the original method after each spec</span></dd>
+ <script type="text/javascript">moveProgressBar('64.7');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_5">A mock</dt>
+ <script type="text/javascript">moveProgressBar('70.5');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub!</span></dd>
+ <script type="text/javascript">moveProgressBar('76.4');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock</span></dd>
+ <script type="text/javascript">moveProgressBar('82.3');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_6">pending example (using pending method)</dt>
+ <script type="text/javascript">makeYellow('example_group_6');</script>
+ <script type="text/javascript">moveProgressBar('88.2');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_7">pending example (with no block)</dt>
+ <script type="text/javascript">makeYellow('example_group_7');</script>
+ <script type="text/javascript">moveProgressBar('94.1');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: Not Yet Implemented&quot; (PENDING: Not Yet Implemented)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_8">pending example (with block for pending)</dt>
+ <script type="text/javascript">makeYellow('example_group_8');</script>
+ <script type="text/javascript">moveProgressBar('100.0');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should have a failing block, passed to pending, reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>x seconds</strong>";</script>
+<script type="text/javascript">document.getElementById('totals').innerHTML = "17 examples, 6 failures, 3 pending";</script>
+</div>
+</div>
+</body>
+</html>
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.6-jruby.html b/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.6-jruby.html
new file mode 100644
index 000000000..466621865
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.6-jruby.html
@@ -0,0 +1,381 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>RSpec results</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Expires" content="-1" />
+ <meta http-equiv="Pragma" content="no-cache" />
+ <style type="text/css">
+ body {
+ margin: 0;
+ padding: 0;
+ background: #fff;
+ font-size: 80%;
+ }
+ </style>
+</head>
+<body>
+<div class="rspec-report">
+ <script type="text/javascript">
+ // <![CDATA[
+function moveProgressBar(percentDone) {
+ document.getElementById("rspec-header").style.width = percentDone +"%";
+}
+function makeRed(element_id) {
+ document.getElementById(element_id).style.background = '#C40D0D';
+ document.getElementById(element_id).style.color = '#FFFFFF';
+}
+
+function makeYellow(element_id) {
+ if (element_id == "rspec-header" && document.getElementById(element_id).style.background != '#C40D0D')
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+ else
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+}
+
+ // ]]>
+ </script>
+ <style type="text/css">
+#rspec-header {
+ background: #65C400; color: #fff;
+}
+
+.rspec-report h1 {
+ margin: 0px 10px 0px 10px;
+ padding: 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ font-size: 1.8em;
+}
+
+#summary {
+ margin: 0; padding: 5px 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ text-align: right;
+ position: absolute;
+ top: 0px;
+ right: 0px;
+}
+
+#summary p {
+ margin: 0 0 0 2px;
+}
+
+#summary #totals {
+ font-size: 1.2em;
+}
+
+.example_group {
+ margin: 0 10px 5px;
+ background: #fff;
+}
+
+dl {
+ margin: 0; padding: 0 0 5px;
+ font: normal 11px "Lucida Grande", Helvetica, sans-serif;
+}
+
+dt {
+ padding: 3px;
+ background: #65C400;
+ color: #fff;
+ font-weight: bold;
+}
+
+dd {
+ margin: 5px 0 5px 5px;
+ padding: 3px 3px 3px 18px;
+}
+
+dd.spec.passed {
+ border-left: 5px solid #65C400;
+ border-bottom: 1px solid #65C400;
+ background: #DBFFB4; color: #3D7700;
+}
+
+dd.spec.failed {
+ border-left: 5px solid #C20000;
+ border-bottom: 1px solid #C20000;
+ color: #C20000; background: #FFFBD3;
+}
+
+dd.spec.not_implemented {
+ border-left: 5px solid #FAF834;
+ border-bottom: 1px solid #FAF834;
+ background: #FCFB98; color: #131313;
+}
+
+dd.spec.pending_fixed {
+ border-left: 5px solid #0000C2;
+ border-bottom: 1px solid #0000C2;
+ color: #0000C2; background: #D3FBFF;
+}
+
+.backtrace {
+ color: #000;
+ font-size: 12px;
+}
+
+a {
+ color: #BE5C00;
+}
+
+/* Ruby code, style similar to vibrant ink */
+.ruby {
+ font-size: 12px;
+ font-family: monospace;
+ color: white;
+ background-color: black;
+ padding: 0.1em 0 0.2em 0;
+}
+
+.ruby .keyword { color: #FF6600; }
+.ruby .constant { color: #339999; }
+.ruby .attribute { color: white; }
+.ruby .global { color: white; }
+.ruby .module { color: white; }
+.ruby .class { color: white; }
+.ruby .string { color: #66FF00; }
+.ruby .ident { color: white; }
+.ruby .method { color: #FFCC00; }
+.ruby .number { color: white; }
+.ruby .char { color: white; }
+.ruby .comment { color: #9933CC; }
+.ruby .symbol { color: white; }
+.ruby .regex { color: #44B4CC; }
+.ruby .punct { color: white; }
+.ruby .escape { color: white; }
+.ruby .interp { color: white; }
+.ruby .expr { color: white; }
+
+.ruby .offending { background-color: gray; }
+.ruby .linenum {
+ width: 75px;
+ padding: 0.1em 1em 0.2em 0;
+ color: #000000;
+ background-color: #FFFBD3;
+}
+
+ </style>
+
+<div id="rspec-header">
+ <h1>RSpec Results</h1>
+
+ <div id="summary">
+ <p id="totals">&nbsp;</p>
+ <p id="duration">&nbsp;</p>
+ </div>
+</div>
+
+<div class="results">
+<div class="example_group">
+ <dl>
+ <dt id="example_group_1">Mocker</dt>
+ <script type="text/javascript">moveProgressBar('5.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to call mock()</span></dd>
+ <script type="text/javascript">makeRed('rspec-header');</script>
+ <script type="text/javascript">makeRed('example_group_1');</script>
+ <script type="text/javascript">moveProgressBar('11.7');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when expected message not received</span>
+ <div class="failure" id="failure_1">
+ <div class="message"><pre>Mock 'poke me' expected :poke with (any args) once, but received it 0 times</pre></div>
+ <div class="backtrace"><pre>/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:13:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:28:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:in `instance_eval'</pre></div>
+ <pre class="ruby"><code><span class="linenum">11</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should fail when expected message not received</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="linenum">12</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">poke me</span><span class="punct">&quot;)</span>
+<span class="offending"><span class="linenum">13</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_receive</span><span class="punct">(</span><span class="symbol">:poke</span><span class="punct">)</span></span>
+<span class="linenum">14</span> <span class="keyword">end</span>
+<span class="linenum">15</span> </code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('17.6');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when messages are received out of order</span>
+ <div class="failure" id="failure_2">
+ <div class="message"><pre>Mock 'one two three' received :three out of order</pre></div>
+ <div class="backtrace"><pre>/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:22:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:16:in `instance_eval'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:28:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:in `instance_eval'</pre></div>
+ <pre class="ruby"><code><span class="linenum">20</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_receive</span><span class="punct">(</span><span class="symbol">:three</span><span class="punct">).</span><span class="ident">ordered</span>
+<span class="linenum">21</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">one</span>
+<span class="offending"><span class="linenum">22</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">three</span></span>
+<span class="linenum">23</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">two</span>
+<span class="linenum">24</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('23.5');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should get yelled at when sending unexpected messages</span>
+ <div class="failure" id="failure_3">
+ <div class="message"><pre>Mock 'don't talk to me' expected :any_message_at_all with (any args) 0 times, but received it once</pre></div>
+ <div class="backtrace"><pre>/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:28:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:28:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:in `instance_eval'</pre></div>
+ <pre class="ruby"><code><span class="linenum">26</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should get yelled at when sending unexpected messages</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="linenum">27</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">don't talk to me</span><span class="punct">&quot;)</span>
+<span class="offending"><span class="linenum">28</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_not_receive</span><span class="punct">(</span><span class="symbol">:any_message_at_all</span><span class="punct">)</span></span>
+<span class="linenum">29</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">any_message_at_all</span>
+<span class="linenum">30</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('29.4');</script>
+ <dd class="spec pending_fixed">
+ <span class="failed_spec_name">has a bug we need to fix</span>
+ <div class="failure" id="failure_4">
+ <div class="message"><pre>Expected pending 'here is the bug' to fail. No Error was raised.</pre></div>
+ <div class="backtrace"><pre>/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:33:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/mocking_example.rb:33:in `instance_eval'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:28:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:in `instance_eval'</pre></div>
+ <pre class="ruby"><code><span class="linenum">31</span>
+<span class="linenum">32</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">has a bug we need to fix</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="offending"><span class="linenum">33</span> <span class="ident">pending</span> <span class="punct">&quot;</span><span class="string">here is the bug</span><span class="punct">&quot;</span> <span class="keyword">do</span></span>
+<span class="linenum">34</span> <span class="comment"># Actually, no. It's fixed. This will fail because it passes :-)</span>
+<span class="linenum">35</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">Bug</span><span class="punct">&quot;)</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_2">Running specs with --diff</dt>
+ <script type="text/javascript">makeRed('example_group_2');</script>
+ <script type="text/javascript">moveProgressBar('35.2');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different strings</span>
+ <div class="failure" id="failure_5">
+ <div class="message"><pre>expected: &quot;RSpec is a\nbehaviour driven development\nframework for Ruby\n&quot;,
+ got: &quot;RSpec is a\nbehavior driven development\nframework for Ruby\n&quot; (using ==)
+Diff:
+@@ -1,4 +1,4 @@
+ RSpec is a
+-behavior driven development
++behaviour driven development
+ framework for Ruby
+</pre></div>
+ <div class="backtrace"><pre>/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/diffing_spec.rb:13:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/diffing_spec.rb:2:in `instance_eval'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:28:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:in `instance_eval'</pre></div>
+ <pre class="ruby"><code><span class="linenum">11</span><span class="ident">framework</span> <span class="keyword">for</span> <span class="constant">Ruby</span>
+<span class="linenum">12</span><span class="constant">EOF</span>
+<span class="offending"><span class="linenum">13</span> <span class="ident">usa</span><span class="punct">.</span><span class="ident">should</span> <span class="punct">==</span> <span class="ident">uk</span></span>
+<span class="linenum">14</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('41.1');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different objects' pretty representation</span>
+ <div class="failure" id="failure_6">
+ <div class="message"><pre>expected &lt;Animal
+name=bob,
+species=tortoise
+&gt;
+, got &lt;Animal
+name=bob,
+species=giraffe
+&gt;
+ (using .eql?)
+Diff:
+@@ -1,5 +1,5 @@
+ &lt;Animal
+ name=bob,
+-species=giraffe
++species=tortoise
+ &gt;
+</pre></div>
+ <div class="backtrace"><pre>/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/diffing_spec.rb:34:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./failing_examples/diffing_spec.rb:31:in `instance_eval'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:28:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:in `chdir'
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:
+/Users/david/projects/ruby/jruby/testsuites/rspec/target/rspec/./spec/spec/runner/formatter/html_formatter_spec.rb:24:in `instance_eval'</pre></div>
+ <pre class="ruby"><code><span class="linenum">32</span> <span class="ident">expected</span> <span class="punct">=</span> <span class="constant">Animal</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">&quot;</span><span class="string">bob</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">giraffe</span><span class="punct">&quot;</span>
+<span class="linenum">33</span> <span class="ident">actual</span> <span class="punct">=</span> <span class="constant">Animal</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">&quot;</span><span class="string">bob</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">tortoise</span><span class="punct">&quot;</span>
+<span class="offending"><span class="linenum">34</span> <span class="ident">expected</span><span class="punct">.</span><span class="ident">should</span> <span class="ident">eql</span><span class="punct">(</span><span class="ident">actual</span><span class="punct">)</span></span>
+<span class="linenum">35</span> <span class="keyword">end</span>
+<span class="linenum">36</span><span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_3">A consumer of a stub</dt>
+ <script type="text/javascript">moveProgressBar('47.0');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to stub methods on any Object</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_4">A stubbed method on a class</dt>
+ <script type="text/javascript">moveProgressBar('52.9');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should return the stubbed value</span></dd>
+ <script type="text/javascript">moveProgressBar('58.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should revert to the original method after each spec</span></dd>
+ <script type="text/javascript">moveProgressBar('64.7');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_5">A mock</dt>
+ <script type="text/javascript">moveProgressBar('70.5');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub!</span></dd>
+ <script type="text/javascript">moveProgressBar('76.4');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock</span></dd>
+ <script type="text/javascript">moveProgressBar('82.3');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_6">pending example (using pending method)</dt>
+ <script type="text/javascript">makeYellow('example_group_6');</script>
+ <script type="text/javascript">moveProgressBar('88.2');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_7">pending example (with no block)</dt>
+ <script type="text/javascript">makeYellow('example_group_7');</script>
+ <script type="text/javascript">moveProgressBar('94.1');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: Not Yet Implemented&quot; (PENDING: Not Yet Implemented)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_8">pending example (with block for pending)</dt>
+ <script type="text/javascript">makeYellow('example_group_8');</script>
+ <script type="text/javascript">moveProgressBar('100.0');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should have a failing block, passed to pending, reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>x seconds</strong>";</script>
+<script type="text/javascript">document.getElementById('totals').innerHTML = "17 examples, 6 failures, 3 pending";</script>
+</div>
+</div>
+</body>
+</html>
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.6.html b/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.6.html
new file mode 100644
index 000000000..511495bcd
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/html_formatted-1.8.6.html
@@ -0,0 +1,365 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>RSpec results</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Expires" content="-1" />
+ <meta http-equiv="Pragma" content="no-cache" />
+ <style type="text/css">
+ body {
+ margin: 0;
+ padding: 0;
+ background: #fff;
+ font-size: 80%;
+ }
+ </style>
+</head>
+<body>
+<div class="rspec-report">
+ <script type="text/javascript">
+ // <![CDATA[
+function moveProgressBar(percentDone) {
+ document.getElementById("rspec-header").style.width = percentDone +"%";
+}
+function makeRed(element_id) {
+ document.getElementById(element_id).style.background = '#C40D0D';
+ document.getElementById(element_id).style.color = '#FFFFFF';
+}
+
+function makeYellow(element_id) {
+ if (element_id == "rspec-header" && document.getElementById(element_id).style.background != '#C40D0D')
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+ else
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+}
+
+ // ]]>
+ </script>
+ <style type="text/css">
+#rspec-header {
+ background: #65C400; color: #fff;
+}
+
+.rspec-report h1 {
+ margin: 0px 10px 0px 10px;
+ padding: 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ font-size: 1.8em;
+}
+
+#summary {
+ margin: 0; padding: 5px 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ text-align: right;
+ position: absolute;
+ top: 0px;
+ right: 0px;
+}
+
+#summary p {
+ margin: 0 0 0 2px;
+}
+
+#summary #totals {
+ font-size: 1.2em;
+}
+
+.example_group {
+ margin: 0 10px 5px;
+ background: #fff;
+}
+
+dl {
+ margin: 0; padding: 0 0 5px;
+ font: normal 11px "Lucida Grande", Helvetica, sans-serif;
+}
+
+dt {
+ padding: 3px;
+ background: #65C400;
+ color: #fff;
+ font-weight: bold;
+}
+
+dd {
+ margin: 5px 0 5px 5px;
+ padding: 3px 3px 3px 18px;
+}
+
+dd.spec.passed {
+ border-left: 5px solid #65C400;
+ border-bottom: 1px solid #65C400;
+ background: #DBFFB4; color: #3D7700;
+}
+
+dd.spec.failed {
+ border-left: 5px solid #C20000;
+ border-bottom: 1px solid #C20000;
+ color: #C20000; background: #FFFBD3;
+}
+
+dd.spec.not_implemented {
+ border-left: 5px solid #FAF834;
+ border-bottom: 1px solid #FAF834;
+ background: #FCFB98; color: #131313;
+}
+
+dd.spec.pending_fixed {
+ border-left: 5px solid #0000C2;
+ border-bottom: 1px solid #0000C2;
+ color: #0000C2; background: #D3FBFF;
+}
+
+.backtrace {
+ color: #000;
+ font-size: 12px;
+}
+
+a {
+ color: #BE5C00;
+}
+
+/* Ruby code, style similar to vibrant ink */
+.ruby {
+ font-size: 12px;
+ font-family: monospace;
+ color: white;
+ background-color: black;
+ padding: 0.1em 0 0.2em 0;
+}
+
+.ruby .keyword { color: #FF6600; }
+.ruby .constant { color: #339999; }
+.ruby .attribute { color: white; }
+.ruby .global { color: white; }
+.ruby .module { color: white; }
+.ruby .class { color: white; }
+.ruby .string { color: #66FF00; }
+.ruby .ident { color: white; }
+.ruby .method { color: #FFCC00; }
+.ruby .number { color: white; }
+.ruby .char { color: white; }
+.ruby .comment { color: #9933CC; }
+.ruby .symbol { color: white; }
+.ruby .regex { color: #44B4CC; }
+.ruby .punct { color: white; }
+.ruby .escape { color: white; }
+.ruby .interp { color: white; }
+.ruby .expr { color: white; }
+
+.ruby .offending { background-color: gray; }
+.ruby .linenum {
+ width: 75px;
+ padding: 0.1em 1em 0.2em 0;
+ color: #000000;
+ background-color: #FFFBD3;
+}
+
+ </style>
+
+<div id="rspec-header">
+ <h1>RSpec Results</h1>
+
+ <div id="summary">
+ <p id="totals">&nbsp;</p>
+ <p id="duration">&nbsp;</p>
+ </div>
+</div>
+
+<div class="results">
+<div class="example_group">
+ <dl>
+ <dt id="example_group_1">Mocker</dt>
+ <script type="text/javascript">moveProgressBar('5.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to call mock()</span></dd>
+ <script type="text/javascript">makeRed('rspec-header');</script>
+ <script type="text/javascript">makeRed('example_group_1');</script>
+ <script type="text/javascript">moveProgressBar('11.7');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when expected message not received</span>
+ <div class="failure" id="failure_1">
+ <div class="message"><pre>Mock 'poke me' expected :poke with (any args) once, but received it 0 times</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:13:
+./spec/spec/runner/formatter/html_formatter_spec.rb:18:
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:</pre></div>
+ <pre class="ruby"><code><span class="linenum">11</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should fail when expected message not received</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="linenum">12</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">poke me</span><span class="punct">&quot;)</span>
+<span class="offending"><span class="linenum">13</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_receive</span><span class="punct">(</span><span class="symbol">:poke</span><span class="punct">)</span></span>
+<span class="linenum">14</span> <span class="keyword">end</span>
+<span class="linenum">15</span> </code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('17.6');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when messages are received out of order</span>
+ <div class="failure" id="failure_2">
+ <div class="message"><pre>Mock 'one two three' received :three out of order</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:22:
+./spec/spec/runner/formatter/html_formatter_spec.rb:18:
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:</pre></div>
+ <pre class="ruby"><code><span class="linenum">20</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_receive</span><span class="punct">(</span><span class="symbol">:three</span><span class="punct">).</span><span class="ident">ordered</span>
+<span class="linenum">21</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">one</span>
+<span class="offending"><span class="linenum">22</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">three</span></span>
+<span class="linenum">23</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">two</span>
+<span class="linenum">24</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('23.5');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should get yelled at when sending unexpected messages</span>
+ <div class="failure" id="failure_3">
+ <div class="message"><pre>Mock 'don't talk to me' expected :any_message_at_all with (any args) 0 times, but received it once</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:28:
+./spec/spec/runner/formatter/html_formatter_spec.rb:18:
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:</pre></div>
+ <pre class="ruby"><code><span class="linenum">26</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should get yelled at when sending unexpected messages</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="linenum">27</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">don't talk to me</span><span class="punct">&quot;)</span>
+<span class="offending"><span class="linenum">28</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_not_receive</span><span class="punct">(</span><span class="symbol">:any_message_at_all</span><span class="punct">)</span></span>
+<span class="linenum">29</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">any_message_at_all</span>
+<span class="linenum">30</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('29.4');</script>
+ <dd class="spec pending_fixed">
+ <span class="failed_spec_name">has a bug we need to fix</span>
+ <div class="failure" id="failure_4">
+ <div class="message"><pre>Expected pending 'here is the bug' to fail. No Error was raised.</pre></div>
+
+ <pre class="ruby"><code><span class="linenum">31</span>
+<span class="linenum">32</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">has a bug we need to fix</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="offending"><span class="linenum">33</span> <span class="ident">pending</span> <span class="punct">&quot;</span><span class="string">here is the bug</span><span class="punct">&quot;</span> <span class="keyword">do</span></span>
+<span class="linenum">34</span> <span class="comment"># Actually, no. It's fixed. This will fail because it passes :-)</span>
+<span class="linenum">35</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">Bug</span><span class="punct">&quot;)</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_2">Running specs with --diff</dt>
+ <script type="text/javascript">makeRed('example_group_2');</script>
+ <script type="text/javascript">moveProgressBar('35.2');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different strings</span>
+ <div class="failure" id="failure_5">
+ <div class="message"><pre>expected: &quot;RSpec is a\nbehaviour driven development\nframework for Ruby\n&quot;,
+ got: &quot;RSpec is a\nbehavior driven development\nframework for Ruby\n&quot; (using ==)
+Diff:
+@@ -1,4 +1,4 @@
+ RSpec is a
+-behavior driven development
++behaviour driven development
+ framework for Ruby
+</pre></div>
+
+ <pre class="ruby"><code><span class="linenum">11</span><span class="ident">framework</span> <span class="keyword">for</span> <span class="constant">Ruby</span>
+<span class="linenum">12</span><span class="constant">EOF</span>
+<span class="offending"><span class="linenum">13</span> <span class="ident">usa</span><span class="punct">.</span><span class="ident">should</span> <span class="punct">==</span> <span class="ident">uk</span></span>
+<span class="linenum">14</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('41.1');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different objects' pretty representation</span>
+ <div class="failure" id="failure_6">
+ <div class="message"><pre>expected &lt;Animal
+name=bob,
+species=tortoise
+&gt;
+, got &lt;Animal
+name=bob,
+species=giraffe
+&gt;
+ (using .eql?)
+Diff:
+@@ -1,5 +1,5 @@
+ &lt;Animal
+ name=bob,
+-species=giraffe
++species=tortoise
+ &gt;
+</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:33:
+./spec/spec/runner/formatter/html_formatter_spec.rb:18:
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:</pre></div>
+ <pre class="ruby"><code><span class="linenum">32</span> <span class="ident">expected</span> <span class="punct">=</span> <span class="constant">Animal</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">&quot;</span><span class="string">bob</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">giraffe</span><span class="punct">&quot;</span>
+<span class="linenum">33</span> <span class="ident">actual</span> <span class="punct">=</span> <span class="constant">Animal</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">&quot;</span><span class="string">bob</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">tortoise</span><span class="punct">&quot;</span>
+<span class="offending"><span class="linenum">34</span> <span class="ident">expected</span><span class="punct">.</span><span class="ident">should</span> <span class="ident">eql</span><span class="punct">(</span><span class="ident">actual</span><span class="punct">)</span></span>
+<span class="linenum">35</span> <span class="keyword">end</span>
+<span class="linenum">36</span><span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_3">A consumer of a stub</dt>
+ <script type="text/javascript">moveProgressBar('47.0');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to stub methods on any Object</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_4">A stubbed method on a class</dt>
+ <script type="text/javascript">moveProgressBar('52.9');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should return the stubbed value</span></dd>
+ <script type="text/javascript">moveProgressBar('58.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should revert to the original method after each spec</span></dd>
+ <script type="text/javascript">moveProgressBar('64.7');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_5">A mock</dt>
+ <script type="text/javascript">moveProgressBar('70.5');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub!</span></dd>
+ <script type="text/javascript">moveProgressBar('76.4');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock</span></dd>
+ <script type="text/javascript">moveProgressBar('82.3');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_6">pending example (using pending method)</dt>
+ <script type="text/javascript">makeYellow('example_group_6');</script>
+ <script type="text/javascript">moveProgressBar('88.2');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_7">pending example (with no block)</dt>
+ <script type="text/javascript">makeYellow('example_group_7');</script>
+ <script type="text/javascript">moveProgressBar('94.1');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: Not Yet Implemented&quot; (PENDING: Not Yet Implemented)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_8">pending example (with block for pending)</dt>
+ <script type="text/javascript">makeYellow('example_group_8');</script>
+ <script type="text/javascript">moveProgressBar('100.0');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should have a failing block, passed to pending, reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>x seconds</strong>";</script>
+<script type="text/javascript">document.getElementById('totals').innerHTML = "17 examples, 6 failures, 3 pending";</script>
+</div>
+</div>
+</body>
+</html>
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/html_formatter_spec.rb b/vendor/gems/rspec/spec/spec/runner/formatter/html_formatter_spec.rb
new file mode 100644
index 000000000..5ba39f0e9
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/html_formatter_spec.rb
@@ -0,0 +1,66 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require 'hpricot' # Needed to compare generated with wanted HTML
+require 'spec/runner/formatter/html_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ describe HtmlFormatter do
+ ['--diff', '--dry-run'].each do |opt|
+ def jruby?
+ PLATFORM == 'java'
+ end
+
+ it "should produce HTML identical to the one we designed manually with #{opt}" do
+ root = File.expand_path(File.dirname(__FILE__) + '/../../../..')
+ suffix = jruby? ? '-jruby' : ''
+ expected_file = File.dirname(__FILE__) + "/html_formatted-#{::VERSION}#{suffix}.html"
+ raise "There is no HTML file with expected content for this platform: #{expected_file}" unless File.file?(expected_file)
+ expected_html = File.read(expected_file)
+ unless jruby?
+ raise "There should be no absolute paths in html_formatted.html!!" if (expected_html =~ /\/Users/n || expected_html =~ /\/home/n)
+ end
+
+ Dir.chdir(root) do
+ args = ['failing_examples/mocking_example.rb', 'failing_examples/diffing_spec.rb', 'examples/pure/stubbing_example.rb', 'examples/pure/pending_example.rb', '--format', 'html', opt]
+ err = StringIO.new
+ out = StringIO.new
+ CommandLine.run(
+ OptionParser.parse(args, err, out)
+ )
+
+ seconds = /\d+\.\d+ seconds/
+ html = out.string.gsub seconds, 'x seconds'
+ expected_html.gsub! seconds, 'x seconds'
+
+ if opt == '--diff'
+ # Uncomment this line temporarily in order to overwrite the expected with actual.
+ # Use with care!!!
+ # File.open(expected_file, 'w') {|io| io.write(html)}
+
+ doc = Hpricot(html)
+ backtraces = doc.search("div.backtrace").collect {|e| e.at("/pre").inner_html}
+ doc.search("div.backtrace").remove
+
+ expected_doc = Hpricot(expected_html)
+ expected_backtraces = expected_doc.search("div.backtrace").collect {|e| e.at("/pre").inner_html}
+ expected_doc.search("div.backtrace").remove
+
+ doc.inner_html.should == expected_doc.inner_html
+
+ expected_backtraces.each_with_index do |expected_line, i|
+ expected_path, expected_line_number, expected_suffix = expected_line.split(':')
+ actual_path, actual_line_number, actual_suffix = backtraces[i].split(':')
+ File.expand_path(actual_path).should == File.expand_path(expected_path)
+ actual_line_number.should == expected_line_number
+ end
+ else
+ html.should =~ /This was a dry-run/m
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/profile_formatter_spec.rb b/vendor/gems/rspec/spec/spec/runner/formatter/profile_formatter_spec.rb
new file mode 100644
index 000000000..981805411
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/profile_formatter_spec.rb
@@ -0,0 +1,65 @@
+require File.dirname(__FILE__) + '/../../../spec_helper.rb'
+require 'spec/runner/formatter/profile_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ describe ProfileFormatter do
+ attr_reader :io, :formatter
+ before(:each) do
+ @io = StringIO.new
+ options = mock('options')
+ options.stub!(:colour).and_return(true)
+ @formatter = ProfileFormatter.new(options, io)
+ end
+
+ it "should print a heading" do
+ formatter.start(0)
+ io.string.should eql("Profiling enabled.\n")
+ end
+
+ it "should record the current time when starting a new example" do
+ now = Time.now
+ Time.stub!(:now).and_return(now)
+ formatter.example_started('should foo')
+ formatter.instance_variable_get("@time").should == now
+ end
+
+ it "should correctly record a passed example" do
+ now = Time.now
+ Time.stub!(:now).and_return(now)
+ parent_example_group = Class.new(ExampleGroup).describe('Parent')
+ child_example_group = Class.new(parent_example_group).describe('Child')
+
+ formatter.add_example_group(child_example_group)
+
+ formatter.example_started('when foo')
+ Time.stub!(:now).and_return(now+1)
+ formatter.example_passed(stub('foo', :description => 'i like ice cream'))
+
+ formatter.start_dump
+ io.string.should include('Parent Child')
+ end
+
+ it "should sort the results in descending order" do
+ formatter.instance_variable_set("@example_times", [['a', 'a', 0.1], ['b', 'b', 0.3], ['c', 'c', 0.2]])
+ formatter.start_dump
+ formatter.instance_variable_get("@example_times").should == [ ['b', 'b', 0.3], ['c', 'c', 0.2], ['a', 'a', 0.1]]
+ end
+
+ it "should print the top 10 results" do
+ example_group = Class.new(::Spec::Example::ExampleGroup).describe("ExampleGroup")
+ formatter.add_example_group(example_group)
+ formatter.instance_variable_set("@time", Time.now)
+
+ 15.times do
+ formatter.example_passed(stub('foo', :description => 'i like ice cream'))
+ end
+
+ io.should_receive(:print).exactly(10)
+ formatter.start_dump
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/progress_bar_formatter_spec.rb b/vendor/gems/rspec/spec/spec/runner/formatter/progress_bar_formatter_spec.rb
new file mode 100644
index 000000000..127a617c1
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/progress_bar_formatter_spec.rb
@@ -0,0 +1,127 @@
+require File.dirname(__FILE__) + '/../../../spec_helper.rb'
+require 'spec/runner/formatter/progress_bar_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ describe ProgressBarFormatter do
+ before(:each) do
+ @io = StringIO.new
+ @options = mock('options')
+ @options.stub!(:dry_run).and_return(false)
+ @options.stub!(:colour).and_return(false)
+ @formatter = ProgressBarFormatter.new(@options, @io)
+ end
+
+ it "should produce line break on start dump" do
+ @formatter.start_dump
+ @io.string.should eql("\n")
+ end
+
+ it "should produce standard summary without pending when pending has a 0 count" do
+ @formatter.dump_summary(3, 2, 1, 0)
+ @io.string.should eql("\nFinished in 3 seconds\n\n2 examples, 1 failure\n")
+ end
+
+ it "should produce standard summary" do
+ @formatter.example_pending("example_group", ExampleGroup.new("example"), "message")
+ @io.rewind
+ @formatter.dump_summary(3, 2, 1, 1)
+ @io.string.should eql(%Q|
+Finished in 3 seconds
+
+2 examples, 1 failure, 1 pending
+|)
+ end
+
+ it "should push green dot for passing spec" do
+ @io.should_receive(:tty?).and_return(true)
+ @options.should_receive(:colour).and_return(true)
+ @formatter.example_passed("spec")
+ @io.string.should == "\e[32m.\e[0m"
+ end
+
+ it "should push red F for failure spec" do
+ @io.should_receive(:tty?).and_return(true)
+ @options.should_receive(:colour).and_return(true)
+ @formatter.example_failed("spec", 98, Reporter::Failure.new("c s", Spec::Expectations::ExpectationNotMetError.new))
+ @io.string.should eql("\e[31mF\e[0m")
+ end
+
+ it "should push magenta F for error spec" do
+ @io.should_receive(:tty?).and_return(true)
+ @options.should_receive(:colour).and_return(true)
+ @formatter.example_failed("spec", 98, Reporter::Failure.new("c s", RuntimeError.new))
+ @io.string.should eql("\e[35mF\e[0m")
+ end
+
+ it "should push blue F for fixed pending spec" do
+ @io.should_receive(:tty?).and_return(true)
+ @options.should_receive(:colour).and_return(true)
+ @formatter.example_failed("spec", 98, Reporter::Failure.new("c s", Spec::Example::PendingExampleFixedError.new))
+ @io.string.should eql("\e[34mF\e[0m")
+ end
+
+ it "should push nothing on start" do
+ @formatter.start(4)
+ @io.string.should eql("")
+ end
+
+ it "should ensure two ':' in the first backtrace" do
+ backtrace = ["/tmp/x.rb:1", "/tmp/x.rb:2", "/tmp/x.rb:3"]
+ @formatter.format_backtrace(backtrace).should eql(<<-EOE.rstrip)
+/tmp/x.rb:1:
+/tmp/x.rb:2:
+/tmp/x.rb:3:
+EOE
+
+ backtrace = ["/tmp/x.rb:1: message", "/tmp/x.rb:2", "/tmp/x.rb:3"]
+ @formatter.format_backtrace(backtrace).should eql(<<-EOE.rstrip)
+/tmp/x.rb:1: message
+/tmp/x.rb:2:
+/tmp/x.rb:3:
+EOE
+ end
+
+ it "should dump pending" do
+ @formatter.example_pending("example_group", ExampleGroup.new("example"), "message")
+ @formatter.dump_pending
+ @io.string.should =~ /Pending\:\nexample_group example \(message\)\n/
+ end
+ end
+
+ describe "ProgressBarFormatter outputting to custom out" do
+ before(:each) do
+ @out = mock("out")
+ @options = mock('options')
+ @out.stub!(:puts)
+ @formatter = ProgressBarFormatter.new(@options, @out)
+ @formatter.class.send :public, :output_to_tty?
+ end
+
+ after(:each) do
+ @formatter.class.send :protected, :output_to_tty?
+ end
+
+ it "should not throw NoMethodError on output_to_tty?" do
+ @out.should_receive(:tty?).and_raise(NoMethodError)
+ @formatter.output_to_tty?.should be_false
+ end
+ end
+
+ describe ProgressBarFormatter, "dry run" do
+ before(:each) do
+ @io = StringIO.new
+ options = mock('options')
+ options.stub!(:dry_run).and_return(true)
+ @formatter = ProgressBarFormatter.new(options, @io)
+ end
+
+ it "should not produce summary on dry run" do
+ @formatter.dump_summary(3, 2, 1, 0)
+ @io.string.should eql("")
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/snippet_extractor_spec.rb b/vendor/gems/rspec/spec/spec/runner/formatter/snippet_extractor_spec.rb
new file mode 100644
index 000000000..4bb2f1585
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/snippet_extractor_spec.rb
@@ -0,0 +1,18 @@
+require File.dirname(__FILE__) + '/../../../spec_helper.rb'
+require 'spec/runner/formatter/snippet_extractor'
+
+module Spec
+ module Runner
+ module Formatter
+ describe SnippetExtractor do
+ it "should fall back on a default message when it doesn't understand a line" do
+ SnippetExtractor.new.snippet_for("blech").should == ["# Couldn't get snippet for blech", 1]
+ end
+
+ it "should fall back on a default message when it doesn't find the file" do
+ SnippetExtractor.new.lines_around("blech", 8).should == "# Couldn't get snippet for blech"
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb b/vendor/gems/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb
new file mode 100644
index 000000000..e782254e2
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb
@@ -0,0 +1,103 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require 'hpricot' # Needed to compare generated with wanted HTML
+require 'spec/runner/formatter/text_mate_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ describe TextMateFormatter do
+ attr_reader :root, :suffix, :expected_file
+ before do
+ @root = File.expand_path(File.dirname(__FILE__) + '/../../../..')
+ @suffix = jruby? ? '-jruby' : ''
+ @expected_file = File.dirname(__FILE__) + "/text_mate_formatted-#{::VERSION}#{suffix}.html"
+ end
+
+ def jruby?
+ PLATFORM == 'java'
+ end
+
+ def produces_html_identical_to_manually_designed_document(opt)
+ root = File.expand_path(File.dirname(__FILE__) + '/../../../..')
+
+ Dir.chdir(root) do
+ args = [
+ 'failing_examples/mocking_example.rb',
+ 'failing_examples/diffing_spec.rb',
+ 'examples/pure/stubbing_example.rb',
+ 'examples/pure/pending_example.rb',
+ '--format',
+ 'textmate',
+ opt
+ ]
+ err = StringIO.new
+ out = StringIO.new
+ options = ::Spec::Runner::OptionParser.parse(args, err, out)
+ Spec::Runner::CommandLine.run(options)
+
+ yield(out.string)
+ end
+ end
+
+ # # Uncomment this spec temporarily in order to overwrite the expected with actual.
+ # # Use with care!!!
+ # describe TextMateFormatter, "functional spec file generator" do
+ # it "generates a new comparison file" do
+ # Dir.chdir(root) do
+ # args = ['failing_examples/mocking_example.rb', 'failing_examples/diffing_spec.rb', 'examples/pure/stubbing_example.rb', 'examples/pure/pending_example.rb', '--format', 'textmate', '--diff']
+ # err = StringIO.new
+ # out = StringIO.new
+ # Spec::Runner::CommandLine.run(
+ # ::Spec::Runner::OptionParser.parse(args, err, out)
+ # )
+ #
+ # seconds = /\d+\.\d+ seconds/
+ # html = out.string.gsub seconds, 'x seconds'
+ #
+ # File.open(expected_file, 'w') {|io| io.write(html)}
+ # end
+ # end
+ # end
+
+ describe "functional spec using --diff" do
+ it "should produce HTML identical to the one we designed manually with --diff" do
+ produces_html_identical_to_manually_designed_document("--diff") do |html|
+ suffix = jruby? ? '-jruby' : ''
+ expected_file = File.dirname(__FILE__) + "/text_mate_formatted-#{::VERSION}#{suffix}.html"
+ unless File.file?(expected_file)
+ raise "There is no HTML file with expected content for this platform: #{expected_file}"
+ end
+ expected_html = File.read(expected_file)
+
+ seconds = /\d+\.\d+ seconds/
+ html.gsub! seconds, 'x seconds'
+ expected_html.gsub! seconds, 'x seconds'
+
+ doc = Hpricot(html)
+ backtraces = doc.search("div.backtrace/a")
+ doc.search("div.backtrace").remove
+
+ expected_doc = Hpricot(expected_html)
+ expected_doc.search("div.backtrace").remove
+
+ doc.inner_html.should == expected_doc.inner_html
+
+ backtraces.each do |backtrace_link|
+ backtrace_link[:href].should include("txmt://open?url=")
+ end
+ end
+ end
+
+ end
+
+ describe "functional spec using --dry-run" do
+ it "should produce HTML identical to the one we designed manually with --dry-run" do
+ produces_html_identical_to_manually_designed_document("--dry-run") do |html, expected_html|
+ html.should =~ /This was a dry-run/m
+ end
+ end
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/specdoc_formatter_spec.rb b/vendor/gems/rspec/spec/spec/runner/formatter/specdoc_formatter_spec.rb
new file mode 100644
index 000000000..79995309d
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/specdoc_formatter_spec.rb
@@ -0,0 +1,126 @@
+require File.dirname(__FILE__) + '/../../../spec_helper.rb'
+require 'spec/runner/formatter/specdoc_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ describe SpecdocFormatter do
+ it_should_behave_like "sandboxed rspec_options"
+ attr_reader :io, :options, :formatter, :example_group
+ before(:each) do
+ @io = StringIO.new
+ options.stub!(:dry_run).and_return(false)
+ options.stub!(:colour).and_return(false)
+ @formatter = SpecdocFormatter.new(options, io)
+ @example_group = Class.new(::Spec::Example::ExampleGroup).describe("ExampleGroup")
+ end
+
+ describe "where ExampleGroup has no superclasss with a description" do
+ before do
+ formatter.add_example_group(example_group)
+ end
+
+ it "should produce standard summary without pending when pending has a 0 count" do
+ formatter.dump_summary(3, 2, 1, 0)
+ io.string.should have_example_group_output("\nFinished in 3 seconds\n\n2 examples, 1 failure\n")
+ end
+
+ it "should produce standard summary" do
+ formatter.dump_summary(3, 2, 1, 4)
+ io.string.should have_example_group_output("\nFinished in 3 seconds\n\n2 examples, 1 failure, 4 pending\n")
+ end
+
+ it "should push ExampleGroup name" do
+ io.string.should eql("\nExampleGroup\n")
+ end
+
+ it "when having an error, should push failing spec name and failure number" do
+ formatter.example_failed(
+ example_group.it("spec"),
+ 98,
+ Reporter::Failure.new("c s", RuntimeError.new)
+ )
+ io.string.should have_example_group_output("- spec (ERROR - 98)\n")
+ end
+
+ it "when having an expectation failure, should push failing spec name and failure number" do
+ formatter.example_failed(
+ example_group.it("spec"),
+ 98,
+ Reporter::Failure.new("c s", Spec::Expectations::ExpectationNotMetError.new)
+ )
+ io.string.should have_example_group_output("- spec (FAILED - 98)\n")
+ end
+
+ it "should push nothing on start" do
+ formatter.start(5)
+ io.string.should have_example_group_output("")
+ end
+
+ it "should push nothing on start dump" do
+ formatter.start_dump
+ io.string.should have_example_group_output("")
+ end
+
+ it "should push passing spec name" do
+ formatter.example_passed(example_group.it("spec"))
+ io.string.should have_example_group_output("- spec\n")
+ end
+
+ it "should push pending example name and message" do
+ formatter.example_pending('example_group', ExampleGroup.new("example"), 'reason')
+ io.string.should have_example_group_output("- example (PENDING: reason)\n")
+ end
+
+ it "should dump pending" do
+ formatter.example_pending('example_group', ExampleGroup.new("example"), 'reason')
+ io.rewind
+ formatter.dump_pending
+ io.string.should =~ /Pending\:\nexample_group example \(reason\)\n/
+ end
+
+ def have_example_group_output(expected_output)
+ expected = "\nExampleGroup\n#{expected_output}"
+ ::Spec::Matchers::SimpleMatcher.new(expected) do |actual|
+ actual == expected
+ end
+ end
+ end
+
+ describe "where ExampleGroup has two superclasses with a description" do
+ attr_reader :child_example_group, :grand_child_example_group
+ before do
+ @child_example_group = Class.new(example_group).describe("Child ExampleGroup")
+ @grand_child_example_group = Class.new(child_example_group).describe("GrandChild ExampleGroup")
+ formatter.add_example_group(grand_child_example_group)
+ end
+
+ specify "when having an error, should push failing spec name and failure number" do
+ formatter.example_failed(
+ example_group.it("spec"),
+ 98,
+ Reporter::Failure.new("c s", RuntimeError.new)
+ )
+ io.string.should have_nested_example_group_output("- spec (ERROR - 98)\n")
+ end
+
+ specify "when having an expectation failure, should push failing spec name and failure number" do
+ formatter.example_failed(
+ example_group.it("spec"),
+ 98,
+ Reporter::Failure.new("c s", Spec::Expectations::ExpectationNotMetError.new)
+ )
+ io.string.should have_nested_example_group_output("- spec (FAILED - 98)\n")
+ end
+
+ def have_nested_example_group_output(expected_output)
+ expected_full_output = "\nExampleGroup Child ExampleGroup GrandChild ExampleGroup\n#{expected_output}"
+ ::Spec::Matchers::SimpleMatcher.new(expected_full_output) do |actual|
+ actual == expected_full_output
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/story/html_formatter_spec.rb b/vendor/gems/rspec/spec/spec/runner/formatter/story/html_formatter_spec.rb
new file mode 100644
index 000000000..37fb7c670
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/story/html_formatter_spec.rb
@@ -0,0 +1,61 @@
+require File.dirname(__FILE__) + '/../../../../spec_helper.rb'
+require 'spec/runner/formatter/story/html_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ module Story
+ describe HtmlFormatter do
+ before :each do
+ @out = StringIO.new
+ @options = mock('options')
+ @reporter = HtmlFormatter.new(@options, @out)
+ end
+
+ it "should just be poked at" do
+ @reporter.run_started(1)
+ @reporter.story_started('story_title', 'narrative')
+
+ @reporter.scenario_started('story_title', 'succeeded_scenario_name')
+ @reporter.step_succeeded('given', 'succeded_step', 'one', 'two')
+ @reporter.scenario_succeeded('story_title', 'succeeded_scenario_name')
+
+ @reporter.scenario_started('story_title', 'pending_scenario_name')
+ @reporter.step_pending('when', 'pending_step', 'un', 'deux')
+ @reporter.scenario_pending('story_title', 'pending_scenario_name', 'not done')
+
+ @reporter.scenario_started('story_title', 'failed_scenario_name')
+ @reporter.step_failed('then', 'failed_step', 'en', 'to')
+ @reporter.scenario_failed('story_title', 'failed_scenario_name', NameError.new('sup'))
+
+ @reporter.scenario_started('story_title', 'scenario_with_given_scenario_name')
+ @reporter.found_scenario('given scenario', 'succeeded_scenario_name')
+
+ @reporter.story_ended('story_title', 'narrative')
+ @reporter.run_ended
+ end
+
+ it "should create spans for params" do
+ @reporter.step_succeeded('given', 'a $coloured $animal', 'brown', 'dog')
+ @out.string.should == " <li class=\"passed\">Given a <span class=\"param\">brown</span> <span class=\"param\">dog</span></li>\n"
+ end
+
+ it 'should create spanes for params in regexp steps' do
+ @reporter.step_succeeded :given, /a (pink|blue) (.*)/, 'brown', 'dog'
+ @out.string.should == " <li class=\"passed\">Given a <span class=\"param\">brown</span> <span class=\"param\">dog</span></li>\n"
+ end
+
+ it "should create a ul for collected_steps" do
+ @reporter.collected_steps(['Given a $coloured $animal', 'Given a $n legged eel'])
+ @out.string.should == (<<-EOF)
+ <ul id="stock_steps" style="display: none;">
+ <li>Given a $coloured $animal</li>
+ <li>Given a $n legged eel</li>
+ </ul>
+EOF
+ end
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb b/vendor/gems/rspec/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb
new file mode 100644
index 000000000..9632b0606
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/story/plain_text_formatter_spec.rb
@@ -0,0 +1,335 @@
+require File.dirname(__FILE__) + '/../../../../spec_helper.rb'
+require 'spec/runner/formatter/story/plain_text_formatter'
+
+module Spec
+ module Runner
+ module Formatter
+ module Story
+ describe PlainTextFormatter do
+ before :each do
+ # given
+ @out = StringIO.new
+ @tweaker = mock('tweaker')
+ @tweaker.stub!(:tweak_backtrace)
+ @options = mock('options')
+ @options.stub!(:colour).and_return(false)
+ @options.stub!(:backtrace_tweaker).and_return(@tweaker)
+ @formatter = PlainTextFormatter.new(@options, @out)
+ end
+
+ it 'should summarize the number of scenarios when the run ends' do
+ # when
+ @formatter.run_started(3)
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_succeeded('story', 'scenario1')
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_succeeded('story', 'scenario2')
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_succeeded('story', 'scenario3')
+ @formatter.run_ended
+
+ # then
+ @out.string.should include('3 scenarios')
+ end
+
+ it 'should summarize the number of successful scenarios when the run ends' do
+ # when
+ @formatter.run_started(3)
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_succeeded('story', 'scenario1')
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_succeeded('story', 'scenario2')
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_succeeded('story', 'scenario3')
+ @formatter.run_ended
+
+ # then
+ @out.string.should include('3 scenarios: 3 succeeded')
+ end
+
+ it 'should summarize the number of failed scenarios when the run ends' do
+ # when
+ @formatter.run_started(3)
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_succeeded('story', 'scenario1')
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops' })
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_failed('story', 'scenario3', exception_from { raise RuntimeError, 'oops' })
+ @formatter.run_ended
+
+ # then
+ @out.string.should include("3 scenarios: 1 succeeded, 2 failed")
+ end
+
+ it 'should end cleanly (no characters on the last line) with successes' do
+ # when
+ @formatter.run_started(1)
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_succeeded('story', 'scenario')
+ @formatter.run_ended
+
+ # then
+ @out.string.should =~ /\n\z/
+ end
+
+ it 'should end cleanly (no characters on the last line) with failures' do
+ # when
+ @formatter.run_started(1)
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_failed('story', 'scenario', exception_from { raise RuntimeError, 'oops' })
+ @formatter.run_ended
+
+ # then
+ @out.string.should =~ /\n\z/
+ end
+
+ it 'should end cleanly (no characters on the last line) with pending steps' do
+ # when
+ @formatter.run_started(1)
+ @formatter.scenario_started(nil, nil)
+ @formatter.step_pending(:then, 'do pend')
+ @formatter.scenario_pending('story', 'scenario', exception_from { raise RuntimeError, 'oops' })
+ @formatter.run_ended
+
+ # then
+ @out.string.should =~ /\n\z/
+ end
+
+ it 'should summarize the number of pending scenarios when the run ends' do
+ # when
+ @formatter.run_started(3)
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_succeeded('story', 'scenario1')
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_pending('story', 'scenario2', 'message')
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_pending('story', 'scenario3', 'message')
+ @formatter.run_ended
+
+ # then
+ @out.string.should include("3 scenarios: 1 succeeded, 0 failed, 2 pending")
+ end
+
+ it "should only count the first failure in one scenario" do
+ # when
+ @formatter.run_started(3)
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_succeeded('story', 'scenario1')
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops' })
+ @formatter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops again' })
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_failed('story', 'scenario3', exception_from { raise RuntimeError, 'oops' })
+ @formatter.run_ended
+
+ # then
+ @out.string.should include("3 scenarios: 1 succeeded, 2 failed")
+ end
+
+ it "should only count the first pending in one scenario" do
+ # when
+ @formatter.run_started(3)
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_succeeded('story', 'scenario1')
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_pending('story', 'scenario2', 'because ...')
+ @formatter.scenario_pending('story', 'scenario2', 'because ...')
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_pending('story', 'scenario3', 'because ...')
+ @formatter.run_ended
+
+ # then
+ @out.string.should include("3 scenarios: 1 succeeded, 0 failed, 2 pending")
+ end
+
+ it "should only count a failure before the first pending in one scenario" do
+ # when
+ @formatter.run_started(3)
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_succeeded('story', 'scenario1')
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_pending('story', 'scenario2', exception_from { raise RuntimeError, 'oops' })
+ @formatter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops again' })
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_failed('story', 'scenario3', exception_from { raise RuntimeError, 'oops' })
+ @formatter.run_ended
+
+ # then
+ @out.string.should include("3 scenarios: 1 succeeded, 1 failed, 1 pending")
+ end
+
+ it 'should produce details of the first failure each failed scenario when the run ends' do
+ # when
+ @formatter.run_started(3)
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_succeeded('story', 'scenario1')
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops2' })
+ @formatter.scenario_failed('story', 'scenario2', exception_from { raise RuntimeError, 'oops2 - this one should not appear' })
+ @formatter.scenario_started(nil, nil)
+ @formatter.scenario_failed('story', 'scenario3', exception_from { raise RuntimeError, 'oops3' })
+ @formatter.run_ended
+
+ # then
+ @out.string.should include("FAILURES:\n")
+ @out.string.should include("1) story (scenario2) FAILED")
+ @out.string.should include("RuntimeError: oops2")
+ @out.string.should_not include("RuntimeError: oops2 - this one should not appear")
+ @out.string.should include("2) story (scenario3) FAILED")
+ @out.string.should include("RuntimeError: oops3")
+ end
+
+ it 'should produce details of each pending step when the run ends' do
+ # when
+ @formatter.run_started(2)
+ @formatter.story_started('story 1', 'narrative')
+ @formatter.scenario_started('story 1', 'scenario 1')
+ @formatter.step_pending(:given, 'todo 1', [])
+ @formatter.story_started('story 2', 'narrative')
+ @formatter.scenario_started('story 2', 'scenario 2')
+ @formatter.step_pending(:given, 'todo 2', [])
+ @formatter.run_ended
+
+ # then
+ @out.string.should include("Pending Steps:\n")
+ @out.string.should include("1) story 1 (scenario 1): todo 1")
+ @out.string.should include("2) story 2 (scenario 2): todo 2")
+ end
+
+ it 'should document a story title and narrative' do
+ # when
+ @formatter.story_started 'story', 'narrative'
+
+ # then
+ @out.string.should include("Story: story\n\n narrative")
+ end
+
+ it 'should document a scenario name' do
+ # when
+ @formatter.scenario_started 'story', 'scenario'
+
+ # then
+ @out.string.should include("\n\n Scenario: scenario")
+ end
+
+ it 'should document a step by sentence-casing its name' do
+ # when
+ @formatter.step_succeeded :given, 'a context'
+ @formatter.step_succeeded :when, 'an event'
+ @formatter.step_succeeded :then, 'an outcome'
+
+ # then
+ @out.string.should include("\n\n Given a context\n\n When an event\n\n Then an outcome")
+ end
+
+ it 'should document additional givens using And' do
+ # when
+ @formatter.step_succeeded :given, 'step 1'
+ @formatter.step_succeeded :given, 'step 2'
+ @formatter.step_succeeded :given, 'step 3'
+
+ # then
+ @out.string.should include(" Given step 1\n And step 2\n And step 3")
+ end
+
+ it 'should document additional events using And' do
+ # when
+ @formatter.step_succeeded :when, 'step 1'
+ @formatter.step_succeeded :when, 'step 2'
+ @formatter.step_succeeded :when, 'step 3'
+
+ # then
+ @out.string.should include(" When step 1\n And step 2\n And step 3")
+ end
+
+ it 'should document additional outcomes using And' do
+ # when
+ @formatter.step_succeeded :then, 'step 1'
+ @formatter.step_succeeded :then, 'step 2'
+ @formatter.step_succeeded :then, 'step 3'
+
+ # then
+ @out.string.should include(" Then step 1\n And step 2\n And step 3")
+ end
+
+ it 'should document a GivenScenario followed by a Given using And' do
+ # when
+ @formatter.step_succeeded :'given scenario', 'a scenario'
+ @formatter.step_succeeded :given, 'a context'
+
+ # then
+ @out.string.should include(" Given scenario a scenario\n And a context")
+ end
+
+ it 'should document steps with replaced params' do
+ @formatter.step_succeeded :given, 'a $coloured dog with $n legs', 'pink', 21
+ @out.string.should include(" Given a pink dog with 21 legs")
+ end
+
+ it 'should document regexp steps with replaced params' do
+ @formatter.step_succeeded :given, /a (pink|blue) dog with (.*) legs/, 'pink', 21
+ @out.string.should include(" Given a pink dog with 21 legs")
+ end
+
+ it "should append PENDING for the first pending step" do
+ @formatter.scenario_started('','')
+ @formatter.step_pending(:given, 'a context')
+
+ @out.string.should include('Given a context (PENDING)')
+ end
+
+ it "should append PENDING for pending after already pending" do
+ @formatter.scenario_started('','')
+ @formatter.step_pending(:given, 'a context')
+ @formatter.step_pending(:when, 'I say hey')
+
+ @out.string.should include('When I say hey (PENDING)')
+ end
+
+ it "should append FAILED for the first failiure" do
+ @formatter.scenario_started('','')
+ @formatter.step_failed(:given, 'a context')
+
+ @out.string.should include('Given a context (FAILED)')
+ end
+
+ it "should append SKIPPED for the second failiure" do
+ @formatter.scenario_started('','')
+ @formatter.step_failed(:given, 'a context')
+ @formatter.step_failed(:when, 'I say hey')
+
+ @out.string.should include('When I say hey (SKIPPED)')
+ end
+
+ it "should append SKIPPED for the a failiure after PENDING" do
+ @formatter.scenario_started('','')
+ @formatter.step_pending(:given, 'a context')
+ @formatter.step_failed(:when, 'I say hey')
+
+ @out.string.should include('When I say hey (SKIPPED)')
+ end
+
+ it 'should print some white space after each story' do
+ # when
+ @formatter.story_ended 'title', 'narrative'
+
+ # then
+ @out.string.should include("\n\n")
+ end
+
+ it "should print nothing for collected_steps" do
+ @formatter.collected_steps(['Given a $coloured $animal', 'Given a $n legged eel'])
+ @out.string.should == ("")
+ end
+
+ it "should ignore messages it doesn't care about" do
+ lambda {
+ @formatter.this_method_does_not_exist
+ }.should_not raise_error
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.4.html b/vendor/gems/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.4.html
new file mode 100644
index 000000000..3f263747a
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.4.html
@@ -0,0 +1,365 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>RSpec results</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Expires" content="-1" />
+ <meta http-equiv="Pragma" content="no-cache" />
+ <style type="text/css">
+ body {
+ margin: 0;
+ padding: 0;
+ background: #fff;
+ font-size: 80%;
+ }
+ </style>
+</head>
+<body>
+<div class="rspec-report">
+ <script type="text/javascript">
+ // <![CDATA[
+function moveProgressBar(percentDone) {
+ document.getElementById("rspec-header").style.width = percentDone +"%";
+}
+function makeRed(element_id) {
+ document.getElementById(element_id).style.background = '#C40D0D';
+ document.getElementById(element_id).style.color = '#FFFFFF';
+}
+
+function makeYellow(element_id) {
+ if (element_id == "rspec-header" && document.getElementById(element_id).style.background != '#C40D0D')
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+ else
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+}
+
+ // ]]>
+ </script>
+ <style type="text/css">
+#rspec-header {
+ background: #65C400; color: #fff;
+}
+
+.rspec-report h1 {
+ margin: 0px 10px 0px 10px;
+ padding: 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ font-size: 1.8em;
+}
+
+#summary {
+ margin: 0; padding: 5px 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ text-align: right;
+ position: absolute;
+ top: 0px;
+ right: 0px;
+}
+
+#summary p {
+ margin: 0 0 0 2px;
+}
+
+#summary #totals {
+ font-size: 1.2em;
+}
+
+.example_group {
+ margin: 0 10px 5px;
+ background: #fff;
+}
+
+dl {
+ margin: 0; padding: 0 0 5px;
+ font: normal 11px "Lucida Grande", Helvetica, sans-serif;
+}
+
+dt {
+ padding: 3px;
+ background: #65C400;
+ color: #fff;
+ font-weight: bold;
+}
+
+dd {
+ margin: 5px 0 5px 5px;
+ padding: 3px 3px 3px 18px;
+}
+
+dd.spec.passed {
+ border-left: 5px solid #65C400;
+ border-bottom: 1px solid #65C400;
+ background: #DBFFB4; color: #3D7700;
+}
+
+dd.spec.failed {
+ border-left: 5px solid #C20000;
+ border-bottom: 1px solid #C20000;
+ color: #C20000; background: #FFFBD3;
+}
+
+dd.spec.not_implemented {
+ border-left: 5px solid #FAF834;
+ border-bottom: 1px solid #FAF834;
+ background: #FCFB98; color: #131313;
+}
+
+dd.spec.pending_fixed {
+ border-left: 5px solid #0000C2;
+ border-bottom: 1px solid #0000C2;
+ color: #0000C2; background: #D3FBFF;
+}
+
+.backtrace {
+ color: #000;
+ font-size: 12px;
+}
+
+a {
+ color: #BE5C00;
+}
+
+/* Ruby code, style similar to vibrant ink */
+.ruby {
+ font-size: 12px;
+ font-family: monospace;
+ color: white;
+ background-color: black;
+ padding: 0.1em 0 0.2em 0;
+}
+
+.ruby .keyword { color: #FF6600; }
+.ruby .constant { color: #339999; }
+.ruby .attribute { color: white; }
+.ruby .global { color: white; }
+.ruby .module { color: white; }
+.ruby .class { color: white; }
+.ruby .string { color: #66FF00; }
+.ruby .ident { color: white; }
+.ruby .method { color: #FFCC00; }
+.ruby .number { color: white; }
+.ruby .char { color: white; }
+.ruby .comment { color: #9933CC; }
+.ruby .symbol { color: white; }
+.ruby .regex { color: #44B4CC; }
+.ruby .punct { color: white; }
+.ruby .escape { color: white; }
+.ruby .interp { color: white; }
+.ruby .expr { color: white; }
+
+.ruby .offending { background-color: gray; }
+.ruby .linenum {
+ width: 75px;
+ padding: 0.1em 1em 0.2em 0;
+ color: #000000;
+ background-color: #FFFBD3;
+}
+
+ </style>
+
+<div id="rspec-header">
+ <h1>RSpec Results</h1>
+
+ <div id="summary">
+ <p id="totals">&nbsp;</p>
+ <p id="duration">&nbsp;</p>
+ </div>
+</div>
+
+<div class="results">
+<div class="example_group">
+ <dl>
+ <dt id="example_group_1">Mocker</dt>
+ <script type="text/javascript">moveProgressBar('5.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to call mock()</span></dd>
+ <script type="text/javascript">makeRed('rspec-header');</script>
+ <script type="text/javascript">makeRed('example_group_1');</script>
+ <script type="text/javascript">moveProgressBar('11.7');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when expected message not received</span>
+ <div class="failure" id="failure_1">
+ <div class="message"><pre>Mock 'poke me' expected :poke with (any args) once, but received it 0 times</pre></div>
+ <div class="backtrace"><pre><a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/failing_examples/mocking_example.rb&line=13">./failing_examples/mocking_example.rb:13</a>
+<a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb&line=52">./spec/spec/runner/formatter/spec_mate_formatter_spec.rb:52</a>
+<a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb&line=48">./spec/spec/runner/formatter/spec_mate_formatter_spec.rb:48</a> </pre></div>
+ <pre class="ruby"><code><span class="linenum">11</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should fail when expected message not received</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="linenum">12</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">poke me</span><span class="punct">&quot;)</span>
+<span class="offending"><span class="linenum">13</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_receive</span><span class="punct">(</span><span class="symbol">:poke</span><span class="punct">)</span></span>
+<span class="linenum">14</span> <span class="keyword">end</span>
+<span class="linenum">15</span> </code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('17.6');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when messages are received out of order</span>
+ <div class="failure" id="failure_2">
+ <div class="message"><pre>Mock 'one two three' received :three out of order</pre></div>
+ <div class="backtrace"><pre><a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/failing_examples/mocking_example.rb&line=22">./failing_examples/mocking_example.rb:22</a>
+<a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb&line=52">./spec/spec/runner/formatter/spec_mate_formatter_spec.rb:52</a>
+<a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb&line=48">./spec/spec/runner/formatter/spec_mate_formatter_spec.rb:48</a> </pre></div>
+ <pre class="ruby"><code><span class="linenum">20</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_receive</span><span class="punct">(</span><span class="symbol">:three</span><span class="punct">).</span><span class="ident">ordered</span>
+<span class="linenum">21</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">one</span>
+<span class="offending"><span class="linenum">22</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">three</span></span>
+<span class="linenum">23</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">two</span>
+<span class="linenum">24</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('23.5');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should get yelled at when sending unexpected messages</span>
+ <div class="failure" id="failure_3">
+ <div class="message"><pre>Mock 'don't talk to me' expected :any_message_at_all with (any args) 0 times, but received it once</pre></div>
+ <div class="backtrace"><pre><a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/failing_examples/mocking_example.rb&line=28">./failing_examples/mocking_example.rb:28</a>
+<a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb&line=52">./spec/spec/runner/formatter/spec_mate_formatter_spec.rb:52</a>
+<a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb&line=48">./spec/spec/runner/formatter/spec_mate_formatter_spec.rb:48</a> </pre></div>
+ <pre class="ruby"><code><span class="linenum">26</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should get yelled at when sending unexpected messages</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="linenum">27</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">don't talk to me</span><span class="punct">&quot;)</span>
+<span class="offending"><span class="linenum">28</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_not_receive</span><span class="punct">(</span><span class="symbol">:any_message_at_all</span><span class="punct">)</span></span>
+<span class="linenum">29</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">any_message_at_all</span>
+<span class="linenum">30</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('29.4');</script>
+ <dd class="spec pending_fixed">
+ <span class="failed_spec_name">has a bug we need to fix</span>
+ <div class="failure" id="failure_4">
+ <div class="message"><pre>Expected pending 'here is the bug' to fail. No Error was raised.</pre></div>
+ <div class="backtrace"><pre><a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/failing_examples/mocking_example.rb&line=33">./failing_examples/mocking_example.rb:33</a>
+<a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb&line=52">./spec/spec/runner/formatter/spec_mate_formatter_spec.rb:52</a>
+<a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb&line=48">./spec/spec/runner/formatter/spec_mate_formatter_spec.rb:48</a> </pre></div>
+ <pre class="ruby"><code><span class="linenum">31</span>
+<span class="linenum">32</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">has a bug we need to fix</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="offending"><span class="linenum">33</span> <span class="ident">pending</span> <span class="punct">&quot;</span><span class="string">here is the bug</span><span class="punct">&quot;</span> <span class="keyword">do</span></span>
+<span class="linenum">34</span> <span class="comment"># Actually, no. It's fixed. This will fail because it passes :-)</span>
+<span class="linenum">35</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">Bug</span><span class="punct">&quot;)</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_2">Running specs with --diff</dt>
+ <script type="text/javascript">makeRed('example_group_2');</script>
+ <script type="text/javascript">moveProgressBar('35.2');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different strings</span>
+ <div class="failure" id="failure_5">
+ <div class="message"><pre>expected: &quot;RSpec is a\nbehaviour driven development\nframework for Ruby\n&quot;,
+ got: &quot;RSpec is a\nbehavior driven development\nframework for Ruby\n&quot; (using ==)
+Diff:
+@@ -1,4 +1,4 @@
+ RSpec is a
+-behavior driven development
++behaviour driven development
+ framework for Ruby
+</pre></div>
+ <div class="backtrace"><pre><a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/failing_examples/diffing_spec.rb&line=13">./failing_examples/diffing_spec.rb:13</a>
+<a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb&line=52">./spec/spec/runner/formatter/spec_mate_formatter_spec.rb:52</a>
+<a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb&line=48">./spec/spec/runner/formatter/spec_mate_formatter_spec.rb:48</a> </pre></div>
+ <pre class="ruby"><code><span class="linenum">11</span><span class="ident">framework</span> <span class="keyword">for</span> <span class="constant">Ruby</span>
+<span class="linenum">12</span><span class="constant">EOF</span>
+<span class="offending"><span class="linenum">13</span> <span class="ident">usa</span><span class="punct">.</span><span class="ident">should</span> <span class="punct">==</span> <span class="ident">uk</span></span>
+<span class="linenum">14</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('41.1');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different objects' pretty representation</span>
+ <div class="failure" id="failure_6">
+ <div class="message"><pre>expected &lt;Animal
+name=bob,
+species=tortoise
+&gt;
+, got &lt;Animal
+name=bob,
+species=giraffe
+&gt;
+ (using .eql?)
+Diff:
+@@ -1,5 +1,5 @@
+ &lt;Animal
+ name=bob,
+-species=giraffe
++species=tortoise
+ &gt;
+</pre></div>
+ <div class="backtrace"><pre><a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/failing_examples/diffing_spec.rb&line=34">./failing_examples/diffing_spec.rb:34</a>
+<a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb&line=52">./spec/spec/runner/formatter/spec_mate_formatter_spec.rb:52</a>
+<a href="txmt://open?url=file:///Users/aslakhellesoy/scm/rspec/trunk/rspec/spec/spec/runner/formatter/spec_mate_formatter_spec.rb&line=48">./spec/spec/runner/formatter/spec_mate_formatter_spec.rb:48</a> </pre></div>
+ <pre class="ruby"><code><span class="linenum">32</span> <span class="ident">expected</span> <span class="punct">=</span> <span class="constant">Animal</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">&quot;</span><span class="string">bob</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">giraffe</span><span class="punct">&quot;</span>
+<span class="linenum">33</span> <span class="ident">actual</span> <span class="punct">=</span> <span class="constant">Animal</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">&quot;</span><span class="string">bob</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">tortoise</span><span class="punct">&quot;</span>
+<span class="offending"><span class="linenum">34</span> <span class="ident">expected</span><span class="punct">.</span><span class="ident">should</span> <span class="ident">eql</span><span class="punct">(</span><span class="ident">actual</span><span class="punct">)</span></span>
+<span class="linenum">35</span> <span class="keyword">end</span>
+<span class="linenum">36</span><span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_3">A consumer of a stub</dt>
+ <script type="text/javascript">moveProgressBar('47.0');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to stub methods on any Object</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_4">A stubbed method on a class</dt>
+ <script type="text/javascript">moveProgressBar('52.9');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should return the stubbed value</span></dd>
+ <script type="text/javascript">moveProgressBar('58.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should revert to the original method after each spec</span></dd>
+ <script type="text/javascript">moveProgressBar('64.7');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_5">A mock</dt>
+ <script type="text/javascript">moveProgressBar('70.5');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub!</span></dd>
+ <script type="text/javascript">moveProgressBar('76.4');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock</span></dd>
+ <script type="text/javascript">moveProgressBar('82.3');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_6">pending example (using pending method)</dt>
+ <script type="text/javascript">makeYellow('example_group_6');</script>
+ <script type="text/javascript">moveProgressBar('88.2');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_7">pending example (with no block)</dt>
+ <script type="text/javascript">makeYellow('example_group_7');</script>
+ <script type="text/javascript">moveProgressBar('94.1');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: Not Yet Implemented&quot; (PENDING: Not Yet Implemented)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_8">pending example (with block for pending)</dt>
+ <script type="text/javascript">makeYellow('example_group_8');</script>
+ <script type="text/javascript">moveProgressBar('100.0');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should have a failing block, passed to pending, reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>x seconds</strong>";</script>
+<script type="text/javascript">document.getElementById('totals').innerHTML = "17 examples, 6 failures, 3 pending";</script>
+</div>
+</div>
+</body>
+</html>
diff --git a/vendor/gems/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html b/vendor/gems/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html
new file mode 100644
index 000000000..8a2b12e7d
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/formatter/text_mate_formatted-1.8.6.html
@@ -0,0 +1,365 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>RSpec results</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Expires" content="-1" />
+ <meta http-equiv="Pragma" content="no-cache" />
+ <style type="text/css">
+ body {
+ margin: 0;
+ padding: 0;
+ background: #fff;
+ font-size: 80%;
+ }
+ </style>
+</head>
+<body>
+<div class="rspec-report">
+ <script type="text/javascript">
+ // <![CDATA[
+function moveProgressBar(percentDone) {
+ document.getElementById("rspec-header").style.width = percentDone +"%";
+}
+function makeRed(element_id) {
+ document.getElementById(element_id).style.background = '#C40D0D';
+ document.getElementById(element_id).style.color = '#FFFFFF';
+}
+
+function makeYellow(element_id) {
+ if (element_id == "rspec-header" && document.getElementById(element_id).style.background != '#C40D0D')
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+ else
+ {
+ document.getElementById(element_id).style.background = '#FAF834';
+ document.getElementById(element_id).style.color = '#000000';
+ }
+}
+
+ // ]]>
+ </script>
+ <style type="text/css">
+#rspec-header {
+ background: #65C400; color: #fff;
+}
+
+.rspec-report h1 {
+ margin: 0px 10px 0px 10px;
+ padding: 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ font-size: 1.8em;
+}
+
+#summary {
+ margin: 0; padding: 5px 10px;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+ text-align: right;
+ position: absolute;
+ top: 0px;
+ right: 0px;
+}
+
+#summary p {
+ margin: 0 0 0 2px;
+}
+
+#summary #totals {
+ font-size: 1.2em;
+}
+
+.example_group {
+ margin: 0 10px 5px;
+ background: #fff;
+}
+
+dl {
+ margin: 0; padding: 0 0 5px;
+ font: normal 11px "Lucida Grande", Helvetica, sans-serif;
+}
+
+dt {
+ padding: 3px;
+ background: #65C400;
+ color: #fff;
+ font-weight: bold;
+}
+
+dd {
+ margin: 5px 0 5px 5px;
+ padding: 3px 3px 3px 18px;
+}
+
+dd.spec.passed {
+ border-left: 5px solid #65C400;
+ border-bottom: 1px solid #65C400;
+ background: #DBFFB4; color: #3D7700;
+}
+
+dd.spec.failed {
+ border-left: 5px solid #C20000;
+ border-bottom: 1px solid #C20000;
+ color: #C20000; background: #FFFBD3;
+}
+
+dd.spec.not_implemented {
+ border-left: 5px solid #FAF834;
+ border-bottom: 1px solid #FAF834;
+ background: #FCFB98; color: #131313;
+}
+
+dd.spec.pending_fixed {
+ border-left: 5px solid #0000C2;
+ border-bottom: 1px solid #0000C2;
+ color: #0000C2; background: #D3FBFF;
+}
+
+.backtrace {
+ color: #000;
+ font-size: 12px;
+}
+
+a {
+ color: #BE5C00;
+}
+
+/* Ruby code, style similar to vibrant ink */
+.ruby {
+ font-size: 12px;
+ font-family: monospace;
+ color: white;
+ background-color: black;
+ padding: 0.1em 0 0.2em 0;
+}
+
+.ruby .keyword { color: #FF6600; }
+.ruby .constant { color: #339999; }
+.ruby .attribute { color: white; }
+.ruby .global { color: white; }
+.ruby .module { color: white; }
+.ruby .class { color: white; }
+.ruby .string { color: #66FF00; }
+.ruby .ident { color: white; }
+.ruby .method { color: #FFCC00; }
+.ruby .number { color: white; }
+.ruby .char { color: white; }
+.ruby .comment { color: #9933CC; }
+.ruby .symbol { color: white; }
+.ruby .regex { color: #44B4CC; }
+.ruby .punct { color: white; }
+.ruby .escape { color: white; }
+.ruby .interp { color: white; }
+.ruby .expr { color: white; }
+
+.ruby .offending { background-color: gray; }
+.ruby .linenum {
+ width: 75px;
+ padding: 0.1em 1em 0.2em 0;
+ color: #000000;
+ background-color: #FFFBD3;
+}
+
+ </style>
+
+<div id="rspec-header">
+ <h1>RSpec Results</h1>
+
+ <div id="summary">
+ <p id="totals">&nbsp;</p>
+ <p id="duration">&nbsp;</p>
+ </div>
+</div>
+
+<div class="results">
+<div class="example_group">
+ <dl>
+ <dt id="example_group_1">Mocker</dt>
+ <script type="text/javascript">moveProgressBar('5.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to call mock()</span></dd>
+ <script type="text/javascript">makeRed('rspec-header');</script>
+ <script type="text/javascript">makeRed('example_group_1');</script>
+ <script type="text/javascript">moveProgressBar('11.7');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when expected message not received</span>
+ <div class="failure" id="failure_1">
+ <div class="message"><pre>Mock 'poke me' expected :poke with (any args) once, but received it 0 times</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:13:
+./spec/spec/runner/formatter/html_formatter_spec.rb:18:
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:</pre></div>
+ <pre class="ruby"><code><span class="linenum">11</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should fail when expected message not received</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="linenum">12</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">poke me</span><span class="punct">&quot;)</span>
+<span class="offending"><span class="linenum">13</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_receive</span><span class="punct">(</span><span class="symbol">:poke</span><span class="punct">)</span></span>
+<span class="linenum">14</span> <span class="keyword">end</span>
+<span class="linenum">15</span> </code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('17.6');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should fail when messages are received out of order</span>
+ <div class="failure" id="failure_2">
+ <div class="message"><pre>Mock 'one two three' received :three out of order</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:22:
+./spec/spec/runner/formatter/html_formatter_spec.rb:18:
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:</pre></div>
+ <pre class="ruby"><code><span class="linenum">20</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_receive</span><span class="punct">(</span><span class="symbol">:three</span><span class="punct">).</span><span class="ident">ordered</span>
+<span class="linenum">21</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">one</span>
+<span class="offending"><span class="linenum">22</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">three</span></span>
+<span class="linenum">23</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">two</span>
+<span class="linenum">24</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('23.5');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should get yelled at when sending unexpected messages</span>
+ <div class="failure" id="failure_3">
+ <div class="message"><pre>Mock 'don't talk to me' expected :any_message_at_all with (any args) 0 times, but received it once</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:28:
+./spec/spec/runner/formatter/html_formatter_spec.rb:18:
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:</pre></div>
+ <pre class="ruby"><code><span class="linenum">26</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">should get yelled at when sending unexpected messages</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="linenum">27</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">don't talk to me</span><span class="punct">&quot;)</span>
+<span class="offending"><span class="linenum">28</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">should_not_receive</span><span class="punct">(</span><span class="symbol">:any_message_at_all</span><span class="punct">)</span></span>
+<span class="linenum">29</span> <span class="ident">mock</span><span class="punct">.</span><span class="ident">any_message_at_all</span>
+<span class="linenum">30</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('29.4');</script>
+ <dd class="spec pending_fixed">
+ <span class="failed_spec_name">has a bug we need to fix</span>
+ <div class="failure" id="failure_4">
+ <div class="message"><pre>Expected pending 'here is the bug' to fail. No Error was raised.</pre></div>
+
+ <pre class="ruby"><code><span class="linenum">31</span>
+<span class="linenum">32</span> <span class="ident">it</span> <span class="punct">&quot;</span><span class="string">has a bug we need to fix</span><span class="punct">&quot;</span> <span class="keyword">do</span>
+<span class="offending"><span class="linenum">33</span> <span class="ident">pending</span> <span class="punct">&quot;</span><span class="string">here is the bug</span><span class="punct">&quot;</span> <span class="keyword">do</span></span>
+<span class="linenum">34</span> <span class="comment"># Actually, no. It's fixed. This will fail because it passes :-)</span>
+<span class="linenum">35</span> <span class="ident">mock</span> <span class="punct">=</span> <span class="ident">mock</span><span class="punct">(&quot;</span><span class="string">Bug</span><span class="punct">&quot;)</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_2">Running specs with --diff</dt>
+ <script type="text/javascript">makeRed('example_group_2');</script>
+ <script type="text/javascript">moveProgressBar('35.2');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different strings</span>
+ <div class="failure" id="failure_5">
+ <div class="message"><pre>expected: &quot;RSpec is a\nbehaviour driven development\nframework for Ruby\n&quot;,
+ got: &quot;RSpec is a\nbehavior driven development\nframework for Ruby\n&quot; (using ==)
+Diff:
+@@ -1,4 +1,4 @@
+ RSpec is a
+-behavior driven development
++behaviour driven development
+ framework for Ruby
+</pre></div>
+
+ <pre class="ruby"><code><span class="linenum">11</span><span class="ident">framework</span> <span class="keyword">for</span> <span class="constant">Ruby</span>
+<span class="linenum">12</span><span class="constant">EOF</span>
+<span class="offending"><span class="linenum">13</span> <span class="ident">usa</span><span class="punct">.</span><span class="ident">should</span> <span class="punct">==</span> <span class="ident">uk</span></span>
+<span class="linenum">14</span> <span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ <script type="text/javascript">moveProgressBar('41.1');</script>
+ <dd class="spec failed">
+ <span class="failed_spec_name">should print diff of different objects' pretty representation</span>
+ <div class="failure" id="failure_6">
+ <div class="message"><pre>expected &lt;Animal
+name=bob,
+species=tortoise
+&gt;
+, got &lt;Animal
+name=bob,
+species=giraffe
+&gt;
+ (using .eql?)
+Diff:
+@@ -1,5 +1,5 @@
+ &lt;Animal
+ name=bob,
+-species=giraffe
++species=tortoise
+ &gt;
+</pre></div>
+ <div class="backtrace"><pre>./failing_examples/mocking_example.rb:33:
+./spec/spec/runner/formatter/html_formatter_spec.rb:18:
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:in `chdir'
+./spec/spec/runner/formatter/html_formatter_spec.rb:14:</pre></div>
+ <pre class="ruby"><code><span class="linenum">32</span> <span class="ident">expected</span> <span class="punct">=</span> <span class="constant">Animal</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">&quot;</span><span class="string">bob</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">giraffe</span><span class="punct">&quot;</span>
+<span class="linenum">33</span> <span class="ident">actual</span> <span class="punct">=</span> <span class="constant">Animal</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">&quot;</span><span class="string">bob</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">tortoise</span><span class="punct">&quot;</span>
+<span class="offending"><span class="linenum">34</span> <span class="ident">expected</span><span class="punct">.</span><span class="ident">should</span> <span class="ident">eql</span><span class="punct">(</span><span class="ident">actual</span><span class="punct">)</span></span>
+<span class="linenum">35</span> <span class="keyword">end</span>
+<span class="linenum">36</span><span class="keyword">end</span></code></pre>
+ </div>
+ </dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_3">A consumer of a stub</dt>
+ <script type="text/javascript">moveProgressBar('47.0');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should be able to stub methods on any Object</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_4">A stubbed method on a class</dt>
+ <script type="text/javascript">moveProgressBar('52.9');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should return the stubbed value</span></dd>
+ <script type="text/javascript">moveProgressBar('58.8');</script>
+ <dd class="spec passed"><span class="passed_spec_name">should revert to the original method after each spec</span></dd>
+ <script type="text/javascript">moveProgressBar('64.7');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_5">A mock</dt>
+ <script type="text/javascript">moveProgressBar('70.5');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub!</span></dd>
+ <script type="text/javascript">moveProgressBar('76.4');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock</span></dd>
+ <script type="text/javascript">moveProgressBar('82.3');</script>
+ <dd class="spec passed"><span class="passed_spec_name">can stub! and mock the same message</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_6">pending example (using pending method)</dt>
+ <script type="text/javascript">makeYellow('example_group_6');</script>
+ <script type="text/javascript">moveProgressBar('88.2');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_7">pending example (with no block)</dt>
+ <script type="text/javascript">makeYellow('example_group_7');</script>
+ <script type="text/javascript">moveProgressBar('94.1');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should be reported as &quot;PENDING: Not Yet Implemented&quot; (PENDING: Not Yet Implemented)</span></dd>
+ </dl>
+</div>
+<div class="example_group">
+ <dl>
+ <dt id="example_group_8">pending example (with block for pending)</dt>
+ <script type="text/javascript">makeYellow('example_group_8');</script>
+ <script type="text/javascript">moveProgressBar('100.0');</script>
+ <dd class="spec not_implemented"><span class="not_implemented_spec_name">should have a failing block, passed to pending, reported as &quot;PENDING: for some reason&quot; (PENDING: for some reason)</span></dd>
+ </dl>
+</div>
+<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>x seconds</strong>";</script>
+<script type="text/javascript">document.getElementById('totals').innerHTML = "17 examples, 6 failures, 3 pending";</script>
+</div>
+</div>
+</body>
+</html>
diff --git a/vendor/gems/rspec/spec/spec/runner/heckle_runner_spec.rb b/vendor/gems/rspec/spec/spec/runner/heckle_runner_spec.rb
new file mode 100644
index 000000000..539d908c2
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/heckle_runner_spec.rb
@@ -0,0 +1,78 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+unless [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM}
+ require 'spec/runner/heckle_runner'
+
+ module Foo
+ class Bar
+ def one; end
+ def two; end
+ end
+
+ class Zap
+ def three; end
+ def four; end
+ end
+ end
+
+ describe "HeckleRunner" do
+ before(:each) do
+ @heckle = mock("heckle", :null_object => true)
+ @heckle_class = mock("heckle_class")
+ end
+
+ it "should heckle all methods in all classes in a module" do
+ @heckle_class.should_receive(:new).with("Foo::Bar", "one", rspec_options).and_return(@heckle)
+ @heckle_class.should_receive(:new).with("Foo::Bar", "two", rspec_options).and_return(@heckle)
+ @heckle_class.should_receive(:new).with("Foo::Zap", "three", rspec_options).and_return(@heckle)
+ @heckle_class.should_receive(:new).with("Foo::Zap", "four", rspec_options).and_return(@heckle)
+
+ heckle_runner = Spec::Runner::HeckleRunner.new("Foo", @heckle_class)
+ heckle_runner.heckle_with
+ end
+
+ it "should heckle all methods in a class" do
+ @heckle_class.should_receive(:new).with("Foo::Bar", "one", rspec_options).and_return(@heckle)
+ @heckle_class.should_receive(:new).with("Foo::Bar", "two", rspec_options).and_return(@heckle)
+
+ heckle_runner = Spec::Runner::HeckleRunner.new("Foo::Bar", @heckle_class)
+ heckle_runner.heckle_with
+ end
+
+ it "should fail heckling when the class is not found" do
+ lambda do
+ heckle_runner = Spec::Runner::HeckleRunner.new("Foo::Bob", @heckle_class)
+ heckle_runner.heckle_with
+ end.should raise_error(StandardError, "Heckling failed - \"Foo::Bob\" is not a known class or module")
+ end
+
+ it "should heckle specific method in a class (with #)" do
+ @heckle_class.should_receive(:new).with("Foo::Bar", "two", rspec_options).and_return(@heckle)
+
+ heckle_runner = Spec::Runner::HeckleRunner.new("Foo::Bar#two", @heckle_class)
+ heckle_runner.heckle_with
+ end
+
+ it "should heckle specific method in a class (with .)" do
+ @heckle_class.should_receive(:new).with("Foo::Bar", "two", rspec_options).and_return(@heckle)
+
+ heckle_runner = Spec::Runner::HeckleRunner.new("Foo::Bar.two", @heckle_class)
+ heckle_runner.heckle_with
+ end
+ end
+
+ describe "Heckler" do
+ it "should say yes to tests_pass? if specs pass" do
+ options = mock("options", :null_object => true)
+ options.should_receive(:run_examples).and_return(true)
+ heckler = Spec::Runner::Heckler.new("Foo", nil, options)
+ heckler.tests_pass?.should be_true
+ end
+
+ it "should say no to tests_pass? if specs fail" do
+ options = mock("options", :null_object => true)
+ options.should_receive(:run_examples).and_return(false)
+ heckler = Spec::Runner::Heckler.new("Foo", nil, options)
+ heckler.tests_pass?.should be_false
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/heckler_spec.rb b/vendor/gems/rspec/spec/spec/runner/heckler_spec.rb
new file mode 100644
index 000000000..7cf6606ec
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/heckler_spec.rb
@@ -0,0 +1,13 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+unless [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM}
+ require 'spec/runner/heckle_runner'
+
+ describe "Heckler" do
+ it "should run examples on tests_pass?" do
+ options = Spec::Runner::Options.new(StringIO.new, StringIO.new)
+ options.should_receive(:run_examples).with().and_return(&options.method(:run_examples))
+ heckler = Spec::Runner::Heckler.new('Array', 'push', options)
+ heckler.tests_pass?
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/noisy_backtrace_tweaker_spec.rb b/vendor/gems/rspec/spec/spec/runner/noisy_backtrace_tweaker_spec.rb
new file mode 100644
index 000000000..e097f2ec0
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/noisy_backtrace_tweaker_spec.rb
@@ -0,0 +1,45 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Runner
+ describe "NoisyBacktraceTweaker" do
+ before(:each) do
+ @error = RuntimeError.new
+ @tweaker = NoisyBacktraceTweaker.new
+ end
+
+ it "should leave anything in lib spec dir" do
+ ["expectations", "mocks", "runner", "stubs"].each do |child|
+ @error.set_backtrace(["/lib/spec/#{child}/anything.rb"])
+ @tweaker.tweak_backtrace(@error)
+ @error.backtrace.should_not be_empty
+ end
+ end
+
+ it "should leave anything in spec dir" do
+ @error.set_backtrace(["/lib/spec/expectations/anything.rb"])
+ @tweaker.tweak_backtrace(@error)
+ @error.backtrace.should_not be_empty
+ end
+
+ it "should leave bin spec" do
+ @error.set_backtrace(["bin/spec:"])
+ @tweaker.tweak_backtrace(@error)
+ @error.backtrace.should_not be_empty
+ end
+
+ it "should not barf on nil backtrace" do
+ lambda do
+ @tweaker.tweak_backtrace(@error)
+ end.should_not raise_error
+ end
+
+ it "should clean up double slashes" do
+ @error.set_backtrace(["/a//b/c//d.rb"])
+ @tweaker.tweak_backtrace(@error)
+ @error.backtrace.should include("/a/b/c/d.rb")
+ end
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/option_parser_spec.rb b/vendor/gems/rspec/spec/spec/runner/option_parser_spec.rb
new file mode 100644
index 000000000..71619b8fc
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/option_parser_spec.rb
@@ -0,0 +1,378 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+require 'fileutils'
+
+describe "OptionParser" do
+ before(:each) do
+ @out = StringIO.new
+ @err = StringIO.new
+ @parser = Spec::Runner::OptionParser.new(@err, @out)
+ end
+
+ def parse(args)
+ @parser.parse(args)
+ @parser.options
+ end
+
+ it "should accept files to include" do
+ options = parse(["--pattern", "foo"])
+ options.filename_pattern.should == "foo"
+ end
+
+ it "should accept dry run option" do
+ options = parse(["--dry-run"])
+ options.dry_run.should be_true
+ end
+
+ it "should eval and use custom formatter when none of the builtins" do
+ options = parse(["--format", "Custom::Formatter"])
+ options.formatters[0].class.should be(Custom::Formatter)
+ end
+
+ it "should support formatters with relative and absolute paths, even on windows" do
+ options = parse([
+ "--format", "Custom::Formatter:C:\\foo\\bar",
+ "--format", "Custom::Formatter:foo/bar",
+ "--format", "Custom::Formatter:foo\\bar",
+ "--format", "Custom::Formatter:/foo/bar"
+ ])
+ options.formatters[0].where.should eql("C:\\foo\\bar")
+ options.formatters[1].where.should eql("foo/bar")
+ options.formatters[2].where.should eql("foo\\bar")
+ options.formatters[3].where.should eql("/foo/bar")
+ end
+
+ it "should not be verbose by default" do
+ options = parse([])
+ options.verbose.should be_nil
+ end
+
+ it "should not use colour by default" do
+ options = parse([])
+ options.colour.should == false
+ end
+
+ it "should print help to stdout if no args" do
+ pending 'A regression since 1.0.8' do
+ options = parse([])
+ @out.rewind
+ @out.read.should match(/Usage: spec \(FILE\|DIRECTORY\|GLOB\)\+ \[options\]/m)
+ end
+ end
+
+ it "should print help to stdout" do
+ options = parse(["--help"])
+ @out.rewind
+ @out.read.should match(/Usage: spec \(FILE\|DIRECTORY\|GLOB\)\+ \[options\]/m)
+ end
+
+ it "should print instructions about how to require missing formatter" do
+ lambda do
+ options = parse(["--format", "Custom::MissingFormatter"])
+ options.formatters
+ end.should raise_error(NameError)
+ @err.string.should match(/Couldn't find formatter class Custom::MissingFormatter/n)
+ end
+
+ it "should print version to stdout" do
+ options = parse(["--version"])
+ @out.rewind
+ @out.read.should match(/RSpec-\d+\.\d+\.\d+.*\(build \d+\) - BDD for Ruby\nhttp:\/\/rspec.rubyforge.org\/\n/n)
+ end
+
+ it "should require file when require specified" do
+ lambda do
+ parse(["--require", "whatever"])
+ end.should raise_error(LoadError)
+ end
+
+ it "should support c option" do
+ options = parse(["-c"])
+ options.colour.should be_true
+ end
+
+ it "should support queens colour option" do
+ options = parse(["--colour"])
+ options.colour.should be_true
+ end
+
+ it "should support us color option" do
+ options = parse(["--color"])
+ options.colour.should be_true
+ end
+
+ it "should support single example with -e option" do
+ options = parse(["-e", "something or other"])
+ options.examples.should eql(["something or other"])
+ end
+
+ it "should support single example with -s option (will be removed when autotest supports -e)" do
+ options = parse(["-s", "something or other"])
+ options.examples.should eql(["something or other"])
+ end
+
+ it "should support single example with --example option" do
+ options = parse(["--example", "something or other"])
+ options.examples.should eql(["something or other"])
+ end
+
+ it "should read several example names from file if --example is given an existing file name" do
+ options = parse(["--example", File.dirname(__FILE__) + '/examples.txt'])
+ options.examples.should eql([
+ "Sir, if you were my husband, I would poison your drink.",
+ "Madam, if you were my wife, I would drink it."])
+ end
+
+ it "should read no examples if given an empty file" do
+ options = parse(["--example", File.dirname(__FILE__) + '/empty_file.txt'])
+ options.examples.should eql([])
+ end
+
+ it "should use html formatter when format is h" do
+ options = parse(["--format", "h"])
+ options.formatters[0].class.should equal(Spec::Runner::Formatter::HtmlFormatter)
+ end
+
+ it "should use html story formatter when format is h" do
+ options = parse(["--format", "h"])
+ options.story_formatters[0].class.should equal(Spec::Runner::Formatter::Story::HtmlFormatter)
+ end
+
+ it "should use html formatter when format is html" do
+ options = parse(["--format", "html"])
+ options.formatters[0].class.should equal(Spec::Runner::Formatter::HtmlFormatter)
+ end
+
+ it "should use html story formatter when format is html" do
+ options = parse(["--format", "html"])
+ options.story_formatters[0].class.should equal(Spec::Runner::Formatter::Story::HtmlFormatter)
+ end
+
+ it "should use html formatter with explicit output when format is html:test.html" do
+ FileUtils.rm 'test.html' if File.exist?('test.html')
+ options = parse(["--format", "html:test.html"])
+ options.formatters # creates the file
+ File.should be_exist('test.html')
+ options.formatters[0].class.should equal(Spec::Runner::Formatter::HtmlFormatter)
+ options.formatters[0].close
+ FileUtils.rm 'test.html'
+ end
+
+ it "should use noisy backtrace tweaker with b option" do
+ options = parse(["-b"])
+ options.backtrace_tweaker.should be_instance_of(Spec::Runner::NoisyBacktraceTweaker)
+ end
+
+ it "should use noisy backtrace tweaker with backtrace option" do
+ options = parse(["--backtrace"])
+ options.backtrace_tweaker.should be_instance_of(Spec::Runner::NoisyBacktraceTweaker)
+ end
+
+ it "should use quiet backtrace tweaker by default" do
+ options = parse([])
+ options.backtrace_tweaker.should be_instance_of(Spec::Runner::QuietBacktraceTweaker)
+ end
+
+ it "should use progress bar formatter by default" do
+ options = parse([])
+ options.formatters[0].class.should equal(Spec::Runner::Formatter::ProgressBarFormatter)
+ end
+
+ it "should use specdoc formatter when format is s" do
+ options = parse(["--format", "s"])
+ options.formatters[0].class.should equal(Spec::Runner::Formatter::SpecdocFormatter)
+ end
+
+ it "should use specdoc formatter when format is specdoc" do
+ options = parse(["--format", "specdoc"])
+ options.formatters[0].class.should equal(Spec::Runner::Formatter::SpecdocFormatter)
+ end
+
+ it "should support diff option when format is not specified" do
+ options = parse(["--diff"])
+ options.diff_format.should == :unified
+ end
+
+ it "should use unified diff format option when format is unified" do
+ options = parse(["--diff", "unified"])
+ options.diff_format.should == :unified
+ options.differ_class.should equal(Spec::Expectations::Differs::Default)
+ end
+
+ it "should use context diff format option when format is context" do
+ options = parse(["--diff", "context"])
+ options.diff_format.should == :context
+ options.differ_class.should == Spec::Expectations::Differs::Default
+ end
+
+ it "should use custom diff format option when format is a custom format" do
+ Spec::Expectations.differ.should_not be_instance_of(Custom::Differ)
+
+ options = parse(["--diff", "Custom::Differ"])
+ options.parse_diff "Custom::Differ"
+ options.diff_format.should == :custom
+ options.differ_class.should == Custom::Differ
+ Spec::Expectations.differ.should be_instance_of(Custom::Differ)
+ end
+
+ it "should print instructions about how to fix missing differ" do
+ lambda { parse(["--diff", "Custom::MissingFormatter"]) }.should raise_error(NameError)
+ @err.string.should match(/Couldn't find differ class Custom::MissingFormatter/n)
+ end
+
+ describe "when attempting a focussed spec" do
+ attr_reader :file, :dir
+ before do
+ @original_rspec_options = $rspec_options
+ @file = "#{File.dirname(__FILE__)}/spec_parser/spec_parser_fixture.rb"
+ @dir = File.dirname(file)
+ end
+
+ after do
+ $rspec_options = @original_rspec_options
+ end
+
+ def parse(args)
+ options = super
+ $rspec_options = options
+ options.filename_pattern = "*_fixture.rb"
+ options
+ end
+
+ it "should support --line to identify spec" do
+ options = parse([file, "--line", "13"])
+ options.line_number.should == 13
+ options.examples.should be_empty
+ options.run_examples
+ options.examples.should eql(["d"])
+ end
+
+ it "should fail with error message if file is dir along with --line" do
+ options = parse([dir, "--line", "169"])
+ options.line_number.should == 169
+ options.run_examples
+ @err.string.should match(/You must specify one file, not a directory when using the --line option/n)
+ end
+
+ it "should fail with error message if file does not exist along with --line" do
+ options = parse(["some file", "--line", "169"])
+ proc do
+ options.run_examples
+ end.should raise_error
+ end
+
+ it "should fail with error message if more than one files are specified along with --line" do
+ options = parse([file, file, "--line", "169"])
+ options.run_examples
+ @err.string.should match(/Only one file can be specified when using the --line option/n)
+ end
+
+ it "should fail with error message if --example and --line are used simultaneously" do
+ options = parse([file, "--example", "some example", "--line", "169"])
+ options.run_examples
+ @err.string.should match(/You cannot use both --line and --example/n)
+ end
+ end
+
+ if [/mswin/, /java/].detect{|p| p =~ RUBY_PLATFORM}
+ it "should barf when --heckle is specified (and platform is windows)" do
+ lambda do
+ options = parse(["--heckle", "Spec"])
+ end.should raise_error(StandardError, "Heckle not supported on Windows")
+ end
+ else
+ it "should heckle when --heckle is specified (and platform is not windows)" do
+ options = parse(["--heckle", "Spec"])
+ options.heckle_runner.should be_instance_of(Spec::Runner::HeckleRunner)
+ end
+ end
+
+ it "should read options from file when --options is specified" do
+ options = parse(["--options", File.dirname(__FILE__) + "/spec.opts"])
+ options.diff_format.should_not be_nil
+ options.colour.should be_true
+ end
+
+ it "should default the formatter to ProgressBarFormatter when using options file" do
+ options = parse(["--options", File.dirname(__FILE__) + "/spec.opts"])
+ options.formatters.first.should be_instance_of(::Spec::Runner::Formatter::ProgressBarFormatter)
+ end
+
+ it "should read spaced and multi-line options from file when --options is specified" do
+ options = parse(["--options", File.dirname(__FILE__) + "/spec_spaced.opts"])
+ options.diff_format.should_not be_nil
+ options.colour.should be_true
+ options.formatters.first.should be_instance_of(::Spec::Runner::Formatter::SpecdocFormatter)
+ end
+
+ it "should save config to file when --generate-options is specified" do
+ FileUtils.rm 'test.spec.opts' if File.exist?('test.spec.opts')
+ options = parse(["--colour", "--generate-options", "test.spec.opts", "--diff"])
+ IO.read('test.spec.opts').should == "--colour\n--diff\n"
+ FileUtils.rm 'test.spec.opts'
+ end
+
+ it "should save config to file when -G is specified" do
+ FileUtils.rm 'test.spec.opts' if File.exist?('test.spec.opts')
+ options = parse(["--colour", "-G", "test.spec.opts", "--diff"])
+ IO.read('test.spec.opts').should == "--colour\n--diff\n"
+ FileUtils.rm 'test.spec.opts'
+ end
+
+ it "when --drb is specified, calls DrbCommandLine all of the other ARGV arguments" do
+ options = Spec::Runner::OptionParser.parse([
+ "some/spec.rb", "--diff", "--colour"
+ ], @err, @out)
+ Spec::Runner::DrbCommandLine.should_receive(:run).and_return do |options|
+ options.argv.should == ["some/spec.rb", "--diff", "--colour"]
+ end
+ parse(["some/spec.rb", "--diff", "--drb", "--colour"])
+ end
+
+ it "should reverse spec order when --reverse is specified" do
+ options = parse(["some/spec.rb", "--reverse"])
+ end
+
+ it "should set an mtime comparator when --loadby mtime" do
+ options = parse(["--loadby", 'mtime'])
+ runner = Spec::Runner::ExampleGroupRunner.new(options)
+ Spec::Runner::ExampleGroupRunner.should_receive(:new).
+ with(options).
+ and_return(runner)
+ runner.should_receive(:load_files).with(["most_recent_spec.rb", "command_line_spec.rb"])
+
+ Dir.chdir(File.dirname(__FILE__)) do
+ options.files << 'command_line_spec.rb'
+ options.files << 'most_recent_spec.rb'
+ FileUtils.touch "most_recent_spec.rb"
+ options.run_examples
+ FileUtils.rm "most_recent_spec.rb"
+ end
+ end
+
+ it "should use the standard runner by default" do
+ runner = ::Spec::Runner::ExampleGroupRunner.new(@parser.options)
+ ::Spec::Runner::ExampleGroupRunner.should_receive(:new).
+ with(@parser.options).
+ and_return(runner)
+ options = parse([])
+ options.run_examples
+ end
+
+ it "should use a custom runner when given" do
+ runner = Custom::ExampleGroupRunner.new(@parser.options, nil)
+ Custom::ExampleGroupRunner.should_receive(:new).
+ with(@parser.options, nil).
+ and_return(runner)
+ options = parse(["--runner", "Custom::ExampleGroupRunner"])
+ options.run_examples
+ end
+
+ it "should use a custom runner with extra options" do
+ runner = Custom::ExampleGroupRunner.new(@parser.options, 'something')
+ Custom::ExampleGroupRunner.should_receive(:new).
+ with(@parser.options, 'something').
+ and_return(runner)
+ options = parse(["--runner", "Custom::ExampleGroupRunner:something"])
+ options.run_examples
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/options_spec.rb b/vendor/gems/rspec/spec/spec/runner/options_spec.rb
new file mode 100644
index 000000000..6f0893751
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/options_spec.rb
@@ -0,0 +1,364 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Runner
+ describe Options do
+ before(:each) do
+ @err = StringIO.new('')
+ @out = StringIO.new('')
+ @options = Options.new(@err, @out)
+ end
+
+ after(:each) do
+ Spec::Expectations.differ = nil
+ end
+
+ describe "#examples" do
+ it "should default to empty array" do
+ @options.examples.should == []
+ end
+ end
+
+ describe "#include_pattern" do
+ it "should default to '**/*_spec.rb'" do
+ @options.filename_pattern.should == "**/*_spec.rb"
+ end
+ end
+
+ describe "#files_to_load" do
+
+ it "should load files not following pattern if named explicitly" do
+ file = File.expand_path(File.dirname(__FILE__) + "/resources/a_bar.rb")
+ @options.files << file
+ @options.files_to_load.should include(file)
+ end
+
+ describe "with default --pattern" do
+ it "should load files named _spec.rb" do
+ dir = File.expand_path(File.dirname(__FILE__) + "/resources/")
+ @options.files << dir
+ @options.files_to_load.should == ["#{dir}/a_spec.rb"]
+ end
+ end
+
+ describe "with explicit pattern (single)" do
+ before(:each) do
+ @options.filename_pattern = "**/*_foo.rb"
+ end
+
+ it "should load files following pattern" do
+ file = File.expand_path(File.dirname(__FILE__) + "/resources/a_foo.rb")
+ @options.files << file
+ @options.files_to_load.should include(file)
+ end
+
+ it "should load files in directories following pattern" do
+ dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+ @options.files << dir
+ @options.files_to_load.should include("#{dir}/a_foo.rb")
+ end
+
+ it "should not load files in directories not following pattern" do
+ dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+ @options.files << dir
+ @options.files_to_load.should_not include("#{dir}/a_bar.rb")
+ end
+ end
+
+ describe "with explicit pattern (comma,separated,values)" do
+
+ before(:each) do
+ @options.filename_pattern = "**/*_foo.rb,**/*_bar.rb"
+ end
+
+ it "should support comma separated values" do
+ dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+ @options.files << dir
+ @options.files_to_load.should include("#{dir}/a_foo.rb")
+ @options.files_to_load.should include("#{dir}/a_bar.rb")
+ end
+
+ it "should support comma separated values with spaces" do
+ dir = File.expand_path(File.dirname(__FILE__) + "/resources")
+ @options.files << dir
+ @options.files_to_load.should include("#{dir}/a_foo.rb")
+ @options.files_to_load.should include("#{dir}/a_bar.rb")
+ end
+
+ end
+
+ end
+
+ describe "#backtrace_tweaker" do
+ it "should default to QuietBacktraceTweaker" do
+ @options.backtrace_tweaker.class.should == QuietBacktraceTweaker
+ end
+ end
+
+ describe "#dry_run" do
+ it "should default to false" do
+ @options.dry_run.should == false
+ end
+ end
+
+ describe "#context_lines" do
+ it "should default to 3" do
+ @options.context_lines.should == 3
+ end
+ end
+
+ describe "#parse_diff with nil" do
+ before(:each) do
+ @options.parse_diff nil
+ end
+
+ it "should make diff_format unified" do
+ @options.diff_format.should == :unified
+ end
+
+ it "should set Spec::Expectations.differ to be a default differ" do
+ Spec::Expectations.differ.class.should ==
+ ::Spec::Expectations::Differs::Default
+ end
+ end
+
+ describe "#parse_diff with 'unified'" do
+ before(:each) do
+ @options.parse_diff 'unified'
+ end
+
+ it "should make diff_format unified and uses default differ_class" do
+ @options.diff_format.should == :unified
+ @options.differ_class.should equal(Spec::Expectations::Differs::Default)
+ end
+
+ it "should set Spec::Expectations.differ to be a default differ" do
+ Spec::Expectations.differ.class.should ==
+ ::Spec::Expectations::Differs::Default
+ end
+ end
+
+ describe "#parse_diff with 'context'" do
+ before(:each) do
+ @options.parse_diff 'context'
+ end
+
+ it "should make diff_format context and uses default differ_class" do
+ @options.diff_format.should == :context
+ @options.differ_class.should == Spec::Expectations::Differs::Default
+ end
+
+ it "should set Spec::Expectations.differ to be a default differ" do
+ Spec::Expectations.differ.class.should ==
+ ::Spec::Expectations::Differs::Default
+ end
+ end
+
+ describe "#parse_diff with Custom::Differ" do
+ before(:each) do
+ @options.parse_diff 'Custom::Differ'
+ end
+
+ it "should use custom differ_class" do
+ @options.diff_format.should == :custom
+ @options.differ_class.should == Custom::Differ
+ Spec::Expectations.differ.should be_instance_of(Custom::Differ)
+ end
+
+ it "should set Spec::Expectations.differ to be a default differ" do
+ Spec::Expectations.differ.class.should ==
+ ::Custom::Differ
+ end
+ end
+
+ describe "#parse_diff with missing class name" do
+ it "should raise error" do
+ lambda { @options.parse_diff "Custom::MissingDiffer" }.should raise_error(NameError)
+ @err.string.should match(/Couldn't find differ class Custom::MissingDiffer/n)
+ end
+ end
+
+ describe "#parse_example" do
+ it "with argument thats not a file path, sets argument as the example" do
+ example = "something or other"
+ File.file?(example).should == false
+ @options.parse_example example
+ @options.examples.should eql(["something or other"])
+ end
+
+ it "with argument that is a file path, sets examples to contents of the file" do
+ example = "#{File.dirname(__FILE__)}/examples.txt"
+ File.should_receive(:file?).with(example).and_return(true)
+ file = StringIO.new("Sir, if you were my husband, I would poison your drink.\nMadam, if you were my wife, I would drink it.")
+ File.should_receive(:open).with(example).and_return(file)
+
+ @options.parse_example example
+ @options.examples.should eql([
+ "Sir, if you were my husband, I would poison your drink.",
+ "Madam, if you were my wife, I would drink it."
+ ])
+ end
+ end
+
+ describe "#examples_should_not_be_run" do
+ it "should cause #run_examples to return true and do nothing" do
+ @options.examples_should_not_be_run
+ ExampleGroupRunner.should_not_receive(:new)
+
+ @options.run_examples.should be_true
+ end
+ end
+
+ describe "#load_class" do
+ it "should raise error when not class name" do
+ lambda do
+ @options.send(:load_class, 'foo', 'fruit', '--food')
+ end.should raise_error('"foo" is not a valid class name')
+ end
+ end
+
+ describe "#reporter" do
+ it "returns a Reporter" do
+ @options.reporter.should be_instance_of(Reporter)
+ @options.reporter.options.should === @options
+ end
+ end
+
+ describe "#add_example_group affecting passed in example_group" do
+ it "runs all examples when options.examples is nil" do
+ example_1_has_run = false
+ example_2_has_run = false
+ @example_group = Class.new(::Spec::Example::ExampleGroup).describe("Some Examples") do
+ it "runs 1" do
+ example_1_has_run = true
+ end
+ it "runs 2" do
+ example_2_has_run = true
+ end
+ end
+
+ @options.examples = nil
+
+ @options.add_example_group @example_group
+ @options.run_examples
+ example_1_has_run.should be_true
+ example_2_has_run.should be_true
+ end
+
+ it "keeps all example_definitions when options.examples is empty" do
+ example_1_has_run = false
+ example_2_has_run = false
+ @example_group = Class.new(::Spec::Example::ExampleGroup).describe("Some Examples") do
+ it "runs 1" do
+ example_1_has_run = true
+ end
+ it "runs 2" do
+ example_2_has_run = true
+ end
+ end
+
+ @options.examples = []
+
+ @options.add_example_group @example_group
+ @options.run_examples
+ example_1_has_run.should be_true
+ example_2_has_run.should be_true
+ end
+ end
+
+ describe "#add_example_group affecting example_group" do
+ it "adds example_group when example_group has example_definitions and is not shared" do
+ @example_group = Class.new(::Spec::Example::ExampleGroup).describe("Some Examples") do
+ it "uses this example_group" do
+ end
+ end
+
+ @options.number_of_examples.should == 0
+ @options.add_example_group @example_group
+ @options.number_of_examples.should == 1
+ @options.example_groups.length.should == 1
+ end
+ end
+
+ describe "#remove_example_group" do
+ it "should remove the ExampleGroup from the list of ExampleGroups" do
+ @example_group = Class.new(::Spec::Example::ExampleGroup).describe("Some Examples") do
+ end
+ @options.add_example_group @example_group
+ @options.example_groups.should include(@example_group)
+
+ @options.remove_example_group @example_group
+ @options.example_groups.should_not include(@example_group)
+ end
+ end
+
+ describe "#run_examples" do
+ it "should use the standard runner by default" do
+ runner = ::Spec::Runner::ExampleGroupRunner.new(@options)
+ ::Spec::Runner::ExampleGroupRunner.should_receive(:new).
+ with(@options).
+ and_return(runner)
+ @options.user_input_for_runner = nil
+
+ @options.run_examples
+ end
+
+ it "should use a custom runner when given" do
+ runner = Custom::ExampleGroupRunner.new(@options, nil)
+ Custom::ExampleGroupRunner.should_receive(:new).
+ with(@options, nil).
+ and_return(runner)
+ @options.user_input_for_runner = "Custom::ExampleGroupRunner"
+
+ @options.run_examples
+ end
+
+ it "should use a custom runner with extra options" do
+ runner = Custom::ExampleGroupRunner.new(@options, 'something')
+ Custom::ExampleGroupRunner.should_receive(:new).
+ with(@options, 'something').
+ and_return(runner)
+ @options.user_input_for_runner = "Custom::ExampleGroupRunner:something"
+
+ @options.run_examples
+ end
+
+ describe "when there are examples" do
+ before(:each) do
+ @options.add_example_group Class.new(::Spec::Example::ExampleGroup)
+ @options.formatters << Formatter::BaseTextFormatter.new(@options, @out)
+ end
+
+ it "runs the Examples and outputs the result" do
+ @options.run_examples
+ @out.string.should include("0 examples, 0 failures")
+ end
+
+ it "sets #examples_run? to true" do
+ @options.examples_run?.should be_false
+ @options.run_examples
+ @options.examples_run?.should be_true
+ end
+ end
+
+ describe "when there are no examples" do
+ before(:each) do
+ @options.formatters << Formatter::BaseTextFormatter.new(@options, @out)
+ end
+
+ it "does not run Examples and does not output a result" do
+ @options.run_examples
+ @out.string.should_not include("examples")
+ @out.string.should_not include("failures")
+ end
+
+ it "sets #examples_run? to false" do
+ @options.examples_run?.should be_false
+ @options.run_examples
+ @options.examples_run?.should be_false
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/output_one_time_fixture.rb b/vendor/gems/rspec/spec/spec/runner/output_one_time_fixture.rb
new file mode 100644
index 000000000..444730dc3
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/output_one_time_fixture.rb
@@ -0,0 +1,7 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "Running an Example" do
+ it "should not output twice" do
+ true.should be_true
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/runner/output_one_time_fixture_runner.rb b/vendor/gems/rspec/spec/spec/runner/output_one_time_fixture_runner.rb
new file mode 100644
index 000000000..a0e61316e
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/output_one_time_fixture_runner.rb
@@ -0,0 +1,8 @@
+dir = File.dirname(__FILE__)
+require "#{dir}/../../spec_helper"
+
+triggering_double_output = rspec_options
+options = Spec::Runner::OptionParser.parse(
+ ["#{dir}/output_one_time_fixture.rb"], $stderr, $stdout
+)
+Spec::Runner::CommandLine.run(options)
diff --git a/vendor/gems/rspec/spec/spec/runner/output_one_time_spec.rb b/vendor/gems/rspec/spec/spec/runner/output_one_time_spec.rb
new file mode 100644
index 000000000..8f67a380a
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/output_one_time_spec.rb
@@ -0,0 +1,16 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Runner
+ describe CommandLine do
+ it "should not output twice" do
+ dir = File.dirname(__FILE__)
+ Dir.chdir("#{dir}/../../..") do
+ output =`ruby #{dir}/output_one_time_fixture_runner.rb`
+ output.should include("1 example, 0 failures")
+ output.should_not include("0 examples, 0 failures")
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/runner/quiet_backtrace_tweaker_spec.rb b/vendor/gems/rspec/spec/spec/runner/quiet_backtrace_tweaker_spec.rb
new file mode 100644
index 000000000..e47b6c735
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/quiet_backtrace_tweaker_spec.rb
@@ -0,0 +1,56 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Runner
+ describe "QuietBacktraceTweaker" do
+ before(:each) do
+ @error = RuntimeError.new
+ @tweaker = QuietBacktraceTweaker.new
+ end
+
+ it "should not barf on nil backtrace" do
+ lambda do
+ @tweaker.tweak_backtrace(@error)
+ end.should_not raise_error
+ end
+
+ it "should remove anything from textmate ruby bundle" do
+ @error.set_backtrace(["/Applications/TextMate.app/Contents/SharedSupport/Bundles/Ruby.tmbundle/Support/tmruby.rb:147"])
+ @tweaker.tweak_backtrace(@error)
+ @error.backtrace.should be_empty
+ end
+
+ it "should remove anything in lib spec dir" do
+ ["expectations", "mocks", "runner"].each do |child|
+ element="/lib/spec/#{child}/anything.rb"
+ @error.set_backtrace([element])
+ @tweaker.tweak_backtrace(@error)
+ unless (@error.backtrace.empty?)
+ raise("Should have tweaked away '#{element}'")
+ end
+ end
+ end
+
+ it "should remove mock_frameworks/rspec" do
+ element = "mock_frameworks/rspec"
+ @error.set_backtrace([element])
+ @tweaker.tweak_backtrace(@error)
+ unless (@error.backtrace.empty?)
+ raise("Should have tweaked away '#{element}'")
+ end
+ end
+
+ it "should remove bin spec" do
+ @error.set_backtrace(["bin/spec:"])
+ @tweaker.tweak_backtrace(@error)
+ @error.backtrace.should be_empty
+ end
+
+ it "should clean up double slashes" do
+ @error.set_backtrace(["/a//b/c//d.rb"])
+ @tweaker.tweak_backtrace(@error)
+ @error.backtrace.should include("/a/b/c/d.rb")
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/reporter_spec.rb b/vendor/gems/rspec/spec/spec/runner/reporter_spec.rb
new file mode 100644
index 000000000..52377e7f3
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/reporter_spec.rb
@@ -0,0 +1,189 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+module Spec
+ module Runner
+ describe Reporter do
+ attr_reader :formatter_output, :options, :backtrace_tweaker, :formatter, :reporter, :example_group
+ before(:each) do
+ @formatter_output = StringIO.new
+ @options = Options.new(StringIO.new, StringIO.new)
+ @backtrace_tweaker = stub("backtrace tweaker", :tweak_backtrace => nil)
+ options.backtrace_tweaker = backtrace_tweaker
+ @formatter = ::Spec::Runner::Formatter::BaseTextFormatter.new(options, formatter_output)
+ options.formatters << formatter
+ @reporter = Reporter.new(options)
+ @example_group = create_example_group("example_group")
+ reporter.add_example_group example_group
+ end
+
+ def failure
+ Mocks::DuckTypeArgConstraint.new(:header, :exception)
+ end
+
+ def create_example_group(description_text)
+ example_group = Class.new(Spec::Example::ExampleGroup)
+ example_group.describe description_text
+ example_group
+ end
+
+ it "should assign itself as the reporter to options" do
+ options.reporter.should equal(@reporter)
+ end
+
+ it "should tell formatter when example_group is added" do
+ formatter.should_receive(:add_example_group).with(example_group)
+ reporter.add_example_group(example_group)
+ end
+
+ it "should handle multiple example_groups with same name" do
+ formatter.should_receive(:add_example_group).exactly(3).times
+ formatter.should_receive(:example_started).exactly(3).times
+ formatter.should_receive(:example_passed).exactly(3).times
+ formatter.should_receive(:start_dump)
+ formatter.should_receive(:dump_pending)
+ formatter.should_receive(:close).with(no_args)
+ formatter.should_receive(:dump_summary).with(anything(), 3, 0, 0)
+ reporter.add_example_group(create_example_group("example_group"))
+ reporter.example_started("spec 1")
+ reporter.example_finished("spec 1")
+ reporter.add_example_group(create_example_group("example_group"))
+ reporter.example_started("spec 2")
+ reporter.example_finished("spec 2")
+ reporter.add_example_group(create_example_group("example_group"))
+ reporter.example_started("spec 3")
+ reporter.example_finished("spec 3")
+ reporter.dump
+ end
+
+ it "should handle multiple examples with the same name" do
+ error=RuntimeError.new
+ passing = ExampleGroup.new("example")
+ failing = ExampleGroup.new("example")
+
+ formatter.should_receive(:add_example_group).exactly(2).times
+ formatter.should_receive(:example_passed).with(passing).exactly(2).times
+ formatter.should_receive(:example_failed).with(failing, 1, failure)
+ formatter.should_receive(:example_failed).with(failing, 2, failure)
+ formatter.should_receive(:dump_failure).exactly(2).times
+ formatter.should_receive(:start_dump)
+ formatter.should_receive(:dump_pending)
+ formatter.should_receive(:close).with(no_args)
+ formatter.should_receive(:dump_summary).with(anything(), 4, 2, 0)
+ backtrace_tweaker.should_receive(:tweak_backtrace).twice
+
+ reporter.add_example_group(create_example_group("example_group"))
+ reporter.example_finished(passing)
+ reporter.example_finished(failing, error)
+
+ reporter.add_example_group(create_example_group("example_group"))
+ reporter.example_finished(passing)
+ reporter.example_finished(failing, error)
+ reporter.dump
+ end
+
+ it "should push stats to formatter even with no data" do
+ formatter.should_receive(:start_dump)
+ formatter.should_receive(:dump_pending)
+ formatter.should_receive(:dump_summary).with(anything(), 0, 0, 0)
+ formatter.should_receive(:close).with(no_args)
+ reporter.dump
+ end
+
+ it "should push time to formatter" do
+ formatter.should_receive(:start).with(5)
+ formatter.should_receive(:start_dump)
+ formatter.should_receive(:dump_pending)
+ formatter.should_receive(:close).with(no_args)
+ formatter.should_receive(:dump_summary) do |time, a, b|
+ time.to_s.should match(/[0-9].[0-9|e|-]+/)
+ end
+ reporter.start(5)
+ reporter.end
+ reporter.dump
+ end
+
+ describe Reporter, "reporting one passing example" do
+ it "should tell formatter example passed" do
+ formatter.should_receive(:example_passed)
+ reporter.example_finished("example")
+ end
+
+ it "should not delegate to backtrace tweaker" do
+ formatter.should_receive(:example_passed)
+ backtrace_tweaker.should_not_receive(:tweak_backtrace)
+ reporter.example_finished("example")
+ end
+
+ it "should account for passing example in stats" do
+ formatter.should_receive(:example_passed)
+ formatter.should_receive(:start_dump)
+ formatter.should_receive(:dump_pending)
+ formatter.should_receive(:dump_summary).with(anything(), 1, 0, 0)
+ formatter.should_receive(:close).with(no_args)
+ reporter.example_finished("example")
+ reporter.dump
+ end
+ end
+
+ describe Reporter, "reporting one failing example" do
+ it "should tell formatter that example failed" do
+ formatter.should_receive(:example_failed)
+ reporter.example_finished(example_group, RuntimeError.new)
+ end
+
+ it "should delegate to backtrace tweaker" do
+ formatter.should_receive(:example_failed)
+ backtrace_tweaker.should_receive(:tweak_backtrace)
+ reporter.example_finished(ExampleGroup.new("example"), RuntimeError.new)
+ end
+
+ it "should account for failing example in stats" do
+ example = ExampleGroup.new("example")
+ formatter.should_receive(:example_failed).with(example, 1, failure)
+ formatter.should_receive(:start_dump)
+ formatter.should_receive(:dump_pending)
+ formatter.should_receive(:dump_failure).with(1, anything())
+ formatter.should_receive(:dump_summary).with(anything(), 1, 1, 0)
+ formatter.should_receive(:close).with(no_args)
+ reporter.example_finished(example, RuntimeError.new)
+ reporter.dump
+ end
+
+ end
+
+ describe Reporter, "reporting one pending example (ExamplePendingError)" do
+ it "should tell formatter example is pending" do
+ example = ExampleGroup.new("example")
+ formatter.should_receive(:example_pending).with(example_group.description, example, "reason")
+ formatter.should_receive(:add_example_group).with(example_group)
+ reporter.add_example_group(example_group)
+ reporter.example_finished(example, Spec::Example::ExamplePendingError.new("reason"))
+ end
+
+ it "should account for pending example in stats" do
+ example = ExampleGroup.new("example")
+ formatter.should_receive(:example_pending).with(example_group.description, example, "reason")
+ formatter.should_receive(:start_dump)
+ formatter.should_receive(:dump_pending)
+ formatter.should_receive(:dump_summary).with(anything(), 1, 0, 1)
+ formatter.should_receive(:close).with(no_args)
+ formatter.should_receive(:add_example_group).with(example_group)
+ reporter.add_example_group(example_group)
+ reporter.example_finished(example, Spec::Example::ExamplePendingError.new("reason"))
+ reporter.dump
+ end
+ end
+
+ describe Reporter, "reporting one pending example (PendingExampleFixedError)" do
+ it "should tell formatter pending example is fixed" do
+ formatter.should_receive(:example_failed) do |name, counter, failure|
+ failure.header.should == "'example_group example' FIXED"
+ end
+ formatter.should_receive(:add_example_group).with(example_group)
+ reporter.add_example_group(example_group)
+ reporter.example_finished(ExampleGroup.new("example"), Spec::Example::PendingExampleFixedError.new("reason"))
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/resources/a_bar.rb b/vendor/gems/rspec/spec/spec/runner/resources/a_bar.rb
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/resources/a_bar.rb
diff --git a/vendor/gems/rspec/spec/spec/runner/resources/a_foo.rb b/vendor/gems/rspec/spec/spec/runner/resources/a_foo.rb
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/resources/a_foo.rb
diff --git a/vendor/gems/rspec/spec/spec/runner/resources/a_spec.rb b/vendor/gems/rspec/spec/spec/runner/resources/a_spec.rb
new file mode 100644
index 000000000..d9b67cc76
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/resources/a_spec.rb
@@ -0,0 +1 @@
+# Empty - used by ../options_spec.rb \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/runner/spec.opts b/vendor/gems/rspec/spec/spec/runner/spec.opts
new file mode 100644
index 000000000..fd816a424
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/spec.opts
@@ -0,0 +1,2 @@
+--diff
+--colour \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/runner/spec_parser/spec_parser_fixture.rb b/vendor/gems/rspec/spec/spec/runner/spec_parser/spec_parser_fixture.rb
new file mode 100644
index 000000000..14602d934
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/spec_parser/spec_parser_fixture.rb
@@ -0,0 +1,70 @@
+require File.dirname(__FILE__) + '/../../../spec_helper.rb'
+
+describe "c" do
+
+ it "1" do
+ end
+
+ it "2" do
+ end
+
+end
+
+describe "d" do
+
+ it "3" do
+ end
+
+ it "4" do
+ end
+
+end
+
+class SpecParserSubject
+end
+
+describe SpecParserSubject do
+
+ it "5" do
+ end
+
+end
+
+describe SpecParserSubject, "described" do
+
+ it "6" do
+ end
+
+end
+
+describe SpecParserSubject, "described", :something => :something_else do
+
+ it "7" do
+ end
+
+end
+
+describe "described", :something => :something_else do
+
+ it "8" do
+ end
+
+end
+
+describe "e" do
+
+ it "9" do
+ end
+
+ it "10" do
+ end
+
+ describe "f" do
+ it "11" do
+ end
+
+ it "12" do
+ end
+ end
+
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/spec_parser_spec.rb b/vendor/gems/rspec/spec/spec/runner/spec_parser_spec.rb
new file mode 100644
index 000000000..3d8d9c2e9
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/spec_parser_spec.rb
@@ -0,0 +1,79 @@
+require File.dirname(__FILE__) + '/../../spec_helper.rb'
+
+describe "SpecParser" do
+ attr_reader :parser, :file
+ before(:each) do
+ @parser = Spec::Runner::SpecParser.new
+ @file = "#{File.dirname(__FILE__)}/spec_parser/spec_parser_fixture.rb"
+ require file
+ end
+
+ it "should find spec name for 'specify' at same line" do
+ parser.spec_name_for(file, 5).should == "c 1"
+ end
+
+ it "should find spec name for 'specify' at end of spec line" do
+ parser.spec_name_for(file, 6).should == "c 1"
+ end
+
+ it "should find context for 'context' above all specs" do
+ parser.spec_name_for(file, 4).should == "c"
+ end
+
+ it "should find spec name for 'it' at same line" do
+ parser.spec_name_for(file, 15).should == "d 3"
+ end
+
+ it "should find spec name for 'it' at end of spec line" do
+ parser.spec_name_for(file, 16).should == "d 3"
+ end
+
+ it "should find context for 'describe' above all specs" do
+ parser.spec_name_for(file, 14).should == "d"
+ end
+
+ it "should find nearest example name between examples" do
+ parser.spec_name_for(file, 7).should == "c 1"
+ end
+
+ it "should find nothing outside a context" do
+ parser.spec_name_for(file, 2).should be_nil
+ end
+
+ it "should find context name for type" do
+ parser.spec_name_for(file, 26).should == "SpecParserSubject"
+ end
+
+ it "should find context and spec name for type" do
+ parser.spec_name_for(file, 28).should == "SpecParserSubject 5"
+ end
+
+ it "should find context and description for type" do
+ parser.spec_name_for(file, 33).should == "SpecParserSubject described"
+ end
+
+ it "should find context and description and example for type" do
+ parser.spec_name_for(file, 36).should == "SpecParserSubject described 6"
+ end
+
+ it "should find context and description for type with modifications" do
+ parser.spec_name_for(file, 40).should == "SpecParserSubject described"
+ end
+
+ it "should find context and described and example for type with modifications" do
+ parser.spec_name_for(file, 43).should == "SpecParserSubject described 7"
+ end
+
+ it "should find example group" do
+ parser.spec_name_for(file, 47).should == "described"
+ end
+
+ it "should find example" do
+ parser.spec_name_for(file, 50).should == "described 8"
+ end
+
+ it "should find nested example" do
+ parser.spec_name_for(file, 63).should == "e f 11"
+ end
+
+end
diff --git a/vendor/gems/rspec/spec/spec/runner/spec_spaced.opts b/vendor/gems/rspec/spec/spec/runner/spec_spaced.opts
new file mode 100644
index 000000000..6b3efd20f
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner/spec_spaced.opts
@@ -0,0 +1,2 @@
+--diff --colour
+--format s \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/runner_spec.rb b/vendor/gems/rspec/spec/spec/runner_spec.rb
new file mode 100644
index 000000000..d75e66111
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/runner_spec.rb
@@ -0,0 +1,11 @@
+require File.dirname(__FILE__) + '/../spec_helper.rb'
+
+module Spec
+ describe Runner, ".configure" do
+ it "should yield global configuration" do
+ Spec::Runner.configure do |config|
+ config.should equal(Spec::Runner.configuration)
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/spec_classes.rb b/vendor/gems/rspec/spec/spec/spec_classes.rb
new file mode 100644
index 000000000..c8900a789
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/spec_classes.rb
@@ -0,0 +1,133 @@
+# This file contains various classes used by the specs.
+module Spec
+ module Expectations
+ class Person
+ attr_reader :name
+ def initialize name
+ @name = name
+ end
+ def == other
+ return @name == other.name
+ end
+ end
+
+ class ClassWithMultiWordPredicate
+ def multi_word_predicate?
+ true
+ end
+ end
+
+ module Helper
+ class CollectionWithSizeMethod
+ def initialize; @list = []; end
+ def size; @list.size; end
+ def push(item); @list.push(item); end
+ end
+
+ class CollectionWithLengthMethod
+ def initialize; @list = []; end
+ def length; @list.size; end
+ def push(item); @list.push(item); end
+ end
+
+ class CollectionOwner
+ attr_reader :items_in_collection_with_size_method, :items_in_collection_with_length_method
+
+ def initialize
+ @items_in_collection_with_size_method = CollectionWithSizeMethod.new
+ @items_in_collection_with_length_method = CollectionWithLengthMethod.new
+ end
+
+ def add_to_collection_with_size_method(item)
+ @items_in_collection_with_size_method.push(item)
+ end
+
+ def add_to_collection_with_length_method(item)
+ @items_in_collection_with_length_method.push(item)
+ end
+
+ def items_for(arg)
+ return [1, 2, 3] if arg == 'a'
+ [1]
+ end
+
+ def items
+ @items_in_collection_with_size_method
+ end
+ end
+
+ class HandCodedMock
+ include Spec::Matchers
+ def initialize(return_val)
+ @return_val = return_val
+ @funny_called = false
+ end
+
+ def funny?
+ @funny_called = true
+ @return_val
+ end
+
+ def hungry?(a, b, c)
+ a.should equal(1)
+ b.should equal(2)
+ c.should equal(3)
+ @funny_called = true
+ @return_val
+ end
+
+ def exists?
+ @return_val
+ end
+
+ def multi_word_predicate?
+ @return_val
+ end
+
+ def rspec_verify
+ @funny_called.should be_true
+ end
+ end
+ class ClassWithUnqueriedPredicate
+ attr_accessor :foo
+ def initialize(foo)
+ @foo = foo
+ end
+ end
+ end
+ end
+end
+
+module Custom
+ require 'spec/runner/formatter/base_text_formatter'
+ class Formatter < Spec::Runner::Formatter::BaseTextFormatter
+ attr_reader :options, :where
+
+ def initialize(options, where)
+ @options = options
+ @where = where
+ end
+ end
+
+ class BadFormatter < Spec::Runner::Formatter::BaseTextFormatter
+ attr_reader :where
+
+ def initialize(options, where)
+ bad_method
+ end
+ end
+
+ class Differ
+ attr_reader :options
+ def initialize(options)
+ @options = options
+ end
+
+ def diff_as_object(target, expected)
+ ""
+ end
+ end
+end
+
+class FakeReporter < Spec::Runner::Reporter
+end
diff --git a/vendor/gems/rspec/spec/spec/story/builders.rb b/vendor/gems/rspec/spec/spec/story/builders.rb
new file mode 100644
index 000000000..77d50d53e
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/builders.rb
@@ -0,0 +1,46 @@
+module Spec
+ module Story
+ class StoryBuilder
+ def initialize
+ @title = 'a story'
+ @narrative = 'narrative'
+ end
+
+ def title(value)
+ @title = value
+ self
+ end
+
+ def narrative(value)
+ @narrative = value
+ self
+ end
+
+ def to_story(&block)
+ block = lambda {} unless block_given?
+ Story.new @title, @narrative, &block
+ end
+ end
+
+ class ScenarioBuilder
+ def initialize
+ @name = 'a scenario'
+ @story = StoryBuilder.new.to_story
+ end
+
+ def name(value)
+ @name = value
+ self
+ end
+
+ def story(value)
+ @story = value
+ self
+ end
+
+ def to_scenario(&block)
+ Scenario.new @story, @name, &block
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/story/extensions/main_spec.rb b/vendor/gems/rspec/spec/spec/story/extensions/main_spec.rb
new file mode 100644
index 000000000..acdc341ce
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/extensions/main_spec.rb
@@ -0,0 +1,161 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+module Spec
+ module Story
+ module Extensions
+ describe "the main object extended with Main", :shared => true do
+ before(:each) do
+ @main = Class.new do; include Main; end
+ @original_rspec_story_steps, $rspec_story_steps = $rspec_story_steps, nil
+ end
+
+ after(:each) do
+ $rspec_story_steps = @original_rspec_story_steps
+ end
+
+ def have_step(type, name)
+ return simple_matcher(%[step group containing a #{type} named #{name.inspect}]) do |actual|
+ Spec::Story::Step === actual.find(type, name)
+ end
+ end
+ end
+
+ describe Main, "#run_story" do
+ it_should_behave_like "the main object extended with Main"
+
+ it "should create a PlainTextStoryRunner with run_story" do
+ Spec::Story::Runner::PlainTextStoryRunner.should_receive(:new).and_return(mock("runner", :null_object => true))
+ @main.run_story
+ end
+
+ it "should yield the runner if arity == 1" do
+ File.should_receive(:read).with("some/path").and_return("Story: foo")
+ $main_spec_runner = nil
+ @main.run_story("some/path") do |runner|
+ $main_spec_runner = runner
+ end
+ $main_spec_runner.should be_an_instance_of(Spec::Story::Runner::PlainTextStoryRunner)
+ end
+
+ it "should run in the runner if arity == 0" do
+ File.should_receive(:read).with("some/path").and_return("Story: foo")
+ $main_spec_runner = nil
+ @main.run_story("some/path") do
+ $main_spec_runner = self
+ end
+ $main_spec_runner.should be_an_instance_of(Spec::Story::Runner::PlainTextStoryRunner)
+ end
+
+ it "should tell the PlainTextStoryRunner to run with run_story" do
+ runner = mock("runner")
+ Spec::Story::Runner::PlainTextStoryRunner.should_receive(:new).and_return(runner)
+ runner.should_receive(:run)
+ @main.run_story
+ end
+ end
+
+ describe Main, "#steps_for" do
+ it_should_behave_like "the main object extended with Main"
+
+ it "should have no steps for a non existent key" do
+ @main.steps_for(:key).find(:given, "foo").should be_nil
+ end
+
+ it "should create steps for a key" do
+ $main_spec_invoked = false
+ @main.steps_for(:key) do
+ Given("foo") {
+ $main_spec_invoked = true
+ }
+ end
+ @main.steps_for(:key).find(:given, "foo").perform(Object.new, "foo")
+ $main_spec_invoked.should be_true
+ end
+
+ it "should append steps to steps_for a given key" do
+ @main.steps_for(:key) do
+ Given("first") {}
+ end
+ @main.steps_for(:key) do
+ Given("second") {}
+ end
+ @main.steps_for(:key).should have_step(:given, "first")
+ @main.steps_for(:key).should have_step(:given, "second")
+ end
+ end
+
+ describe Main, "#with_steps_for adding new steps" do
+ it_should_behave_like "the main object extended with Main"
+
+ it "should result in a group containing pre-existing steps and newly defined steps" do
+ first_group = @main.steps_for(:key) do
+ Given("first") {}
+ end
+ second_group = @main.with_steps_for(:key) do
+ Given("second") {}
+ end
+
+ second_group.should have_step(:given, "first")
+ second_group.should have_step(:given, "second")
+ end
+
+ it "should not add its steps to the existing group" do
+ first_group = @main.steps_for(:key) do
+ Given("first") {}
+ end
+ second_group = @main.with_steps_for(:key) do
+ Given("second") {}
+ end
+
+ first_group.should have_step(:given, "first")
+ first_group.should_not have_step(:given, "second")
+ end
+ end
+
+ describe Main, "#with_steps_for running a story" do
+ it_should_behave_like "the main object extended with Main"
+
+ before(:each) do
+ @runner = mock("runner")
+ @runner_step_group = StepGroup.new
+ @runner.stub!(:steps).and_return(@runner_step_group)
+ @runner.stub!(:run)
+ Spec::Story::Runner::PlainTextStoryRunner.stub!(:new).and_return(@runner)
+ end
+
+ it "should create a PlainTextStoryRunner with a path" do
+ Spec::Story::Runner::PlainTextStoryRunner.should_receive(:new).with('path/to/file',{}).and_return(@runner)
+ @main.with_steps_for(:foo) do
+ run 'path/to/file'
+ end
+ end
+
+ it "should create a PlainTextStoryRunner with a path and options" do
+ Spec::Story::Runner::PlainTextStoryRunner.should_receive(:new).with(anything,{:bar => :baz}).and_return(@runner)
+ @main.with_steps_for(:foo) do
+ run 'path/to/file', :bar => :baz
+ end
+ end
+
+ it "should pass the group it creates to the runner's steps" do
+ steps = @main.steps_for(:ice_cream) do
+ Given("vanilla") {}
+ end
+ @main.with_steps_for(:ice_cream) do
+ run 'foo'
+ end
+ @runner_step_group.should have_step(:given, "vanilla")
+ end
+
+ it "should run a story" do
+ @runner.should_receive(:run)
+ Spec::Story::Runner::PlainTextStoryRunner.should_receive(:new).and_return(@runner)
+ @main.with_steps_for(:foo) do
+ run 'path/to/file'
+ end
+ end
+
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/story/extensions_spec.rb b/vendor/gems/rspec/spec/spec/story/extensions_spec.rb
new file mode 100644
index 000000000..612ddc72f
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/extensions_spec.rb
@@ -0,0 +1,14 @@
+require File.dirname(__FILE__) + '/story_helper'
+
+require 'spec/story'
+
+describe Kernel, "#Story" do
+ before(:each) do
+ Kernel.stub!(:at_exit)
+ end
+
+ it "should delegate to ::Spec::Story::Runner.story_runner" do
+ ::Spec::Story::Runner.story_runner.should_receive(:Story)
+ story = Story("title","narrative"){}
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/story/given_scenario_spec.rb b/vendor/gems/rspec/spec/spec/story/given_scenario_spec.rb
new file mode 100644
index 000000000..a688f88d5
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/given_scenario_spec.rb
@@ -0,0 +1,27 @@
+require File.dirname(__FILE__) + '/story_helper'
+
+module Spec
+ module Story
+ describe GivenScenario do
+ it 'should execute a scenario from the current story in its world' do
+ # given
+ class MyWorld
+ attr :scenario_ran
+ end
+ instance = World.create(MyWorld)
+ scenario = ScenarioBuilder.new.to_scenario do
+ @scenario_ran = true
+ end
+ Runner::StoryRunner.should_receive(:scenario_from_current_story).with('scenario name').and_return(scenario)
+
+ step = GivenScenario.new 'scenario name'
+
+ # when
+ step.perform(instance, nil)
+
+ # then
+ instance.scenario_ran.should be_true
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/story/runner/plain_text_story_runner_spec.rb b/vendor/gems/rspec/spec/spec/story/runner/plain_text_story_runner_spec.rb
new file mode 100644
index 000000000..1d5f2e0c3
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/runner/plain_text_story_runner_spec.rb
@@ -0,0 +1,92 @@
+require File.dirname(__FILE__) + '/../story_helper'
+
+module Spec
+ module Story
+ module Runner
+ describe PlainTextStoryRunner do
+ before(:each) do
+ StoryParser.stub!(:new).and_return(@parser = mock("parser"))
+ @parser.stub!(:parse).and_return([])
+ File.stub!(:read).with("path").and_return("this\nand that")
+ end
+
+ it "should provide access to steps" do
+ runner = PlainTextStoryRunner.new("path")
+
+ runner.steps do |add|
+ add.given("baz") {}
+ end
+
+ runner.steps.find(:given, "baz").should_not be_nil
+ end
+
+ it "should parse a story file" do
+ runner = PlainTextStoryRunner.new("path")
+
+ during {
+ runner.run
+ }.expect {
+ @parser.should_receive(:parse).with(["this", "and that"])
+ }
+ end
+
+ it "should build up a mediator with its own steps and the singleton story_runner" do
+ runner = PlainTextStoryRunner.new("path")
+ Spec::Story::Runner.should_receive(:story_runner).and_return(story_runner = mock("story runner"))
+ Spec::Story::Runner::StoryMediator.should_receive(:new).with(runner.steps, story_runner, {}).
+ and_return(mediator = stub("mediator", :run_stories => nil))
+ runner.run
+ end
+
+ it "should build up a parser with the mediator" do
+ runner = PlainTextStoryRunner.new("path")
+ Spec::Story::Runner.should_receive(:story_runner).and_return(story_runner = mock("story runner"))
+ Spec::Story::Runner::StoryMediator.should_receive(:new).and_return(mediator = stub("mediator", :run_stories => nil))
+ Spec::Story::Runner::StoryParser.should_receive(:new).with(mediator).and_return(@parser)
+ runner.run
+ end
+
+ it "should tell the mediator to run the stories" do
+ runner = PlainTextStoryRunner.new("path")
+ mediator = mock("mediator")
+ Spec::Story::Runner::StoryMediator.should_receive(:new).and_return(mediator)
+ mediator.should_receive(:run_stories)
+ runner.run
+ end
+
+ it "should accept a block instead of a path" do
+ runner = PlainTextStoryRunner.new do |runner|
+ runner.load("path/to/story")
+ end
+ File.should_receive(:read).with("path/to/story").and_return("this\nand that")
+ runner.run
+ end
+
+ it "should tell you if you try to run with no path set" do
+ runner = PlainTextStoryRunner.new
+ lambda {
+ runner.run
+ }.should raise_error(RuntimeError, "You must set a path to the file with the story. See the RDoc.")
+ end
+
+ it "should pass options to the mediator" do
+ runner = PlainTextStoryRunner.new("path", :foo => :bar)
+ Spec::Story::Runner::StoryMediator.should_receive(:new).
+ with(anything, anything, :foo => :bar).
+ and_return(mediator = stub("mediator", :run_stories => nil))
+ runner.run
+ end
+
+ it "should provide access to its options" do
+ runner = PlainTextStoryRunner.new("path")
+ runner[:foo] = :bar
+ Spec::Story::Runner::StoryMediator.should_receive(:new).
+ with(anything, anything, :foo => :bar).
+ and_return(mediator = stub("mediator", :run_stories => nil))
+ runner.run
+ end
+
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/story/runner/scenario_collector_spec.rb b/vendor/gems/rspec/spec/spec/story/runner/scenario_collector_spec.rb
new file mode 100644
index 000000000..042c41e8d
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/runner/scenario_collector_spec.rb
@@ -0,0 +1,27 @@
+require File.dirname(__FILE__) + '/../story_helper'
+
+module Spec
+ module Story
+ module Runner
+ describe ScenarioCollector do
+ it 'should construct scenarios with the supplied story' do
+ # given
+ story = stub_everything('story')
+ scenario_collector = ScenarioCollector.new(story)
+
+ # when
+ scenario_collector.Scenario 'scenario1' do end
+ scenario_collector.Scenario 'scenario2' do end
+ scenarios = scenario_collector.scenarios
+
+ # then
+ scenario_collector.should have(2).scenarios
+ scenarios.first.name.should == 'scenario1'
+ scenarios.first.story.should equal(story)
+ scenarios.last.name.should == 'scenario2'
+ scenarios.last.story.should equal(story)
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/story/runner/scenario_runner_spec.rb b/vendor/gems/rspec/spec/spec/story/runner/scenario_runner_spec.rb
new file mode 100644
index 000000000..a69ed4a99
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/runner/scenario_runner_spec.rb
@@ -0,0 +1,142 @@
+require File.dirname(__FILE__) + '/../story_helper'
+
+module Spec
+ module Story
+ module Runner
+ describe ScenarioRunner do
+ it 'should run a scenario in its story' do
+ # given
+ world = stub_everything
+ scenario_runner = ScenarioRunner.new
+ $answer = nil
+ story = Story.new 'story', 'narrative' do
+ @answer = 42 # this should be available to the scenario
+ end
+ scenario = Scenario.new story, 'scenario' do
+ $answer = @answer
+ end
+
+ # when
+ scenario_runner.run(scenario, world)
+
+ # then
+ $answer.should == 42
+ end
+
+ it 'should allow scenarios to share methods' do
+ # given
+ world = stub_everything
+ $shared_invoked = 0
+ story = Story.new 'story', 'narrative' do
+ def shared
+ $shared_invoked += 1
+ end
+ end
+ scenario1 = Scenario.new story, 'scenario1' do
+ shared()
+ end
+ scenario2 = Scenario.new story, 'scenario2' do
+ shared()
+ end
+ scenario_runner = ScenarioRunner.new
+
+ # when
+ scenario_runner.run(scenario1, world)
+ scenario_runner.run(scenario2, world)
+
+ # then
+ $shared_invoked.should == 2
+ end
+
+ it 'should notify listeners when a scenario starts' do
+ # given
+ world = stub_everything
+ story = Story.new 'story', 'narrative' do end
+ scenario = Scenario.new story, 'scenario1' do
+ # succeeds
+ end
+ scenario_runner = ScenarioRunner.new
+ mock_listener1 = stub_everything('listener1')
+ mock_listener2 = stub_everything('listener2')
+ scenario_runner.add_listener(mock_listener1)
+ scenario_runner.add_listener(mock_listener2)
+
+ # expect
+ mock_listener1.should_receive(:scenario_started).with('story', 'scenario1')
+ mock_listener2.should_receive(:scenario_started).with('story', 'scenario1')
+
+ # when
+ scenario_runner.run(scenario, world)
+
+ # then
+ end
+
+ it 'should notify listeners when a scenario succeeds' do
+ # given
+ world = stub_everything('world')
+ story = Story.new 'story', 'narrative' do end
+ scenario = Scenario.new story, 'scenario1' do
+ # succeeds
+ end
+ scenario_runner = ScenarioRunner.new
+ mock_listener1 = stub_everything('listener1')
+ mock_listener2 = stub_everything('listener2')
+ scenario_runner.add_listener(mock_listener1)
+ scenario_runner.add_listener(mock_listener2)
+
+ # expect
+ mock_listener1.should_receive(:scenario_succeeded).with('story', 'scenario1')
+ mock_listener2.should_receive(:scenario_succeeded).with('story', 'scenario1')
+
+ # when
+ scenario_runner.run(scenario, world)
+
+ # then
+ end
+
+ it 'should notify listeners ONCE when a scenario raises an error' do
+ # given
+ error = RuntimeError.new('oops')
+ story = Story.new 'title', 'narrative' do end
+ scenario = Scenario.new story, 'scenario1' do
+ end
+ scenario_runner = ScenarioRunner.new
+ mock_listener = stub_everything('listener')
+ scenario_runner.add_listener(mock_listener)
+ world = stub_everything
+
+ # expect
+ world.should_receive(:errors).twice.and_return([error, error])
+ mock_listener.should_receive(:scenario_failed).with('title', 'scenario1', error).once
+
+ # when
+ scenario_runner.run scenario, world
+
+ # then
+ end
+
+ it 'should notify listeners when a scenario is pending' do
+ # given
+ pending_error = Spec::Example::ExamplePendingError.new('todo')
+ story = Story.new 'title', 'narrative' do end
+ scenario = Scenario.new story, 'scenario1' do
+ end
+ scenario_runner = ScenarioRunner.new
+ mock_listener = mock('listener')
+ scenario_runner.add_listener(mock_listener)
+ world = stub_everything
+
+ # expect
+ world.should_receive(:errors).twice.and_return([pending_error, pending_error])
+ mock_listener.should_receive(:scenario_started).with('title', 'scenario1')
+ mock_listener.should_receive(:scenario_pending).with('title', 'scenario1', 'todo').once
+
+ # when
+ scenario_runner.run scenario, world
+
+ # then
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/story/runner/story_mediator_spec.rb b/vendor/gems/rspec/spec/spec/story/runner/story_mediator_spec.rb
new file mode 100644
index 000000000..4192e483a
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/runner/story_mediator_spec.rb
@@ -0,0 +1,133 @@
+require File.dirname(__FILE__) + '/../story_helper'
+
+module Spec
+ module Story
+ module Runner
+
+ describe StoryMediator do
+ before(:each) do
+ $story_mediator_spec_value = nil
+ @step_group = StepGroup.new
+ @step_group.create_matcher(:given, "given") { $story_mediator_spec_value = "given matched" }
+ @step_group.create_matcher(:when, "when") { $story_mediator_spec_value = "when matched" }
+ @step_group.create_matcher(:then, "then") { $story_mediator_spec_value = "then matched" }
+
+ @scenario_runner = ScenarioRunner.new
+ @runner = StoryRunner.new @scenario_runner
+ @mediator = StoryMediator.new @step_group, @runner
+ end
+
+ def run_stories
+ @mediator.run_stories
+ @runner.run_stories
+ end
+
+ it "should have no stories" do
+ @mediator.stories.should be_empty
+ end
+
+ it "should create two stories" do
+ @mediator.create_story "story title", "story narrative"
+ @mediator.create_story "story title 2", "story narrative 2"
+ run_stories
+
+ @runner.should have(2).stories
+ @runner.stories.first.title.should == "story title"
+ @runner.stories.first.narrative.should == "story narrative"
+ @runner.stories.last.title.should == "story title 2"
+ @runner.stories.last.narrative.should == "story narrative 2"
+ end
+
+ it "should create a scenario" do
+ @mediator.create_story "title", "narrative"
+ @mediator.create_scenario "scenario name"
+ run_stories
+
+ @runner.should have(1).scenarios
+ @runner.scenarios.first.name.should == "scenario name"
+ @runner.scenarios.first.story.should == @runner.stories.first
+ end
+
+ it "should create a given scenario step if one matches" do
+ pending("need to untangle the dark mysteries of the story runner - something needs to get stubbed here") do
+ story = @mediator.create_story "title", "narrative"
+ @mediator.create_scenario "previous scenario"
+ @mediator.create_scenario "current scenario"
+ @mediator.create_given_scenario "previous scenario"
+ run_stories
+
+ $story_mediator_spec_value.should == "previous scenario matched"
+ end
+ end
+
+ it "should create a given step if one matches" do
+ @mediator.create_story "title", "narrative"
+ @mediator.create_scenario "scenario"
+ @mediator.create_given "given"
+ run_stories
+
+ $story_mediator_spec_value.should == "given matched"
+ end
+
+ it "should create a pending step if no given step matches" do
+ @mediator.create_story "title", "narrative"
+ @mediator.create_scenario "scenario"
+ @mediator.create_given "no match"
+ mock_listener = stub_everything("listener")
+ mock_listener.should_receive(:scenario_pending).with("title", "scenario", "Unimplemented step: no match")
+ @scenario_runner.add_listener mock_listener
+ run_stories
+ end
+
+ it "should create a when step if one matches" do
+ @mediator.create_story "title", "narrative"
+ @mediator.create_scenario "scenario"
+ @mediator.create_when "when"
+ run_stories
+
+ $story_mediator_spec_value.should == "when matched"
+ end
+
+ it "should create a pending step if no when step matches" do
+ @mediator.create_story "title", "narrative"
+ @mediator.create_scenario "scenario"
+ @mediator.create_when "no match"
+ mock_listener = stub_everything("listener")
+ mock_listener.should_receive(:scenario_pending).with("title", "scenario", "Unimplemented step: no match")
+ @scenario_runner.add_listener mock_listener
+ run_stories
+ end
+
+ it "should create a then step if one matches" do
+ @mediator.create_story "title", "narrative"
+ @mediator.create_scenario "scenario"
+ @mediator.create_then "then"
+ run_stories
+
+ $story_mediator_spec_value.should == "then matched"
+ end
+
+ it "should create a pending step if no 'then' step matches" do
+ @mediator.create_story "title", "narrative"
+ @mediator.create_scenario "scenario"
+ @mediator.create_then "no match"
+ mock_listener = stub_everything("listener")
+ mock_listener.should_receive(:scenario_pending).with("title", "scenario", "Unimplemented step: no match")
+ @scenario_runner.add_listener mock_listener
+ run_stories
+ end
+
+ it "should pass options to the stories it creates" do
+ @mediator = StoryMediator.new @step_group, @runner, :foo => :bar
+ @mediator.create_story "story title", "story narrative"
+
+ run_stories
+
+ @runner.stories.first[:foo].should == :bar
+ end
+
+ end
+
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/story/runner/story_parser_spec.rb b/vendor/gems/rspec/spec/spec/story/runner/story_parser_spec.rb
new file mode 100644
index 000000000..5efc8fd18
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/runner/story_parser_spec.rb
@@ -0,0 +1,384 @@
+require File.dirname(__FILE__) + '/../story_helper'
+
+module Spec
+ module Story
+ module Runner
+
+ describe StoryParser do
+ before(:each) do
+ @story_mediator = mock("story_mediator")
+ @parser = StoryParser.new(@story_mediator)
+ end
+
+ it "should parse no lines" do
+ @parser.parse([])
+ end
+
+ it "should ignore text before the first Story: begins" do
+ @story_mediator.should_not_receive(:create_scenario)
+ @story_mediator.should_not_receive(:create_given)
+ @story_mediator.should_not_receive(:create_when)
+ @story_mediator.should_not_receive(:create_then)
+ @story_mediator.should_receive(:create_story).with("simple addition", "")
+ @parser.parse(["Here is a bunch of text", "about a calculator and all the things", "that it will do", "Story: simple addition"])
+ end
+
+ it "should create a story" do
+ @story_mediator.should_receive(:create_story).with("simple addition", "")
+ @parser.parse(["Story: simple addition"])
+ end
+
+ it "should create a story when line has leading spaces" do
+ @story_mediator.should_receive(:create_story).with("simple addition", "")
+ @parser.parse([" Story: simple addition"])
+ end
+
+ it "should add a one line narrative to the story" do
+ @story_mediator.should_receive(:create_story).with("simple addition","narrative")
+ @parser.parse(["Story: simple addition","narrative"])
+ end
+
+ it "should add a multi line narrative to the story" do
+ @story_mediator.should_receive(:create_story).with("simple addition","narrative line 1\nline 2\nline 3")
+ @parser.parse(["Story: simple addition","narrative line 1", "line 2", "line 3"])
+ end
+
+ it "should exclude blank lines from the narrative" do
+ @story_mediator.should_receive(:create_story).with("simple addition","narrative line 1\nline 2")
+ @parser.parse(["Story: simple addition","narrative line 1", "", "line 2"])
+ end
+
+ it "should exclude Scenario from the narrative" do
+ @story_mediator.should_receive(:create_story).with("simple addition","narrative line 1\nline 2")
+ @story_mediator.should_receive(:create_scenario)
+ @parser.parse(["Story: simple addition","narrative line 1", "line 2", "Scenario: add one plus one"])
+ end
+
+ end
+
+ describe StoryParser, "in Story state" do
+ before(:each) do
+ @story_mediator = mock("story_mediator")
+ @parser = StoryParser.new(@story_mediator)
+ @story_mediator.stub!(:create_story)
+ end
+
+ it "should create a second Story for Story" do
+ @story_mediator.should_receive(:create_story).with("number two","")
+ @parser.parse(["Story: s", "Story: number two"])
+ end
+
+ it "should include And in the narrative" do
+ @story_mediator.should_receive(:create_story).with("s","And foo")
+ @story_mediator.should_receive(:create_scenario).with("bar")
+ @parser.parse(["Story: s", "And foo", "Scenario: bar"])
+ end
+
+ it "should create a Scenario for Scenario" do
+ @story_mediator.should_receive(:create_scenario).with("number two")
+ @parser.parse(["Story: s", "Scenario: number two"])
+ end
+
+ it "should include Given in the narrative" do
+ @story_mediator.should_receive(:create_story).with("s","Given foo")
+ @story_mediator.should_receive(:create_scenario).with("bar")
+ @parser.parse(["Story: s", "Given foo", "Scenario: bar"])
+ end
+
+ it "should include Given: in the narrative" do
+ @story_mediator.should_receive(:create_story).with("s","Given: foo")
+ @story_mediator.should_receive(:create_scenario).with("bar")
+ @parser.parse(["Story: s", "Given: foo", "Scenario: bar"])
+ end
+
+ it "should include When in the narrative" do
+ @story_mediator.should_receive(:create_story).with("s","When foo")
+ @story_mediator.should_receive(:create_scenario).with("bar")
+ @parser.parse(["Story: s", "When foo", "Scenario: bar"])
+ end
+
+ it "should include Then in the narrative" do
+ @story_mediator.should_receive(:create_story).with("s","Then foo")
+ @story_mediator.should_receive(:create_scenario).with("bar")
+ @parser.parse(["Story: s", "Then foo", "Scenario: bar"])
+ end
+
+ it "should include other in the story" do
+ @story_mediator.should_receive(:create_story).with("s","narrative")
+ @parser.parse(["Story: s", "narrative"])
+ end
+ end
+
+ describe StoryParser, "in Scenario state" do
+ before(:each) do
+ @story_mediator = mock("story_mediator")
+ @parser = StoryParser.new(@story_mediator)
+ @story_mediator.stub!(:create_story)
+ @story_mediator.stub!(:create_scenario)
+ end
+
+ it "should create a Story for Story" do
+ @story_mediator.should_receive(:create_story).with("number two","")
+ @parser.parse(["Story: s", "Scenario: s", "Story: number two"])
+ end
+
+ it "should create a Scenario for Scenario" do
+ @story_mediator.should_receive(:create_scenario).with("number two")
+ @parser.parse(["Story: s", "Scenario: s", "Scenario: number two"])
+ end
+
+ it "should raise for And" do
+ lambda {
+ @parser.parse(["Story: s", "Scenario: s", "And second"])
+ }.should raise_error(IllegalStepError, /^Illegal attempt to create a And after a Scenario/)
+ end
+
+ it "should create a Given for Given" do
+ @story_mediator.should_receive(:create_given).with("gift")
+ @parser.parse(["Story: s", "Scenario: s", "Given gift"])
+ end
+
+ it "should create a Given for Given:" do
+ @story_mediator.should_receive(:create_given).with("gift")
+ @parser.parse(["Story: s", "Scenario: s", "Given: gift"])
+ end
+
+ it "should create a GivenScenario for GivenScenario" do
+ @story_mediator.should_receive(:create_given_scenario).with("previous")
+ @parser.parse(["Story: s", "Scenario: s", "GivenScenario previous"])
+ end
+
+ it "should create a GivenScenario for GivenScenario:" do
+ @story_mediator.should_receive(:create_given_scenario).with("previous")
+ @parser.parse(["Story: s", "Scenario: s", "GivenScenario: previous"])
+ end
+
+ it "should transition to Given state after GivenScenario" do
+ @story_mediator.stub!(:create_given_scenario)
+ @parser.parse(["Story: s", "Scenario: s", "GivenScenario previous"])
+ @parser.instance_eval{@state}.should be_an_instance_of(StoryParser::GivenState)
+ end
+
+ it "should transition to Given state after GivenScenario:" do
+ @story_mediator.stub!(:create_given_scenario)
+ @parser.parse(["Story: s", "Scenario: s", "GivenScenario: previous"])
+ @parser.instance_eval{@state}.should be_an_instance_of(StoryParser::GivenState)
+ end
+
+ it "should create a When for When" do
+ @story_mediator.should_receive(:create_when).with("ever")
+ @parser.parse(["Story: s", "Scenario: s", "When ever"])
+ end
+
+ it "should create a When for When:" do
+ @story_mediator.should_receive(:create_when).with("ever")
+ @parser.parse(["Story: s", "Scenario: s", "When: ever"])
+ end
+
+ it "should create a Then for Then" do
+ @story_mediator.should_receive(:create_then).with("and there")
+ @parser.parse(["Story: s", "Scenario: s", "Then and there"])
+ end
+
+ it "should create a Then for Then:" do
+ @story_mediator.should_receive(:create_then).with("and there")
+ @parser.parse(["Story: s", "Scenario: s", "Then: and there"])
+ end
+
+ it "should ignore other" do
+ @parser.parse(["Story: s", "Scenario: s", "this is ignored"])
+ end
+ end
+
+ describe StoryParser, "in Given state" do
+ before(:each) do
+ @story_mediator = mock("story_mediator")
+ @parser = StoryParser.new(@story_mediator)
+ @story_mediator.stub!(:create_story)
+ @story_mediator.stub!(:create_scenario)
+ @story_mediator.should_receive(:create_given).with("first")
+ end
+
+ it "should create a Story for Story" do
+ @story_mediator.should_receive(:create_story).with("number two","")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "Story: number two"])
+ end
+
+ it "should create a Scenario for Scenario" do
+ @story_mediator.should_receive(:create_scenario).with("number two")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "Scenario: number two"])
+ end
+
+ it "should create a second Given for Given" do
+ @story_mediator.should_receive(:create_given).with("second")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "Given second"])
+ end
+
+ it "should create a second Given for And" do
+ @story_mediator.should_receive(:create_given).with("second")
+ @parser.parse(["Story: s", "Scenario: s", "Given: first", "And second"])
+ end
+
+ it "should create a second Given for And:" do
+ @story_mediator.should_receive(:create_given).with("second")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "And: second"])
+ end
+
+ it "should create a When for When" do
+ @story_mediator.should_receive(:create_when).with("ever")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When ever"])
+ end
+
+ it "should create a When for When:" do
+ @story_mediator.should_receive(:create_when).with("ever")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When: ever"])
+ end
+
+ it "should create a Then for Then" do
+ @story_mediator.should_receive(:create_then).with("and there")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "Then and there"])
+ end
+
+ it "should create a Then for Then:" do
+ @story_mediator.should_receive(:create_then).with("and there")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "Then: and there"])
+ end
+
+ it "should ignore other" do
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "this is ignored"])
+ end
+ end
+
+ describe StoryParser, "in When state" do
+ before(:each) do
+ @story_mediator = mock("story_mediator")
+ @parser = StoryParser.new(@story_mediator)
+ @story_mediator.stub!(:create_story)
+ @story_mediator.stub!(:create_scenario)
+ @story_mediator.should_receive(:create_given).with("first")
+ @story_mediator.should_receive(:create_when).with("else")
+ end
+
+ it "should create a Story for Story" do
+ @story_mediator.should_receive(:create_story).with("number two","")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When: else", "Story: number two"])
+ end
+
+ it "should create a Scenario for Scenario" do
+ @story_mediator.should_receive(:create_scenario).with("number two")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Scenario: number two"])
+ end
+
+ it "should create Given for Given" do
+ @story_mediator.should_receive(:create_given).with("second")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Given second"])
+ end
+
+ it "should create Given for Given:" do
+ @story_mediator.should_receive(:create_given).with("second")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Given: second"])
+ end
+
+ it "should create a second When for When" do
+ @story_mediator.should_receive(:create_when).with("ever")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "When ever"])
+ end
+
+ it "should create a second When for When:" do
+ @story_mediator.should_receive(:create_when).with("ever")
+ @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "When: ever"])
+ end
+
+ it "should create a second When for And" do
+ @story_mediator.should_receive(:create_when).with("ever")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "And ever"])
+ end
+
+ it "should create a second When for And:" do
+ @story_mediator.should_receive(:create_when).with("ever")
+ @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "And: ever"])
+ end
+
+ it "should create a Then for Then" do
+ @story_mediator.should_receive(:create_then).with("and there")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then and there"])
+ end
+
+ it "should create a Then for Then:" do
+ @story_mediator.should_receive(:create_then).with("and there")
+ @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "Then: and there"])
+ end
+
+ it "should ignore other" do
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "this is ignored"])
+ end
+ end
+
+ describe StoryParser, "in Then state" do
+ before(:each) do
+ @story_mediator = mock("story_mediator")
+ @parser = StoryParser.new(@story_mediator)
+ @story_mediator.stub!(:create_story)
+ @story_mediator.stub!(:create_scenario)
+ @story_mediator.should_receive(:create_given).with("first")
+ @story_mediator.should_receive(:create_when).with("else")
+ @story_mediator.should_receive(:create_then).with("what")
+ end
+
+ it "should create a Story for Story" do
+ @story_mediator.should_receive(:create_story).with("number two","")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "Story: number two"])
+ end
+
+ it "should create a Scenario for Scenario" do
+ @story_mediator.should_receive(:create_scenario).with("number two")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "Scenario: number two"])
+ end
+
+ it "should create Given for Given" do
+ @story_mediator.should_receive(:create_given).with("second")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "Given second"])
+ end
+
+ it "should create Given for Given:" do
+ @story_mediator.should_receive(:create_given).with("second")
+ @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "Then: what", "Given: second"])
+ end
+
+ it "should create When for When" do
+ @story_mediator.should_receive(:create_when).with("ever")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "When ever"])
+ end
+
+ it "should create When for When:" do
+ @story_mediator.should_receive(:create_when).with("ever")
+ @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "Then: what", "When: ever"])
+ end
+
+ it "should create a Then for Then" do
+ @story_mediator.should_receive(:create_then).with("and there")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "Then and there"])
+ end
+
+ it "should create a Then for Then:" do
+ @story_mediator.should_receive(:create_then).with("and there")
+ @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "Then: what", "Then: and there"])
+ end
+
+ it "should create a second Then for And" do
+ @story_mediator.should_receive(:create_then).with("ever")
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "And ever"])
+ end
+
+ it "should create a second Then for And:" do
+ @story_mediator.should_receive(:create_then).with("ever")
+ @parser.parse(["Story: s", "Scenario: s", "Given: first", "When: else", "Then: what", "And: ever"])
+ end
+
+ it "should ignore other" do
+ @parser.parse(["Story: s", "Scenario: s", "Given first", "When else", "Then what", "this is ignored"])
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/spec/spec/story/runner/story_runner_spec.rb b/vendor/gems/rspec/spec/spec/story/runner/story_runner_spec.rb
new file mode 100644
index 000000000..0fc46405a
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/runner/story_runner_spec.rb
@@ -0,0 +1,256 @@
+require File.dirname(__FILE__) + '/../story_helper'
+
+module Spec
+ module Story
+ module Runner
+ describe StoryRunner do
+ it 'should collect all the stories' do
+ # given
+ story_runner = StoryRunner.new(stub('scenario_runner'))
+
+ # when
+ story_runner.Story 'title1', 'narrative1' do end
+ story_runner.Story 'title2', 'narrative2' do end
+ stories = story_runner.stories
+
+ # then
+ story_runner.should have(2).stories
+ stories.first.title.should == 'title1'
+ stories.first.narrative.should == 'narrative1'
+ stories.last.title.should == 'title2'
+ stories.last.narrative.should == 'narrative2'
+ end
+
+ it 'should gather all the scenarios in the stories' do
+ # given
+ story_runner = StoryRunner.new(stub('scenario_runner'))
+
+ # when
+ story_runner.Story "story1", "narrative1" do
+ Scenario "scenario1" do end
+ Scenario "scenario2" do end
+ end
+ story_runner.Story "story2", "narrative2" do
+ Scenario "scenario3" do end
+ end
+ scenarios = story_runner.scenarios
+
+ # then
+ story_runner.should have(3).scenarios
+ scenarios[0].name.should == 'scenario1'
+ scenarios[1].name.should == 'scenario2'
+ scenarios[2].name.should == 'scenario3'
+ end
+
+ # captures worlds passed into a ScenarioRunner
+ class ScenarioWorldCatcher
+ attr_accessor :worlds
+ def run(scenario, world)
+ (@worlds ||= []) << world
+ end
+ end
+
+ it 'should run each scenario in a separate object' do
+ # given
+ scenario_world_catcher = ScenarioWorldCatcher.new
+ story_runner = StoryRunner.new(scenario_world_catcher)
+ story_runner.Story 'story', 'narrative' do
+ Scenario 'scenario1' do end
+ Scenario 'scenario2' do end
+ end
+
+ # when
+ story_runner.run_stories
+
+ # then
+ worlds = scenario_world_catcher.worlds
+ scenario_world_catcher.should have(2).worlds
+ worlds[0].should_not == worlds[1]
+ end
+
+ it 'should use the provided world creator to create worlds' do
+ # given
+ stub_scenario_runner = stub_everything
+ mock_world_creator = mock('world creator')
+ story_runner = StoryRunner.new(stub_scenario_runner, mock_world_creator)
+ story_runner.Story 'story', 'narrative' do
+ Scenario 'scenario1' do end
+ Scenario 'scenario2' do end
+ end
+
+ # expect
+ mock_world_creator.should_receive(:create).twice
+
+ # when
+ story_runner.run_stories
+
+ # then
+ end
+
+ it 'should notify listeners of the scenario count when the run starts' do
+ # given
+ story_runner = StoryRunner.new(stub_everything)
+ mock_listener1 = stub_everything('listener1')
+ mock_listener2 = stub_everything('listener2')
+ story_runner.add_listener(mock_listener1)
+ story_runner.add_listener(mock_listener2)
+
+ story_runner.Story 'story1', 'narrative1' do
+ Scenario 'scenario1' do end
+ end
+ story_runner.Story 'story2', 'narrative2' do
+ Scenario 'scenario2' do end
+ Scenario 'scenario3' do end
+ end
+
+ # expect
+ mock_listener1.should_receive(:run_started).with(3)
+ mock_listener2.should_receive(:run_started).with(3)
+
+ # when
+ story_runner.run_stories
+
+ # then
+ end
+
+ it 'should notify listeners when a story starts' do
+ # given
+ story_runner = StoryRunner.new(stub_everything)
+ mock_listener1 = stub_everything('listener1')
+ mock_listener2 = stub_everything('listener2')
+ story_runner.add_listener(mock_listener1)
+ story_runner.add_listener(mock_listener2)
+
+ story_runner.Story 'story1', 'narrative1' do
+ Scenario 'scenario1' do end
+ end
+ story_runner.Story 'story2', 'narrative2' do
+ Scenario 'scenario2' do end
+ Scenario 'scenario3' do end
+ end
+
+ # expect
+ mock_listener1.should_receive(:story_started).with('story1', 'narrative1')
+ mock_listener1.should_receive(:story_ended).with('story1', 'narrative1')
+ mock_listener2.should_receive(:story_started).with('story2', 'narrative2')
+ mock_listener2.should_receive(:story_ended).with('story2', 'narrative2')
+
+ # when
+ story_runner.run_stories
+
+ # then
+ end
+
+ it 'should notify listeners when the run ends' do
+ # given
+ story_runner = StoryRunner.new(stub_everything)
+ mock_listener1 = stub_everything('listener1')
+ mock_listener2 = stub_everything('listener2')
+ story_runner.add_listener mock_listener1
+ story_runner.add_listener mock_listener2
+ story_runner.Story 'story1', 'narrative1' do
+ Scenario 'scenario1' do end
+ end
+
+ # expect
+ mock_listener1.should_receive(:run_ended)
+ mock_listener2.should_receive(:run_ended)
+
+ # when
+ story_runner.run_stories
+
+ # then
+ end
+
+ it 'should run a story in an instance of a specified class' do
+ # given
+ scenario_world_catcher = ScenarioWorldCatcher.new
+ story_runner = StoryRunner.new(scenario_world_catcher)
+ story_runner.Story 'title', 'narrative', :type => String do
+ Scenario 'scenario' do end
+ end
+
+ # when
+ story_runner.run_stories
+
+ # then
+ scenario_world_catcher.worlds[0].should be_kind_of(String)
+ scenario_world_catcher.worlds[0].should be_kind_of(World)
+ end
+
+ it 'should pass initialization params through to the constructed instance' do
+ # given
+ scenario_world_catcher = ScenarioWorldCatcher.new
+ story_runner = StoryRunner.new(scenario_world_catcher)
+ story_runner.Story 'title', 'narrative', :type => Array, :args => [3] do
+ Scenario 'scenario' do end
+ end
+
+ # when
+ story_runner.run_stories
+
+ # then
+ scenario_world_catcher.worlds[0].should be_kind_of(Array)
+ scenario_world_catcher.worlds[0].size.should == 3
+ end
+
+ it 'should find a scenario in the current story by name' do
+ # given
+ story_runner = StoryRunner.new(ScenarioRunner.new)
+ $scenario = nil
+
+ story_runner.Story 'title', 'narrative' do
+ Scenario 'first scenario' do
+ end
+ Scenario 'second scenario' do
+ $scenario = StoryRunner.scenario_from_current_story 'first scenario'
+ end
+ end
+
+ # when
+ story_runner.run_stories
+
+ # then
+ $scenario.name.should == 'first scenario'
+ end
+
+ it "should clean the steps between stories" do
+ #given
+ story_runner = StoryRunner.new(ScenarioRunner.new)
+ result = mock 'result'
+
+ step1 = Step.new('step') do
+ result.one
+ end
+ steps1 = StepGroup.new
+ steps1.add :when, step1
+
+ story_runner.Story 'title', 'narrative', :steps => steps1 do
+ Scenario 'first scenario' do
+ When 'step'
+ end
+ end
+
+ step2 = Step.new('step') do
+ result.two
+ end
+ steps2 = StepGroup.new
+ steps2.add :when, step2
+
+ story_runner.Story 'title2', 'narrative', :steps => steps2 do
+ Scenario 'second scenario' do
+ When 'step'
+ end
+ end
+
+ #then
+ result.should_receive(:one)
+ result.should_receive(:two)
+
+ #when
+ story_runner.run_stories
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/story/runner_spec.rb b/vendor/gems/rspec/spec/spec/story/runner_spec.rb
new file mode 100644
index 000000000..81e852640
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/runner_spec.rb
@@ -0,0 +1,106 @@
+require File.dirname(__FILE__) + '/story_helper'
+
+module Spec
+ module Story
+ describe Runner, "module" do
+ def dev_null
+ io = StringIO.new
+ def io.write(str)
+ str.to_s.size
+ end
+ return io
+ end
+
+ before :each do
+ Kernel.stub!(:at_exit)
+ @stdout, $stdout = $stdout, dev_null
+ @argv = Array.new(ARGV)
+ @runner_module = Runner.dup
+ @world_creator = World.dup
+ @runner_module.module_eval { @run_options = @story_runner = @scenario_runner = @world_creator = nil }
+ end
+
+ after :each do
+ $stdout = @stdout
+ ARGV.replace @argv
+ @runner_module.module_eval { @run_options = @story_runner = @scenario_runner = @world_creator = nil }
+ end
+
+ it 'should wire up a singleton StoryRunner' do
+ @runner_module.story_runner.should_not be_nil
+ end
+
+ it 'should set its options based on ARGV' do
+ # given
+ ARGV << '--dry-run'
+
+ # when
+ options = @runner_module.run_options
+
+ # then
+ options.dry_run.should be_true
+ end
+
+ it 'should add a reporter to the runner classes' do
+ # given
+ story_runner = mock('story runner', :null_object => true)
+ scenario_runner = mock('scenario runner', :null_object => true)
+ world_creator = mock('world', :null_object => true)
+
+ @runner_module::class_eval { @world_creator = world_creator }
+ @runner_module::StoryRunner.stub!(:new).and_return(story_runner)
+ @runner_module::ScenarioRunner.stub!(:new).and_return(scenario_runner)
+
+ # expect
+ world_creator.should_receive(:add_listener).with(an_instance_of(Spec::Runner::Formatter::Story::PlainTextFormatter))
+ story_runner.should_receive(:add_listener).with(an_instance_of(Spec::Runner::Formatter::Story::PlainTextFormatter))
+ scenario_runner.should_receive(:add_listener).with(an_instance_of(Spec::Runner::Formatter::Story::PlainTextFormatter))
+
+ # when
+ @runner_module.story_runner
+ end
+
+ it 'should add a documenter to the runner classes if one is specified' do
+ # given
+ ARGV << "--format" << "html"
+ story_runner = mock('story runner', :null_object => true)
+ scenario_runner = mock('scenario runner', :null_object => true)
+ world_creator = mock('world', :null_object => true)
+
+ @runner_module::class_eval { @world_creator = world_creator }
+ @runner_module::StoryRunner.stub!(:new).and_return(story_runner)
+ @runner_module::ScenarioRunner.stub!(:new).and_return(scenario_runner)
+
+ # expect
+ world_creator.should_receive(:add_listener).with(an_instance_of(Spec::Runner::Formatter::Story::HtmlFormatter))
+ story_runner.should_receive(:add_listener).with(an_instance_of(Spec::Runner::Formatter::Story::HtmlFormatter))
+ scenario_runner.should_receive(:add_listener).with(an_instance_of(Spec::Runner::Formatter::Story::HtmlFormatter))
+
+ # when
+ @runner_module.story_runner
+ end
+
+ it 'should add any registered listener to the runner classes' do
+ # given
+ ARGV << "--format" << "html"
+ story_runner = mock('story runner', :null_object => true)
+ scenario_runner = mock('scenario runner', :null_object => true)
+ world_creator = mock('world', :null_object => true)
+
+ @runner_module::class_eval { @world_creator = world_creator }
+ @runner_module::StoryRunner.stub!(:new).and_return(story_runner)
+ @runner_module::ScenarioRunner.stub!(:new).and_return(scenario_runner)
+
+ listener = Object.new
+
+ # expect
+ world_creator.should_receive(:add_listener).with(listener)
+ story_runner.should_receive(:add_listener).with(listener)
+ scenario_runner.should_receive(:add_listener).with(listener)
+
+ # when
+ @runner_module.register_listener listener
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/story/scenario_spec.rb b/vendor/gems/rspec/spec/spec/story/scenario_spec.rb
new file mode 100644
index 000000000..0cf7aff30
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/scenario_spec.rb
@@ -0,0 +1,20 @@
+require File.dirname(__FILE__) + '/story_helper'
+
+module Spec
+ module Story
+ describe Scenario do
+ it 'should not raise an error if no body is supplied' do
+ # given
+ story = StoryBuilder.new.to_story
+
+ # when
+ error = exception_from do
+ Scenario.new story, 'name'
+ end
+
+ # then
+ error.should be_nil
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/story/step_group_spec.rb b/vendor/gems/rspec/spec/spec/story/step_group_spec.rb
new file mode 100644
index 000000000..dd28bfa26
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/step_group_spec.rb
@@ -0,0 +1,157 @@
+require File.dirname(__FILE__) + '/story_helper'
+
+module Spec
+ module Story
+ describe StepGroup do
+ before(:each) do
+ @step_group = StepGroup.new
+ end
+
+ it "should not find a matcher if empty" do
+ @step_group.find(:given, "this and that").should be_nil
+ end
+
+ it "should create a given_scenario matcher" do
+ step = @step_group.given_scenario("this and that") {}
+ @step_group.find(:given_scenario, "this and that").should_not be_nil
+ @step_group.find(:given_scenario, "this and that").should equal(step)
+ end
+
+ it "should create a given matcher" do
+ step = @step_group.given("this and that") {}
+ @step_group.find(:given, "this and that").should equal(step)
+ end
+
+ it "should create a when matcher" do
+ step = @step_group.when("this and that") {}
+ @step_group.find(:when, "this and that").should equal(step)
+ end
+
+ it "should create a them matcher" do
+ step = @step_group.then("this and that") {}
+ @step_group.find(:then, "this and that").should equal(step)
+ end
+
+ it "should add a matcher object" do
+ step = Step.new("this and that") {}
+ @step_group.add(:given, step)
+ @step_group.find(:given, "this and that").should equal(step)
+ end
+
+ it "should add it matchers to another StepGroup (with one given)" do
+ source = StepGroup.new
+ target = StepGroup.new
+ step = source.given("this and that") {}
+ source.add_to target
+ target.find(:given, "this and that").should equal(step)
+ end
+
+ it "should add it matchers to another StepGroup (with some of each type)" do
+ source = StepGroup.new
+ target = StepGroup.new
+ given_scenario = source.given_scenario("1") {}
+ given = source.given("1") {}
+ when1 = source.when("1") {}
+ when2 = source.when("2") {}
+ then1 = source.then("1") {}
+ then2 = source.then("2") {}
+ then3 = source.then("3") {}
+ source.add_to target
+ target.find(:given_scenario, "1").should equal(given_scenario)
+ target.find(:given, "1").should equal(given)
+ target.find(:when, "1").should equal(when1)
+ target.find(:when, "2").should equal(when2)
+ target.find(:then, "1").should equal(then1)
+ target.find(:then, "2").should equal(then2)
+ target.find(:then, "3").should equal(then3)
+ end
+
+ it "should append another collection" do
+ matchers_to_append = StepGroup.new
+ step = matchers_to_append.given("this and that") {}
+ @step_group << matchers_to_append
+ @step_group.find(:given, "this and that").should equal(step)
+ end
+
+ it "should append several other collections" do
+ matchers_to_append = StepGroup.new
+ more_matchers_to_append = StepGroup.new
+ first_matcher = matchers_to_append.given("this and that") {}
+ second_matcher = more_matchers_to_append.given("and the other") {}
+ @step_group << matchers_to_append
+ @step_group << more_matchers_to_append
+ @step_group.find(:given, "this and that").should equal(first_matcher)
+ @step_group.find(:given, "and the other").should equal(second_matcher)
+ end
+
+ it "should yield itself on initialization" do
+ begin
+ $step_group_spec_step = nil
+ matchers = StepGroup.new do |matchers|
+ $step_group_spec_step = matchers.given("foo") {}
+ end
+ $step_group_spec_step.matches?("foo").should be_true
+ ensure
+ $step_group_spec_step = nil
+ end
+ end
+
+ it "should support defaults" do
+ class StepGroupSubclass < StepGroup
+ steps do |add|
+ add.given("foo") {}
+ end
+ end
+ StepGroupSubclass.new.find(:given, "foo").should_not be_nil
+ end
+
+ it "should create a Given" do
+ sub = Class.new(StepGroup).new
+ step = sub.Given("foo") {}
+ sub.find(:given, "foo").should == step
+ end
+
+ it "should create a When" do
+ sub = Class.new(StepGroup).new
+ step = sub.When("foo") {}
+ sub.find(:when, "foo").should == step
+ end
+
+ it "should create a Then" do
+ sub = Class.new(StepGroup).new
+ step = sub.Then("foo") {}
+ sub.find(:then, "foo").should == step
+ end
+
+ it "should create steps in a block" do
+ sub = Class.new(StepGroup).new do
+ Given("a given") {}
+ When("a when") {}
+ Then("a then") {}
+ end
+ sub.find(:given, "a given").should_not be_nil
+ sub.find(:when, "a when").should_not be_nil
+ sub.find(:then, "a then").should_not be_nil
+ end
+
+ it "should clear itself" do
+ step = @step_group.given("this and that") {}
+ @step_group.clear
+ @step_group.find(:given, "this and that").should be_nil
+ end
+
+ it "should tell you when it is empty" do
+ @step_group.should be_empty
+ end
+
+ it "should tell you when it is not empty" do
+ @step_group.given("this and that") {}
+ @step_group.should_not be_empty
+ end
+
+ it "should handle << nil" do
+ @step_group << nil
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/story/step_mother_spec.rb b/vendor/gems/rspec/spec/spec/story/step_mother_spec.rb
new file mode 100644
index 000000000..64efd7a6a
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/step_mother_spec.rb
@@ -0,0 +1,72 @@
+require File.dirname(__FILE__) + '/story_helper'
+
+module Spec
+ module Story
+ describe StepMother do
+ it 'should store a step by name and type' do
+ # given
+ step_mother = StepMother.new
+ step = Step.new("a given", &lambda {})
+ step_mother.store(:given, step)
+
+ # when
+ found = step_mother.find(:given, "a given")
+
+ # then
+ found.should == step
+ end
+
+ it 'should NOT raise an error if a step is missing' do
+ # given
+ step_mother = StepMother.new
+
+ # then
+ lambda do
+ # when
+ step_mother.find(:given, "doesn't exist")
+ end.should_not raise_error
+ end
+
+ it "should create a default step which raises a pending error" do
+ # given
+ step_mother = StepMother.new
+
+ # when
+ step = step_mother.find(:given, "doesn't exist")
+
+ # then
+ step.should be_an_instance_of(Step)
+
+ lambda do
+ step.perform(Object.new, "doesn't exist")
+ end.should raise_error(Spec::Example::ExamplePendingError, /Unimplemented/)
+ end
+
+ it 'should clear itself' do
+ # given
+ step_mother = StepMother.new
+ step = Step.new("a given") do end
+ step_mother.store(:given, step)
+
+ # when
+ step_mother.clear
+
+ # then
+ step_mother.should be_empty
+ end
+
+ it "should use assigned steps" do
+ step_mother = StepMother.new
+
+ step = Step.new('step') {}
+ step_group = StepGroup.new
+ step_group.add(:given, step)
+
+ step_mother.use(step_group)
+
+ step_mother.find(:given, "step").should equal(step)
+ end
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/story/step_spec.rb b/vendor/gems/rspec/spec/spec/story/step_spec.rb
new file mode 100644
index 000000000..0b6e515e9
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/step_spec.rb
@@ -0,0 +1,200 @@
+require File.dirname(__FILE__) + '/story_helper'
+
+module Spec
+ module Story
+ describe Step, "matching" do
+ it "should match a text string" do
+ step = Step.new("this text") {}
+ step.matches?("this text").should be_true
+ end
+
+ it "should not match a text string that does not start the same" do
+ step = Step.new("this text") {}
+ step.matches?("Xthis text").should be_false
+ end
+
+ it "should not match a text string that does not end the same" do
+ step = Step.new("this text") {}
+ step.matches?("this textX").should be_false
+ end
+
+ it "should match a text string with a param" do
+ step = Step.new("this $param text") {}
+ step.matches?("this anything text").should be_true
+ end
+
+ it "should not be greedy" do
+ step = Step.new("enter $value for $key") {}
+ step.parse_args("enter 3 for keys for a piano").should == ['3','keys for a piano']
+ end
+
+ it "should match a text string with 3 params" do
+ step = Step.new("1 $one 2 $two 3 $three 4") {}
+ step.matches?("1 a 2 b 3 c 4").should be_true
+ end
+
+ it "should match a text string with a param at the beginning" do
+ step = Step.new("$one 2 3") {}
+ step.matches?("a 2 3").should be_true
+ end
+
+ it "should match a text string with a param at the end" do
+ step = Step.new("1 2 $three") {}
+ step.matches?("1 2 c").should be_true
+ end
+
+ it "should not match a different string" do
+ step = Step.new("this text") {}
+ step.matches?("other text").should be_false
+ end
+
+ it "should match a regexp" do
+ step = Step.new(/this text/) {}
+ step.matches?("this text").should be_true
+ end
+
+ it "should match a regexp with a match group" do
+ step = Step.new(/this (.*) text/) {}
+ step.matches?("this anything text").should be_true
+ end
+
+ it "should match a regexp with a named variable" do
+ step = Step.new(/this $variable text/) {}
+ step.matches?("this anything text").should be_true
+ end
+
+ it "should not match a non matching regexp" do
+ step = Step.new(/this (.*) text/) {}
+ step.matches?("other anything text").should be_false
+ end
+
+ it "should not match a non matching regexp with a named variable" do
+ step = Step.new(/this $variable text/) {}
+ step.matches?("other anything text").should be_false
+ end
+
+ it "should not get bogged down by parens in strings" do
+ step = Step.new("before () after") {}
+ step.matches?("before () after").should be_true
+ end
+
+ it "should match any option of an alteration" do
+ step = Step.new(/(he|she) is cool/) {}
+ step.matches?("he is cool").should be_true
+ step.matches?("she is cool").should be_true
+ end
+
+ it "should match alteration as well as a variable" do
+ step = Step.new(/(he|she) is (.*)/) {}
+ step.matches?("he is cool").should be_true
+ step.parse_args("he is cool").should == ['he', 'cool']
+ end
+
+ it "should match alteration as well as a named variable" do
+ step = Step.new(/(he|she) is $adjective/) {}
+ step.matches?("he is cool").should be_true
+ step.parse_args("he is cool").should == ['he', 'cool']
+ end
+
+ it "should match alteration as well as a anonymous and named variable" do
+ step = Step.new(/(he|she) is (.*?) $adjective/) {}
+ step.matches?("he is very cool").should be_true
+ step.parse_args("he is very cool").should == ['he', 'very', 'cool']
+ end
+
+ end
+
+ describe Step do
+ it "should make complain with no block" do
+ lambda {
+ step = Step.new("foo")
+ }.should raise_error
+ end
+
+ it "should perform itself on an object" do
+ # given
+ $instance = nil
+ step = Step.new 'step' do
+ $instance = self
+ end
+ instance = Object.new
+
+ # when
+ step.perform(instance, "step")
+
+ # then
+ $instance.should == instance
+ end
+
+ it "should perform itself with one parameter with match expression" do
+ # given
+ $result = nil
+ step = Step.new 'an account with $count dollars' do |count|
+ $result = count
+ end
+ instance = Object.new
+
+ # when
+ args = step.parse_args("an account with 3 dollars")
+ step.perform(instance, *args)
+
+ # then
+ $result.should == "3"
+ end
+
+ it "should perform itself with one parameter without a match expression" do
+ # given
+ $result = nil
+ step = Step.new 'an account with a balance of' do |amount|
+ $result = amount
+ end
+ instance = Object.new
+
+ # when
+ step.perform(instance, 20)
+
+ # then
+ $result.should == 20
+ end
+
+ it "should perform itself with 2 parameters" do
+ # given
+ $account_type = nil
+ $amount = nil
+ step = Step.new 'a $account_type account with $amount dollars' do |account_type, amount|
+ $account_type = account_type
+ $amount = amount
+ end
+ instance = Object.new
+
+ # when
+ args = step.parse_args("a savings account with 3 dollars")
+ step.perform(instance, *args)
+
+ # then
+ $account_type.should == "savings"
+ $amount.should == "3"
+ end
+
+ it "should perform itself when defined with a regexp with 2 parameters" do
+ # given
+ $pronoun = nil
+ $adjective = nil
+ step = Step.new /(he|she) is (.*)/ do |pronoun, adjective|
+ $pronoun = pronoun
+ $adjective = adjective
+ end
+ instance = Object.new
+
+ # when
+ args = step.parse_args("he is cool")
+ step.perform(instance, *args)
+
+ # then
+ $pronoun.should == "he"
+ $adjective.should == "cool"
+ end
+
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/story/story_helper.rb b/vendor/gems/rspec/spec/spec/story/story_helper.rb
new file mode 100644
index 000000000..bb906f255
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/story_helper.rb
@@ -0,0 +1,2 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+require File.dirname(__FILE__) + '/builders'
diff --git a/vendor/gems/rspec/spec/spec/story/story_spec.rb b/vendor/gems/rspec/spec/spec/story/story_spec.rb
new file mode 100644
index 000000000..21257e9a7
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/story_spec.rb
@@ -0,0 +1,86 @@
+require File.dirname(__FILE__) + '/story_helper'
+
+module Spec
+ module Story
+ describe Story do
+ it 'should run itself in a given object' do
+ # given
+ $instance = nil
+ story = Story.new 'title', 'narrative' do
+ $instance = self
+ end
+ object = Object.new
+
+ # when
+ story.run_in(object)
+
+ # then
+ $instance.should be(object)
+ end
+
+ it 'should not raise an error if no block is supplied' do
+ # when
+ error = exception_from do
+ Story.new 'title', 'narrative'
+ end
+
+ # then
+ error.should be_nil
+ end
+
+ it "should raise when error raised running in another object" do
+ #given
+ story = Story.new 'title', 'narrative' do
+ raise "this is raised in the story"
+ end
+ object = Object.new
+
+ # when/then
+ lambda do
+ story.run_in(object)
+ end.should raise_error
+ end
+
+ it "should use the steps it is told to using a StepGroup" do
+ story = Story.new("title", "narrative", :steps => steps = StepGroup.new) do end
+ assignee = mock("assignee")
+ assignee.should_receive(:use).with(steps)
+ story.assign_steps_to(assignee)
+ end
+
+ it "should use the steps it is told to using a key" do
+ begin
+ orig_rspec_story_steps = $rspec_story_steps
+ $rspec_story_steps = StepGroupHash.new
+ $rspec_story_steps[:foo] = steps = Object.new
+
+ story = Story.new("title", "narrative", :steps_for => :foo) do end
+ assignee = mock("assignee")
+
+ assignee.should_receive(:use).with(steps)
+ story.assign_steps_to(assignee)
+ ensure
+ $rspec_story_steps = orig_rspec_story_steps
+ end
+ end
+
+ it "should use the steps it is told to using multiple keys" do
+ begin
+ orig_rspec_story_steps = $rspec_story_steps
+ $rspec_story_steps = StepGroupHash.new
+ $rspec_story_steps[:foo] = foo_steps = Object.new
+ $rspec_story_steps[:bar] = bar_steps = Object.new
+
+ story = Story.new("title", "narrative", :steps_for => [:foo, :bar]) do end
+ assignee = mock("assignee")
+
+ assignee.should_receive(:use).with(foo_steps)
+ assignee.should_receive(:use).with(bar_steps)
+ story.assign_steps_to(assignee)
+ ensure
+ $rspec_story_steps = orig_rspec_story_steps
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/story/world_spec.rb b/vendor/gems/rspec/spec/spec/story/world_spec.rb
new file mode 100644
index 000000000..f5113dc42
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/story/world_spec.rb
@@ -0,0 +1,423 @@
+require File.dirname(__FILE__) + '/story_helper'
+
+require 'spec/story'
+
+module Spec
+ module Story
+ describe World do
+ before :each do
+ World.listeners.clear
+ end
+
+ after :each do
+ World.listeners.clear
+ World.step_mother.clear
+ end
+
+ it 'should create an object that mixes in a World' do
+ # when
+ obj = World::create
+
+ # then
+ obj.should be_kind_of(World)
+ end
+
+ it 'should create a World from any object type' do
+ # when
+ obj = World::create String
+
+ # then
+ obj.should be_kind_of(String)
+ obj.should be_kind_of(World)
+ end
+
+ it 'should pass arguments to #new when creating an object of a specified type that mixes in a world' do
+ # given
+ Thing = Struct.new(:name, :age)
+
+ # when
+ obj = World::create Thing, "David", "I'm not telling"
+
+ # then
+ obj.should be_an_instance_of(Thing)
+ obj.name.should == "David"
+ obj.age.should == "I'm not telling"
+ obj.should be_kind_of(World)
+ end
+
+ def ensure_world_executes_step(&block)
+ # given
+ obj = World::create
+ $step_ran = false
+
+ # when
+ obj.instance_eval(&block)
+
+ # then
+ $step_ran.should be_true
+ end
+
+ it 'should execute a Given, When or Then step' do
+ ensure_world_executes_step do
+ Given 'a given' do
+ $step_ran = true
+ end
+ end
+
+ ensure_world_executes_step do
+ When 'an event' do
+ $step_ran = true
+ end
+ end
+
+ ensure_world_executes_step do
+ Then 'an outcome' do
+ $step_ran = true
+ end
+ end
+ end
+
+ it 'should interpret Given... And... as multiple givens' do
+ # given
+ world = World.create
+ $steps = []
+
+ # when
+ world.instance_eval do
+ Given 'step 1' do
+ $steps << 1
+ end
+ And 'step 2' do
+ $steps << 2
+ end
+ end
+
+ # then
+ $steps.should == [1,2]
+ World.step_mother.find(:given, 'step 1').should_not be_nil
+ World.step_mother.find(:given, 'step 2').should_not be_nil
+ end
+
+ it 'should interpret When... And... as multiple events' do
+ # given
+ world = World.create
+ $steps = []
+
+ # when
+ world.instance_eval do
+ When 'step 1' do
+ $steps << 1
+ end
+ And 'step 2' do
+ $steps << 2
+ end
+ end
+
+ # then
+ $steps.should == [1,2]
+ World.step_mother.find(:when, 'step 1').should_not be_nil
+ World.step_mother.find(:when, 'step 2').should_not be_nil
+ end
+
+ it 'should interpret Then... And... as multiple outcomes' do
+ # given
+ world = World.create
+ $steps = []
+
+ # when
+ world.instance_eval do
+ Then 'step 1' do
+ $steps << 1
+ end
+ And 'step 2' do
+ $steps << 2
+ end
+ end
+
+ # then
+ $steps.should == [1,2]
+ World.step_mother.find(:then, 'step 1').should_not be_nil
+ World.step_mother.find(:then, 'step 2').should_not be_nil
+ end
+
+ it 'should reuse a given across scenarios' do
+ # given
+ $num_invoked = 0
+ a_world = World::create
+ a_world.instance_eval do
+ Given 'a given' do
+ $num_invoked += 1
+ end
+ end
+ another_world = World::create
+
+ # when
+ another_world.instance_eval do
+ Given 'a given' # without a body
+ end
+
+ # then
+ $num_invoked.should == 2
+ end
+
+ it 'should reuse an event across scenarios' do
+ # given
+ $num_invoked = 0
+ a_world = World::create
+ a_world.instance_eval do
+ When 'an event' do
+ $num_invoked += 1
+ end
+ end
+
+ another_world = World::create
+
+ # when
+ another_world.instance_eval do
+ When 'an event' # without a body
+ end
+
+ # then
+ $num_invoked.should == 2
+ end
+
+ it 'should reuse an outcome across scenarios' do
+ # given
+ $num_invoked = 0
+ a_world = World::create
+ a_world.instance_eval do
+ Then 'an outcome' do
+ $num_invoked += 1
+ end
+ end
+
+ another_world = World::create
+
+ # when
+ another_world.instance_eval do
+ Then 'an outcome' # without a body
+ end
+
+ # then
+ $num_invoked.should == 2
+ end
+
+ it 'should preserve instance variables between steps within a scenario' do
+ # given
+ world = World::create
+ $first = nil
+ $second = nil
+
+ # when
+ world.instance_eval do
+ Given 'given' do
+ @first = 'first'
+ end
+ When 'event' do
+ @second = @first # from given
+ end
+ Then 'outcome' do
+ $first = @first # from given
+ $second = @second # from event
+ end
+ end
+
+ # then
+ $first.should == 'first'
+ $second.should == 'first'
+ end
+
+ it 'should invoke a reused step in the new object instance' do
+ # given
+ $instances = []
+ $debug = true
+ world1 = World.create
+ world1.instance_eval do
+ Given 'a given' do
+ $instances << self.__id__
+ end
+ end
+ world2 = World.create
+
+ # when
+ world2.instance_eval do
+ Given 'a given' # reused
+ Then 'an outcome' do
+ $instances << __id__
+ end
+ end
+ $debug = false
+ # then
+ $instances.should == [ world1.__id__, world2.__id__, world2.__id__ ]
+ end
+
+ def ensure_world_collects_error(expected_error, &block)
+ # given
+ world = World.create
+ # $error = nil
+
+ # when
+ world.start_collecting_errors
+ world.instance_eval(&block)
+
+ # then
+ world.should have(1).errors
+ world.errors[0].should be_kind_of(expected_error)
+ end
+
+ it 'should collect a failure from a Given step' do
+ ensure_world_collects_error RuntimeError do
+ Given 'a given' do
+ raise RuntimeError, "oops"
+ end
+ end
+ end
+
+ it 'should collect a failure from a When step' do
+ ensure_world_collects_error RuntimeError do
+ When 'an event' do
+ raise RuntimeError, "oops"
+ end
+ end
+ end
+
+ it 'should collect a failure from a Then step' do
+ ensure_world_collects_error RuntimeError do
+ Then 'an outcome' do
+ raise RuntimeError, "oops"
+ end
+ end
+ end
+
+ it 'should inform listeners when it runs a Given, When or Then step' do
+ # given
+ world = World.create
+ mock_listener1 = mock('listener1')
+ mock_listener2 = mock('listener2')
+ World.add_listener(mock_listener1)
+ World.add_listener(mock_listener2)
+
+ # expect
+ mock_listener1.should_receive(:step_upcoming).with(:given, 'a context')
+ mock_listener1.should_receive(:step_succeeded).with(:given, 'a context')
+ mock_listener1.should_receive(:step_upcoming).with(:when, 'an event')
+ mock_listener1.should_receive(:step_succeeded).with(:when, 'an event')
+ mock_listener1.should_receive(:step_upcoming).with(:then, 'an outcome')
+ mock_listener1.should_receive(:step_succeeded).with(:then, 'an outcome')
+
+ mock_listener2.should_receive(:step_upcoming).with(:given, 'a context')
+ mock_listener2.should_receive(:step_succeeded).with(:given, 'a context')
+ mock_listener2.should_receive(:step_upcoming).with(:when, 'an event')
+ mock_listener2.should_receive(:step_succeeded).with(:when, 'an event')
+ mock_listener2.should_receive(:step_upcoming).with(:then, 'an outcome')
+ mock_listener2.should_receive(:step_succeeded).with(:then, 'an outcome')
+
+ # when
+ world.instance_eval do
+ Given 'a context' do end
+ When 'an event' do end
+ Then 'an outcome' do end
+ end
+
+ # then
+ end
+
+ it 'should tell listeners but not execute the step in dry-run mode' do
+ # given
+ Runner.stub!(:dry_run).and_return(true)
+ mock_listener = mock('listener')
+ World.add_listener(mock_listener)
+ $step_invoked = false
+ world = World.create
+
+ # expect
+ mock_listener.should_receive(:step_upcoming).with(:given, 'a context')
+ mock_listener.should_receive(:step_succeeded).with(:given, 'a context')
+
+ # when
+ world.instance_eval do
+ Given 'a context' do
+ $step_invoked = true
+ end
+ end
+
+ # then
+ $step_invoked.should be(false)
+ end
+
+ it 'should suppress listeners while it runs a GivenScenario' do
+ # given
+ $scenario_ran = false
+
+ scenario = ScenarioBuilder.new.name('a scenario').to_scenario do
+ $scenario_ran = true
+ Given 'given' do end
+ When 'event' do end
+ Then 'outcome' do end
+ end
+
+ given_scenario = GivenScenario.new('a scenario')
+ Runner::StoryRunner.should_receive(:scenario_from_current_story).
+ with('a scenario').and_return(scenario)
+
+ world = World.create
+ listener = mock('listener')
+ World.add_listener(listener)
+
+ # expect
+ listener.should_receive(:found_scenario).with(:'given scenario', 'a scenario')
+ listener.should_receive(:step_succeeded).never.with(:given, 'given')
+ listener.should_receive(:step_succeeded).never.with(:when, 'event')
+ listener.should_receive(:step_succeeded).never.with(:then, 'outcome')
+
+ # when
+ world.GivenScenario 'a scenario'
+
+ # then
+ $scenario_ran.should be_true
+ end
+
+ it 'should interpret GivenScenario... And... as multiple givens' do
+ # given
+ world = World.create
+ $steps = []
+
+ scenario = ScenarioBuilder.new.name('a scenario').to_scenario do
+ $steps << 1
+ end
+ Runner::StoryRunner.should_receive(:scenario_from_current_story).
+ with('a scenario').and_return(scenario)
+
+ # when
+ world.instance_eval do
+ GivenScenario 'a scenario'
+ And 'step 2' do
+ $steps << 2
+ end
+ end
+
+ # then
+ $steps.should == [1,2]
+ World.step_mother.find(:given, 'step 2').should_not be_nil
+ end
+
+ it 'should provide rspec matchers' do
+ # given
+ world = World.create
+
+ # then
+ world.instance_eval do
+ 'hello'.should match(/^hello$/)
+ end
+ end
+
+ it "should use assigned matchers" do
+ world = World.create
+
+ World.should_receive(:use).with(steps = Object.new)
+
+ World.use(steps)
+ end
+ end
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec/translator_spec.rb b/vendor/gems/rspec/spec/spec/translator_spec.rb
new file mode 100644
index 000000000..01293d9ee
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec/translator_spec.rb
@@ -0,0 +1,265 @@
+require File.dirname(__FILE__) + '/../spec_helper.rb'
+require 'spec/translator'
+
+describe "Translator" do
+ before do
+ @t = Spec::Translator.new
+ end
+
+ it "should translate files" do
+ from = File.dirname(__FILE__) + '/..'
+ to = "#{Dir.tmpdir}/translated_specs"
+ @t.translate_dir(from, to)
+ end
+
+ it "should translate context_setup do" do
+ @t.translate_line(
+ "context_setup do\n"
+ ).should eql(
+ "before(:all) do\n"
+ )
+ end
+
+ it "should translate context_setup {foo}" do
+ @t.translate_line(
+ "context_setup {foo}\n"
+ ).should eql(
+ "before(:all) {foo}\n"
+ )
+ end
+
+ it "should translate context ' to describe '" do
+ @t.translate_line(
+ "context 'Translator' do\n"
+ ).should eql(
+ "describe 'Translator' do\n"
+ )
+ end
+
+ it 'should translate context " to describe "' do
+ @t.translate_line(
+ 'context "Translator"'
+ ).should eql(
+ 'describe "Translator"'
+ )
+ end
+
+ it 'should translate spaces then context " to describe "' do
+ @t.translate_line(
+ ' context "Translator"'
+ ).should eql(
+ ' describe "Translator"'
+ )
+ end
+
+ it "should not translate context=foo" do
+ @t.translate_line(' context=foo').should eql(' context=foo')
+ end
+
+ it "should not translate context = foo" do
+ @t.translate_line(' context = foo').should eql(' context = foo')
+ end
+
+ it "should not translate context = foo" do
+ @t.translate_line(' context = foo').should eql(' context = foo')
+ end
+
+ it "should translate should_be_close" do
+ @t.translate_line('5.0.should_be_close(5.0, 0.5)').should eql('5.0.should be_close(5.0, 0.5)')
+ end
+
+ it "should translate should_not_raise" do
+ @t.translate_line('lambda { self.call }.should_not_raise').should eql('lambda { self.call }.should_not raise_error')
+ end
+
+ it "should translate should_throw" do
+ @t.translate_line('lambda { self.call }.should_throw').should eql('lambda { self.call }.should throw_symbol')
+ end
+
+ it "should not translate 0.9 should_not" do
+ @t.translate_line('@target.should_not @matcher').should eql('@target.should_not @matcher')
+ end
+
+ it "should leave should_not_receive" do
+ @t.translate_line('@mock.should_not_receive(:not_expected).with("unexpected text")').should eql('@mock.should_not_receive(:not_expected).with("unexpected text")')
+ end
+
+ it "should leave should_receive" do
+ @t.translate_line('@mock.should_receive(:not_expected).with("unexpected text")').should eql('@mock.should_receive(:not_expected).with("unexpected text")')
+ end
+
+ it "should translate multi word predicates" do
+ @t.translate_line('foo.should_multi_word_predicate').should eql('foo.should be_multi_word_predicate')
+ end
+
+ it "should translate multi word predicates prefixed with be" do
+ @t.translate_line('foo.should_be_multi_word_predicate').should eql('foo.should be_multi_word_predicate')
+ end
+
+ it "should translate be(expected) to equal(expected)" do
+ @t.translate_line('foo.should_be :cool').should eql('foo.should equal :cool')
+ end
+
+ it "should translate instance_of" do
+ @t.translate_line('5.should_be_an_instance_of(Integer)').should eql('5.should be_an_instance_of(Integer)')
+ end
+
+ it "should translate should_be <" do
+ @t.translate_line('3.should_be < 4').should eql('3.should be < 4')
+ end
+
+ it "should translate should_be <=" do
+ @t.translate_line('3.should_be <= 4').should eql('3.should be <= 4')
+ end
+
+ it "should translate should_be >=" do
+ @t.translate_line('4.should_be >= 3').should eql('4.should be >= 3')
+ end
+
+ it "should translate should_be >" do
+ @t.translate_line('4.should_be > 3').should eql('4.should be > 3')
+ end
+
+ it "should translate should_be_happy" do
+ @t.translate_line("4.should_be_happy").should eql("4.should be_happy")
+ end
+
+ it "should translate custom method taking regexp with parenthesis" do
+ @t.translate_line("@browser.should_contain_text(/Sn.rrunger og annet rusk/)").should eql("@browser.should be_contain_text(/Sn.rrunger og annet rusk/)")
+ end
+
+ it "should translate custom method taking regexp without parenthesis" do
+ @t.translate_line("@browser.should_contain_text /Sn.rrunger og annet rusk/\n").should eql("@browser.should be_contain_text(/Sn.rrunger og annet rusk/)\n")
+ end
+
+ it "should translate should_not_be_nil" do
+ @t.translate_line("foo.should_not_be_nil\n").should eql("foo.should_not be_nil\n")
+ end
+
+ it "should translate kind of" do
+ @t.translate_line('@object.should_be_kind_of(MessageExpectation)').should(
+ eql('@object.should be_kind_of(MessageExpectation)'))
+ end
+
+ it "should translate should_be_true" do
+ @t.translate_line("foo.should_be_true\n").should eql("foo.should be_true\n")
+ end
+
+ # [#9674] spec_translate incorrectly handling shoud_match, when regexp in a var, in a block
+ # http://rubyforge.org/tracker/?func=detail&atid=3149&aid=9674&group_id=797
+ it "should translate should_match on a regexp, in a var, in a block" do
+ @t.translate_line("collection.each { |c| c.should_match a_regexp_in_a_var }\n").should eql("collection.each { |c| c.should match(a_regexp_in_a_var) }\n")
+ @t.translate_line("collection.each{|c| c.should_match a_regexp_in_a_var}\n").should eql("collection.each{|c| c.should match(a_regexp_in_a_var) }\n")
+ end
+
+ # From Rubinius specs
+ it "should translate close_to without parens" do
+ @t.translate_line("end.should_be_close 3.14159_26535_89793_23846, TOLERANCE\n").should eql("end.should be_close(3.14159_26535_89793_23846, TOLERANCE)\n")
+ end
+
+ # [#9882] 0.9 Beta 1 - translator bugs
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=9882&group_id=797&atid=3149
+ it "should support symbol arguments" do
+ @t.translate_line(
+ "lambda { sequence.parse('bar') }.should_throw :ZeroWidthParseSuccess\n"
+ ).should eql(
+ "lambda { sequence.parse('bar') }.should throw_symbol(:ZeroWidthParseSuccess)\n"
+ )
+ end
+
+ # [#9882] 0.9 Beta 1 - translator bugs
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=9882&group_id=797&atid=3149
+ it "should support instance var arguments" do
+ @t.translate_line(
+ "a.should_eql @local"
+ ).should eql(
+ "a.should eql(@local)"
+ )
+ end
+
+ # [#9882] 0.9 Beta 1 - translator bugs
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=9882&group_id=797&atid=3149
+ it "should support lambdas as expecteds" do
+ @t.translate_line(
+ "@parslet.should_not_eql lambda { nil }.to_parseable"
+ ).should eql(
+ "@parslet.should_not eql(lambda { nil }.to_parseable)"
+ )
+ end
+
+ # [#9882] 0.9 Beta 1 - translator bugs
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=9882&group_id=797&atid=3149
+ it "should support fully qualified names" do
+ @t.translate_line(
+ "results.should_be_kind_of SimpleASTLanguage::Identifier"
+ ).should eql(
+ "results.should be_kind_of(SimpleASTLanguage::Identifier)"
+ )
+ end
+
+ # [#9882] 0.9 Beta 1 - translator bugs
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=9882&group_id=797&atid=3149
+ # it "should leave whitespace between expression and comments" do
+ # @t.translate_line(
+ # "lambda { @instance.foo = foo }.should_raise NoMethodError # no writer defined"
+ # ).should eql(
+ # "lambda { @instance.foo = foo }.should raise_error(NoMethodError) # no writer defined"
+ # )
+ # end
+
+ it "should translate redirects" do
+ @t.translate_line(
+ "controller.should_redirect_to 'http://not_existing_domain_for_novalis.test.host/404.html'"
+ ).should eql(
+ "controller.should redirect_to('http://not_existing_domain_for_novalis.test.host/404.html')"
+ )
+ end
+
+ it "should translate :any_args" do
+ @t.translate_line(
+ "mock.should_receive(:foo).with(:any_args)"
+ ).should eql(
+ "mock.should_receive(:foo).with(any_args)"
+ )
+ end
+
+ it "should translate :anything" do
+ @t.translate_line(
+ "mock.should_receive(:foo).with(:anything)"
+ ).should eql(
+ "mock.should_receive(:foo).with(anything)"
+ )
+ end
+
+ it "should translate :boolean" do
+ @t.translate_line(
+ "mock.should_receive(:foo).with(:boolean)"
+ ).should eql(
+ "mock.should_receive(:foo).with(boolean)"
+ )
+ end
+
+ it "should translate :no_args" do
+ @t.translate_line(
+ "mock.should_receive(:foo).with(:no_args)"
+ ).should eql(
+ "mock.should_receive(:foo).with(no_args)"
+ )
+ end
+
+ it "should translate :numeric" do
+ @t.translate_line(
+ "mock.should_receive(:foo).with(:numeric)"
+ ).should eql(
+ "mock.should_receive(:foo).with(an_instance_of(Numeric))"
+ )
+ end
+
+ it "should translate :string" do
+ @t.translate_line(
+ "mock.should_receive(:foo).with(:string)"
+ ).should eql(
+ "mock.should_receive(:foo).with(an_instance_of(String))"
+ )
+ end
+end
diff --git a/vendor/gems/rspec/spec/spec_helper.rb b/vendor/gems/rspec/spec/spec_helper.rb
new file mode 100644
index 000000000..1318176d5
--- /dev/null
+++ b/vendor/gems/rspec/spec/spec_helper.rb
@@ -0,0 +1,103 @@
+require 'stringio'
+
+dir = File.dirname(__FILE__)
+lib_path = File.expand_path("#{dir}/../lib")
+$LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
+$_spec_spec = true # Prevents Kernel.exit in various places
+
+require 'spec'
+require 'spec/mocks'
+require 'spec/story'
+spec_classes_path = File.expand_path("#{dir}/../spec/spec/spec_classes")
+require spec_classes_path unless $LOAD_PATH.include?(spec_classes_path)
+require File.dirname(__FILE__) + '/../lib/spec/expectations/differs/default'
+
+module Spec
+ module Matchers
+ def fail
+ raise_error(Spec::Expectations::ExpectationNotMetError)
+ end
+
+ def fail_with(message)
+ raise_error(Spec::Expectations::ExpectationNotMetError, message)
+ end
+
+ class Pass
+ def matches?(proc, &block)
+ begin
+ proc.call
+ true
+ rescue Exception => @error
+ false
+ end
+ end
+
+ def failure_message
+ @error.message + "\n" + @error.backtrace.join("\n")
+ end
+ end
+
+ def pass
+ Pass.new
+ end
+
+ class CorrectlyOrderedMockExpectation
+ def initialize(&event)
+ @event = event
+ end
+
+ def expect(&expectations)
+ expectations.call
+ @event.call
+ end
+ end
+
+ def during(&block)
+ CorrectlyOrderedMockExpectation.new(&block)
+ end
+ end
+end
+
+class NonStandardError < Exception; end
+
+module Custom
+ class ExampleGroupRunner
+ attr_reader :options, :arg
+ def initialize(options, arg)
+ @options, @arg = options, arg
+ end
+
+ def load_files(files)
+ end
+
+ def run
+ end
+ end
+end
+
+def exception_from(&block)
+ exception = nil
+ begin
+ yield
+ rescue StandardError => e
+ exception = e
+ end
+ exception
+end
+
+describe "sandboxed rspec_options", :shared => true do
+ attr_reader :options
+
+ before(:all) do
+ @original_rspec_options = $rspec_options
+ end
+
+ before(:each) do
+ @options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new)
+ $rspec_options = options
+ end
+
+ after do
+ $rspec_options = @original_rspec_options
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/stories/all.rb b/vendor/gems/rspec/stories/all.rb
new file mode 100644
index 000000000..c2428fdf8
--- /dev/null
+++ b/vendor/gems/rspec/stories/all.rb
@@ -0,0 +1,5 @@
+require File.join(File.dirname(__FILE__), *%w[helper])
+
+["example_groups","interop"].each do |dir|
+ require File.join(File.dirname(__FILE__), "#{dir}/stories")
+end
diff --git a/vendor/gems/rspec/stories/example_groups/autogenerated_docstrings b/vendor/gems/rspec/stories/example_groups/autogenerated_docstrings
new file mode 100644
index 000000000..b3ff68998
--- /dev/null
+++ b/vendor/gems/rspec/stories/example_groups/autogenerated_docstrings
@@ -0,0 +1,45 @@
+Story: autogenerated docstrings
+
+ As an RSpec user
+ I want examples to generate their own names
+ So that I can reduce duplication between example names and example code
+
+ Scenario: run passing examples with ruby
+ Given the file ../../examples/pure/autogenerated_docstrings_example.rb
+
+ When I run it with the ruby interpreter -fs
+
+ Then the stdout should match /should equal 5/
+ And the stdout should match /should be < 5/
+ And the stdout should match /should include "a"/
+ And the stdout should match /should respond to #size/
+
+ Scenario: run failing examples with ruby
+ Given the file ../../failing_examples/failing_autogenerated_docstrings_example.rb
+
+ When I run it with the ruby interpreter -fs
+
+ Then the stdout should match /should equal 2/
+ And the stdout should match /should be > 5/
+ And the stdout should match /should include "b"/
+ And the stdout should match /should not respond to #size/
+
+ Scenario: run passing examples with spec
+ Given the file ../../examples/pure/autogenerated_docstrings_example.rb
+
+ When I run it with the spec script -fs
+
+ Then the stdout should match /should equal 5/
+ And the stdout should match /should be < 5/
+ And the stdout should match /should include "a"/
+ And the stdout should match /should respond to #size/
+
+ Scenario: run failing examples with spec
+ Given the file ../../failing_examples/failing_autogenerated_docstrings_example.rb
+
+ When I run it with the spec script -fs
+
+ Then the stdout should match /should equal 2/
+ And the stdout should match /should be > 5/
+ And the stdout should match /should include "b"/
+ And the stdout should match /should not respond to #size/
diff --git a/vendor/gems/rspec/stories/example_groups/example_group_with_should_methods b/vendor/gems/rspec/stories/example_groups/example_group_with_should_methods
new file mode 100644
index 000000000..3d2bc61eb
--- /dev/null
+++ b/vendor/gems/rspec/stories/example_groups/example_group_with_should_methods
@@ -0,0 +1,17 @@
+Story: Spec::ExampleGroup with should methods
+
+ As an RSpec adopter accustomed to classes and methods
+ I want to use should_* methods in an ExampleGroup
+ So that I use RSpec with classes and methods that look more like RSpec examples
+
+ Scenario: Run with ruby
+ Given the file spec/example_group_with_should_methods.rb
+ When I run it with the ruby interpreter
+ Then the exit code should be 256
+ And the stdout should match "2 examples, 1 failure"
+
+ Scenario: Run with spec
+ Given the file spec/example_group_with_should_methods.rb
+ When I run it with the spec script
+ Then the exit code should be 256
+ And the stdout should match "2 examples, 1 failure"
diff --git a/vendor/gems/rspec/stories/example_groups/nested_groups b/vendor/gems/rspec/stories/example_groups/nested_groups
new file mode 100644
index 000000000..ede978563
--- /dev/null
+++ b/vendor/gems/rspec/stories/example_groups/nested_groups
@@ -0,0 +1,17 @@
+Story: Nested example groups
+
+ As an RSpec user
+ I want to nest examples groups
+ So that I can better organize my examples
+
+ Scenario: Run with ruby
+ Given the file ../../examples/pure/stack_spec_with_nested_example_groups.rb
+ When I run it with the ruby interpreter -fs
+ Then the stdout should match /Stack \(empty\)/
+ And the stdout should match /Stack \(full\)/
+
+ Scenario: Run with ruby
+ Given the file ../../examples/pure/stack_spec_with_nested_example_groups.rb
+ When I run it with the spec script -fs
+ Then the stdout should match /Stack \(empty\)/
+ And the stdout should match /Stack \(full\)/
diff --git a/vendor/gems/rspec/stories/example_groups/output b/vendor/gems/rspec/stories/example_groups/output
new file mode 100644
index 000000000..4947bdcaf
--- /dev/null
+++ b/vendor/gems/rspec/stories/example_groups/output
@@ -0,0 +1,25 @@
+Story: Getting correct output
+
+ As an RSpec user
+ I want to see output only once
+ So that I don't get confused
+
+ Scenario: Run with ruby
+ Given the file spec/simple_spec.rb
+ When I run it with the ruby interpreter
+ Then the exit code should be 0
+ And the stdout should not match /\d+ tests, \d+ assertions, \d+ failures, \d+ errors/m
+ And the stdout should match "1 example, 0 failures"
+
+ Scenario: Run with CommandLine object
+ Given the file spec/simple_spec.rb
+ When I run it with the CommandLine object
+ Then the exit code should be 0
+ And the stdout should not match "Loaded suite"
+ And the stdout should not match /\d+ tests, \d+ assertions, \d+ failures, \d+ errors/m
+ And the stdout should match "1 example, 0 failures"
+
+ Scenario: Tweak backtrace
+ Given the file stories/failing_story.rb
+ When I run it with the ruby interpreter
+ Then the stdout should not match /\/lib\/spec\//
diff --git a/vendor/gems/rspec/stories/example_groups/stories.rb b/vendor/gems/rspec/stories/example_groups/stories.rb
new file mode 100644
index 000000000..e45882a93
--- /dev/null
+++ b/vendor/gems/rspec/stories/example_groups/stories.rb
@@ -0,0 +1,7 @@
+require File.join(File.dirname(__FILE__), *%w[.. helper])
+
+with_steps_for :running_rspec do
+ Dir["#{File.dirname(__FILE__)}/*"].each do |file|
+ run file if File.file?(file) && !(file =~ /\.rb$/)
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/stories/helper.rb b/vendor/gems/rspec/stories/helper.rb
new file mode 100644
index 000000000..d9a105e76
--- /dev/null
+++ b/vendor/gems/rspec/stories/helper.rb
@@ -0,0 +1,6 @@
+$LOAD_PATH.unshift File.expand_path("#{File.dirname(__FILE__)}/../lib")
+require 'spec'
+require 'tempfile'
+require File.join(File.dirname(__FILE__), *%w[resources matchers smart_match])
+require File.join(File.dirname(__FILE__), *%w[resources helpers story_helper])
+require File.join(File.dirname(__FILE__), *%w[resources steps running_rspec])
diff --git a/vendor/gems/rspec/stories/interop/examples_and_tests_together b/vendor/gems/rspec/stories/interop/examples_and_tests_together
new file mode 100644
index 000000000..6583f89c6
--- /dev/null
+++ b/vendor/gems/rspec/stories/interop/examples_and_tests_together
@@ -0,0 +1,30 @@
+Story: Spec and test together
+
+ As an RSpec adopter with existing Test::Unit tests
+ I want to run a few specs alongside my existing Test::Unit tests
+ So that I can experience a smooth, gradual migration path
+
+ Scenario: Run with ruby
+ Given the file test/spec_and_test_together.rb
+
+ When I run it with the ruby interpreter -fs
+
+ Then the exit code should be 256
+ And the stdout should match "ATest"
+ And the stdout should match "Test::Unit::AssertionFailedError in 'An Example should fail with assert'"
+ And the stdout should match "'An Example should fail with should' FAILED"
+ And the stdout should match "10 examples, 6 failures"
+ And the stdout should match /expected: 40,\s*got: 4/m
+ And the stdout should match /expected: 50,\s*got: 5/m
+ Scenario: Run with spec
+ Given the file test/spec_and_test_together.rb
+
+ When I run it with the spec script -fs
+
+ Then the exit code should be 256
+ Ands the stdout should match "ATest"
+ And the stdout should match "Test::Unit::AssertionFailedError in 'An Example should fail with assert'"
+ And the stdout should match "'An Example should fail with should' FAILED"
+ And the stdout should match "10 examples, 6 failures"
+ And the stdout should match /expected: 40,\s*got: 4/m
+ And the stdout should match /expected: 50,\s*got: 5/m
diff --git a/vendor/gems/rspec/stories/interop/stories.rb b/vendor/gems/rspec/stories/interop/stories.rb
new file mode 100644
index 000000000..e45882a93
--- /dev/null
+++ b/vendor/gems/rspec/stories/interop/stories.rb
@@ -0,0 +1,7 @@
+require File.join(File.dirname(__FILE__), *%w[.. helper])
+
+with_steps_for :running_rspec do
+ Dir["#{File.dirname(__FILE__)}/*"].each do |file|
+ run file if File.file?(file) && !(file =~ /\.rb$/)
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/stories/interop/test_case_with_should_methods b/vendor/gems/rspec/stories/interop/test_case_with_should_methods
new file mode 100644
index 000000000..d618c50e2
--- /dev/null
+++ b/vendor/gems/rspec/stories/interop/test_case_with_should_methods
@@ -0,0 +1,17 @@
+Story: Test::Unit::TestCase extended by rspec with should methods
+
+ As an RSpec adopter with existing Test::Unit tests
+ I want to use should_* methods in a Test::Unit::TestCase
+ So that I use RSpec with classes and methods that look more like RSpec examples
+
+ Scenario: Run with ruby
+ Given the file test/test_case_with_should_methods.rb
+ When I run it with the ruby interpreter
+ Then the exit code should be 256
+ And the stdout should match "5 examples, 3 failures"
+
+ Scenario: Run with spec
+ Given the file test/test_case_with_should_methods.rb
+ When I run it with the spec script
+ Then the exit code should be 256
+ And the stdout should match "5 examples, 3 failures"
diff --git a/vendor/gems/rspec/stories/pending_stories/README b/vendor/gems/rspec/stories/pending_stories/README
new file mode 100644
index 000000000..2f9b44314
--- /dev/null
+++ b/vendor/gems/rspec/stories/pending_stories/README
@@ -0,0 +1,3 @@
+This directory contains stories that are currently not passing
+because they are new or they represent regressions.
+
diff --git a/vendor/gems/rspec/stories/resources/helpers/cmdline.rb b/vendor/gems/rspec/stories/resources/helpers/cmdline.rb
new file mode 100644
index 000000000..ab86bd3e1
--- /dev/null
+++ b/vendor/gems/rspec/stories/resources/helpers/cmdline.rb
@@ -0,0 +1,9 @@
+$:.push File.join(File.dirname(__FILE__), *%w[.. .. .. lib])
+require 'spec'
+
+# Uncommenting next line will break the output story (no output!!)
+# rspec_options
+options = Spec::Runner::OptionParser.parse(
+ ARGV, $stderr, $stdout
+)
+Spec::Runner::CommandLine.run(options)
diff --git a/vendor/gems/rspec/stories/resources/helpers/story_helper.rb b/vendor/gems/rspec/stories/resources/helpers/story_helper.rb
new file mode 100644
index 000000000..e0aef5b45
--- /dev/null
+++ b/vendor/gems/rspec/stories/resources/helpers/story_helper.rb
@@ -0,0 +1,16 @@
+require 'spec/story'
+require File.dirname(__FILE__) + '/../../../spec/ruby_forker'
+
+module StoryHelper
+ include RubyForker
+
+ def spec(args, stderr)
+ ruby("#{File.dirname(__FILE__) + '/../../../bin/spec'} #{args}", stderr)
+ end
+
+ def cmdline(args, stderr)
+ ruby("#{File.dirname(__FILE__) + '/../../resources/helpers/cmdline.rb'} #{args}", stderr)
+ end
+
+ Spec::Story::World.send :include, self
+end
diff --git a/vendor/gems/rspec/stories/resources/matchers/smart_match.rb b/vendor/gems/rspec/stories/resources/matchers/smart_match.rb
new file mode 100644
index 000000000..7b1672bc0
--- /dev/null
+++ b/vendor/gems/rspec/stories/resources/matchers/smart_match.rb
@@ -0,0 +1,37 @@
+module Spec
+ module Matchers
+ class SmartMatch
+ def initialize(expected)
+ @expected = expected
+ end
+
+ def matches?(actual)
+ @actual = actual
+ # Satisfy expectation here. Return false or raise an error if it's not met.
+
+ if @expected =~ /^\/.*\/?$/ || @expected =~ /^".*"$/
+ regex_or_string = eval(@expected)
+ if Regexp === regex_or_string
+ (@actual =~ regex_or_string) ? true : false
+ else
+ @actual.index(regex_or_string) != nil
+ end
+ else
+ false
+ end
+ end
+
+ def failure_message
+ "expected #{@actual.inspect} to smart_match #{@expected.inspect}, but it didn't"
+ end
+
+ def negative_failure_message
+ "expected #{@actual.inspect} not to smart_match #{@expected.inspect}, but it did"
+ end
+ end
+
+ def smart_match(expected)
+ SmartMatch.new(expected)
+ end
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/stories/resources/spec/example_group_with_should_methods.rb b/vendor/gems/rspec/stories/resources/spec/example_group_with_should_methods.rb
new file mode 100644
index 000000000..4c0505d2a
--- /dev/null
+++ b/vendor/gems/rspec/stories/resources/spec/example_group_with_should_methods.rb
@@ -0,0 +1,12 @@
+$:.push File.join(File.dirname(__FILE__), *%w[.. .. .. lib])
+require 'spec'
+
+class MySpec < Spec::ExampleGroup
+ def should_pass_with_should
+ 1.should == 1
+ end
+
+ def should_fail_with_should
+ 1.should == 2
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/stories/resources/spec/simple_spec.rb b/vendor/gems/rspec/stories/resources/spec/simple_spec.rb
new file mode 100644
index 000000000..2fb67ba49
--- /dev/null
+++ b/vendor/gems/rspec/stories/resources/spec/simple_spec.rb
@@ -0,0 +1,8 @@
+$:.push File.join(File.dirname(__FILE__), *%w[.. .. .. lib])
+require 'spec'
+
+describe "Running an Example" do
+ it "should not output twice" do
+ true.should be_true
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/stories/resources/steps/running_rspec.rb b/vendor/gems/rspec/stories/resources/steps/running_rspec.rb
new file mode 100644
index 000000000..496847fe4
--- /dev/null
+++ b/vendor/gems/rspec/stories/resources/steps/running_rspec.rb
@@ -0,0 +1,50 @@
+steps_for :running_rspec do
+
+ Given("the file $relative_path") do |relative_path|
+ @path = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "resources", relative_path))
+ unless File.exist?(@path)
+ raise "could not find file at #{@path}"
+ end
+ end
+
+ When("I run it with the $interpreter") do |interpreter|
+ stderr_file = Tempfile.new('rspec')
+ stderr_file.close
+ @stdout = case(interpreter)
+ when /^ruby interpreter/
+ args = interpreter.gsub('ruby interpreter','')
+ ruby("#{@path}#{args}", stderr_file.path)
+ when /^spec script/
+ args = interpreter.gsub('spec script','')
+ spec("#{@path}#{args}", stderr_file.path)
+ when 'CommandLine object' then cmdline(@path, stderr_file.path)
+ else raise "Unknown interpreter: #{interpreter}"
+ end
+ @stderr = IO.read(stderr_file.path)
+ @exit_code = $?.to_i
+ end
+
+ Then("the exit code should be $exit_code") do |exit_code|
+ if @exit_code != exit_code.to_i
+ raise "Did not exit with #{exit_code}, but with #{@exit_code}. Standard error:\n#{@stderr}"
+ end
+ end
+
+ Then("the $stream should match $regex") do |stream, string_or_regex|
+ written = case(stream)
+ when 'stdout' then @stdout
+ when 'stderr' then @stderr
+ else raise "Unknown stream: #{stream}"
+ end
+ written.should smart_match(string_or_regex)
+ end
+
+ Then("the $stream should not match $regex") do |stream, string_or_regex|
+ written = case(stream)
+ when 'stdout' then @stdout
+ when 'stderr' then @stderr
+ else raise "Unknown stream: #{stream}"
+ end
+ written.should_not smart_match(string_or_regex)
+ end
+end
diff --git a/vendor/gems/rspec/stories/resources/stories/failing_story.rb b/vendor/gems/rspec/stories/resources/stories/failing_story.rb
new file mode 100644
index 000000000..cc9506c66
--- /dev/null
+++ b/vendor/gems/rspec/stories/resources/stories/failing_story.rb
@@ -0,0 +1,15 @@
+$:.push File.join(File.dirname(__FILE__), *%w[.. .. .. lib])
+
+require 'spec/story'
+
+Story "Failing story",
+%(As an RSpec user
+ I want a failing test
+ So that I can observe the output) do
+
+ Scenario "Failing scenario" do
+ Then "true should be false" do
+ true.should == false
+ end
+ end
+end
diff --git a/vendor/gems/rspec/stories/resources/test/spec_and_test_together.rb b/vendor/gems/rspec/stories/resources/test/spec_and_test_together.rb
new file mode 100644
index 000000000..eb2b4e074
--- /dev/null
+++ b/vendor/gems/rspec/stories/resources/test/spec_and_test_together.rb
@@ -0,0 +1,57 @@
+$:.push File.join(File.dirname(__FILE__), *%w[.. .. .. lib])
+require 'spec'
+# TODO - this should not be necessary, ay?
+require 'spec/interop/test'
+
+describe "An Example" do
+ it "should pass with assert" do
+ assert true
+ end
+
+ it "should fail with assert" do
+ assert false
+ end
+
+ it "should pass with should" do
+ 1.should == 1
+ end
+
+ it "should fail with should" do
+ 1.should == 2
+ end
+end
+
+class ATest < Test::Unit::TestCase
+ def test_should_pass_with_assert
+ assert true
+ end
+
+ def test_should_fail_with_assert
+ assert false
+ end
+
+ def test_should_pass_with_should
+ 1.should == 1
+ end
+
+ def test_should_fail_with_should
+ 1.should == 2
+ end
+
+ def setup
+ @from_setup ||= 3
+ @from_setup += 1
+ end
+
+ def test_should_fail_with_setup_method_variable
+ @from_setup.should == 40
+ end
+
+ before do
+ @from_before = @from_setup + 1
+ end
+
+ def test_should_fail_with_before_block_variable
+ @from_before.should == 50
+ end
+end \ No newline at end of file
diff --git a/vendor/gems/rspec/stories/resources/test/test_case_with_should_methods.rb b/vendor/gems/rspec/stories/resources/test/test_case_with_should_methods.rb
new file mode 100644
index 000000000..3912429e3
--- /dev/null
+++ b/vendor/gems/rspec/stories/resources/test/test_case_with_should_methods.rb
@@ -0,0 +1,30 @@
+$:.push File.join(File.dirname(__FILE__), *%w[.. .. .. lib])
+require 'test/unit'
+require 'spec'
+require 'spec/interop/test'
+
+class MySpec < Test::Unit::TestCase
+ def should_pass_with_should
+ 1.should == 1
+ end
+
+ def should_fail_with_should
+ 1.should == 2
+ end
+
+ def should_pass_with_assert
+ assert true
+ end
+
+ def should_fail_with_assert
+ assert false
+ end
+
+ def test
+ raise "This is not a real test"
+ end
+
+ def test_ify
+ raise "This is a real test"
+ end
+end \ No newline at end of file