padiddler 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +47 -0
- data/Rakefile +1 -0
- data/lib/padiddler/base.rb +68 -0
- data/lib/padiddler/version.rb +3 -0
- data/lib/padiddler.rb +7 -0
- data/padiddler.gemspec +24 -0
- data/spec/padiddler/base_spec.rb +105 -0
- data/spec/spec_helper.rb +6 -0
- metadata +108 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Jeremiah
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Padiddler
|
2
|
+
|
3
|
+
Sometimes data comes to you with a headlight out.
|
4
|
+
|
5
|
+
## Description
|
6
|
+
|
7
|
+
Maniuplate hashes from an external source so they work for your database setup. Especially useful when reading data from external api or csv. Instead of writing a messy conversion system, create easily testable Diddler objects to massage the data.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'paddiddler'
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
First, get a sample piece of input that needs diddling. In this example, the first name and last name don't need extra processing but the date of birth should be renamed and turned into a Date object.
|
18
|
+
|
19
|
+
input = {
|
20
|
+
first_name: 'Jeremiah',
|
21
|
+
last_name: 'Hemphill',
|
22
|
+
tel_no: '555-1234',
|
23
|
+
dob_year: '2014',
|
24
|
+
dob_month: '1',
|
25
|
+
dob_day: '24'
|
26
|
+
}
|
27
|
+
|
28
|
+
Second, define your Diddler for the input
|
29
|
+
|
30
|
+
PersonDiddler < Padiddler::Base
|
31
|
+
# these instance variables should be made public with no changes
|
32
|
+
keep :first_name, :last_name
|
33
|
+
|
34
|
+
# these instance variable should be renamed in the output
|
35
|
+
rename :phone => :tel_no
|
36
|
+
|
37
|
+
# this additional output should be added
|
38
|
+
add :date_of_birth do
|
39
|
+
Date.parse("#{@dob_year}/#{@dob_month}/#{@dob_day}")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Third, diddle away
|
44
|
+
|
45
|
+
input = get_input_from_csv
|
46
|
+
pdiddler = PersonDiddler.new(input)
|
47
|
+
Person.create(pdiddler.diddle)
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Padiddler
|
2
|
+
class Base
|
3
|
+
|
4
|
+
class << self
|
5
|
+
# defines which attributes should be used in the output without changing their values
|
6
|
+
#
|
7
|
+
# @param Array outputs an array of strings or symbols that correspond to instance variable names
|
8
|
+
def keep(*outputs)
|
9
|
+
outputs.each do |name|
|
10
|
+
instance_variable_accessor(name, name)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# defines outputs whose names do not match the name of their instance variable
|
15
|
+
#
|
16
|
+
# @param Hash outputs Each pair should have the format :new_name => :original_name
|
17
|
+
def rename(outputs)
|
18
|
+
outputs.each_pair do |public_name, instance_var_name|
|
19
|
+
instance_variable_accessor(instance_var_name, public_name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# adds a new output that is not directly related to an instance variable
|
24
|
+
# here to keep things consistent
|
25
|
+
#
|
26
|
+
# note that this functionality can be duplicated by just defining methods
|
27
|
+
#
|
28
|
+
# @param Symbol name The name of the output
|
29
|
+
def add(name, &block)
|
30
|
+
define_method(name.to_sym) { yield block }
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# create a name accessor for an instance variable
|
36
|
+
def instance_variable_accessor(var_name, name)
|
37
|
+
instance_var = instance_variable_name(var_name)
|
38
|
+
define_method(name) { instance_variable_get(instance_var) }
|
39
|
+
end
|
40
|
+
|
41
|
+
# convenience method for turning a string into an instance variable symbol
|
42
|
+
# will take a string or symbol as an argument
|
43
|
+
# will add one @ to the front of the input
|
44
|
+
def instance_variable_name(name)
|
45
|
+
"@#{name.to_s}".to_sym
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Turns a hash into instance variables based on top level keys
|
50
|
+
# if the top level key is pointing to a hash, the value is not changed
|
51
|
+
def initialize(input = {})
|
52
|
+
input.each_pair do |key, value|
|
53
|
+
instance_variable_set(self.class.send(:instance_variable_name, key), value)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# gets a list of public methods, assigns their name and value to a hash, and returns
|
58
|
+
# ignores private methods and methods that require arguments
|
59
|
+
def diddle
|
60
|
+
output = {}
|
61
|
+
output_methods = public_methods(false).select { |m| method(m).arity == 0 && m != :diddle }
|
62
|
+
output_methods.each do |name|
|
63
|
+
output[name] = send(name)
|
64
|
+
end
|
65
|
+
output
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/padiddler.rb
ADDED
data/padiddler.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'padiddler/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "padiddler"
|
8
|
+
spec.version = Padiddler::VERSION
|
9
|
+
spec.authors = ["Jeremiah"]
|
10
|
+
spec.email = ["jeremiah@cloudspace.com"]
|
11
|
+
spec.summary = %q{Convert external data into a more usable format}
|
12
|
+
spec.description = %q{Convert external data into a more usable format}
|
13
|
+
spec.homepage = "http://www.github.com/jeremiahishere/padiddler"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# the sample class to test on
|
4
|
+
class SampleDiddler < Padiddler::Base
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Padiddler::Base do
|
8
|
+
# after running each test, remove the methods we have added
|
9
|
+
after(:each) do
|
10
|
+
diddler = SampleDiddler.new({})
|
11
|
+
SampleDiddler.send(:remove_method, :first_name) if diddler.respond_to? :first_name
|
12
|
+
SampleDiddler.send(:remove_method, :middle_name) if diddler.respond_to? :middle_name
|
13
|
+
SampleDiddler.send(:remove_method, :last_name) if diddler.respond_to? :last_name
|
14
|
+
SampleDiddler.send(:remove_method, :hello) if diddler.respond_to? :hello
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'keep' do
|
18
|
+
it 'should take a list of symbols and define multiple instance methods' do
|
19
|
+
SampleDiddler.keep(:first_name, :last_name)
|
20
|
+
diddler = SampleDiddler.new
|
21
|
+
expect(diddler).to respond_to(:first_name)
|
22
|
+
expect(diddler).to respond_to(:last_name)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should take a single symbol and define one instance method' do
|
26
|
+
SampleDiddler.keep(:middle_name)
|
27
|
+
diddler = SampleDiddler.new
|
28
|
+
expect(diddler).to respond_to(:middle_name)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'the new method should return the value of the instance variable with the same name' do
|
32
|
+
SampleDiddler.keep(:first_name, :last_name)
|
33
|
+
diddler = SampleDiddler.new
|
34
|
+
diddler.instance_variable_set(:@first_name, 'Jeremiah')
|
35
|
+
expect(diddler.first_name).to eq('Jeremiah')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'rename' do
|
40
|
+
it 'should take a hash and define instance methods' do
|
41
|
+
SampleDiddler.rename(:first_name => :firstname)
|
42
|
+
diddler = SampleDiddler.new
|
43
|
+
expect(diddler).to respond_to(:first_name)
|
44
|
+
expect(diddler).not_to respond_to(:firstname)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should return the instance referred to in the value of the key value pair' do
|
48
|
+
SampleDiddler.rename(:first_name => :firstname)
|
49
|
+
diddler = SampleDiddler.new
|
50
|
+
diddler.instance_variable_set(:@firstname, 'Jeremiah')
|
51
|
+
expect(diddler.first_name).to eq('Jeremiah')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'add' do
|
56
|
+
it 'should create a new method with the name and body given by the arguments' do
|
57
|
+
SampleDiddler.add(:hello) { 'Hello World' }
|
58
|
+
diddler = SampleDiddler.new
|
59
|
+
expect(diddler.hello).to eq('Hello World')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe 'initialize' do
|
64
|
+
it 'should iterate over the hash and create instance variables' do
|
65
|
+
diddler = SampleDiddler.new(first_name: 'Jeremiah')
|
66
|
+
expect(diddler.instance_variables).to include(:@first_name)
|
67
|
+
expect(diddler.instance_variable_get(:@first_name)).to eq('Jeremiah')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'diddle' do
|
72
|
+
before(:each) do
|
73
|
+
@diddler = SampleDiddler.new(first_name: 'Jeremiah', last_name: 'Hemphill')
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should iterate over public methods and return their outputs' do
|
77
|
+
def @diddler.first_name
|
78
|
+
@first_name
|
79
|
+
end
|
80
|
+
|
81
|
+
expect(@diddler.diddle).to eq(first_name: 'Jeremiah')
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should not include keys in the hash that were not excplicitly made public' do
|
85
|
+
expect(@diddler.diddle.keys).not_to include(:last_name)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should not include private methods' do
|
89
|
+
SampleDiddler.send(:define_method, :first_name) do
|
90
|
+
@first_name
|
91
|
+
end
|
92
|
+
SampleDiddler.instance_eval { private :first_name }
|
93
|
+
|
94
|
+
expect(@diddler.diddle.keys).not_to include(:first_name)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should not include methods that require arguments' do
|
98
|
+
def @diddler.first_name(arg)
|
99
|
+
@first_name + arg
|
100
|
+
end
|
101
|
+
|
102
|
+
expect(@diddler.diddle.keys).not_to include(:first_name)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: padiddler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jeremiah
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-01-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.5'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.5'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Convert external data into a more usable format
|
63
|
+
email:
|
64
|
+
- jeremiah@cloudspace.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- .gitignore
|
70
|
+
- Gemfile
|
71
|
+
- LICENSE.txt
|
72
|
+
- README.md
|
73
|
+
- Rakefile
|
74
|
+
- lib/padiddler.rb
|
75
|
+
- lib/padiddler/base.rb
|
76
|
+
- lib/padiddler/version.rb
|
77
|
+
- padiddler.gemspec
|
78
|
+
- spec/padiddler/base_spec.rb
|
79
|
+
- spec/spec_helper.rb
|
80
|
+
homepage: http://www.github.com/jeremiahishere/padiddler
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.8.25
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: Convert external data into a more usable format
|
105
|
+
test_files:
|
106
|
+
- spec/padiddler/base_spec.rb
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
has_rdoc:
|