axiom-types-0.1.1/0000755000004100000410000000000012322241316014014 5ustar www-datawww-dataaxiom-types-0.1.1/Rakefile0000600000004100000410000000010012322241316015440 0ustar www-datawww-data# encoding: utf-8 require 'devtools' Devtools.init_rake_tasks axiom-types-0.1.1/Gemfile0000644000004100000410000000037212322241316015311 0ustar www-datawww-data# encoding: utf-8 source 'https://rubygems.org' gemspec platforms :rbx do gem 'rubysl-bigdecimal', '~> 2.0.2' end group :development, :test do gem 'devtools', git: 'https://github.com/rom-rb/devtools.git' end eval_gemfile 'Gemfile.devtools' axiom-types-0.1.1/Gemfile.devtools0000644000004100000410000000315212322241316017146 0ustar www-datawww-data# encoding: utf-8 group :development do gem 'rake', '~> 10.2.1' gem 'rspec', '~> 2.14.1' gem 'rspec-core', '~> 2.14.8' gem 'yard', '~> 0.8.7.4' platform :rbx do gem 'rubysl-singleton', '~> 2.0.0' end end group :yard do gem 'kramdown', '~> 1.3.3' end group :guard do gem 'guard', '~> 2.6.0' gem 'guard-bundler', '~> 2.0.0' gem 'guard-rspec', '~> 4.2.8' gem 'guard-rubocop', '~> 1.0.2' # file system change event handling gem 'listen', '~> 2.7.1' gem 'rb-fchange', '~> 0.0.6', require: false gem 'rb-fsevent', '~> 0.9.4', require: false gem 'rb-inotify', '~> 0.9.3', require: false # notification handling gem 'libnotify', '~> 0.8.2', 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.7' gem 'rubocop', '~> 0.19.1' gem 'simplecov', '~> 0.8.2' gem 'yardstick', '~> 0.9.9' platforms :mri do gem 'mutant', '~> 0.5.8' gem 'mutant-rspec', '~> 0.5.3' end platforms :ruby_19, :ruby_20 do gem 'yard-spellcheck', '~> 0.1.5' end platform :rbx do gem 'json', '~> 1.8.1' gem 'racc', '~> 1.4.11' gem 'rubysl-logger', '~> 2.0.0' gem 'rubysl-open-uri', '~> 2.0.0' gem 'rubysl-prettyprint', '~> 2.0.3' 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 axiom-types-0.1.1/.rspec0000644000004100000410000000007612322241316015134 0ustar www-datawww-data--color --format progress --profile --warnings --order random axiom-types-0.1.1/spec/0000755000004100000410000000000012322241316014746 5ustar www-datawww-dataaxiom-types-0.1.1/spec/spec_helper.rb0000644000004100000410000000160712322241316017570 0ustar www-datawww-data# 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 'axiom-types' include Axiom::Types RSpec.configure do |config| config.expect_with :rspec do |expect_with| expect_with.syntax = :expect end # Record the original Type descendants config.before do @original_descendants = Axiom::Types::Type.descendants.dup end # Reset the Type descendants config.after do Axiom::Types::Type.descendants.replace(@original_descendants) Axiom::Types.instance_variable_get(:@inference_cache).clear end end axiom-types-0.1.1/spec/unit/0000755000004100000410000000000012322241316015725 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/0000755000004100000410000000000012322241316017042 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/0000755000004100000410000000000012322241316020206 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/set/0000755000004100000410000000000012322241316021001 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/set/class_methods/0000755000004100000410000000000012322241316023631 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/set/class_methods/infer_spec.rb0000644000004100000410000000425212322241316026276 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Set, '.infer' do subject { object.infer(arg) } before do object.finalize end before do # Initialize a custom type that will be used if the class lookup does not # restrict matching to only types with an Object member_type Axiom::Types.infer(Set[Float]) end context 'with Axiom::Types::Set' do let(:object) { described_class } context 'when the argument is the type object' do let(:arg) { object } it { should be(object) } end context 'when the argument is ::Set' do let(:arg) { ::Set } it { should be(object) } end context 'when the argument is an empty Set' do let(:arg) { ::Set[] } it { should be(object) } end context 'when the argument is an Set with a type' do let(:arg) { ::Set[object] } its(:ancestors) { should include(object) } its(:primitive) { should be(object.primitive) } its(:member_type) { should be(object) } end context 'when the argument is an Set with a primitive' do let(:arg) { ::Set[::Set] } its(:ancestors) { should include(object) } its(:primitive) { should be(object.primitive) } its(:member_type) { should be(object) } end context 'when the argument is nil' do let(:arg) { nil } it { should be_nil } end end context 'with Axiom::Types::Set subclass' do let(:object) { Class.new(described_class) } context 'when the argument is the type object' do let(:arg) { object } it { should be(object) } end context 'when the argument is ::Set' do let(:arg) { ::Set } it { should be(object) } end context 'when the argument is an empty Set' do let(:arg) { ::Set[] } it { should be(object) } end context 'when the argument is an Set with a type' do let(:arg) { ::Set[object] } it { should be_nil } end context 'when the argument is an Set with a primitive' do let(:arg) { ::Set[::Set] } it { should be_nil } end context 'when the argument is nil' do let(:arg) { nil } it { should be_nil } end end end axiom-types-0.1.1/spec/unit/axiom/types/options/0000755000004100000410000000000012322241316021701 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/options/inherited_spec.rb0000644000004100000410000000135312322241316025215 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Options, '#inherited' do subject { descendant } let(:object) do Class.new(ancestor) do extend Options, DescendantsTracker accept_options :primitive, :coerce_method primitive ::String end end let(:ancestor) do Class.new end let(:descendant) do Class.new(object) end it 'delegates to the ancestor' do expect(ancestor).to receive(:inherited).twice subject end it 'adds the accepted option to the descendant' do subject expect(descendant).to respond_to(:primitive, :coerce_method) end it 'sets the default value for the descendant' do subject expect(descendant.primitive).to be(::String) end end axiom-types-0.1.1/spec/unit/axiom/types/options/accept_options_spec.rb0000644000004100000410000000574012322241316026260 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Options, '#accept_options' do subject { object.accept_options(*new_options) } let(:object) { Class.new { extend Options, DescendantsTracker } } let(:descendant) { Class.new(object) } context 'with valid options' do let(:new_options) { [:primitive, :coerce_method] } it_should_behave_like 'a command method' it_should_behave_like 'an idempotent method' it 'adds methods to the object' do expect(object).to_not respond_to(*new_options) subject expect(object).to respond_to(*new_options) end it 'defines the instance variables for the options' do subject expect(object.instance_variable_defined?(:@primitive)).to be(true) expect(object.instance_variable_defined?(:@coerce_method)).to be(true) end it 'adds methods to the object that can set a value' do subject expect { object.primitive(Class) } .to change(object, :primitive).from(nil).to(Class) expect { object.coerce_method(:to_class) } .to change(object, :coerce_method).from(nil).to(:to_class) end context 'with the descendant class' do let(:default) { ::String } def force_inherit descendant end context 'option added before inherited' do before do subject expect(object.primitive(default)).to be(object) force_inherit end it 'is idempotent' do expect(descendant.accept_options(:primitive)).to be(descendant) end it 'adds the method to the descendants' do expect(descendant).to respond_to(*new_options) end it 'sets the descendant defaults' do expect(descendant.primitive).to be(default) end it 'adds methods to the descendant that can set a value' do descendant.primitive(::Symbol) expect(descendant.primitive).to be(::Symbol) end end context 'option added after inherited' do before do force_inherit subject expect(object.primitive(default)).to be(object) end it 'is idempotent' do expect(descendant.accept_options(:primitive)).to be(descendant) end it 'adds the method to the descendants' do expect(descendant).to respond_to(*new_options) end it 'does not set the descendant defaults' do expect(descendant.primitive).to be_nil end it 'adds methods to the descendant that can set a value' do descendant.primitive(::Symbol) expect(descendant.primitive).to be(::Symbol) end end end end context 'with an option that conflicts with an existing method' do let(:new_options) { [:name] } specify do expect { subject }.to raise_error( Axiom::Types::Options::ReservedMethodError, 'method named `:name` is already defined' ) end end end axiom-types-0.1.1/spec/unit/axiom/types/type/0000755000004100000410000000000012322241316021167 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/type/class_methods/0000755000004100000410000000000012322241316024017 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/type/class_methods/finalize_spec.rb0000644000004100000410000000056512322241316027165 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Type, '.finalize' do subject { object.finalize } let(:object) do Class.new(described_class) do constraint Tautology end end it_should_behave_like 'a command method' it_should_behave_like 'an idempotent method' it { should be_frozen } its(:constraint) { should be_frozen } end axiom-types-0.1.1/spec/unit/axiom/types/type/class_methods/infer_spec.rb0000644000004100000410000000076212322241316026466 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Type, '.infer' do subject { object.infer(arg) } let(:object) { described_class } context 'when the argument is the type object' do let(:arg) { object } it { should be(object) } end Axiom::Types::Type.descendants.each do |descendant| context "when the argument is #{descendant}" do let(:arg) { descendant } it 'does not match any other type' do should be_nil end end end end axiom-types-0.1.1/spec/unit/axiom/types/type/class_methods/includes_spec.rb0000644000004100000410000000213012322241316027160 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Type, '.includes' do subject { object.includes(*members) } let(:object) { Class.new(described_class) } context 'with a non-empty list' do let(:member) { Object.new } let(:members) { [member, member] } it_should_behave_like 'a command method' it 'adds a constraint that returns true for a valid member' do should include(member) end it 'adds a constraint that returns false for an invalid member' do should_not include(nil) end it 'freezes the members' do expect { subject }.to change(member, :frozen?).from(false).to(true) end it 'removes duplicate members' do expect(member).to receive(:freeze).and_return(member) expect(member).to receive(:hash).exactly(3).times.and_return(1) subject expect(object).to include(member) end end context 'with an empty set' do let(:members) { [] } it_should_behave_like 'a command method' it 'adds a constraint that returns false' do should_not include(Object.new) end end end axiom-types-0.1.1/spec/unit/axiom/types/type/class_methods/anonymous_predicate_spec.rb0000644000004100000410000000055012322241316031426 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Type, '.anonymous?' do subject { object.anonymous? } context 'when the type is named' do let(:object) { described_class } it { should be(false) } end context 'when the type is anonymous' do let(:object) { Class.new(described_class) } it { should be(true) } end end axiom-types-0.1.1/spec/unit/axiom/types/type/class_methods/include_predicate_spec.rb0000644000004100000410000000075112322241316031024 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Type, '.include?' do subject { object.include?(value) } let(:object) do Class.new(described_class) do constraint(->(object) { !object.nil? }) end end context 'when the value matches the type constraint' do let(:value) { Object.new } it { should be(true) } end context 'when the value does not match the type constraint' do let(:value) { nil } it { should be(false) } end end axiom-types-0.1.1/spec/unit/axiom/types/type/class_methods/base_predicate_spec.rb0000644000004100000410000000053612322241316030314 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Type, '.base?' do subject { object.base? } context 'when the type is named' do let(:object) { described_class } it { should be(true) } end context 'when the type is anonymous' do let(:object) { Class.new(described_class) } it { should be(false) } end end axiom-types-0.1.1/spec/unit/axiom/types/type/class_methods/base_spec.rb0000644000004100000410000000056312322241316026274 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Type, '.base' do subject { object.base } context 'when the type is named' do let(:object) { described_class } it { should be(object) } end context 'when the type is anonymous' do let(:object) { Class.new(Class.new(described_class)) } it { should be(described_class) } end end axiom-types-0.1.1/spec/unit/axiom/types/type/class_methods/constraint_spec.rb0000644000004100000410000000455312322241316027551 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Type, '.constraint' do let(:object) { Class.new(described_class) } let(:callable) { ->(number) { number > 1 } } let(:other) { ->(number) { number < 3 } } context 'with no arguments or block' do subject { object.constraint } it { should respond_to(:call) } it { should be(Tautology) } end context 'with a callable object' do subject { object.constraint(callable) } it_should_behave_like 'a command method' its(:constraint) { should respond_to(:call) } it 'creates a constraint that matches a number > 1' do expect(object).to include(1) expect(object).to include(2) expect(object).to include(3) subject expect(object).to_not include(1) expect(object).to include(2) expect(object).to include(3) end context 'with another constraint' do subject { super().constraint(other) } it_should_behave_like 'a command method' its(:constraint) { should respond_to(:call) } it 'creates a constraint that matches a number > 1 and < 3' do expect(object).to include(1) expect(object).to include(2) expect(object).to include(3) subject expect(object).to_not include(1) expect(object).to include(2) expect(object).to_not include(3) end end end context 'with a block' do subject { object.constraint(&callable) } it_should_behave_like 'a command method' its(:constraint) { should respond_to(:call) } it 'creates a constraint that matches a number > 1' do expect(object).to include(1) expect(object).to include(2) expect(object).to include(3) subject expect(object).to_not include(1) expect(object).to include(2) expect(object).to include(3) end context 'with another constraint' do subject { super().constraint(&other) } it_should_behave_like 'a command method' its(:constraint) { should respond_to(:call) } it 'creates a constraint that matches a number > 1 and < 3' do expect(object).to include(1) expect(object).to include(2) expect(object).to include(3) subject expect(object).to_not include(1) expect(object).to include(2) expect(object).to_not include(3) end end end end axiom-types-0.1.1/spec/unit/axiom/types/type/class_methods/new_spec.rb0000644000004100000410000000273412322241316026155 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Type, '.new' do let(:undefined) { Axiom::Types::Undefined } before do object.finalize end context 'with no arguments' do subject { object.new } let(:object) { described_class } it { should be_instance_of(Class) } it { should be_frozen } its(:ancestors) { should include(object) } it 'has no constraints' do should include(undefined) end end context 'with a constraint' do subject { object.new(proc { false }) } let(:object) { described_class } it { should be_instance_of(Class) } it { should be_frozen } its(:ancestors) { should include(object) } it 'has constraints' do should_not include(undefined) end end context 'with a block' do subject do object.new do constraint { false } end end let(:object) { described_class } it { should be_instance_of(Class) } it { should be_frozen } its(:ancestors) { should include(object) } it 'has constraints' do should_not include(undefined) end end context 'with a constraint and block' do subject do object.new(proc { false }) do constraint { false } end end let(:object) { described_class } it { should be_instance_of(Class) } it { should be_frozen } its(:ancestors) { should include(object) } it 'has constraints' do should_not include(undefined) end end end axiom-types-0.1.1/spec/unit/axiom/types/collection/0000755000004100000410000000000012322241316022341 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/collection/class_methods/0000755000004100000410000000000012322241316025171 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/collection/class_methods/finalize_spec.rb0000644000004100000410000000222612322241316030333 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Collection, '.finalize' do subject { object.finalize } let(:object) { Class.new(Axiom::Types::Collection) } context 'with the default member constraints' do it_should_behave_like 'a command method' it_should_behave_like 'an idempotent method' it { should be_frozen } its(:constraint) { should be_frozen } it 'adds a constraint that returns true for a collection' do should include([Object.new]) end it 'adds a constraint that returns false for a non-collection' do should_not include(Object.new) end end context 'with custom member constraints' do let(:member) { :name } before do object.member_type Axiom::Types::Symbol end it_should_behave_like 'a command method' it_should_behave_like 'an idempotent method' it { should be_frozen } its(:constraint) { should be_frozen } it 'adds a constraint that returns true for a valid member' do should include([member]) end it 'adds a constraint that returns false for an invalid member' do should_not include([member.to_s]) end end end axiom-types-0.1.1/spec/unit/axiom/types/collection/class_methods/infer_spec.rb0000644000004100000410000000541612322241316027641 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Collection, '.infer' do subject { object.infer(arg) } before do object.finalize end context 'with the type' do let(:object) { described_class } context 'when the argument is the type object' do let(:arg) { object } it { should be(object) } end context 'when the argument is ::Enumerable' do let(:arg) { ::Enumerable } it { should be(object) } end end context 'with a base class' do let(:object) do Class.new(described_class) do primitive ::SortedSet def self.base? true end end end before do # Initialize a custom type that will be used if the class lookup does not # restrict matching to only types with an Object member_type Axiom::Types.infer(SortedSet[Float]) end context 'when the argument is the type object' do let(:arg) { object } it { should be(object) } end context 'when the argument is ::SortedSet' do let(:arg) { ::SortedSet } it { should be(object) } end context 'when the argument is an empty SortedSet' do let(:arg) { ::SortedSet[] } it { should be(object) } end context 'when the argument is an SortedSet with a type' do let(:arg) { ::SortedSet[object] } its(:ancestors) { should include(object) } its(:primitive) { should be(object.primitive) } its(:member_type) { should be(object) } end context 'when the argument is an SortedSet with a primitive' do let(:arg) { ::SortedSet[::SortedSet] } its(:ancestors) { should include(object) } its(:primitive) { should be(object.primitive) } its(:member_type) { should be(object) } end context 'when the argument is nil' do let(:arg) { nil } it { should be_nil } end end context 'with a a non-base class' do let(:object) do Class.new(described_class) do primitive ::SortedSet end end context 'when the argument is the type object' do let(:arg) { object } it { should be(object) } end context 'when the argument is ::SortedSet' do let(:arg) { ::SortedSet } it { should be(object) } end context 'when the argument is an empty SortedSet' do let(:arg) { ::SortedSet[] } it { should be(object) } end context 'when the argument is an SortedSet with a type' do let(:arg) { ::SortedSet[object] } it { should be_nil } end context 'when the argument is an SortedSet with a primitive' do let(:arg) { ::SortedSet[::SortedSet] } it { should be_nil } end context 'when the argument is nil' do let(:arg) { nil } it { should be_nil } end end end axiom-types-0.1.1/spec/unit/axiom/types/negative_infinity/0000755000004100000410000000000012322241316023721 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/negative_infinity/spaceship_operator_spec.rb0000644000004100000410000000246412322241316031160 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::NegativeInfinity, '#<=>' do subject { object <=> other } let(:object) { described_class.instance } [ 1, # Fixnum 2**63, # Bignum 1.0, # Float Rational(1, 1), # Rational BigDecimal('1'), # BigDecimal ].each do |number| context "when other object is a #{number.class}" do let(:other) { number } it { should be(-1) } it 'is symmetric' do should be(-(other <=> object)) end end end context 'when the other object is infinity' do let(:other) { Axiom::Types::Infinity.instance } it { should be(-1) } it 'is symmetric' do should be(-(other <=> object)) end end context 'when the other object is negative infinity' do let(:other) { object } it { should be(0) } it 'is symmetric' do should be(other <=> object) end end context 'when the other object is -Float::INFINITY' do let(:other) { -Float::INFINITY } it { should be(0) } it 'is symmetric' do should be(other <=> object) end end context 'when the other object is not comparable' do let(:other) { 'string' } it { should be_nil } it 'is symmetric' do should be(other <=> object) end end end axiom-types-0.1.1/spec/unit/axiom/types/boolean/0000755000004100000410000000000012322241316021625 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/boolean/class_methods/0000755000004100000410000000000012322241316024455 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/boolean/class_methods/infer_spec.rb0000644000004100000410000000127012322241316027117 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Boolean, '.infer' do subject { object.infer(arg) } let(:object) { described_class } context 'when the argument is the type object' do let(:arg) { object } it { should be(object) } end context 'when the argument is ::TrueClass' do let(:arg) { ::TrueClass } it { should be(object) } end context 'when the argument is ::FalseClass' do let(:arg) { ::FalseClass } it { should be(object) } end context 'when the argument is nil' do let(:arg) { nil } it { should be_nil } end context 'when the argument is not nil' do let(:arg) { 1 } it { should be_nil } end end axiom-types-0.1.1/spec/unit/axiom/types/array/0000755000004100000410000000000012322241316021324 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/array/class_methods/0000755000004100000410000000000012322241316024154 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/array/class_methods/infer_spec.rb0000644000004100000410000000432612322241316026623 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Array, '.infer' do subject { object.infer(arg) } before do object.finalize end before do # Initialize a custom type that will be used if the class lookup does not # restrict matching to only types with an Object member_type Axiom::Types.infer(Array[Float]) end context 'with Axiom::Types::Array' do let(:object) { described_class } context 'when the argument is the type object' do let(:arg) { object } it { should be(object) } end context 'when the argument is ::Array' do let(:arg) { ::Array } it { should be(object) } end context 'when the argument is an empty Array' do let(:arg) { ::Array[] } it { should be(object) } end context 'when the argument is an Array with a type' do let(:arg) { ::Array[object] } its(:ancestors) { should include(object) } its(:primitive) { should be(object.primitive) } its(:member_type) { should be(object) } end context 'when the argument is an Array with a primitive' do let(:arg) { ::Array[::Array] } its(:ancestors) { should include(object) } its(:primitive) { should be(object.primitive) } its(:member_type) { should be(object) } end context 'when the argument is nil' do let(:arg) { nil } it { should be_nil } end end context 'with Axiom::Types::Array subclass' do let(:object) { Class.new(described_class) } context 'when the argument is the type object' do let(:arg) { object } it { should be(object) } end context 'when the argument is ::Array' do let(:arg) { ::Array } it { should be(object) } end context 'when the argument is an empty Array' do let(:arg) { ::Array[] } it { should be(object) } end context 'when the argument is an Array with a type' do let(:arg) { ::Array[object] } it { should be_nil } end context 'when the argument is an Array with a primitive' do let(:arg) { ::Array[::Array] } it { should be_nil } end context 'when the argument is nil' do let(:arg) { nil } it { should be_nil } end end end axiom-types-0.1.1/spec/unit/axiom/types/hash/0000755000004100000410000000000012322241316021131 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/hash/class_methods/0000755000004100000410000000000012322241316023761 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/hash/class_methods/finalize_spec.rb0000644000004100000410000000256012322241316027124 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Hash, '.finalize' do subject { object.finalize } let(:object) { Class.new(Axiom::Types::Hash) } context 'with the default key and value constraints' do it_should_behave_like 'a command method' it_should_behave_like 'an idempotent method' it { should be_frozen } its(:constraint) { should be_frozen } it 'adds a constraint that returns true for a Hash' do should include(Object.new => Object.new) end it 'adds a constraint that returns false for a non-Hash' do should_not include(Object.new) end end context 'with custom key and value constraints' do let(:key) { :name } let(:value) { 'Dan Kubb' } before do object.key_type Axiom::Types::Symbol object.value_type Axiom::Types::String end it_should_behave_like 'a command method' it_should_behave_like 'an idempotent method' it { should be_frozen } its(:constraint) { should be_frozen } it 'adds a constraint that returns true for valid keys and values' do should include(key => value) end it 'adds a constraint that returns false for an invalid key' do should_not include(key.to_s => value) end it 'adds a constraint that returns false for an invalid value' do should_not include(key => value.to_sym) end end end axiom-types-0.1.1/spec/unit/axiom/types/hash/class_methods/infer_spec.rb0000644000004100000410000001014412322241316026423 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Hash, '.infer' do subject { object.infer(arg) } before do object.finalize end before do # Initialize custom types that will be used if the class lookup does not # restrict matching to only types with an Object key and value types Axiom::Types.infer(Hash[Object => Float]) Axiom::Types.infer(Hash[Float => Object]) end context 'with Axiom::Types::Hash' do let(:object) { described_class } context 'with a type object' do let(:arg) { object } it { should be(object) } end context 'with a ::Hash' do let(:arg) { ::Hash } it { should be(object) } end context 'with an empty Hash' do let(:arg) { ::Hash[] } it { should be(object) } end context 'with an Hash with a key type and nil value' do let(:arg) { ::Hash[object => nil] } its(:ancestors) { should include(object) } its(:primitive) { should be(object.primitive) } its(:key_type) { should be(object) } its(:value_type) { should be(Axiom::Types::Object) } end context 'with an Hash with a nil key and value type' do let(:arg) { ::Hash[nil => object] } its(:ancestors) { should include(object) } its(:primitive) { should be(object.primitive) } its(:key_type) { should be(Axiom::Types::Object) } its(:value_type) { should be(object) } end context 'with an Hash with key and value types' do let(:arg) { ::Hash[object => object] } its(:ancestors) { should include(object) } its(:primitive) { should be(object.primitive) } its(:key_type) { should be(object) } its(:value_type) { should be(object) } end context 'with an Hash with a key primitive and nil value' do let(:arg) { ::Hash[::Hash => nil] } its(:ancestors) { should include(object) } its(:primitive) { should be(object.primitive) } its(:key_type) { should be(object) } its(:value_type) { should be(Axiom::Types::Object) } end context 'with an Hash with a nil key and value primitive' do let(:arg) { ::Hash[nil => ::Hash] } its(:ancestors) { should include(object) } its(:primitive) { should be(object.primitive) } its(:key_type) { should be(Axiom::Types::Object) } its(:value_type) { should be(object) } end context 'with an Hash with key and value primitives' do let(:arg) { ::Hash[::Hash => ::Hash] } its(:ancestors) { should include(object) } its(:primitive) { should be(object.primitive) } its(:key_type) { should be(object) } its(:value_type) { should be(object) } end context 'when the argument is nil' do let(:arg) { nil } it { should be_nil } end end context 'with Axiom::Types::Hash subclass' do let(:object) { Class.new(described_class) } context 'when the argument is the type object' do let(:arg) { object } it { should be(object) } end context 'when the argument is ::Hash' do let(:arg) { ::Hash } it { should be(object) } end context 'with an empty Hash' do let(:arg) { ::Hash[] } it { should be(object) } end context 'with an Hash with a key type and nil value' do let(:arg) { ::Hash[object => nil] } it { should be_nil } end context 'with an Hash with a nil key and value type' do let(:arg) { ::Hash[nil => object] } it { should be_nil } end context 'with an Hash with key and value types' do let(:arg) { ::Hash[object => object] } it { should be_nil } end context 'with an Hash with a key primitive and nil value' do let(:arg) { ::Hash[::Hash => nil] } it { should be_nil } end context 'with an Hash with a nil key and value primitive' do let(:arg) { ::Hash[nil => ::Hash] } it { should be_nil } end context 'with an Hash with key and value primitives' do let(:arg) { ::Hash[::Hash => ::Hash] } it { should be_nil } end context 'with a nil' do let(:arg) { nil } it { should be_nil } end end end axiom-types-0.1.1/spec/unit/axiom/types/infinity/0000755000004100000410000000000012322241316022037 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/infinity/coerce_spec.rb0000644000004100000410000000310512322241316024635 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Infinity, '#coerce' do subject { object.coerce(other) } let(:object) { described_class.instance } [ 1, # Fixnum 2**63, # Bignum 1.0, # Float Rational(1, 1), # Rational BigDecimal('1'), # BigDecimal ].each do |number| context "when other is a #{number.class}" do let(:other) { number } it 'coerces into an array containing inverse and self' do should eql([Axiom::Types::NegativeInfinity.instance, object]) end it 'coerces when comparing' do expect(other).to be < object expect(other).to_not be == object end end end context 'when other is a Float::INFINITY' do let(:other) { Float::INFINITY } it 'coerces into an array containing inverse and self' do should eql([Axiom::Types::Infinity.instance, object]) end it 'coerces when comparing' do expect(other).to_not be < object expect(other).to be == object end end context 'when other is a -Float::INFINITY' do let(:other) { -Float::INFINITY } it 'coerces into an array containing inverse and self' do should eql([Axiom::Types::NegativeInfinity.instance, object]) end it 'coerces when comparing' do expect(other).to be < object expect(other).to_not be == object end end context 'when other is not a number' do let(:other) { 'string' } specify do expect { subject }.to raise_error(TypeError, 'String cannot be coerced') end end end axiom-types-0.1.1/spec/unit/axiom/types/infinity/succ_spec.rb0000644000004100000410000000027512322241316024337 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Infinity, '#succ' do subject { object.succ } let(:object) { described_class.instance } it { should be(object) } end axiom-types-0.1.1/spec/unit/axiom/types/infinity/spaceship_operator_spec.rb0000644000004100000410000000246612322241316027300 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Infinity, '#<=>' do subject { object <=> other } let(:object) { described_class.instance } [ 1, # Fixnum 2**63, # Bignum 1.0, # Float Rational(1, 1), # Rational BigDecimal('1'), # BigDecimal ].each do |number| context "when other object is a #{number.class}" do let(:other) { number } it { should be(1) } it 'is symmetric' do should be(-(other <=> object)) end end end context 'when the other object is negative infinity' do let(:other) { Axiom::Types::NegativeInfinity.instance } it { should be(1) } it 'is symmetric' do should be(-(other <=> object)) end end context 'when the other object is infinity' do let(:other) { object } it { should be(0) } it 'is symmetric' do should be(-(other <=> object)) end end context 'when the other object is Float::INFINITY' do let(:other) { Float::INFINITY } it { should be(0) } it 'is symmetric' do should be(-(other <=> object)) end end context 'when the other object is not comparable' do let(:other) { 'string' } it { should be_nil } it 'is symmetric' do should be(other <=> object) end end end axiom-types-0.1.1/spec/unit/axiom/types/value_comparable/0000755000004100000410000000000012322241316023507 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/value_comparable/finalize_spec.rb0000644000004100000410000000133412322241316026650 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::ValueComparable, '#finalize' do subject { object.finalize } let(:object) do Class.new(Axiom::Types::Type) do extend Axiom::Types::ValueComparable minimum 1 maximum 2 end end it_should_behave_like 'a command method' it_should_behave_like 'an idempotent method' it { should be_frozen } its(:range) { should be_frozen } its(:constraint) { should be_frozen } it 'adds a constraint that returns true for a value within range' do should include(1) should include(2) end it 'adds a constraint that returns false for a value not within range' do should_not include(0) should_not include(3) end end axiom-types-0.1.1/spec/unit/axiom/types/value_comparable/range_spec.rb0000644000004100000410000000063312322241316026144 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::ValueComparable, '#range' do subject { object.range } let(:object) do Class.new(Axiom::Types::Type) do extend Axiom::Types::ValueComparable minimum 1 maximum 2 end end before do object.finalize end it_should_behave_like 'an idempotent method' it { should be_frozen } it { should eql(1..2) } end axiom-types-0.1.1/spec/unit/axiom/types/value_comparable/class_methods/0000755000004100000410000000000012322241316026337 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/value_comparable/class_methods/extended_spec.rb0000644000004100000410000000250112322241316031474 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::ValueComparable, '.extended' do subject { object.extend(described_class) } let(:object) { Class.new(Axiom::Types::Type) } it 'delegates to the ancestor' do # RSpec will reset stubbed methods after the example. A normal expectation # causes a SystemStackError to be thrown, so we stub it first so that # RSpec tracks the original method (if any), then we add our own stub that # actually works, and finally when the example finishes RSpec will reset # the Module#extended method back to it's original state. allow_any_instance_of(Module).to receive(:extended).with(object) delegated_ancestor = false Module.send(:undef_method, :extended) Module.send(:define_method, :extended) { |_| delegated_ancestor = true } expect { subject }.to change { delegated_ancestor }.from(false).to(true) end it 'adds minimum method' do expect { subject }.to change { object.respond_to?(:minimum) } .from(false).to(true) end it 'adds maxumum method' do expect { subject }.to change { object.respond_to?(:maximum) } .from(false).to(true) end it 'does not set the default minimum' do expect(subject.minimum).to be_nil end it 'does not set the default maximum' do expect(subject.maximum).to be_nil end end axiom-types-0.1.1/spec/unit/axiom/types/length_comparable/0000755000004100000410000000000012322241316023654 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/length_comparable/finalize_spec.rb0000644000004100000410000000137012322241316027015 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::LengthComparable, '#finalize' do subject { object.finalize } let(:object) do Class.new(Axiom::Types::Type) do extend Axiom::Types::LengthComparable minimum_length 1 maximum_length 2 end end it_should_behave_like 'a command method' it_should_behave_like 'an idempotent method' it { should be_frozen } its(:range) { should be_frozen } its(:constraint) { should be_frozen } it 'adds a constraint that returns true for a length within range' do should include('a') should include('ab') end it 'adds a constraint that returns false for a length not within range' do should_not include('') should_not include('abc') end end axiom-types-0.1.1/spec/unit/axiom/types/length_comparable/range_spec.rb0000644000004100000410000000065312322241316026313 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::LengthComparable, '#range' do subject { object.range } let(:object) do Class.new(Axiom::Types::Type) do extend Axiom::Types::LengthComparable minimum_length 1 maximum_length 2 end end before do object.finalize end it_should_behave_like 'an idempotent method' it { should be_frozen } it { should eql(1..2) } end axiom-types-0.1.1/spec/unit/axiom/types/length_comparable/class_methods/0000755000004100000410000000000012322241316026504 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/length_comparable/class_methods/extended_spec.rb0000644000004100000410000000270012322241316031642 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::LengthComparable, '.extended' do subject { object.extend(described_class) } let(:object) { Class.new(Axiom::Types::Type) } it 'delegates to the ancestor' do # RSpec will reset stubbed methods after the example. A normal expectation # causes a SystemStackError to be thrown, so we stub it first so that # RSpec tracks the original method (if any), then we add our own stub that # actually works, and finally when the example finishes RSpec will reset # the Module#extended method back to it's original state. allow_any_instance_of(Module).to receive(:extended).with(object) delegated_ancestor = false Module.send(:undef_method, :extended) Module.send(:define_method, :extended) { |_| delegated_ancestor = true } expect { subject }.to change { delegated_ancestor }.from(false).to(true) end it 'adds minimum_length method' do expect { subject }.to change { object.respond_to?(:minimum_length) } .from(false).to(true) end it 'adds maxumum_length method' do expect { subject }.to change { object.respond_to?(:maximum_length) } .from(false).to(true) end it 'sets the default minimum_length' do expect(subject.minimum_length) .to equal(Axiom::Types::Infinity.instance) end it 'sets the default maximum_length' do expect(subject.maximum_length) .to equal(Axiom::Types::NegativeInfinity.instance) end end axiom-types-0.1.1/spec/unit/axiom/types/encodable/0000755000004100000410000000000012322241316022122 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/encodable/finalize_spec.rb0000644000004100000410000000454512322241316025272 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Encodable, '#finalize' do subject { object.finalize } let(:object) { Class.new(Axiom::Types::Type).extend(described_class) } # Test if Symbol encoding is supported let(:symbol_encoding) do !RUBY_PLATFORM.include?('java') && begin encoding = Encoding::UTF_32BE ''.force_encoding(encoding).to_sym.encoding.equal?(encoding) end end context 'when an ascii compatible encoding (UTF-8) is used' do it_should_behave_like 'a command method' it_should_behave_like 'an idempotent method' it { should be_frozen } its(:constraint) { should be_frozen } Encoding.list.each do |encoding| if encoding.equal?(Encoding::UTF_8) string = '𝒜wesome'.force_encoding(encoding) it "adds a constraint that returns true for #{encoding} encoding" do should include(string) should include(string.to_sym) if symbol_encoding end elsif encoding.ascii_compatible? string = ''.force_encoding(encoding) it "adds a constraint that returns true for #{encoding} encoding" do should include(string) should include(string.to_sym) if symbol_encoding end else string = ''.force_encoding(encoding) it "adds a constraint that returns false for #{encoding} encoding" do should_not include(string) should_not include(string.to_sym) if symbol_encoding end end end end context 'when an non-ascii compatible encoding (UTF-16BE) is used' do before do object.encoding Encoding::UTF_16BE end it_should_behave_like 'a command method' it_should_behave_like 'an idempotent method' it { should be_frozen } its(:constraint) { should be_frozen } Encoding.list.each do |encoding| if encoding.equal?(Encoding::UTF_16BE) string = '𝒜wesome'.force_encoding(encoding) it "adds a constraint that returns true for #{encoding} encoding" do should include(string) should include(string.to_sym) if symbol_encoding end else string = ''.force_encoding(encoding) it "adds a constraint that returns false for #{encoding} encoding" do should_not include(string) should_not include(string.to_sym) if symbol_encoding end end end end end axiom-types-0.1.1/spec/unit/axiom/types/encodable/class_methods/0000755000004100000410000000000012322241316024752 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/encodable/class_methods/extended_spec.rb0000644000004100000410000000216212322241316030112 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Encodable, '.extended' do subject { object.extend(described_class) } let(:object) { Class.new(Axiom::Types::Type) } it 'delegates to the ancestor' do # RSpec will reset stubbed methods after the example. A normal expectation # causes a SystemStackError to be thrown, so we stub it first so that # RSpec tracks the original method (if any), then we add our own stub that # actually works, and finally when the example finishes RSpec will reset # the Module#extended method back to it's original state. allow_any_instance_of(Module).to receive(:extended).with(object) delegated_ancestor = false Module.send(:undef_method, :extended) Module.send(:define_method, :extended) { |_| delegated_ancestor = true } expect { subject }.to change { delegated_ancestor }.from(false).to(true) end it 'adds encoding method' do expect { subject }.to change { object.respond_to?(:encoding) } .from(false).to(true) end it 'sets the encoding default to UTF-8' do expect(subject.encoding).to be(Encoding::UTF_8) end end axiom-types-0.1.1/spec/unit/axiom/types/class_methods/0000755000004100000410000000000012322241316023036 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/class_methods/finalize_spec.rb0000644000004100000410000000055712322241316026205 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types, '.finalize' do subject { object.finalize } let(:object) { described_class } let(:descendant) { Class.new(Axiom::Types::Type) } it_should_behave_like 'a command method' it 'finalizes the descendants' do expect(descendant).to receive(:finalize) subject end end axiom-types-0.1.1/spec/unit/axiom/types/class_methods/infer_spec.rb0000644000004100000410000000204612322241316025502 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types, '.infer' do subject { object.infer(type) } let(:object) { described_class } before do object.finalize end Axiom::Types::Type.descendants.each do |descendant| context "when the type is #{descendant}" do let(:type) { descendant } it { should be(descendant) } end if descendant.equal?(Axiom::Types::Boolean) context 'when the type is TrueClass' do let(:type) { ::TrueClass } it { should be(descendant) } end context 'when the type is FalseClass' do let(:type) { ::FalseClass } it { should be(descendant) } end else primitive = descendant.primitive context "when the type is #{primitive}" do let(:type) { primitive } it { should be(descendant) } end end end context 'with a custom type' do let(:type) do Axiom::Types::String.new do minimum_length 1 maximum_length 100 end end it { should be(type) } end end axiom-types-0.1.1/spec/unit/axiom/types/object/0000755000004100000410000000000012322241316021454 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/object/class_methods/0000755000004100000410000000000012322241316024304 5ustar www-datawww-dataaxiom-types-0.1.1/spec/unit/axiom/types/object/class_methods/finalize_spec.rb0000644000004100000410000000122012322241316027437 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Object, '.finalize' do subject { object.finalize } let(:object) do # Class.new { ... } does not work with this on 1.8.7 object = Class.new(described_class) object.primitive(::String) object end it_should_behave_like 'a command method' it_should_behave_like 'an idempotent method' it { should be_frozen } its(:constraint) { should be_frozen } it 'adds a constraint that returns true for a valid primitive' do should include('string') end it 'adds a constraint that returns false for an invalid primitive' do should_not include(nil) end end axiom-types-0.1.1/spec/unit/axiom/types/object/class_methods/infer_spec.rb0000644000004100000410000000416212322241316026751 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Object, '.infer' do subject { object.infer(arg) } context 'with the type' do let(:object) { described_class } context 'when the argument is the type object' do let(:arg) { object } it { should be(object) } end context 'when the argument is ::BasicObject' do let(:arg) { ::BasicObject } it { should be(object) } end context 'when the argument is ::Object' do let(:arg) { ::Object } it { should be(object) } end Axiom::Types::Object.descendants.each do |descendant| primitive = descendant.primitive context "when the argument is #{descendant}" do let(:object) { descendant } let(:arg) { object } it { should be(object) } end context "when the argument is ::#{primitive}" do let(:arg) { primitive } it { should be(object) } end end context 'when the argument is an ::Object instance' do let(:arg) { ::Object.new } it { should be_nil } end context 'when the argument is nil' do let(:arg) { nil } it { should be_nil } end end context 'with a subclass' do let(:object) do described_class.new { primitive ::Struct } end context 'when the argument is the type object' do let(:arg) { object } it { should be(object) } end context 'when the argument is ::BasicObject' do let(:arg) { ::BasicObject } it { should be_nil } end context 'when the argument is ::Object' do let(:arg) { ::Object } it { should be_nil } end context 'when the argument is an ::Object instance' do let(:arg) { ::Object.new } it { should be_nil } end context 'when the argument is ::Struct' do let(:arg) { ::Struct } it { should be(object) } end context 'when the argument is a ::Struct instance' do let(:arg) { ::Struct.new(:a).new(1) } it { should be_nil } end context 'when the argument is nil' do let(:arg) { nil } it { should be_nil } end end end axiom-types-0.1.1/spec/unit/axiom/types/object/class_methods/coercion_method_spec.rb0000644000004100000410000000117712322241316031012 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Object, '.coercion_method' do let(:object) { Class.new(described_class) } let(:coercion_method) { :to_object } context 'with no arguments' do subject { object.coercion_method } it { should be(coercion_method) } end context 'with a symbol' do subject { object.coercion_method(symbol) } let(:symbol) { :to_string } it_should_behave_like 'a command method' it 'sets the coercion_method' do expect { subject }.to change { object.coercion_method } .from(coercion_method).to(symbol) end end end axiom-types-0.1.1/spec/unit/axiom/types/object/class_methods/inspect_spec.rb0000644000004100000410000000033712322241316027313 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Object, '.inspect' do subject { object.inspect } let(:object) { described_class } it { should eql("Axiom::Types::Object (#{object.primitive})") } end axiom-types-0.1.1/spec/unit/axiom/types/object/class_methods/primitive_spec.rb0000644000004100000410000000114112322241316027650 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' describe Axiom::Types::Object, '.primitive' do let(:object) { Class.new(described_class) } let(:primitive) { ::BasicObject } context 'with no arguments' do subject { object.primitive } it { should be(primitive) } end context 'with a class' do subject { object.primitive(klass) } let(:klass) { ::String } it_should_behave_like 'a command method' it 'sets the primitive' do expect { subject }.to change { object.primitive.object_id } .from(primitive.object_id).to(klass.object_id) end end end axiom-types-0.1.1/.travis.yml0000644000004100000410000000142512322241316016127 0ustar www-datawww-datalanguage: ruby before_install: gem install bundler bundler_args: --without yard guard benchmarks script: "bundle exec rake ci:metrics" rvm: - 1.9.3 - 2.0.0 - 2.1.0 - 2.1.1 - ruby-head - rbx-2 matrix: include: - rvm: jruby-19mode env: JRUBY_OPTS="$JRUBY_OPTS --debug" # for simplecov - rvm: jruby-20mode env: JRUBY_OPTS="$JRUBY_OPTS --debug" # for simplecov - rvm: jruby-21mode env: JRUBY_OPTS="$JRUBY_OPTS --debug" # for simplecov - rvm: jruby-head env: JRUBY_OPTS="$JRUBY_OPTS --debug" # for simplecov allow_failures: - rvm: 2.1.0 # buggy runtime - rvm: ruby-head - rvm: jruby-head fast_finish: true notifications: irc: channels: - irc.freenode.org#rom-rb on_success: never on_failure: change axiom-types-0.1.1/lib/0000755000004100000410000000000012322241316014562 5ustar www-datawww-dataaxiom-types-0.1.1/lib/axiom-types.rb0000644000004100000410000000005112322241316017362 0ustar www-datawww-data# encoding: utf-8 require 'axiom/types' axiom-types-0.1.1/lib/axiom/0000755000004100000410000000000012322241316015677 5ustar www-datawww-dataaxiom-types-0.1.1/lib/axiom/types.rb0000644000004100000410000000376312322241316017401 0ustar www-datawww-data# encoding: utf-8 require 'bigdecimal' require 'date' require 'set' require 'singleton' require 'descendants_tracker' require 'ice_nine' require 'thread_safe' module Axiom # Gem namespace module Types # Represent an undefined argument Undefined = Object.new.freeze # A true proposition Tautology = ->(_value) { true }.freeze # A false proposition Contradiction = ->(_value) { true }.freeze # Cache the type inference lookup by object @inference_cache = ThreadSafe::Cache.new do |cache, object| type = nil Type.descendants.detect do |descendant| type = descendant.infer(object) end cache[object] = type end # Infer the type of an object # # @example # Axiom::Types.infer(Integer) # => Axiom::Types::Integer # # @param [Object] object # object to infer the type of # # @return [Class] # # @api public def self.infer(object) @inference_cache[object] end # Finalize Axiom::Types::Type subclasses # # @example # Axiom::Types.finalize # => Axiom::Types # # @return [Module] # # @api public def self.finalize Type.descendants.each(&:finalize) self end end # module Types end # module Axiom require 'axiom/types/support/options' require 'axiom/types/support/infinity' require 'axiom/types/value_comparable' require 'axiom/types/length_comparable' require 'axiom/types/encodable' require 'axiom/types/type' require 'axiom/types/object' require 'axiom/types/collection' require 'axiom/types/numeric' require 'axiom/types/array' require 'axiom/types/boolean' require 'axiom/types/class' require 'axiom/types/date' require 'axiom/types/date_time' require 'axiom/types/decimal' require 'axiom/types/float' require 'axiom/types/hash' require 'axiom/types/integer' require 'axiom/types/set' require 'axiom/types/string' require 'axiom/types/symbol' require 'axiom/types/time' require 'axiom/types/version' axiom-types-0.1.1/lib/axiom/types/0000755000004100000410000000000012322241316017043 5ustar www-datawww-dataaxiom-types-0.1.1/lib/axiom/types/string.rb0000644000004100000410000000050412322241316020675 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a string type class String < Object extend LengthComparable, Encodable primitive ::String coercion_method :to_string minimum_length 0 maximum_length 255 end # class String end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/decimal.rb0000644000004100000410000000036212322241316020767 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a decimal type class Decimal < Numeric primitive ::BigDecimal coercion_method :to_decimal end # class Decimal end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/hash.rb0000644000004100000410000000725412322241316020323 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a hash type class Hash < Object primitive ::Hash coercion_method :to_hash accept_options :key_type, :value_type key_type Object value_type Object # Infer the type of the object # # @example # type = Axiom::Types.infer(object) # # @param [Object] object # # @return [Class] # returned if the type matches # @return [nil] # returned if the type does not match # # @api public def self.infer(object) case object when primitive infer_from_primitive_instance(object) else super end end # Finalize by setting up constraints for the key and value # # @return [Class] # # @api private def self.finalize return self if frozen? key_type.finalize value_type.finalize matches_key_and_value_types super end # Test if the type matches a primitive class # # @param [Object] object # # @return [Boolean] # # @api private def self.match_primitive?(*) super && key_type.equal?(Object) && value_type.equal?(Object) end private_class_method :match_primitive? # Infer the type from a primitive instance # # @param [Object] object # # @return [Class] # returned if the primitive instance matches # @return [nil] # returned if the primitive instance does not match # # @api private def self.infer_from_primitive_instance(object) key, value = object.first key_type = Types.infer(key) || Object value_type = Types.infer(value) || Object infer_from(key_type, value_type) || new_from(key_type, value_type) end private_class_method :infer_from_primitive_instance # Infer the type from the key_type and value_type # # @param [Class] key_type # @param [Class] value_type # # @return [Class] # returned if the key_type and value_type match # @return [nil] # returned if the key_type and value_type do not match # # @api private def self.infer_from(key_type, value_type) self if self.key_type.equal?(key_type) && self.value_type.equal?(value_type) end private_class_method :infer_from # Instantiate a new type from a base type # # @param [Class] key_type # @param [Class] value_type # # @return [Class] # returned if a base type # @return [nil] # returned if not a base type # # @api private def self.new_from(key_type, value_type) new { key_type(key_type).value_type(value_type) } if base? end private_class_method :new_from # Test if the type is a base type # # @return [Boolean] # # @api private def self.base? equal?(Hash) end private_class_method :base? # Add a constraints for the key and value # # @return [undefined] # # @api private def self.matches_key_and_value_types constraint do |object| object.all? do |key, value| key_type.include?(key) && value_type.include?(value) end end end private_class_method :matches_key_and_value_types end # class Hash end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/class.rb0000644000004100000410000000034412322241316020476 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a Class type class Class < Object primitive ::Class coercion_method :to_class end # class Class end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/date_time.rb0000644000004100000410000000072612322241316021330 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a date time type class DateTime < Object extend ValueComparable # The maximum seconds for DateTime MAXIMUM_SECONDS = 60 - Rational(1, 10**12) primitive ::DateTime coercion_method :to_datetime minimum primitive.new(1, 1, 1) maximum primitive.new(9999, 12, 31, 23, 59, MAXIMUM_SECONDS) end # class DateTime end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/set.rb0000644000004100000410000000063412322241316020166 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a set type class Set < Collection primitive ::Set coercion_method :to_set # Test if the type is a base type # # @return [Boolean] # # @api private def self.base? equal?(Set) end private_class_method :base? end # class Set end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/float.rb0000644000004100000410000000044212322241316020475 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a decimal type class Float < Numeric primitive ::Float coercion_method :to_float minimum primitive::MIN maximum primitive::MAX end # class Float end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/time.rb0000644000004100000410000000075112322241316020331 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a date time type class Time < Object extend ValueComparable # The minimum and maximum seconds for Time on 32-bit systems MINIMUM_SECONDS = -2**31 MAXIMUM_SECONDS = 2**31 - 1 primitive ::Time coercion_method :to_time minimum primitive.at(MINIMUM_SECONDS).utc maximum primitive.at(MAXIMUM_SECONDS).utc end # class Time end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/encodable.rb0000644000004100000410000000316612322241316021312 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Add encoding constraints to a type module Encodable # stub module for ruby 1.8 end module Encodable # Hook called when module is extended # # Add #encoding DSL method to descendant and set the default to UTF-8. # # @param [Class] descendant # # @return [undefined] # # @api private def self.extended(descendant) super descendant.accept_options :encoding descendant.encoding Encoding::UTF_8 end private_class_method :extended # Finalize by setting up a primitive constraint # # @return [Axiom::Types::Encodable] # # @api private def finalize return self if frozen? ascii_compatible? ? use_ascii_compatible_encoding : use_encoding super end private # Test if the encoding is ascii compatible # # @return [Boolean] # # @api private def ascii_compatible? encoding.ascii_compatible? end # Add constraint for the ascii compatible encoding # # @return [undefined] # # @api private def use_ascii_compatible_encoding constraint do |object| object.encoding.equal?(encoding) || object.to_s.ascii_only? end end # Add constraint for the encoding # # @return [undefined] # # @api private def use_encoding constraint { |object| object.encoding.equal?(encoding) } end end # module Encodable end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/date.rb0000644000004100000410000000051512322241316020306 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a date type class Date < Object extend ValueComparable primitive ::Date coercion_method :to_date minimum primitive.new(1, 1, 1) maximum primitive.new(9999, 12, 31) end # class Date end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/object.rb0000644000004100000410000000427212322241316020643 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents an object type class Object < Type accept_options :primitive, :coercion_method primitive ::Object.superclass || ::Object coercion_method :to_object # Infer the type of the object # # @example # Axiom::Types::Object.infer(::Object) # => Axiom::Types::Object # # @param [Object] object # # @return [Class] # returned if the type matches # @return [nil] # returned if the type does not match # # @api public def self.infer(object) super || infer_from_primitive_class(object) end # Finalize by setting up a primitive constraint # # @return [Class] # # @api private def self.finalize return self if frozen? inherits_from_primitive super end # The type name and primitive # # @return [String] # # @api public def self.inspect "#{base} (#{primitive})" end # Infer the type if the primitive class matches # # @param [Object] object # # @return [Class] # returned if the primitive class matches # @return [nil] # returned if the primitive class does not match # # @api private def self.infer_from_primitive_class(object) self if match_primitive?(object) end private_class_method :infer_from_primitive_class # Test if the type matches a primitive class # # @param [Object] object # # @return [Boolean] # # @api private def self.match_primitive?(object) Module === object && (equal?(Object) || object.ancestors.include?(primitive)) end private_class_method :match_primitive? # Add a constraint for the primitive # # @return [undefined] # # @api private def self.inherits_from_primitive constraint(&primitive.method(:===)) end private_class_method :inherits_from_primitive end # class Object end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/boolean.rb0000644000004100000410000000140312322241316021005 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a boolean type class Boolean < Object coercion_method :to_boolean includes true, false # Infer the type if the primitive class matches # # @param [Object] object # # @return [Class] # returned if the primitive class matches # @return [nil] # returned if the primitive class does not match # # @api private def self.infer_from_primitive_class(object) case object when TrueClass.singleton_class, FalseClass.singleton_class self end end private_class_method :infer_from_primitive_class end # class Boolean end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/version.rb0000644000004100000410000000021012322241316021046 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Gem version VERSION = '0.1.1'.freeze end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/array.rb0000644000004100000410000000065112322241316020510 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents an array type class Array < Collection primitive ::Array coercion_method :to_array # Test if the type is a base type # # @return [Boolean] # # @api private def self.base? equal?(Array) end private_class_method :base? end # class Array end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/integer.rb0000644000004100000410000000035712322241316021032 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a decimal type class Integer < Numeric primitive ::Integer coercion_method :to_integer end # class Integer end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/collection.rb0000644000004100000410000000764512322241316021537 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a collection type class Collection < Object primitive ::Enumerable accept_options :member_type member_type Object # Infer the type of the object # # @example with a type # Axiom::Types::Array.infer(Axiom::Types::Array) # # => Axiom::Types::Array # # @example with a primitive class # Axiom::Types::Collection.infer(::Array) # # => Axiom::Types::Array # # @example with a primitive instance # Axiom::Types::Array.infer(Array[]) # # => Axiom::Types::Array # # @example with a primitive instance and a member type # Axiom::Types::Collection.infer(Array[Axiom::Types::String]) # # => Axiom::Types::Array subclass w/String member type # # @example with a primitive instance and a member primitive # Axiom::Types::Collection.infer(Array[String]) # # => Axiom::Types::Array subclass w/String member type # # @param [Object] object # # @return [Class] # returned if the type matches # @return [nil] # returned if the type does not match # # @api public def self.infer(object) case object when primitive infer_from_primitive_instance(object) else super end end # Finalize by setting up constraints for the member # # @return [Class] # # @api private def self.finalize return self if frozen? member_type.finalize matches_member_type super end # Test if the type matches a primitive class # # @param [Object] object # # @return [Boolean] # # @api private def self.match_primitive?(*) super && member_type.equal?(Object) end private_class_method :match_primitive? # Infer the type from a primitive instance # # @param [Object] object # # @return [Class] # returned if the primitive instance matches # @return [nil] # returned if the primitive instance does not match # # @api private def self.infer_from_primitive_instance(object) member_type = Types.infer(object.first) || Object infer_from(member_type) || new_from(member_type) end private_class_method :infer_from_primitive_instance # Infer the type from the member_type # # @param [Class] member_type # # @return [Class] # returned if the member_type matches # @return [nil] # returned if the member_type does not match # # @api private def self.infer_from(member_type) self if self.member_type.equal?(member_type) end private_class_method :infer_from # Instantiate a new type from a base type # # @param [Class] member_type # # @return [Class] # returned if a base type # @return [nil] # returned if not a base type # # @api private def self.new_from(member_type) new { member_type(member_type) } if base? end private_class_method :new_from # Test if the type is a base type # # @return [Boolean] # # @api private def self.base? # noop end private_class_method :base? # Add a constraints for the member # # @return [undefined] # # @api private def self.matches_member_type constraint do |object| object.all? { |member| member_type.include?(member) } end end private_class_method :matches_member_type end # class Collection end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/length_comparable.rb0000644000004100000410000000267412322241316023047 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Add a minimum and maximum length constraint to a type module LengthComparable # The range of allowed lengths # # @return [Range] # # @api public attr_reader :range # Hook called when module is extended # # Add #minimum_length and #maximum_length DSL methods to descendant. # # @param [Class] descendant # # @return [undefined] # # @api private def self.extended(descendant) super descendant.class_eval do accept_options :minimum_length, :maximum_length minimum_length Infinity.instance maximum_length NegativeInfinity.instance end end # Finalize by setting up a length range constraint # # @return [Axiom::Types::LengthComparable] # # @api private def finalize return self if frozen? @range = IceNine.deep_freeze(minimum_length..maximum_length) use_length_within_range super end private # Add a constraint for a length within a range # # @return [undefined] # # @todo freeze the minimum_length and maximum_length # # @api private def use_length_within_range constraint { |object| range.cover?(object.length) } end end # module LengthComparable end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/numeric.rb0000644000004100000410000000052512322241316021034 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a numeric type class Numeric < Object extend ValueComparable primitive ::Numeric coercion_method :to_numeric minimum NegativeInfinity.instance maximum Infinity.instance end # class Numeric end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/value_comparable.rb0000644000004100000410000000234712322241316022677 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Add a minimum and maximum value constraint to a type module ValueComparable # The range of allowed values # # @return [Range] # # @api public attr_reader :range # Hook called when module is extended # # Add #minimum and #maximum DSL methods to descendant. # # @param [Class] descendant # # @return [undefined] # # @api private def self.extended(descendant) super descendant.accept_options :minimum, :maximum end # Finalize by setting up a value range constraint # # @return [Axiom::Types::ValueComparable] # # @api private def finalize return self if frozen? @range = IceNine.deep_freeze(minimum..maximum) use_value_within_range super end private # Add a constraint for a value within a range # # @return [undefined] # # @todo freeze the minimum and maximum # # @api private def use_value_within_range constraint(range.method(:cover?)) end end # module ValueComparable end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/support/0000755000004100000410000000000012322241316020557 5ustar www-datawww-dataaxiom-types-0.1.1/lib/axiom/types/support/options.rb0000644000004100000410000000633112322241316022602 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # A module that adds class and instance level options module Options # Raised when the method is already used class ReservedMethodError < ArgumentError; end # Defines which options are valid for a given attribute class # # @example # class MyTypes < Axiom::Types::Object # accept_options :foo, :bar # end # # @return [self] # # @api public def accept_options(*new_options) (new_options - accepted_options).each do |new_option| assert_method_available(new_option) define_option_method(new_option) setup_option(new_option) end self end protected # Set up the option in the current class and descendants # # @param [Symbol] new_option # new option to be added # # @return [self] # # @api private def setup_option(new_option) instance_variable_set(:"@#{new_option}", nil) accepted_options << new_option descendants.each do |descendant| descendant.send(__method__, new_option) end self end private # Adds descendant to descendants array and inherits default options # # @param [Class] descendant # # @return [undefined] # # @api private def inherited(descendant) super options.each do |option, value| descendant.setup_option(option).public_send(option, value) end end # Returns default options hash for a given attribute class # # @example # Axiom::Types::String.options # # => {:primitive => String} # # @return [Hash] # a hash of default option values # # @api private def options accepted_options.each_with_object({}) do |name, options| options[name] = public_send(name) end end # Returns an array of valid options # # @example # Axiom::Types::String.accepted_options # # => [:primitive, :accessor, :reader, :writer] # # @return [Array] # the array of valid option names # # @api private def accepted_options @accepted_options ||= [] end # Assert that the option is not already defined # # @param [Symbol] name # # @return [undefined] # # @raise [ReservedMethodError] # raised when the method is already defined # # @api private def assert_method_available(name) return unless respond_to?(name) fail( ReservedMethodError, "method named `#{name.inspect}` is already defined" ) end # Adds a reader/writer method for the give option name # # @param [#to_s] name # # @return [undefined] # # @api private def define_option_method(name) ivar = :"@#{name}" define_singleton_method(name) do |*args| return instance_variable_get(ivar) if args.empty? instance_variable_set(ivar, *args) self end end end # module Options end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/support/infinity.rb0000644000004100000410000000443212322241316022740 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represent an infinite number class Infinity extend Options, DescendantsTracker include ::Comparable, ::Singleton accept_options :inverse, :number number ::Float::INFINITY # Test the number against infinity # # @param [Numeric, Infinity] other # # @return [0] # returned if the other object is infinity # @return [1] # returned if the other object is something other than infinity # # @api private def <=>(other) klass = self.class case other when BigDecimal then 1 when ->(arg) { arg == klass.number } then 0 when ::Numeric, klass.inverse then 1 end end # Coerce a number into an Infinity instance for comparison # # @param [::Numeric] other # # @return [Array(Infinity, Infinity)] # # @api private def coerce(other) case other when BigDecimal then [inverse, self] when self.class.number then [self, self] when ::Numeric then [inverse, self] else fail TypeError, "#{other.class} cannot be coerced" end end # Return the next successive object, which is always self # # @return [Infinity] # # @api private def succ self end private # The inverse instance # # @return [Infinity] # # @api private def inverse self.class.inverse.instance end end # class Infinity # Represent a negative infinite number class NegativeInfinity < Infinity number(-::Float::INFINITY) # Test the number against negative infinity # # @param [Numeric, Infinity] _other # # @return [0] # returned if the other object is negative infinity # @return [-1] # returned if the other object is not negative infinity # # @api private def <=>(_other) comparison = super -comparison if comparison end end # class NegativeInfinity # Define inverse classes Infinity.inverse NegativeInfinity NegativeInfinity.inverse Infinity end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/symbol.rb0000644000004100000410000000050412322241316020674 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Represents a symbol type class Symbol < Object extend LengthComparable, Encodable primitive ::Symbol coercion_method :to_symbol minimum_length 0 maximum_length 255 end # class Symbol end # module Types end # module Axiom axiom-types-0.1.1/lib/axiom/types/type.rb0000644000004100000410000001045012322241316020351 0ustar www-datawww-data# encoding: utf-8 module Axiom module Types # Abstract base class for every type class Type extend Options, DescendantsTracker accept_options :constraint constraint Tautology # Infer the type of the object # # @example # type = Axiom::Types::Type.infer(Axiom::Types::Integer) # # => Axiom::Types::Integer # # @param [Object] object # # @return [Class] # # @api public def self.infer(object) self if equal?(object) end # Instantiate a new Axiom::Types::Type subclass # # @example # type = Axiom::Types::Type.new # => Axiom::Types::Type # # @param [Array(#call)] args # optional constraint for the new type # # @yield [object] # # @yieldparam object [Object] # test if the object matches the type constraint # # @yieldreturn [Boolean] # true if the object matches the type constraint # # @return [Class] # # @api public def self.new(*args, &block) type = ::Class.new(self, &block) type.constraint(*args) type.finalize end # Finalize by deep freezing # # @return [Class] # # @api private def self.finalize IceNine.deep_freeze(constraint) freeze end # Test if the object matches the type constraint # # @example # type = Axiom::Types::Integer.new do # minimum 1 # maximum 100 # end # # type.include?(1) # => true # type.include?(100) # => true # type.include?(0) # => false # type.include?(101) # => false # # @param [Object] object # # @return [Boolean] # # @api public def self.include?(object) constraint.call(object) end # Silence warnings when redeclaring constraint singleton_class.class_eval { undef_method :constraint } # Add a constraint to the type # # @example with an argument # type.constraint(->(object) { object == 42 } # # @example with a block # type.constraint { |object| object == 42 } # # @example with no arguments # type.constraint # => constraint # # @param [#call] constraint # optional constraint # # @yield [object] # # @yieldparam object [Object] # test if the object matches the type constraint # # @yieldreturn [Boolean] # true if the object matches the type constraint # # @return [Class] # # @api public def self.constraint(constraint = Undefined, &block) constraint = block if constraint.equal?(Undefined) return @constraint if constraint.nil? add_constraint(constraint) self end # Add a constraint that the object must be included in a set # # @param [Array] members # # @return [undefined] # # @todo move into a module # # @api private def self.includes(*members) set = IceNine.deep_freeze(members.to_set) constraint(&set.method(:include?)) end # The base type for the type # # @return [Class] # # @api public def self.base base? ? self : superclass.base end # Test if the type is a base type # # @return [Boolean] # # @api public def self.base? !anonymous? end # Test if the type is anonymous # # @return [Boolean] # # @api public def self.anonymous? name.to_s.empty? end # Add new constraint to existing constraint, if any # # @param [#call] constraint # # @return [undefined] # # @api private def self.add_constraint(constraint) current = self.constraint @constraint = if current ->(object) { constraint.call(object) && current.call(object) } else constraint end end private_class_method :add_constraint end # class Type end # module Types end # module Axiom axiom-types-0.1.1/.rubocop.yml0000644000004100000410000000016712322241316016272 0ustar www-datawww-dataAllCops: Includes: - 'Gemfile' Excludes: - 'Gemfile.devtools' - 'vendor/**' - 'lib/axiom-types.rb' axiom-types-0.1.1/metadata.yml0000644000004100000410000002014312322241316016317 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: axiom-types version: !ruby/object:Gem::Version version: 0.1.1 platform: ruby authors: - Dan Kubb autorequire: bindir: bin cert_chain: [] date: 2014-03-27 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: descendants_tracker requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.0.4 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.0.4 - !ruby/object:Gem::Dependency name: ice_nine requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.11.0 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: 0.11.0 - !ruby/object:Gem::Dependency name: thread_safe requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '0.3' - - '>=' - !ruby/object:Gem::Version version: 0.3.1 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '0.3' - - '>=' - !ruby/object:Gem::Version version: 0.3.1 - !ruby/object:Gem::Dependency name: bundler requirement: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '1.5' - - '>=' - !ruby/object:Gem::Version version: 1.5.3 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ~> - !ruby/object:Gem::Version version: '1.5' - - '>=' - !ruby/object:Gem::Version version: 1.5.3 description: Define types with optional constraints for use within axiom and other libraries. email: dan.kubb@gmail.com executables: [] extensions: [] extra_rdoc_files: - LICENSE - README.md - CONTRIBUTING.md - TODO files: - .gitignore - .rspec - .rubocop.yml - .ruby-gemset - .travis.yml - .yardopts - CONTRIBUTING.md - Gemfile - Gemfile.devtools - Guardfile - LICENSE - README.md - Rakefile - TODO - axiom-types.gemspec - config/devtools.yml - config/flay.yml - config/flog.yml - config/mutant.yml - config/reek.yml - config/roodi.yml - config/rubocop.yml - config/yardstick.yml - lib/axiom-types.rb - lib/axiom/types.rb - lib/axiom/types/array.rb - lib/axiom/types/boolean.rb - lib/axiom/types/class.rb - lib/axiom/types/collection.rb - lib/axiom/types/date.rb - lib/axiom/types/date_time.rb - lib/axiom/types/decimal.rb - lib/axiom/types/encodable.rb - lib/axiom/types/float.rb - lib/axiom/types/hash.rb - lib/axiom/types/integer.rb - lib/axiom/types/length_comparable.rb - lib/axiom/types/numeric.rb - lib/axiom/types/object.rb - lib/axiom/types/set.rb - lib/axiom/types/string.rb - lib/axiom/types/support/infinity.rb - lib/axiom/types/support/options.rb - lib/axiom/types/symbol.rb - lib/axiom/types/time.rb - lib/axiom/types/type.rb - lib/axiom/types/value_comparable.rb - lib/axiom/types/version.rb - spec/spec_helper.rb - spec/unit/axiom/types/array/class_methods/infer_spec.rb - spec/unit/axiom/types/boolean/class_methods/infer_spec.rb - spec/unit/axiom/types/class_methods/finalize_spec.rb - spec/unit/axiom/types/class_methods/infer_spec.rb - spec/unit/axiom/types/collection/class_methods/finalize_spec.rb - spec/unit/axiom/types/collection/class_methods/infer_spec.rb - spec/unit/axiom/types/encodable/class_methods/extended_spec.rb - spec/unit/axiom/types/encodable/finalize_spec.rb - spec/unit/axiom/types/hash/class_methods/finalize_spec.rb - spec/unit/axiom/types/hash/class_methods/infer_spec.rb - spec/unit/axiom/types/infinity/coerce_spec.rb - spec/unit/axiom/types/infinity/spaceship_operator_spec.rb - spec/unit/axiom/types/infinity/succ_spec.rb - spec/unit/axiom/types/length_comparable/class_methods/extended_spec.rb - spec/unit/axiom/types/length_comparable/finalize_spec.rb - spec/unit/axiom/types/length_comparable/range_spec.rb - spec/unit/axiom/types/negative_infinity/spaceship_operator_spec.rb - spec/unit/axiom/types/object/class_methods/coercion_method_spec.rb - spec/unit/axiom/types/object/class_methods/finalize_spec.rb - spec/unit/axiom/types/object/class_methods/infer_spec.rb - spec/unit/axiom/types/object/class_methods/inspect_spec.rb - spec/unit/axiom/types/object/class_methods/primitive_spec.rb - spec/unit/axiom/types/options/accept_options_spec.rb - spec/unit/axiom/types/options/inherited_spec.rb - spec/unit/axiom/types/set/class_methods/infer_spec.rb - spec/unit/axiom/types/type/class_methods/anonymous_predicate_spec.rb - spec/unit/axiom/types/type/class_methods/base_predicate_spec.rb - spec/unit/axiom/types/type/class_methods/base_spec.rb - spec/unit/axiom/types/type/class_methods/constraint_spec.rb - spec/unit/axiom/types/type/class_methods/finalize_spec.rb - spec/unit/axiom/types/type/class_methods/include_predicate_spec.rb - spec/unit/axiom/types/type/class_methods/includes_spec.rb - spec/unit/axiom/types/type/class_methods/infer_spec.rb - spec/unit/axiom/types/type/class_methods/new_spec.rb - spec/unit/axiom/types/value_comparable/class_methods/extended_spec.rb - spec/unit/axiom/types/value_comparable/finalize_spec.rb - spec/unit/axiom/types/value_comparable/range_spec.rb homepage: https://github.com/dkubb/axiom-types licenses: - MIT metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: 1.9.3 required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.2.2 signing_key: specification_version: 4 summary: Abstract types for logic programming test_files: - spec/unit/axiom/types/array/class_methods/infer_spec.rb - spec/unit/axiom/types/boolean/class_methods/infer_spec.rb - spec/unit/axiom/types/class_methods/finalize_spec.rb - spec/unit/axiom/types/class_methods/infer_spec.rb - spec/unit/axiom/types/collection/class_methods/finalize_spec.rb - spec/unit/axiom/types/collection/class_methods/infer_spec.rb - spec/unit/axiom/types/encodable/class_methods/extended_spec.rb - spec/unit/axiom/types/encodable/finalize_spec.rb - spec/unit/axiom/types/hash/class_methods/finalize_spec.rb - spec/unit/axiom/types/hash/class_methods/infer_spec.rb - spec/unit/axiom/types/infinity/coerce_spec.rb - spec/unit/axiom/types/infinity/spaceship_operator_spec.rb - spec/unit/axiom/types/infinity/succ_spec.rb - spec/unit/axiom/types/length_comparable/class_methods/extended_spec.rb - spec/unit/axiom/types/length_comparable/finalize_spec.rb - spec/unit/axiom/types/length_comparable/range_spec.rb - spec/unit/axiom/types/negative_infinity/spaceship_operator_spec.rb - spec/unit/axiom/types/object/class_methods/coercion_method_spec.rb - spec/unit/axiom/types/object/class_methods/finalize_spec.rb - spec/unit/axiom/types/object/class_methods/infer_spec.rb - spec/unit/axiom/types/object/class_methods/inspect_spec.rb - spec/unit/axiom/types/object/class_methods/primitive_spec.rb - spec/unit/axiom/types/options/accept_options_spec.rb - spec/unit/axiom/types/options/inherited_spec.rb - spec/unit/axiom/types/set/class_methods/infer_spec.rb - spec/unit/axiom/types/type/class_methods/anonymous_predicate_spec.rb - spec/unit/axiom/types/type/class_methods/base_predicate_spec.rb - spec/unit/axiom/types/type/class_methods/base_spec.rb - spec/unit/axiom/types/type/class_methods/constraint_spec.rb - spec/unit/axiom/types/type/class_methods/finalize_spec.rb - spec/unit/axiom/types/type/class_methods/include_predicate_spec.rb - spec/unit/axiom/types/type/class_methods/includes_spec.rb - spec/unit/axiom/types/type/class_methods/infer_spec.rb - spec/unit/axiom/types/type/class_methods/new_spec.rb - spec/unit/axiom/types/value_comparable/class_methods/extended_spec.rb - spec/unit/axiom/types/value_comparable/finalize_spec.rb - spec/unit/axiom/types/value_comparable/range_spec.rb has_rdoc: axiom-types-0.1.1/.gitignore0000600000004100000410000000041212322241316015771 0ustar www-datawww-data## MAC OS .DS_Store ## TEXTMATE *.tmproj tmtags ## EMACS *~ \#* .\#* ## VIM *.sw[op] ## Rubinius *.rbc .rbx ## PROJECT::GENERAL *.gem coverage profiling turbulence rdoc pkg tmp doc log .yardoc measurements ## BUNDLER .bundle Gemfile.lock ## PROJECT::SPECIFIC axiom-types-0.1.1/config/0000755000004100000410000000000012322241316015261 5ustar www-datawww-dataaxiom-types-0.1.1/config/flay.yml0000644000004100000410000000004312322241316016734 0ustar www-datawww-data--- threshold: 19 total_score: 175 axiom-types-0.1.1/config/reek.yml0000644000004100000410000000436512322241316016742 0ustar www-datawww-data--- Attribute: enabled: true exclude: - Axiom::Types::LengthComparable - Axiom::Types::ValueComparable BooleanParameter: enabled: true exclude: [] ClassVariable: enabled: true exclude: [] ControlParameter: enabled: true exclude: - Axiom::Types::Boolean#self.infer_from_primitive_class - Axiom::Types::Collection#self.infer_from - Axiom::Types::Infinity#<=> - Axiom::Types::Object#self.infer_from_primitive_class - Axiom::Types::Type#self.infer DataClump: enabled: true exclude: [] max_copies: 0 min_clump_size: 2 DuplicateMethodCall: enabled: true exclude: - Axiom::Types::Infinity#self.coerce max_calls: 1 allow_calls: [] FeatureEnvy: enabled: true exclude: - Axiom::Types::Encodable#has_encoding IrresponsibleModule: enabled: true exclude: [] LongParameterList: enabled: true exclude: [] max_params: 2 overrides: initialize: max_params: 3 LongYieldList: enabled: true exclude: [] max_params: 2 NestedIterators: enabled: true exclude: - Axiom::Types::Hash#self.matches_key_and_value_types - Axiom::Types::Collection#self.matches_member_type max_allowed_nesting: 1 ignore_iterators: [] NilCheck: enabled: true exclude: - Axiom::Types::Type#self.constraint RepeatedConditional: enabled: true exclude: - Axiom::Types::Infinity max_ifs: 1 TooManyInstanceVariables: enabled: true exclude: [] max_instance_variables: 1 TooManyMethods: enabled: true exclude: [] max_methods: 4 TooManyStatements: enabled: true exclude: - each max_statements: 5 UncommunicativeMethodName: enabled: true exclude: [] reject: - !ruby/regexp /^[a-z]$/ - !ruby/regexp /[0-9]$/ - !ruby/regexp /[A-Z]/ accept: [] UncommunicativeModuleName: enabled: true exclude: [] reject: - !ruby/regexp /^.$/ - !ruby/regexp /[0-9]$/ accept: [] UncommunicativeParameterName: enabled: true exclude: [] reject: - !ruby/regexp /^.$/ - !ruby/regexp /[0-9]$/ - !ruby/regexp /[A-Z]/ accept: [] UncommunicativeVariableName: enabled: true exclude: [] reject: - !ruby/regexp /^.$/ - !ruby/regexp /[0-9]$/ - !ruby/regexp /[A-Z]/ accept: [] UnusedParameters: enabled: true exclude: [] UtilityFunction: enabled: true exclude: [] max_helper_calls: 0 axiom-types-0.1.1/config/devtools.yml0000600000004100000410000000003312322241316017627 0ustar www-datawww-data--- unit_test_timeout: 0.1 axiom-types-0.1.1/config/yardstick.yml0000600000004100000410000000002312322241316017764 0ustar www-datawww-data--- threshold: 100 axiom-types-0.1.1/config/rubocop.yml0000644000004100000410000000403612322241316017460 0ustar www-datawww-datainherit_from: ../.rubocop.yml # Avoid parameter lists longer than five parameters. ParameterLists: Max: 3 CountKeywordArgs: true # Limit method length MethodLength: CountComments: false Max: 7 # 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. AccessModifierIndentation: 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 # Do not prefer do/end over {} for multiline blocks Blocks: Enabled: false # Allow empty lines around body EmptyLinesAroundBody: Enabled: false # Prefer String#% over Kernel#sprintf FormatString: Enabled: false # Use square brackets for literal Array objects PercentLiteralDelimiters: PreferredDelimiters: '%': () '%i': '[]' '%q': () '%Q': () '%r': '{}' '%s': () '%w': '[]' '%W': '[]' '%x': () # The #<=> method argument has an underscore because it is not referenced OpMethod: Enabled: false axiom-types-0.1.1/config/roodi.yml0000600000004100000410000000156612322241316017120 0ustar www-datawww-data--- AbcMetricMethodCheck: { score: 6.0 } AssignmentInConditionalCheck: { } CaseMissingElseCheck: { } ClassLineCountCheck: { line_count: 129 } ClassNameCheck: { pattern: !ruby/regexp '/\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/' } ClassVariableCheck: { } CyclomaticComplexityBlockCheck: { complexity: 3 } CyclomaticComplexityMethodCheck: { complexity: 3 } EmptyRescueBodyCheck: { } ForLoopCheck: { } MethodLineCountCheck: { line_count: 5 } MethodNameCheck: { pattern: !ruby/regexp '/\A(?:[a-z\d](?:_?[a-z\d])+[?!=]?|\[\]=?|==|<=>|<<|[+*&|-])\z/' } ModuleLineCountCheck: { line_count: 111 } ModuleNameCheck: { pattern: !ruby/regexp '/\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/' } ParameterNumberCheck: { parameter_count: 2 } axiom-types-0.1.1/config/flog.yml0000644000004100000410000000002412322241316016727 0ustar www-datawww-data--- threshold: 11.4 axiom-types-0.1.1/config/mutant.yml0000600000004100000410000000005612322241316017305 0ustar www-datawww-data--- name: axiom-types namespace: Axiom::Types axiom-types-0.1.1/.yardopts0000600000004100000410000000004612322241316015652 0ustar www-datawww-data--quiet README.md lib/**/*.rb LICENSE axiom-types-0.1.1/CONTRIBUTING.md0000644000004100000410000000201112322241316016237 0ustar www-datawww-data# Contributing * 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. axiom-types-0.1.1/LICENSE0000600000004100000410000000203412322241316015010 0ustar www-datawww-dataCopyright (c) 2013 Dan Kubb 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. axiom-types-0.1.1/.ruby-gemset0000600000004100000410000000001412322241316016243 0ustar www-datawww-dataaxiom-types axiom-types-0.1.1/axiom-types.gemspec0000644000004100000410000000203212322241316017635 0ustar www-datawww-data# encoding: utf-8 require File.expand_path('../lib/axiom/types/version', __FILE__) Gem::Specification.new do |gem| gem.name = 'axiom-types' gem.version = Axiom::Types::VERSION.dup gem.authors = ['Dan Kubb'] gem.email = 'dan.kubb@gmail.com' gem.summary = 'Abstract types for logic programming' gem.description = 'Define types with optional constraints for use within axiom and other libraries.' gem.homepage = 'https://github.com/dkubb/axiom-types' gem.license = 'MIT' gem.require_paths = %w[lib] 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.required_ruby_version = '>= 1.9.3' gem.add_runtime_dependency('descendants_tracker', '~> 0.0.4') gem.add_runtime_dependency('ice_nine', '~> 0.11.0') gem.add_runtime_dependency('thread_safe', '~> 0.3', '>= 0.3.1') gem.add_development_dependency('bundler', '~> 1.5', '>= 1.5.3') end axiom-types-0.1.1/TODO0000600000004100000410000000130212322241316014470 0ustar www-datawww-dataTODO ---- * Add finite limits to all "primitive" types. * Add optional constraint on Date for the timezone * Add optional constraint on DateTime for the timezone * Add optional constraint on Time for the timezone * Add optional regexp constraint to String * format /\A[a-z]+\z/ * Add optional allowed characters constraint to String * allowed_characters 'a', 'b', 'c' * allowed_characters 'a'..'c' * allowed_characters 'a'..'c', 'e', 'f', 'g', 'i' * allowed_characters 'a'..'c', 'e'..'g', 'i' * When axiom-logic is available, replace the Proc based constraints with real predicates so that they can be serialized into SQL or optimized, etc. * Can be performed as part of type finalization axiom-types-0.1.1/checksums.yaml.gz0000444000004100000410000000041612322241316017303 0ustar www-datawww-dataK3Se-A DO 8i̖Ie V~z<_??y+;_WFOJB)=gG2ɘ}}1`T$u6b<˛%x}ݪHF:7ƤGpE*-ŵMϠ(E'`[ID(b-W11:maB҉]W6x-jĵIeO1嵮md-J63J&z;_2(+[ZV{G*axiom-types-0.1.1/README.md0000644000004100000410000000243312322241316015275 0ustar www-datawww-data# axiom-types Define types with optional constraints for use within axiom and other libraries. [![Gem Version](https://badge.fury.io/rb/axiom-types.png)][gem] [![Build Status](https://secure.travis-ci.org/dkubb/axiom-types.png?branch=master)][travis] [![Dependency Status](https://gemnasium.com/dkubb/axiom-types.png)][gemnasium] [![Code Climate](https://codeclimate.com/github/dkubb/axiom-types.png)][codeclimate] [![Coverage Status](https://coveralls.io/repos/dkubb/axiom-types/badge.png?branch=master)][coveralls] [gem]: https://rubygems.org/gems/axiom-types [travis]: https://travis-ci.org/dkubb/axiom-types [gemnasium]: https://gemnasium.com/dkubb/axiom-types [codeclimate]: https://codeclimate.com/github/dkubb/axiom-types [coveralls]: https://coveralls.io/r/dkubb/axiom-types ## Examples ```ruby # Setup constraints for all defined types Axiom::Types.finalize # Create Name subtype Name = Axiom::Types::String.new do minimum_length 1 maximum_length 30 end # Test if the string is a member of the type Name.include?('a') # => true Name.include?('a' * 30) # => true Name.include?('') # => false Name.include?('a' * 31) # => false ``` ## Contributing See [CONTRIBUTING.md](CONTRIBUTING.md) for details. ## Copyright Copyright © 2013 Dan Kubb. See LICENSE for details. axiom-types-0.1.1/Guardfile0000600000004100000410000000235412322241316015635 0ustar www-datawww-data# encoding: utf-8 guard :bundler do watch('Gemfile') watch('Gemfile.lock') watch(%w{.+.gemspec\z}) end guard :rspec, cli: File.read('.rspec').split.push('--fail-fast').join(' '), keep_failed: false do # Run all specs if configuration is modified watch('.rspec') { 'spec' } watch('Guardfile') { 'spec' } watch('Gemfile.lock') { 'spec' } watch('spec/spec_helper.rb') { 'spec' } # Run all specs if supporting files files are modified watch(%r{\Aspec/(?:fixtures|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(%r{\Alib/(.+)/support/(.+)\.rb\z}) { |m| Dir["spec/unit/#{m[1]}/#{m[2]}*"] } 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 guard :rubocop, cli: %w[--config config/rubocop.yml] do watch(%r{.+\.(?:rb|rake)\z}) watch(%r{\Aconfig/rubocop\.yml\z}) { |m| File.dirname(m[0]) } watch(%r{(?:.+/)?\.rubocop\.yml\z}) { |m| File.dirname(m[0]) } end