Skip to content
Permalink
Browse files

require usage consistency

Adding Guard
Adding Config
Adding Mock
Adding Exceptions whenever a method can not be found
  • Loading branch information...
robertodecurnex committed Mar 17, 2015
1 parent 6ecf85e commit a6d16d7e96d6afa7fc65490a17358d7224808b00
@@ -1,4 +1,5 @@
*.swp
.yardoc
Gemfile.lock
coverage/*
sample/Gemfile.lock
.yardoc
@@ -0,0 +1,7 @@
directories %w(lib test)

clearing :on

guard :rake, task: 'default' do
watch /.*/
end
@@ -3,8 +3,11 @@
require 'singleton'
require 'yaml'

require_relative 'sc/database.rb'
require_relative 'sc/spec.rb'
require 'sc/config'
require 'sc/database'
require 'sc/exception'
require 'sc/mock'
require 'sc/spec'

# Specs driven social meta-programming
module SC
@@ -14,15 +17,31 @@ def self.included klass
klass.extend(ClassMethods)
end

# Gives access to the SC::Config instance insde the given block
#
# Usage:
# SC.configure do |config|
# config.enable_mocks!
# end
def self.configure
yield SC::Config.instance
end

module ClassMethods

# Register the given method name supporting the given parameters.
#
# Whenever SC::Config.mocks_enabled? is true it will try to cover unfulfilled
# specs using the knwon rules as mocks.
#
# @param [{String, Symbol=><String, Symbol>}] interfaces hash of method names and required param names that the method supports
def implements interfaces
file_path = caller.first.match(/#{Dir.pwd}\/(.+):\d+:in .+/)[1]
interfaces.each do |method_name, required_params|
λ = SC::Database.fetch(file_path, method_name, *required_params)
λ = SC::Database.fetch(file_path, method_name, *required_params) || SC::Mock.create(file_path, method_name)

raise SC::Exception::UndefinedMethodDefinition.new(file_path, method_name) if λ.nil?

self.send(:define_method, method_name, &λ)
end
end
@@ -0,0 +1,31 @@
module SC

class Config

attr_accessor :mocks_enabled

include Singleton

class << self
extend Forwardable
def_delegators :instance, :enable_mocks!, :mocks_enabled?
end

# Sets mocks_enabled to true
#
# @return [SC::Config] self
def enable_mocks!
self.mocks_enabled = true
return self
end

# Returns the current mocks policy (enabled or disabled)
#
# @return [TrueClass, FalseClass] whether mocks are enabled or not
def mocks_enabled?
return !!self.mocks_enabled
end

end

end
@@ -17,7 +17,10 @@ class << self
def initialize
self.cache = {}
end


# Lazy loads the index.yml and returns it
#
# @return [Hash] the parsed index.yml
def index
@index ||= YAML.load_file('./.sc/index.yml')
end
@@ -30,6 +33,9 @@ def index
# @param [<Symbol>] required_params parameters that would be required by the lambda
# @return [Proc] the labda that would be implemented
def fetch file_path, method_name, *required_params
if self.index["#{file_path}"].nil? || self.index["#{file_path}"]["#{method_name}"].nil?
return nil
end
λ_id = self.index["#{file_path}"]["#{method_name}"]['lambda_id']
return self.cache[λ_id] ||= eval(File.read(".sc/cache/#{λ_id}.rb"))
end
@@ -0,0 +1,8 @@
require 'sc/exception/undefined_method_definition'

module SC

module Exception
end

end
@@ -0,0 +1,22 @@
module SC

module Exception

class UndefinedMethodDefinition < ::Exception

attr_accessor :file_path, :method_name

def initialize file_path, method_name
self.file_path = file_path
self.method_name = method_name
end

def to_s
"[##{self.method_name}] has not been defiend for \"#{self.file_path}\". Verify the specs at \"#{self.file_path}\" and check the `sc compile` output for more detailed information."
end

end

end

end
@@ -0,0 +1,33 @@
module SC

class Mock

# Creates a mock of the given method for the given file based
# on the spec rules.
# If mocks are not enabled it defaults to nil
#
# @param [String] file_path relative path of the file that requests the lambda
# @param [Symbol] method_name the method name that would be implemented
# @return [NilClass, Proc] the mock as Proc or nil if mocks are disabled
def self.create file_path, method_name
return nil unless SC::Config.mocks_enabled?
spec = SC::Spec::Parser.parse(file_path).detect do |spec|
spec.signature.name == method_name
end
param_names = Array.new(spec.signature.params_types.count) do |index|
('a'.ord+index).chr
end
responses = spec.rules.inject({}) do |memo, rule|
memo[rule.params] = rule.output
memo
end
return eval "
lambda do |#{param_names.join(',')}|
return responses[[#{param_names.join(',')}]]
end
"
end

end

end
@@ -1,5 +1,5 @@
require_relative 'spec/rule.rb'
require_relative 'spec/signature.rb'
require 'sc/spec/rule'
require 'sc/spec/signature'

module SC

@@ -1,3 +1,5 @@
require 'rake'

Gem::Specification.new do |s|
s.authors = ['Roberto Decurnex']
s.date = '2015-01-13'
@@ -10,25 +12,20 @@ Gem::Specification.new do |s|

s.bindir = 'bin'
s.executables << 'sc'

s.files = [
'lib/sc.rb',
'lib/sc/client.rb',
'lib/sc/compiler.rb',
'lib/sc/database.rb',
'lib/sc/spec.rb',
'lib/sc/spec/parser.rb',
'lib/sc/spec/rule.rb',
'lib/sc/spec/signature.rb'
]

s.files = FileList['lib/**/*.rb'].to_a

s.extra_rdoc_files = [
'README.md',
]

s.required_ruby_version = '>= 2.0.0'

s.add_runtime_dependency 'thor'

s.add_development_dependency 'codeclimate-test-reporter'
s.add_development_dependency 'guard'
s.add_development_dependency 'guard-rake'
s.add_development_dependency 'minitest'
s.add_development_dependency 'rake'
s.add_development_dependency 'yard'
@@ -15,8 +15,6 @@ def double n1

end



__END__
spec_for hello String -> String
"Minion" -> "Say Hello to Minion"
@@ -0,0 +1,15 @@
require 'sc'

class UndefinedSample

include SC

implements \
i_am_undefined: [],
i_am_too: []

end

__END__
spec_for i_am_undefined -> TrueClass
-> TrueClass
@@ -0,0 +1,19 @@
class TestSC < Minitest::Test

class TestException < Minitest::Test

class TestUndefinedMethodDefinition < Minitest::Test

def test_exception
exception = assert_raises SC::Exception::UndefinedMethodDefinition do
raise SC::Exception::UndefinedMethodDefinition.new('path_here', 'method_name_here')
end

assert_equal '[#method_name_here] has not been defiend for "path_here". Verify the specs at "path_here" and check the `sc compile` output for more detailed information.', exception.message
end

end

end

end
@@ -17,7 +17,7 @@ def teardown

def test_targets
Dir.chdir('test/files') do
assert_equal ['sample.rb'], @compiler.send(:targets).sort
assert_equal ['sample.rb', 'undefined_sample.rb'], @compiler.send(:targets).sort
end
end

@@ -27,7 +27,18 @@ def test_compile
end
expected_yaml = <<YAML
---
"sample.rb":
undefined_sample.rb:
- !ruby/object:SC::Spec
md5: 23d8f3f75459cc94364520d99717a284
rules:
- !ruby/object:SC::Spec::Rule
output: !ruby/class 'TrueClass'
params: []
signature: !ruby/object:SC::Spec::Signature
name: i_am_undefined
output_type: TrueClass
params_types: []
sample.rb:
- !ruby/object:SC::Spec
md5: 94dd639208a00598a7248336398ad769
rules:
@@ -0,0 +1,19 @@
class TestSC < Minitest::Test

class TestConfig < Minitest::Test

def teardown
SC::Config.instance.mocks_enabled = nil
end

def test_mocks_enabled?
# Defaults to nil
assert_equal false, SC::Config.mocks_enabled?
# Force true with #enable_mocks
assert_equal SC::Config.instance, SC::Config.enable_mocks!
assert_equal true, SC::Config.mocks_enabled?
end

end

end
@@ -22,6 +22,22 @@ def test_fetch
assert_equal 'Say Hello to Test', λ.call('Test')
end

def test_fetch_undefined_method
λ = nil
Dir.chdir('test/files') do
λ = @database.fetch('sample.rb', 'unknown', [])
end
assert_equal nil, λ
end

def test_fetch_undefined_file
λ = nil
Dir.chdir('test/files') do
λ = @database.fetch('unknown.rb', 'sum', [:name])
end
assert_equal nil, λ
end

end

end
@@ -0,0 +1,8 @@
require_relative 'exception/test_undefined_method_definition'

class TestSC < Minitest::Test

class TestException < Minitest::Test
end

end
@@ -0,0 +1,29 @@
class TestSC < Minitest::Test

class TestMock < Minitest::Test

def teardown
SC::Config.instance.mocks_enabled = nil
end

def test_create
Dir.chdir('test/files') do
assert_equal nil, SC::Mock.create('sample.rb', 'unknown_lambda')
assert_equal nil, SC::Mock.create('sample.rb', 'rule_of_three')
SC::Config.instance.enable_mocks!
assert_instance_of Proc, SC::Mock.create('sample.rb', 'unknown_lambda')
assert_instance_of Proc, SC::Mock.create('sample.rb', 'rule_of_three')
end
end

def test_mock_scope
Dir.chdir('test/files') do
SC::Config.instance.enable_mocks!
assert_equal true, SC::Mock.create('sample.rb', 'unknown_lambda').call(false)
assert_equal 6.0, SC::Mock.create('sample.rb', 'rule_of_three').call(2.0, 4.0, 3.0)
end
end

end

end
@@ -1,6 +1,6 @@
require_relative './spec/test_parser.rb'
require_relative './spec/test_rule.rb'
require_relative './spec/test_signature.rb'
require_relative 'spec/test_parser'
require_relative 'spec/test_rule'
require_relative 'spec/test_signature'

class TestSC < Minitest::Test

0 comments on commit a6d16d7

Please sign in to comment.
You can’t perform that action at this time.