traitorous 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0597d522d23bd2c71b7f3c32c4ba7051354855e9
4
- data.tar.gz: 74bafa4cbd011ab8ab2e337a12d7f5c2294288b0
3
+ metadata.gz: 51c87b262becc747a334dce20c4b0f149de698d4
4
+ data.tar.gz: 384664790edbfbbcbc95043b7f4cc3fbe78c78e0
5
5
  SHA512:
6
- metadata.gz: 4fd180776568fd37efb6663e4f2dc0635e58973dcd55d7803c7cec0680de77b50b811802897b1ae2e26a855727cfc7d513f764c2aeefd42b35f08f5ad864c685
7
- data.tar.gz: c891627cf1985ec7be19f239c81d9e78bb99c5648678fffe063c9c1f26599d5aa9315f8f29766107a4a1bf6aba305f2a5434eafe74ec1b065663894b5c30cf96
6
+ metadata.gz: 27cecb8725cfe6914c81e26ae45cc2e5f9669228e01f3c139d4e02a309af4763918c45a22e75bd9453b9fbd8254c70248ed3f0ed4a0c7eb5e10e9626cedd47ba
7
+ data.tar.gz: 052ece595a8928766a34eaede53b690981834db33cbedeb2215f940e3d354d2b165118e7e3a2403ff179ecc7d538103c7edf0aa8f645539269c13825627b841e
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
- # Traitorous
1
+ # Traitorous [![Gem Version](https://badge.fury.io/rb/traitorous.svg)](http://badge.fury.io/rb/traitorous)
2
2
 
3
3
  [![Build Status](https://travis-ci.org/anithri/traitorous.svg)](https://travis-ci.org/anithri/traitorous)
4
4
  [![Code Climate](https://codeclimate.com/github/anithri/traitorous/badges/gpa.svg)](https://codeclimate.com/github/anithri/traitorous)
5
+ [![Inline docs](http://inch-ci.org/github/anithri/traitorous.svg?branch=master)](http://inch-ci.org/github/anithri/traitorous)
5
6
 
6
7
  This is a simple trait based system that emphasizes reading in and out data
7
8
  structures, using an plugin Converter system. Each trait defined has a
@@ -85,6 +86,18 @@ puts Area.new(area.export) == area
85
86
  # true
86
87
  ```
87
88
 
89
+ ## Roadmap
90
+
91
+ 1. Add better documentation
92
+ 2. better testing of deep constructions
93
+ 3. Additional Converters
94
+ a. DefaultValueDynamic that stores code to run upon input or output
95
+ b. VariableArray that uses a sub-type in the opts to location the correct
96
+ class to instantiate instead of always using a uniform class
97
+ c. Validations?
98
+ d. translations?
99
+ e. class specific (Date, CreditCard)
100
+
88
101
  ## Development
89
102
 
90
103
  I use Guard to automate testing. It won't affect anything execpt the disk space
data/Rakefile CHANGED
@@ -1,9 +1,10 @@
1
1
  require 'bundler/gem_tasks'
2
- #require 'rake/version_task'
2
+ require 'rake/version_task'
3
3
  require 'rspec/core/rake_task'
4
4
 
5
- #Rake::VersionTask.new
6
-
5
+ Rake::VersionTask.new do |task|
6
+ task.with_git_tag = true
7
+ end
7
8
  RSpec::Core::RakeTask.new(:spec)
8
9
 
9
10
  task :default => :spec
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -1,10 +1,32 @@
1
1
  module Traitorous
2
2
  module Converter
3
+ # The Identity converter is used as a simple default which performs the
4
+ # jobs of a Converter without changing the inputs at all.
5
+ #
6
+ # This converter can be used when you have simple data (strings, dates,
7
+ # numbers, hashes and arrays of the same) that doesn't need to be inflated
8
+ # into an object and needs no changes to be safely stored as the same.
3
9
  class Identity
10
+ # do_export is called in order to take an existing piece of data and
11
+ # prepare it to be written to a simpler data structure.
12
+ #
13
+ # The Identity converter exports the same data it is passed without
14
+ # changing them at all.
15
+ #
16
+ # @params data [Object] the data object passed in to be exported
17
+ # @return [Object] exports data to a form simple enough to save as JSON
4
18
  def do_export(data)
5
19
  data
6
20
  end
7
21
 
22
+ # do_import is called in order to take some opts and to turn them into
23
+ # instantiated objects, arrays, or other types of transformation
24
+ #
25
+ # The Identity converter imports the same opts it is passed without
26
+ # changing them at all.
27
+ #
28
+ # @params opts [Object] the options to be imported
29
+ # @return [Object] opts
8
30
  def do_import(opts)
9
31
  opts
10
32
  end
@@ -0,0 +1,43 @@
1
+ module Traitorous
2
+ module Converter
3
+ # MethodKeyedUniformedHash is meant to take an array of a simple data
4
+ # structures and convert each into a uniform class, and then will call a
5
+ # key_method on that class and use it as the key in the returned hash.
6
+ #
7
+ # Exported data will be converted into an array calling do_export on each
8
+ # element
9
+ class MethodKeyedUniformHash
10
+ attr_accessor :key_method, :uniform_class
11
+ # @param key_method [Symbol] the method to call on the uniform_class instance
12
+ # to generate the key in the returned hash
13
+ # @param uniform_class [Class, #new] the class to instantiate with each
14
+ # element of the do_import array
15
+ def initialize(key_method, uniform_class)
16
+ @key_method = key_method
17
+ @uniform_class = uniform_class
18
+ end
19
+
20
+ # The import instantiates each element of the array as an instance of
21
+ # the uniform_class, the key is determined by calling key_method on the
22
+ # instance and then they are joined to the result hash as a key,
23
+ # instance pair.
24
+ # @param arr_data [Array] the array of data to instantiate
25
+ # @return [Hash] hash containing key, instance pairs
26
+ def do_import(arr_data)
27
+ out = {}
28
+ arr_data.each do |elem_data|
29
+ obj = uniform_class.new(elem_data)
30
+ out[obj.send(key_method)] = obj
31
+ end
32
+ out
33
+ end
34
+
35
+ # @param hsh_data [Hash<obj,#export>] keys are ignored
36
+ # @return Array each element of the values of hsh_data has #export called
37
+ # on it.
38
+ def do_export(hsh_data)
39
+ hsh_data.values.map{|instance| instance.export }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,16 +1,39 @@
1
1
  module Traitorous
2
2
  module Converter
3
+ # The Model converter is used a a simple way to instantiate an object from
4
+ # the model_class using the imported opts, and which will call .export on
5
+ # the data.
6
+ #
7
+ # This converter can be used when you have a set of opts that you can pass
8
+ # to a classes .new command in order to instantiate an object.
3
9
  class Model
10
+ # @param model_klass [Class,#new] class to instantiate when importing
4
11
  def initialize(model_klass)
5
12
  @model_klass = model_klass
6
13
  end
7
- def do_import(opts)
8
- @model_klass.new(opts)
9
- end
14
+
15
+ # do_export is called in order to take an existing piece of data and
16
+ # prepare it to be written to a simpler data structure.
17
+ #
18
+ # The model converter exports the data by calling .export on it
19
+ #
20
+ # @params data [Object] the data object passed in to be exported
21
+ # @return [Object] result of data.export
10
22
  def do_export(data)
11
23
  data.export
12
24
  end
13
25
 
26
+ # do_import is called in order to take some opts and to turn them into
27
+ # instantiated objects, arrays, or other types of transformation
28
+ #
29
+ # The model converter imports the opts by instantiating a model_class
30
+ # object with it.
31
+ #
32
+ # @params opts [Object] the options to be exported
33
+ # @return [Object] result of model_klass.new(opts)
34
+ def do_import(opts)
35
+ @model_klass.new(opts)
36
+ end
14
37
  end
15
38
  end
16
39
  end
@@ -1,7 +1,31 @@
1
1
  require 'traitorous'
2
2
  module Traitorous
3
+ # Provides a mechanism to test equality of objects that implement a traits hash.
4
+ # This is an iffy concept, and if I didn't happen to be using a Coordinate
5
+ # object in te project this was extracted from it probably wouldn't be a part
6
+ #
7
+ # For this module to work it makes a set of assumptions.
8
+ # 1. The base assumption of the types of objects created using Traitorous is
9
+ # that they are easily expressed in text.
10
+ # 2. That the aggregate of the traits equality means the 2 are equal
11
+ # 3. If a trait is an Array, each element of the array is tested against the 2nd,
12
+ # and vice versa.
13
+ # 4. all other equality is tested using ==
14
+ # 5. nested objects should also implement equality to facilitate the
15
+ # comparisons of deeply nested structures
16
+ #
17
+ # Further expansions might call for the converter to assume an equality guise
3
18
  module Equality
19
+
20
+ # Override the normal :== method to compare each trait individually when
21
+ # testing equality.
22
+ #
23
+ # Coordinate.new(x: 1, y: 2) == Coordinate.new(x:1, y: 2)
24
+
25
+ # @param other_val [#traits] target of comparison
26
+ # @return Boolean if all traits values match return true.
4
27
  def ==(other_val)
28
+ return false unless self.class == other_val.class
5
29
  traits.keys.all? do |trait_name|
6
30
  orig_trait = self.send(trait_name.intern)
7
31
  other_trait = other_val.send(trait_name.intern)
@@ -9,6 +33,12 @@ module Traitorous
9
33
  end
10
34
  end
11
35
 
36
+ # compare the equality of 2 arrays, and I'm not sure this is the best way to
37
+ # do the comparisons.
38
+ # @params alpha [Array] first array
39
+ # @params beta [Array] second array
40
+ # @return [Boolean] true if every element in 1 array is equal(==) to an
41
+ # element in the 2nd and vice versa (order doesn't matter, should it?)
12
42
  def array_equality(alpha, beta)
13
43
  return false unless (alpha.is_a?(Array) && beta.is_a?(Array))
14
44
  alpha.all?{|a| beta.any?{|b| a == b}}
data/lib/traitorous.rb CHANGED
@@ -1,18 +1,38 @@
1
1
  require 'active_support/core_ext/hash/indifferent_access'
2
2
 
3
3
  module Traitorous
4
+
5
+ # Use the HashWithIndifferentAccess from the activesupport gem.
4
6
  HASH = HashWithIndifferentAccess
5
7
 
8
+ # Read the VERSION file in gem root to set version number.
6
9
  VERSION = File.read('VERSION')
7
10
 
11
+ # The converter namespace is used to store Converter classes.
12
+ # Each Converter may take initializer arguments, to allow specific classes or
13
+ # values to be defined, and 2 methods: :do_import and :do_export.
14
+ # do_import is meant to take the data, and use the initial data to combine to
15
+ # build objects or other data structures.
8
16
  module Converter
17
+ # The purpose of the converters are to facilitate the importation of simple
18
+ # JSON or YAML data and import that data into an arbitrarily nested tree
19
+ # of objects. And then to take those object and be able to export that data
20
+ # in a simple form ready to save.
21
+ # opts = {some: 'deep', data: ['structures']}
22
+ # r = Mission.new(opts)
23
+ # Mission.new(r.export) == r
9
24
  require 'traitorous/converter/identity'
10
25
  require 'traitorous/converter/default_value_static'
11
26
  require 'traitorous/converter/model'
12
27
  require 'traitorous/converter/uniform_array'
28
+ require 'traitorous/converter/method_keyed_uniform_hash'
29
+ # if no other converter is declared, use the identity converter which
30
+ # merely pass through the data passed to it.
13
31
  DEFAULT_CONVERTER = Converter::Identity.new
14
32
  end
33
+
15
34
  require 'traitorous/equality'
35
+
16
36
  module ClassMethods
17
37
  attr_accessor :traits
18
38
 
@@ -30,6 +50,7 @@ module Traitorous
30
50
  end
31
51
 
32
52
  def initialize(opts = {})
53
+ raise "No traits have been defined for #{self.class}" unless self.class.traits
33
54
  @opts = HASH.new(opts)
34
55
  traits.each_pair do |new_trait, trait_opts|
35
56
  converter = trait_opts[:converter]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: traitorous
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - scott m parrish
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-09-01 00:00:00.000000000 Z
11
+ date: 2015-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -104,6 +104,7 @@ files:
104
104
  - lib/traitorous.rb
105
105
  - lib/traitorous/converter/default_value_static.rb
106
106
  - lib/traitorous/converter/identity.rb
107
+ - lib/traitorous/converter/method_keyed_uniform_hash.rb
107
108
  - lib/traitorous/converter/model.rb
108
109
  - lib/traitorous/converter/uniform_array.rb
109
110
  - lib/traitorous/equality.rb