varia_model-0.5.0/0000755000004100000410000000000012614014326014025 5ustar www-datawww-datavaria_model-0.5.0/Thorfile0000644000004100000410000000174312614014326015531 0ustar www-datawww-data# encoding: utf-8 $:.push File.expand_path("../lib", __FILE__) require 'bundler' require 'bundler/setup' require 'buff/ruby_engine' require 'varia_model' class Default < Thor extend Buff::RubyEngine unless jruby? require 'thor/rake_compat' include Thor::RakeCompat Bundler::GemHelper.install_tasks desc "build", "Build varia_model-#{VariaModel::VERSION}.gem into the pkg directory" def build Rake::Task["build"].execute end desc "install", "Build and install varia_model-#{VariaModel::VERSION}.gem into system gems" def install Rake::Task["install"].execute end desc "release", "Create tag v#{VariaModel::VERSION} and build and push varia_model-#{VariaModel::VERSION}.gem to Rubygems" def release Rake::Task["release"].execute end end class Spec < Thor namespace :spec default_task :all desc "all", "run all tests" def all exec "rspec --color --format=documentation spec" end end end varia_model-0.5.0/Rakefile0000644000004100000410000000003412614014326015467 0ustar www-datawww-datarequire 'bundler/gem_tasks' varia_model-0.5.0/Gemfile0000644000004100000410000000131012614014326015313 0ustar www-datawww-datasource 'https://rubygems.org' gemspec group :development do gem 'coolline' require 'rbconfig' if RbConfig::CONFIG['target_os'] =~ /darwin/i gem 'growl', require: false gem 'rb-fsevent', require: false if `uname`.strip == 'Darwin' && `sw_vers -productVersion`.strip >= '10.8' gem 'terminal-notifier-guard', '~> 1.5.3', require: false end rescue Errno::ENOENT elsif RbConfig::CONFIG['target_os'] =~ /linux/i gem 'libnotify', '~> 0.8.0', require: false gem 'rb-inotify', require: false elsif RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i gem 'win32console', require: false gem 'rb-notifu', '>= 0.0.4', require: false gem 'wdm', require: false end end varia_model-0.5.0/spec/0000755000004100000410000000000012614014326014757 5ustar www-datawww-datavaria_model-0.5.0/spec/spec_helper.rb0000644000004100000410000000114412614014326017575 0ustar www-datawww-data$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'rspec' require 'buff/ruby_engine' def setup_rspec Dir[File.join(File.expand_path("../../spec/support/**/*.rb", __FILE__))].each { |f| require f } RSpec.configure do |config| config.expect_with :rspec do |c| c.syntax = :expect end config.mock_with :rspec config.filter_run focus: true config.run_all_when_everything_filtered = true end end if Buff::RubyEngine.jruby? require 'varia_model' setup_rspec else require 'spork' Spork.prefork { setup_rspec } Spork.each_run { require 'varia_model' } end varia_model-0.5.0/spec/unit/0000755000004100000410000000000012614014326015736 5ustar www-datawww-datavaria_model-0.5.0/spec/unit/varia_model_spec.rb0000644000004100000410000004443612614014326021572 0ustar www-datawww-datarequire 'spec_helper' describe VariaModel do describe "ClassMethods" do subject do Class.new do include VariaModel end end describe "::attributes" do it "returns a VariaModel::Attributes" do expect(subject.attributes).to be_a(described_class::Attributes) end it "is empty by default" do expect(subject.attributes).to be_empty end end describe "::attribute" do it "adds an attribute to the attributes hash for each attribute function call" do subject.attribute 'jamie.winsor' subject.attribute 'brooke.winsor' expect(subject.attributes.size).to eq(2) end it "adds a validation if :required option is true" do subject.attribute 'brooke.winsor', required: true expect(subject.validations.size).to eq(1) end it "adds a validation if the :type option is provided" do subject.attribute 'brooke.winsor', type: :string expect(subject.validations.size).to eq(1) end it "sets a default value if :default option is provided" do subject.attribute 'brooke.winsor', default: 'rhode island' expect(subject.attributes.dig('brooke.winsor')).to eql('rhode island') end it "allows an attribute called 'attributes'" do subject.attribute 'attributes', default: 'bag of junk' expect(subject.attributes.dig('attributes')).to eql('bag of junk') end it "allows an attribute called 'attribute'" do subject.attribute 'attribute', default: 'some value' expect(subject.attributes.dig('attribute')).to eql('some value') end it "allows an attribute that has a lambda default value" do subject.attribute 'brooke', default: ->{ "winsor".upcase } expect(subject.attributes.dig('brooke')).to be_a(Proc) end end describe "::validations" do it "returns a Hashie::Mash" do expect(subject.validations).to be_a(Hashie::Mash) end it "is empty by default" do expect(subject.validations).to be_empty end end describe "::validations_for" do context "when an attribute is registered and has validations" do before(:each) do subject.attribute("nested.attribute", required: true, type: String) end it "returns an array of procs" do validations = subject.validations_for("nested.attribute") expect(validations).to be_a(Array) expect(validations).to each be_a(Proc) end end context "when an attribute is registered but has no validations" do before(:each) do subject.attribute("nested.attribute") end it "returns an empty array" do validations = subject.validations_for("nested.attribute") expect(validations).to be_a(Array) expect(validations).to be_empty end end context "when an attribute is not registered" do it "returns an empty array" do validations = subject.validations_for("not_existing.attribute") expect(validations).to be_a(Array) expect(validations).to be_empty end end describe "#assignment_mode" do it "returns the default assignment mode :whitelist" do expect(subject.assignment_mode).to eql(:whitelist) end end describe "#set_assignment_mode" do it "sets the assignment_mode to whitelist" do subject.set_assignment_mode(:whitelist) expect(subject.assignment_mode).to eql(:whitelist) end it "sets the assignment_mode to carefree" do subject.set_assignment_mode(:carefree) expect(subject.assignment_mode).to eql(:carefree) end it "raises if given an invalid assignment mode" do expect { subject.set_assignment_mode(:not_a_real_mode) }.to raise_error(ArgumentError) end end end describe "::validate_kind_of" do let(:types) { [ String, Buff::Boolean ] } let(:key) { 'nested.one' } subject do Class.new do include VariaModel attribute 'nested.one', types: [String, Buff::Boolean] end end let(:model) { subject.new } it "returns an array" do expect(subject.validate_kind_of(types, model, key)).to be_a(Array) end context "failure" do before(:each) { model.nested.one = nil } it "returns an array where the first element is ':error'" do expect(subject.validate_kind_of(types, model, key).first).to eql(:error) end it "returns an array where the second element is an error message containing the attribute and types" do types.each do |type| expect(subject.validate_kind_of(types, model, key)[1]).to match(/#{type}/) end expect(subject.validate_kind_of(types, model, key)[1]).to match(/#{key}/) end end context "success" do before(:each) { model.nested.one = true } it "returns an array where the first element is ':ok'" do expect(subject.validate_kind_of(types, model, key).first).to eql(:ok) end it "returns an array where the second element is a blank string" do expect(subject.validate_kind_of(types, model, key)[1]).to be_blank end end context "when given two types of the same kind" do let(:types) { [ String, String ] } let(:key) { 'nested.one' } subject do Class.new do include VariaModel attribute 'nested.one', types: [String, Buff::Boolean] end end let(:model) { subject.new } before(:each) { model.nested.one = nil } it "returns a error message that contains the type error only once" do error_message = "Expected attribute: 'nested.one' to be a type of: 'String'" expect(subject.validate_kind_of(types, model, key)[1]).to eql(error_message) end end end describe "::validate_required" do subject do Class.new do include VariaModel attribute 'nested.one', required: true end end let(:key) { 'nested.one' } let(:model) { subject.new } it "returns an array" do expect(subject.validate_required(model, key)).to be_a(Array) end it "fails validation if the value of the attribute is nil" do model.set_attribute(key, nil) expect(subject.validate_required(model, key).first).to eql(:error) end it "passes validation if the value of the attribute is false" do model.set_attribute(key, false) expect(subject.validate_required(model, key).first).to eql(:ok) end it "passes validation if the value of the attribute is not nil" do model.set_attribute(key, 'some_value') expect(subject.validate_required(model, key).first).to eql(:ok) end context "failure" do before(:each) { model.nested.one = nil } it "returns an array where the first element is ':error'" do expect(subject.validate_required(model, key).first).to eql(:error) end it "returns an array where the second element is an error message containing the attribute name" do expect(subject.validate_required(model, key)[1]).to match(/#{key}/) end end context "success" do before(:each) { model.nested.one = "hello" } it "returns an array where the first element is ':ok'" do expect(subject.validate_required(model, key).first).to eql(:ok) end it "returns an array where the second element is a blank string" do expect(subject.validate_required(model, key)[1]).to be_blank end end end end subject do Class.new do include VariaModel attribute 'nested.not_coerced', default: 'hello' attribute 'nested.no_default' attribute 'nested.coerced', coerce: lambda { |m| m.to_s } attribute 'toplevel', default: 'hello' attribute 'no_default' attribute 'coerced', coerce: lambda { |m| m.to_s } end.new end describe "GeneratedAccessors" do describe "nested getter" do it "returns the default value" do expect(subject.nested.not_coerced).to eql('hello') end it "returns nil if there is no default value" do expect(subject.nested.no_default).to be_nil end end describe "toplevel getter" do it "returns the default value" do expect(subject.toplevel).to eql('hello') end it "returns nil if there is no default value" do expect(subject.no_default).to be_nil end end describe "nested setter" do it "sets the value of the nested attribute" do subject.nested.not_coerced = 'world' expect(subject.nested.not_coerced).to eql('world') end end describe "toplevel setter" do it "sets the value of the top level attribute" do subject.toplevel = 'world' expect(subject.toplevel).to eql('world') end end describe "nested coerced setter" do it "sets the value of the nested coerced attribute" do subject.nested.coerced = 1 expect(subject.nested.coerced).to eql("1") end end describe "toplevel coerced setter" do it "sets the value of the top level coerced attribute" do subject.coerced = 1 expect(subject.coerced).to eql('1') end end context "given two nested attributes with a common parent and default values" do subject do Class.new do include VariaModel attribute 'nested.one', default: 'val_one' attribute 'nested.two', default: 'val_two' end.new end it "sets a default value for each nested attribute" do expect(subject.nested.one).to eql('val_one') expect(subject.nested.two).to eql('val_two') end end context "given two nested attributes with a common parent and coercions" do subject do Class.new do include VariaModel attribute 'nested.one', coerce: lambda { |m| m.to_s } attribute 'nested.two', coerce: lambda { |m| m.to_s } end.new end it "coerces each value if both have a coercion" do subject.nested.one = 1 subject.nested.two = 2 expect(subject.nested.one).to eql("1") expect(subject.nested.two).to eql("2") end end context "given an attribute called 'attributes'" do subject do Class.new do include VariaModel attribute 'attributes', default: Hash.new end.new end it "allows the setting and getting of the 'attributes' mimic methods" do expect(subject.attributes).to be_a(Hash) expect(subject.attributes).to be_empty new_hash = { something: "here" } subject.attributes = new_hash expect(subject.attributes[:something]).to eql("here") end end end describe "Validations" do describe "validate required" do subject do Class.new do include VariaModel attribute 'brooke.winsor', required: true end.new end it "is not valid if it fails validation" do expect(subject).not_to be_valid end it "adds an error for each attribute that fails validations" do subject.validate expect(subject.errors.size).to eq(1) end it "adds a message for each failed validation" do subject.validate expect(subject.errors['brooke.winsor'].size).to eq(1) expect(subject.errors['brooke.winsor'][0]).to eql("A value is required for attribute: 'brooke.winsor'") end end describe "validate type" do subject do Class.new do include VariaModel attribute 'brooke.winsor', type: String end.new end before(:each) { subject.brooke.winsor = false } it "returns false if it fails validation" do expect(subject).not_to be_valid end it "adds an error if it fails validation" do subject.validate expect(subject.errors.size).to eq(1) expect(subject.errors['brooke.winsor'].size).to eq(1) expect(subject.errors['brooke.winsor'][0]).to eql("Expected attribute: 'brooke.winsor' to be a type of: 'String', 'NilClass'") end end end describe "#set_attribute" do subject do Class.new do include VariaModel attribute 'brooke.winsor', type: String, default: 'sister' attribute 'brooke.costantini', type: String, default: 'sister' end.new end it "sets the value of the given attribute" do subject.set_attribute('brooke.winsor', 'rhode island') expect(subject.brooke.winsor).to eql('rhode island') end it "does not disturb the other attributes" do subject.set_attribute('brooke.winsor', 'rhode island') expect(subject.brooke.costantini).to eql('sister') end end describe "#get_attribute" do subject do Class.new do include VariaModel attribute 'brooke.winsor', type: String, default: 'sister' end.new end it "returns the value of the given dotted path" do expect(subject.get_attribute('brooke.winsor')).to eql('sister') end it "returns nil if the dotted path matches no attributes" do expect(subject.get_attribute('brooke.costantini')).to be_nil end it "returns the current value of the Proc" do subject.brooke.winsor = ->{ "bacon".upcase } expect(subject.get_attribute("brooke.winsor")).to eql("BACON") end it "returns the current value of the Proc each time" do @magic = "ponies" subject.brooke.winsor = -> { @magic } expect(subject.get_attribute("brooke.winsor")).to eql("ponies") @magic = "unicorns" expect(subject.get_attribute("brooke.winsor")).to eql("unicorns") end end describe "#[]" do subject do Class.new do include VariaModel attribute 'foo', default: ->{ String.new("Bacon").upcase } end.new end it "returns the current value of the Proc" do expect(subject['foo']).to eql("BACON") end it "returns the updated value of the Proc" do subject['foo'] subject['foo'] = 'hello' expect(subject['foo']).to eql('hello') end end describe "#mass_assign" do subject do Class.new do include VariaModel attribute 'brooke.winsor', type: String, default: 'sister' attribute 'jamie.winsor', type: String, default: 'brother' attribute 'gizmo', type: String, default: 'dog' end.new end it "sets the values of all matching defined attributes" do new_attrs = { brooke: { winsor: "other" }, jamie: { winsor: "other_two" } } subject.mass_assign(new_attrs) expect(subject.brooke.winsor).to eql("other") expect(subject.jamie.winsor).to eql("other_two") end it "leaves the values of untouched attributes" do new_attrs = { brooke: { winsor: "other" }, jamie: { winsor: "other_two" } } subject.mass_assign(new_attrs) expect(subject.gizmo).to eql("dog") end it "ignores values which are not defined attributes" do new_attrs = { undefined_attribute: "value" } subject.mass_assign(new_attrs) expect(subject.get_attribute(:undefined_attribute)).to be_nil expect(subject).not_to respond_to(:undefined_attribute) end context "when in carefree assignment mode" do subject do Class.new do include VariaModel set_assignment_mode :carefree end.new end it "does not ignore values which are not defined" do new_attrs = { undefined_attribute: "value" } subject.mass_assign(new_attrs) expect(subject.get_attribute(:undefined_attribute)).to eql("value") end end end describe "#from_json" do subject do Class.new do include VariaModel attribute 'first_name', type: String attribute 'nick', type: String end.new end it "returns self" do expect(subject.from_json(JSON.dump(first_name: "jamie", nick: "reset"))).to be_a(described_class) end it "updates self from JSON data" do subject.from_json(JSON.dump(first_name: "jamie", nick: "reset")) expect(subject.first_name).to eql("jamie") expect(subject.nick).to eql("reset") end end describe "#from_hash" do subject do Class.new do include VariaModel attribute 'first_name', type: String attribute 'nick', type: String end.new end it "returns self" do expect(subject.from_hash(first_name: "jamie", nick: "reset")).to be_a(described_class) end it "updates and returns self from a Hash" do subject.from_hash(first_name: "jamie", nick: "reset") expect(subject.first_name).to eql("jamie") expect(subject.nick).to eql("reset") end end describe "#to_json" do class Playa include VariaModel attribute 'first_name', type: String attribute 'nick', type: String end subject do Playa.new end it "returns a JSON string containin the serialized attributes" do subject.first_name = "brooke" subject.nick = "leblanc" expect(subject.to_json).to eql(JSON.dump(first_name: "brooke", nick: "leblanc", json_class: "Playa")) end it "includes the most recent value for any Procs" do subject.first_name = ->{ "seth".capitalize } subject.nick = ->{ "name".upcase } expect(subject.to_json).to eql(JSON.dump(first_name: "Seth", nick: "NAME", json_class: "Playa")) end describe "when JSON.create_id is nil" do before do @_old_create_id = JSON.create_id JSON.create_id = nil end after do JSON.create_id = @_old_create_id end it "does not include a nil key" do subject.first_name = "brooke" subject.nick = "leblanc" expect(subject.to_json).to eql(JSON.dump(first_name: "brooke", nick: "leblanc")) end end end describe "#to_hash" do it "returns all of the varia dattributes" do expect(subject.to_hash).to eql(subject.send(:_attributes_)) end end end varia_model-0.5.0/spec/support/0000755000004100000410000000000012614014326016473 5ustar www-datawww-datavaria_model-0.5.0/spec/support/matchers/0000755000004100000410000000000012614014326020301 5ustar www-datawww-datavaria_model-0.5.0/spec/support/matchers/each.rb0000644000004100000410000000037112614014326021527 0ustar www-datawww-dataRSpec::Matchers.define :each do |check| match do |actual| actual.each_with_index do |index, o| @object = o expect(index).to check end end failure_message do |actual| "at[#{@object}] #{check.failure_message}" end end varia_model-0.5.0/.travis.yml0000644000004100000410000000015112614014326016133 0ustar www-datawww-datalanguage: ruby rvm: - 2.0.0 - 2.1 - 2.2 script: "bundle exec thor spec" sudo: false cache: bundler varia_model-0.5.0/lib/0000755000004100000410000000000012614014326014573 5ustar www-datawww-datavaria_model-0.5.0/lib/varia_model.rb0000644000004100000410000001654512614014326017415 0ustar www-datawww-datarequire 'buff/extensions' require 'json' module VariaModel require_relative 'varia_model/version' require_relative 'varia_model/attributes' module ClassMethods ASSIGNMENT_MODES = [ :whitelist, :carefree ] # @return [VariaModel::Attributes] def attributes @attributes ||= Attributes.new end # @return [Hashie::Mash] def validations @validations ||= Hashie::Mash.new end # @return [Symbol] def assignment_mode @assignment_mode ||= :whitelist end # Set the attribute mass assignment mode # * :whitelist - only attributes defined on the class will have values set # * :carefree - values will be set for attributes that are not explicitly defined # in the class definition # # @param [Symbol] mode # an assignment mode to use @see {ASSIGNMENT_MODES} def set_assignment_mode(mode) unless ASSIGNMENT_MODES.include?(mode) raise ArgumentError, "unknown assignment mode: #{mode}" end @assignment_mode = mode end # @param [#to_s] name # @option options [Symbol, Array] :type # @option options [Buff::Boolean] :required # @option options [Object] :default # @option options [Proc] :coerce def attribute(name, options = {}) name = name.to_s options[:type] = Array(options[:type]) options[:required] ||= false register_attribute(name, options) define_mimic_methods(name, options) end # @param [String] name # # @return [Array] def validations_for(name) self.validations[name] ||= Array.new end # @param [Constant, Array] types # @param [VariaModel] model # @param [String] key # # @return [Array] def validate_kind_of(types, model, key) errors = Array.new types = types.uniq matches = false types.each do |type| if model.get_attribute(key).is_a?(type) matches = true break end end if matches [ :ok, "" ] else types_msg = types.collect { |type| "'#{type}'" } [ :error, "Expected attribute: '#{key}' to be a type of: #{types_msg.join(', ')}" ] end end # Validate that the attribute on the given model has a non-nil value assigned # # @param [VariaModel] model # @param [String] key # # @return [Array] def validate_required(model, key) if model.get_attribute(key).nil? [ :error, "A value is required for attribute: '#{key}'" ] else [ :ok, "" ] end end private def register_attribute(name, options = {}) if options[:type] && options[:type].any? unless options[:required] options[:type] << NilClass end register_validation(name, lambda { |object, key| validate_kind_of(options[:type], object, key) }) end if options[:required] register_validation(name, lambda { |object, key| validate_required(object, key) }) end class_eval do new_attributes = Attributes.from_dotted_path(name, options[:default]) self.attributes.merge!(new_attributes) if options[:coerce].is_a?(Proc) register_coercion(name, options[:coerce]) end end end def register_validation(name, fun) self.validations[name] = (self.validations_for(name) << fun) end def register_coercion(name, fun) self.attributes.container(name).set_coercion(name.split('.').last, fun) end def define_mimic_methods(name, options = {}) fun_name = name.split('.').first class_eval do define_method(fun_name) do _attributes_[fun_name] end define_method("#{fun_name}=") do |value| value = if options[:coerce].is_a?(Proc) options[:coerce].call(value) else value end _attributes_[fun_name] = value end end end end class << self def included(base) base.extend(ClassMethods) end end # @return [Hashie::Mash] def validate self.class.validations.each do |attr_path, validations| validations.each do |validation| status, messages = validation.call(self, attr_path) if status == :error if messages.is_a?(Array) messages.each do |message| self.add_error(attr_path, message) end else self.add_error(attr_path, messages) end end end end self.errors end # @return [Buff::Boolean] def valid? validate.empty? end # @return [Hashie::Mash] def errors @errors ||= Hashie::Mash.new end # Assigns the attributes of a model from a given hash of attributes. # # If the assignment mode is set to `:whitelist`, then only the values of keys which have a # corresponding attribute definition on the model will be set. All other keys will have their # values ignored. # # If the assignment mode is set to `:carefree`, then the attributes hash will be populated # with any key/values that are provided. # # @param [Hash] new_attrs def mass_assign(new_attrs = {}) case self.class.assignment_mode when :whitelist whitelist_assign(new_attrs) when :carefree carefree_assign(new_attrs) end end # @param [#to_s] key # # @return [Object] def get_attribute(key) eval_as_proc(_attributes_.dig(key.to_s)) end alias_method :[], :get_attribute # @param [#to_s] key # @param [Object] value def set_attribute(key, value) _attributes_.deep_merge!(Attributes.from_dotted_path(key.to_s, value)) end alias_method :[]=, :set_attribute # @param [#to_hash] hash # # @return [self] def from_hash(hash) mass_assign(hash.to_hash) self end # @param [String] data # # @return [self] def from_json(data) mass_assign(JSON.parse(data)) self end # The storage hash containing all of the key/values for this object's attributes # # @return [Hashie::Mash] def _attributes_ @_attributes_ ||= self.class.attributes.dup end alias_method :to_hash, :_attributes_ # @option options [Buff::Boolean] :symbolize_keys # @option options [Class, Symbol, String] :adapter # # @return [String] def to_json(*options) as_json.to_json(*options) end # @return [Hash] def as_json(*) opts = {} opts[JSON.create_id] = self.class.name if JSON.create_id to_hash.merge(opts) end # Convert the object to a hash. def to_hash _attributes_.inject({}) { |h, (k,v)| h[k] = eval_as_proc(v); h } end protected # @param [String] attribute # @param [String] message def add_error(attribute, message) self.errors[attribute] ||= Array.new self.errors[attribute] << message end private # Send #call to the given object if it responds to it. If it doesn't, just return the # object. # # @param [#call] def eval_as_proc(obj) obj.respond_to?(:call) ? obj.call : obj end def carefree_assign(new_attrs = {}) _attributes_.deep_merge!(new_attrs) end def whitelist_assign(new_attrs = {}) self.class.attributes.dotted_paths.each do |dotted_path| value = new_attrs.dig(dotted_path) next if value.nil? set_attribute(dotted_path, value) end end end varia_model-0.5.0/lib/varia_model/0000755000004100000410000000000012614014326017055 5ustar www-datawww-datavaria_model-0.5.0/lib/varia_model/version.rb0000644000004100000410000000005212614014326021064 0ustar www-datawww-datamodule VariaModel VERSION = "0.5.0" end varia_model-0.5.0/lib/varia_model/attributes.rb0000644000004100000410000000211612614014326021570 0ustar www-datawww-datarequire 'hashie' require 'hashie/mash' module VariaModel class Attributes < Hashie::Mash alias_method :old_setter, :[]= alias_method :old_dup, :dup attr_writer :coercions # @return [Hashie::Mash] def coercions @coercions ||= Hashie::Mash.new end def coercion(key) self.coercions[key] end def set_coercion(key, fun) self.coercions[key] = fun end # Override setter to coerce the given value if a coercion is defined def []=(key, value) coerced_value = coercion(key).present? ? coercion(key).call(value) : value old_setter(key, coerced_value) end # Return the containing Hashie::Mash of the given dotted path # # @param [String] path # # @return [Hashie::Mash, nil] def container(path) parts = path.split('.', 2) match = (self[parts[0].to_s] || self[parts[0].to_sym]) if !parts[1] or match.nil? self else match.container(parts[1]) end end def dup mash = old_dup mash.coercions = self.coercions mash end end end varia_model-0.5.0/metadata.yml0000644000004100000410000001334212614014326016333 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: varia_model version: !ruby/object:Gem::Version version: 0.5.0 platform: ruby authors: - Jamie Winsor autorequire: bindir: bin cert_chain: [] date: 2015-10-07 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: hashie requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 2.0.2 - - "<" - !ruby/object:Gem::Version version: 4.0.0 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 2.0.2 - - "<" - !ruby/object:Gem::Version version: 4.0.0 - !ruby/object:Gem::Dependency name: buff-extensions requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '1.0' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '1.0' - !ruby/object:Gem::Dependency name: buff-ruby_engine requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '0.1' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '0.1' - !ruby/object:Gem::Dependency name: thor requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: 0.18.0 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: 0.18.0 - !ruby/object:Gem::Dependency name: bundler requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '1.3' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '1.3' - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: rspec requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: fuubar requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: guard requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: guard-rspec requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: guard-spork requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: spork requirement: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' description: A mixin to provide objects with magic attribute reading and writing email: - jamie@vialstudios.com executables: [] extensions: [] extra_rdoc_files: [] files: - ".gitignore" - ".travis.yml" - Gemfile - Guardfile - LICENSE - README.md - Rakefile - Thorfile - lib/varia_model.rb - lib/varia_model/attributes.rb - lib/varia_model/version.rb - spec/spec_helper.rb - spec/support/matchers/each.rb - spec/unit/varia_model_spec.rb - varia_model.gemspec homepage: https://github.com/RiotGames/varia_model licenses: - Apache 2.0 metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 2.0.0 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: A mixin to provide objects with magic attribute reading and writing test_files: - spec/spec_helper.rb - spec/support/matchers/each.rb - spec/unit/varia_model_spec.rb varia_model-0.5.0/.gitignore0000644000004100000410000000025712614014326016021 0ustar www-datawww-data*.gem *.rbc .bundle .config .yardoc .ruby-version Gemfile.lock InstalledFiles _yardoc coverage doc/ lib/bundler/man pkg rdoc spec/reports test/tmp test/version_tmp tmp .rspec varia_model-0.5.0/LICENSE0000644000004100000410000000113012614014326015025 0ustar www-datawww-dataCopyright 2012-2013 Riot Games Jamie Winsor () Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. varia_model-0.5.0/varia_model.gemspec0000644000004100000410000000253412614014326017660 0ustar www-datawww-data# -*- encoding: utf-8 -*- require File.expand_path('../lib/varia_model/version', __FILE__) Gem::Specification.new do |spec| spec.authors = ["Jamie Winsor"] spec.email = ["jamie@vialstudios.com"] spec.description = %q{A mixin to provide objects with magic attribute reading and writing} spec.summary = spec.description spec.homepage = "https://github.com/RiotGames/varia_model" spec.license = "Apache 2.0" spec.files = `git ls-files`.split($\) spec.executables = spec.files.grep(%r{^bin/}).map { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(spec)/}) spec.name = "varia_model" spec.require_paths = ["lib"] spec.version = VariaModel::VERSION spec.required_ruby_version = ">= 2.0.0" spec.add_dependency "hashie", ">= 2.0.2", "< 4.0.0" spec.add_dependency "buff-extensions", "~> 1.0" spec.add_development_dependency "buff-ruby_engine", "~> 0.1" spec.add_development_dependency "thor", "~> 0.18.0" spec.add_development_dependency "bundler", "~> 1.3" spec.add_development_dependency "rake" spec.add_development_dependency "rspec" spec.add_development_dependency "fuubar" spec.add_development_dependency "guard" spec.add_development_dependency "guard-rspec" spec.add_development_dependency "guard-spork" spec.add_development_dependency "spork" end varia_model-0.5.0/README.md0000644000004100000410000000122212614014326015301 0ustar www-datawww-data# VariaModel [![Gem Version](https://badge.fury.io/rb/varia_model.png)](http://badge.fury.io/rb/varia_model) [![Build Status](https://secure.travis-ci.org/reset/varia_model.png?branch=master)](http://travis-ci.org/reset/varia_model) A mixin to provide objects with magic attribute reading and writing ## Installation $ gem install varia_model ## Usage require 'varia_model' module MyApp class Config include VariaModel end end # Authors and Contributors * Jamie Winsor () Thank you to all of our [Contributors](https://github.com/reset/varia_model/graphs/contributors), testers, and users. varia_model-0.5.0/Guardfile0000644000004100000410000000124612614014326015655 0ustar www-datawww-datanotification :off interactor :coolline guard 'spork' do watch('Gemfile') watch('spec/spec_helper.rb') { :rspec } watch(%r{^spec/support/.+\.rb$}) { :rspec } end guard 'rspec', version: 2, cli: "--color --drb --format Fuubar", all_on_start: false, all_after_pass: false do watch(%r{^spec/unit/.+_spec\.rb$}) watch(%r{^spec/acceptance/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" } watch('spec/spec_helper.rb') { "spec" } watch(%r{^spec/support/.+\.rb$}) { "spec" } watch(%r{^spec/shared_examples/(.*)\.rb$}) { |m| ["spec/unit/#{m[1]}_spec.rb", "spec/unit/#{m[1]}"] } end