├── .gemtest ├── .gitignore ├── Rakefile ├── questionable.gemspec ├── test ├── helper.rb └── questionable_test.rb ├── LICENSE ├── README.md └── lib └── questionable.rb /.gemtest: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | Gemfile.lock 4 | pkg/* 5 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | task :test do 2 | $:.unshift './test' 3 | Dir.glob("test/*_test.rb").each { |test| require "./#{test}" } 4 | end 5 | 6 | task :default => :test -------------------------------------------------------------------------------- /questionable.gemspec: -------------------------------------------------------------------------------- 1 | $:.push File.expand_path('../lib', __FILE__) 2 | require 'questionable' 3 | 4 | Gem::Specification.new do |s| 5 | s.name = 'questionable' 6 | s.version = Questionable::VERSION 7 | s.author = 'Lee Jarvis' 8 | s.email = 'lee@jarvis.co' 9 | s.homepage = 'http://github.com/injekt/questionable' 10 | s.summary = 'Question your objects!' 11 | s.description = 'Easily add method helpers for testing instance variables' 12 | s.files = `git ls-files`.split("\n") 13 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 14 | end 15 | -------------------------------------------------------------------------------- /test/helper.rb: -------------------------------------------------------------------------------- 1 | unless Object.const_defined? 'Questionable' 2 | $:.unshift File.expand_path('../../lib', __FILE__) 3 | require 'questionable' 4 | end 5 | 6 | require 'minitest/autorun' 7 | 8 | begin 9 | require 'turn' 10 | rescue LoadError 11 | end 12 | 13 | class TestCase < MiniTest::Unit::TestCase 14 | def self.test(name, &block) 15 | test_name = "test_#{name.gsub(/\s+/, '_')}".to_sym 16 | defined = instance_method(test_name) rescue false 17 | raise "#{test_name} is already defined in #{self}" if defined 18 | if block_given? 19 | define_method(test_name, &block) 20 | else 21 | define_method(test_name) do 22 | flunk "No implementation provided for #{name}" 23 | end 24 | end 25 | end 26 | end -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Lee Jarvis 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Questionable 2 | ============ 3 | 4 | Installation 5 | ------------ 6 | 7 | ### RubyGems 8 | 9 | gem install questionable 10 | 11 | ### GitHub 12 | 13 | git clone git://github.com/injekt/questionable.git 14 | gem build questionable.gemspec 15 | gem install questionable-.gem 16 | 17 | Usage 18 | ----- 19 | 20 | ```ruby 21 | class Person 22 | include Questionable 23 | 24 | questionable :name, :age 25 | questionable :has_password? => :password 26 | 27 | questionable :friends_with_robert? => :friends do |friends| 28 | friends.include? 'Robert' 29 | end 30 | 31 | questionable :has_friend? => :friends do |friends, friend| 32 | friends.include? friend 33 | end 34 | 35 | def initialize(name, age, password=nil) 36 | @name = name 37 | @age = age 38 | @password = password 39 | @friends = ['Phil', 'Robert'] 40 | end 41 | end 42 | 43 | roy = Person.new 'Roy', 36, 'Sekret!!' 44 | roy.name? #=> true 45 | roy.has_password? #=> true 46 | roy.friends_with_robert? #=> true 47 | 48 | dave = Person.new 'Dave', 42 49 | dave.age? #=> true 50 | dave.has_password? #=> false 51 | dave.has_friend? 'Steve' #=> false 52 | ``` 53 | -------------------------------------------------------------------------------- /test/questionable_test.rb: -------------------------------------------------------------------------------- 1 | require 'helper' 2 | 3 | class Klass 4 | extend Questionable 5 | 6 | questionable :foo, :bar, :missing 7 | questionable :has_password => :password 8 | questionable :has_missing? => :missing 9 | 10 | questionable :has_ralf? do |i| 11 | i.include? 'Ralf' 12 | end 13 | 14 | questionable :has_person? => :people do |v, person| 15 | v.include? person 16 | end 17 | 18 | def initialize 19 | @foo, @bar = true, false 20 | @password = "sekret" 21 | @has_ralf = ['Ralf'] 22 | @people = ['Lee', 'Rob'] 23 | end 24 | end 25 | 26 | class QuestionableTest < TestCase 27 | def setup 28 | @klass = Klass.new 29 | end 30 | 31 | test 'questioning multiple vars' do 32 | assert @klass.foo? 33 | refute @klass.bar? 34 | assert_raises(RuntimeError, /@missing/) { @klass.missing? } 35 | end 36 | 37 | test 'alias/hash syntax' do 38 | assert @klass.has_password? 39 | assert_raises(RuntimeError, /@missing/) { @klass.has_missing? } 40 | assert_raises(NoMethodError) { @klass.password? } 41 | end 42 | 43 | test 'blocks' do 44 | assert @klass.has_ralf? 45 | assert @klass.has_person? 'Lee' 46 | refute @klass.has_person? 'Ralf' 47 | end 48 | 49 | end -------------------------------------------------------------------------------- /lib/questionable.rb: -------------------------------------------------------------------------------- 1 | module Questionable 2 | VERSION = '0.1.0' 3 | 4 | # Extend `klass` with Questionable. This means nothing more than 5 | # a user can use both `include` and `extend` 6 | # 7 | # @param [Class] klass 8 | def self.included(klass) 9 | klass.extend self 10 | end 11 | 12 | # Add questionable items 13 | # 14 | # @example 15 | # class Person 16 | # include Questionable 17 | # 18 | # questionable :name, :age 19 | # questionable :has_password? => :password 20 | # 21 | # questionable :friends_with_robert? => :friends do |friends| 22 | # friends.include? 'Robert' 23 | # end 24 | # 25 | # questionable :has_friend? => :friends do |friends, friend| 26 | # friends.include? friend 27 | # end 28 | # 29 | # def initialize(name, age, password=nil) 30 | # @name = name 31 | # @age = age 32 | # @password = password 33 | # @friends = ['Phil', 'Robert'] 34 | # end 35 | # end 36 | # 37 | # roy = Person.new 'Roy', 36, 'Sekret!!' 38 | # roy.name? #=> true 39 | # roy.has_password? #=> true 40 | # roy.friends_with_robert? #=> true 41 | # 42 | # dave = Person.new 'Dave', 42 43 | # dave.age? #=> true 44 | # dave.has_password? #=> false 45 | # dave.has_friend? 'Steve' #=> false 46 | def questionable(*items, &block) 47 | if items.first.respond_to? :keys 48 | __create_questionable_method *items[0].shift, &block 49 | else 50 | if items.size == 1 51 | __create_questionable_method items.shift, &block 52 | else 53 | items.each { |i| __create_questionable_method i, &block } 54 | end 55 | end 56 | end 57 | 58 | private 59 | 60 | def __create_questionable_method(to, from=nil, &block) 61 | from ||= to 62 | meth_name = to.to_s.chomp('?').insert(-1, '?').to_sym 63 | ivar = from.to_s.sub(/\A@/, '').insert(0, '@').chomp('?') 64 | 65 | if block_given? 66 | define_method(meth_name) do |*a| 67 | if instance_variable_defined? ivar 68 | yield instance_variable_get(ivar), *a 69 | else 70 | raise RuntimeError, "Instance variable #{ivar} is undefined" 71 | end 72 | end 73 | else 74 | define_method(meth_name) do 75 | if instance_variable_defined? ivar 76 | !!instance_variable_get(ivar) 77 | else 78 | raise RuntimeError, "Instance variable #{ivar} is undefined" 79 | end 80 | end 81 | end 82 | end 83 | 84 | end 85 | --------------------------------------------------------------------------------