traitorous 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +14 -1
- data/Rakefile +4 -3
- data/VERSION +1 -1
- data/lib/traitorous/converter/identity.rb +22 -0
- data/lib/traitorous/converter/method_keyed_uniform_hash.rb +43 -0
- data/lib/traitorous/converter/model.rb +26 -3
- data/lib/traitorous/equality.rb +30 -0
- data/lib/traitorous.rb +21 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51c87b262becc747a334dce20c4b0f149de698d4
|
4
|
+
data.tar.gz: 384664790edbfbbcbc95043b7f4cc3fbe78c78e0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27cecb8725cfe6914c81e26ae45cc2e5f9669228e01f3c139d4e02a309af4763918c45a22e75bd9453b9fbd8254c70248ed3f0ed4a0c7eb5e10e9626cedd47ba
|
7
|
+
data.tar.gz: 052ece595a8928766a34eaede53b690981834db33cbedeb2215f940e3d354d2b165118e7e3a2403ff179ecc7d538103c7edf0aa8f645539269c13825627b841e
|
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
# Traitorous
|
1
|
+
# Traitorous [](http://badge.fury.io/rb/traitorous)
|
2
2
|
|
3
3
|
[](https://travis-ci.org/anithri/traitorous)
|
4
4
|
[](https://codeclimate.com/github/anithri/traitorous)
|
5
|
+
[](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
|
-
|
2
|
+
require 'rake/version_task'
|
3
3
|
require 'rspec/core/rake_task'
|
4
4
|
|
5
|
-
|
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.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
|
-
|
8
|
-
|
9
|
-
|
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
|
data/lib/traitorous/equality.rb
CHANGED
@@ -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.
|
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-
|
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
|