abstract-type-0.0.7/0000755000175100017510000000000013631365763013611 5ustar hackskhackskabstract-type-0.0.7/spec/0000755000175100017510000000000013631365763014543 5ustar hackskhackskabstract-type-0.0.7/spec/unit/0000755000175100017510000000000013631365763015522 5ustar hackskhackskabstract-type-0.0.7/spec/unit/abstract_type/0000755000175100017510000000000013631365763020366 5ustar hackskhackskabstract-type-0.0.7/spec/unit/abstract_type/module_methods/0000755000175100017510000000000013631365763023376 5ustar hackskhackskabstract-type-0.0.7/spec/unit/abstract_type/module_methods/create_new_method_spec.rb0000644000175100017510000000211013631365763030403 0ustar hackskhacksk# encoding: utf-8 require 'spec_helper' describe AbstractType, '.create_new_method' do context 'with arguments' do subject { object.new(:foo) } let(:abstract_type) do Class.new do include AbstractType def initialize(foo) @foo = foo end end end it_behaves_like 'AbstractType.create_new_method' end context 'with a block' do subject { object.new(:foo) { nil } } let(:abstract_type) do Class.new do include AbstractType def initialize(foo) @foo = foo yield end end end it_behaves_like 'AbstractType.create_new_method' end context 'without arguments' do subject { object.new } let(:abstract_type) { Class.new { include AbstractType } } it_behaves_like 'AbstractType.create_new_method' end context 'on an class that doesn\'t have Object as its superclass' do subject { object.new } let(:abstract_type) { Class.new(RuntimeError) { include AbstractType } } it_behaves_like 'AbstractType.create_new_method' end end abstract-type-0.0.7/spec/unit/abstract_type/abstract_method_declarations/0000755000175100017510000000000013631365763026261 5ustar hackskhackskabstract-type-0.0.7/spec/unit/abstract_type/abstract_method_declarations/included_spec.rb0000644000175100017510000000163513631365763031414 0ustar hackskhacksk# encoding: utf-8 require 'spec_helper' describe AbstractType, '.included' do subject { object } let(:object) { described_class } let(:klass) { Class.new } it 'extends the klass' do expect(klass.singleton_class) .to_not include(described_class::AbstractMethodDeclarations) klass.send(:include, subject) expect(klass.singleton_class) .to include(described_class::AbstractMethodDeclarations) end it 'overrides the new singleton method' do expect(klass.method(:new).owner).to eq(Class) klass.send(:include, subject) expect(klass.method(:new).owner).to eq(klass.singleton_class) end it 'delegates to the ancestor' do included_ancestor = false subject.extend Module.new { define_method(:included) { |_| included_ancestor = true } } expect { klass.send(:include, subject) } .to change { included_ancestor }.from(false).to(true) end end ././@LongLink0000644000000000000000000000015300000000000011602 Lustar rootrootabstract-type-0.0.7/spec/unit/abstract_type/abstract_method_declarations/abstract_singleton_method_spec.rbabstract-type-0.0.7/spec/unit/abstract_type/abstract_method_declarations/abstract_singleton_method_s0000644000175100017510000000166113631365763033757 0ustar hackskhacksk# encoding: utf-8 require 'spec_helper' describe AbstractType::AbstractMethodDeclarations, '#abstract_singleton_method' do subject { object.abstract_singleton_method(:some_method) } let(:object) { Class.new { include AbstractType } } let(:subclass) { Class.new(object) } before do Subclass = subclass end after do Object.class_eval { remove_const(:Subclass) } end it { should equal(object) } it 'creates an abstract method' do expect { subject }.to change { subclass.respond_to?(:some_method) } .from(false) .to(true) end it 'creates an abstract method with the expected arity' do subject expect(object.method(:some_method).arity).to be(-1) end it 'creates a method that raises an exception' do subject expect { subclass.some_method }.to raise_error( NotImplementedError, 'Subclass.some_method is not implemented' ) end end abstract-type-0.0.7/spec/unit/abstract_type/abstract_method_declarations/abstract_method_spec.rb0000644000175100017510000000164513631365763032771 0ustar hackskhacksk# encoding: utf-8 require 'spec_helper' describe AbstractType::AbstractMethodDeclarations, '#abstract_method' do subject { object.abstract_method(:some_method) } let(:object) { Class.new { include AbstractType } } let(:subclass) { Class.new(object) } before do Subclass = subclass end after do Object.class_eval { remove_const(:Subclass) } end it { should equal(object) } it 'creates an abstract method' do expect { subject }.to change { subclass.method_defined?(:some_method) } .from(false) .to(true) end it 'creates an abstract method with the expected arity' do subject expect(object.instance_method(:some_method).arity).to be(-1) end it 'creates a method that raises an exception' do subject expect { subclass.new.some_method }.to raise_error( NotImplementedError, 'Subclass#some_method is not implemented' ) end end abstract-type-0.0.7/spec/support/0000755000175100017510000000000013631365763016257 5ustar hackskhackskabstract-type-0.0.7/spec/support/config_alias.rb0000644000175100017510000000012513631365763021220 0ustar hackskhacksk# encoding: utf-8 require 'rbconfig' ::Config = RbConfig unless defined?(::Config) abstract-type-0.0.7/spec/spec_helper.rb0000644000175100017510000000106713631365763017365 0ustar hackskhacksk# encoding: utf-8 if ENV['COVERAGE'] == 'true' require 'simplecov' require 'coveralls' SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter ] SimpleCov.start do command_name 'spec:unit' add_filter 'config' add_filter 'spec' add_filter 'vendor' minimum_coverage 100 end end require 'devtools/spec_helper' require 'abstract_type' RSpec.configure do |config| config.expect_with :rspec do |expect_with| expect_with.syntax = :expect end end abstract-type-0.0.7/spec/shared/0000755000175100017510000000000013631365763016011 5ustar hackskhackskabstract-type-0.0.7/spec/shared/create_new_method_shared_spec.rb0000644000175100017510000000065013631365763024353 0ustar hackskhacksk# encoding: utf-8 shared_examples 'AbstractType.create_new_method' do context 'called on a subclass' do let(:object) { Class.new(abstract_type) } it { should be_instance_of(object) } end context 'called on the class' do let(:object) { abstract_type } specify do expect { subject }.to raise_error( NotImplementedError, "#{object} is an abstract type" ) end end end abstract-type-0.0.7/lib/0000755000175100017510000000000013631365763014357 5ustar hackskhackskabstract-type-0.0.7/lib/abstract_type/0000755000175100017510000000000013631365763017223 5ustar hackskhackskabstract-type-0.0.7/lib/abstract_type/version.rb0000644000175100017510000000015613631365763021237 0ustar hackskhacksk# encoding: utf-8 module AbstractType # Gem version VERSION = '0.0.7'.freeze end # module AbstractType abstract-type-0.0.7/lib/abstract_type.rb0000644000175100017510000000516713631365763017561 0ustar hackskhacksk# encoding: utf-8 # Module to allow class and methods to be abstract module AbstractType # Hook called when module is included # # @param [Module] descendant # the module or class including AbstractType # # @return [undefined] # # @api private def self.included(descendant) super create_new_method(descendant) descendant.extend(AbstractMethodDeclarations) end private_class_method :included # Define the new method on the abstract type # # Ensures that the instance cannot be of the abstract type # and must be a descendant. # # @param [Class] abstract_class # # @return [undefined] # # @api private def self.create_new_method(abstract_class) abstract_class.define_singleton_method(:new) do |*args, &block| if equal?(abstract_class) fail NotImplementedError, "#{inspect} is an abstract type" else super(*args, &block) end end end private_class_method :create_new_method module AbstractMethodDeclarations # Create abstract instance methods # # @example # class Foo # include AbstractType # # # Create an abstract instance method # abstract_method :some_method # end # # @param [Array<#to_s>] names # # @return [self] # # @api public def abstract_method(*names) names.each(&method(:create_abstract_instance_method)) self end # Create abstract singleton methods # # @example # class Foo # include AbstractType # # # Create an abstract instance method # abstract_singleton_method :some_method # end # # @param [Array<#to_s>] names # # @return [self] # # @api private def abstract_singleton_method(*names) names.each(&method(:create_abstract_singleton_method)) self end private # Create abstract singleton method # # @param [#to_s] name # the name of the method to create # # @return [undefined] # # @api private def create_abstract_singleton_method(name) define_singleton_method(name) do |*| fail NotImplementedError, "#{inspect}.#{name} is not implemented" end end # Create abstract instance method # # @param [#to_s] name # the name of the method to create # # @return [undefined] # # @api private def create_abstract_instance_method(name) define_method(name) do |*| fail NotImplementedError, "#{self.class}##{name} is not implemented" end end end # module AbstractMethodDeclarations end # module AbstractType require 'abstract_type/version' abstract-type-0.0.7/config/0000755000175100017510000000000013631365763015056 5ustar hackskhackskabstract-type-0.0.7/config/yardstick.yml0000644000175100017510000000002313631365763017571 0ustar hackskhacksk--- threshold: 100 abstract-type-0.0.7/config/rubocop.yml0000644000175100017510000000300213631365763017245 0ustar hackskhackskAllCops: Includes: - '../**/*.rake' - 'Gemfile' Excludes: - '**/vendor/**' - '**/benchmarks/**' # Avoid parameter lists longer than five parameters. ParameterLists: Max: 3 CountKeywordArgs: true # Avoid more than `Max` levels of nesting. BlockNesting: Max: 3 # Align with the style guide. CollectionMethods: PreferredMethods: collect: 'map' inject: 'reduce' find: 'detect' find_all: 'select' # Do not force public/protected/private keyword to be indented at the same # level as the def keyword. My personal preference is to outdent these keywords # because I think when scanning code it makes it easier to identify the # sections of code and visually separate them. When the keyword is at the same # level I think it sort of blends in with the def keywords and makes it harder # to scan the code and see where the sections are. AccessControl: Enabled: false # Limit line length LineLength: Max: 79 # Disable documentation checking until a class needs to be documented once Documentation: Enabled: false # Do not always use &&/|| instead of and/or. AndOr: Enabled: false # Do not favor modifier if/unless usage when you have a single-line body IfUnlessModifier: Enabled: false # Allow case equality operator (in limited use within the specs) CaseEquality: Enabled: false # Constants do not always have to use SCREAMING_SNAKE_CASE ConstantName: Enabled: false # Not all trivial readers/writers can be defined with attr_* methods TrivialAccessors: Enabled: false abstract-type-0.0.7/config/roodi.yml0000644000175100017510000000171213631365763016716 0ustar hackskhacksk--- AbcMetricMethodCheck: { score: 10.3 } AssignmentInConditionalCheck: { } CaseMissingElseCheck: { } ClassLineCountCheck: { line_count: 293 } ClassNameCheck: { pattern: !ruby/regexp '/\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/' } ClassVariableCheck: { } CyclomaticComplexityBlockCheck: { complexity: 2 } CyclomaticComplexityMethodCheck: { complexity: 4 } EmptyRescueBodyCheck: { } ForLoopCheck: { } # TODO: decrease line_count to 5 to 10 MethodLineCountCheck: { line_count: 14 } MethodNameCheck: { pattern: !ruby/regexp '/\A(?:[a-z\d](?:_?[a-z\d])+[?!=]?|\[\]=?|==|<=>|[+*&|-])\z/' } ModuleLineCountCheck: { line_count: 295 } ModuleNameCheck: { pattern: !ruby/regexp '/\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/' } # TODO: decrease parameter_count to 2 or less ParameterNumberCheck: { parameter_count: 3 } abstract-type-0.0.7/config/reek.yml0000644000175100017510000000331013631365763016524 0ustar hackskhacksk--- UncommunicativeParameterName: accept: [] exclude: [] enabled: true reject: - !ruby/regexp /^.$/ - !ruby/regexp /[0-9]$/ - !ruby/regexp /[A-Z]/ TooManyMethods: max_methods: 10 exclude: [] enabled: true max_instance_variables: 2 UncommunicativeMethodName: accept: [] exclude: [] enabled: true reject: - !ruby/regexp /^[a-z]$/ - !ruby/regexp /[0-9]$/ - !ruby/regexp /[A-Z]/ LongParameterList: max_params: 2 # TODO: decrease max_params to 2 exclude: [] enabled: true overrides: {} FeatureEnvy: exclude: [] enabled: true ClassVariable: exclude: [] enabled: true BooleanParameter: exclude: [] enabled: true IrresponsibleModule: exclude: [] enabled: true UncommunicativeModuleName: accept: [] exclude: [] enabled: true reject: - !ruby/regexp /^.$/ - !ruby/regexp /[0-9]$/ NestedIterators: ignore_iterators: [] exclude: [ 'AbstractType::AbstractMethodDeclarations#create_abstract_singleton_method' ] enabled: true max_allowed_nesting: 1 TooManyStatements: max_statements: 7 # TODO: decrease max_statements to 5 or less exclude: [] enabled: true DuplicateMethodCall: allow_calls: [] exclude: [] enabled: true max_calls: 1 UtilityFunction: max_helper_calls: 1 exclude: [] enabled: true Attribute: exclude: [] enabled: false UncommunicativeVariableName: accept: [] exclude: [] enabled: true reject: - !ruby/regexp /^.$/ - !ruby/regexp /[0-9]$/ - !ruby/regexp /[A-Z]/ RepeatedConditional: exclude: [] enabled: true max_ifs: 1 DataClump: exclude: [] enabled: true max_copies: 1 min_clump_size: 3 ControlParameter: exclude: [] enabled: true LongYieldList: max_params: 1 exclude: [] enabled: true abstract-type-0.0.7/config/mutant.yml0000644000175100017510000000006013631365763017105 0ustar hackskhacksk--- name: abstract_type namespace: AbstractType abstract-type-0.0.7/config/flog.yml0000644000175100017510000000002313631365763016523 0ustar hackskhacksk--- threshold: 8.2 abstract-type-0.0.7/config/flay.yml0000644000175100017510000000004113631365763016527 0ustar hackskhacksk--- threshold: 8 total_score: 20 abstract-type-0.0.7/abstract_type.gemspec0000644000175100017510000000132613631365763020024 0ustar hackskhacksk# encoding: utf-8 require File.expand_path('../lib/abstract_type/version', __FILE__) Gem::Specification.new do |gem| gem.name = 'abstract_type' gem.version = AbstractType::VERSION.dup gem.authors = [ 'Dan Kubb' ] gem.email = %w[ dan.kubb@gmail.com ] gem.description = 'Module to declare abstract classes and methods' gem.summary = gem.description gem.homepage = 'https://github.com/dkubb/abstract_type' gem.license = 'MIT' gem.files = `git ls-files`.split($/) gem.test_files = `git ls-files -- spec/unit`.split($/) gem.extra_rdoc_files = %w[LICENSE README.md CONTRIBUTING.md TODO] gem.add_development_dependency('bundler', '~> 1.3', '>= 1.3.5') end abstract-type-0.0.7/TODO0000644000175100017510000000000013631365763014267 0ustar hackskhackskabstract-type-0.0.7/Rakefile0000644000175100017510000000010013631365763015245 0ustar hackskhacksk# encoding: utf-8 require 'devtools' Devtools.init_rake_tasks abstract-type-0.0.7/README.md0000644000175100017510000000315213631365763015071 0ustar hackskhacksk# abstract_type This is a small standalone gem featuring a module ripped out from [axiom](https://github.com/dkubb/axiom). It allows to declare abstract_type classes and modules in an unobstrusive way. [![Gem Version](https://badge.fury.io/rb/abstract_type.png)][gem] [![Build Status](https://secure.travis-ci.org/dkubb/abstract_type.png?branch=master)][travis] [![Dependency Status](https://gemnasium.com/dkubb/abstract_type.png)][gemnasium] [![Code Climate](https://codeclimate.com/github/dkubb/abstract_type.png)][codeclimate] [![Coverage Status](https://coveralls.io/repos/dkubb/abstract_type/badge.png?branch=master)][coveralls] [gem]: https://rubygems.org/gems/abstract_type [travis]: https://travis-ci.org/dkubb/abstract_type [gemnasium]: https://gemnasium.com/dkubb/abstract_type [codeclimate]: https://codeclimate.com/github/dkubb/abstract_type [coveralls]: https://coveralls.io/r/dkubb/abstract_type ## Examples ``` ruby class Foo include AbstractType # Declare abstract instance method abstract_method :bar # Declare abstract singleton method abstract_singleton_method :baz end Foo.new # raises NotImplementedError: Foo is an abstract type Foo.baz # raises NotImplementedError: Foo.baz is not implemented # Subclassing to allow instantiation class Baz < Foo; end object = Baz.new object.bar # raises NotImplementedError: Baz#bar is not implemented ``` ## Credits * Dan Kubb ([dkubb](https://github.com/dkubb)) * Markus Schirp ([mbj](https://github.com/mbj)) ## Contributing See [CONTRIBUTING.md](CONTRIBUTING.md) for details. ## Copyright Copyright © 2009-2013 Dan Kubb. See LICENSE for details. abstract-type-0.0.7/LICENSE0000644000175100017510000000210213631365763014611 0ustar hackskhackskCopyright (c) 2009-2013 Dan Kubb Copyright (c) 2012 Markus Schirp Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. abstract-type-0.0.7/Guardfile0000644000175100017510000000117113631365763015436 0ustar hackskhacksk# encoding: utf-8 guard :bundler do watch('Gemfile') end guard :rspec do # run all specs if the spec_helper or supporting files files are modified watch('spec/spec_helper.rb') { 'spec' } watch(%r{\Aspec/(?:lib|support|shared)/.+\.rb\z}) { 'spec' } # run unit specs if associated lib code is modified watch(%r{\Alib/(.+)\.rb\z}) { |m| Dir["spec/unit/#{m[1]}"] } watch("lib/#{File.basename(File.expand_path('../', __FILE__))}.rb") { 'spec' } # run a spec if it is modified watch(%r{\Aspec/(?:unit|integration)/.+_spec\.rb\z}) end abstract-type-0.0.7/Gemfile.devtools0000644000175100017510000000265213631365763016747 0ustar hackskhacksk# encoding: utf-8 group :development do gem 'rake', '~> 10.1.0' gem 'rspec', '~> 2.14.1' gem 'yard', '~> 0.8.7' end group :yard do gem 'kramdown', '~> 1.2.0' end group :guard do gem 'guard', '~> 1.8.1' gem 'guard-bundler', '~> 1.0.0' gem 'guard-rspec', '~> 3.0.2' gem 'guard-rubocop', '~> 0.2.0' gem 'guard-mutant', '~> 0.0.1' # file system change event handling gem 'listen', '~> 1.3.0' gem 'rb-fchange', '~> 0.0.6', require: false gem 'rb-fsevent', '~> 0.9.3', require: false gem 'rb-inotify', '~> 0.9.0', require: false # notification handling gem 'libnotify', '~> 0.8.0', require: false gem 'rb-notifu', '~> 0.0.4', require: false gem 'terminal-notifier-guard', '~> 1.5.3', require: false end group :metrics do gem 'coveralls', '~> 0.7.0' gem 'flay', '~> 2.4.0' gem 'flog', '~> 4.2.0' gem 'reek', '~> 1.3.2' gem 'rubocop', '~> 0.14.1' gem 'simplecov', '~> 0.7.1' gem 'yardstick', '~> 0.9.7', git: 'https://github.com/dkubb/yardstick.git' platforms :ruby_19, :ruby_20 do gem 'mutant', '~> 0.3.0.rc3', git: 'https://github.com/mbj/mutant.git' gem 'unparser', '~> 0.1.3', git: 'https://github.com/mbj/unparser.git' gem 'yard-spellcheck', '~> 0.1.5' end end group :benchmarks do gem 'rbench', '~> 0.2.3' end platform :jruby do group :jruby do gem 'jruby-openssl', '~> 0.8.5' end end abstract-type-0.0.7/Gemfile0000644000175100017510000000027513631365763015110 0ustar hackskhacksk# encoding: utf-8 source 'https://rubygems.org' gemspec group :development, :test do gem 'devtools', git: 'https://github.com/rom-rb/devtools.git' end eval_gemfile 'Gemfile.devtools' abstract-type-0.0.7/CONTRIBUTING.md0000644000175100017510000000202413631365763016040 0ustar hackskhackskContributing ------------ * If you want your code merged into the mainline, please discuss the proposed changes with me before doing any work on it. This library is still in early development, and the direction it is going may not always be clear. Some features may not be appropriate yet, may need to be deferred until later when the foundation for them is laid, or may be more applicable in a plugin. * Fork the project. * Make your feature addition or bug fix. * Follow this [style guide](https://github.com/dkubb/styleguide). * Add specs for it. This is important so I don't break it in a future version unintentionally. Tests must cover all branches within the code, and code must be fully covered. * Commit, do not mess with Rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull) * Run "rake ci". This must pass and not show any regressions in the metrics for the code to be merged. * Send me a pull request. Bonus points for topic branches. abstract-type-0.0.7/.travis.yml0000644000175100017510000000067713631365763015734 0ustar hackskhacksklanguage: ruby before_install: gem install bundler bundler_args: --without yard guard benchmarks script: "bundle exec rake ci" rvm: - 1.9.3 - 2.0.0 - ruby-head - rbx-19mode matrix: include: - rvm: jruby-19mode env: JRUBY_OPTS="$JRUBY_OPTS --debug" - rvm: jruby-head env: JRUBY_OPTS="$JRUBY_OPTS --debug" notifications: irc: channels: - irc.freenode.org#rom-rb on_success: never on_failure: change abstract-type-0.0.7/.ruby-gemset0000644000175100017510000000001613631365763016052 0ustar hackskhackskabstract_type abstract-type-0.0.7/.rspec0000644000175100017510000000007613631365763014731 0ustar hackskhacksk--color --format progress --profile --warnings --order random abstract-type-0.0.7/.gitignore0000644000175100017510000000040713631365763015602 0ustar hackskhacksk## MAC OS .DS_Store ## TEXTMATE *.tmproj tmtags ## EMACS *~ \#* .\#* ## VIM *.swp ## Rubinius *.rbc .rbx ## PROJECT::GENERAL *.gem coverage profiling turbulence rdoc pkg tmp doc log .yardoc measurements ## BUNDLER .bundle Gemfile.lock ## PROJECT::SPECIFIC