├── var ├── name ├── title ├── version ├── created ├── organizations ├── summary ├── authors ├── copyrights ├── repositories ├── requirements ├── description └── resources ├── lib ├── assay.yml ├── assay │ ├── core_ext │ │ ├── na.rb │ │ └── kernel.rb │ ├── nil_assay.rb │ ├── match_assay.rb │ ├── boolean_assay.rb │ ├── false_assay.rb │ ├── empty_assay.rb │ ├── file_assay.rb │ ├── path_assay.rb │ ├── like_assay.rb │ ├── instance_assay.rb │ ├── include_assay.rb │ ├── less_assay.rb │ ├── case_assay.rb │ ├── more_assay.rb │ ├── equality_assay.rb │ ├── kind_assay.rb │ ├── nomatch_assay.rb │ ├── directory_assay.rb │ ├── respond_assay.rb │ ├── true_assay.rb │ ├── stderr_assay.rb │ ├── stdout_assay.rb │ ├── equal_assay.rb │ ├── less_equal_assay.rb │ ├── more_equal_assay.rb │ ├── unequal_assay.rb │ ├── compare_assay.rb │ ├── within_assay.rb │ ├── output_assay.rb │ ├── adapter │ │ ├── minitest.rb │ │ └── testunit.rb │ ├── close_assay.rb │ ├── return_assay.rb │ ├── rescue_assay.rb │ ├── identity_assay.rb │ ├── silent_assay.rb │ ├── execution_assay.rb │ ├── throw_assay.rb │ ├── raise_assay.rb │ ├── assertion.rb │ ├── assertor.rb │ └── assertable.rb └── assay.rb ├── Gemfile ├── demo ├── applique │ ├── setup.rb │ └── helper.rb ├── 01_assay_classes │ ├── 00_introduction.md │ ├── 21_empty_assay.md │ ├── 10_match_assay.md │ ├── 22_respond_assay.md │ ├── 18_kind_assay.md │ ├── 19_instance_assay.md │ ├── 20_include_assay.md │ ├── 27_path_assay.md │ ├── 29_file_assay.md │ ├── 11_nomatch_assay.md │ ├── 03_true_assay.md │ ├── 05_equal_assay.md │ ├── 03_false_assay.md │ ├── 07_equality_assay.md │ ├── 28_directory_assay.md │ ├── 31_stdout_assay.md │ ├── 04_like_assay.md │ ├── 09_case_assay.md │ ├── 32_stderr_assay.md │ ├── 01_nil_assay.md │ ├── 12_compare_assay.md │ ├── 02_boolean_assay.md │ ├── 08_identity_assay.md │ ├── 06_unequal_assay.md │ ├── 13_less_assay.md │ ├── 14_more_assay.md │ ├── 16_more_equal_assay.md │ ├── 15_less_equal_assay.md │ ├── 23_return_assay.md │ ├── 17_close_assay.md │ ├── 17_within_assay.md │ ├── 30_output_assay.md │ ├── 23_execution_assay.md │ ├── 25_raise_assay.md │ ├── 24_rescue_assay.md │ └── 26_throw_assay.md ├── 00_introduction.md ├── 02_lookup.md ├── 04_assay.md └── 03_assertor.md ├── work ├── defunct │ ├── static_assertion_methods │ │ └── matchers │ │ │ ├── rspec.rb │ │ │ ├── class.rb │ │ │ └── be.rb │ ├── assertable_module │ │ ├── assertable │ │ │ ├── nil.rb │ │ │ ├── false.rb │ │ │ ├── true.rb │ │ │ ├── compare.rb │ │ │ ├── match.rb │ │ │ ├── kind.rb │ │ │ ├── instance.rb │ │ │ ├── response.rb │ │ │ ├── identity.rb │ │ │ ├── raises.rb │ │ │ ├── execution.rb │ │ │ ├── delta.rb │ │ │ ├── returns.rb │ │ │ ├── same.rb │ │ │ └── equality.rb │ │ ├── assertions │ │ │ ├── operator.rb │ │ │ ├── false.rb │ │ │ ├── true.rb │ │ │ ├── nil.rb │ │ │ ├── instance_of.rb │ │ │ ├── match.rb │ │ │ ├── compare.rb │ │ │ ├── identity.rb │ │ │ ├── execution.rb │ │ │ ├── kind_of.rb │ │ │ ├── in_delta.rb │ │ │ ├── same.rb │ │ │ ├── equal.rb │ │ │ ├── respond_to.rb │ │ │ ├── sends.rb │ │ │ ├── returns.rb │ │ │ ├── raises.rb │ │ │ └── throws.rb │ │ ├── assertable.rb │ │ └── compare.rb │ ├── oldschool_matchers │ │ ├── be.rb │ │ └── is.rb │ ├── oldschool_extensions │ │ └── is.rb │ ├── complex_nomenclature_system │ │ ├── nomenclature │ │ │ ├── must.rb │ │ │ ├── shall.rb │ │ │ ├── should.rb │ │ │ ├── verify.rb │ │ │ ├── will.rb │ │ │ ├── expect.rb │ │ │ └── assert.rb │ │ └── nomenclature.rb │ ├── tobe.rb │ └── object-assays │ │ ├── assay.rb │ │ └── definitions.rb ├── benchmarks │ ├── mem_method.rb │ ├── mem_object.rb │ └── method_vs_object.rb └── consider │ ├── operator.rb │ ├── approx.rb │ ├── sends.rb │ └── return_failure.rb ├── .yardopts ├── .gitignore ├── .travis.yml ├── etc └── qed.rb ├── try ├── testunit │ └── example.rb └── qed │ └── 01_example.rdoc ├── .test ├── Assembly ├── test ├── helper.rb ├── case_empty_assay.rb ├── case_kind_assay.rb ├── case_identity_assay.rb ├── case_include_assay.rb ├── case_less_assay.rb ├── case_more_assay.rb ├── case_instance_assay.rb ├── case_match_assay.rb ├── case_equal_assay.rb ├── case_throw_assay.rb ├── case_nomatch_assay.rb ├── case_nil_assay.rb ├── case_respond_assay.rb ├── case_unequal_assay.rb ├── case_less_equal_assay.rb ├── case_more_equal_assay.rb ├── case_raise_assay.rb ├── case_true_assay.rb ├── case_equality_assay.rb ├── case_false_assay.rb ├── case_like_assay.rb ├── case_compare_assay.rb └── case_within_assay.rb ├── LICENSE.txt ├── .index ├── HISTORY.md ├── MANIFEST ├── README.md └── .gemspec /var/name: -------------------------------------------------------------------------------- 1 | assay 2 | -------------------------------------------------------------------------------- /lib/assay.yml: -------------------------------------------------------------------------------- 1 | ../.ruby -------------------------------------------------------------------------------- /var/title: -------------------------------------------------------------------------------- 1 | Assay 2 | -------------------------------------------------------------------------------- /var/version: -------------------------------------------------------------------------------- 1 | 0.4.1 2 | -------------------------------------------------------------------------------- /var/created: -------------------------------------------------------------------------------- 1 | 2010-11-14 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source :rubygems 2 | gemspec 3 | -------------------------------------------------------------------------------- /demo/applique/setup.rb: -------------------------------------------------------------------------------- 1 | require 'assay' 2 | -------------------------------------------------------------------------------- /var/organizations: -------------------------------------------------------------------------------- 1 | --- 2 | - Rubyworks 3 | -------------------------------------------------------------------------------- /var/summary: -------------------------------------------------------------------------------- 1 | Class-based Assertions Framework 2 | -------------------------------------------------------------------------------- /var/authors: -------------------------------------------------------------------------------- 1 | --- 2 | - Trans 3 | -------------------------------------------------------------------------------- /var/copyrights: -------------------------------------------------------------------------------- 1 | --- 2 | - 2010 Rubyworks (BSD-2-Clause) 3 | -------------------------------------------------------------------------------- /demo/01_assay_classes/00_introduction.md: -------------------------------------------------------------------------------- 1 | # Assay Classes 2 | 3 | -------------------------------------------------------------------------------- /demo/00_introduction.md: -------------------------------------------------------------------------------- 1 | Assay is an foundational assertion framework. 2 | 3 | -------------------------------------------------------------------------------- /var/repositories: -------------------------------------------------------------------------------- 1 | --- 2 | upstream: git@github.com:rubyworks/assay.git 3 | 4 | -------------------------------------------------------------------------------- /work/defunct/static_assertion_methods/matchers/rspec.rb: -------------------------------------------------------------------------------- 1 | require_relative 'be' 2 | -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --title "Assay" 2 | --readme README.rdoc 3 | --protected 4 | --private 5 | lib 6 | - 7 | [A-Z]*.* 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .fire/digest 2 | .yardoc 3 | doc 4 | log 5 | pkg 6 | site 7 | tmp 8 | web 9 | wiki 10 | work/trash 11 | DEMO.md 12 | -------------------------------------------------------------------------------- /var/requirements: -------------------------------------------------------------------------------- 1 | --- 2 | - ansi 3 | - brass 4 | - detroit (build) 5 | - ergo (build) 6 | - qed (test) 7 | - ae (test) 8 | 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: ruby 3 | script: "bundle exec qed" 4 | rvm: 5 | - 1.9.2 6 | - 1.9.3 7 | - rbx-19mode 8 | - jruby-19mode 9 | 10 | -------------------------------------------------------------------------------- /lib/assay/core_ext/na.rb: -------------------------------------------------------------------------------- 1 | 2 | class << NA = ArgumentError.new 3 | def inspect ; 'N/A' ; end 4 | def method_missing(*); self; end 5 | end 6 | 7 | def __ 8 | NA 9 | end 10 | -------------------------------------------------------------------------------- /var/description: -------------------------------------------------------------------------------- 1 | Assay defines assertions in the same way that Ruby defines exceptions. 2 | Each type of asserition, called an assay, is then a child of the base 3 | Assertion class, which itself is a subclass of the Exception class. 4 | -------------------------------------------------------------------------------- /lib/assay/nil_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'assertion' 2 | 3 | class NilAssay < Assertion 4 | 5 | register :nil 6 | 7 | # 8 | # Check assertion. 9 | # 10 | def self.pass?(subject) 11 | subject.nil? 12 | end 13 | 14 | end 15 | 16 | -------------------------------------------------------------------------------- /work/benchmarks/mem_method.rb: -------------------------------------------------------------------------------- 1 | n = 1000000 2 | 3 | class X 4 | def self.call(a,b) 5 | a == b 6 | end 7 | 8 | def initialize(a,b) 9 | @a = a 10 | @b = b 11 | end 12 | def call 13 | @a == @b 14 | end 15 | end 16 | 17 | n.times{ X.call(1,1) } 18 | 19 | -------------------------------------------------------------------------------- /work/benchmarks/mem_object.rb: -------------------------------------------------------------------------------- 1 | n = 1000000 2 | 3 | class X 4 | def self.call(a,b) 5 | a == b 6 | end 7 | 8 | def initialize(a,b) 9 | @a = a 10 | @b = b 11 | end 12 | def call 13 | @a == @b 14 | end 15 | end 16 | 17 | n.times{ X.new(1,1).call } 18 | 19 | -------------------------------------------------------------------------------- /etc/qed.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # 4 | # Setup QED to create coverage report. 5 | # 6 | QED.configure 'cov' do 7 | require 'simplecov' 8 | SimpleCov.start do 9 | coverage_dir 'log/coverage' 10 | #add_group "RSpec", "lib/assay/rspec.rb" 11 | end 12 | end 13 | 14 | -------------------------------------------------------------------------------- /try/testunit/example.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | require 'assay' 3 | require 'assay/adapters/testunit' 4 | 5 | class ExampleTest < Test::Unit::TestCase 6 | 7 | include Assay::Assertives 8 | 9 | def test_this 10 | assert_equal(1,2,"not this dingo!") 11 | end 12 | end 13 | 14 | -------------------------------------------------------------------------------- /lib/assay/match_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'like_assay' 2 | 3 | # 4 | # 5 | # 6 | class MatchAssay < LikeAssay 7 | 8 | register :=~, :match 9 | 10 | # 11 | # Check assertion for `#=~` method. 12 | # 13 | def self.pass?(matcher, matchee) 14 | matcher =~ matchee 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /.test: -------------------------------------------------------------------------------- 1 | Test.run(:default) do |run| 2 | require './test/helper' 3 | run.files << 'test/case_*.rb' 4 | end 5 | 6 | Test.run(:cov) do |run| 7 | require './test/helper' 8 | run.files << 'test/case_*.rb' 9 | SimpleCov.start do |cov| 10 | cov.coverage_dir = 'log/coverage' 11 | end 12 | end 13 | 14 | -------------------------------------------------------------------------------- /lib/assay/boolean_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'assertion' 2 | 3 | class BooleanAssay < Assertion 4 | 5 | register :boolean 6 | 7 | # 8 | # Check assertion. 9 | # 10 | def self.pass?(subject) 11 | subject.true? || subject.false? # TODO: Kernel#boolean? method 12 | end 13 | 14 | end 15 | 16 | -------------------------------------------------------------------------------- /var/resources: -------------------------------------------------------------------------------- 1 | --- 2 | home: http://rubyworks.github.com/assay 3 | docs: http://rubydoc.info/gems/assay/frames 4 | code: http://github.com/rubyworks/assay 5 | bugs: http://github.com/rubyworks/assay/issues 6 | chat: http://chat.us.freenode.net/rubyworks 7 | mail: http://groups.google.com/groups/rubyworks-mailinglist 8 | 9 | -------------------------------------------------------------------------------- /lib/assay/false_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'boolean_assay' 2 | 3 | # Assert and object if strictly `false`. 4 | # 5 | class FalseAssay < BooleanAssay 6 | 7 | register :false 8 | 9 | # 10 | # Check assertion. 11 | # 12 | def self.pass?(subject) 13 | subject.false? #FalseClass === subject 14 | end 15 | 16 | end 17 | 18 | -------------------------------------------------------------------------------- /lib/assay/empty_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'include_assay' 2 | 3 | # Empty assertion tests an object with `#empty?` method. 4 | # 5 | class EmptyAssay < IncludeAssay 6 | 7 | register :empty 8 | 9 | # 10 | # Check assertion with `#empty?`. 11 | # 12 | def self.pass?(subject) 13 | subject.empty? 14 | end 15 | 16 | end 17 | 18 | -------------------------------------------------------------------------------- /lib/assay/file_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'path_assay' 2 | 3 | # Assert the existance of a file with `File.file?` call. 4 | # 5 | class FileAssay < PathAssay 6 | 7 | register :file 8 | 9 | # 10 | # Check assertion using `File.file?` method. 11 | # 12 | def self.pass?(path) 13 | File.file?(path) 14 | end 15 | 16 | end 17 | 18 | -------------------------------------------------------------------------------- /lib/assay/path_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'assertion' 2 | 3 | # Assert the existance of a file with `File.file?` call. 4 | # 5 | class PathAssay < Assertion 6 | 7 | register :path 8 | 9 | # 10 | # Check assertion using `File.exist?` method. 11 | # 12 | def self.pass?(path) 13 | File.exist?(path) 14 | end 15 | 16 | end 17 | 18 | -------------------------------------------------------------------------------- /lib/assay/like_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'assertion' 2 | 3 | # LikeAssay defines an assertion for broad equality. 4 | # 5 | class LikeAssay < Assertion 6 | 7 | register :like 8 | 9 | # 10 | # Test assertion for `#like?`. 11 | # 12 | def self.pass?(subject, criterion) 13 | subject.like?(criterion) 14 | end 15 | 16 | end 17 | 18 | -------------------------------------------------------------------------------- /lib/assay/instance_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'kind_assay' 2 | 3 | # Assert that an object is an instance of a class. 4 | # 5 | class InstanceAssay < KindAssay 6 | 7 | register :instance_of 8 | 9 | # 10 | # Check assertion. 11 | # 12 | def self.pass?(object, class_type) 13 | object.instance_of?(class_type) 14 | end 15 | 16 | end 17 | 18 | -------------------------------------------------------------------------------- /demo/01_assay_classes/21_empty_assay.md: -------------------------------------------------------------------------------- 1 | ## EmptyAssay 2 | 3 | The `EmptyAssay` asserts that a collection includes no members, using the 4 | `#empty?` method. 5 | 6 | assert EmptyAssay.pass?([]) 7 | 8 | refute EmptyAssay.pass?([1]) 9 | 10 | And conversely, 11 | 12 | assert EmptyAssay.fail?([1]) 13 | 14 | refute EmptyAssay.fail?([]) 15 | 16 | -------------------------------------------------------------------------------- /lib/assay/include_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'assertion' 2 | 3 | # Assert that a container includes some object. 4 | # 5 | class IncludeAssay < Assertion 6 | 7 | register :include 8 | 9 | # 10 | # Check assertion using `#include?` method. 11 | # 12 | def self.pass?(container, member) 13 | container.include?(member) 14 | end 15 | 16 | end 17 | 18 | -------------------------------------------------------------------------------- /lib/assay/less_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'compare_assay' 2 | 3 | # Compare assertion is used to test a comparision 4 | # made by `#<`. 5 | # 6 | class LessAssay < CompareAssay 7 | 8 | register :<, :less_than 9 | 10 | # 11 | # Check assertion. 12 | # 13 | def self.pass?(subject, criterion) 14 | subject < criterion 15 | end 16 | 17 | end 18 | 19 | -------------------------------------------------------------------------------- /demo/01_assay_classes/10_match_assay.md: -------------------------------------------------------------------------------- 1 | ## MatchAssay 2 | 3 | The `MatchAssay` class defines an assertion for matching using the `#=~` 4 | method. 5 | 6 | assert MatchAssay.pass?('a', /a/) 7 | 8 | refute MatchAssay.pass?('a', /b/) 9 | 10 | And conversely, 11 | 12 | assert MatchAssay.fail?('a', /b/) 13 | 14 | refute MatchAssay.fail?('a', /a/) 15 | 16 | -------------------------------------------------------------------------------- /lib/assay/case_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'equality_assay' 2 | 3 | # Equality assertion using `#===`, the case equality method. 4 | # 5 | class CaseAssay < EqualityAssay 6 | 7 | register :===, :case 8 | 9 | # 10 | # Check assertion via `#===` method. 11 | # 12 | def self.pass?(subject, criterion) 13 | subject === criterion 14 | end 15 | 16 | end 17 | 18 | -------------------------------------------------------------------------------- /lib/assay/more_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'compare_assay' 2 | 3 | # Compare assertion is used to test a comparision 4 | # made by `#>`. 5 | # 6 | class MoreAssay < CompareAssay 7 | 8 | register :>, :more_than 9 | 10 | # 11 | # Check assertion using `#>` method call. 12 | # 13 | def self.pass?(subject, criterion) 14 | subject > criterion 15 | end 16 | 17 | end 18 | 19 | -------------------------------------------------------------------------------- /lib/assay/equality_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'equal_assay' 2 | 3 | # EqualityAssay defines the assertion for the `#eql?`, the strict 4 | # equality method. 5 | # 6 | class EqualityAssay < EqualAssay 7 | 8 | register :eql 9 | 10 | # 11 | # Check assertion via `#eql?` method. 12 | # 13 | def self.pass?(subject, criterion) 14 | subject.eql?(criterion) 15 | end 16 | 17 | end 18 | 19 | -------------------------------------------------------------------------------- /demo/01_assay_classes/22_respond_assay.md: -------------------------------------------------------------------------------- 1 | ## RespondAssay 2 | 3 | The `RespondAssay` asserts if a an object responds to a message using 4 | then `#respond_to?` method. 5 | 6 | assert RespondAssay.pass?('a', :to_s) 7 | 8 | refute RespondAssay.pass?('a', :foo) 9 | 10 | And conversely, 11 | 12 | assert RespondAssay.fail?('a', :foo) 13 | 14 | refute RespondAssay.fail?('a', :to_s) 15 | 16 | -------------------------------------------------------------------------------- /lib/assay/kind_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'assertion' 2 | 3 | # Comparison assertion for #kind_of? 4 | # 5 | # KindAssay.pass?(1, Integer) #=> true 6 | # KindAssay.fail?(1, String) #=> true 7 | # 8 | class KindAssay < Assertion 9 | 10 | register :kind_of 11 | 12 | # Check assertion. 13 | def self.pass?(object, class_type) 14 | object.kind_of?(class_type) 15 | end 16 | 17 | end 18 | 19 | -------------------------------------------------------------------------------- /lib/assay/nomatch_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'match_assay' 2 | 3 | # Ruby 1.9+ allows #!~ to redfined as it's own method, so a corresponding 4 | # assay is required to cover it. 5 | # 6 | class NoMatchAssay < MatchAssay 7 | 8 | register :!~, :nomatch 9 | 10 | # 11 | # Check no match assertion with `#!~` method. 12 | # 13 | def self.pass?(matcher, matchee) 14 | matcher !~ matchee 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /work/benchmarks/method_vs_object.rb: -------------------------------------------------------------------------------- 1 | require 'benchmark' 2 | 3 | class X 4 | def self.call(a,b) 5 | a == b 6 | end 7 | 8 | def initialize(a,b) 9 | @a = a 10 | @b = b 11 | end 12 | def call 13 | @a == @b 14 | end 15 | end 16 | 17 | 18 | n = 1000000 19 | Benchmark.bm do |x| 20 | x.report("method") { n.times{ X.call(1,1) } } 21 | x.report("object") { n.times{ X.new(1,1).call } } 22 | end 23 | 24 | -------------------------------------------------------------------------------- /try/qed/01_example.rdoc: -------------------------------------------------------------------------------- 1 | = Sample Assay via QED 2 | 3 | require 'assay' 4 | 5 | include Assay::Matchers 6 | 7 | Example of a failed assertion. 8 | 9 | 1.assert is_equal_to(2) 10 | 11 | Example of a failed refutation. 12 | 13 | 1.refute is_equal_to(1) 14 | 15 | Lets try the assertives. 16 | 17 | include Assay::Assertives 18 | 19 | Now 20 | 21 | assert_equal(1,2, "1 is not 2 dingo!") 22 | 23 | QED. 24 | -------------------------------------------------------------------------------- /lib/assay/directory_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'path_assay' 2 | 3 | # Assert the existance of a directory with `File.directory?` call. 4 | # 5 | class DirectoryAssay < PathAssay 6 | 7 | register :directory 8 | 9 | # 10 | # Check assertion using `File.file?` method. 11 | # 12 | def self.pass?(path) 13 | File.directory?(path) 14 | end 15 | 16 | end 17 | 18 | # I would prefer this name. 19 | #FolderAssay = DirectoryAssay 20 | 21 | -------------------------------------------------------------------------------- /lib/assay/respond_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'assertion' 2 | 3 | # Does an object #respond_to? a method call. 4 | # 5 | class RespondAssay < Assertion 6 | 7 | register :respond_to 8 | 9 | # Check assertion. 10 | def self.pass?(reciever, method_name) 11 | #flip = (Symbol === obj) && ! (Symbol === meth) # HACK for specs 12 | #obj, meth = meth, obj if flip 13 | reciever.respond_to?(method_name) 14 | end 15 | 16 | end 17 | 18 | -------------------------------------------------------------------------------- /demo/01_assay_classes/18_kind_assay.md: -------------------------------------------------------------------------------- 1 | ## KindAssay 2 | 3 | The `KindAssay` asserts that an object is a class or any ancestor 4 | of that class. 5 | 6 | assert KindAssay.pass?(1, Fixnum) 7 | assert KindAssay.pass?(1, Numeric) 8 | 9 | refute KindAssay.pass?(1, String) 10 | 11 | And conversely, 12 | 13 | assert KindAssay.fail?(1, String) 14 | 15 | refute KindAssay.fail?(1, Fixnum) 16 | refute KindAssay.fail?(1, Numeric) 17 | 18 | -------------------------------------------------------------------------------- /lib/assay/true_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'boolean_assay' 2 | 3 | # Comparison assertion for TrueClass. 4 | # 5 | # TrueAssay.pass?(true) #=> true 6 | # TrueAssay.fail?(true) #=> false 7 | # TrueAssay.pass?(1) #=> false 8 | # 9 | class TrueAssay < BooleanAssay 10 | 11 | register :true 12 | 13 | # 14 | # Check assertion using `#true?` method. 15 | # 16 | def self.pass?(subject) 17 | subject.true? #TrueClass === subject 18 | end 19 | 20 | end 21 | -------------------------------------------------------------------------------- /demo/01_assay_classes/19_instance_assay.md: -------------------------------------------------------------------------------- 1 | ## InstanceAssay 2 | 3 | The `InstanceAssay` asserts that an object is an instance of a specific class. 4 | 5 | assert InstanceAssay.pass?(1, Fixnum) 6 | 7 | refute InstanceAssay.pass?(1, Numeric) 8 | refute InstanceAssay.pass?(1, String) 9 | 10 | And conversely, 11 | 12 | assert InstanceAssay.fail?(1, String) 13 | assert InstanceAssay.fail?(1, Numeric) 14 | 15 | refute InstanceAssay.fail?(1, Fixnum) 16 | 17 | -------------------------------------------------------------------------------- /demo/01_assay_classes/20_include_assay.md: -------------------------------------------------------------------------------- 1 | ## IncludeAssay 2 | 3 | The `IncludeAssay` asserts that a collection includes a specific member, using 4 | the `#include?` method. 5 | 6 | assert IncludeAssay.pass?([1], 1) 7 | 8 | refute IncludeAssay.pass?([], 1) 9 | refute IncludeAssay.pass?([2], 1) 10 | 11 | And conversely, 12 | 13 | assert IncludeAssay.fail?([], 1) 14 | assert IncludeAssay.fail?([2], 1) 15 | 16 | refute IncludeAssay.fail?([1], 1) 17 | 18 | -------------------------------------------------------------------------------- /demo/01_assay_classes/27_path_assay.md: -------------------------------------------------------------------------------- 1 | ## PathAssay 2 | 3 | The `PathAssay` asserts that a file-system path exists. 4 | 5 | file = __FILE__ 6 | dir = File.dirname(file) 7 | dne = __FILE__ + '~' 8 | 9 | assert PathAssay.pass?(file) 10 | assert PathAssay.pass?(dir) 11 | 12 | refute PathAssay.pass?(dne) 13 | 14 | And conversely, 15 | 16 | assert PathAssay.fail?(dne) 17 | 18 | refute PathAssay.fail?(file) 19 | refute PathAssay.fail?(dir) 20 | 21 | -------------------------------------------------------------------------------- /work/consider/operator.rb: -------------------------------------------------------------------------------- 1 | require 'assertion' 2 | 3 | module Assertable 4 | 5 | # Compares the +object1+ with +object2+ using operator. 6 | # 7 | # Passes if object1.send(operator, object2) is true. 8 | # 9 | # assert_operator 5, :>=, 4 10 | # 11 | def assert_operator(o1, op, o2, opts={}) 12 | if !o1.__send__(op, o2) 13 | msg = opts[:message] || "Expected #{o1}.#{op}(#{o2}) to be true" 14 | fail Assertion.new(msg, caller) 15 | end 16 | end 17 | 18 | end 19 | -------------------------------------------------------------------------------- /demo/01_assay_classes/29_file_assay.md: -------------------------------------------------------------------------------- 1 | ## FileAssay 2 | 3 | The `FileAssay` asserts that a file-system path exists and it is a file. 4 | 5 | file = __FILE__ 6 | dir = File.dirname(file) 7 | dne = __FILE__ + '~' 8 | 9 | assert FileAssay.pass?(file) 10 | 11 | refute FileAssay.pass?(dir) 12 | refute FileAssay.pass?(dne) 13 | 14 | And conversely, 15 | 16 | assert FileAssay.fail?(dir) 17 | assert FileAssay.fail?(dne) 18 | 19 | refute FileAssay.fail?(file) 20 | 21 | -------------------------------------------------------------------------------- /demo/01_assay_classes/11_nomatch_assay.md: -------------------------------------------------------------------------------- 1 | ## NoMatchAssay 2 | 3 | The `NoMatchAssay` class defines an assertion for matching using the `#!~` 4 | method. As of Ruby 1.9, the `#!~` method is redefinable independent of `#=~`, 5 | so a separate assertion class is needed to cover it. 6 | 7 | assert NoMatchAssay.pass?('a', /b/) 8 | 9 | refute NoMatchAssay.pass?('a', /a/) 10 | 11 | And conversely, 12 | 13 | assert NoMatchAssay.fail?('a', /a/) 14 | 15 | refute NoMatchAssay.fail?('a', /b/) 16 | 17 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/nil.rb: -------------------------------------------------------------------------------- 1 | require 'assertions/failures/nil' 2 | 3 | module Assertable 4 | 5 | # Passed if object is +nil+. 6 | # 7 | def assert_nil(exp, opts={}) 8 | opts[:backtrace] ||= caller 9 | NilFailure.assert(exp, opts) 10 | end 11 | 12 | # Passed if object is not +nil+. 13 | # 14 | # assert_not_nil(true) 15 | # 16 | def assert_not_nil(exp, opts={}) 17 | opts[:backtrace] ||= caller 18 | NilFailure.assert!(exp, opts) 19 | end 20 | 21 | end 22 | 23 | -------------------------------------------------------------------------------- /demo/01_assay_classes/03_true_assay.md: -------------------------------------------------------------------------------- 1 | ## TrueAssay 2 | 3 | The `TrueAssay` class asserts that an object is `true`. 4 | Reference to any other object will fail. 5 | 6 | assert TrueAssay.pass?(true) 7 | 8 | refute TrueAssay.pass?(false) 9 | refute TrueAssay.pass?(nil) 10 | refute TrueAssay.pass?('foo') 11 | 12 | And conversely, 13 | 14 | assert TrueAssay.fail?(false) 15 | assert TrueAssay.fail?(nil) 16 | assert TrueAssay.fail?('foo') 17 | 18 | refute TrueAssay.fail?(true) 19 | 20 | 21 | -------------------------------------------------------------------------------- /demo/01_assay_classes/05_equal_assay.md: -------------------------------------------------------------------------------- 1 | ## EqualAssay 2 | 3 | The `EqualAssay` class defines an assertion for equality based on the `==` method. 4 | 5 | assert EqualAssay.pass?(1, 1) 6 | assert EqualAssay.pass?(1, 1.0) 7 | 8 | refute EqualAssay.pass?(1, 2) 9 | refute EqualAssay.pass?(1, 'foo') 10 | 11 | And conversely, 12 | 13 | assert EqualAssay.fail?(1, 2) 14 | assert EqualAssay.fail?(1, 'foo') 15 | 16 | refute EqualAssay.fail?(1, 1) 17 | refute EqualAssay.fail?(1, 1.0) 18 | 19 | 20 | -------------------------------------------------------------------------------- /demo/01_assay_classes/03_false_assay.md: -------------------------------------------------------------------------------- 1 | ## FalseAssay 2 | 3 | The `FalseAssay` class asserts that an object is `false. 4 | Reference to any other object will fail. 5 | 6 | assert FalseAssay.pass?(false) 7 | 8 | refute FalseAssay.pass?(true) 9 | refute FalseAssay.pass?(nil) 10 | refute FalseAssay.pass?('foo') 11 | 12 | And conversely, 13 | 14 | assert FalseAssay.fail?(true) 15 | assert FalseAssay.fail?(nil) 16 | assert FalseAssay.fail?('foo') 17 | 18 | refute FalseAssay.fail?(false) 19 | 20 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/false.rb: -------------------------------------------------------------------------------- 1 | require 'assertions/failures/false' 2 | 3 | module Assertable 4 | 5 | # Passed if object is +false+. 6 | # 7 | def assert_false(exp, opts={}) 8 | opts[:backtrace] ||= caller 9 | FalseFailure.assert(exp, opts) 10 | end 11 | 12 | # Passed if object is not +false+. 13 | # 14 | # assert_not_false(false) 15 | # 16 | def assert_not_false(exp, opts={}) 17 | opts[:backtrace] ||= caller 18 | FalseFailure.assert!(exp, opts) 19 | end 20 | 21 | end 22 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/true.rb: -------------------------------------------------------------------------------- 1 | require 'assertions/failures/true' 2 | 3 | module Assertable 4 | 5 | # Passed if object is +true+. 6 | # 7 | def assert_true(exp, opts={}) 8 | opts[:backtrace] ||= caller 9 | TrueFailure.assert(exp, opts) 10 | end 11 | 12 | # Passed if object is not +true+. 13 | # 14 | # assert_not_true(false) 15 | # 16 | def assert_not_true(exp, opts={}) 17 | opts[:backtrace] ||= caller 18 | TrueFailure.assert!(exp, opts) 19 | end 20 | 21 | end 22 | 23 | -------------------------------------------------------------------------------- /demo/01_assay_classes/07_equality_assay.md: -------------------------------------------------------------------------------- 1 | ## EqualityAssay 2 | 3 | The `EqualityAssay` class defines an assertion for strict equality via 4 | the `eql?` method. 5 | 6 | assert EqualityAssay.pass?(1, 1) 7 | 8 | refute EqualityAssay.pass?(1, 1.0) 9 | refute EqualityAssay.pass?(1, 2) 10 | refute EqualityAssay.pass?(1, 'foo') 11 | 12 | And conversely, 13 | 14 | assert EqualityAssay.fail?(1, 2) 15 | assert EqualityAssay.fail?(1, 1.0) 16 | assert EqualityAssay.fail?(1, 'foo') 17 | 18 | refute EqualityAssay.fail?(1, 1) 19 | 20 | -------------------------------------------------------------------------------- /demo/01_assay_classes/28_directory_assay.md: -------------------------------------------------------------------------------- 1 | ## DirectoryAssay 2 | 3 | The `DirectoryAssay` asserts that a file-system path exists 4 | and it is a directory. 5 | 6 | file = __FILE__ 7 | dir = File.dirname(file) 8 | dne = __FILE__ + '~' 9 | 10 | assert DirectoryAssay.pass?(dir) 11 | 12 | refute DirectoryAssay.pass?(file) 13 | refute DirectoryAssay.pass?(dne) 14 | 15 | And conversely, 16 | 17 | assert DirectoryAssay.fail?(file) 18 | assert DirectoryAssay.fail?(dne) 19 | 20 | refute DirectoryAssay.fail?(dir) 21 | 22 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/operator.rb: -------------------------------------------------------------------------------- 1 | require 'assertion' 2 | require 'ae/assertable' 3 | 4 | class OperatorFailure < ExecutionFailure 5 | 6 | # Compares the +object1+ with +object2+ using operator. 7 | # 8 | # Passes if object1.send(operator, object2) is true. 9 | # 10 | # assert_operator 5, :>=, 4 11 | # 12 | def self.operator(o1, op, o2, msg="") 13 | test = o1.__send__(op, o2) 14 | msg = "Expected #{o1}.#{op}(#{o2}) to be true" unless msg 15 | raise Assertion.new(msg, caller) unless test 16 | end 17 | 18 | end 19 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/compare.rb: -------------------------------------------------------------------------------- 1 | module Assertable 2 | 3 | # Passes if +actual+ .equte? +expected+. 4 | # 5 | # o = Object.new 6 | # assert_like(o, o) 7 | # 8 | def self.like(exp, act, opts={}) 9 | opts[:backtrace] ||= caller 10 | CompareFailure.assert(exp, act, opts) 11 | end 12 | 13 | # Passes if ! actual .equte? expected 14 | # 15 | # assert_not_like(Object.new, Object.new) 16 | # 17 | def self.not_like(exp, act, opts) 18 | opts[:backtrace] ||= caller 19 | CompareFailure.assert(exp, act, opts) 20 | end 21 | 22 | end 23 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/match.rb: -------------------------------------------------------------------------------- 1 | require 'assertion/failures/match' 2 | 3 | module Assertable 4 | 5 | # Passes if string =~ pattern. 6 | # 7 | # assert_match(/\d+/, 'five, 6, seven') 8 | # 9 | def self.match(exp, act, opts={}) 10 | opts[:backtrace] ||= caller 11 | MatchFailure.assert(exp, act, opts) 12 | end 13 | 14 | # Passes if regexp !~ string 15 | # 16 | # assert_no_match(/two/, 'one 2 three') 17 | # 18 | def self.no_match(exp, act, opts={}) 19 | opts[:backtrace] ||= caller 20 | MatchFailure.assert!(exp, act, opts) 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/kind.rb: -------------------------------------------------------------------------------- 1 | require 'assertions/failures/kind' 2 | 3 | module Assertable 4 | 5 | # Passes if object .kind_of? klass 6 | # 7 | # assert_kind_of(Object, 'foo') 8 | # 9 | def assert_kind_of(cls, obj, opts={}) 10 | opts[:backtrace] ||= caller 11 | KindFailure.assert(exp, act, opts) 12 | end 13 | 14 | # Passes if object .kind_of? klass 15 | # 16 | # assert_not_kind_of(Object, 'foo') 17 | # 18 | def assert_not_kind_of(cls, obj, opts={}) 19 | opts[:backtrace] ||= caller 20 | KindFailure.assert!(exp, act, opts) 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/instance.rb: -------------------------------------------------------------------------------- 1 | require 'assertions/failures/instance' 2 | 3 | module Assertable 4 | 5 | # Passes if object .instance_of? klass 6 | # 7 | # assert_instance_of(String, 'foo') 8 | # 9 | def self.instance_of(cls, obj, opts={}) 10 | opts[:backtrace] ||= caller 11 | InstanceFailure.assert(cls, act, opts) 12 | end 13 | 14 | # Passes if object .instance_of? klass 15 | # 16 | # assert_instance_of(String, 'foo') 17 | # 18 | def self.not_instance_of(cls, obj, opts={}) 19 | opts[:backtrace] ||= caller 20 | InstanceFailure.assert!(cls, act, opts) 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /lib/assay/stderr_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'output_assay' 2 | 3 | # Assert that there is output $stderr. 4 | # 5 | # StderrAssay.pass?(/foo/){ $stderr.puts 'foo!' } #=> true 6 | # 7 | class StderrAssay < OutputAssay 8 | 9 | register :stderr 10 | 11 | # 12 | # Check assertion via `#===` method. 13 | # 14 | def self.pass?(match, &block) 15 | require 'stringio' 16 | 17 | begin 18 | stderr = $stderr 19 | newerr = StringIO.new 20 | $stderr = newerr 21 | yield 22 | ensure 23 | $stderr = stderr 24 | end 25 | 26 | match === newerr.string.chomp("\n") 27 | end 28 | 29 | end 30 | 31 | -------------------------------------------------------------------------------- /lib/assay/stdout_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'output_assay' 2 | 3 | # Assert that there is output, either from stdout or stderr. 4 | # 5 | # StdoutAssay.pass?(/foo/){ puts 'foo!' } #=> true 6 | # 7 | class StdoutAssay < OutputAssay 8 | 9 | register :output 10 | 11 | # 12 | # Check assertion via `#===` method. 13 | # 14 | def self.pass?(match, &block) 15 | require 'stringio' 16 | 17 | begin 18 | stdout = $stdout 19 | newout = StringIO.new 20 | $stdout = newout 21 | yield 22 | ensure 23 | $stdout = stdout 24 | end 25 | 26 | match === newout.string.chomp("\n") 27 | end 28 | 29 | end 30 | 31 | -------------------------------------------------------------------------------- /demo/01_assay_classes/31_stdout_assay.md: -------------------------------------------------------------------------------- 1 | ## StdoutAssay 2 | 3 | The `StdoutAssay` asserts that a output is sent to `$stdout`. 4 | 5 | assert StdoutAssay.pass?('foo'){ puts 'foo' } 6 | 7 | refute StdoutAssay.pass?('foo'){ nil } 8 | refute StdoutAssay.pass?('foo'){ puts 'bar' } 9 | 10 | And conversely, 11 | 12 | refute StdoutAssay.fail?('foo'){ puts 'foo' } 13 | 14 | assert StdoutAssay.fail?('foo'){ nil } 15 | assert StdoutAssay.fail?('foo'){ puts 'bar' } 16 | 17 | The StdoutAssay uses `#===` to test the match so we can also 18 | match against a regular expression. 19 | 20 | assert StdoutAssay.pass?(/f/){ puts 'foo' } 21 | 22 | -------------------------------------------------------------------------------- /demo/01_assay_classes/04_like_assay.md: -------------------------------------------------------------------------------- 1 | ## LikeAssay 2 | 3 | The `LikeAssay` is a very ... assertion. It is a comparison that 4 | evaluates to true for any of Ruby's many "equal" operators, `equal?` 5 | (same as `identical?`), `eql?`, `==`, `===` and `=~`. If any one 6 | of these evaluates to true, than two objects can be said to be alike. 7 | 8 | assert LikeAssay.pass?(1, 1) 9 | assert LikeAssay.pass?(1, 1.0) 10 | assert LikeAssay.pass?("1", /\d/) 11 | 12 | refute LikeAssay.pass?(1, "1") 13 | refute LikeAssay.pass?("1", /\D/) 14 | 15 | And conversely, 16 | 17 | assert LikeAssay.fail?(1, "1") 18 | assert LikeAssay.fail?("1", /\D/) 19 | 20 | -------------------------------------------------------------------------------- /demo/01_assay_classes/09_case_assay.md: -------------------------------------------------------------------------------- 1 | ## CaseAssay 2 | 3 | The `CaseAssay` class defines an assertion for case equality using the `#===` 4 | method. 5 | 6 | assert CaseAssay.pass?(1, 1) 7 | assert CaseAssay.pass?(1, 1.0) 8 | assert CaseAssay.pass?(/a/, 'a') 9 | assert CaseAssay.pass?(String, 'foo') 10 | 11 | refute CaseAssay.pass?(1, 2) 12 | refute CaseAssay.pass?(1, 'foo') 13 | 14 | And conversely, 15 | 16 | assert CaseAssay.fail?(1, 2) 17 | assert CaseAssay.fail?(1, 'foo') 18 | 19 | refute CaseAssay.fail?(1, 1) 20 | refute CaseAssay.fail?(1, 1.0) 21 | refute CaseAssay.fail?(/a/, 'a') 22 | refute CaseAssay.fail?(String, 'foo') 23 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/response.rb: -------------------------------------------------------------------------------- 1 | require 'assertions/failures/response' 2 | 3 | module Assertable 4 | # Passes if +object+ respond_to? +methods+. 5 | # 6 | # assert_respond_to 'bugbear', :slice 7 | # 8 | def assert_respond_to(reciever, method, opts={}) 9 | opts[:backtrace] ||= caller 10 | ResponseFailure.assert(reciever, method, opts) 11 | end 12 | 13 | # Passes if +object+ does not respond_to? +methods+. 14 | # 15 | # assert_not_respond_to 'bugbear', :slice 16 | # 17 | def assert_not_respond_to(reciever, method, opts={}) 18 | opts[:backtrace] ||= caller 19 | ResponseFailure.assert!(reciever, method, opts) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /demo/01_assay_classes/32_stderr_assay.md: -------------------------------------------------------------------------------- 1 | ## StderrAssay 2 | 3 | The `StderrAssay` asserts that a output is sent to `$stderr`. 4 | 5 | assert StderrAssay.pass?('foo'){ $stderr.puts 'foo' } 6 | 7 | refute StderrAssay.pass?('foo'){ nil } 8 | refute StderrAssay.pass?('foo'){ $stderr.puts 'bar' } 9 | 10 | And conversely, 11 | 12 | refute StderrAssay.fail?('foo'){ $stderr.puts 'foo' } 13 | 14 | assert StderrAssay.fail?('foo'){ nil } 15 | assert StderrAssay.fail?('foo'){ $stderr.puts 'bar' } 16 | 17 | The StderrAssay uses `#===` to test the match so we can also 18 | match against a regular expression. 19 | 20 | assert StderrAssay.pass?(/f/){ $stderr.puts 'foo' } 21 | 22 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/identity.rb: -------------------------------------------------------------------------------- 1 | require 'assertions/failures/identity' 2 | 3 | module Assertable 4 | 5 | # Passes if +actual+ .equal? +expected+ (i.e. they are the same instance). 6 | # 7 | # o = Object.new 8 | # assert_identical(o, o) 9 | # 10 | def assert_identical(exp, act, opts={}) 11 | opts[:backtrace] ||= caller 12 | IdentityFailure.assert(exp, act, opts) 13 | end 14 | 15 | # Passes if ! actual .equal? expected 16 | # 17 | # assert_not_identical(Object.new, Object.new) 18 | # 19 | def assert_not_identical(exp, act, opts={}) 20 | opts[:backtrace] ||= caller 21 | IdentityFailure.assert!(exp, act, opts) 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /work/defunct/oldschool_matchers/be.rb: -------------------------------------------------------------------------------- 1 | module Assay 2 | 3 | # This module holds the subject matcher methods, which can be mixin 4 | # to one's testing scope (e.g. World). 5 | # 6 | module Matchers 7 | 8 | # 9 | # Meta-programming routine for creating all the subjective methods. 10 | # 11 | def self.bootstrap 12 | Assay.constants.each do |const| 13 | next unless const < Assertion 14 | 15 | name = const.subjective_name 16 | 17 | define_method("be_#{name}") do |*args| 18 | const.to_matcher(*args) 19 | end 20 | end 21 | end 22 | 23 | # 24 | # Do it! 25 | # 26 | bootstrap 27 | 28 | end 29 | 30 | end 31 | 32 | -------------------------------------------------------------------------------- /work/defunct/oldschool_matchers/is.rb: -------------------------------------------------------------------------------- 1 | module Assay 2 | 3 | # This module holds the subject matcher methods, which can be mixin 4 | # to one's testing scope (e.g. World). 5 | # 6 | module Matchers 7 | 8 | # 9 | # Meta-programming routine for creating all the subjective methods. 10 | # 11 | def self.bootstrap 12 | Assay.constants.each do |const| 13 | next unless const < Assertion 14 | 15 | name = const.objective_name 16 | 17 | define_method("is_#{name}") do |*args| 18 | const.to_matcher(*args) 19 | end 20 | end 21 | end 22 | 23 | # 24 | # Do it! 25 | # 26 | bootstrap 27 | 28 | end 29 | 30 | end 31 | 32 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/raises.rb: -------------------------------------------------------------------------------- 1 | require 'assertions/failures/raises' 2 | 3 | module Assertable 4 | 5 | # Passes if the block raises a given exceptions. 6 | # 7 | # assert_raises RuntimeError do 8 | # raise 'Boom!!!' 9 | # end 10 | # 11 | def self.raises(exp, msg=nil, call=nil, &blk) #:yeild: 12 | RaiseFailure.assert(exp, msg=nil, call=nil, &blk) 13 | end 14 | 15 | # Passes if the block *does not* raise a given exceptions. 16 | # 17 | # assert_not_raised IOError do 18 | # raise 'Boom!!!' 19 | # end 20 | # 21 | def self.not_raised(exp, msg=nil, call=nil, &blk) #:yeild: 22 | RaiseFailure.assert!(exp, msg, call, &blk) 23 | end 24 | 25 | end 26 | -------------------------------------------------------------------------------- /Assembly: -------------------------------------------------------------------------------- 1 | --- 2 | github: 3 | gh_pages: web 4 | 5 | gem: 6 | active: true 7 | 8 | dnote: 9 | title: Source Notes 10 | output: log/notes.html 11 | 12 | vclog: 13 | output: 14 | - log/history.html 15 | - log/changes.html 16 | 17 | email: 18 | mailto: 19 | - ruby-talk@ruby-lang.org 20 | - rubyworks-mailinglist@googlegroups.com 21 | 22 | qed: 23 | files: demo/ 24 | 25 | qedoc: 26 | files: demo/ 27 | output: 28 | - DEMO.md 29 | - web/demos.html 30 | 31 | # OMG! Look at this old thing! 32 | #rubyforge: 33 | # service : Rubyforge 34 | # unixname: <= suite %> 35 | # groupid : ~ 36 | # package : <= name %> 37 | # sitemap: 38 | # doc/rdoc: <= name %> 39 | # active : false 40 | 41 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/execution.rb: -------------------------------------------------------------------------------- 1 | require 'assertion' 2 | 3 | module Assertable 4 | 5 | # Passes if the block yields successfully. 6 | # 7 | # assert_executes "Couldn't do the thing" do 8 | # do_the_thing 9 | # end 10 | # 11 | def assert_executes(opts={}, &blk) # :yield: 12 | opts[:backtrace] ||= caller 13 | ExecutionFailure.assert(blk, opts) 14 | end 15 | 16 | # Passes if the block does not yield successfully. 17 | # 18 | # assert_not_executes "Couldn't do the thing" do 19 | # do_the_thing 20 | # end 21 | # 22 | def assert_not_executes(opts={}, &blk) # :yield: 23 | opts[:backtrace] ||= caller 24 | ExecutionFailure.assert!(blk, opts) 25 | end 26 | 27 | end 28 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/delta.rb: -------------------------------------------------------------------------------- 1 | require 'assertions/failures/delta' 2 | 3 | module Assertable 4 | 5 | # Passes if expected_float and actual_float are equal within delta tolerance. 6 | # 7 | # assert_in_delta 0.05, (50000.0 / 10**6), 0.00001 8 | # 9 | def assert_in_delta(exp, act, delta, opts={}) 10 | opts[:backtrace] ||= caller 11 | DeltaFailure.assert(exp, act, delta, opts) 12 | end 13 | 14 | # Passes if expected_float and actual_float are equal not within delta tolerance. 15 | # 16 | # assert_not_in_delta 0.05, (50000.0 / 10**6), 0.00001 17 | # 18 | def self.not_in_delta(exp, act, delta, opts) 19 | opts[:backtrace] ||= caller 20 | DeltaFailure.assert!(exp, act, delta, opts) 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /work/consider/approx.rb: -------------------------------------------------------------------------------- 1 | def close1(a,b,x) 2 | (a >= (b - x)) && (a <= (b + x)) 3 | end 4 | 5 | def close2(a,b,x) 6 | (a / b - 1).abs <= x/b 7 | end 8 | 9 | def close3(a,b,x) 10 | ax, bx = a/x, b/x 11 | (ax >= (bx - 1)) && (a <= (bx + 1)) 12 | end 13 | 14 | def close4(a,b,x) 15 | ax, bx = a/x, b/x 16 | (ax / bx - 1).abs <= 1/bx 17 | end 18 | 19 | def close5(a,b,x) 20 | (a - b).abs / [a.abs, b.abs].max <= x 21 | end 22 | 23 | 24 | try = [[1.0, 1.1, 0.2, true], [1.1, 1.0, 0.1, true], [1.0, 1.1, 0.01, false]] 25 | 26 | try.each do |(a,b,x,r)| 27 | c1 = close1(a,b,x) 28 | c2 = close2(a,b,x) 29 | c3 = close3(a,b,x) 30 | c4 = close4(a,b,x) 31 | c5 = close5(a,b,x) 32 | 33 | puts "%f %f %f %5s | %5s %5s %5s %5s %5s" % [a,b,x,r,c1,c2,c3,c4,c5] 34 | end 35 | 36 | -------------------------------------------------------------------------------- /work/defunct/oldschool_extensions/is.rb: -------------------------------------------------------------------------------- 1 | module Assay 2 | 3 | # This module holds the objective "is" methods, which are mixed in to 4 | # all objects. 5 | # 6 | module Expectations 7 | 8 | # 9 | # Meta-programming routine for creating all the subjective methods. 10 | # 11 | def self.bootstrap 12 | Assay.constants.each do |const| 13 | next unless const < Assertion 14 | 15 | name = const.objective_name 16 | 17 | define_method("is_#{name}") do |*args| 18 | const.assert(self, *args) 19 | end 20 | 21 | define_method("is_not_#{name}") do |*args| 22 | const.refute(self, *args) 23 | end 24 | end 25 | end 26 | 27 | # 28 | # Do it! 29 | # 30 | bootstrap 31 | 32 | end 33 | 34 | end 35 | 36 | -------------------------------------------------------------------------------- /demo/01_assay_classes/01_nil_assay.md: -------------------------------------------------------------------------------- 1 | ## NilAssay 2 | 3 | The `NilAssay` asserts that an object reference is `nil`. 4 | Reference to any other object will fail. 5 | 6 | assert NilAssay.pass?(nil) 7 | 8 | refute NilAssay.pass?(true) 9 | refute NilAssay.pass?(false) 10 | refute NilAssay.pass?("foo") 11 | 12 | And conversely, 13 | 14 | assert NilAssay.fail?(true) 15 | assert NilAssay.fail?(false) 16 | assert NilAssay.fail?("foo") 17 | 18 | refute NilAssay.fail?(nil) 19 | 20 | Making assertions, 21 | 22 | assert NilAssay.assert!(nil) 23 | 24 | expect ::NilAssay do 25 | NilAssay.assert!(true) 26 | end 27 | 28 | And refutations, 29 | 30 | assert NilAssay.refute!(true) 31 | 32 | expect ::NilAssay do 33 | NilAssay.refute!(nil) 34 | end 35 | 36 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/returns.rb: -------------------------------------------------------------------------------- 1 | require 'assertions/failures/returns' 2 | 3 | module Assertable 4 | 5 | # Passes if the block yields a specified value (Compares with #==). 6 | # 7 | # assert_returns "Did not return something" do 8 | # do_the_thing 9 | # end 10 | # 11 | def assert_returns(exp=:"N/A", opts={}, &blk) # :yield: 12 | opts[:backtrace] ||= caller 13 | ReturnFailure.assert(exp, opts, &blk) 14 | end 15 | 16 | # Passes if the block does not yield a specific value. 17 | # 18 | # assert_does_not_return "Returned something unwanted" do 19 | # do_the_thing 20 | # end 21 | # 22 | def assert_does_not_return(exp=:"N/A", opts={}, &blk) # :yield: 23 | opts[:backtrace] ||= caller 24 | ReturnFailure.assert!(exp, opts, &blk) 25 | end 26 | 27 | end 28 | -------------------------------------------------------------------------------- /demo/01_assay_classes/12_compare_assay.md: -------------------------------------------------------------------------------- 1 | ## CompareAssay 2 | 3 | The `CompareAssay` class defines an assertion of comparison around the `#<=>` 4 | method. Since `#<=>` can return either a `1`, `0` or `-1`, an extra criterion 5 | is needed when making testing the assertion. 6 | 7 | assert CompareAssay.pass?(1, 1, 0) 8 | assert CompareAssay.pass?(1, 2, -1) 9 | assert CompareAssay.pass?(2, 1, 1) 10 | 11 | refute CompareAssay.pass?(1, 1, 1) 12 | refute CompareAssay.pass?(1, 1, -1) 13 | 14 | refute CompareAssay.pass?(1, 'foo', 0) 15 | 16 | And conversely, 17 | 18 | assert CompareAssay.fail?(1, 1, 1) 19 | assert CompareAssay.fail?(1, 1, -1) 20 | 21 | refute CompareAssay.fail?(1, 1, 0) 22 | refute CompareAssay.fail?(1, 2, -1) 23 | refute CompareAssay.fail?(2, 1, 1) 24 | 25 | -------------------------------------------------------------------------------- /test/helper.rb: -------------------------------------------------------------------------------- 1 | require 'lemon' 2 | 3 | # Simple helper assertion method. 4 | def assert(truth, msg=nil, trace=nil) 5 | if truth 6 | increment_counts(:pass) 7 | else 8 | increment_counts(:fail) 9 | raise Assertion, msg || "assert failed", trace || caller 10 | end 11 | end 12 | 13 | def refute(truth) 14 | assert(!truth, "refute failed", caller) 15 | end 16 | 17 | def expect(error) 18 | begin 19 | yield 20 | increment_counts(:fail) 21 | raise Assertion, "#{error} not raised.", caller 22 | rescue error 23 | increment_counts(:pass) 24 | end 25 | end 26 | 27 | def increment_counts(which) 28 | case which 29 | when :pass 30 | $ASSERTION_COUNTS[:pass] += 1 31 | when :fail 32 | $ASSERTION_COUNTS[:fail] += 1 33 | end 34 | $ASSERTION_COUNTS[:total] += 1 35 | end 36 | 37 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/same.rb: -------------------------------------------------------------------------------- 1 | require 'assertions/failures/same' 2 | 3 | module Assertable 4 | 5 | # Passes if +expected+ .eq? +actual+. 6 | # 7 | # Note that the ordering of arguments is important, 8 | # since a helpful error message is generated when this 9 | # one fails that tells you the values of expected and actual. 10 | # 11 | # assert_equal 'MY STRING', 'my string'.upcase 12 | # 13 | def self.same(exp, act, opts={}) 14 | opts[:backtrace] ||= caller 15 | SameFailure.assert(exp, act, opts) 16 | end 17 | 18 | # Passes if not +expected+ .eq? +actual+. 19 | # 20 | # assert_not_equal 'some string', 5 21 | # 22 | def self.not_the_same(exp, act, opts={}) 23 | opts[:backtrace] ||= caller 24 | SameFailure.assert!(exp, act, opts) 25 | end 26 | 27 | end 28 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable/equality.rb: -------------------------------------------------------------------------------- 1 | require 'assertions/failures/equality' 2 | 3 | module Assertable 4 | 5 | # Passes if expected == +actual. 6 | # 7 | # Note that the ordering of arguments is important, 8 | # since a helpful error message is generated when this 9 | # one fails that tells you the values of expected and actual. 10 | # 11 | # assert_equal 'MY STRING', 'my string'.upcase 12 | # 13 | def assert_equal(exp, act, opts={}) 14 | opts[:backtrace] ||= caller 15 | EqualityFailure.assert(exp, act, opts) 16 | end 17 | 18 | # Passes if expected != actual 19 | # 20 | # assert_not_equal 'some string', 5 21 | # 22 | def assert_not_equal(exp, act, opts) 23 | opts[:backtrace] ||= caller 24 | EqualityFailure.assert!(exp, act, opts) 25 | end 26 | 27 | end 28 | -------------------------------------------------------------------------------- /lib/assay/equal_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'like_assay' 2 | 3 | # EqualAssay coers the assertion comparing two objects with `#==` operator. 4 | # 5 | class EqualAssay < LikeAssay 6 | 7 | register :==, :equal 8 | 9 | # 10 | # Test assertion of `#==` method. 11 | # 12 | def self.pass?(subject, criterion) 13 | subject == criterion 14 | end 15 | 16 | # 17 | # Error message for equal assertion. 18 | # 19 | def self.assert_message(subject, criterion) 20 | a = subject.inspect 21 | b = criterion.inspect 22 | 23 | if a.size > SIZE_LIMIT or b.size > SIZE_LIMIT 24 | if $ansi 25 | d = ANSI::Diff.new(a, b) 26 | a, b = d.diff1, d.diff2 # *d.to_a 27 | end 28 | "a == b\na) #{a}\nb) #{b}" 29 | else 30 | "#{a} == #{b}" 31 | end 32 | end 33 | 34 | end 35 | 36 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/false.rb: -------------------------------------------------------------------------------- 1 | require 'ae/assertable' 2 | 3 | class IsFalseFailure < Assertion 4 | def self.assertion_name 5 | :false 6 | end 7 | 8 | def fail_message(exp) 9 | "Expected #{exp} to be false" 10 | end 11 | 12 | def fail_message!(exp) 13 | "Expected #{exp} NOT to be false" 14 | end 15 | 16 | def self.check(act) 17 | FalseClass === act 18 | end 19 | end 20 | 21 | module Assertable 22 | # Passed if object is +false+. 23 | # 24 | def self.false(obj, opts={}) 25 | opts[:backtrace] ||= caller 26 | IsFalseFailure.assert(obj, opts) 27 | end 28 | 29 | # Passed if object is not +false+. 30 | # 31 | # assert_not_false(false) 32 | # 33 | def self.not_false(obj, opts={}) 34 | opts[:backtrace] ||= caller 35 | IsFalseFailure.assert!(obj, opts) 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/true.rb: -------------------------------------------------------------------------------- 1 | require 'assertion' 2 | require 'ae/assertable' 3 | 4 | class IsTrueFailure < Assertion 5 | def self.assertion_name 6 | :true 7 | end 8 | 9 | def fail_message(exp) 10 | "Expected #{exp} to be true" 11 | end 12 | 13 | def fail_message!(exp) 14 | "Expected #{exp} NOT to be true" 15 | end 16 | 17 | def self.check(act) 18 | TrueClass === act 19 | end 20 | end 21 | 22 | module Assertable 23 | # Passed if object is +true+. 24 | # 25 | def assert_true(obj, opts) 26 | options[:backtrace] ||= caller 27 | IsTrueFailure.assert(obj, opts) 28 | end 29 | 30 | # Passed if object is not +true+. 31 | # 32 | # assert_not_true(false) 33 | # 34 | def assert_not_true(obj, opts) 35 | opts[:backtrace] ||= caller 36 | IsTrueFailure.assert!(obj, opts) 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/assay/less_equal_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'compare_assay' 2 | 3 | # Compare assertion is used to test a comparision made by `#<=`. 4 | # 5 | # NOTE: We are taking some leeway here with the name of this class, 6 | # which ordinarily would be called `LesserThanOrEqualAssay`. 7 | # However, such a name is a bit winded. The shortest name then, 8 | # without resorting to abbreviations, is _less-equal_, a monosyllabic 9 | # reading of the operator itself. Since it is ordinarily meaningless 10 | # to say something is "more equal" than something else, why not allow 11 | # it to be meaningful and save ourselves all that uneccessary verbage? 12 | # 13 | class LessEqualAssay < CompareAssay 14 | 15 | register :<=, :less_equal 16 | 17 | # 18 | # Check assertion. 19 | # 20 | def self.pass?(subject, criterion) 21 | subject <= criterion 22 | end 23 | 24 | end 25 | 26 | -------------------------------------------------------------------------------- /demo/01_assay_classes/02_boolean_assay.md: -------------------------------------------------------------------------------- 1 | ## BooleanAssay 2 | 3 | The `BooleanAssay` asserts that an object reference is `nil`. 4 | Reference to any other object will fail. 5 | 6 | assert BooleanAssay.pass?(true) 7 | assert BooleanAssay.pass?(false) 8 | 9 | refute BooleanAssay.pass?(nil) 10 | refute BooleanAssay.pass?("foo") 11 | 12 | And conversely, 13 | 14 | assert BooleanAssay.fail?(nil) 15 | assert BooleanAssay.fail?("foo") 16 | 17 | refute BooleanAssay.fail?(true) 18 | refute BooleanAssay.fail?(false) 19 | 20 | Making assertions, 21 | 22 | assert BooleanAssay.assert!(true) 23 | 24 | expect ::BooleanAssay do 25 | BooleanAssay.assert!(nil) 26 | end 27 | 28 | And refutations, 29 | 30 | assert BooleanAssay.refute!(nil) 31 | 32 | expect ::BooleanAssay do 33 | BooleanAssay.refute!(true) 34 | end 35 | 36 | -------------------------------------------------------------------------------- /demo/02_lookup.md: -------------------------------------------------------------------------------- 1 | # Asay Lookup 2 | 3 | Assay classes are indexed by both name and associated operation, so they 4 | can be looked-up by either. The indexes are stored as class attributes of 5 | the Assertion base class. 6 | 7 | Let's lookup the class for `==` equality. 8 | 9 | Assertion.by_operator(:==) #=> ::EqualAssay 10 | 11 | Let's lookup the assertion class for `#empty?`. 12 | 13 | Assertion.by_operator(:empty?) #=> ::EmptyAssay 14 | 15 | If we wish to lookup by assertive name instead of operator, we can use 16 | the `by_name` method instead. 17 | 18 | Assertion.by_name(:empty) #=> ::EmptyAssay 19 | 20 | We can also use the `Assay.lookup` module method, which will lookup an assay 21 | class by either assertion name or associated operator. 22 | 23 | Assay.lookup(:==) #=> ::EqualAssay 24 | Assay.lookup(:empty?) #=> ::EmptyAssay 25 | 26 | -------------------------------------------------------------------------------- /demo/01_assay_classes/08_identity_assay.md: -------------------------------------------------------------------------------- 1 | ## IdentityAssay 2 | 3 | The `IdentityAssay` class defines an assertion for identity comparison via 4 | the `#identical?` method, which is an alias for the `#equal?` method. 5 | We have choosen not to use the term `equal` to avoid confusion with the 6 | ordinary `==` type of equality. 7 | 8 | assert IdentityAssay.pass?(1, 1) 9 | assert IdentityAssay.pass?(:a, :a) 10 | 11 | refute IdentityAssay.pass?('a', 'a') 12 | refute IdentityAssay.pass?(1, 1.0) 13 | refute IdentityAssay.pass?(1, 2) 14 | refute IdentityAssay.pass?(1, 'foo') 15 | 16 | And conversely, 17 | 18 | assert IdentityAssay.fail?(1, 2) 19 | assert IdentityAssay.fail?(1, 1.0) 20 | assert IdentityAssay.fail?(1, 'foo') 21 | assert IdentityAssay.fail?('a', 'a') 22 | 23 | refute IdentityAssay.fail?(1, 1) 24 | refute IdentityAssay.fail?(:a, :a) 25 | -------------------------------------------------------------------------------- /lib/assay/more_equal_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'compare_assay' 2 | 3 | # Compare assertion is used to test a comparision made by `#>=`. 4 | # 5 | # NOTE: We are taking some leeway here with the name of this class, 6 | # which ordinarily would be called `GreaterThanOrEqualAssay`. 7 | # However, such a name is a bit winded. The shortest name then, 8 | # without resorting to abbreviations, is _more-equal_, a monosyllabic 9 | # reading of the operator itself. Since it is ordinarily meaningless 10 | # to say something is "more equal" than something else, why not allow 11 | # it to be meaningful and save ourselves all that uneccessary verbage? 12 | # 13 | class MoreEqualAssay < CompareAssay 14 | 15 | register :>=, :more_equal 16 | 17 | # 18 | # Check assertion using `#>=` method. 19 | # 20 | def self.pass?(subject, criterion) 21 | subject >= criterion 22 | end 23 | 24 | end 25 | 26 | -------------------------------------------------------------------------------- /test/case_empty_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/empty_assay' 2 | 3 | testcase EmptyAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert EmptyAssay.pass?([]) 9 | refute EmptyAssay.pass?([1]) 10 | end 11 | 12 | end 13 | 14 | class_method :fail? do 15 | 16 | test do 17 | refute EmptyAssay.fail?([]) 18 | assert EmptyAssay.fail?([1]) 19 | end 20 | 21 | end 22 | 23 | class_method :assert! do 24 | 25 | test do 26 | EmptyAssay.assert!([]) 27 | end 28 | 29 | test do 30 | expect EmptyAssay do 31 | EmptyAssay.assert!([1]) 32 | end 33 | end 34 | 35 | end 36 | 37 | class_method :refute! do 38 | 39 | test do 40 | EmptyAssay.refute!([1]) 41 | end 42 | 43 | test do 44 | expect EmptyAssay do 45 | EmptyAssay.refute!([]) 46 | end 47 | end 48 | 49 | end 50 | 51 | end 52 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/nil.rb: -------------------------------------------------------------------------------- 1 | require 'assertion' 2 | require 'ae/assertable' 3 | 4 | class IsNilFailure < Assertion 5 | def self.assertion_name 6 | :nil 7 | end 8 | 9 | def fail_message(exp) 10 | "Expected #{exp} to be nil" 11 | end 12 | 13 | def fail_message!(exp) 14 | "Expected #{exp} to NOT be nil" 15 | end 16 | 17 | def self.check(obj) 18 | obj.nil? 19 | end 20 | end 21 | 22 | module Assertable 23 | # Passes if object nil? 24 | # 25 | # assert_nil [1, 2].uniq! 26 | # 27 | def self.nil(obj, opts={}) 28 | opts[:backtrace] ||= caller 29 | IsNilFailure.assert(obj, opts) 30 | end 31 | 32 | # Passes if object is not nil? 33 | # 34 | # assert_not_nil '1 two 3'.sub!(/two/, '2') 35 | # 36 | def self.not_nil(obj, opts={}) 37 | opts[:backtrace] ||= caller 38 | IsNilFailure.assert!(obj, opts) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /work/defunct/complex_nomenclature_system/nomenclature/must.rb: -------------------------------------------------------------------------------- 1 | require 'ae/must' 2 | require 'ae/nomenclature' 3 | 4 | class AE 5 | 6 | module Nomenclature 7 | 8 | # = Extended Must Nomenclature 9 | # 10 | module Must 11 | 12 | # Setup a predicate for this nomenclature. 13 | def self.define_predicate(pname) 14 | name = make_subjunctive(pname) 15 | super('must', name, pname) 16 | end 17 | 18 | # Returns the predicate name without the prefix 19 | # phrase that corresponds to this nomenclature. 20 | # If the term doesn't conform to this nomenclature 21 | # then returns nil. 22 | def self.make_neutral(name) 23 | case name 24 | when /^must_/ then $' 25 | else nil 26 | end 27 | end 28 | 29 | # Must is a nomenclature. 30 | extend Nomenclature 31 | 32 | end 33 | 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /lib/assay/unequal_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'equal_assay' 2 | 3 | # UnequalAssay compares objects with `#!=` operator. Yes, as of Ruby 1.9 4 | # the `!=` is a redefinable method, and as such, we need a separate 5 | # assay to cover it. 6 | # 7 | class UnequalAssay < EqualAssay 8 | 9 | register :!=, :unequal 10 | 11 | # 12 | # Check assertion using `#!=` method. 13 | # 14 | def self.pass?(subject, criterion) 15 | subject != criterion 16 | end 17 | 18 | # 19 | # Failed assertion message. 20 | # 21 | def self.assert_message(subject, criterion) 22 | a = subject.inspect 23 | b = criterion.inspect 24 | 25 | if a.size > SIZE_LIMIT or b.size > SIZE_LIMIT 26 | if $ansi 27 | d = ANSI::Diff.new(a, b) 28 | a, b = d.diff1, d.diff2 # *d.to_a 29 | end 30 | "a != b\na) #{a}\nb) #{b}" 31 | else 32 | "#{a} != #{b}" 33 | end 34 | end 35 | 36 | end 37 | 38 | -------------------------------------------------------------------------------- /demo/01_assay_classes/06_unequal_assay.md: -------------------------------------------------------------------------------- 1 | ## UnequalAssay 2 | 3 | The `UnequalAssay` class defines an assertion for equality based on the `!=` 4 | method, which in Ruby 1.8 is a redefinable method all it's own. 5 | 6 | assert UnequalAssay.pass?(1, 2) 7 | assert UnequalAssay.pass?(1, 'foo') 8 | 9 | refute UnequalAssay.pass?(1, 1) 10 | refute UnequalAssay.pass?(1, 1.0) 11 | 12 | And conversely, 13 | 14 | assert UnequalAssay.fail?(1, 1) 15 | assert UnequalAssay.fail?(1, 1.0) 16 | 17 | refute UnequalAssay.fail?(1, 2) 18 | refute UnequalAssay.fail?(1, 'foo') 19 | 20 | Making assertions, 21 | 22 | assert UnequalAssay.assert!(10, 20) 23 | 24 | expect ::UnequalAssay do 25 | UnequalAssay.assert!(10, 10) 26 | end 27 | 28 | And refutations, 29 | 30 | assert UnequalAssay.refute!(10, 10) 31 | 32 | expect ::UnequalAssay do 33 | UnequalAssay.refute!(10, 20) 34 | end 35 | 36 | -------------------------------------------------------------------------------- /test/case_kind_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/kind_assay' 2 | 3 | testcase KindAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert KindAssay.pass?(1,Integer) 9 | refute KindAssay.pass?(1,String) 10 | end 11 | 12 | end 13 | 14 | class_method :fail? do 15 | 16 | test do 17 | refute KindAssay.fail?(1,Integer) 18 | assert KindAssay.fail?(1,String) 19 | end 20 | 21 | end 22 | 23 | class_method :assert! do 24 | 25 | test do 26 | KindAssay.assert!(1,Fixnum) 27 | end 28 | 29 | test do 30 | expect KindAssay do 31 | KindAssay.assert!(1,Symbol) 32 | end 33 | end 34 | 35 | end 36 | 37 | class_method :refute! do 38 | 39 | test do 40 | KindAssay.refute!(1,String) 41 | end 42 | 43 | test do 44 | expect KindAssay do 45 | KindAssay.refute!(1,Numeric) 46 | end 47 | end 48 | 49 | end 50 | 51 | end 52 | -------------------------------------------------------------------------------- /work/defunct/complex_nomenclature_system/nomenclature/shall.rb: -------------------------------------------------------------------------------- 1 | require 'ae/shall' 2 | require 'ae/nomenclature' 3 | 4 | class AE 5 | 6 | module Nomenclature 7 | 8 | # = Extended Shall Nomenclature 9 | # 10 | module Shall 11 | 12 | # Setup a predicate for this nomenclature. 13 | def self.define_predicate(pname) 14 | name = make_subjunctive(pname) 15 | super('shall', name, pname) 16 | end 17 | 18 | # Returns the predicate name without the prefix 19 | # phrase that corresponds to this nomenclature. 20 | # If the term doesn't conform to this nomenclature 21 | # then returns nil. 22 | def self.make_neutral(name) 23 | case name 24 | when /^shall_/ then $' 25 | else nil 26 | end 27 | end 28 | 29 | # Shall is a nomenclature. 30 | extend Nomenclature 31 | 32 | end #module Shall 33 | 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /lib/assay/compare_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'assertion' 2 | 3 | # Compare assertion serves primarily as a base class 4 | # for other more specific comparison assertions. 5 | # 6 | # In itself it can be used to test a comparision 7 | # made by #<=>. 8 | # 9 | class CompareAssay < Assertion 10 | 11 | # TODO: What about #cmp alias? 12 | 13 | register :<=>, :compare 14 | 15 | # 16 | # Check assertion using `<=>`. 17 | # 18 | def self.pass?(subject, criterion, result=0) 19 | (subject <=> criterion) == result 20 | end 21 | 22 | # 23 | # Error message for campare assertion. 24 | # 25 | def self.assert_message(subject, criterion, result=0) 26 | a = subject.inspect 27 | b = criterion.inspect 28 | r = result.inspect 29 | 30 | if a.size > SIZE_LIMIT or b.size > SIZE_LIMIT 31 | "a <=> b == #{r}\na) #{a}\nb) #{b}" 32 | else 33 | "#{a} <=> #{b} == #{r}" 34 | end 35 | end 36 | 37 | end 38 | 39 | -------------------------------------------------------------------------------- /test/case_identity_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/identity_assay' 2 | 3 | testcase IdentityAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert IdentityAssay.pass?(1,1) 9 | refute IdentityAssay.pass?(1,2) 10 | end 11 | 12 | end 13 | 14 | class_method :fail? do 15 | 16 | test do 17 | refute IdentityAssay.fail?(1,1) 18 | assert IdentityAssay.fail?(1,2) 19 | end 20 | 21 | end 22 | 23 | class_method :assert! do 24 | 25 | test do 26 | IdentityAssay.assert!(1,1) 27 | end 28 | 29 | test do 30 | expect IdentityAssay do 31 | IdentityAssay.assert!(1,2) 32 | end 33 | end 34 | 35 | end 36 | 37 | class_method :refute! do 38 | 39 | test do 40 | IdentityAssay.refute!(1,2) 41 | end 42 | 43 | test do 44 | expect IdentityAssay do 45 | IdentityAssay.refute!(1,1) 46 | end 47 | end 48 | 49 | end 50 | 51 | end 52 | -------------------------------------------------------------------------------- /work/defunct/complex_nomenclature_system/nomenclature/should.rb: -------------------------------------------------------------------------------- 1 | require 'ae/kernel/should' 2 | require 'ae/nomenclature' 3 | 4 | class AE 5 | 6 | module Nomenclature 7 | 8 | # = Extended Should Nomenclature 9 | # 10 | module Should 11 | 12 | # Setup a predicate for this nomenclature. 13 | def self.define_predicate(pname) 14 | name = make_subjunctive(pname) 15 | super('should', name, pname) 16 | end 17 | 18 | # Returns the predicate name without the prefix 19 | # phrase that corresponds to this nomenclature. 20 | # If the term doesn't conform to this nomenclature 21 | # then returns nil. 22 | def self.make_neutral(name) 23 | case name 24 | when /^should_/ then $' 25 | else nil 26 | end 27 | end 28 | 29 | # Should is a nomenclature. 30 | extend Nomenclature 31 | 32 | end #module Should 33 | 34 | end 35 | 36 | end 37 | -------------------------------------------------------------------------------- /demo/01_assay_classes/13_less_assay.md: -------------------------------------------------------------------------------- 1 | ## LessAssay 2 | 3 | The `LessAssay` class defines an assertion of comparison around the `#<` 4 | method. This method usually depends on the `#<=>` method via Ruby's Comparable 5 | mixin, so `LessAssay` is a subclass of `ComapreAssay`, though techincally 6 | the `#<` method can be defined independently. 7 | 8 | assert LessAssay.pass?( 1, 2) 9 | assert LessAssay.pass?(-1, 0) 10 | 11 | refute LessAssay.pass?(1, 1) 12 | refute LessAssay.pass?(1, 0) 13 | 14 | And conversely, 15 | 16 | assert LessAssay.fail?(1, 1) 17 | assert LessAssay.fail?(1, 0) 18 | 19 | refute LessAssay.fail?( 1, 2) 20 | refute LessAssay.fail?(-1, 0) 21 | 22 | This applies to any type of object that defines `#<=`, not just numbers. 23 | 24 | assert LessAssay.pass?('a', 'b') 25 | refute LessAssay.pass?('b', 'a') 26 | 27 | assert LessAssay.fail?('b', 'a') 28 | refute LessAssay.fail?('a', 'b') 29 | 30 | -------------------------------------------------------------------------------- /lib/assay/within_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'compare_assay' 2 | 3 | # TODO: Support Range for Delta comparisons. 4 | 5 | # 6 | class WithinAssay < CompareAssay 7 | 8 | register :within 9 | 10 | # 11 | # Check assertion. 12 | # 13 | def self.pass?(subject, criterion, delta) 14 | if [subject, criterion, delta].all?{ |v| Numeric === v } 15 | a, b, d = subject.to_f, criterion.to_f, delta.to_f 16 | else 17 | a, b, d = subject, criterion, delta 18 | end 19 | 20 | (b - d) <= a && (b + d) >= a 21 | end 22 | 23 | # 24 | # Failed assertion message. 25 | # 26 | def self.assert_message(subject, criterion, delta) 27 | a = subject.inspect 28 | b = criterion.inspect 29 | d = delta.inspect 30 | 31 | if [a, b, d].any?{ |e| e.size > SIZE_LIMIT } 32 | "b - d <= a <= b + d\na) #{a}\nb) #{b}\nd) #{d}" 33 | else 34 | "#{b} - #{d} <= #{a} <= #{b} + #{d}" 35 | end 36 | end 37 | 38 | end 39 | 40 | -------------------------------------------------------------------------------- /test/case_include_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/include_assay' 2 | 3 | testcase IncludeAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert IncludeAssay.pass?([1], 1) 9 | refute IncludeAssay.pass?([1], 2) 10 | end 11 | 12 | end 13 | 14 | class_method :fail? do 15 | 16 | test do 17 | refute IncludeAssay.fail?([1], 1) 18 | assert IncludeAssay.fail?([1], 2) 19 | end 20 | 21 | end 22 | 23 | class_method :assert! do 24 | 25 | test do 26 | IncludeAssay.assert!([1], 1) 27 | end 28 | 29 | test do 30 | expect IncludeAssay do 31 | IncludeAssay.assert!([1], 2) 32 | end 33 | end 34 | 35 | end 36 | 37 | class_method :refute! do 38 | 39 | test do 40 | IncludeAssay.refute!([1], 2) 41 | end 42 | 43 | test do 44 | expect IncludeAssay do 45 | IncludeAssay.refute!([1], 1) 46 | end 47 | end 48 | 49 | end 50 | 51 | end 52 | -------------------------------------------------------------------------------- /demo/applique/helper.rb: -------------------------------------------------------------------------------- 1 | 2 | # Very simple helper assertion system, so we can test 3 | # Assay without name clashes. 4 | 5 | def assert(truth, msg=nil, trace=nil) 6 | if truth 7 | increment_counts(:pass) 8 | else 9 | increment_counts(:fail) 10 | raise Assertion, msg || "assert failed", trace || caller 11 | end 12 | end 13 | 14 | def refute(truth) 15 | assert(!truth, "refute failed", caller) 16 | end 17 | 18 | def expect(error) 19 | counts = $ASSERTION_COUNTS.dup 20 | begin 21 | yield 22 | $ASSERTION_COUNTS = counts 23 | increment_counts(:fail) 24 | raise Assertion, "#{error} not raised.", caller 25 | rescue error 26 | $ASSERTION_COUNTS = counts 27 | increment_counts(:pass) 28 | end 29 | end 30 | 31 | def increment_counts(which) 32 | case which 33 | when :pass 34 | $ASSERTION_COUNTS[:pass] += 1 35 | when :fail 36 | $ASSERTION_COUNTS[:fail] += 1 37 | end 38 | $ASSERTION_COUNTS[:total] += 1 39 | end 40 | 41 | -------------------------------------------------------------------------------- /test/case_less_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/less_assay' 2 | 3 | testcase LessAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert LessAssay.pass?(1, 2) 9 | refute LessAssay.pass?(1, 1) 10 | refute LessAssay.pass?(2, 1) 11 | end 12 | 13 | end 14 | 15 | class_method :fail? do 16 | 17 | test do 18 | refute LessAssay.fail?(1, 2) 19 | assert LessAssay.fail?(1, 1) 20 | assert LessAssay.fail?(2, 1) 21 | end 22 | 23 | end 24 | 25 | class_method :assert! do 26 | 27 | test do 28 | LessAssay.assert!(1, 2) 29 | end 30 | 31 | test do 32 | expect LessAssay do 33 | LessAssay.assert!(2, 1) 34 | end 35 | end 36 | 37 | end 38 | 39 | class_method :refute! do 40 | 41 | test do 42 | LessAssay.refute!(2, 1) 43 | end 44 | 45 | test do 46 | expect LessAssay do 47 | LessAssay.refute!(1, 2) 48 | end 49 | end 50 | 51 | end 52 | 53 | end 54 | -------------------------------------------------------------------------------- /test/case_more_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/more_assay' 2 | 3 | testcase MoreAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert MoreAssay.pass?(2, 1) 9 | refute MoreAssay.pass?(1, 1) 10 | refute MoreAssay.pass?(1, 2) 11 | end 12 | 13 | end 14 | 15 | class_method :fail? do 16 | 17 | test do 18 | refute MoreAssay.fail?(2, 1) 19 | assert MoreAssay.fail?(1, 1) 20 | assert MoreAssay.fail?(1, 2) 21 | end 22 | 23 | end 24 | 25 | class_method :assert! do 26 | 27 | test do 28 | MoreAssay.assert!(2, 1) 29 | end 30 | 31 | test do 32 | expect MoreAssay do 33 | MoreAssay.assert!(1, 2) 34 | end 35 | end 36 | 37 | end 38 | 39 | class_method :refute! do 40 | 41 | test do 42 | MoreAssay.refute!(1, 2) 43 | end 44 | 45 | test do 46 | expect MoreAssay do 47 | MoreAssay.refute!(2, 1) 48 | end 49 | end 50 | 51 | end 52 | 53 | end 54 | -------------------------------------------------------------------------------- /demo/01_assay_classes/14_more_assay.md: -------------------------------------------------------------------------------- 1 | ## MoreAssay 2 | 3 | The `MoreAssay` class defines an assertion of comparison around the `#>` 4 | method. This method usually depends on the `#<=>` method via Ruby's Comparable 5 | mixin, so `MoreAssay` is a subclass of `ComapreAssay`, though techincally 6 | the `#>` method can be defined indenpendently. 7 | 8 | assert MoreAssay.pass?(2, 1) 9 | assert MoreAssay.pass?(0, -1) 10 | assert MoreAssay.pass?(1, 0) 11 | 12 | refute MoreAssay.pass?(1, 1) 13 | refute MoreAssay.pass?(1, 2) 14 | 15 | And conversely, 16 | 17 | assert MoreAssay.fail?(1, 1) 18 | assert MoreAssay.fail?(0, 1) 19 | 20 | refute MoreAssay.fail?(2, 1) 21 | refute MoreAssay.fail?(0, -1) 22 | 23 | This applies to any type of object that defines `#>`, not just numbers. 24 | 25 | assert MoreAssay.pass?('b', 'a') 26 | refute MoreAssay.pass?('a', 'b') 27 | 28 | assert MoreAssay.fail?('a', 'b') 29 | refute MoreAssay.fail?('b', 'a') 30 | -------------------------------------------------------------------------------- /lib/assay/output_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'assertion' 2 | 3 | # Assert that there is output, either from stdout or stderr. 4 | # 5 | # OutputAssay.pass?(/foo/){ puts 'foo!' } #=> true 6 | # 7 | class OutputAssay < Assertion 8 | 9 | register :output 10 | 11 | # 12 | # Compare +match+ against $stdout and $stderr via `#===` method. 13 | # 14 | # Note that $stdout and $stderr are temporarily reouted to StringIO 15 | # objects and the results have any trailing newline chomped off. 16 | # 17 | def self.pass?(match, &block) 18 | require 'stringio' 19 | 20 | begin 21 | stdout, stderr = $stdout, $stderr 22 | newout, newerr = StringIO.new, StringIO.new 23 | $stdout, $stderr = newout, newerr 24 | yield 25 | ensure 26 | $stdout, $stderr = stdout, stderr 27 | end 28 | 29 | newout, newerr = newout.string.chomp("\n"), newerr.string.chomp("\n") 30 | 31 | match === newout || match === newerr 32 | end 33 | 34 | end 35 | 36 | -------------------------------------------------------------------------------- /test/case_instance_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/instance_assay' 2 | 3 | testcase InstanceAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert InstanceAssay.pass?(1,Fixnum) 9 | refute InstanceAssay.pass?(1,Integer) 10 | end 11 | 12 | end 13 | 14 | class_method :fail? do 15 | 16 | test do 17 | refute InstanceAssay.fail?(1,Fixnum) 18 | assert InstanceAssay.fail?(1,String) 19 | end 20 | 21 | end 22 | 23 | class_method :assert! do 24 | 25 | test do 26 | InstanceAssay.assert!(1,Fixnum) 27 | end 28 | 29 | test do 30 | expect InstanceAssay do 31 | InstanceAssay.assert!(1,Symbol) 32 | end 33 | end 34 | 35 | end 36 | 37 | class_method :refute! do 38 | 39 | test do 40 | InstanceAssay.refute!(1,Numeric) 41 | end 42 | 43 | test do 44 | expect InstanceAssay do 45 | InstanceAssay.refute!(1,Fixnum) 46 | end 47 | end 48 | 49 | end 50 | 51 | end 52 | -------------------------------------------------------------------------------- /test/case_match_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/match_assay' 2 | 3 | testcase MatchAssay do 4 | 5 | class_method :pass? do 6 | test do 7 | assert MatchAssay.pass?('a', /a/) 8 | refute MatchAssay.pass?('b', /a/) 9 | refute MatchAssay.pass?('a', /b/) 10 | end 11 | end 12 | 13 | class_method :fail? do 14 | test do 15 | refute MatchAssay.fail?('a', /a/) 16 | assert MatchAssay.fail?('b', /a/) 17 | assert MatchAssay.fail?('a', /b/) 18 | end 19 | end 20 | 21 | class_method :assert! do 22 | test do 23 | MatchAssay.assert!('a', /a/) 24 | end 25 | 26 | test do 27 | expect MatchAssay do 28 | MatchAssay.assert!('a', /b/) 29 | end 30 | end 31 | end 32 | 33 | class_method :refute! do 34 | test do 35 | MatchAssay.refute!('a', /b/) 36 | end 37 | 38 | test do 39 | expect MatchAssay do 40 | MatchAssay.refute!('a', /a/) 41 | end 42 | end 43 | end 44 | 45 | end 46 | -------------------------------------------------------------------------------- /lib/assay/adapter/minitest.rb: -------------------------------------------------------------------------------- 1 | module MiniTest #:nodoc: 2 | class Unit #:nodoc: 3 | # To teach MiniTest to recognize the expanded concept of assertions 4 | # we add in an extra capture clause to the it's #puke method. 5 | def puke c, m, x 6 | case x 7 | when MiniTest::Skip 8 | @skips = @skips + 1 9 | x = "Skipped:\n#{m}(#{c}) [#{location x}]:\n#{x.message}\n" 10 | when MiniTest::Assertion 11 | @failures = @failures + 1 12 | x = "Failure:\n#{m}(#{c}) [#{location x}]:\n#{x.message}\n" 13 | when x.respond_to?(:assertion?) && x.assertion? 14 | @failures = @failures + 1 15 | x = "Failure:\n#{m}(#{c}) [#{location x}]:\n#{x.message}\n" 16 | else 17 | @errors = @errors + 1 18 | b = MiniTest::filter_backtrace(x.backtrace).join("\n ") 19 | x = "Error:\n#{m}(#{c}):\n#{x.class}: #{x.message}\n #{b}\n" 20 | end 21 | @report << x 22 | x[0, 1] 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/case_equal_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/equal_assay' 2 | 3 | testcase EqualAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert EqualAssay.pass?(1, 1) 9 | assert EqualAssay.pass?(1, 1.0) 10 | refute EqualAssay.pass?(1, 2) 11 | end 12 | 13 | end 14 | 15 | class_method :fail? do 16 | 17 | test do 18 | refute EqualAssay.fail?(1, 1) 19 | refute EqualAssay.fail?(1, 1.0) 20 | assert EqualAssay.fail?(1, 2) 21 | end 22 | 23 | end 24 | 25 | class_method :assert! do 26 | 27 | test do 28 | EqualAssay.assert!(1, 1) 29 | end 30 | 31 | test do 32 | expect EqualAssay do 33 | EqualAssay.assert!(1, 2) 34 | end 35 | end 36 | 37 | end 38 | 39 | class_method :refute! do 40 | 41 | test do 42 | EqualAssay.refute!(1, 2) 43 | end 44 | 45 | test do 46 | expect EqualAssay do 47 | EqualAssay.refute!(1, 1) 48 | end 49 | end 50 | 51 | end 52 | 53 | end 54 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/instance_of.rb: -------------------------------------------------------------------------------- 1 | require 'ae/assertions/compare' 2 | 3 | class InstanceOfFailure < CompareFailure 4 | def self.assertion_name 5 | :instance_of 6 | end 7 | 8 | def fail_message(cls, obj) 9 | "Expected #{obj} to be a #{cls}" 10 | end 11 | 12 | def fail_message!(cls, obj) 13 | "Expected #{obj} NOT to be #{cls}" 14 | end 15 | 16 | def self.check(exp, act) 17 | act.instance_of?(exp) 18 | end 19 | end 20 | 21 | module Assertable 22 | # Passes if object .instance_of? klass 23 | # 24 | # assert_instance_of(String, 'foo') 25 | # 26 | def self.instance_of(cls, obj, opts={}) 27 | opts[:backtrace] ||= caller 28 | InstanceOfFailure.assert(cls, obj, opts) 29 | end 30 | 31 | # Passes if object .instance_of? klass 32 | # 33 | # assert_instance_of(String, 'foo') 34 | # 35 | def self.not_instance_of(cls, obj, opts={}) 36 | opts[:backtrace] ||= caller 37 | InstanceOfFailure.assert!(cls, obj, opts) 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /test/case_throw_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/throw_assay' 2 | 3 | testcase ThrowAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert ThrowAssay.pass?(:foo){ throw :foo } 9 | refute ThrowAssay.pass?(:foo){ throw :bar } 10 | end 11 | 12 | end 13 | 14 | class_method :fail? do 15 | 16 | test do 17 | assert ThrowAssay.fail?(:foo){ throw :bar } 18 | refute ThrowAssay.fail?(:foo){ throw :foo } 19 | end 20 | 21 | end 22 | 23 | class_method :assert! do 24 | 25 | test do 26 | ThrowAssay.assert!(:foo){ throw :foo } 27 | end 28 | 29 | test do 30 | expect ThrowAssay do 31 | ThrowAssay.assert!(:bar){ throw :foo } 32 | end 33 | end 34 | 35 | end 36 | 37 | class_method :refute! do 38 | 39 | test do 40 | ThrowAssay.refute!(:bar){ throw :foo } 41 | end 42 | 43 | test do 44 | expect ThrowAssay do 45 | ThrowAssay.refute!(:bar){ throw :bar } 46 | end 47 | end 48 | 49 | end 50 | 51 | end 52 | -------------------------------------------------------------------------------- /test/case_nomatch_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/nomatch_assay' 2 | 3 | testcase NoMatchAssay do 4 | 5 | class_method :pass? do 6 | test do 7 | assert NoMatchAssay.pass?('b', /a/) 8 | assert NoMatchAssay.pass?('a', /b/) 9 | 10 | refute NoMatchAssay.pass?('a', /a/) 11 | end 12 | end 13 | 14 | class_method :fail? do 15 | test do 16 | refute NoMatchAssay.fail?('b', /a/) 17 | refute NoMatchAssay.fail?('a', /b/) 18 | 19 | assert NoMatchAssay.fail?('a', /a/) 20 | end 21 | end 22 | 23 | class_method :assert! do 24 | test do 25 | NoMatchAssay.assert!('a', /b/) 26 | end 27 | 28 | test do 29 | expect NoMatchAssay do 30 | NoMatchAssay.assert!('a', /a/) 31 | end 32 | end 33 | end 34 | 35 | class_method :refute! do 36 | test do 37 | NoMatchAssay.refute!('a', /a/) 38 | end 39 | 40 | test do 41 | expect NoMatchAssay do 42 | NoMatchAssay.refute!('a', /b/) 43 | end 44 | end 45 | end 46 | 47 | end 48 | -------------------------------------------------------------------------------- /test/case_nil_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/nil_assay' 2 | 3 | testcase NilAssay do 4 | 5 | class_method :pass? do 6 | test do 7 | assert NilAssay.pass?(nil) 8 | refute NilAssay.pass?(true) 9 | refute NilAssay.pass?(false) 10 | refute NilAssay.pass?(:foobar) 11 | end 12 | end 13 | 14 | class_method :fail? do 15 | test do 16 | refute NilAssay.fail?(nil) 17 | assert NilAssay.fail?(true) 18 | assert NilAssay.fail?(false) 19 | assert NilAssay.fail?(:foobar) 20 | end 21 | end 22 | 23 | class_method :assert! do 24 | test do 25 | NilAssay.assert!(nil) 26 | end 27 | 28 | test do 29 | expect NilAssay do 30 | NilAssay.assert!(false) 31 | end 32 | end 33 | end 34 | 35 | class_method :refute! do 36 | test do 37 | NilAssay.refute!(true) 38 | NilAssay.refute!(false) 39 | end 40 | 41 | test do 42 | expect NilAssay do 43 | NilAssay.refute!(nil) 44 | end 45 | end 46 | end 47 | 48 | end 49 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertable.rb: -------------------------------------------------------------------------------- 1 | require 'asserere/failures' 2 | 3 | # = Assertable 4 | # 5 | # Singleton methods defined against Assertable 6 | # are transformated into assertions corresponding 7 | # to active nomenclatures and then defined as instance 8 | # methods of Assertable. 9 | # 10 | # Example 11 | # 12 | # require 'ae/nomenclature/assert' 13 | # require 'ae/nomenclature/should' 14 | # 15 | # def Assertable.should_be_like_mike(name) 16 | # raise CompareFailure.new("Not a Mike!", caller) unless /mike/i =~ name 17 | # end 18 | # 19 | # include Assertable 20 | # 21 | # assert_like_jimmy("Jim Bo") 22 | # should_be_like_jimmy("Jim Bo") 23 | # 24 | module Assertable 25 | 26 | ObjectSpace.each_object(Class) do |cls| 27 | if cls < Failure 28 | define_method(cls.assertable_method) do |*args, &blk| 29 | opts = Hash === args.last ? args.pop : {} 30 | opts[:backtrace] ||= caller 31 | cls.check(*args, opts, &blk) 32 | end 33 | end 34 | end 35 | 36 | end 37 | 38 | -------------------------------------------------------------------------------- /demo/01_assay_classes/16_more_equal_assay.md: -------------------------------------------------------------------------------- 1 | ## MoreEqualAssay 2 | 3 | The `MoreEqualAssay` class defines an assertion of comparison around the `#>=` 4 | method. This method usually depends on the `#<=>` method via Ruby's Comparable 5 | mixin, so `MoreEqualAssay` is a subclass of `ComapreAssay`, though techincally 6 | the `#>=` method can be defined indenpendently. 7 | 8 | assert MoreEqualAssay.pass?(2, 1) 9 | assert MoreEqualAssay.pass?(0, -1) 10 | assert MoreEqualAssay.pass?(1, 1) 11 | 12 | refute MoreEqualAssay.pass?(0, 1) 13 | 14 | And conversely, 15 | 16 | assert MoreEqualAssay.fail?(0, 1) 17 | 18 | refute MoreEqualAssay.fail?( 1, 1) 19 | refute MoreEqualAssay.fail?( 2, 1) 20 | refute MoreEqualAssay.fail?( 0, -1) 21 | 22 | This applies to any type of object that defines `#<=`, not just numbers. 23 | 24 | assert MoreEqualAssay.pass?('b', 'a') 25 | refute MoreEqualAssay.pass?('a', 'b') 26 | 27 | assert MoreEqualAssay.fail?('a', 'b') 28 | refute MoreEqualAssay.fail?('b', 'a') 29 | 30 | -------------------------------------------------------------------------------- /test/case_respond_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/respond_assay' 2 | 3 | testcase RespondAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert RespondAssay.pass?(:symbol, :to_s) 9 | refute RespondAssay.pass?(:symbol, :no_method) 10 | end 11 | 12 | end 13 | 14 | class_method :fail? do 15 | 16 | test do 17 | refute RespondAssay.fail?(:symbol, :to_s) 18 | assert RespondAssay.fail?(:symbol, :no_method) 19 | end 20 | 21 | end 22 | 23 | class_method :assert! do 24 | 25 | test do 26 | RespondAssay.assert!(:symbol, :to_s) 27 | end 28 | 29 | test do 30 | expect RespondAssay do 31 | RespondAssay.assert!(:symbol, :no_method) 32 | end 33 | end 34 | 35 | end 36 | 37 | class_method :refute! do 38 | 39 | test do 40 | RespondAssay.refute!(:symbol, :no_method) 41 | end 42 | 43 | test do 44 | expect RespondAssay do 45 | RespondAssay.refute!(:symbol, :to_s) 46 | end 47 | end 48 | 49 | end 50 | 51 | end 52 | -------------------------------------------------------------------------------- /test/case_unequal_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/unequal_assay' 2 | 3 | testcase UnequalAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert UnequalAssay.pass?(1, 2) 9 | 10 | refute UnequalAssay.pass?(1, 1) 11 | refute UnequalAssay.pass?(1, 1.0) 12 | end 13 | 14 | end 15 | 16 | class_method :fail? do 17 | 18 | test do 19 | assert UnequalAssay.fail?(1, 1) 20 | assert UnequalAssay.fail?(1, 1.0) 21 | 22 | refute UnequalAssay.fail?(1, 2) 23 | end 24 | 25 | end 26 | 27 | class_method :assert! do 28 | 29 | test do 30 | UnequalAssay.assert!(1, 2) 31 | end 32 | 33 | test do 34 | expect UnequalAssay do 35 | UnequalAssay.assert!(1, 1) 36 | end 37 | end 38 | 39 | end 40 | 41 | class_method :refute! do 42 | 43 | test do 44 | UnequalAssay.refute!(1, 1) 45 | end 46 | 47 | test do 48 | expect UnequalAssay do 49 | UnequalAssay.refute!(1, 2) 50 | end 51 | end 52 | 53 | end 54 | 55 | end 56 | -------------------------------------------------------------------------------- /demo/01_assay_classes/15_less_equal_assay.md: -------------------------------------------------------------------------------- 1 | ## LessEqualAssay 2 | 3 | The `LessEqualAssay` class defines an assertion of comparison around the `#<=` 4 | method. This method usually depends on the `#<=>` method via Ruby's Comparable 5 | mixin, so `LessEqualAssay` is a subclass of `ComapreAssay`, though techincally 6 | the `#<=` method can be defined indenpendently. 7 | 8 | assert LessEqualAssay.pass?( 1, 2) 9 | assert LessEqualAssay.pass?(-1, 0) 10 | assert LessEqualAssay.pass?( 1, 1) 11 | 12 | refute LessEqualAssay.pass?(1, 0) 13 | 14 | And conversely, 15 | 16 | assert LessEqualAssay.fail?(1, 0) 17 | 18 | refute LessEqualAssay.fail?( 1, 1) 19 | refute LessEqualAssay.fail?( 1, 2) 20 | refute LessEqualAssay.fail?(-1, 0) 21 | 22 | This applies to any type of object that defines `#<=`, not just numbers. 23 | 24 | assert LessEqualAssay.pass?('a', 'b') 25 | refute LessEqualAssay.pass?('b', 'a') 26 | 27 | assert LessEqualAssay.fail?('b', 'a') 28 | refute LessEqualAssay.fail?('a', 'b') 29 | 30 | 31 | -------------------------------------------------------------------------------- /demo/01_assay_classes/23_return_assay.md: -------------------------------------------------------------------------------- 1 | ## ReturnAssay 2 | 3 | The `ReturnAssay` asserts that a procedure runs without error and returns 4 | a specified result. 5 | 6 | assert ReturnAssay.pass?(:foo){ :foo } 7 | assert ReturnAssay.pass?(true){ true } 8 | 9 | refute ReturnAssay.pass?(:foo){ :bar } 10 | refute ReturnAssay.pass?(:foo){ true } 11 | refute ReturnAssay.pass?(:foo){ raise } 12 | 13 | And conversely, 14 | 15 | assert ReturnAssay.fail?(:foo){ :bar } 16 | assert ReturnAssay.fail?(:foo){ true } 17 | assert ReturnAssay.fail?(:foo){ raise } 18 | 19 | refute ReturnAssay.fail?(:foo){ :foo } 20 | refute ReturnAssay.fail?(true){ true } 21 | 22 | Making assertions, 23 | 24 | assert ReturnAssay.assert!(true){ true } 25 | 26 | expect ::ReturnAssay do 27 | assert ReturnAssay.assert!(:foo){ :bar } 28 | end 29 | 30 | And refutations, 31 | 32 | assert ReturnAssay.refute!(:foo){ :bar } 33 | 34 | expect ::ReturnAssay do 35 | assert ReturnAssay.refute!(:foo){ :foo } 36 | end 37 | 38 | -------------------------------------------------------------------------------- /test/case_less_equal_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/less_equal_assay' 2 | 3 | testcase LessEqualAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert LessEqualAssay.pass?(1, 2) 9 | assert LessEqualAssay.pass?(1, 1) 10 | refute LessEqualAssay.pass?(2, 1) 11 | end 12 | 13 | end 14 | 15 | class_method :fail? do 16 | 17 | test do 18 | refute LessEqualAssay.fail?(1, 2) 19 | refute LessEqualAssay.fail?(1, 1) 20 | assert LessEqualAssay.fail?(2, 1) 21 | end 22 | 23 | end 24 | 25 | class_method :assert! do 26 | 27 | test do 28 | LessEqualAssay.assert!(1, 2) 29 | end 30 | 31 | test do 32 | expect LessEqualAssay do 33 | LessEqualAssay.assert!(2, 1) 34 | end 35 | end 36 | 37 | end 38 | 39 | class_method :refute! do 40 | 41 | test do 42 | LessEqualAssay.refute!(2, 1) 43 | end 44 | 45 | test do 46 | expect LessEqualAssay do 47 | LessEqualAssay.refute!(1, 2) 48 | end 49 | end 50 | 51 | end 52 | 53 | end 54 | -------------------------------------------------------------------------------- /test/case_more_equal_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/more_equal_assay' 2 | 3 | testcase MoreEqualAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert MoreEqualAssay.pass?(2, 1) 9 | assert MoreEqualAssay.pass?(1, 1) 10 | refute MoreEqualAssay.pass?(1, 2) 11 | end 12 | 13 | end 14 | 15 | class_method :fail? do 16 | 17 | test do 18 | refute MoreEqualAssay.fail?(2, 1) 19 | refute MoreEqualAssay.fail?(1, 1) 20 | assert MoreEqualAssay.fail?(1, 2) 21 | end 22 | 23 | end 24 | 25 | class_method :assert! do 26 | 27 | test do 28 | MoreEqualAssay.assert!(2, 1) 29 | end 30 | 31 | test do 32 | expect MoreEqualAssay do 33 | MoreEqualAssay.assert!(1, 2) 34 | end 35 | end 36 | 37 | end 38 | 39 | class_method :refute! do 40 | 41 | test do 42 | MoreEqualAssay.refute!(1, 2) 43 | end 44 | 45 | test do 46 | expect MoreEqualAssay do 47 | MoreEqualAssay.refute!(2, 1) 48 | end 49 | end 50 | 51 | end 52 | 53 | end 54 | -------------------------------------------------------------------------------- /test/case_raise_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/raise_assay' 2 | 3 | testcase RaiseAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert RaiseAssay.pass?(StandardError){ raise } 9 | refute RaiseAssay.pass?(ArgumentError){ raise } 10 | end 11 | 12 | end 13 | 14 | class_method :fail? do 15 | 16 | test do 17 | refute RaiseAssay.fail?(StandardError){ raise } 18 | assert RaiseAssay.fail?(ArgumentError){ raise } 19 | end 20 | 21 | end 22 | 23 | class_method :assert! do 24 | 25 | test do 26 | RaiseAssay.assert!(StandardError){ raise } 27 | end 28 | 29 | test do 30 | expect RaiseAssay do 31 | RaiseAssay.assert!(ArgumentError){ raise } 32 | end 33 | end 34 | 35 | end 36 | 37 | class_method :refute! do 38 | 39 | test do 40 | RaiseAssay.refute!(ArgumentError){ raise } 41 | end 42 | 43 | test do 44 | expect RaiseAssay do 45 | RaiseAssay.refute!(StandardError){ raise } 46 | end 47 | end 48 | 49 | end 50 | 51 | end 52 | -------------------------------------------------------------------------------- /test/case_true_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/true_assay' 2 | 3 | testcase TrueAssay do 4 | 5 | class_method :pass? do 6 | test do 7 | assert TrueAssay.pass?(true) 8 | refute TrueAssay.pass?(nil) 9 | refute TrueAssay.pass?(false) 10 | refute TrueAssay.pass?(:foobar) 11 | end 12 | end 13 | 14 | class_method :fail? do 15 | test do 16 | refute TrueAssay.fail?(true) 17 | assert TrueAssay.fail?(nil) 18 | assert TrueAssay.fail?(false) 19 | assert TrueAssay.fail?(:foobar) 20 | end 21 | end 22 | 23 | class_method :assert! do 24 | test do 25 | TrueAssay.assert!(true) 26 | end 27 | 28 | test do 29 | expect TrueAssay do 30 | TrueAssay.assert!(false) 31 | end 32 | end 33 | end 34 | 35 | class_method :refute! do 36 | test do 37 | TrueAssay.refute!(nil) 38 | TrueAssay.refute!(false) 39 | end 40 | 41 | test do 42 | expect TrueAssay do 43 | TrueAssay.refute!(true) 44 | end 45 | end 46 | end 47 | 48 | end 49 | -------------------------------------------------------------------------------- /work/defunct/static_assertion_methods/matchers/class.rb: -------------------------------------------------------------------------------- 1 | module Assay 2 | 3 | # Examples 4 | # 5 | # "string".it IsLike[/string/i] 6 | # 7 | # "string".it IsKind[String] 8 | # 9 | # case 10.1 10 | # when IsInstance[Fixnum] 11 | # when IsWithin[0.2, 10] 12 | # when IsMatch[/\d+\.\d+/] 13 | # end 14 | # 15 | module IsClasses 16 | 17 | IsLike = Assay::CompareFailure 18 | IsWithin = Assay::DeltaFailure 19 | IsEqual = Assay::EqualityFailure 20 | IsExecuted = Assay::ExecutionFailure 21 | IsFalse = Assay::FalseFailure 22 | IsIdentical = Assay::IdentityFailure 23 | IsInstance = Assay::InstanceFailure 24 | IsKind = Assay::KindFailure 25 | IsMatch = Assay::MatchFailure 26 | IsNil = Assay::NilFailure 27 | IsRaised = Assay::RaiseFailure 28 | IsResponsive = Assay::RespondFailure 29 | IsSame = Assay::SameFailure 30 | IsThrown = Assay::ThrowFailure 31 | IsTrue = Assay::TrueFailure 32 | 33 | end 34 | 35 | end 36 | 37 | -------------------------------------------------------------------------------- /test/case_equality_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/equality_assay' 2 | 3 | testcase EqualityAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert EqualityAssay.pass?(1, 1) 9 | 10 | refute EqualityAssay.pass?(1, 1.0) 11 | refute EqualityAssay.pass?(1, 2) 12 | end 13 | 14 | end 15 | 16 | class_method :fail? do 17 | 18 | test do 19 | refute EqualityAssay.fail?(1, 1) 20 | 21 | assert EqualityAssay.fail?(1, 1.0) 22 | assert EqualityAssay.fail?(1, 2) 23 | end 24 | 25 | end 26 | 27 | class_method :assert! do 28 | 29 | test do 30 | EqualityAssay.assert!(1, 1) 31 | end 32 | 33 | test do 34 | expect EqualityAssay do 35 | EqualityAssay.assert!(1, 2) 36 | end 37 | end 38 | 39 | end 40 | 41 | class_method :refute! do 42 | 43 | test do 44 | EqualityAssay.refute!(1, 1.0) 45 | end 46 | 47 | test do 48 | expect EqualityAssay do 49 | EqualityAssay.refute!(1, 1) 50 | end 51 | end 52 | 53 | end 54 | 55 | end 56 | -------------------------------------------------------------------------------- /test/case_false_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/false_assay' 2 | 3 | testcase FalseAssay do 4 | 5 | class_method :pass? do 6 | test do 7 | assert FalseAssay.pass?(false) 8 | refute FalseAssay.pass?(true) 9 | refute FalseAssay.pass?(nil) 10 | refute FalseAssay.pass?(:foobar) 11 | end 12 | end 13 | 14 | class_method :fail? do 15 | test do 16 | refute FalseAssay.fail?(false) 17 | assert FalseAssay.fail?(true) 18 | assert FalseAssay.fail?(nil) 19 | assert FalseAssay.fail?(:foobar) 20 | end 21 | end 22 | 23 | class_method :assert! do 24 | test do 25 | FalseAssay.assert!(false) 26 | end 27 | 28 | test do 29 | expect FalseAssay do 30 | FalseAssay.assert!(nil) 31 | end 32 | end 33 | end 34 | 35 | class_method :refute! do 36 | test do 37 | FalseAssay.refute!(true) 38 | FalseAssay.refute!(nil) 39 | end 40 | 41 | test do 42 | expect FalseAssay do 43 | FalseAssay.refute!(false) 44 | end 45 | end 46 | end 47 | 48 | end 49 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/match.rb: -------------------------------------------------------------------------------- 1 | require 'ae/assertions/compare' 2 | 3 | # 4 | class MatchFailure < CompareFailure 5 | def self.assertion_name 6 | :match 7 | end 8 | 9 | def fail_message(exp, act) 10 | "Expected #{act.inspect} to match #{exp.inspect}" 11 | end 12 | 13 | def fail_message!(exp, act) 14 | "Expected #{act.inspect} NOT to match #{exp.inspect}" 15 | end 16 | 17 | def self.check(exp, act) 18 | act =~ exp 19 | end 20 | 21 | def self.check!(exp, act) 22 | act !~ exp 23 | end 24 | end 25 | 26 | module Assertable 27 | # Passes if string =~ pattern. 28 | # 29 | # assert_match(/\d+/, 'five, 6, seven') 30 | # 31 | def self.match(exp, act, opts={}) 32 | opts[:backtrace] ||= caller 33 | MatchFailure.assert(exp, act, opts) 34 | end 35 | 36 | # Passes if regexp !~ string 37 | # 38 | # assert_no_match(/two/, 'one 2 three') 39 | # 40 | def self.no_match(exp, act, opts={}) 41 | opts[:backtrace] ||= caller 42 | MatchFailure.assert!(exp, act, opts={}) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /work/defunct/complex_nomenclature_system/nomenclature/verify.rb: -------------------------------------------------------------------------------- 1 | require 'ae/verify' 2 | require 'ae/nomenclature' 3 | 4 | class AE 5 | 6 | module Nomenclature 7 | 8 | # = Extended Verify Nomenclature 9 | # 10 | module Verify 11 | 12 | # Setup a predicate for this nomenclature. 13 | def self.define_predicate(pname) 14 | name = make_interjective(pname) 15 | name = case name 16 | when /^is/ then "#{name.sub('is_','')}" 17 | else "#{name}" 18 | end 19 | super('verify', name, pname) 20 | end 21 | 22 | # Returns the predicate name without the prefix 23 | # phrase that corresponds to this nomenclature. 24 | # If the term doesn't conform to this nomenclature 25 | # then returns nil. 26 | def self.make_neutral(name) 27 | case name 28 | when /^verify_/ then $' 29 | else nil 30 | end 31 | end 32 | 33 | # Verify is a nomenclature. 34 | extend Nomenclature 35 | 36 | end #module Verify 37 | 38 | end 39 | 40 | end 41 | -------------------------------------------------------------------------------- /test/case_like_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/like_assay' 2 | 3 | testcase LikeAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert LikeAssay.pass?(1, 1) 9 | assert LikeAssay.pass?(1, 1.0) 10 | assert LikeAssay.pass?(1, Integer) 11 | 12 | refute LikeAssay.pass?(1, 2) 13 | end 14 | 15 | end 16 | 17 | class_method :fail? do 18 | 19 | test do 20 | refute LikeAssay.fail?(1, 1) 21 | refute LikeAssay.fail?(1, 1.0) 22 | refute LikeAssay.fail?(1, Integer) 23 | 24 | assert LikeAssay.fail?(1, 2) 25 | end 26 | 27 | end 28 | 29 | class_method :assert! do 30 | 31 | test do 32 | LikeAssay.assert!(1, Numeric) 33 | end 34 | 35 | test do 36 | expect LikeAssay do 37 | LikeAssay.assert!(1, 2) 38 | end 39 | end 40 | 41 | end 42 | 43 | class_method :refute! do 44 | 45 | test do 46 | LikeAssay.refute!(1, 2) 47 | end 48 | 49 | test do 50 | expect LikeAssay do 51 | LikeAssay.refute!(1, 1) 52 | end 53 | end 54 | 55 | end 56 | 57 | end 58 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/compare.rb: -------------------------------------------------------------------------------- 1 | require 'assertion' 2 | 3 | class CompareFailure < Assertion 4 | def self.assertion_name 5 | :like 6 | end 7 | 8 | def self.fail_message(exp, act) 9 | "Expected #{act.inspect} to be like #{exp.inspect}" 10 | end 11 | 12 | def self.fail_message!(exp, act) 13 | "Expected #{act.inspect} NOT to be like #{exp.inspect}" 14 | end 15 | 16 | def self.check(exp, act) 17 | exp.equals?(act) || 18 | exp.eq?(act) || 19 | exp.==(act) || 20 | exp.===(act) 21 | end 22 | end 23 | 24 | module Assertable 25 | # Passes if +actual+ .equte? +expected+. 26 | # 27 | # o = Object.new 28 | # assert_like(o, o) 29 | # 30 | def self.like(exp, act, opts={}) 31 | opts[:backtrace] ||= caller 32 | CompareFailure.assert(exp, act, opts) 33 | end 34 | 35 | # Passes if ! actual .equte? expected 36 | # 37 | # assert_not_like(Object.new, Object.new) 38 | # 39 | def self.not_like(exp, act, opts) 40 | opts[:backtrace] ||= caller 41 | CompareFailure.assert(exp, act, opts) 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/compare.rb: -------------------------------------------------------------------------------- 1 | require 'assertion' 2 | 3 | class CompareFailure < Assertion 4 | def self.assertion_name 5 | :like 6 | end 7 | 8 | def self.fail_message(exp, act) 9 | "Expected #{act.inspect} to be like #{exp.inspect}" 10 | end 11 | 12 | def self.fail_message!(exp, act) 13 | "Expected #{act.inspect} NOT to be like #{exp.inspect}" 14 | end 15 | 16 | def self.check(exp, act) 17 | exp.equals?(act) || 18 | exp.eq?(act) || 19 | exp.==(act) || 20 | exp.===(act) 21 | end 22 | end 23 | 24 | module Assertable 25 | # Passes if +actual+ .equte? +expected+. 26 | # 27 | # o = Object.new 28 | # assert_like(o, o) 29 | # 30 | def self.like(exp, act, opts={}) 31 | opts[:backtrace] ||= caller 32 | CompareFailure.assert(exp, act, opts) 33 | end 34 | 35 | # Passes if ! actual .equte? expected 36 | # 37 | # assert_not_like(Object.new, Object.new) 38 | # 39 | def self.not_like(exp, act, opts) 40 | opts[:backtrace] ||= caller 41 | CompareFailure.assert(exp, act, opts) 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /lib/assay/close_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'compare_assay' 2 | 3 | # Relative approximation, sometimes refered to as *within epsilon*. 4 | # 5 | class CloseAssay < CompareAssay 6 | 7 | register :close 8 | 9 | # 10 | # Check assertion. 11 | # 12 | def self.pass?(subject, criterion, epsilon) 13 | #if [subject, criterion, epsilon].all?{ |v| Numeric === v } 14 | a, b, e = subject.to_f, criterion.to_f, epsilon.to_f 15 | #else 16 | # a, b, e = subject, criterion, epsilon 17 | #end 18 | 19 | #(a - b).abs / [a.abs, b.abs].max <= e 20 | 21 | d = b * e # [a.abs,b.abs].max * e 22 | 23 | (b - d) <= a && (b + d) >= a 24 | end 25 | 26 | # 27 | # Failed assertion message. 28 | # 29 | def self.assert_message(subject, criterion, delta) 30 | a = subject.inspect 31 | b = criterion.inspect 32 | e = delta.inspect 33 | 34 | if [a, b, e].any?{ |e| e.to_s.size > SIZE_LIMIT } 35 | "b(1 - e) <= a <= b(1 + e)\na) #{a}\nb) #{b}\nd) #{d}" 36 | else 37 | "#{b}(1 - #{e}) <= #{a} <= #{b}(1 + #{e})" 38 | end 39 | end 40 | 41 | end 42 | 43 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/identity.rb: -------------------------------------------------------------------------------- 1 | require 'ae/assertions/compare' 2 | 3 | class IdentityFailure < CompareFailure 4 | def self.assertion_name 5 | :identical 6 | end 7 | 8 | def fail_message(exp, act) 9 | "Expected #{act.inspect} to be identical to #{exp.inspect}" 10 | end 11 | 12 | def fail_message!(exp, act) 13 | "Expected #{act.inspect} NOT to be identical to #{exp.inspect}" 14 | end 15 | 16 | def self.check(exp, act) 17 | exp.equal?(act) 18 | end 19 | end 20 | 21 | module Assertable 22 | # Passes if +actual+ .equal? +expected+ (i.e. they are the same instance). 23 | # 24 | # o = Object.new 25 | # assert_identical(o, o) 26 | # 27 | def self.identical(exp, act, opts={}) 28 | opts[:backtrace] ||= caller 29 | Identityfailure.assert(exp, act, opts) 30 | end 31 | 32 | # Passes if ! actual .equal? expected 33 | # 34 | # assert_not_identical(Object.new, Object.new) 35 | # 36 | def self.not_identical(exp, act, opts={}) 37 | opts[:backtrace] ||= caller 38 | IdentityFailure.assert!(exp, act, opts) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /demo/01_assay_classes/17_close_assay.md: -------------------------------------------------------------------------------- 1 | ## CloseAssay 2 | 3 | The `CloseAssay` class defines an assertion for matching that two values 4 | are within a relative difference. 5 | 6 | assert CloseAssay.pass?(1, 1, 0) 7 | assert CloseAssay.pass?(1, 1.1, 0.1) 8 | 9 | refute CloseAssay.pass?(1, 2, 0) 10 | refute CloseAssay.pass?(1, 1.2, 0.1) 11 | 12 | And conversely, 13 | 14 | assert CloseAssay.fail?(1, 2, 0) 15 | assert CloseAssay.fail?(1, 1.2, 0.1) 16 | 17 | refute CloseAssay.fail?(1, 1, 0) 18 | refute CloseAssay.fail?(1, 1.1, 0.1) 19 | 20 | The object do not have to be numbers necessaity, just so long as they 21 | are comparable and subtractable. 22 | 23 | time = Time.now 24 | 25 | assert CloseAssay.pass?(time, time+1, 2) 26 | 27 | Making assertions, 28 | 29 | assert CloseAssay.assert!(10, 11, 1) 30 | 31 | expect ::CloseAssay do 32 | CloseAssay.assert!(10, 15, 0.25) 33 | end 34 | 35 | And refutations, 36 | 37 | assert CloseAssay.refute!(10, 11, 0.01) 38 | 39 | expect ::CloseAssay do 40 | CloseAssay.refute!(10, 11, 1) 41 | end 42 | 43 | -------------------------------------------------------------------------------- /demo/01_assay_classes/17_within_assay.md: -------------------------------------------------------------------------------- 1 | ## WithinAssay 2 | 3 | The `WithinAssay` class defines an assertion for matching that two values 4 | lie with a range. 5 | 6 | assert WithinAssay.pass?(1, 1, 0) 7 | assert WithinAssay.pass?(1, 1.1, 0.1) 8 | 9 | refute WithinAssay.pass?(1, 2, 0) 10 | refute WithinAssay.pass?(1, 1.2, 0.1) 11 | 12 | And conversely, 13 | 14 | assert WithinAssay.fail?(1, 2, 0) 15 | assert WithinAssay.fail?(1, 1.2, 0.1) 16 | 17 | refute WithinAssay.fail?(1, 1, 0) 18 | refute WithinAssay.fail?(1, 1.1, 0.1) 19 | 20 | The object do not have to be numbers necessaity, just so long as they 21 | are comparable and subtractable. 22 | 23 | time = Time.now 24 | 25 | assert WithinAssay.pass?(time, time+1, 2) 26 | 27 | Making assertions, 28 | 29 | assert WithinAssay.assert!(10, 11, 1) 30 | 31 | expect ::WithinAssay do 32 | WithinAssay.assert!(10, 15, 2) 33 | end 34 | 35 | And refutations, 36 | 37 | assert WithinAssay.refute!(10, 11, 0.1) 38 | 39 | expect ::WithinAssay do 40 | WithinAssay.refute!(10, 11, 1) 41 | end 42 | 43 | -------------------------------------------------------------------------------- /work/defunct/complex_nomenclature_system/nomenclature/will.rb: -------------------------------------------------------------------------------- 1 | require 'ae/will' 2 | require 'ae/nomenclature' 3 | 4 | class AE 5 | 6 | module Nomenclature 7 | 8 | # = Extended Will Nomenclature 9 | # 10 | module Will #:nodoc: 11 | 12 | # Define a predicate for this nomenclature. 13 | def self.define_predicate(pname) 14 | name = make_subjunctive(pname) 15 | super('will', name, pname) 16 | case name 17 | when /^will_not/ 18 | alias_method "wont_{$'}", name 19 | end 20 | end 21 | 22 | # Returns the predicate name without the prefix 23 | # phrase that corresponds to this nomenclature. 24 | # If the term doesn't conform to this nomenclature 25 | # then returns nil. 26 | def self.make_neutral(name) 27 | case name 28 | when /^will_have_been_/ then "has_#{$'}" 29 | when /^will_be_/ then $' 30 | when /^will_/ then $' 31 | else nil 32 | end 33 | end 34 | 35 | # Will is a nomenclature. 36 | extend Nomenclature 37 | 38 | end #module Will 39 | 40 | end 41 | 42 | end 43 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/execution.rb: -------------------------------------------------------------------------------- 1 | require 'assertion' 2 | require 'ae/assertable' 3 | 4 | class ExecutionFailure < Assertion 5 | 6 | def fail_message 7 | "Expected procedure to execute sucessfully" 8 | end 9 | 10 | def fail_message! 11 | "Expected procedure not execute sucessfully" 12 | end 13 | 14 | def check(&blk) 15 | begin 16 | blk.call 17 | true 18 | rescure Exception 19 | false 20 | end 21 | end 22 | 23 | end 24 | 25 | module Assertable 26 | 27 | # Passes if the block yields successfully. 28 | # 29 | # assert_executes "Couldn't do the thing" do 30 | # do_the_thing 31 | # end 32 | # 33 | def self.executes(opts={}, &blk) # :yield: 34 | opts[:backtrace] ||= caller 35 | EcecutionFailure.assert(opts, &blk) 36 | end 37 | 38 | # Passes if the block does not yield successfully. 39 | # 40 | # assert_not_executing "Couldn't do the thing" do 41 | # do_the_thing 42 | # end 43 | # 44 | def self.not_executing(opts={}, &blk) # :yield: 45 | opts[:backtrace] ||= caller 46 | EcecutionFailure.assert!(opts, &blk) 47 | end 48 | 49 | end 50 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/kind_of.rb: -------------------------------------------------------------------------------- 1 | require 'ae/assertions/compare' 2 | 3 | # Passes if object .kind_of? cls 4 | # 5 | # assert_kind_of(Object, 'foo') 6 | # 7 | # === Contemporary 8 | # 9 | # 'foo'.assert.kind_of?(Object) 10 | # 11 | class KindOfFailure < CompareFailure 12 | def self.assertion_name 13 | :kind_of 14 | end 15 | 16 | def fail_message(cls, obj) 17 | "Expected #{obj.inspect} to be a kind of #{cls}" 18 | end 19 | 20 | def fail_message!(cls, obj) 21 | "Expected #{obj.inspect} to NOT be a kind of #{cls}" 22 | end 23 | 24 | def check(cls, obj) 25 | obj.kind_of?(cls) 26 | end 27 | end 28 | 29 | module Assertable 30 | # Passes if object .kind_of? klass 31 | # 32 | # assert_kind_of(Object, 'foo') 33 | # 34 | def self.kind_of(cls, obj, opts={}) 35 | opts[:backtrace] ||= caller 36 | KindOfFailure.assert(cls, obj, opts={}) 37 | end 38 | 39 | # Passes if object .kind_of? klass 40 | # 41 | # assert_kind_of(Object, 'foo') 42 | # 43 | def self.not_kind_of(cls, obj, opts={}) 44 | opts[:backtrace] ||= caller 45 | KindOfFailure.assert!(cls, obj, opts) 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /lib/assay/return_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'execution_assay' 2 | 3 | # Assert that a block of code returns a specific result, also 4 | # fails if an error is raised in the block. 5 | # 6 | class ReturnAssay < ExecutionAssay 7 | 8 | register :returns 9 | 10 | # 11 | # Check that a block returns a specific value comparing 12 | # the +returns+ argument and actual returned value with 13 | # the `#==` operator. 14 | # 15 | def self.pass?(returns, *arguments) #:yield: 16 | begin 17 | result = yield(*arguments) 18 | returns == result 19 | rescue Exception 20 | false 21 | end 22 | end 23 | 24 | # 25 | # Check that a block does NOT return a specific value comparing 26 | # the +returns+ argument and actual returned value with 27 | # the `#==` operator. 28 | # 29 | def self.fail?(returns, *arguments) #:yield: 30 | begin 31 | result = yield(*arguments) 32 | returns != result 33 | rescue Exception 34 | true 35 | end 36 | end 37 | 38 | ## 39 | ## 40 | ## 41 | #def self.assert_message(*arguments, &block) 42 | # "#{block}.call(*#{arguments.inspect})" 43 | #end 44 | 45 | end 46 | 47 | -------------------------------------------------------------------------------- /work/defunct/complex_nomenclature_system/nomenclature/expect.rb: -------------------------------------------------------------------------------- 1 | require 'ae/expect' 2 | require 'ae/nomenclature' 3 | 4 | class AE 5 | 6 | module Nomenclature 7 | 8 | # = Extended Expect Nomenclature 9 | # 10 | module Expect 11 | 12 | # Setup a predicate for this nomenclature. 13 | def self.define_predicate(pname) 14 | name = make_interjective(pname) 15 | name = case name 16 | when /^is/ then "#{name.sub('is_','')}" 17 | else "#{name}" 18 | end 19 | super('expect', name, pname) 20 | end 21 | 22 | # Returns the predicate name without the prefix 23 | # phrase that corresponds to this nomenclature. 24 | # If the term doesn't conform to this nomenclature 25 | # then returns nil. 26 | def self.make_neutral(name) 27 | case name 28 | when /^expect_/ then $' 29 | else nil 30 | end 31 | end 32 | 33 | # Expect is a nomenclature. 34 | # This is done last to prevent any Nomenclature 35 | # callbacks from triggering on the above definitions. 36 | extend Nomenclature 37 | 38 | end #module Expect 39 | 40 | end 41 | 42 | end 43 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/in_delta.rb: -------------------------------------------------------------------------------- 1 | require 'ae/assertions/compare' 2 | 3 | class InDeltaFailure < CompareFailure 4 | def self.assertion_name 5 | :in_delta 6 | end 7 | 8 | def self.fail_message(exp, act, delta) 9 | "Expected #{exp} to be within #{delta} of #{act}" 10 | end 11 | 12 | def self.fail_message!(exp, act, delta) 13 | "Expected #{exp} NOT to be within #{delta} of #{act}" 14 | end 15 | 16 | def self.check(exp, act, delta) 17 | (exp.to_f - act.to_f).abs <= delta.to_f 18 | end 19 | end 20 | 21 | module Assertable 22 | # Passes if expected_float and actual_float are equal within delta tolerance. 23 | # 24 | # assert_in_delta 0.05, (50000.0 / 10**6), 0.00001 25 | # 26 | def self.in_delta(exp, act, delta, opts={}) 27 | opts[:backtrace] ||= caller 28 | InDeltaFailure.assert(exp, act, delta, opts) 29 | end 30 | 31 | # Passes if expected_float and actual_float are equal not within delta tolerance. 32 | # 33 | # assert_not_in_delta 0.05, (50000.0 / 10**6), 0.00001 34 | # 35 | def self.not_in_delta(exp, act, delta, opts) 36 | opts[:backtrace] ||= caller 37 | InDeltaFailure.assert!(exp, act, delta, opts) 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /demo/01_assay_classes/30_output_assay.md: -------------------------------------------------------------------------------- 1 | ## OutputAssay 2 | 3 | The `OutputAssay` asserts that a output is sent to either `$stdout` or `$stderr`. 4 | 5 | Let's do the simple stdout case first. 6 | 7 | assert OutputAssay.pass?('foo'){ puts 'foo' } 8 | 9 | refute OutputAssay.pass?('foo'){ nil } 10 | refute OutputAssay.pass?('foo'){ puts 'bar' } 11 | 12 | And conversely, 13 | 14 | refute OutputAssay.fail?('foo'){ puts 'foo' } 15 | 16 | assert OutputAssay.fail?('foo'){ nil } 17 | assert OutputAssay.fail?('foo'){ puts 'bar' } 18 | 19 | Now the same for `$stderr`. 20 | 21 | assert OutputAssay.pass?('foo'){ $stderr.puts 'foo' } 22 | 23 | refute OutputAssay.pass?('foo'){ nil } 24 | refute OutputAssay.pass?('foo'){ $stderr.puts 'bar' } 25 | 26 | And conversely, 27 | 28 | refute OutputAssay.fail?('foo'){ $stderr.puts 'foo' } 29 | 30 | assert OutputAssay.fail?('foo'){ nil } 31 | assert OutputAssay.fail?('foo'){ $stderr.puts 'bar' } 32 | 33 | The OutputAssay uses `#===` to test the match so we can also 34 | match against a regular expression. 35 | 36 | assert OutputAssay.pass?(/f/){ puts 'foo' } 37 | 38 | assert OutputAssay.pass?(/f/){ $stderr.puts 'foo' } 39 | 40 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/same.rb: -------------------------------------------------------------------------------- 1 | require 'ae/assertions/compare' 2 | 3 | class SameFailure < CompareFailure 4 | def self.assertion_name 5 | :same 6 | end 7 | 8 | def fail_message(exp, act) 9 | "Expected #{act.inspect} to be the same as #{exp.inspect}" 10 | end 11 | 12 | def fail_message!(exp, act) 13 | "Expected #{act.inspect} to NOT be the same as #{exp.inspect}" 14 | end 15 | 16 | def check(exp, act) 17 | exp.eq?(act) 18 | end 19 | end 20 | 21 | module Assertable 22 | # Passes if +expected+ .eq? +actual+. 23 | # 24 | # Note that the ordering of arguments is important, 25 | # since a helpful error message is generated when this 26 | # one fails that tells you the values of expected and actual. 27 | # 28 | # assert_equal 'MY STRING', 'my string'.upcase 29 | # 30 | def self.same(exp, act, opts={}) 31 | opts[:backtrace] ||= caller 32 | SameFailure.assert(exp, act, opts) 33 | end 34 | 35 | # Passes if not +expected+ .eq? +actual+. 36 | # 37 | # assert_not_equal 'some string', 5 38 | # 39 | def self.not_the_same(exp, act, opts={}) 40 | opts[:backtrace] ||= caller 41 | SameFailure.assert!(exp, act, opts) 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /lib/assay/core_ext/kernel.rb: -------------------------------------------------------------------------------- 1 | module Kernel 2 | 3 | # Do two references have the same `#object_id`, and hence are the 4 | # same object. 5 | # 6 | # @param [Object] other 7 | # Any object reference. 8 | # 9 | def identical?(other) 10 | object_id == other.object_id 11 | end 12 | 13 | # Ascertain likeness, returns true if any of `equal?`, `eql?`, `==`, 14 | # `===` or `=~` evaluate truthfully, either with `self` as the receiver 15 | # or `other` as the receiver. 16 | # 17 | # @todo Should `#=~` be apart of this comparison? 18 | # 19 | # @param [Object] other 20 | # Any object reference. 21 | # 22 | # @return [Boolean] +true+ if alike. 23 | # 24 | def like?(other) 25 | self.equal?(other) || 26 | self.eql?(other) || 27 | self.==(other) || 28 | self.===(other) || 29 | self.=~(other) || 30 | other.equal?(self) || 31 | other.eql?(self) || 32 | other.==(self) || 33 | other.===(self) || 34 | other.=~(self) 35 | end 36 | 37 | # 38 | def true? 39 | TrueClass === self 40 | end 41 | 42 | # 43 | def false? 44 | FalseClass === self 45 | end 46 | 47 | # 48 | def boolean? 49 | true? || false? 50 | end 51 | 52 | end 53 | -------------------------------------------------------------------------------- /demo/01_assay_classes/23_execution_assay.md: -------------------------------------------------------------------------------- 1 | ## ExecutionAssay 2 | 3 | The `ExecutionAssay` asserts that a procedure runs without error and returns 4 | a result other than `false` or `nil`. It is not particularly useful, because 5 | what it does is effectively what testing in itself does. So it is rather 6 | redundant. However, it serves as the base class for the more specific 7 | `ReturnAssay`. 8 | 9 | assert ExecutionAssay.pass?{ true } 10 | assert ExecutionAssay.pass?{ :foo } 11 | 12 | refute ExecutionAssay.pass?{ nil } 13 | refute ExecutionAssay.pass?{ false } 14 | refute ExecutionAssay.pass?{ raise } 15 | 16 | And conversely, 17 | 18 | assert ExecutionAssay.fail?{ raise } 19 | assert ExecutionAssay.fail?{ nil } 20 | assert ExecutionAssay.fail?{ false } 21 | 22 | refute ExecutionAssay.fail?{ true } 23 | refute ExecutionAssay.fail?{ :foo } 24 | 25 | Making assertions, 26 | 27 | assert ExecutionAssay.assert!{ true } 28 | 29 | expect ::ExecutionAssay do 30 | assert ExecutionAssay.assert!{ false } 31 | end 32 | 33 | And refutations, 34 | 35 | assert ExecutionAssay.refute!{ false } 36 | 37 | expect ::ExecutionAssay do 38 | assert ExecutionAssay.refute!{ true } 39 | end 40 | 41 | -------------------------------------------------------------------------------- /test/case_compare_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/compare_assay' 2 | 3 | testcase CompareAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert CompareAssay.pass?(1, 1, 0) 9 | assert CompareAssay.pass?(1, 2, -1) 10 | assert CompareAssay.pass?(2, 1, 1) 11 | 12 | refute CompareAssay.pass?(1, 1, 1) 13 | refute CompareAssay.pass?(1, 1, -1) 14 | end 15 | 16 | end 17 | 18 | class_method :fail? do 19 | 20 | test do 21 | assert CompareAssay.fail?(1, 1, 1) 22 | assert CompareAssay.fail?(1, 1, -1) 23 | 24 | refute CompareAssay.fail?(1, 1, 0) 25 | refute CompareAssay.fail?(1, 2, -1) 26 | refute CompareAssay.fail?(2, 1, 1) 27 | end 28 | 29 | end 30 | 31 | class_method :assert! do 32 | 33 | test do 34 | CompareAssay.assert!(1, 1, 0) 35 | end 36 | 37 | test do 38 | expect CompareAssay do 39 | CompareAssay.assert!(1, 1, 1) 40 | end 41 | end 42 | 43 | end 44 | 45 | class_method :refute! do 46 | 47 | test do 48 | CompareAssay.refute!(1, 2, 0) 49 | end 50 | 51 | test do 52 | expect CompareAssay do 53 | CompareAssay.refute!(1, 1, 0) 54 | end 55 | end 56 | 57 | end 58 | 59 | end 60 | -------------------------------------------------------------------------------- /work/defunct/tobe.rb: -------------------------------------------------------------------------------- 1 | module Assay 2 | 3 | # This module provides assertion mettods as object extensions in the 4 | # form of bang methods. 5 | # 6 | # Examples 7 | # 8 | # "string".is.instance_of?(String) 9 | # 10 | # "string".is.equal?("string") 11 | # 12 | # "string".should be.not_equal?("another") 13 | # 14 | class ToBe 15 | 16 | NAMES = { 17 | :== => :equal, 18 | :=~ => [:case, :match] 19 | } 20 | 21 | # 22 | def new(target) 23 | @target = target 24 | end 25 | 26 | # 27 | # Meta-programming routine for creating all the subjective methods. 28 | # 29 | def self.bootstrap 30 | Assay.constants.each do |const| 31 | next unless const < Assertion 32 | 33 | name = (const.operator || cont.assertive_name).to_sym 34 | names = [NAMES[name] || name].flatten 35 | 36 | name.each do |name| 37 | define_method("#{name}") do |*args| 38 | const.assert(@target, *args) 39 | end 40 | 41 | define_method("not_#{name}") do |*args| 42 | const.refute(@target, *args) 43 | end 44 | end 45 | end 46 | end 47 | 48 | # 49 | # Do it! 50 | # 51 | bootstrap 52 | 53 | end 54 | 55 | end 56 | 57 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | (BSD-2-Clause License) 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, 7 | this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 14 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 15 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 16 | COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 17 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 22 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/equal.rb: -------------------------------------------------------------------------------- 1 | require 'ae/assertions/compare' 2 | 3 | class EqualityFailure < CompareFailure 4 | def self.assertion_name 5 | :equal 6 | end 7 | 8 | def self.assertion_operator 9 | :== 10 | end 11 | 12 | def self.fail_message(exp, act) 13 | "Expected #{act.inspect} == #{exp.inspect}" 14 | end 15 | 16 | def self.fail_message!(exp, act) 17 | "Expected #{act.inspect} != #{exp.inspect}" 18 | end 19 | 20 | def self.check(exp, act) 21 | exp == act 22 | end 23 | 24 | def self.check!(exp, act) 25 | exp != act 26 | end 27 | end 28 | 29 | module Assertable 30 | # Passes if expected == +actual. 31 | # 32 | # Note that the ordering of arguments is important, 33 | # since a helpful error message is generated when this 34 | # one fails that tells you the values of expected and actual. 35 | # 36 | # assert_equal 'MY STRING', 'my string'.upcase 37 | # 38 | def assert_equal(exp, act, opts={}) 39 | opts[:backtrace] ||= caller 40 | EqualityFailure.assert(exp, act, opts) 41 | end 42 | 43 | # Passes if expected != actual 44 | # 45 | # assert_not_equal 'some string', 5 46 | # 47 | def assert_not_equal(exp, act, opts) 48 | opts[:backtrace] ||= caller 49 | EqualityFailure.assert!(exp, act, opts) 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /demo/04_assay.md: -------------------------------------------------------------------------------- 1 | # Assay Class Methods 2 | 3 | ## Metadata 4 | 5 | Assay support full project metadata access thanks to the `.ruby` 6 | standard. 7 | 8 | Assay.metadata['name'] #=> 'assay' 9 | 10 | The metadata also dynamically translates into constants, so we 11 | can work with this information in the traditional fashion. 12 | 13 | Assay::NAME #=> 'assay' 14 | 15 | ## Color Messages 16 | 17 | We can have some Assay error messages use ANSI color output by 18 | setting the `Assay.color` setting to `true`. 19 | 20 | Assay.color = true 21 | 22 | Keep in mind that this requires the `ansi` library. 23 | 24 | In particular it is the equality related assertions that utilize color 25 | output when the objects compared are large. This helps the developer 26 | pinpint the differences quickly. 27 | 28 | expect EqualAssay do 29 | EqualAssay['really long string'] === 'other string' 30 | end 31 | 32 | ## Lookup Assay Classes 33 | 34 | Assay tracks all created Assay classes by both associated operation 35 | and assertive name. 36 | 37 | Assay.lookup_by_operator(:==) #=> EqualAssay 38 | 39 | Assay.lookup_by_name(:equal) #=> EqualAssay 40 | 41 | We can look for either with just `lookup`. 42 | 43 | Assay.lookup(:==) #=> EqualAssay 44 | Assay.lookup(:equal) #=> EqualAssay 45 | 46 | 47 | -------------------------------------------------------------------------------- /demo/01_assay_classes/25_raise_assay.md: -------------------------------------------------------------------------------- 1 | ## RaiseAssay 2 | 3 | The `RaiseAssay` asserts that a procedure will raise a specific error. 4 | 5 | assert RaiseAssay.pass?{ raise } 6 | assert RaiseAssay.pass?(RuntimeError){ raise } 7 | assert RaiseAssay.pass?(ArgumentError){ raise ArgumentError } 8 | 9 | refute RaiseAssay.pass?{ raise Exception } 10 | refute RaiseAssay.pass?(Exception){ raise ArgumentError } 11 | refute RaiseAssay.pass?(StandardError){ nil } 12 | refute RaiseAssay.pass?(ArgumentError){ raise } 13 | 14 | And conversely, 15 | 16 | assert RaiseAssay.fail?{ raise Exception } 17 | assert RaiseAssay.fail?(RuntimeError){ nil } 18 | assert RaiseAssay.fail?(ArgumentError){ raise } 19 | assert RaiseAssay.fail?(Exception){ raise ArgumentError } 20 | 21 | refute RaiseAssay.fail?{ raise } 22 | refute RaiseAssay.fail?(RuntimeError){ raise } 23 | refute RaiseAssay.fail?(ArgumentError){ raise ArgumentError } 24 | 25 | Making assertions, 26 | 27 | assert RaiseAssay.assert!(RuntimeError){ raise } 28 | 29 | expect ::RaiseAssay do 30 | RaiseAssay.assert!(RuntimeError){ nil } 31 | end 32 | 33 | And refutations, 34 | 35 | assert RaiseAssay.refute!(RuntimeError){ nil } 36 | 37 | expect ::RaiseAssay do 38 | RaiseAssay.refute!(RuntimeError){ raise } 39 | end 40 | 41 | -------------------------------------------------------------------------------- /lib/assay/rescue_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'assertion' 2 | 3 | # Assert that a kind of exception class is rescued 4 | # from the execution of a block. 5 | # 6 | class RescueAssay < Assertion 7 | 8 | register :rescued 9 | 10 | # 11 | # Check assertion. 12 | # 13 | def self.pass?(*exceptions) 14 | exceptions = [RuntimeError] if exceptions.empty? 15 | begin 16 | yield 17 | false 18 | rescue Exception => e 19 | exceptions.any? do |x| 20 | x === e 21 | end 22 | end 23 | end 24 | 25 | # 26 | # Check negated assertion. 27 | # 28 | def self.fail?(*exceptions) 29 | exceptions = [RuntimeError] if exceptions.empty? 30 | begin 31 | yield 32 | true 33 | rescue Exception => e 34 | !exceptions.any? do |x| 35 | x === e 36 | end 37 | end 38 | end 39 | 40 | # TODO: How to add `but got class` message to error? 41 | # May have to override #assert! and #refute! method. 42 | 43 | # 44 | def self.assert_message(*exceptions) 45 | exp = exceptions.map{ |e| e.inspect }.join(' or ') 46 | "raise #{exp}" #, but was #{err} instead." 47 | end 48 | 49 | # 50 | def self.refute_message(*exceptions) 51 | exp = exceptions.map{ |e| e.inspect }.join(' or ') 52 | "! raise #{exp}" #, but was #{err} instead." 53 | end 54 | 55 | end 56 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/respond_to.rb: -------------------------------------------------------------------------------- 1 | require 'ae/assertions/execution' 2 | 3 | class RespondToFailure < ExecutionFailure 4 | def self.assertion_name 5 | :respond_to 6 | end 7 | 8 | def self.assertion_name! 9 | :not_respond_to 10 | end 11 | 12 | def fail_message(reciever, method) 13 | "Expected #{reciever} (#{reciever.class}) to respond to ##{method}" 14 | end 15 | 16 | def fail_message!(reciever, method) 17 | "Expected #{reciever} (#{reciever.class}) to not respond to ##{method}" 18 | end 19 | 20 | def self.check(reciver, method) 21 | #flip = (Symbol === obj) && ! (Symbol === meth) # HACK for specs 22 | #obj, meth = meth, obj if flip 23 | reciever.respond_to?(method) 24 | end 25 | end 26 | 27 | module Assertable 28 | # Passes if +object+ respond_to? +methods+. 29 | # 30 | # assert_respond_to 'bugbear', :slice 31 | # 32 | def assert_respond_to(reciever, method, opts={}) 33 | opts[:backtrace] ||= caller 34 | RespondToFailure.assert(reciever, method, opts) 35 | end 36 | 37 | # Passes if +object+ does not respond_to? +methods+. 38 | # 39 | # assert_not_respond_to 'bugbear', :slice 40 | # 41 | def assert_not_respond_to(reciever, method, opts={}) 42 | opts[:backtrace] ||= caller 43 | RespondToFailure.assert!(reciever, method, opts) 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /demo/01_assay_classes/24_rescue_assay.md: -------------------------------------------------------------------------------- 1 | ## RescueAssay 2 | 3 | The `RescueAssay` asserts that a procedure will raise a specific error. 4 | 5 | assert RescueAssay.pass?{ raise } 6 | assert RescueAssay.pass?(RuntimeError){ raise } 7 | assert RescueAssay.pass?(ArgumentError){ raise ArgumentError } 8 | assert RescueAssay.pass?(Exception){ raise ArgumentError } 9 | 10 | refute RescueAssay.pass?{ raise Exception } 11 | refute RescueAssay.pass?(RuntimeError){ nil } 12 | refute RescueAssay.pass?(ArgumentError){ raise } 13 | 14 | And conversely, 15 | 16 | assert RescueAssay.fail?{ raise Exception } 17 | assert RescueAssay.fail?(RuntimeError){ nil } 18 | assert RescueAssay.fail?(ArgumentError){ raise } 19 | 20 | refute RescueAssay.fail?{ raise } 21 | refute RescueAssay.fail?(RuntimeError){ raise } 22 | refute RescueAssay.fail?(ArgumentError){ raise ArgumentError } 23 | refute RescueAssay.fail?(Exception){ raise ArgumentError } 24 | 25 | Making assertions, 26 | 27 | assert RescueAssay.assert!(RuntimeError){ raise } 28 | 29 | expect ::RescueAssay do 30 | RaiseAssay.assert!(RuntimeError){ nil } 31 | end 32 | 33 | And refutations, 34 | 35 | assert RescueAssay.refute!(RuntimeError){ nil } 36 | 37 | expect ::RescueAssay do 38 | RaiseAssay.refute!(RuntimeError){ raise } 39 | end 40 | 41 | -------------------------------------------------------------------------------- /lib/assay/identity_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'equality_assay' 2 | 3 | # Check that two objects are one and the same object. 4 | # 5 | # NOTE: Ruby defines #equal? to mean #identical? but I believe 6 | # this to be a misnomer, at the very least. So we use the term 7 | # `identical` instead. 8 | # 9 | class IdentityAssay < EqualityAssay 10 | 11 | register :identical 12 | 13 | # 14 | # Check assertion using `object_id == object_id`. 15 | # 16 | def self.pass?(subject, criterion) 17 | subject.identical?(criterion) #subject.object_id == criterion.object_id 18 | end 19 | 20 | # # 21 | # # 22 | # # 23 | # def assert_message(subject) 24 | # a = subject.inspect 25 | # b = criteria.first.inspect 26 | # 27 | # if a.size > SIZE_LIMIT or b.size > SIZE_LIMIT 28 | # "a.identical?object_id == b.object.id\na) #{criterion}\nb) #{actual}" 29 | # else 30 | # "#{criterion}.object_id == #{actual}.object.id" 31 | # end 32 | # end 33 | # 34 | # # 35 | # # 36 | # # 37 | # def refute_message(subject) 38 | # actual = subject.inspect 39 | # criterion = criteria.first.inspect 40 | # 41 | # if actual.size > SIZE_LIMIT or criterion.size > SIZE_LIMIT 42 | # "a.object_id != b.object.id\na) #{criterion}\nb) #{actual}" 43 | # else 44 | # "#{criterion}.object_id != #{actual}.object.id" 45 | # end 46 | # end 47 | 48 | end 49 | 50 | -------------------------------------------------------------------------------- /test/case_within_assay.rb: -------------------------------------------------------------------------------- 1 | covers 'assay/within_assay' 2 | 3 | testcase WithinAssay do 4 | 5 | class_method :pass? do 6 | 7 | test do 8 | assert WithinAssay.pass?(1, 1, 0) 9 | assert WithinAssay.pass?(1, 1.1, 0.1) 10 | assert WithinAssay.pass?(1.0, 1.2, 0.2) 11 | 12 | refute WithinAssay.pass?(1, 2, 0.5) 13 | refute WithinAssay.pass?(1.0, 2, 0.5) 14 | refute WithinAssay.pass?(1.0, 2.0, 0.5) 15 | end 16 | 17 | end 18 | 19 | class_method :fail? do 20 | 21 | test do 22 | refute WithinAssay.fail?(1, 1, 0) 23 | refute WithinAssay.fail?(1, 1.1, 0.1) 24 | refute WithinAssay.fail?(1.0, 1.2, 0.2) 25 | 26 | assert WithinAssay.fail?(1, 2, 0.5) 27 | assert WithinAssay.fail?(1.0, 2, 0.5) 28 | assert WithinAssay.fail?(1.0, 2.0, 0.5) 29 | end 30 | 31 | end 32 | 33 | class_method :assert! do 34 | 35 | test do 36 | WithinAssay.assert!(1, 1.1, 0.1) 37 | end 38 | 39 | test do 40 | expect WithinAssay do 41 | WithinAssay.assert!(1, 1.2, 0.1) 42 | end 43 | end 44 | 45 | end 46 | 47 | class_method :refute! do 48 | 49 | test do 50 | WithinAssay.refute!(1, 2, 0.1) 51 | end 52 | 53 | test do 54 | expect WithinAssay do 55 | WithinAssay.refute!(1, 1.1, 0.1) 56 | end 57 | end 58 | 59 | end 60 | 61 | end 62 | -------------------------------------------------------------------------------- /lib/assay/adapter/testunit.rb: -------------------------------------------------------------------------------- 1 | module Test #:nodoc: 2 | module Unit #:nodoc: 3 | class TestCase #:nodoc: 4 | # Runs the individual test method represented by this 5 | # instance of the fixture, collecting statistics, failures 6 | # and errors in result. 7 | def run(result) 8 | yield(STARTED, name) 9 | @_result = result 10 | begin 11 | setup 12 | __send__(@method_name) 13 | rescue AssertionFailedError => e 14 | add_failure(e.message, e.backtrace) 15 | rescue Exception => e 16 | if e.respond_to?(:assertion?) && e.assertion? 17 | add_failure(e.message, e.backtrace) 18 | else 19 | raise if PASSTHROUGH_EXCEPTIONS.include? $!.class 20 | add_error($!) 21 | end 22 | ensure 23 | begin 24 | teardown 25 | rescue AssertionFailedError => e 26 | add_failure(e.message, e.backtrace) 27 | rescue Exception => e 28 | if e.respond_to?(:assertion?) && e.assertion? 29 | add_failure(e.message, e.backtrace) 30 | else 31 | raise if PASSTHROUGH_EXCEPTIONS.include? $!.class 32 | add_error($!) 33 | end 34 | end 35 | end 36 | result.add_run 37 | yield(FINISHED, name) 38 | end 39 | end 40 | end 41 | end 42 | 43 | -------------------------------------------------------------------------------- /demo/01_assay_classes/26_throw_assay.md: -------------------------------------------------------------------------------- 1 | ## ThrowAssay 2 | 3 | The `ThrowAssay` asserts that a procedure will call `throw` and optionally 4 | of a specific type. 5 | 6 | assert ThrowAssay.pass?(:foo){ throw :foo } 7 | refute ThrowAssay.pass?(:foo){ throw :bar } 8 | 9 | And conversely, 10 | 11 | assert ThrowAssay.fail?(:foo){ throw :bar } 12 | refute ThrowAssay.fail?(:foo){ throw :foo } 13 | 14 | In addition `ThrowAssay` can assert that there is a throw, regardless 15 | of tag. 16 | 17 | assert ThrowAssay.pass?{ throw :foo } 18 | refute ThrowAssay.pass?{ nil } 19 | 20 | And converselry, 21 | 22 | assert ThrowAssay.fail?{ nil } 23 | refute ThrowAssay.fail?{ throw :bar } 24 | 25 | Making assertions, notice that the `#assert!` method requires a `nil` 26 | argument in order to test for any throw. This is not needed on the 27 | `#pass?` method because the `#pass` method can't take aditional options 28 | for setting the message or backtrace. 29 | 30 | assert ThrowAssay.assert!(nil){ throw :foo } 31 | 32 | assert ThrowAssay.assert!(nil, :message=>"optional message"){ 33 | throw :foo 34 | } 35 | 36 | expect ThrowAssay do 37 | ThrowAssay.assert!(nil){ 'nothing' } 38 | end 39 | 40 | And refutations, 41 | 42 | assert ThrowAssay.refute!(:foo){ throw :bar } 43 | 44 | expect ThrowAssay do 45 | ThrowAssay.refute!(:foo){ throw :foo } 46 | end 47 | 48 | -------------------------------------------------------------------------------- /lib/assay/silent_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'output_assay' 2 | 3 | # Assert that there is no output, either from stdout or stderr. 4 | # 5 | # SilentAssay.pass?{ puts 'foo!' } #=> false 6 | # 7 | class SilentAssay < OutputAssay 8 | 9 | register :silent 10 | 11 | # 12 | # Compare +match+ against $stdout and $stderr via `#===` method. 13 | # 14 | # Note that $stdout and $stderr are temporarily reouted to StringIO 15 | # objects and the results have any trailing newline chomped off. 16 | # 17 | def self.pass?(&block) 18 | require 'stringio' 19 | 20 | begin 21 | stdout, stderr = $stdout, $stderr 22 | newout, newerr = StringIO.new, StringIO.new 23 | $stdout, $stderr = newout, newerr 24 | yield 25 | ensure 26 | $stdout, $stderr = stdout, stderr 27 | end 28 | 29 | newout, newerr = newout.string.chomp("\n"), newerr.string.chomp("\n") 30 | 31 | newout.empty? && newerr.empty? 32 | end 33 | 34 | # TODO: Assertable isn't dealing with no-argument assertions well, 35 | # see if this can be improved. 36 | 37 | # 38 | # Opposite of `SilentAssay.pass?`. 39 | # 40 | def self.fail?(&block) 41 | ! pass?(&block) 42 | end 43 | 44 | # 45 | # 46 | # 47 | def self.assert_message(*) 48 | "unexpected output" 49 | end 50 | 51 | # 52 | # 53 | # 54 | def self.refute_message(*) 55 | "expected output" 56 | end 57 | 58 | end 59 | 60 | -------------------------------------------------------------------------------- /work/defunct/complex_nomenclature_system/nomenclature/assert.rb: -------------------------------------------------------------------------------- 1 | require 'ae/kernel/assert' 2 | require 'ae/nomenclature' 3 | 4 | class AE 5 | 6 | module Nomenclature 7 | 8 | # = Extended Assert Nomenclature 9 | # 10 | module Assert 11 | # Define predicate +pname+ for this nomenclature. 12 | # 13 | def self.define_predicate(pname) 14 | #puts "Assert::define_predicate(#{pname.inspect})" if $DEBUG 15 | name = make_interjective(pname) 16 | name = case name 17 | when /^is/ then "#{name.sub('is_','')}" 18 | else "#{name}" 19 | end 20 | super('assert', name, pname) 21 | case name 22 | when /^assert_not/ 23 | alias_method "refute_{$'}", name 24 | when /^assert_no/ 25 | alias_method "refute_{$'}", name 26 | end 27 | end 28 | 29 | # Returns the predicate name without the prefix 30 | # phrase that corresponds to this nomenclature. 31 | # If the term doesn't conform to this nomenclature 32 | # then returns nil. 33 | def self.make_neutral(name) 34 | case name 35 | when /^assert_/ then $' 36 | else nil 37 | end 38 | end 39 | 40 | # Assert is a Nomenclature. 41 | # This is done last to prevent any Nomenclature 42 | # callbacks from triggering on the above definitions. 43 | extend Nomenclature 44 | end 45 | 46 | end 47 | 48 | end 49 | -------------------------------------------------------------------------------- /lib/assay/execution_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'assertion' 2 | 3 | # Assert that a block of coded executes without error and does 4 | # not return +nil+ or +false+. 5 | # 6 | # NOTE: To test only for successful execution regardless of return value 7 | # use a negated {RaiseAssay} on the Exception class. But generally 8 | # this would be pretty silly, if you think about it, this is exactly 9 | # what testing is for! 10 | # 11 | class ExecutionAssay < Assertion 12 | 13 | register :executes 14 | 15 | # 16 | # Check assertion. 17 | # 18 | def self.pass?(*arguments, &block) 19 | begin 20 | block.call(*arguments) 21 | rescue Exception 22 | false 23 | end 24 | end 25 | 26 | # 27 | # Check negated assertion. 28 | # 29 | def self.fail?(*arguments, &block) 30 | begin 31 | ! block.call(*arguments) 32 | rescue Exception 33 | true 34 | end 35 | end 36 | 37 | # 38 | #def self.assert!(*criteria, &block) 39 | # options = (Hash === criteria.last ? criteria.pop : {}) 40 | # assay = new(nil, *criteria) #, &block) 41 | # assay.assert!(options, &block) 42 | #end 43 | 44 | # 45 | #def self.refute!(*criteria, &block) 46 | # options = (Hash === criteria.last ? criteria.pop : {}) 47 | # assay = new(nil, *criteria) #, &block) 48 | # assay.refute!(options, &block) 49 | #end 50 | 51 | # 52 | # 53 | # 54 | def self.assert_message(*arguments, &block) 55 | "#{block}.call(*#{arguments.inspect})" 56 | end 57 | 58 | end 59 | 60 | -------------------------------------------------------------------------------- /work/defunct/object-assays/assay.rb: -------------------------------------------------------------------------------- 1 | module Assay 2 | 3 | $ASSERTION_COUNTS = Hash.new{ |h,k| h[k] = 0 } 4 | 5 | def self.[](name) 6 | index[name.to_sym] 7 | end 8 | 9 | def self.index 10 | @index ||= {} 11 | end 12 | 13 | # 14 | # 15 | def self.new(name, error=StandardError, options={}, &condition) 16 | name = name.to_sym 17 | assay = Definition.new(name, error, options, &condition) 18 | index[name] = assay 19 | end 20 | 21 | # 22 | # 23 | class Definition 24 | 25 | def initialize(name, error=StandardError, options={}, &test) 26 | @name = name 27 | @error = error || StandardError 28 | @test = test 29 | end 30 | 31 | def name 32 | @name 33 | end 34 | 35 | def error 36 | @error 37 | end 38 | 39 | # TODO: Better name? 40 | def test 41 | @test 42 | end 43 | 44 | # 45 | def pass?(*args, &blk) 46 | @test.call(*args, &blk) 47 | end 48 | 49 | def assert!(*args, &blk) 50 | if pass?(*args, &blk) 51 | increment_counts(:pass) 52 | else 53 | increment_counts(:fail) 54 | raise @error, message(*args, &blk) 55 | end 56 | end 57 | 58 | # TODO: Better name? 59 | def message(*args, &blk) 60 | "#{name} " + args.inspect 61 | end 62 | 63 | # TODO: Better name? 64 | def increment_counts(which) 65 | $ASSERTION_COUNTS[which] += 1 66 | $ASSERTION_COUNTS[:total] += 1 67 | end 68 | 69 | end 70 | 71 | end 72 | -------------------------------------------------------------------------------- /work/consider/sends.rb: -------------------------------------------------------------------------------- 1 | require 'assertion' 2 | 3 | module Assertable 4 | # Passes if the method send returns a true value. 5 | # The parameter +send_array+ is composed of: 6 | # 7 | # * receiver 8 | # * method 9 | # * arguments to method 10 | # 11 | # Example: 12 | # 13 | # sends [[1, 2], :include?, 4] 14 | # 15 | # NOTE: You can not change the message for this assertion. 16 | # 17 | def assert_sends(receiver, method, *args) 18 | pass = begin 19 | receiver.__send__(method, *args) 20 | true 21 | rescue Excepton #StandardError 22 | false 23 | end 24 | msg = opts[:message] || "Expected #{receiver}.#{method}(*#{args.inspect}) call to return" 25 | call = opts[:backtrace] || caller 26 | fail Assertion.new(msg, call) unless pass 27 | end 28 | 29 | # Passes if the method send *does not* return. 30 | # The parameter +send_array+ is composed of: 31 | # 32 | # * receiver 33 | # * method 34 | # * arguments to method 35 | # 36 | # Example: 37 | # 38 | # sends [[1, 2], :include?, 4] 39 | # 40 | # NOTE: You can not change the message for this assertion. 41 | # 42 | def assert_does_not_send(receiver, method, *args) 43 | pass = begin 44 | receiver.__send__(method, *args) 45 | true 46 | rescue Excepton #StandardError 47 | false 48 | end 49 | msg = opts[:message] || "Expected #{receiver}.#{method}(*#{args.inspect}) call NOT to return" 50 | call = opts[:backtrace] || caller 51 | fail Assertion.new(msg, call) if pass 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /.index: -------------------------------------------------------------------------------- 1 | --- 2 | revision: 2013 3 | type: ruby 4 | sources: 5 | - var 6 | authors: 7 | - name: Trans 8 | email: transfire@gmail.com 9 | organizations: 10 | - name: Rubyworks 11 | requirements: 12 | - name: ansi 13 | - name: brass 14 | - groups: 15 | - build 16 | development: true 17 | name: detroit 18 | - groups: 19 | - build 20 | development: true 21 | name: ergo 22 | - groups: 23 | - test 24 | development: true 25 | name: qed 26 | - groups: 27 | - test 28 | development: true 29 | name: ae 30 | conflicts: [] 31 | alternatives: [] 32 | resources: 33 | - type: home 34 | uri: http://rubyworks.github.com/assay 35 | label: Homepage 36 | - type: docs 37 | uri: http://rubydoc.info/gems/assay/frames 38 | label: Documentation 39 | - type: code 40 | uri: http://github.com/rubyworks/assay 41 | label: Source Code 42 | - type: bugs 43 | uri: http://github.com/rubyworks/assay/issues 44 | label: Issue Tracker 45 | - type: chat 46 | uri: http://chat.us.freenode.net/rubyworks 47 | label: IRC Channel 48 | - type: mail 49 | uri: http://groups.google.com/groups/rubyworks-mailinglist 50 | label: Mailing List 51 | repositories: 52 | - name: upstream 53 | scm: git 54 | uri: git@github.com:rubyworks/assay.git 55 | categories: [] 56 | copyrights: 57 | - holder: Rubyworks 58 | year: '2010' 59 | license: BSD-2-Clause 60 | customs: [] 61 | paths: 62 | lib: 63 | - lib 64 | created: '2010-11-14' 65 | summary: Class-based Assertions Framework 66 | title: Assay 67 | version: 0.4.1 68 | name: assay 69 | description: ! 'Assay defines assertions in the same way that Ruby defines exceptions. 70 | 71 | Each type of asserition, called an assay, is then a child of the base 72 | 73 | Assertion class, which itself is a subclass of the Exception class.' 74 | date: '2013-03-09' 75 | -------------------------------------------------------------------------------- /work/defunct/object-assays/definitions.rb: -------------------------------------------------------------------------------- 1 | require 'assay/assay' 2 | 3 | 4 | class EqualityError < StandardError 5 | def self.assay(name, options={}, &block) 6 | Assay.new(name, self, options, &block) 7 | end 8 | end 9 | 10 | 11 | #def assay(name, error=StandardError, options={}, &block) 12 | # Assay.new(name, options, &block) 13 | #end 14 | 15 | # 16 | TypeError.assay(:kind_of) do |target, criterion| 17 | target.kind_of?(criterion) 18 | end 19 | 20 | # 21 | TypeError.assay(:instance_of) do |target, criterion| 22 | target.instance_of?(criterion) 23 | end 24 | 25 | # 26 | EqualityError.assay(:identical) do |target, criterion| 27 | criterion.object_id == target.object_id 28 | end 29 | 30 | # 31 | #assay :equal, EqualityError do |target, criterion| 32 | # criterion.equal?(target) 33 | #end 34 | 35 | # 36 | EqualityError.assay :eql do |target, criterion| 37 | criterion.eql?(target) 38 | end 39 | 40 | # 41 | EqualityError.assay :eq, :operator=>:== do |target, criterion| 42 | criterion == target 43 | end 44 | 45 | # 46 | EqualityError.assay :like do |target, criterion| 47 | criterion === target || 48 | criterion.equal?(target) || 49 | criterion.eql?(target) || 50 | criterion.==(target) 51 | end 52 | 53 | # 54 | StandardError.assay :empty do |target| 55 | target.empty? 56 | end 57 | 58 | # 59 | StandardError.assay :include do |target, criterion| 60 | target.include?(criterion) 61 | end 62 | 63 | StandardError.assay :false do |target| 64 | FalseClass = target # target.false? 65 | end 66 | 67 | StandardError.assay :true do |target| 68 | TrueClass = target # target.true? 69 | end 70 | 71 | StandardError.assay :nil do |target| 72 | NilClass = target # target.nil? 73 | end 74 | 75 | NoMethodError.assay :respond_to |target, method| 76 | target.respond_to?(method) 77 | end 78 | 79 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | # HISTORY 2 | 3 | ## 0.4.1 | 2012-01-27 4 | 5 | This release adds CloseAssay for relative approxmation assertions on values, 6 | where as the WithinAssay handles absolute difference. 7 | 8 | Changes: 9 | 10 | * Add CloseAssay for relative approximation. 11 | * Use past tense for RescueAssay's assertive name, i.e. :rescued. 12 | 13 | 14 | ## 0.4.0 | 2012-01-25 15 | 16 | Version 0.4 is a very polished partial rewrite of the Assay project. 17 | This release sheds all ancillary code to separate projects. The 18 | compatibility layers are now `assay-testunit`, `assay-minitest` and 19 | `assay-rspec`. The built-in grammar is now the `fluidity` project. 20 | All assertion classes now end with `Assay` suffix instead of `Failure` 21 | and they are defined at the toplevel. 22 | 23 | Changes: 24 | 25 | * Spin-off all ancillary code, leaving only core functionality. 26 | * Polish and semi-rewrite code. 27 | * Renamed all Assertion subclasses form xxxFailure to xxxAssay. 28 | * Add many new Assertion subclasses. 29 | 30 | 31 | ## 0.3.0 | 2011-05-07 32 | 33 | This release fix the interface of the assertive methods so they accept 34 | a message argument, like the original testunit. 35 | 36 | Changes: 37 | 38 | * Fix assertive methods to take message argument. 39 | * Fix Assertion class to store message. 40 | 41 | 42 | ## 0.2.0 | 2011-05-05 43 | 44 | This release of Assay is in good working order and can now be used 45 | by other frameworks such as A.E. The only caveats at this point 46 | are the Matcher API, which is still a bit unstable as the names of 47 | some of its methods may yet change, and the error messages 48 | for the various Failure classes still need improvement. 49 | 50 | Changes: 51 | 52 | * Add adapters for minitest and testunit. 53 | * Add colorized comparison to EqualityFailure (via ANSI gem). 54 | * Use standard exception messages (#to_s) instead of class methods. 55 | 56 | 57 | ## 0.1.0 | 2010-11-14 58 | 59 | This is the initial working version of Assay. 60 | But it is far from ready for widespread usage. 61 | 62 | Changes: 63 | 64 | * Happy Birthday! 65 | 66 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/sends.rb: -------------------------------------------------------------------------------- 1 | require 'ae/assertions/execution' 2 | 3 | class SendFailure < ExecutionFailure 4 | def self.assertion_name 5 | :sends 6 | end 7 | 8 | def self.assertion_name! 9 | :does_not_send 10 | end 11 | 12 | def self.assert(receiver, methods *args) 13 | msg = fail_message(receiver, method, *args) 14 | fail new(msg, call||caller) unless check(receiver, method, *args) 15 | end 16 | 17 | def self.assert!(receiver, methods *args) 18 | msg = msg || fail_message!(receiver, method, *args) 19 | fail new(msg, call||caller) unless check!(receiver, method, *args) 20 | end 21 | 22 | def self.fail_message(reciever, method, *args) 23 | "Expected #{receiver}.#{method}(*#{args.inspect}) call to return true" 24 | end 25 | 26 | def self.fail_message!(reciever, method, *args) 27 | "Expected #{receiver}.#{method}(*#{args.inspect}) call to return false" 28 | end 29 | 30 | def self.check(receiver, method, *args) 31 | begin 32 | receiver.__send__(method, *args) 33 | true 34 | rescue Excepton #StandardError 35 | false 36 | end 37 | end 38 | end 39 | 40 | module Assertable 41 | # Passes if the method send returns a true value. 42 | # The parameter +send_array+ is composed of: 43 | # 44 | # * receiver 45 | # * method 46 | # * arguments to method 47 | # 48 | # Example: 49 | # 50 | # sends [[1, 2], :include?, 4] 51 | # 52 | # NOTE: You can not change the message for this assertion. 53 | # 54 | def assert_sends(receiver, method, *args) 55 | SendFailure.assert(receiver, method, *args) 56 | end 57 | 58 | # Passes if the method send *does not* returns a true value. 59 | # The parameter +send_array+ is composed of: 60 | # 61 | # * receiver 62 | # * method 63 | # * arguments to method 64 | # 65 | # Example: 66 | # 67 | # sends [[1, 2], :include?, 4] 68 | # 69 | # NOTE: You can not change the message for this assertion. 70 | # 71 | def assert_does_not_send(receiver, method, *args) 72 | SendFailure.assert!(receiver, method, *args) 73 | end 74 | end 75 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/returns.rb: -------------------------------------------------------------------------------- 1 | require 'assertion' 2 | require 'ae/assertable' 3 | 4 | NoArgument = Object.new 5 | 6 | class ReturnFailure < Assertion 7 | 8 | def self.assert(exp, opts={}, &blk) #:yeild: 9 | msg = fail_message(exp) 10 | res = yield 11 | if :"N/A" == exp 12 | chk = (res ? true : false) 13 | else 14 | chk = (exp == res) 15 | msg = msg + ", but was #{res}" 16 | end 17 | fail new(opts[:message]||msg, opts[:backtrace]||caller) unless chk 18 | end 19 | 20 | def self.assert!(exp, opts={}, &blk) # :yield: 21 | msg = fail_message!(exp) 22 | res = yield 23 | if :"N/A" == exp 24 | chk = (res ? false : true) 25 | else 26 | chk = (exp != res) 27 | msg = msg + ", but was #{res}" 28 | end 29 | fail new(opts[:message]||msg, opts[:backtrace]||caller) unless chk 30 | end 31 | 32 | def fail_message(exp) 33 | if :"N/A" == exp 34 | "Expected block to return a value" 35 | else 36 | "Expected block to return #{exp}" 37 | end 38 | end 39 | 40 | def fail_message!(exp) 41 | if :"N/A" == exp 42 | "Expected block not to return a value" 43 | else 44 | "Expected block not to return #{exp}" 45 | end 46 | end 47 | 48 | def check(exp) #:yield: 49 | case exp 50 | when :"N/A" 51 | yield ? true : false 52 | else 53 | exp == yield 54 | end 55 | end 56 | 57 | end 58 | 59 | module Assertable 60 | 61 | # Passes if the block yields a specified value (Compares with #==). 62 | # 63 | # assert_executes "Couldn't do the thing" do 64 | # do_the_thing 65 | # end 66 | # 67 | def assert_returns(exp=:"N/A", opts={}, &blk) # :yield: 68 | opts[:backtrace] ||= caller 69 | ReturnFailure.assert(exp, opts, &blk) 70 | end 71 | 72 | # Passes if the block does not yield a specific value. 73 | # 74 | # assert_not_executing "Couldn't do the thing" do 75 | # do_the_thing 76 | # end 77 | # 78 | def assert_does_not_return(exp=:"N/A", opts={}, &blk) # :yield: 79 | opts[:backtrace] ||= caller 80 | ReturnFailure.assert!(exp, opts, &blk) 81 | end 82 | 83 | end 84 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/raises.rb: -------------------------------------------------------------------------------- 1 | require 'ae/assertions/execution' 2 | 3 | class RaiseFailure < ExecutionFailure 4 | def self.assertion_name 5 | :raises 6 | end 7 | 8 | def self.assertion_name! 9 | :not_raised 10 | end 11 | 12 | def self.assert(exp, msg=nil, call=nil) #:yeild: 13 | begin 14 | yield 15 | msg = msg || fail_message(exp) 16 | test = false 17 | rescue Exception => err 18 | msg = msg || fail_message(exp, err) 19 | test = (exp === err) 20 | end 21 | fail new(msg, call||caller) unless test 22 | end 23 | 24 | def self.assert!(exp, msg=nil, call=nil) #:yield: 25 | begin 26 | yield 27 | test = true 28 | rescue Exception => err 29 | msg = msg || fail_message!(exp, err) 30 | test = (exp === err) 31 | end 32 | fail new(msg, call||caller) unless test 33 | end 34 | 35 | def self.fail_message(exp, err=nil) 36 | if err 37 | "Expected #{exp} to be raised, but got #{err.class}" 38 | else 39 | "Expected #{exp} to be raised" 40 | end 41 | end 42 | 43 | def self.fail_message!(exp) 44 | "Expected #{exp} NOT to be raised" 45 | end 46 | 47 | # Note: This is not used by the #assert method. 48 | def self.check(*exp) 49 | begin 50 | yield 51 | false 52 | rescue Exception => e 53 | exp.any?{ |x| x === e } 54 | end 55 | end 56 | 57 | # Note: This is not used by the #assert! method. 58 | def self.check(*exp) 59 | begin 60 | yield 61 | true 62 | rescue Exception => e 63 | !exp.any?{ |x| x === e } 64 | end 65 | end 66 | 67 | end 68 | 69 | module Assertable 70 | # Passes if the block raises a given exceptions. 71 | # 72 | # assert_raises RuntimeError do 73 | # raise 'Boom!!!' 74 | # end 75 | # 76 | def self.raises(exp, msg=nil, call=nil, &blk) #:yeild: 77 | RaiseFailure.assert(exp, msg=nil, call=nil, &blk) 78 | end 79 | 80 | # Passes if the block *does not* raise a given exceptions. 81 | # 82 | # assert_not_raised IOError do 83 | # raise 'Boom!!!' 84 | # end 85 | # 86 | def self.not_raised(exp, msg=nil, call=nil, &blk) #:yeild: 87 | RaiseFailure.assert!(exp, msg, call, &blk) 88 | end 89 | end 90 | -------------------------------------------------------------------------------- /lib/assay.rb: -------------------------------------------------------------------------------- 1 | # Load Assay's assertion classes. 2 | require_relative 'assay/assertion' 3 | dir = File.dirname(__FILE__) + '/assay' 4 | Dir.entries(dir).each do |file| 5 | next if File.extname(file) != '.rb' 6 | require_relative 'assay/' + file 7 | end 8 | 9 | module Assay 10 | 11 | # 12 | # Returns Hash table of project metadata. 13 | # 14 | def self.metadata 15 | @spec ||= ( 16 | require 'yaml' 17 | YAML.load(File.new(File.dirname(__FILE__) + '/assay.yml')) 18 | ) 19 | end 20 | 21 | # 22 | # Check metadata for missing constants. 23 | # 24 | def self.const_missing(name) 25 | metadata[name.to_s.downcase] || super(name) 26 | end 27 | 28 | # 29 | # Returns a list of Assertion subclasses. 30 | # 31 | def self.assertions 32 | Assertion.subclasses 33 | end 34 | 35 | # 36 | # Set ANSI color mode. Default is false, so set to `true` to get ANSI color 37 | # in some error messages. 38 | # 39 | # @example 40 | # Assay.color = true 41 | # 42 | def self.color=(boolean) 43 | if boolean 44 | require 'ansi/diff' 45 | $ansi = true 46 | else 47 | $ansi = false 48 | end 49 | end 50 | 51 | # 52 | # Lookup assay class by operator or name. 53 | # 54 | def self.lookup(symbol) 55 | lookup_by_operator(symbol) || lookup_by_name(symbol) 56 | end 57 | 58 | # 59 | # If operator is not given, returns a hash table of assertion classes 60 | # indexed by operator. 61 | # 62 | def self.lookup_by_operator(operator=nil) 63 | Assertion.by_operator(operator) 64 | end 65 | 66 | # 67 | # If operator is not given, returns a hash table of assertion classes 68 | # indexed by assertive name. 69 | # 70 | def self.lookup_by_name(name=nil) 71 | Assertion.by_name(name) 72 | end 73 | 74 | # This module serves as the primary container for traditonal style assertion 75 | # methods, which can be mixed in to one's testing scope (e.g. World). 76 | # 77 | module Assertions 78 | end 79 | 80 | # This module holds the subject matcher methods, which can be mixin 81 | # to one's testing scope (e.g. World). 82 | # 83 | module Matchers 84 | end 85 | 86 | # This module holds the assertion extension mehods, which are mixed into 87 | # the Object class. 88 | # 89 | module Extensions 90 | end 91 | 92 | #class ::Object 93 | # include Assay::Extensions 94 | #end 95 | 96 | end 97 | 98 | -------------------------------------------------------------------------------- /lib/assay/throw_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'execution_assay' 2 | 3 | # Assertion for catching specific throws. 4 | # 5 | class ThrowAssay < ExecutionAssay 6 | 7 | register :throw 8 | 9 | # TODO: Is it possible to catch _any_ type of throw? If so make the 10 | # argument optional for that. 11 | 12 | # Passes if the block throws given symbol. 13 | # 14 | # ThrowAssay.pass? :done do 15 | # throw :done 16 | # end 17 | # 18 | # If no symbol is given than passes if any is thrown. 19 | # But note that in `#assert!`, the symbol must be `nil` 20 | # rather than not given. 21 | # 22 | def self.pass?(symbol=nil) #:yield: 23 | pass = true 24 | if symbol 25 | catch(symbol) do 26 | begin 27 | yield 28 | rescue ArgumentError => err # 1.9 exception 29 | #msg += ", not #{err.message.split(/ /).last}" 30 | rescue NameError => err # 1.8 exception 31 | #msg += ", not #{err.name.inspect}" 32 | end 33 | pass = false 34 | end 35 | else 36 | begin 37 | yield 38 | pass = false 39 | rescue ArgumentError => error 40 | pass = false if /\Auncaught throw (.+)\z/ !~ error.message 41 | end 42 | end 43 | pass 44 | end 45 | 46 | # Passes if the block does not throw given +symbol+. 47 | # 48 | # ThrowAssay.fail? :done do 49 | # throw :chimp 50 | # end 51 | # 52 | # If no symbol is given then passes if nothing is thrown. 53 | # But note that in `#refute!`, the symbol must be `nil` 54 | # rather than not given. 55 | # 56 | def self.fail?(symbol=nil) #:yield: 57 | if symbol 58 | pass = false 59 | catch(symbol) do 60 | begin 61 | yield 62 | rescue ArgumentError => err # 1.9 exception 63 | #msg += ", not #{err.message.split(/ /).last}" 64 | rescue NameError => err # 1.8 exception 65 | #msg += ", not #{err.name.inspect}" 66 | end 67 | pass = true 68 | end 69 | else 70 | pass = false 71 | begin 72 | yield 73 | pass = true 74 | rescue ArgumentError => error 75 | pass = true if /\Auncaught throw (.+)\z/ !~ error.message 76 | end 77 | end 78 | pass 79 | end 80 | 81 | # 82 | # 83 | # 84 | def self.assert_message(symbol) 85 | s = symbol.inspect 86 | "throw #{s}" 87 | end 88 | 89 | end 90 | -------------------------------------------------------------------------------- /work/defunct/complex_nomenclature_system/nomenclature.rb: -------------------------------------------------------------------------------- 1 | require 'assertion' 2 | require 'ae/assertable' 3 | 4 | class AE 5 | 6 | # 7 | module Nomenclature 8 | 9 | # Store list of currently active nomenclatures. 10 | ACTIVE = [] 11 | 12 | private 13 | 14 | def self.extended(nomenclature) 15 | setup_nomenclature(nomenclature) 16 | end 17 | 18 | # Setup pre-existing predicates. 19 | # 20 | def self.setup_nomenclature(nomenclature) 21 | ACTIVE << nomenclature 22 | #(@nomenclatures ||= []) << nomenclature 23 | Assertable.private_instance_methods(false).each do |name| 24 | next if :define_predicate == name.to_sym 25 | nomenclature.define_predicate(name) 26 | end 27 | end 28 | 29 | # Converts 30 | def make_subjunctive(name) 31 | name = name.to_s 32 | name = case name 33 | #when /^not_/ then "not_be_#{$'}" 34 | when /^no_/ then "not_have_#{$'}" 35 | when /^is_/ then "be_#{$'}" 36 | when /^in_/ then "be_#{name}" 37 | when /^like_/ then "be_#{name}" 38 | when /^has_/ then "have_been_#{$'}" 39 | when /_of$/ then "be_#{name}" 40 | else name 41 | end 42 | name = name.chomp('s') if /s$/ =~ name 43 | name 44 | end 45 | 46 | # Converts 47 | def make_interjective(name) 48 | name = name.to_s 49 | name = case name 50 | when /^not_be_/ then "not_#{$'}" 51 | when /^not_have_/ then "no_#{$'}" 52 | when /^be_/ then "#{$'}" 53 | #when /^be_in_/ then "in_#{$'}" 54 | #when /^be_like_/ then "like_#{$'}" 55 | when /^have_been_/ then "has_#{$'}" 56 | else name 57 | end 58 | #name = name.chomp('s') if /s$/ =~ name 59 | name 60 | end 61 | 62 | # Predicate definition. This must be overriden 63 | # in nomenclature submodules. 64 | # 65 | def define_predicate(prefix, name, pname) 66 | return if :singleton_method_added == pname.to_sym 67 | return if :make_subjunctive == pname.to_sym 68 | return if :make_interjective == pname.to_sym 69 | return if :define_predicate == pname.to_sym 70 | 71 | puts "Nomenclature#define_predicate(#{prefix.inspect}, #{name.inspect}, #{pname.inspect})" if $DEBUG 72 | 73 | Assertable.module_eval <<-END, __FILE__, __LINE__ 74 | private 75 | def #{prefix}_#{name}(*a,&b) 76 | Assertable.#{pname}(*a,&b) 77 | end 78 | END 79 | end 80 | 81 | end 82 | 83 | end 84 | -------------------------------------------------------------------------------- /lib/assay/raise_assay.rb: -------------------------------------------------------------------------------- 1 | require_relative 'rescue_assay' 2 | 3 | # 4 | class RaiseAssay < RescueAssay 5 | 6 | register :raised 7 | 8 | # 9 | # Check assertion. 10 | # 11 | def self.pass?(*exceptions) 12 | exceptions = [RuntimeError] if exceptions.empty? 13 | begin 14 | yield 15 | false 16 | rescue Exception => e 17 | exceptions.any? do |x| 18 | x.instance_of?(Module) ? x === e : e.class == x 19 | end 20 | end 21 | end 22 | 23 | # 24 | # Check negated assertion. 25 | # 26 | def self.fail?(*exceptions) 27 | exceptions = [RuntimeError] if exceptions.empty? 28 | begin 29 | yield 30 | true 31 | rescue Exception => e 32 | !exceptions.any? do |x| 33 | x.instance_of?(Module) ? x === e : e.class == x 34 | end 35 | end 36 | end 37 | 38 | # TODO: How to add `but got class` to message? 39 | # May have to override `#assert!` and `#refute!`. 40 | 41 | # 42 | # 43 | # 44 | def self.assert_message(*exceptions) 45 | exp = exceptions.map{ |e| e.inspect }.join(' or ') 46 | "raise #{exp}" #, but was #{err} instead." 47 | end 48 | 49 | # 50 | # 51 | # 52 | def self.refute_message(*exceptions) 53 | exp = exceptions.map{ |e| e.inspect }.join(' or ') 54 | "! raise #{exp}" #, but was #{err} instead." 55 | end 56 | 57 | =begin 58 | # 59 | # 60 | # 61 | def self.assert!(*exp) #:yeild: 62 | options = (Hash === exp.last ? exp.pop : {}) 63 | 64 | exp = exp.first 65 | 66 | begin 67 | yield 68 | test = false 69 | arguments = [exp] 70 | rescue Exception => err 71 | test = (exp === err) 72 | arguments = [exp, err] 73 | end 74 | 75 | message = options[:message] || pass_message(*arguments) 76 | backtrace = options[:backtrace] || caller 77 | 78 | if !test 79 | fail self, message, backtrace 80 | end 81 | end 82 | 83 | # 84 | # 85 | # 86 | def self.refute!(*exp) #:yield: 87 | options = (Hash === exp.last ? exp.pop : {}) 88 | 89 | #exp = exp.first 90 | 91 | begin 92 | yield 93 | test = true 94 | arguments = exp 95 | rescue Exception => err 96 | test = !exp.any?{ |e| e === err } 97 | arguments = exp #+ [err] 98 | end 99 | 100 | message = options[:message] || fail_message(*arguments) 101 | backtrace = options[:backtrace] || caller 102 | 103 | if !test 104 | fail self, message, backtrace 105 | end 106 | end 107 | =end 108 | 109 | end 110 | -------------------------------------------------------------------------------- /demo/03_assertor.md: -------------------------------------------------------------------------------- 1 | # Assay as Assertor 2 | 3 | Assay classes can be converted to assertors, otherwise known as *matchers* in 4 | RSpec circles. The idea behind Assertors is that they can be initialized with 5 | pre-set criteria and then applied to target subjects. 6 | 7 | ## Standard Target Matching 8 | 9 | assertor = EqualAssay[1] 10 | 11 | assertor.assert!(1) 12 | 13 | expect EqualAssay do 14 | assertor.assert!(2) 15 | end 16 | 17 | ## Partial Arguments 18 | 19 | assertor = LessAssay[1,__] 20 | 21 | We can apply the assertor using the `#pass!` method. 22 | 23 | assertor.assert!(2) 24 | 25 | Likewise we can assert the negated expression using `#fail!`. 26 | 27 | assertor.refute!(0) 28 | 29 | Assay partial a very versile because they allow any argument to become 30 | the target of a assertor. 31 | 32 | assertor = CompareAssay[2,1,__] 33 | 34 | assertor.assert!(1) 35 | assertor.refute!(0) 36 | 37 | ## Match Operator 38 | 39 | The `#=~` method is an alias for `#assert!`. 40 | 41 | assertor = EqualAssay[1] 42 | assertor =~ 1 43 | 44 | Conversely, `#!~` method is an alias for `#refute!`. 45 | 46 | assertor !~ 2 47 | 48 | ## Case Operator 49 | 50 | The `#===` method is also an alias for `#assert!`. 51 | 52 | assertor === 1 53 | 54 | This allows the `case` statement to be used in an intersting way. 55 | 56 | case 10 57 | when KindAssay[Numeric] 58 | when EqualAssay[10.0] 59 | end 60 | 61 | ## Negated Assertors 62 | 63 | Assertors can also be negated so that pass and fail methods swap behaviors. 64 | 65 | assertor = EqualityAssay[1] 66 | 67 | assertor.not =~ 2 68 | assertor.not !~ 1 69 | 70 | For conveience we can also negate the assertor using the `~` unary operator. 71 | 72 | !assertor === 2 73 | 74 | ## Just Cheking 75 | 76 | Assertors can also be used just to test the assertion without actually 77 | raising the associated exception. 78 | 79 | assertor = EqualityAssay[__,1] 80 | 81 | assertor.pass?(1) 82 | assertor.fail?(2) 83 | 84 | ## RSpec Compatability 85 | 86 | RSpec compatibality is provided via neccessary method alias, in particular 87 | `#matches?` and `#does_not_match?`. 88 | 89 | assertor = EqualityAssay[__,1] 90 | 91 | assert assertor.matches?(1) 92 | assert assertor.does_not_match?(2) 93 | 94 | Error messages are handle by RSpec by `#failure_message_for_should` and 95 | `#failure_message_for_should_not`. 96 | 97 | assertor.failure_message_for_should(1) 98 | assertor.failure_message_for_should_not(2) 99 | 100 | -------------------------------------------------------------------------------- /work/defunct/assertable_module/assertions/throws.rb: -------------------------------------------------------------------------------- 1 | require 'ae/assertions/execution' 2 | 3 | class ThrowFailure < ExecutionFailure 4 | def self.assertion_name 5 | :throws 6 | end 7 | 8 | def self.assertion_name! 9 | :not_thown 10 | end 11 | 12 | def self.assert(sym, msg=nil, call=nil) #:yeild: 13 | msg = msg || fail_message(sym) 14 | test = true 15 | catch(sym) do 16 | begin 17 | yield 18 | rescue ArgumentError => err # 1.9 exception 19 | msg += ", not #{err.message.split(/ /).last}" 20 | test = false 21 | rescue NameError => err # 1.8 exception 22 | msg += ", not #{err.name.inspect}" 23 | test = false 24 | end 25 | end 26 | fail new(msg, call||caller) unless test 27 | end 28 | 29 | # FIXME: How to get the opposite? 30 | def self.assert!(sym, msg=nil, call=nil) #:yield: 31 | msg = msg || fail_message(sym) 32 | test = false 33 | catch(sym) do 34 | begin 35 | yield 36 | rescue ArgumentError => err # 1.9 exception 37 | #msg += ", not #{err.message.split(/ /).last}" 38 | test = true 39 | rescue NameError => err # 1.8 exception 40 | #msg += ", not #{err.name.inspect}" 41 | test = true 42 | end 43 | end 44 | fail new(msg, call||caller) unless test 45 | end 46 | 47 | def fail_message(sym) 48 | "Expected #{sym} to have been thrown" 49 | end 50 | 51 | def fail_message!(sym) 52 | "Expected #{sym} NOT to have been thrown" 53 | end 54 | 55 | # Note: This is not used by the #assert method. 56 | def self.check(sym) #:yield: 57 | test = true 58 | catch(sym) do 59 | begin 60 | yield 61 | rescue ArgumentError => err # 1.9 exception 62 | test = false 63 | rescue NameError => err # 1.8 exception 64 | test = false 65 | end 66 | end 67 | test 68 | end 69 | 70 | # Note: This is not used by the #assert! method. 71 | def self.check!(sym) #:yield: 72 | test = false 73 | catch(sym) do 74 | begin 75 | yield 76 | rescue ArgumentError => err # 1.9 exception 77 | test = true 78 | rescue NameError => err # 1.8 exception 79 | test = true 80 | end 81 | end 82 | test 83 | end 84 | end 85 | 86 | module Assertable 87 | # Passes if the block throws expected_symbol 88 | # 89 | # assert_throws :done do 90 | # throw :done 91 | # end 92 | # 93 | def assert_throws(sym, opts, &blk) 94 | opts[:backtrace] ||= caller 95 | ThrowFailure.assert(sym, opts, &blk) 96 | end 97 | 98 | # Passes if the block throws expected_symbol 99 | # 100 | # assert_not_thrown :done do 101 | # throw :chimp 102 | # end 103 | # 104 | def assert_not_thrown(sym, opts, &blk) 105 | opts[:backtrace] ||= caller 106 | ThrowFailure.assert!(sym, opts, &blk) 107 | end 108 | end 109 | -------------------------------------------------------------------------------- /lib/assay/assertion.rb: -------------------------------------------------------------------------------- 1 | require 'brass' 2 | 3 | require_relative 'core_ext/na' 4 | require_relative 'core_ext/kernel' 5 | 6 | require_relative 'assertor' 7 | require_relative 'assertable' 8 | 9 | # TODO: Don't care for Proc === subject conditional code, but not 10 | # sure how else to deal with lambda subjects. 11 | 12 | # Base class for all Assay classes. This class defines all the logic 13 | # for assertions as exception classes as well as test assertion matchers. 14 | # 15 | class Assertion < Exception 16 | 17 | extend Assay::Assertable 18 | 19 | # 20 | # When displaying errors, use this as a rule of thumb 21 | # for determining when the inspected object will be too 22 | # big for a single line message. 23 | # 24 | SIZE_LIMIT = 13 25 | 26 | # 27 | # Each new subclass must call the +register+ method. This is not an option! 28 | # The method must be called in order to add the class to the Assertion 29 | # name and operator indicies, so they might be looked-up efficiently by 30 | # other libraries. 31 | # 32 | def self.register(op, name=nil) 33 | case op.to_s 34 | when /\W/ 35 | @operator = op.to_sym 36 | @assertive_name = name.to_sym if name 37 | else 38 | @operator = (op.to_s + '?').to_sym 39 | @assertive_name = op.to_sym 40 | end 41 | 42 | operator_index[operator] = self 43 | name_index[assertive_name] = self 44 | end 45 | 46 | # 47 | # When Assertion is inherited, a list of all Assertion subclasses is kept. 48 | # This can be used to assertions frameworks with dynamic implementations. 49 | # 50 | def self.inherited(base) 51 | @@by_operator = nil 52 | @@by_name = nil 53 | subclasses << base 54 | end 55 | 56 | # 57 | # List of all subclasses of Assertion. 58 | # 59 | def self.subclasses 60 | @@subclasses ||= [] 61 | end 62 | 63 | # 64 | # If operator is not given, returns a hash table of assertion classes 65 | # indexed by operator. 66 | # 67 | def self.by_operator(operator=nil) 68 | return operator_index.dup unless operator 69 | operator_index[operator.to_sym] 70 | end 71 | 72 | # 73 | # If operator is not given, returns a hash table of assertion classes 74 | # indexed by assertive name. 75 | # 76 | def self.by_name(name=nil) 77 | return name_index.dup unless name 78 | name_index[name.to_sym] 79 | end 80 | 81 | private 82 | 83 | def self.operator_index 84 | @@operator_index ||= {} 85 | end 86 | 87 | def self.name_index 88 | @@name_index ||= {} 89 | end 90 | 91 | # 92 | # Setup new Assertion object. 93 | # 94 | def initialize(msg=nil) #, *criteria, &block) 95 | super(msg) 96 | 97 | #@criteria = criteria 98 | #@block = block 99 | #@not = false 100 | 101 | @assertion = true 102 | 103 | #options = (Hash === criteria.last ? criteria.pop : {}) 104 | #set_backtrace(options[:backtrace]) if options[:backtrace] 105 | #set_negative(options[:negated]) if options[:negated] 106 | end 107 | 108 | end 109 | 110 | 111 | =begin 112 | 113 | # 114 | #def to_s 115 | # #if @negative 116 | # # "NOT " + super() 117 | # #else 118 | # super() 119 | # #end 120 | #end 121 | 122 | =end 123 | 124 | -------------------------------------------------------------------------------- /work/consider/return_failure.rb: -------------------------------------------------------------------------------- 1 | require 'assay/failure' 2 | 3 | module Assay 4 | 5 | #NoArgument = Object.new 6 | 7 | # DEPRECATE: This class has little value. Instead of doing 8 | # 9 | # assert_returns(4){ v } 10 | # 11 | # Simply test equality on the returned value. 12 | # 13 | # assert_equal(4, v) 14 | # 15 | # TODO: What's up with N/A? Use Facets' NA object? 16 | class ReturnFailure < Failure 17 | 18 | # 19 | def self.assert(exp, opts={}, &blk) #:yeild: 20 | #msg = fail_message(exp) 21 | res = yield 22 | if :"N/A" == exp 23 | chk = (res ? true : false) 24 | args = [exp] 25 | else 26 | chk = (exp == res) 27 | #msg = msg + ", but was #{res}" 28 | args = [exp, res] 29 | end 30 | if !chk 31 | msg = opts[:message] 32 | bkt = opts[:backtrace] || caller 33 | fail new(msg, :backtrace=>bkt, :arguments=>args) 34 | end 35 | end 36 | 37 | # 38 | def self.refute(exp, opts={}, &blk) # :yield: 39 | #msg = fail_message!(exp) 40 | res = yield 41 | if :"N/A" == exp 42 | chk = (res ? false : true) 43 | args = [exp] 44 | else 45 | chk = (exp != res) 46 | #msg = msg + ", but was #{res}" 47 | args = [exp, res] 48 | end 49 | if !chk 50 | msg = opts[:message] 51 | bkt = opts[:backtrace] || caller 52 | fail new(msg, :backtrace=>bkt, :arguments=>args) 53 | end 54 | end 55 | 56 | # Check assertion. 57 | def self.check(exp) #:yield: 58 | case exp 59 | when :"N/A" 60 | yield ? true : false 61 | else 62 | exp == yield 63 | end 64 | end 65 | 66 | # 67 | def to_s 68 | return super unless @arguments.size == 2 69 | 70 | exp = @arguments[0].inspect 71 | 72 | if @_negated 73 | if :"N/A" == exp 74 | "Expected block NOT to return a value" 75 | else 76 | "Expected block NOT to return #{exp}" 77 | end 78 | else 79 | if :"N/A" == exp 80 | "Expected block to return a value" 81 | else 82 | "Expected block to return #{exp}" 83 | end 84 | end 85 | end 86 | 87 | end 88 | 89 | 90 | module Assertable 91 | 92 | # Passes if the block yields a specified value (Compares with #==). 93 | # 94 | # assert_returns "something wanted" do 95 | # do_the_thing 96 | # end 97 | # 98 | def assert_returns(exp=:"N/A", opts={}, &blk) # :yield: 99 | opts[:backtrace] ||= caller 100 | ReturnFailure.assert(exp, opts, &blk) 101 | end 102 | 103 | # Passes if the block does not yield a specific value. 104 | # 105 | # refute_returns "something unwanted" do 106 | # do_the_thing 107 | # end 108 | # 109 | def refute_returns(exp=:"N/A", opts={}, &blk) # :yield: 110 | opts[:backtrace] ||= caller 111 | ReturnFailure.refute(exp, opts, &blk) 112 | end 113 | 114 | alias_method :assert_does_not_return, :refute_returns 115 | end 116 | 117 | 118 | module Matchers 119 | # 120 | # 121 | # object.assert is_returned{ ... } 122 | # 123 | def is_returned(&blk) 124 | ReturnFailure.to_matcher(&blk) 125 | end 126 | 127 | # 128 | # 129 | # object.should be_returned{ ... } 130 | # 131 | def be_returned(&blk) 132 | ReturnFailure.to_matcher(&blk) 133 | end 134 | end 135 | 136 | end 137 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | #!mast .index bin demo lib spec test [A-Z][A-Z]* 2 | .index 3 | demo/00_introduction.md 4 | demo/01_assay_classes/00_introduction.md 5 | demo/01_assay_classes/01_nil_assay.md 6 | demo/01_assay_classes/02_boolean_assay.md 7 | demo/01_assay_classes/03_false_assay.md 8 | demo/01_assay_classes/03_true_assay.md 9 | demo/01_assay_classes/04_like_assay.md 10 | demo/01_assay_classes/05_equal_assay.md 11 | demo/01_assay_classes/06_unequal_assay.md 12 | demo/01_assay_classes/07_equality_assay.md 13 | demo/01_assay_classes/08_identity_assay.md 14 | demo/01_assay_classes/09_case_assay.md 15 | demo/01_assay_classes/10_match_assay.md 16 | demo/01_assay_classes/11_nomatch_assay.md 17 | demo/01_assay_classes/12_compare_assay.md 18 | demo/01_assay_classes/13_less_assay.md 19 | demo/01_assay_classes/14_more_assay.md 20 | demo/01_assay_classes/15_less_equal_assay.md 21 | demo/01_assay_classes/16_more_equal_assay.md 22 | demo/01_assay_classes/17_close_assay.md 23 | demo/01_assay_classes/17_within_assay.md 24 | demo/01_assay_classes/18_kind_assay.md 25 | demo/01_assay_classes/19_instance_assay.md 26 | demo/01_assay_classes/20_include_assay.md 27 | demo/01_assay_classes/21_empty_assay.md 28 | demo/01_assay_classes/22_respond_assay.md 29 | demo/01_assay_classes/23_execution_assay.md 30 | demo/01_assay_classes/23_return_assay.md 31 | demo/01_assay_classes/24_rescue_assay.md 32 | demo/01_assay_classes/25_raise_assay.md 33 | demo/01_assay_classes/26_throw_assay.md 34 | demo/01_assay_classes/27_path_assay.md 35 | demo/01_assay_classes/28_directory_assay.md 36 | demo/01_assay_classes/29_file_assay.md 37 | demo/01_assay_classes/30_output_assay.md 38 | demo/01_assay_classes/31_stdout_assay.md 39 | demo/01_assay_classes/32_stderr_assay.md 40 | demo/02_lookup.md 41 | demo/03_assertor.md 42 | demo/04_assay.md 43 | demo/applique/helper.rb 44 | demo/applique/setup.rb 45 | lib/assay/adapter/minitest.rb 46 | lib/assay/adapter/testunit.rb 47 | lib/assay/assertable.rb 48 | lib/assay/assertion.rb 49 | lib/assay/assertor.rb 50 | lib/assay/boolean_assay.rb 51 | lib/assay/case_assay.rb 52 | lib/assay/close_assay.rb 53 | lib/assay/compare_assay.rb 54 | lib/assay/core_ext/kernel.rb 55 | lib/assay/core_ext/na.rb 56 | lib/assay/directory_assay.rb 57 | lib/assay/empty_assay.rb 58 | lib/assay/equal_assay.rb 59 | lib/assay/equality_assay.rb 60 | lib/assay/execution_assay.rb 61 | lib/assay/false_assay.rb 62 | lib/assay/file_assay.rb 63 | lib/assay/identity_assay.rb 64 | lib/assay/include_assay.rb 65 | lib/assay/instance_assay.rb 66 | lib/assay/kind_assay.rb 67 | lib/assay/less_assay.rb 68 | lib/assay/less_equal_assay.rb 69 | lib/assay/like_assay.rb 70 | lib/assay/match_assay.rb 71 | lib/assay/more_assay.rb 72 | lib/assay/more_equal_assay.rb 73 | lib/assay/nil_assay.rb 74 | lib/assay/nomatch_assay.rb 75 | lib/assay/output_assay.rb 76 | lib/assay/path_assay.rb 77 | lib/assay/raise_assay.rb 78 | lib/assay/rescue_assay.rb 79 | lib/assay/respond_assay.rb 80 | lib/assay/return_assay.rb 81 | lib/assay/silent_assay.rb 82 | lib/assay/stderr_assay.rb 83 | lib/assay/stdout_assay.rb 84 | lib/assay/throw_assay.rb 85 | lib/assay/true_assay.rb 86 | lib/assay/unequal_assay.rb 87 | lib/assay/within_assay.rb 88 | lib/assay.rb 89 | lib/assay.yml 90 | test/case_compare_assay.rb 91 | test/case_empty_assay.rb 92 | test/case_equal_assay.rb 93 | test/case_equality_assay.rb 94 | test/case_false_assay.rb 95 | test/case_identity_assay.rb 96 | test/case_include_assay.rb 97 | test/case_instance_assay.rb 98 | test/case_kind_assay.rb 99 | test/case_less_assay.rb 100 | test/case_less_equal_assay.rb 101 | test/case_like_assay.rb 102 | test/case_match_assay.rb 103 | test/case_more_assay.rb 104 | test/case_more_equal_assay.rb 105 | test/case_nil_assay.rb 106 | test/case_nomatch_assay.rb 107 | test/case_raise_assay.rb 108 | test/case_respond_assay.rb 109 | test/case_throw_assay.rb 110 | test/case_true_assay.rb 111 | test/case_unequal_assay.rb 112 | test/case_within_assay.rb 113 | test/helper.rb 114 | LICENSE.txt 115 | HISTORY.md 116 | README.md 117 | DEMO.md 118 | -------------------------------------------------------------------------------- /lib/assay/assertor.rb: -------------------------------------------------------------------------------- 1 | module Assay 2 | 3 | # Assertor delegates to Assay class. It provides an object-oriented 4 | # interface to makeing assertions, as opposed to the functional 5 | # interface of the Assay classes themselves. 6 | # 7 | class Assertor 8 | 9 | # 10 | # 11 | def initialize(assay_class, *criteria, &block) 12 | @assay = assay_class 13 | @criteria = criteria 14 | @block = block 15 | @not = false 16 | end 17 | 18 | # 19 | # The assay class to which this assertor delegates. 20 | # 21 | attr :assay 22 | 23 | # 24 | # The criteria for applying the assertor. 25 | # 26 | attr :criteria 27 | 28 | # 29 | # Block criterion. 30 | # 31 | attr :block 32 | 33 | # 34 | # Is the assertor negated? 35 | # 36 | def not? 37 | @not 38 | end 39 | 40 | # 41 | # 42 | def pass?(subject, &block) 43 | arguments, block = complete_criteria(subject, &block) 44 | @not ^ @assay.pass?(*arguments, &block) 45 | end 46 | 47 | # 48 | # 49 | def fail?(subject, &block) 50 | arguments, block = complete_criteria(subject, &block) 51 | @not ^ @assay.fail?(*arguments, &block) 52 | end 53 | 54 | # 55 | # 56 | def assert!(subject, &block) 57 | # technically this needs to be controlled by the assay class 58 | if block.nil? && Proc === subject 59 | block = subject 60 | subject = NA 61 | end 62 | 63 | arguments, block = complete_criteria(subject, &block) 64 | 65 | if @not 66 | @assay.refute!(*arguments, &block) 67 | else 68 | @assay.assert!(*arguments, &block) 69 | end 70 | end 71 | 72 | # 73 | # 74 | def refute!(subject, &block) 75 | # technically this needs to be controlled by the assay class 76 | if block.nil? && Proc === subject 77 | block = subject 78 | subject = NA 79 | end 80 | 81 | arguments, block = complete_criteria(subject, &block) 82 | 83 | if @not 84 | @assay.assert!(*arguments, &block) 85 | else 86 | @assay.refute!(*arguments, &block) 87 | end 88 | end 89 | 90 | alias_method :==, :pass? 91 | alias_method :!=, :fail? 92 | 93 | alias_method :=~, :assert! 94 | alias_method :!~, :refute! 95 | 96 | alias_method :===, :assert! 97 | 98 | # 99 | # Create a negated form of the matcher. 100 | # 101 | # @todo Should this be @! method instead? 102 | # 103 | def !@ 104 | dup.negate! 105 | end 106 | 107 | # 108 | # Create a negated form of the matcher. 109 | # 110 | # @todo Best name for this method? 111 | # 112 | def not 113 | dup.negate! 114 | end 115 | 116 | # 117 | # Assertion message. This is only used by RSpec compatibility methods. 118 | # 119 | def assert_message(subject, &block) 120 | arguments, block = complete_criteria(subject, &block) 121 | @assay.assert_message(*arguments, &block) 122 | end 123 | 124 | # 125 | # Refutation message. This is only used by RSpec compatibility methods. 126 | # 127 | def refute_message(subject, &block) 128 | arguments, block = complete_criteria(subject, &block) 129 | @assay.refute_message(*arguments, &block) 130 | end 131 | 132 | # The following methods allow Assay objects to work as RSpec matchers. 133 | 134 | # For RSpec matcher compatability. 135 | alias matches? pass? 136 | 137 | # For RSpec matcher compatability. 138 | alias does_not_match? fail? 139 | 140 | # For RSpec matcher compatability. 141 | alias failure_message_for_should assert_message 142 | 143 | # For RSpec matcher compatability. 144 | alias failure_message_for_should_not refute_message 145 | 146 | ## 147 | ## Returns Assay instance. 148 | ## 149 | #def exception(subject, msg=nil) 150 | # @assay.new(msg || message, subject, *criteria, &block) 151 | # # :negated => options[:negated], 152 | # # :backtrace => options[:backtrace] || caller, 153 | #end 154 | 155 | protected 156 | 157 | # 158 | # Toggle the `@not` flag. 159 | # 160 | def negate! 161 | @not = !@not 162 | self 163 | end 164 | 165 | private 166 | 167 | # 168 | # 169 | # 170 | def complete_criteria(subject, &block) 171 | block = block || @block 172 | 173 | return @criteria, block if subject == NA 174 | 175 | if i = @criteria.index(NA) 176 | args = @criteria[0...i] + [subject] + @criteria[i+1..-1] 177 | else 178 | args = [subject] + @criteria 179 | end 180 | 181 | return args, block 182 | end 183 | 184 | end 185 | 186 | end 187 | 188 | -------------------------------------------------------------------------------- /lib/assay/assertable.rb: -------------------------------------------------------------------------------- 1 | require_relative 'assertor' 2 | 3 | module Assay 4 | 5 | module Assertable 6 | 7 | $ASSERTION_COUNTS ||= Hash.new{ |h,k| h[k] = 0 } #{:total=>0,:pass=>0,:fail=>0} 8 | 9 | # 10 | # When displaying errors, use this as a rule of thumb 11 | # for determining when the inspected object will be too 12 | # big for a single line message. 13 | # 14 | SIZE_LIMIT = 13 15 | 16 | # TODO: There's really no point to the defaults for #operator and 17 | # assertive name b/c `register` is now reauired which set them. 18 | # But that's in Assertion not Assertable, so something's not quite 19 | # right in that regard. 20 | 21 | # 22 | # If the assertion coresponds to a regular method, particular a symbolic 23 | # operator (hence the name of this method) then it should be specified via 24 | # this interface. Otherwise, it should be given a fitting "make believe" 25 | # method name and specified here. If not overridden it will be assumed 26 | # to be the same as the `assertion_name` appended by `?`. 27 | # 28 | def operator 29 | @operator ||= (name.split('::').last.chomp('Assay').downcase + '?').to_sym 30 | end 31 | 32 | # 33 | # The assertive name is used for the construction of assertive nomenclatures 34 | # such as `assert_equal`. 35 | # 36 | def assertive_name 37 | @assertive_name ||= ( 38 | if operator.to_s.end_with?('?') 39 | operator.to_s.chomp('?').to_sym 40 | else 41 | name.split('::').last.chomp('Assay').downcase.to_sym 42 | end 43 | ) 44 | end 45 | 46 | # 47 | # Create an assertor for the assay class, given +criteria+. 48 | # 49 | def assertor(*criteria, &block) 50 | Assertor.new(self, *criteria, &block) 51 | end 52 | 53 | # 54 | # Alias for `#assertor`. 55 | # 56 | def [](*criteria, &block) 57 | assertor(*criteria, &block) 58 | end 59 | 60 | # 61 | # Check the assertion, return `true` if passing, `false` otherwise. 62 | # 63 | def pass?(subject, *criteria, &block) 64 | subject 65 | end 66 | 67 | # 68 | # Check the assertion, return `true` if failing, `false` otherwise. 69 | # 70 | def fail?(subject, *criteria, &block) 71 | ! pass?(subject, *criteria, &block) 72 | end 73 | 74 | # 75 | # Test the assertion, raising the exception if failing. 76 | # 77 | def assert!(*arguments, &block) 78 | options = (Hash === arguments.last ? arguments.pop : {}) 79 | 80 | backtrace = options[:backtrace] || caller 81 | message = options[:message] || assert_message(*arguments, &block) 82 | 83 | pass = pass?(*arguments, &block) 84 | 85 | assert pass, self, message, backtrace 86 | 87 | #if pass?(*arguments, &block) 88 | # increment(:pass) 89 | #else 90 | # increment(:fail) 91 | # fail self, message, backtrace 92 | #end 93 | end 94 | 95 | # 96 | # Test the refutation of the assertion. 97 | # 98 | # Test the inverse assertion, raising the exception if not failing. 99 | # 100 | def refute!(*arguments, &block) 101 | options = (Hash === arguments.last ? arguments.pop : {}) 102 | 103 | backtrace = options[:backtrace] || caller 104 | message = options[:message] || refute_message(*arguments, &block) 105 | 106 | fail = fail?(*arguments, &block) 107 | 108 | assert fail, self, message, backtrace 109 | 110 | #if fail?(*arguments, &block) 111 | # increment(:pass) 112 | #else 113 | # increment(:fail) 114 | # fail self, message, backtrace 115 | #end 116 | end 117 | 118 | ## 119 | ## 120 | ## 121 | #def get_message(subject, fail=false) 122 | # @not ^ fail ? refute_message(subject) : assert_message(subject) 123 | #end 124 | 125 | # 126 | # 127 | # 128 | def assert_message(*arguments, &block) 129 | standard_message(*arguments, &block) 130 | end 131 | 132 | # 133 | # 134 | # 135 | def refute_message(*arguments, &block) 136 | "! " + assert_message(*arguments, &block) 137 | end 138 | 139 | private 140 | 141 | ## 142 | ## Increment global `$ASSERTION_COUNTS` variable. 143 | ## 144 | #def increment(which) 145 | # $ASSERTION_COUNTS[:total] += 1 146 | # $ASSERTION_COUNTS[which.to_sym] += 1 147 | #end 148 | 149 | # 150 | # Construct a standard error message. 151 | # 152 | def standard_message(*arguments, &block) 153 | args_inspect = arguments.map{ |o| o.inspect } 154 | 155 | op = self.operator.to_s 156 | op = (/\w/ =~ op) ? ".#{op} " : " #{op} " 157 | 158 | if args_inspect.any?{ |o| o.size > SIZE_LIMIT } 159 | vars = ['b'] 160 | t = args_inspect.size - 2 161 | t.times{ vars << vars.last.succ } 162 | 163 | msg = '' 164 | msg << "a#{op} " + vars.join(',') + "\n" 165 | msg << args_inspect.join("\n") 166 | msg 167 | else 168 | args_inspect.first + "#{op}" + args_inspect[1..-1].join(', ') + "" 169 | end 170 | end 171 | 172 | end 173 | 174 | end 175 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Assay 2 | 3 | [Website](http://rubyworks.github.com/assay) / 4 | [Documentation](http://rubydoc.info/gems/assay) / 5 | [Report Issue](http://github.com/rubyworks/assay/issues) / 6 | [Source Code](http://github.com/rubyworks/assay) 7 | 8 | [![Gem Version](https://badge.fury.io/rb/assay.png)](http://badge.fury.io/rb/assay) 9 | [![Build Status](https://secure.travis-ci.org/rubyworks/assay.png)](http://travis-ci.org/rubyworks/assay)     10 | [![Flattr Me](http://api.flattr.com/button/flattr-badge-large.png)](http://flattr.com/thing/324911/Rubyworks-Ruby-Development-Fund) 11 | 12 | 13 | ## DESCRIPTION 14 | 15 | Assay defines assertions in the same way that Ruby defines 16 | exceptions. An assertion then is nothing more that an 17 | extended Exception class. Assay provides a complete set 18 | of these assertion classes for the most common assertion types. 19 | It also provides both TestUnit-style assertion methods and 20 | RSpec-compatiable matchers built from these assertion classes 21 | for use in your preferred test harness. Assay is compatible with 22 | TestUnit, MiniTest, RSpec and other test frameworks. 23 | 24 | 25 | ## FEATURES 26 | 27 | * Patterned after the Ruby exception system. 28 | * Allows assertions specialized error messages. 29 | * Supports any variety of assertion "grammers". 30 | * Can be used with almost any test framework. 31 | 32 | 33 | ## LIMITATIONS 34 | 35 | * Assay is Ruby 1.9+ only! 36 | 37 | 38 | ## INSTALLATION 39 | 40 | To install with RubyGems simply open a console and type: 41 | 42 | $ gem install assay 43 | 44 | Site installation with the tarball can be done with Ruby Setup 45 | (gem install setup). See http://rubyworks.github.com/setup. 46 | 47 | 48 | ## UTILIZATION 49 | 50 | ### Assay Classes 51 | 52 | Assay consists of a set of Assertion subclasses known as *assays*. They 53 | are akin to Ruby's Exception subclasses, indeed the +Assertion+ base class 54 | is a subclass of Exception. But assays have special class methods that are 55 | used to make assertions. 56 | 57 | Consider the +EqualityAssay+ class. It defines methods for asserting equality 58 | via the `#==` method. 59 | 60 | EqualityAssay.assert!(1,1) 61 | 62 | Additionally, we can check the assertion's test without actually raising the 63 | assertion if it fails using the query method. 64 | 65 | EqualityAssay.pass?(1,1) #=> true 66 | 67 | Assays also provide the opposite method `#refute!` along with `#fail?`. 68 | 69 | EqualityAssay.refute!(1,2) 70 | 71 | EqualityAssay.fail?(1,2) #=> true 72 | 73 | Assay instances are test matchers, which can be conveniently defined with `#[]`. 74 | 75 | EqualityAssay[1] =~ 1 76 | 77 | Notice in the example we have used `#=~` to apply the matcher which makes 78 | the `#assert!` call to the Assay object. Likewise `#!~` can be used to 79 | call `#refute!` instead. And note that `#===` is also an alias for `#=~`. 80 | 81 | EqualityAssay[1] === 1 82 | 83 | Which means assay matchers can be used in case statments. 84 | 85 | case 10 86 | when InstanceAssay[Fixnum] 87 | when EqualityAssay[10.0] 88 | end 89 | 90 | Pretty neat. 91 | 92 | ### Framework Adapters 93 | 94 | Assay follows a standard practice of defining assertion error classes with 95 | an `#assertion?` method that returns +true+. This can be used by any test 96 | framework to easily detect when a raised error is an assertion rather than 97 | an ordinary error. To add support for this to common test frameworks Assay 98 | provides adapters. 99 | 100 | For example, to use assay with MiniTest framework add to your test helper 101 | script: 102 | 103 | require 'assay/adapter/minitest' 104 | 105 | Likewise for TestUnit. 106 | 107 | require 'assay/adapter/testunit' 108 | 109 | An RSpec adadpter is in the works, and should be out with the next release. 110 | 111 | Note that even without the adapter, you can still use Assay with other test 112 | frameworks. They will simply count Assay's assertions as regular errors. 113 | 114 | ### Customized Grammars 115 | 116 | Of course the classes are interesting and clearly make for a sound foundation, 117 | but in the end we want to write assertions more easily and concisely. For this 118 | we turn to separate "grammar" projects that depend on Assay's classes. The 119 | first of these, created as a spin-off project to demonstrate Assay's prowess, 120 | is {Fluidity}[http://rubyworks.github.com/fluidity]. Here is a quick taste of 121 | that gem's functionality. 122 | 123 | require 'fluidity' 124 | 125 | 10.should.be.kind_of(Integer) 126 | 127 | But is you are acustom to MiniTest's spec methods, you might prefer `must`. 128 | 129 | 10.must.be.kind_of(Integer) 130 | 131 | And to satisfy all those technical aficionados (like yours truly) there is `assert`. 132 | 133 | 10.assert.kind_of(Integer) 134 | 135 | Thre are also compatibility grammar projects available, spun-off from Assay, that 136 | provide compatability with legacy test frameworks which can serve as transition 137 | to Assay from these other frameworks. Follow the links below for each: 138 | 139 | * [Assay TestUnit](http://github.com/rubyworks/assay-testunit) 140 | * [Assay MiniTest](http://github.com/rubyworks/assay-minitest) 141 | * [RSpecial](http://github.com/rubyworks/rspecial) 142 | 143 | Usage is essentially the same for any one of them. For example, 144 | 145 | require 'assay/rspec' 146 | 147 | include Assay::Matchers 148 | 149 | 10.should be_kind_of(Integer) 150 | 151 | Note that the compatibility modules are not yet 100% compatable, lacking some 152 | of the more esoteric and complex features. But they are very nearly so, and 153 | will become more so in time. 154 | 155 | These are just a few possible grammars. There is no reason not to build 156 | your own grammar on top of Assay's classes if you have another approach in mind. 157 | Indeed, please do! That, after all, is the main purpose of having such 158 | a set of reusable assertion classes! 159 | 160 | ### Learning More 161 | 162 | There's more learn about Assay, mainly the variety of assay classes available, 163 | but also a few other bits of functionality not comvered here. To learn 164 | about these check out the {QED documentation}[http://github.com/rubyworks/assay] 165 | which provides an overiew of functionality with working examples, and the 166 | the {API documentation}[http://rubydoc.info/gems/asasy] for a more in depth look 167 | under the hood. 168 | 169 | 170 | ## LICENSE & COPYRIGHT 171 | 172 | Copyright (c) 2010 Rubyworks 173 | 174 | This program is ditributed under the terms of the *BSD-2-Cluase* license. 175 | 176 | See LICENSE.txtfile for details. 177 | 178 | -------------------------------------------------------------------------------- /work/defunct/static_assertion_methods/matchers/be.rb: -------------------------------------------------------------------------------- 1 | require 'assay/nomenclature/hander/should' 2 | 3 | module Assay 4 | 5 | module Nomenclature 6 | 7 | # Be Matchers provide a set of RSpec-compatible matcher methods. 8 | # These matchers provide all the traditional Rspec matchers, less 9 | # a bit of extraneous verbosity, plus a few additional matchers. 10 | # 11 | module Be 12 | 13 | # 14 | def self.activate 15 | ::Object.__send__(:include, self) 16 | end 17 | 18 | # CompareFailure 19 | 20 | # Passes if the expected and actual are alike. 21 | # 22 | # object.should be_like(criterion) 23 | # 24 | def be_like(exp) 25 | CompareFailure.to_matcher(exp) 26 | end 27 | 28 | # Passes if the expected and actual are alike. 29 | # 30 | # object.assert is_like(criterion) 31 | # 32 | alias_method :is_like, :be_like 33 | 34 | # DeltaFailure 35 | 36 | # Passes if expected and actual are equal within delta tolerance. 37 | # 38 | # value1.should be_within(delta, value2) 39 | # 40 | def is_within(delta, exp) 41 | DeltaFailure.to_matcher(exp, delta) 42 | end 43 | 44 | # Passes if expected and actual are nto equal within delta tolerance. 45 | # 46 | # value1.assert is_within(delta, value2) 47 | # 48 | def be_within(delta, exp) 49 | DeltaFailure.to_matcher(exp, delta) 50 | end 51 | 52 | # EmptyFailure 53 | 54 | # Passes if object is empty. 55 | # 56 | # object.assert is_empty 57 | # 58 | def is_empty 59 | EmptyFailure.to_matcher 60 | end 61 | 62 | # Passes if object is empty. 63 | # 64 | # object.should be_empty 65 | # 66 | def be_empty 67 | EmptyFailure.to_matcher 68 | end 69 | 70 | # EqualityFailure 71 | 72 | # Passes if +expected+ == +actual+. 73 | # 74 | # 'MY STRING'.assert is_equal_to('my string'.upcase) 75 | # 'MY STRING'.refute is_equal_to('another string') 76 | # 77 | def is_equal_to(exp) #, opts={}) 78 | EqualityFailure.to_matcher(exp) 79 | end 80 | 81 | # Passes if +expected+ == +actual+. 82 | # 83 | # 'MY STRING'.should be_equal_to('my string'.upcase) 84 | # 'MY STRING'.should_not be_equal_to('another string') 85 | # 86 | def be_equal_to(exp) 87 | EqualityFailure.to_matcher(exp) 88 | end 89 | 90 | # ExecutionFailure 91 | 92 | # FIXME: Reasonable matcher for ExectuionFailure ? 93 | # 94 | # 95 | # proc.assert is_executed(*args) 96 | # 97 | def is_executed(*args, &block) 98 | ExecutionFailure.to_matcher(args, &block) 99 | end 100 | 101 | # 102 | # 103 | # proc.should be_executed(*args) 104 | # 105 | def be_extecuted(&block) 106 | ExecutionFailure.to_matcher(args, &block) 107 | end 108 | 109 | # FalseFailure 110 | 111 | # Passed if object is +false+. 112 | # 113 | # value.assert is_false 114 | # 115 | def is_false 116 | FalseFailure.to_matcher 117 | end 118 | 119 | # Passed if object is +false+. 120 | # 121 | # value.should be_false 122 | # 123 | def be_false 124 | FalseFailure.to_matcher 125 | end 126 | 127 | # IdentityFailure 128 | 129 | # Passes if actual is the same exact object as expected. 130 | # 131 | # object.assert is_identical_to(object) 132 | # 133 | def is_identical_to(obj) 134 | IdentityFailure.to_matcher(obj) 135 | end 136 | 137 | # Passes if actual is the same exact object as expected. 138 | # 139 | # object.should be_identical_to(object) 140 | # 141 | def be_identical_to(obj) 142 | IdentityFailure.to_matcher(obj) 143 | end 144 | 145 | # InstanceFailure 146 | 147 | # Passes if object is an instance of class. 148 | # 149 | # object.assert is_instance_of(class) 150 | # 151 | def is_instance_of(cls) 152 | InstanceFailure.to_matcher(cls) 153 | end 154 | 155 | # Passes if object is an instance of class. 156 | # 157 | # object.should be_instance_of(class) 158 | # 159 | def be_instance_of(cls) 160 | InstanceFailure.to_matcher(cls) 161 | end 162 | 163 | # KindFailure 164 | 165 | # Passes if object is a kind of class. 166 | # 167 | # object.assert is_a_kind_of(class) 168 | # 169 | def is_kind_of(cls) 170 | KindFailure.to_matcher(cls) 171 | end 172 | 173 | # Passes if object is a kind of class. 174 | # 175 | # object.should be_a_kind_of(class) 176 | # 177 | def be_kind_of(cls) 178 | KindFailure.to_matcher(cls) 179 | end 180 | 181 | # MatchFailure 182 | 183 | # Passes if object matches pattern using `#=~` method. 184 | # 185 | # object.assert is_match_for(regexp) 186 | # 187 | def is_match_for(regexp) 188 | MatchFailure.to_matcher(regexp) 189 | end 190 | 191 | # Passes if object matches pattern using `#=~` method. 192 | # 193 | # object.should be_match_for(regexp) 194 | # 195 | def be_match_for(regexp) 196 | MatchFailure.to_matcher(regexp) 197 | end 198 | 199 | # NilFailure 200 | 201 | # Passed if object is +nil+. 202 | # 203 | # value.assert is_nil 204 | # 205 | def is_nil 206 | NilFailure.to_matcher 207 | end 208 | 209 | # Passed if object is +nil+. 210 | # 211 | # value.should be_nil 212 | # 213 | def be_nil 214 | NilFailure.to_matcher 215 | end 216 | 217 | # RaiseFailure 218 | 219 | # FIXME: Fix raise matchers 220 | # 221 | # Exception.assert is_raised{ ... } 222 | # 223 | def is_raised(&blk) 224 | RaiseFailure.to_matcher(&blk) 225 | end 226 | 227 | # 228 | # 229 | # Exception.should be_raised{ ... } 230 | # 231 | def be_raised(&blk) 232 | RaiseFailure.to_matcher(&blk) 233 | end 234 | 235 | # RespondFailure 236 | 237 | # 238 | # 239 | # object.assert is_responsive_to(:method_symbol) 240 | # 241 | def is_responsive_to(method) 242 | ResponseFailure.to_matcher(method) 243 | end 244 | 245 | # 246 | # 247 | # object.should be_responsive_to(:method_symbol) 248 | # 249 | def be_responsive_to(method) 250 | ResponseFailure.to_matcher(method) 251 | end 252 | 253 | # SameFailure 254 | 255 | # 256 | # 257 | # object1.assert is_same_as(object2) 258 | # 259 | def is_same_as(obj) 260 | SameFailure.to_matcher(obj) 261 | end 262 | 263 | # 264 | # 265 | # object1.should be_same_as(object2) 266 | # 267 | def be_same_as(obj) 268 | SameFailure.to_matcher(obj) 269 | end 270 | 271 | # ThrowFailure 272 | 273 | # 274 | # 275 | # :symbol.assert is_thrown{ ... } 276 | # 277 | def is_thrown(&blk) 278 | ThrowFailure.to_matcher(&blk) 279 | end 280 | 281 | # 282 | # 283 | # :symbol.should be_thrown{ ... } 284 | # 285 | def be_thrown(&blk) 286 | ThrowFailure.to_matcher(&blk) 287 | end 288 | 289 | # TrueFailure 290 | 291 | # Passed if object is +true+. 292 | # 293 | # value.assert is_true 294 | # 295 | def is_true 296 | TrueFailure.to_matcher 297 | end 298 | 299 | # Passed if object is +true+. 300 | # 301 | # value.should be_true 302 | # 303 | def be_true 304 | TrueFailure.to_matcher 305 | end 306 | 307 | end 308 | 309 | end 310 | 311 | end 312 | -------------------------------------------------------------------------------- /.gemspec: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | require 'yaml' 4 | require 'pathname' 5 | 6 | module Indexer 7 | 8 | # Convert index data into a gemspec. 9 | # 10 | # Notes: 11 | # * Assumes all executables are in bin/. 12 | # * Does not yet handle default_executable setting. 13 | # * Does not yet handle platform setting. 14 | # * Does not yet handle required_ruby_version. 15 | # * Support for rdoc entries is weak. 16 | # 17 | class GemspecExporter 18 | 19 | # File globs to include in package --unless a manifest file exists. 20 | FILES = ".index .yardopts alt bin data demo ext features lib man spec test try* [A-Z]*.*" unless defined?(FILES) 21 | 22 | # File globs to omit from FILES. 23 | OMIT = "Config.rb" unless defined?(OMIT) 24 | 25 | # Standard file patterns. 26 | PATTERNS = { 27 | :root => '{.index,Gemfile}', 28 | :bin => 'bin/*', 29 | :lib => 'lib/{**/}*', #.rb', 30 | :ext => 'ext/{**/}extconf.rb', 31 | :doc => '*.{txt,rdoc,md,markdown,tt,textile}', 32 | :test => '{test,spec}/{**/}*.rb' 33 | } unless defined?(PATTERNS) 34 | 35 | # For which revision of indexer spec is this converter intended? 36 | REVISION = 2013 unless defined?(REVISION) 37 | 38 | # 39 | def self.gemspec 40 | new.to_gemspec 41 | end 42 | 43 | # 44 | attr :metadata 45 | 46 | # 47 | def initialize(metadata=nil) 48 | @root_check = false 49 | 50 | if metadata 51 | root_dir = metadata.delete(:root) 52 | if root_dir 53 | @root = root_dir 54 | @root_check = true 55 | end 56 | metadata = nil if metadata.empty? 57 | end 58 | 59 | @metadata = metadata || YAML.load_file(root + '.index') 60 | 61 | if @metadata['revision'].to_i != REVISION 62 | warn "This gemspec exporter was not designed for this revision of index metadata." 63 | end 64 | end 65 | 66 | # 67 | def has_root? 68 | root ? true : false 69 | end 70 | 71 | # 72 | def root 73 | return @root if @root || @root_check 74 | @root_check = true 75 | @root = find_root 76 | end 77 | 78 | # 79 | def manifest 80 | return nil unless root 81 | @manifest ||= Dir.glob(root + 'manifest{,.txt}', File::FNM_CASEFOLD).first 82 | end 83 | 84 | # 85 | def scm 86 | return nil unless root 87 | @scm ||= %w{git hg}.find{ |m| (root + ".#{m}").directory? }.to_sym 88 | end 89 | 90 | # 91 | def files 92 | return [] unless root 93 | @files ||= \ 94 | if manifest 95 | File.readlines(manifest). 96 | map{ |line| line.strip }. 97 | reject{ |line| line.empty? || line[0,1] == '#' } 98 | else 99 | list = [] 100 | Dir.chdir(root) do 101 | FILES.split(/\s+/).each do |pattern| 102 | list.concat(glob(pattern)) 103 | end 104 | OMIT.split(/\s+/).each do |pattern| 105 | list = list - glob(pattern) 106 | end 107 | end 108 | list 109 | end.select{ |path| File.file?(path) }.uniq 110 | end 111 | 112 | # 113 | def glob_files(pattern) 114 | return [] unless root 115 | Dir.chdir(root) do 116 | Dir.glob(pattern).select do |path| 117 | File.file?(path) && files.include?(path) 118 | end 119 | end 120 | end 121 | 122 | def patterns 123 | PATTERNS 124 | end 125 | 126 | def executables 127 | @executables ||= \ 128 | glob_files(patterns[:bin]).map do |path| 129 | File.basename(path) 130 | end 131 | end 132 | 133 | def extensions 134 | @extensions ||= \ 135 | glob_files(patterns[:ext]).map do |path| 136 | File.basename(path) 137 | end 138 | end 139 | 140 | def name 141 | metadata['name'] || metadata['title'].downcase.gsub(/\W+/,'_') 142 | end 143 | 144 | def homepage 145 | page = ( 146 | metadata['resources'].find{ |r| r['type'] =~ /^home/i } || 147 | metadata['resources'].find{ |r| r['name'] =~ /^home/i } || 148 | metadata['resources'].find{ |r| r['name'] =~ /^web/i } 149 | ) 150 | page ? page['uri'] : false 151 | end 152 | 153 | def licenses 154 | metadata['copyrights'].map{ |c| c['license'] }.compact 155 | end 156 | 157 | def require_paths 158 | paths = metadata['paths'] || {} 159 | paths['load'] || ['lib'] 160 | end 161 | 162 | # 163 | # Convert to gemnspec. 164 | # 165 | def to_gemspec 166 | if has_root? 167 | Gem::Specification.new do |gemspec| 168 | to_gemspec_data(gemspec) 169 | to_gemspec_paths(gemspec) 170 | end 171 | else 172 | Gem::Specification.new do |gemspec| 173 | to_gemspec_data(gemspec) 174 | to_gemspec_paths(gemspec) 175 | end 176 | end 177 | end 178 | 179 | # 180 | # Convert pure data settings. 181 | # 182 | def to_gemspec_data(gemspec) 183 | gemspec.name = name 184 | gemspec.version = metadata['version'] 185 | gemspec.summary = metadata['summary'] 186 | gemspec.description = metadata['description'] 187 | 188 | metadata['authors'].each do |author| 189 | gemspec.authors << author['name'] 190 | 191 | if author.has_key?('email') 192 | if gemspec.email 193 | gemspec.email << author['email'] 194 | else 195 | gemspec.email = [author['email']] 196 | end 197 | end 198 | end 199 | 200 | gemspec.licenses = licenses 201 | 202 | requirements = metadata['requirements'] || [] 203 | requirements.each do |req| 204 | next if req['optional'] 205 | next if req['external'] 206 | 207 | name = req['name'] 208 | groups = req['groups'] || [] 209 | 210 | version = gemify_version(req['version']) 211 | 212 | if groups.empty? or groups.include?('runtime') 213 | # populate runtime dependencies 214 | if gemspec.respond_to?(:add_runtime_dependency) 215 | gemspec.add_runtime_dependency(name,*version) 216 | else 217 | gemspec.add_dependency(name,*version) 218 | end 219 | else 220 | # populate development dependencies 221 | if gemspec.respond_to?(:add_development_dependency) 222 | gemspec.add_development_dependency(name,*version) 223 | else 224 | gemspec.add_dependency(name,*version) 225 | end 226 | end 227 | end 228 | 229 | # convert external dependencies into gemspec requirements 230 | requirements.each do |req| 231 | next unless req['external'] 232 | gemspec.requirements << ("%s-%s" % req.values_at('name', 'version')) 233 | end 234 | 235 | gemspec.homepage = homepage 236 | gemspec.require_paths = require_paths 237 | gemspec.post_install_message = metadata['install_message'] 238 | end 239 | 240 | # 241 | # Set gemspec settings that require a root directory path. 242 | # 243 | def to_gemspec_paths(gemspec) 244 | gemspec.files = files 245 | gemspec.extensions = extensions 246 | gemspec.executables = executables 247 | 248 | if Gem::VERSION < '1.7.' 249 | gemspec.default_executable = gemspec.executables.first 250 | end 251 | 252 | gemspec.test_files = glob_files(patterns[:test]) 253 | 254 | unless gemspec.files.include?('.document') 255 | gemspec.extra_rdoc_files = glob_files(patterns[:doc]) 256 | end 257 | end 258 | 259 | # 260 | # Return a copy of this file. This is used to generate a local 261 | # .gemspec file that can automatically read the index file. 262 | # 263 | def self.source_code 264 | File.read(__FILE__) 265 | end 266 | 267 | private 268 | 269 | def find_root 270 | root_files = patterns[:root] 271 | if Dir.glob(root_files).first 272 | Pathname.new(Dir.pwd) 273 | elsif Dir.glob("../#{root_files}").first 274 | Pathname.new(Dir.pwd).parent 275 | else 276 | #raise "Can't find root of project containing `#{root_files}'." 277 | warn "Can't find root of project containing `#{root_files}'." 278 | nil 279 | end 280 | end 281 | 282 | def glob(pattern) 283 | if File.directory?(pattern) 284 | Dir.glob(File.join(pattern, '**', '*')) 285 | else 286 | Dir.glob(pattern) 287 | end 288 | end 289 | 290 | def gemify_version(version) 291 | case version 292 | when /^(.*?)\+$/ 293 | ">= #{$1}" 294 | when /^(.*?)\-$/ 295 | "< #{$1}" 296 | when /^(.*?)\~$/ 297 | "~> #{$1}" 298 | else 299 | version 300 | end 301 | end 302 | 303 | end 304 | 305 | end 306 | 307 | Indexer::GemspecExporter.gemspec --------------------------------------------------------------------------------