carats 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +2 -0
- data/LICENSE +5 -0
- data/README +67 -0
- data/Reapfile +72 -0
- data/ToDo +24 -0
- data/bench/b_harray.rb +49 -0
- data/bench/b_range.rb +64 -0
- data/demo/ansicolor/cdiff.rb +20 -0
- data/demo/ansicolor/example.rb +82 -0
- data/demo/io-reactor/chatserver.rb +347 -0
- data/doc/classes/Array.html +172 -0
- data/doc/classes/BBCode.html +638 -0
- data/doc/classes/BinaryReader.html +675 -0
- data/doc/classes/Binding.html +223 -0
- data/doc/classes/ByteOrder.html +284 -0
- data/doc/classes/Class.html +189 -0
- data/doc/classes/Constant.html +785 -0
- data/doc/classes/Constant/CGS.html +609 -0
- data/doc/classes/Continuation.html +113 -0
- data/doc/classes/Coroutine.html +387 -0
- data/doc/classes/CountingSemaphore.html +337 -0
- data/doc/classes/CrossCase.html +561 -0
- data/doc/classes/DynamicMixin.html +185 -0
- data/doc/classes/EnumerableWithArgs.html +550 -0
- data/doc/classes/Expect.html +428 -0
- data/doc/classes/Expect/DefaultChain.html +113 -0
- data/doc/classes/Expect/SeparatedPattern.html +223 -0
- data/doc/classes/Expect/Timeout.html +167 -0
- data/doc/classes/Expect/UnmatchedMessage.html +160 -0
- data/doc/classes/FileList.html +833 -0
- data/doc/classes/FloatString.html +534 -0
- data/doc/classes/Functor.html +211 -0
- data/doc/classes/HArray.html +1872 -0
- data/doc/classes/HTML.html +328 -0
- data/doc/classes/Heap.html +683 -0
- data/doc/classes/Heap/EmptyHeapException.html +111 -0
- data/doc/classes/Heap/Max.html +176 -0
- data/doc/classes/Heap/Min.html +176 -0
- data/doc/classes/IO.html +108 -0
- data/doc/classes/IO/Reactor.html +790 -0
- data/doc/classes/IO/Redirect.html +289 -0
- data/doc/classes/Infinity.html +320 -0
- data/doc/classes/Interval.html +1014 -0
- data/doc/classes/InvalidNackError.html +161 -0
- data/doc/classes/Kernel.html +204 -0
- data/doc/classes/Lisp.html +1132 -0
- data/doc/classes/Lisp/DottedPair.html +379 -0
- data/doc/classes/Lisp/Format.html +178 -0
- data/doc/classes/Lisp/Format/ArgumentError.html +126 -0
- data/doc/classes/Lisp/Format/Directives.html +155 -0
- data/doc/classes/Lisp/Format/Directives/ArgJump.html +178 -0
- data/doc/classes/Lisp/Format/Directives/Ascii.html +119 -0
- data/doc/classes/Lisp/Format/Directives/BeginCaseConversion.html +185 -0
- data/doc/classes/Lisp/Format/Directives/BeginConditional.html +307 -0
- data/doc/classes/Lisp/Format/Directives/BeginIteration.html +338 -0
- data/doc/classes/Lisp/Format/Directives/Binary.html +157 -0
- data/doc/classes/Lisp/Format/Directives/Character.html +228 -0
- data/doc/classes/Lisp/Format/Directives/CharacterDirective.html +203 -0
- data/doc/classes/Lisp/Format/Directives/ClauseSeparator.html +166 -0
- data/doc/classes/Lisp/Format/Directives/Decimal.html +119 -0
- data/doc/classes/Lisp/Format/Directives/Directive.html +397 -0
- data/doc/classes/Lisp/Format/Directives/DollarFP.html +205 -0
- data/doc/classes/Lisp/Format/Directives/EndCaseConversion.html +174 -0
- data/doc/classes/Lisp/Format/Directives/EndConditional.html +159 -0
- data/doc/classes/Lisp/Format/Directives/EndIteration.html +163 -0
- data/doc/classes/Lisp/Format/Directives/ExpFP.html +252 -0
- data/doc/classes/Lisp/Format/Directives/FFFP.html +224 -0
- data/doc/classes/Lisp/Format/Directives/Factory.html +180 -0
- data/doc/classes/Lisp/Format/Directives/FreshLine.html +175 -0
- data/doc/classes/Lisp/Format/Directives/GeneralFP.html +265 -0
- data/doc/classes/Lisp/Format/Directives/Hexadecimal.html +157 -0
- data/doc/classes/Lisp/Format/Directives/Indirection.html +183 -0
- data/doc/classes/Lisp/Format/Directives/Literal.html +187 -0
- data/doc/classes/Lisp/Format/Directives/NewLine.html +158 -0
- data/doc/classes/Lisp/Format/Directives/NewPage.html +158 -0
- data/doc/classes/Lisp/Format/Directives/Number.html +243 -0
- data/doc/classes/Lisp/Format/Directives/Octal.html +157 -0
- data/doc/classes/Lisp/Format/Directives/Plural.html +177 -0
- data/doc/classes/Lisp/Format/Directives/Print.html +237 -0
- data/doc/classes/Lisp/Format/Directives/Radix.html +432 -0
- data/doc/classes/Lisp/Format/Directives/SExpression.html +157 -0
- data/doc/classes/Lisp/Format/Directives/SkipWhitespace.html +165 -0
- data/doc/classes/Lisp/Format/Directives/Tabulate.html +198 -0
- data/doc/classes/Lisp/Format/Directives/Tilde.html +158 -0
- data/doc/classes/Lisp/Format/Directives/UnknownDirectiveError.html +117 -0
- data/doc/classes/Lisp/Format/Formatter.html +193 -0
- data/doc/classes/Lisp/Format/IncompleteParameterError.html +119 -0
- data/doc/classes/Lisp/Format/IndexError.html +126 -0
- data/doc/classes/Lisp/Format/Lexer.html +479 -0
- data/doc/classes/Lisp/Format/MalformedError.html +119 -0
- data/doc/classes/Lisp/Format/MissingParameterError.html +119 -0
- data/doc/classes/Lisp/Format/ModifierError.html +119 -0
- data/doc/classes/Lisp/Format/Output.html +239 -0
- data/doc/classes/Lisp/Format/ParameterError.html +126 -0
- data/doc/classes/Lisp/Format/Parameters.html +123 -0
- data/doc/classes/Lisp/Format/Parameters/Argument.html +172 -0
- data/doc/classes/Lisp/Format/Parameters/ArgumentCount.html +159 -0
- data/doc/classes/Lisp/Format/Parameters/Character.html +119 -0
- data/doc/classes/Lisp/Format/Parameters/Default.html +120 -0
- data/doc/classes/Lisp/Format/Parameters/Integer.html +119 -0
- data/doc/classes/Lisp/Format/Parameters/Parameter.html +206 -0
- data/doc/classes/Lisp/Format/Parser.html +212 -0
- data/doc/classes/Lisp/Format/Positioned.html +166 -0
- data/doc/classes/Lisp/Format/State.html +455 -0
- data/doc/classes/Lisp/Format/SyntaxError.html +126 -0
- data/doc/classes/Method.html +274 -0
- data/doc/classes/Method/DuckHunter.html +281 -0
- data/doc/classes/Module.html +709 -0
- data/doc/classes/Multiton.html +284 -0
- data/doc/classes/Multiton/New.html +164 -0
- data/doc/classes/Multiton/Semi.html +155 -0
- data/doc/classes/NackClass.html +322 -0
- data/doc/classes/NilClass.html +231 -0
- data/doc/classes/NilComparable.html +179 -0
- data/doc/classes/NotCopyable.html +273 -0
- data/doc/classes/Object.html +261 -0
- data/doc/classes/OpenStructable.html +346 -0
- data/doc/classes/OrderedHash.html +939 -0
- data/doc/classes/Parser.html +515 -0
- data/doc/classes/Parser/Main.html +178 -0
- data/doc/classes/Parser/Marker.html +475 -0
- data/doc/classes/Parser/Registry.html +354 -0
- data/doc/classes/Parser/Token.html +399 -0
- data/doc/classes/Parser/UnitToken.html +222 -0
- data/doc/classes/Ref.html +230 -0
- data/doc/classes/SimpleStringIO.html +183 -0
- data/doc/classes/StaticHash.html +202 -0
- data/doc/classes/String.html +172 -0
- data/doc/classes/Struct.html +181 -0
- data/doc/classes/SuperStruct.html +382 -0
- data/doc/classes/Term.html +156 -0
- data/doc/classes/Term/ANSIColor.html +185 -0
- data/doc/classes/Text.html +138 -0
- data/doc/classes/Text/Soundex.html +222 -0
- data/doc/classes/TextTagIterator.html +911 -0
- data/doc/classes/Time.html +119 -0
- data/doc/classes/Time/Limit.html +303 -0
- data/doc/classes/Time/Limit/Dummy.html +181 -0
- data/doc/classes/Timer.html +351 -0
- data/doc/classes/TracePoint.html +532 -0
- data/doc/classes/Tuple.html +178 -0
- data/doc/classes/Uninheritable.html +213 -0
- data/doc/classes/Version.html +783 -0
- data/doc/created.rid +1 -0
- data/doc/files/LICENSE.html +113 -0
- data/doc/files/README.html +201 -0
- data/doc/files/lib/carat/1st_rb.html +107 -0
- data/doc/files/lib/carat/ansicolor_rb.html +146 -0
- data/doc/files/lib/carat/attr_rb.html +101 -0
- data/doc/files/lib/carat/bbcode_rb.html +152 -0
- data/doc/files/lib/carat/binaryreader_rb.html +114 -0
- data/doc/files/lib/carat/binding-of-caller_rb.html +108 -0
- data/doc/files/lib/carat/byteorder_rb.html +107 -0
- data/doc/files/lib/carat/constant_rb.html +167 -0
- data/doc/files/lib/carat/coroutine_rb.html +156 -0
- data/doc/files/lib/carat/crosscase_rb.html +224 -0
- data/doc/files/lib/carat/duckhunter_rb.html +165 -0
- data/doc/files/lib/carat/dynamic-mixin_rb.html +101 -0
- data/doc/files/lib/carat/enumerable-args_rb.html +140 -0
- data/doc/files/lib/carat/expect_rb.html +137 -0
- data/doc/files/lib/carat/filelist_rb.html +130 -0
- data/doc/files/lib/carat/floatstring_rb.html +126 -0
- data/doc/files/lib/carat/functor_rb.html +140 -0
- data/doc/files/lib/carat/harray_rb.html +128 -0
- data/doc/files/lib/carat/heap_rb.html +154 -0
- data/doc/files/lib/carat/html-helpers_rb.html +116 -0
- data/doc/files/lib/carat/infinity_rb.html +142 -0
- data/doc/files/lib/carat/init_rb.html +127 -0
- data/doc/files/lib/carat/interval_rb.html +162 -0
- data/doc/files/lib/carat/io-reactor_rb.html +211 -0
- data/doc/files/lib/carat/io-redirect_rb.html +132 -0
- data/doc/files/lib/carat/lisp-format_rb.html +187 -0
- data/doc/files/lib/carat/lisp_rb.html +152 -0
- data/doc/files/lib/carat/macro_rb.html +129 -0
- data/doc/files/lib/carat/multiton_rb.html +178 -0
- data/doc/files/lib/carat/nack_rb.html +193 -0
- data/doc/files/lib/carat/nil-comparable_rb.html +126 -0
- data/doc/files/lib/carat/nil-missing_rb.html +101 -0
- data/doc/files/lib/carat/notcopyable_rb.html +166 -0
- data/doc/files/lib/carat/orderedhash_rb.html +107 -0
- data/doc/files/lib/carat/ostructable_rb.html +157 -0
- data/doc/files/lib/carat/parser-old_rb.html +239 -0
- data/doc/files/lib/carat/parser_rb.html +244 -0
- data/doc/files/lib/carat/ref_rb.html +107 -0
- data/doc/files/lib/carat/semaphore_rb.html +132 -0
- data/doc/files/lib/carat/snapshot_rb.html +152 -0
- data/doc/files/lib/carat/soundex_rb.html +128 -0
- data/doc/files/lib/carat/sstruct_rb.html +142 -0
- data/doc/files/lib/carat/statichash_rb.html +150 -0
- data/doc/files/lib/carat/tagiter_rb.html +236 -0
- data/doc/files/lib/carat/timelimit_rb.html +136 -0
- data/doc/files/lib/carat/timer_rb.html +153 -0
- data/doc/files/lib/carat/tracepoint_rb.html +160 -0
- data/doc/files/lib/carat/tuple_rb.html +123 -0
- data/doc/files/lib/carat/uninheritable_rb.html +101 -0
- data/doc/files/lib/carat/version_rb.html +141 -0
- data/doc/fr_class_index.html +159 -0
- data/doc/fr_file_index.html +78 -0
- data/doc/fr_method_index.html +663 -0
- data/doc/index.html +24 -0
- data/doc/rdoc-style.css +208 -0
- data/lib/carat-dev/README +11 -0
- data/lib/carat-dev/access-blocks/access_blocks.rb +42 -0
- data/lib/carat-dev/association/association.rb +70 -0
- data/lib/carat-dev/blankslate/blankslate.rb +51 -0
- data/lib/carat-dev/breakpoint.rb +518 -0
- data/lib/carat-dev/class-constructor/constructor_methods.rb +78 -0
- data/lib/carat-dev/class-constructor/tc_constructor.rb +35 -0
- data/lib/carat-dev/closecall/closecall-test.rb +39 -0
- data/lib/carat-dev/closecall/closecall.rb +101 -0
- data/lib/carat-dev/commandrunner/commandrunner.rb +100 -0
- data/lib/carat-dev/conditional/conditionals.rb +106 -0
- data/lib/carat-dev/daemon/daemon.rb +70 -0
- data/lib/carat-dev/detach/detach.rb +363 -0
- data/lib/carat-dev/detach/tc_detach.rb +57 -0
- data/lib/carat-dev/import-module/import-module-0.81.tar.gz +0 -0
- data/lib/carat-dev/import-module/import-module-0.81/LICENSE +1 -0
- data/lib/carat-dev/import-module/import-module-0.81/Makefile +11 -0
- data/lib/carat-dev/import-module/import-module-0.81/README +4 -0
- data/lib/carat-dev/import-module/import-module-0.81/dev-lib/import-module-hash.rb +49 -0
- data/lib/carat-dev/import-module/import-module-0.81/dev-lib/import-module-pip.rb +71 -0
- data/lib/carat-dev/import-module/import-module-0.81/dev-lib/import-module-unbound-method.rb +36 -0
- data/lib/carat-dev/import-module/import-module-0.81/doc/README-ja.html +293 -0
- data/lib/carat-dev/import-module/import-module-0.81/doc/README-ja.rd +306 -0
- data/lib/carat-dev/import-module/import-module-0.81/doc/README.html +290 -0
- data/lib/carat-dev/import-module/import-module-0.81/doc/README.rd +303 -0
- data/lib/carat-dev/import-module/import-module-0.81/doc/style.css +85 -0
- data/lib/carat-dev/import-module/import-module-0.81/install.rb +99 -0
- data/lib/carat-dev/import-module/import-module-0.81/lib/import-module-single-thread.rb +84 -0
- data/lib/carat-dev/import-module/import-module-0.81/lib/import-module.rb +493 -0
- data/lib/carat-dev/import-module/import-module-0.81/test/Makefile +2 -0
- data/lib/carat-dev/import-module/import-module-0.81/test/test +91 -0
- data/lib/carat-dev/import-module/import-module-0.81/test/test-import-module.rb +936 -0
- data/lib/carat-dev/import-module/import-module-0.81/test/test-import_scope.rb +33 -0
- data/lib/carat-dev/import-module/import-module-0.81/test/test-scope_import.rb +33 -0
- data/lib/carat-dev/import-module/import-module-0.81/test/test-time.rb +184 -0
- data/lib/carat-dev/import-module/import-module-0.81/test/test.sh +91 -0
- data/lib/carat-dev/import-module/import-module-0.81/test/time.rb +135 -0
- data/lib/carat-dev/import-module/import-module-0.81/test/times-do.sh +10 -0
- data/lib/carat-dev/interface_work/SCRAP/i-contracts.rb +37 -0
- data/lib/carat-dev/interface_work/SCRAP/interface.rb +105 -0
- data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0.zip +0 -0
- data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/CHANGES +3 -0
- data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/MANIFEST +15 -0
- data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/README +32 -0
- data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/doc/interface.rd +73 -0
- data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/doc/interface.txt +94 -0
- data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/install.rb +16 -0
- data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/lib/interface.rb +50 -0
- data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/test/tc_interface.rb +51 -0
- data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/test/test.rb +29 -0
- data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/test/test_instance.rb +24 -0
- data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/test/test_sub.rb +29 -0
- data/lib/carat-dev/interface_work/SCRAP/j-interface/interface-0.1.0/test/test_unrequire.rb +28 -0
- data/lib/carat-dev/interface_work/contracts/contract.zip +0 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.html +376 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.src/M000001.html +23 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.src/M000002.html +18 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.src/M000003.html +19 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.src/M000004.html +29 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.src/M000005.html +18 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract.src/M000006.html +18 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract/ContractError.html +142 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract/ContractException.html +153 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Contract/ContractMismatch.html +125 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Module.html +157 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/classes/Module.src/M000007.html +112 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/created.rid +1 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/files/lib/contract/assertions_rb.html +109 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/files/lib/contract/exception_rb.html +108 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/files/lib/contract/integration_rb.html +108 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/files/lib/contract/overrides_rb.html +109 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/files/lib/contract_rb.html +114 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/fr_class_index.html +31 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/fr_file_index.html +31 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/fr_method_index.html +33 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/index.html +24 -0
- data/lib/carat-dev/interface_work/contracts/contract/doc/rdoc-style.css +208 -0
- data/lib/carat-dev/interface_work/contracts/contract/lib/contract.rb +88 -0
- data/lib/carat-dev/interface_work/contracts/contract/lib/contract/assertions.rb +37 -0
- data/lib/carat-dev/interface_work/contracts/contract/lib/contract/exception.rb +92 -0
- data/lib/carat-dev/interface_work/contracts/contract/lib/contract/integration.rb +132 -0
- data/lib/carat-dev/interface_work/contracts/contract/lib/contract/overrides.rb +32 -0
- data/lib/carat-dev/interface_work/must.rb +37 -0
- data/lib/carat-dev/interface_work/type.rb +232 -0
- data/lib/carat-dev/main/tc_toplevel.rb +23 -0
- data/lib/carat-dev/main/toplevel.rb +33 -0
- data/lib/carat-dev/main/toplevel_test.rb +24 -0
- data/lib/carat-dev/misc/1.rb +40 -0
- data/lib/carat-dev/misc/misc.rb +44 -0
- data/lib/carat-dev/misc/sys.rb +186 -0
- data/lib/carat-dev/misc/temp.rb +1 -0
- data/lib/carat-dev/misc/utils.rb +518 -0
- data/lib/carat-dev/predicate/predicate.rb +109 -0
- data/lib/carat-dev/predicate/predicate_test.rb +67 -0
- data/lib/carat-dev/premshree.rb +40 -0
- data/lib/carat-dev/priority-queue/pqueue.rb +183 -0
- data/lib/carat-dev/priority-queue/priorityqueue.rb +84 -0
- data/lib/carat-dev/quaternion/quaternion.rb +529 -0
- data/lib/carat-dev/range.rb +259 -0
- data/lib/carat-dev/system/rubyinfo.rb +75 -0
- data/lib/carat-dev/system/system.rb +105 -0
- data/lib/carat-dev/tc_range.rb +118 -0
- data/lib/carat-dev/timer/timer-doc/classes/Timer.html +291 -0
- data/lib/carat-dev/timer/timer-doc/classes/Timer.src/M000001.html +26 -0
- data/lib/carat-dev/timer/timer-doc/classes/Timer.src/M000002.html +19 -0
- data/lib/carat-dev/timer/timer-doc/classes/Timer.src/M000003.html +18 -0
- data/lib/carat-dev/timer/timer-doc/classes/Timer.src/M000004.html +18 -0
- data/lib/carat-dev/timer/timer-doc/classes/Timer.src/M000005.html +21 -0
- data/lib/carat-dev/timer/timer-doc/classes/Timer.src/M000006.html +23 -0
- data/lib/carat-dev/timer/timer-doc/created.rid +1 -0
- data/lib/carat-dev/timer/timer-doc/files/timer_rb.html +144 -0
- data/lib/carat-dev/timer/timer-doc/fr_class_index.html +27 -0
- data/lib/carat-dev/timer/timer-doc/fr_file_index.html +27 -0
- data/lib/carat-dev/timer/timer-doc/fr_method_index.html +32 -0
- data/lib/carat-dev/timer/timer-doc/index.html +24 -0
- data/lib/carat-dev/timer/timer-doc/rdoc-style.css +208 -0
- data/lib/carat-dev/timer/timer.rb +160 -0
- data/lib/carat-dev/vars/vars.rb +62 -0
- data/lib/carat/1st.rb +58 -0
- data/lib/carat/ansicolor.rb +122 -0
- data/lib/carat/attr.rb +342 -0
- data/lib/carat/bbcode.rb +352 -0
- data/lib/carat/binaryreader.rb +170 -0
- data/lib/carat/binding-of-caller.rb +83 -0
- data/lib/carat/byteorder.rb +34 -0
- data/lib/carat/constant.rb +287 -0
- data/lib/carat/coroutine.rb +102 -0
- data/lib/carat/crosscase.rb +309 -0
- data/lib/carat/duckhunter.rb +158 -0
- data/lib/carat/dynamic-mixin.rb +71 -0
- data/lib/carat/enumerable-args.rb +125 -0
- data/lib/carat/expect.rb +192 -0
- data/lib/carat/filelist.rb +277 -0
- data/lib/carat/floatstring.rb +153 -0
- data/lib/carat/functor.rb +41 -0
- data/lib/carat/harray.rb +507 -0
- data/lib/carat/heap.rb +193 -0
- data/lib/carat/html-helpers.rb +82 -0
- data/lib/carat/infinity.rb +61 -0
- data/lib/carat/init.rb +33 -0
- data/lib/carat/interval.rb +248 -0
- data/lib/carat/io-reactor.rb +657 -0
- data/lib/carat/io-redirect.rb +99 -0
- data/lib/carat/lisp-format.rb +1832 -0
- data/lib/carat/lisp.rb +336 -0
- data/lib/carat/macro.rb +68 -0
- data/lib/carat/multiton.rb +153 -0
- data/lib/carat/nack.rb +115 -0
- data/lib/carat/nil-comparable.rb +67 -0
- data/lib/carat/nil-missing.rb +12 -0
- data/lib/carat/notcopyable.rb +68 -0
- data/lib/carat/orderedhash.rb +249 -0
- data/lib/carat/ostructable.rb +138 -0
- data/lib/carat/parser-old.rb +350 -0
- data/lib/carat/parser.rb +393 -0
- data/lib/carat/ref.rb +31 -0
- data/lib/carat/semaphore.rb +69 -0
- data/lib/carat/snapshot.rb +94 -0
- data/lib/carat/soundex.rb +104 -0
- data/lib/carat/sstruct.rb +223 -0
- data/lib/carat/statichash.rb +49 -0
- data/lib/carat/tagiter.rb +345 -0
- data/lib/carat/timelimit.rb +114 -0
- data/lib/carat/timer.rb +99 -0
- data/lib/carat/tracepoint.rb +154 -0
- data/lib/carat/tuple.rb +31 -0
- data/lib/carat/uninheritable.rb +68 -0
- data/lib/carat/version.rb +147 -0
- data/pub/doc/sstruct.txt +204 -0
- data/pub/doc/tagiter.html +145 -0
- data/setup.rb +1361 -0
- data/test/fixtures/filelist/testfile.txt +1 -0
- data/test/fixtures/filelist/testfile2.txt +1 -0
- data/test/tc_1st.rb +16 -0
- data/test/tc_ansicolor.rb +23 -0
- data/test/tc_attr.rb +46 -0
- data/test/tc_bbcode.rb +20 -0
- data/test/tc_binaryreader.rb +14 -0
- data/test/tc_binding_of_caller.rb +2 -0
- data/test/tc_byteorder.rb +41 -0
- data/test/tc_constant.rb +12 -0
- data/test/tc_coroutine.rb +50 -0
- data/test/tc_crosscase.rb +33 -0
- data/test/tc_duckhunter.rb +37 -0
- data/test/tc_dynamic-mixin.rb +66 -0
- data/test/tc_enumerable-args.rb +66 -0
- data/test/tc_expect.rb +83 -0
- data/test/tc_filelist.rb +17 -0
- data/test/tc_floatstring.rb +22 -0
- data/test/tc_functor.rb +18 -0
- data/test/tc_harray.rb +280 -0
- data/test/tc_heap.rb +6 -0
- data/test/tc_infinity.rb +23 -0
- data/test/tc_init.rb +29 -0
- data/test/tc_interval.rb +153 -0
- data/test/tc_io-reactor.rb +5 -0
- data/test/tc_io-redirect.rb +5 -0
- data/test/tc_lisp-format.rb +24 -0
- data/test/tc_lisp.rb +32 -0
- data/test/tc_macro.rb +48 -0
- data/test/tc_multiton.rb +188 -0
- data/test/tc_nack.rb +31 -0
- data/test/tc_nil-as-emptiness.rb +19 -0
- data/test/tc_nil-comparable.rb +29 -0
- data/test/tc_nil-missing.rb +0 -0
- data/test/tc_notcopyable.rb +64 -0
- data/test/tc_orderedhash.rb +36 -0
- data/test/tc_ostructable.rb +31 -0
- data/test/tc_semaphore.rb +5 -0
- data/test/tc_snapshot.rb +20 -0
- data/test/tc_soundex.rb +19 -0
- data/test/tc_sstruct.rb +313 -0
- data/test/tc_statichash.rb +24 -0
- data/test/tc_tagiter.rb +80 -0
- data/test/tc_timelimit.rb +47 -0
- data/test/tc_timer.rb +35 -0
- data/test/tc_tracepoint.rb +10 -0
- data/test/tc_tuple.rb +25 -0
- data/test/tc_uninheritable.rb +33 -0
- data/test/tc_version.rb +90 -0
- metadata +531 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
|
|
2
|
+
body {
|
|
3
|
+
font-family: Verdana,Arial,Helvetica,sans-serif;
|
|
4
|
+
font-size: 90%;
|
|
5
|
+
margin: 0;
|
|
6
|
+
margin-left: 40px;
|
|
7
|
+
padding: 0;
|
|
8
|
+
background: white;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
|
|
12
|
+
h1 { font-size: 150%; }
|
|
13
|
+
h2,h3,h4 { margin-top: 1em; }
|
|
14
|
+
|
|
15
|
+
a { background: #eef; color: #039; text-decoration: none; }
|
|
16
|
+
a:hover { background: #039; color: #eef; }
|
|
17
|
+
|
|
18
|
+
/* Override the base stylesheet's Anchor inside a table cell */
|
|
19
|
+
td > a {
|
|
20
|
+
background: transparent;
|
|
21
|
+
color: #039;
|
|
22
|
+
text-decoration: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* and inside a section title */
|
|
26
|
+
.section-title > a {
|
|
27
|
+
background: transparent;
|
|
28
|
+
color: #eee;
|
|
29
|
+
text-decoration: none;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* === Structural elements =================================== */
|
|
33
|
+
|
|
34
|
+
div#index {
|
|
35
|
+
margin: 0;
|
|
36
|
+
margin-left: -40px;
|
|
37
|
+
padding: 0;
|
|
38
|
+
font-size: 90%;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
div#index a {
|
|
43
|
+
margin-left: 0.7em;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
div#index .section-bar {
|
|
47
|
+
margin-left: 0px;
|
|
48
|
+
padding-left: 0.7em;
|
|
49
|
+
background: #ccc;
|
|
50
|
+
font-size: small;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
div#classHeader, div#fileHeader {
|
|
55
|
+
width: auto;
|
|
56
|
+
color: white;
|
|
57
|
+
padding: 0.5em 1.5em 0.5em 1.5em;
|
|
58
|
+
margin: 0;
|
|
59
|
+
margin-left: -40px;
|
|
60
|
+
border-bottom: 3px solid #006;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
div#classHeader a, div#fileHeader a {
|
|
64
|
+
background: inherit;
|
|
65
|
+
color: white;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
div#classHeader td, div#fileHeader td {
|
|
69
|
+
background: inherit;
|
|
70
|
+
color: white;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
div#fileHeader {
|
|
75
|
+
background: #057;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
div#classHeader {
|
|
79
|
+
background: #048;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
.class-name-in-header {
|
|
84
|
+
font-size: 180%;
|
|
85
|
+
font-weight: bold;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
div#bodyContent {
|
|
90
|
+
padding: 0 1.5em 0 1.5em;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
div#description {
|
|
94
|
+
padding: 0.5em 1.5em;
|
|
95
|
+
background: #efefef;
|
|
96
|
+
border: 1px dotted #999;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
div#description h1,h2,h3,h4,h5,h6 {
|
|
100
|
+
color: #125;;
|
|
101
|
+
background: transparent;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
div#validator-badges {
|
|
105
|
+
text-align: center;
|
|
106
|
+
}
|
|
107
|
+
div#validator-badges img { border: 0; }
|
|
108
|
+
|
|
109
|
+
div#copyright {
|
|
110
|
+
color: #333;
|
|
111
|
+
background: #efefef;
|
|
112
|
+
font: 0.75em sans-serif;
|
|
113
|
+
margin-top: 5em;
|
|
114
|
+
margin-bottom: 0;
|
|
115
|
+
padding: 0.5em 2em;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
/* === Classes =================================== */
|
|
120
|
+
|
|
121
|
+
table.header-table {
|
|
122
|
+
color: white;
|
|
123
|
+
font-size: small;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.type-note {
|
|
127
|
+
font-size: small;
|
|
128
|
+
color: #DEDEDE;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.xxsection-bar {
|
|
132
|
+
background: #eee;
|
|
133
|
+
color: #333;
|
|
134
|
+
padding: 3px;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.section-bar {
|
|
138
|
+
color: #333;
|
|
139
|
+
border-bottom: 1px solid #999;
|
|
140
|
+
margin-left: -20px;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
.section-title {
|
|
145
|
+
background: #79a;
|
|
146
|
+
color: #eee;
|
|
147
|
+
padding: 3px;
|
|
148
|
+
margin-top: 2em;
|
|
149
|
+
margin-left: -30px;
|
|
150
|
+
border: 1px solid #999;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.top-aligned-row { vertical-align: top }
|
|
154
|
+
.bottom-aligned-row { vertical-align: bottom }
|
|
155
|
+
|
|
156
|
+
/* --- Context section classes ----------------------- */
|
|
157
|
+
|
|
158
|
+
.context-row { }
|
|
159
|
+
.context-item-name { font-family: monospace; font-weight: bold; color: black; }
|
|
160
|
+
.context-item-value { font-size: small; color: #448; }
|
|
161
|
+
.context-item-desc { color: #333; padding-left: 2em; }
|
|
162
|
+
|
|
163
|
+
/* --- Method classes -------------------------- */
|
|
164
|
+
.method-detail {
|
|
165
|
+
background: #efefef;
|
|
166
|
+
padding: 0;
|
|
167
|
+
margin-top: 0.5em;
|
|
168
|
+
margin-bottom: 1em;
|
|
169
|
+
border: 1px dotted #ccc;
|
|
170
|
+
}
|
|
171
|
+
.method-heading {
|
|
172
|
+
color: black;
|
|
173
|
+
background: #ccc;
|
|
174
|
+
border-bottom: 1px solid #666;
|
|
175
|
+
padding: 0.2em 0.5em 0 0.5em;
|
|
176
|
+
}
|
|
177
|
+
.method-signature { color: black; background: inherit; }
|
|
178
|
+
.method-name { font-weight: bold; }
|
|
179
|
+
.method-args { font-style: italic; }
|
|
180
|
+
.method-description { padding: 0 0.5em 0 0.5em; }
|
|
181
|
+
|
|
182
|
+
/* --- Source code sections -------------------- */
|
|
183
|
+
|
|
184
|
+
a.source-toggle { font-size: 90%; }
|
|
185
|
+
div.method-source-code {
|
|
186
|
+
background: #262626;
|
|
187
|
+
color: #ffdead;
|
|
188
|
+
margin: 1em;
|
|
189
|
+
padding: 0.5em;
|
|
190
|
+
border: 1px dashed #999;
|
|
191
|
+
overflow: hidden;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
div.method-source-code pre { color: #ffdead; overflow: hidden; }
|
|
195
|
+
|
|
196
|
+
/* --- Ruby keyword styles --------------------- */
|
|
197
|
+
|
|
198
|
+
.standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
|
|
199
|
+
|
|
200
|
+
.ruby-constant { color: #7fffd4; background: transparent; }
|
|
201
|
+
.ruby-keyword { color: #00ffff; background: transparent; }
|
|
202
|
+
.ruby-ivar { color: #eedd82; background: transparent; }
|
|
203
|
+
.ruby-operator { color: #00ffee; background: transparent; }
|
|
204
|
+
.ruby-identifier { color: #ffdead; background: transparent; }
|
|
205
|
+
.ruby-node { color: #ffa07a; background: transparent; }
|
|
206
|
+
.ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
|
|
207
|
+
.ruby-regexp { color: #ffa07a; background: transparent; }
|
|
208
|
+
.ruby-value { color: #7fffd4; background: transparent; }
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require 'test/unit/testcase'
|
|
2
|
+
require 'test/unit/testresult'
|
|
3
|
+
require 'test/unit/testsuite'
|
|
4
|
+
|
|
5
|
+
require 'contract/exception'
|
|
6
|
+
require 'contract/overrides'
|
|
7
|
+
require 'contract/assertions'
|
|
8
|
+
require 'contract/integration'
|
|
9
|
+
|
|
10
|
+
# Represents a contract between Objects as a collection of test cases.
|
|
11
|
+
# Objects are said to fulfill a contract if all test cases suceed. This
|
|
12
|
+
# is useful for ensuring that Objects your code is getting behave in a
|
|
13
|
+
# way that you expect them to behave so you can fail early or execute
|
|
14
|
+
# different logic for Objects with different interfaces.
|
|
15
|
+
#
|
|
16
|
+
# The tests of the test suite will be run on a copy of the tested Object
|
|
17
|
+
# so you can safely test its behavior without having to fear data loss.
|
|
18
|
+
# By default Contracts obtain deep copies of Objects by serializing and
|
|
19
|
+
# unserializing them with Ruby's +Marshal+ functionality. This will work
|
|
20
|
+
# in most cases but can fail for Objects containing unserializable parts
|
|
21
|
+
# like Procs, Files or Sockets. In those cases it is currently of your
|
|
22
|
+
# responsibility to provide a fitting implementation by overwriting the
|
|
23
|
+
# Contract.deep_copy method. In the future the contract library might
|
|
24
|
+
# provide different implementations of it via Ruby's mixin mechanism.
|
|
25
|
+
class Contract < Test::Unit::TestCase
|
|
26
|
+
id = %q$Id: contract.rb 52 2005-01-26 16:19:39Z flgr $
|
|
27
|
+
# The Version of the contract library you are using.
|
|
28
|
+
Version = id.split(" ")[2].to_i
|
|
29
|
+
|
|
30
|
+
# Returns true if the given object fulfills this contract.
|
|
31
|
+
# This is useful for implementing dispatching mechanisms where you
|
|
32
|
+
# want to hit different code branches based on whether an Object has
|
|
33
|
+
# one or another interface.
|
|
34
|
+
def self.fulfilled_by?(object)
|
|
35
|
+
self.test(object).nil?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class << self
|
|
39
|
+
alias :=== :fulfilled_by?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Enforces that object implements this contract. If it does not an
|
|
43
|
+
# Exception will be raised. This is useful for example useful when
|
|
44
|
+
# you need to ensure that the arguments given to a method fulfill a
|
|
45
|
+
# given contract.
|
|
46
|
+
def self.enforce(object)
|
|
47
|
+
reason = self.test(object)
|
|
48
|
+
raise reason if reason
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Tests whether the given Object fulfils this contract.
|
|
52
|
+
#
|
|
53
|
+
# Note: This will return the first reason for the Object not fulfilling
|
|
54
|
+
# the contract or +nil+ in case it fulfills it.
|
|
55
|
+
def self.test(object, return_all = false)
|
|
56
|
+
reasons = []
|
|
57
|
+
|
|
58
|
+
result = Test::Unit::TestResult.new
|
|
59
|
+
result.add_listener(Test::Unit::TestResult::FAULT) do |fault|
|
|
60
|
+
reason = Contract.fault_to_exception(fault, object, self)
|
|
61
|
+
return reason unless return_all
|
|
62
|
+
reasons << reason
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
self.suite.run(result, object)
|
|
66
|
+
|
|
67
|
+
return reasons unless result.passed?
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Same as Contract.test, but will return all reasons for the Object not
|
|
71
|
+
# fulfilling the contract in an Array or nil in case of fulfillment.
|
|
72
|
+
# (as an Array of Exceptions) or +nil+ in the case it does fulfill it.
|
|
73
|
+
def self.test_all(object)
|
|
74
|
+
test(object, true)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# This method is used internally for getting a copy of Objects that
|
|
78
|
+
# the contract is checked against. By default it uses Ruby's +Marshal+
|
|
79
|
+
# functionality for obtaining a copy, but this can fail if the Object
|
|
80
|
+
# contains unserializable parts like Procs, Files or Sockets. It is
|
|
81
|
+
# currently your responsibility to provide a fitting implementation
|
|
82
|
+
# of this by overwriting the method in case the default implementation
|
|
83
|
+
# does not work for you. In the future the contract library might offer
|
|
84
|
+
# different implementations for this via Ruby's mixin mechanism.
|
|
85
|
+
def self.deep_copy(object)
|
|
86
|
+
Marshal.load(Marshal.dump(object))
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# This file provides a few new assertions and class methods for expressing
|
|
2
|
+
# contracts in a comfortable way that does not require manually writing test
|
|
3
|
+
# methods.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Contract < Test::Unit::TestCase
|
|
7
|
+
# Tests that the tested Object provides the specified methods with
|
|
8
|
+
# the specified behavior.
|
|
9
|
+
#
|
|
10
|
+
# This can be used like this:
|
|
11
|
+
# class ListContract < Contract
|
|
12
|
+
# provides :size do
|
|
13
|
+
# assert(@object.size >= 0, "#size should never be negative.")
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# provides :include?
|
|
17
|
+
#
|
|
18
|
+
# provides :each do
|
|
19
|
+
# count = 0
|
|
20
|
+
# @object.each do |item|
|
|
21
|
+
# assert(@object.include?(item),
|
|
22
|
+
# "#each should only yield items that the list includes.")
|
|
23
|
+
# count += 1
|
|
24
|
+
# end
|
|
25
|
+
# assert_equal(@object.size, count,
|
|
26
|
+
# "#each should yield #size items.")
|
|
27
|
+
# end
|
|
28
|
+
# end
|
|
29
|
+
def self.provides(*symbols, &block)
|
|
30
|
+
symbols.each do |symbol|
|
|
31
|
+
define_method(:"test_provides_#{symbol}") do
|
|
32
|
+
assert_respond_to(@object, symbol)
|
|
33
|
+
instance_eval(&block) if block
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# This file contains things needed to map Test::Unit status objects to
|
|
2
|
+
# Exceptions, Exception related infrastructure and similar things.
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Contract < Test::Unit::TestCase
|
|
6
|
+
# Exceptions raised by Contract contain some usual meta-information.
|
|
7
|
+
# This module is mixed into Exceptions that provide such information.
|
|
8
|
+
module ContractException
|
|
9
|
+
def ce_initialize(original_message, backtrace, test_object,
|
|
10
|
+
test_method, test_contract, *more) # :nodoc:
|
|
11
|
+
@original_message = original_message
|
|
12
|
+
message = original_message.dup
|
|
13
|
+
detail = " for #{test_object.inspect} in " +
|
|
14
|
+
"#{test_contract.inspect}"
|
|
15
|
+
message[/(\s*)[.!?]?\s*\Z/, 1] = detail
|
|
16
|
+
Exception.instance_method(:initialize).bind(self).call(message)
|
|
17
|
+
|
|
18
|
+
set_backtrace(backtrace)
|
|
19
|
+
@test_object = test_object
|
|
20
|
+
@test_method = test_method
|
|
21
|
+
@test_contract = test_contract
|
|
22
|
+
end
|
|
23
|
+
private :ce_initialize
|
|
24
|
+
|
|
25
|
+
# What object was tested when this Exception was raised?
|
|
26
|
+
attr_reader :test_object
|
|
27
|
+
# What method implemented that test?
|
|
28
|
+
attr_reader :test_method
|
|
29
|
+
# What contract was that method part of?
|
|
30
|
+
attr_reader :test_contract
|
|
31
|
+
# The original, unfiltered exception message.
|
|
32
|
+
attr_reader :original_message
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Represents a failed test in a contract. This means that an object
|
|
36
|
+
# simply does not fulfill one of the parts of a contract. Subclass of
|
|
37
|
+
# TypeError.
|
|
38
|
+
class ContractMismatch < TypeError
|
|
39
|
+
def initialize(*args) # :nodoc:
|
|
40
|
+
ce_initialize(*args)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
include ContractException
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Represents an unexpected failure while processing a contract test.
|
|
47
|
+
# This is more critical than ContractMismatch and usually means that
|
|
48
|
+
# something is wrong with the test itself.
|
|
49
|
+
class ContractError < StandardError
|
|
50
|
+
def initialize(*args) # :nodoc:
|
|
51
|
+
@type = args.pop
|
|
52
|
+
ce_initialize(*args)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# The type of the original Exception that triggered the unexpected
|
|
56
|
+
# failure.
|
|
57
|
+
attr_reader :type
|
|
58
|
+
|
|
59
|
+
include ContractException
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# Maps a Test::Unit::Failure instance to an actual Exception with the
|
|
64
|
+
# specified meta data.
|
|
65
|
+
def self.failure_to_exception(failure, object, contract) # :nodoc:
|
|
66
|
+
ContractMismatch.new(failure.message, failure.location, object,
|
|
67
|
+
extract_method_name(failure.test_name), contract)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Maps a Test::Unit::Error instance to an actual Exception with the
|
|
71
|
+
# specified meta data.
|
|
72
|
+
def self.error_to_exception(error, object, contract) # :nodoc:
|
|
73
|
+
original = error.exception
|
|
74
|
+
ContractError.new(original.message, original.backtrace, object,
|
|
75
|
+
extract_method_name(error.test_name), contract, original.class)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Maps a Test::Unit fault (either a Failure or Error) to an actual
|
|
79
|
+
# exception with the specified meta data.
|
|
80
|
+
def self.fault_to_exception(fault, *args) # :nodoc:
|
|
81
|
+
if fault.is_a?(Test::Unit::Failure) then
|
|
82
|
+
failure_to_exception(fault, *args)
|
|
83
|
+
else
|
|
84
|
+
error_to_exception(fault, *args)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Extracts the method name from a Test::Unit test_name style String.
|
|
89
|
+
def self.extract_method_name(test_name) # :nodoc:
|
|
90
|
+
test_name[/\A(.+?)\(.+?\)\Z/, 1]
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# This file contains code for integrating the contract library with built-in
|
|
2
|
+
# classes and methods.
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Contract < Test::Unit::TestCase
|
|
6
|
+
class << self
|
|
7
|
+
# Whether signatures should be checked. By default signatures are checked
|
|
8
|
+
# only when the application is run in $DEBUG mode. (By specifying the -d
|
|
9
|
+
# switch on the invocation of Ruby.)
|
|
10
|
+
#
|
|
11
|
+
# Note: If you want to change this you need to do so before doing any
|
|
12
|
+
# signature calls or it will not be applied.
|
|
13
|
+
attr_accessor :check_signatures
|
|
14
|
+
alias :check_signatures? :check_signatures
|
|
15
|
+
end
|
|
16
|
+
self.check_signatures = $DEBUG if self.check_signatures.nil?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class Module
|
|
20
|
+
# Checks that the arguments and return value of a method match the
|
|
21
|
+
# specified signature.
|
|
22
|
+
#
|
|
23
|
+
# Usage:
|
|
24
|
+
# signature(:to_s) # no arguments
|
|
25
|
+
# signature(:+, :any) # one argument, type unchecked
|
|
26
|
+
# signature(:+, Fixnum) # one argument, type Fixnum
|
|
27
|
+
# signature(:+, NumericContract)
|
|
28
|
+
# signature(:+, 1 .. 10)
|
|
29
|
+
#
|
|
30
|
+
# signature(:each, :block => true) # has to have block
|
|
31
|
+
# signature(:to_i, :block => false) # not allowd to have block
|
|
32
|
+
# signature(:to_i, :result => Fixnum) # return value must be Fixnum
|
|
33
|
+
# signature(:zip, :allow_trailing => true) # unchecked trailing args
|
|
34
|
+
# signature(:zip, :repeated => [Enumerable]) # repeated trailing args
|
|
35
|
+
def signature(method, *args)
|
|
36
|
+
return unless Contract.check_signatures?
|
|
37
|
+
|
|
38
|
+
options = {}
|
|
39
|
+
signature = args.dup
|
|
40
|
+
options.update(signature.pop) if signature.last.is_a?(Hash)
|
|
41
|
+
|
|
42
|
+
old_method = instance_method(method)
|
|
43
|
+
remove_method(method)
|
|
44
|
+
|
|
45
|
+
if old_method.arity < signature.size then
|
|
46
|
+
raise(ArgumentError, "signature isn't compatible with arity")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if options.include?(:repeated)
|
|
50
|
+
if options[:repeated].size == 0 then
|
|
51
|
+
raise(ArgumentError, "repeated arguments may not be an empty Array")
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# We need to keep around references to our arguments because we will
|
|
56
|
+
# need to access them via ObjectSpace._id2ref so that they do not
|
|
57
|
+
# get garbage collected.
|
|
58
|
+
@signatures ||= Hash.new
|
|
59
|
+
@signatures[method] = args + [method]
|
|
60
|
+
|
|
61
|
+
# We have to use class_eval so that signatures can be specified for
|
|
62
|
+
# methods taking blocks in Ruby 1.8. (This will be obsolete in 1.9)
|
|
63
|
+
# We also make the checks as efficient as we can.
|
|
64
|
+
class_eval %{
|
|
65
|
+
def #{method}(*args, &block)
|
|
66
|
+
old_args = args.dup
|
|
67
|
+
|
|
68
|
+
#{if options.include?(:block) then
|
|
69
|
+
if options[:block] then
|
|
70
|
+
%{raise(ArgumentError, "no block given") unless block}
|
|
71
|
+
else
|
|
72
|
+
%{raise(ArgumentError, "block given") if block}
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
#{unless options[:allow_trailing] or options.include?(:repeated)
|
|
78
|
+
msg = "wrong number of arguments (\#{args.size} for " +
|
|
79
|
+
"#{signature.size})"
|
|
80
|
+
%{if args.size != #{signature.size} then
|
|
81
|
+
raise(ArgumentError, "#{msg}")
|
|
82
|
+
end
|
|
83
|
+
}
|
|
84
|
+
else
|
|
85
|
+
msg = "wrong number of arguments (\#{args.size} for " +
|
|
86
|
+
"at least #{signature.size}"
|
|
87
|
+
%{if args.size < #{signature.size} then
|
|
88
|
+
raise(ArgumentError, "#{msg}")
|
|
89
|
+
end
|
|
90
|
+
}
|
|
91
|
+
end
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
#{index = 0
|
|
95
|
+
signature.map do |part|
|
|
96
|
+
next if part == :any
|
|
97
|
+
index += 1
|
|
98
|
+
msg = "argument #{index} (\#{arg.inspect}) does not match " +
|
|
99
|
+
"#{part.inspect}"
|
|
100
|
+
%{unless ObjectSpace._id2ref(#{part.object_id}) === (arg = args.shift)
|
|
101
|
+
raise(ArgumentError, "#{msg}")
|
|
102
|
+
end
|
|
103
|
+
}
|
|
104
|
+
end
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
#{if repeated = options[:repeated] then %{
|
|
108
|
+
%{args.each_with_index do |arg, index|
|
|
109
|
+
part = ObjectSpace._id2ref(#{repeated.object_id})
|
|
110
|
+
if part != :any and not part[index % #{repeated.size}] === arg
|
|
111
|
+
raise(ArgumentError, "argument \#{index + #{signature.size}}" +
|
|
112
|
+
"(\#{arg.inspect}) does not match \#{part.inspect}")
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
}
|
|
116
|
+
} end
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
result = ObjectSpace._id2ref(#{old_method.object_id}).bind(self).
|
|
120
|
+
call(*old_args, &block)
|
|
121
|
+
#{if rt = options[:return] and rt != :any then
|
|
122
|
+
msg = "return value (\#{result.inspect}) does not match #{rt.inspect}"
|
|
123
|
+
%{unless ObjectSpace._id2ref(#{rt.object_id}) === rt
|
|
124
|
+
raise(StandardError, "#{msg}")
|
|
125
|
+
end
|
|
126
|
+
}
|
|
127
|
+
end
|
|
128
|
+
}
|
|
129
|
+
end
|
|
130
|
+
}, "(signature check for #{old_method.inspect[/: (.+?)>\Z/, 1]})"
|
|
131
|
+
end
|
|
132
|
+
end
|