typedeaf 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3a8ff4243653190eb9017aabc61f79b3654f4dd2
4
+ data.tar.gz: 7d7c83e7048c3667c48096ebf812a311c5c375fb
5
+ SHA512:
6
+ metadata.gz: a454e734801b2f24eef4d02d2e81d9f46c6b8aacb20ee6f2aad1a85056bcf98647e7375c8d64492c69d4a9dd64c49cfa98b29967b81dec0aa9f07160894fce54
7
+ data.tar.gz: 92f730e8823c3c7fe8900b051f6277785bac51b9fbf5aa816ce48bd5fe2fc08b03ae82360fb9ea86bcfaa99a10beb1207a6b1e32e4fd244de32147188c55627b
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .ruby-*
16
+ *.sw*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --order random --fail-fast --color --format doc
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in typedeaf.gemspec
4
+ gemspec
5
+
6
+ group :development do
7
+ gem 'rake'
8
+ gem 'rspec'
9
+ gem 'pry'
10
+ gem 'debugger-pry', :platform => :mri
11
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 R. Tyler Croy
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # Typedeaf
2
+
3
+ Typedeaf is a gem to help add some type-checking to method declarations in Ruby
4
+
5
+
6
+ ## Usage
7
+
8
+ ```
9
+ [1] pry(main)> require 'typedeaf'
10
+ => true
11
+ [2] pry(main)> class Logger
12
+ [2] pry(main)* include Typedeaf
13
+ [2] pry(main)*
14
+ [2] pry(main)* define :log, message: String, level: Symbol do
15
+ [2] pry(main)* puts "Logging #{message} at level #{level}"
16
+ [2] pry(main)* end
17
+ [2] pry(main)* end
18
+ => Logger
19
+ [3] pry(main)> l = Logger.new
20
+ => #<Logger:0x00000803c616b8>
21
+ [4] pry(main)> l.log("Hello World", :debug)
22
+ Logging Hello World at level debug
23
+ => nil
24
+ [5] pry(main)> l.log(4, :debug)
25
+ Typedeaf::InvalidTypeException: Expected `message` to be a kind of String but was Fixnum
26
+ from /usr/home/tyler/source/github/ruby/typedeaf/lib/typedeaf.rb:41:in `type_validation!'
27
+ [6] pry(main)> l.log('Whoopsies', 'debug')
28
+ Typedeaf::InvalidTypeException: Expected `level` to be a kind of Symbol but was String
29
+ from /usr/home/tyler/source/github/ruby/typedeaf/lib/typedeaf.rb:41:in `type_validation!'
30
+ [7] pry(main)>
31
+ ```
32
+
33
+
34
+ ## Installation
35
+
36
+ Add this line to your application's Gemfile:
37
+
38
+ ```ruby
39
+ gem 'typedeaf'
40
+ ```
41
+
42
+ And then execute:
43
+
44
+ $ bundle
45
+
46
+ Or install it yourself as:
47
+
48
+ $ gem install typedeaf
49
+
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => [:spec, :build]
7
+
@@ -0,0 +1,5 @@
1
+
2
+ module Typedeaf
3
+ class MissingMethodException < StandardError; end
4
+ class InvalidTypeException < StandardError; end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Typedeaf
2
+ VERSION = "0.0.1"
3
+ end
data/lib/typedeaf.rb ADDED
@@ -0,0 +1,86 @@
1
+ require 'typedeaf/errors'
2
+ require "typedeaf/version"
3
+
4
+ module Typedeaf
5
+ def self.included(base)
6
+ base.send(:include, InstanceMethods)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module InstanceMethods
11
+ def __typedeaf_varstack__
12
+ if @__typedeaf_varstack__.nil?
13
+ @__typedeaf_varstack__ = []
14
+ end
15
+ return @__typedeaf_varstack__
16
+ end
17
+
18
+ def method_missing(sym, *args)
19
+ # We only want to peek at the stack if we have no args (i.e. not trying
20
+ # to make a method call
21
+ if args.empty? && !(__typedeaf_varstack__.empty?)
22
+ params, values = __typedeaf_varstack__.last
23
+ # The top of our stack contains something that we want
24
+ return values[sym] if params[sym]
25
+ end
26
+
27
+ return super
28
+ end
29
+
30
+ def positional_validation!(params, args)
31
+ if params.size != args.size
32
+ raise ArgumentError, "wrong number of arguments (#{args.size} for #{params.size}"
33
+ end
34
+ end
35
+
36
+ def type_validation!(expected, param, value)
37
+ unless value.is_a?(expected)
38
+ raise InvalidTypeException,
39
+ "Expected `#{param}` to be a kind of #{expected} but was #{value.class}"
40
+ end
41
+ end
42
+ end
43
+
44
+ module ClassMethods
45
+ def define(method_sym, params={}, &block)
46
+ if block.nil?
47
+ raise MissingMethodException,
48
+ "You must provide a block for the #{method_sym} body"
49
+ end
50
+
51
+ define_method(method_sym) do |*args|
52
+ positional_validation!(params.keys, args)
53
+
54
+ param_indices = {}
55
+ params.each.with_index do |(param, type), index|
56
+ value = args[index]
57
+ type_validation!(type, param, value)
58
+ param_indices[param] = value
59
+ end
60
+ __typedeaf_varstack__ << [params, param_indices]
61
+
62
+ begin
63
+ instance_exec(*args, &block)
64
+ ensure
65
+ __typedeaf_varstack__.pop
66
+ end
67
+ end
68
+ return self
69
+ end
70
+ end
71
+
72
+ # Install the Typedeaf methods onto Class to be used everywhere
73
+ def self.global_install
74
+ Class.class_eval do
75
+ include Typedeaf
76
+
77
+ alias_method :old_inherited, :inherited
78
+ def inherited(subclass)
79
+ subclass.class_eval do
80
+ include Typedeaf
81
+ end
82
+ return old_inherited(subclass)
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'typedeaf'
3
+
4
+ unless RUBY_PLATFORM == 'java'
5
+ require 'debugger/pry'
6
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe Typedeaf do
4
+ subject(:klass) do
5
+ Class.new do
6
+ include Typedeaf
7
+ end
8
+ end
9
+
10
+ context 'with a new class' do
11
+ it { should be_kind_of Class }
12
+ it { should respond_to :define }
13
+ end
14
+
15
+ context 'defining typedeaf instance methods' do
16
+ subject(:instance) { klass.new }
17
+
18
+ context 'defining a method with an invalid block' do
19
+ it 'should raise a MissingMethodException' do
20
+ expect {
21
+ klass.class_eval do
22
+ define :log
23
+ end
24
+ }.to raise_error(Typedeaf::MissingMethodException)
25
+ end
26
+ end
27
+
28
+
29
+ context 'defining a method with no arguments' do
30
+ before :each do
31
+ klass.class_eval do
32
+ define :log do
33
+ 'hello rspec'
34
+ end
35
+ end
36
+ end
37
+
38
+ it { should respond_to :log }
39
+
40
+ it 'should return the right value when invoked' do
41
+ expect(instance.log).to eql('hello rspec')
42
+ end
43
+ end
44
+
45
+
46
+ context 'defining a method with arguments' do
47
+ before :each do
48
+ klass.class_eval do
49
+ define :log, message: String do
50
+ "hello #{message}"
51
+ end
52
+ end
53
+ end
54
+
55
+ it { should respond_to :log }
56
+ it 'should use the arguments to generate a result' do
57
+ expect(instance.log('world')).to eql('hello world')
58
+ end
59
+
60
+ it 'should raise when not enough args are passed' do
61
+ expect {
62
+ instance.log
63
+ }.to raise_error(ArgumentError)
64
+ end
65
+
66
+ it 'should raise when an incorrectly typed argument is passed' do
67
+ expect {
68
+ instance.log 4
69
+ }.to raise_error(Typedeaf::InvalidTypeException)
70
+ end
71
+ end
72
+ end
73
+ end
data/typedeaf.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'typedeaf/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "typedeaf"
8
+ spec.version = Typedeaf::VERSION
9
+ spec.authors = ["R. Tyler Croy"]
10
+ spec.email = ["tyler@monkeypox.org"]
11
+ spec.summary = %q{Typedeaf is a gem to help add some type-checking to method declarations in Ruby}
12
+ spec.homepage = "https://github.com/rtyler/typedeaf"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.7"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: typedeaf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - R. Tyler Croy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2014-10-24 00:00:00 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: "1.7"
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: *id001
24
+ - !ruby/object:Gem::Dependency
25
+ name: rake
26
+ requirement: &id002 !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: "10.0"
31
+ type: :development
32
+ prerelease: false
33
+ version_requirements: *id002
34
+ description:
35
+ email:
36
+ - tyler@monkeypox.org
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - .gitignore
45
+ - .rspec
46
+ - Gemfile
47
+ - LICENSE.txt
48
+ - README.md
49
+ - Rakefile
50
+ - lib/typedeaf.rb
51
+ - lib/typedeaf/errors.rb
52
+ - lib/typedeaf/version.rb
53
+ - spec/spec_helper.rb
54
+ - spec/typedeaf_spec.rb
55
+ - typedeaf.gemspec
56
+ homepage: https://github.com/rtyler/typedeaf
57
+ licenses:
58
+ - MIT
59
+ metadata: {}
60
+
61
+ post_install_message:
62
+ rdoc_options: []
63
+
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - &id003
69
+ - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - *id003
75
+ requirements: []
76
+
77
+ rubyforge_project:
78
+ rubygems_version: 2.4.1
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Typedeaf is a gem to help add some type-checking to method declarations in Ruby
82
+ test_files:
83
+ - spec/spec_helper.rb
84
+ - spec/typedeaf_spec.rb