suds 0.1.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 +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +62 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +77 -0
- data/Guardfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +68 -0
- data/lib/suds.rb +1 -0
- data/lib/suds/all.rb +12 -0
- data/lib/suds/cleaner.rb +32 -0
- data/lib/suds/cleaner/column_converter_cleaner.rb +26 -0
- data/lib/suds/cleaner/column_filter_cleaner.rb +26 -0
- data/lib/suds/cleaner/downcase_cleaner.rb +21 -0
- data/lib/suds/cleaner/regex_cleaner.rb +41 -0
- data/lib/suds/cleaner/whitespace_cleaner.rb +9 -0
- data/lib/suds/converter.rb +27 -0
- data/lib/suds/converter/json_converter.rb +8 -0
- data/lib/suds/interpreter.rb +19 -0
- data/lib/suds/interpreter/csv_interpreter.rb +28 -0
- data/lib/suds/interpreter/file_interpreter.rb +11 -0
- data/lib/suds/suds.rb +46 -0
- data/lib/suds/version.rb +4 -0
- data/spec/lib/suds/all_spec.rb +13 -0
- data/spec/lib/suds/cleaner/column_converter_cleaner_spec.rb +29 -0
- data/spec/lib/suds/cleaner/column_filter_cleaner_spec.rb +56 -0
- data/spec/lib/suds/cleaner/downcase_cleaner_spec.rb +15 -0
- data/spec/lib/suds/cleaner/regex_cleaner_spec.rb +52 -0
- data/spec/lib/suds/cleaner/whitespace_cleaner_spec.rb +15 -0
- data/spec/lib/suds/cleaner_spec.rb +28 -0
- data/spec/lib/suds/converter/json_converter_spec.rb +12 -0
- data/spec/lib/suds/converter_spec.rb +12 -0
- data/spec/lib/suds/interpreter/csv_interpreter_spec.rb +45 -0
- data/spec/lib/suds/interpreter_spec.rb +11 -0
- data/spec/lib/suds/suds_spec.rb +121 -0
- data/spec/spec_helper.rb +87 -0
- data/spec/support/cleaner_context.rb +5 -0
- data/suds.gemspec +15 -0
- metadata +83 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: e0fc3f6bfeb9132463f70ae8bfb07e1ec04c0fa4
|
|
4
|
+
data.tar.gz: 770b6fe86d994af04989b28d7fd22c4b1d335053
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 116913488fb79c62e8f75ba6bd0adc6232ca1124b23bc0b2598b3709c9419f55d831c948bf2b8585f8857228812e95fe3df499cd5f8ed92bc7035781f39281c0
|
|
7
|
+
data.tar.gz: c8601f3759c37aa3150ed440e9af5bd0d8d37bbfc428441dfa7e66d73b47b06ddd61df653c70722944bb6cf0df1a4ca6be99d0130427fb16398d947ca9917094
|
data/.coveralls.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
repo_token: ULz8tz46aXDE4AbHGI2sh3SwgqjJvHLQs
|
data/.gitignore
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
data/*
|
|
2
|
+
|
|
3
|
+
### Ruby
|
|
4
|
+
|
|
5
|
+
*.gem
|
|
6
|
+
*.rbc
|
|
7
|
+
/.config
|
|
8
|
+
/coverage/
|
|
9
|
+
/InstalledFiles
|
|
10
|
+
/pkg/
|
|
11
|
+
/spec/reports/
|
|
12
|
+
/test/tmp/
|
|
13
|
+
/test/version_tmp/
|
|
14
|
+
/tmp/
|
|
15
|
+
|
|
16
|
+
## Specific to RubyMotion:
|
|
17
|
+
.dat*
|
|
18
|
+
.repl_history
|
|
19
|
+
build/
|
|
20
|
+
|
|
21
|
+
## Documentation cache and generated files:
|
|
22
|
+
/.yardoc/
|
|
23
|
+
/_yardoc/
|
|
24
|
+
/doc/
|
|
25
|
+
/rdoc/
|
|
26
|
+
|
|
27
|
+
## Environment normalisation:
|
|
28
|
+
/.bundle/
|
|
29
|
+
/lib/bundler/man/
|
|
30
|
+
|
|
31
|
+
# for a library or gem, you might want to ignore these files since the code is
|
|
32
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
33
|
+
# Gemfile.lock
|
|
34
|
+
# .ruby-version
|
|
35
|
+
.ruby-gemset
|
|
36
|
+
|
|
37
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
|
38
|
+
.rvmrc
|
|
39
|
+
|
|
40
|
+
### Mac
|
|
41
|
+
|
|
42
|
+
.DS_Store
|
|
43
|
+
.AppleDouble
|
|
44
|
+
.LSOverride
|
|
45
|
+
|
|
46
|
+
# Icon must end with two \r
|
|
47
|
+
Icon
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# Thumbnails
|
|
51
|
+
._*
|
|
52
|
+
|
|
53
|
+
# Files that might appear on external disk
|
|
54
|
+
.Spotlight-V100
|
|
55
|
+
.Trashes
|
|
56
|
+
|
|
57
|
+
# Directories potentially created on remote AFP share
|
|
58
|
+
.AppleDB
|
|
59
|
+
.AppleDesktop
|
|
60
|
+
Network Trash Folder
|
|
61
|
+
Temporary Items
|
|
62
|
+
.apdisk
|
data/.rspec
ADDED
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.1.3
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: https://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
celluloid (0.15.2)
|
|
5
|
+
timers (~> 1.1.0)
|
|
6
|
+
codeclimate-test-reporter (0.3.0)
|
|
7
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
|
8
|
+
coderay (1.1.0)
|
|
9
|
+
coveralls (0.7.0)
|
|
10
|
+
multi_json (~> 1.3)
|
|
11
|
+
rest-client
|
|
12
|
+
simplecov (>= 0.7)
|
|
13
|
+
term-ansicolor
|
|
14
|
+
thor
|
|
15
|
+
diff-lcs (1.2.5)
|
|
16
|
+
docile (1.1.5)
|
|
17
|
+
ffi (1.9.3)
|
|
18
|
+
formatador (0.2.5)
|
|
19
|
+
guard (2.6.1)
|
|
20
|
+
formatador (>= 0.2.4)
|
|
21
|
+
listen (~> 2.7)
|
|
22
|
+
lumberjack (~> 1.0)
|
|
23
|
+
pry (>= 0.9.12)
|
|
24
|
+
thor (>= 0.18.1)
|
|
25
|
+
guard-rspec (4.2.10)
|
|
26
|
+
guard (~> 2.1)
|
|
27
|
+
rspec (>= 2.14, < 4.0)
|
|
28
|
+
listen (2.7.9)
|
|
29
|
+
celluloid (>= 0.15.2)
|
|
30
|
+
rb-fsevent (>= 0.9.3)
|
|
31
|
+
rb-inotify (>= 0.9)
|
|
32
|
+
lumberjack (1.0.7)
|
|
33
|
+
method_source (0.8.2)
|
|
34
|
+
mime-types (2.3)
|
|
35
|
+
multi_json (1.10.1)
|
|
36
|
+
pry (0.10.0)
|
|
37
|
+
coderay (~> 1.1.0)
|
|
38
|
+
method_source (~> 0.8.1)
|
|
39
|
+
slop (~> 3.4)
|
|
40
|
+
rb-fsevent (0.9.4)
|
|
41
|
+
rb-inotify (0.9.5)
|
|
42
|
+
ffi (>= 0.5.0)
|
|
43
|
+
rest-client (1.6.7)
|
|
44
|
+
mime-types (>= 1.16)
|
|
45
|
+
rspec (3.0.0)
|
|
46
|
+
rspec-core (~> 3.0.0)
|
|
47
|
+
rspec-expectations (~> 3.0.0)
|
|
48
|
+
rspec-mocks (~> 3.0.0)
|
|
49
|
+
rspec-core (3.0.2)
|
|
50
|
+
rspec-support (~> 3.0.0)
|
|
51
|
+
rspec-expectations (3.0.2)
|
|
52
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
53
|
+
rspec-support (~> 3.0.0)
|
|
54
|
+
rspec-mocks (3.0.2)
|
|
55
|
+
rspec-support (~> 3.0.0)
|
|
56
|
+
rspec-support (3.0.2)
|
|
57
|
+
simplecov (0.8.2)
|
|
58
|
+
docile (~> 1.1.0)
|
|
59
|
+
multi_json
|
|
60
|
+
simplecov-html (~> 0.8.0)
|
|
61
|
+
simplecov-html (0.8.0)
|
|
62
|
+
slop (3.5.0)
|
|
63
|
+
term-ansicolor (1.3.0)
|
|
64
|
+
tins (~> 1.0)
|
|
65
|
+
terminal-notifier-guard (1.5.3)
|
|
66
|
+
thor (0.19.1)
|
|
67
|
+
timers (1.1.0)
|
|
68
|
+
tins (1.3.0)
|
|
69
|
+
|
|
70
|
+
PLATFORMS
|
|
71
|
+
ruby
|
|
72
|
+
|
|
73
|
+
DEPENDENCIES
|
|
74
|
+
codeclimate-test-reporter
|
|
75
|
+
coveralls
|
|
76
|
+
guard-rspec
|
|
77
|
+
terminal-notifier-guard
|
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014 HealthWave.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# suds
|
|
2
|
+
|
|
3
|
+
Welcome to the suds project. This is very much a work in progress, so please use this at your own risk. I am changing the DSL constantly and rewriting the history.
|
|
4
|
+
|
|
5
|
+
This project will become stable fairly soon.
|
|
6
|
+
|
|
7
|
+
Suds is a essentially a tool for working with data files. Suds is broken up into three modular components: **interpreters**, **cleaners**, and **converters**.
|
|
8
|
+
|
|
9
|
+
**Interpreters** load the data into the `suds` object. This can be in the form of raw text, json, csv, etc. Interpreteres can be chained together, for instance a (fictional) `GoogleDriveInterpreter` can pass it's data to the `CSVInterpreter`.
|
|
10
|
+
|
|
11
|
+
**Cleaners** manipulate the data. You can modify/remove rows/columns (in the context of a CSV file).
|
|
12
|
+
|
|
13
|
+
**Converters** export the file either to disk or to a remote location.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
Ruby `2.0.x` is tested. If you need support for `1.9.3` use the `1.9.3` branch.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
gem install suds
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Or if you're using Bundler, include the following line in your Gemfile:
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
gem 'suds', git: 'git@github.com:HealthWave/suds.git'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Getting started starting
|
|
34
|
+
|
|
35
|
+
Initialize your interpreter(s):
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
f_interpreter = FileInterpreter.new('./path/to/my/file')
|
|
40
|
+
csv_interpreter = CSVInterpreter.new(f_interpreter.data)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Create a suds list and add the interpreters to it:
|
|
44
|
+
|
|
45
|
+
```ruby
|
|
46
|
+
list = Suds.new( csv_interpreter )
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Add some cleaners to it:
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
list.add_cleaner Cleaner.new {|_,v| v.strip! if v } # Inline initialization of a generic cleaner
|
|
53
|
+
# Configuring an existing cleaner
|
|
54
|
+
list.add_cleaner ColumnConverterCleaner.new({
|
|
55
|
+
company: :name,
|
|
56
|
+
nlacno: :partner_practitioner_id,
|
|
57
|
+
})
|
|
58
|
+
list.add_cleaner ColumnFilterCleaner.new(include_columns: [:name, :partner_practitioner_id, :email])
|
|
59
|
+
list.add_cleaner DowncaseCleaner.new()
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Run all the cleaners:
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
list.clean
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
|
data/lib/suds.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'suds/suds'
|
data/lib/suds/all.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
require 'suds/suds'
|
|
3
|
+
require 'suds/cleaner/column_converter_cleaner'
|
|
4
|
+
require 'suds/cleaner/column_filter_cleaner'
|
|
5
|
+
require 'suds/cleaner/downcase_cleaner'
|
|
6
|
+
require 'suds/cleaner/regex_cleaner'
|
|
7
|
+
require 'suds/cleaner/whitespace_cleaner'
|
|
8
|
+
|
|
9
|
+
require 'suds/interpreter/file_interpreter'
|
|
10
|
+
require 'suds/interpreter/csv_interpreter'
|
|
11
|
+
|
|
12
|
+
require 'suds/converter/json_converter'
|
data/lib/suds/cleaner.rb
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
class Cleaner
|
|
3
|
+
attr_accessor :data, :action
|
|
4
|
+
|
|
5
|
+
def initialize &b
|
|
6
|
+
block_given? ? @action = b : raise("The generic Cleaner must be provided a block.")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.clean_array array, &b
|
|
10
|
+
raise "Please provide either a hash or an array as the main parameter" unless Array === array
|
|
11
|
+
array.each do |row|
|
|
12
|
+
clean_hash row, &b
|
|
13
|
+
end
|
|
14
|
+
return array
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.clean_hash hash, &b
|
|
18
|
+
raise "Please provide either a hash or an array as the main parameter" unless Hash === hash
|
|
19
|
+
|
|
20
|
+
hash.each do |k,v|
|
|
21
|
+
b.call(k,v)
|
|
22
|
+
end
|
|
23
|
+
return hash
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def clean data
|
|
27
|
+
@data = data
|
|
28
|
+
self.class.clean_array(@data) do |k,v|
|
|
29
|
+
@action.call(k,v)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'suds/cleaner'
|
|
2
|
+
|
|
3
|
+
class ColumnConverterCleaner < Cleaner
|
|
4
|
+
def initialize convert_hash, force_strings = false
|
|
5
|
+
@force_strings = force_strings
|
|
6
|
+
@convert_hash = convert_hash
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def clean data
|
|
10
|
+
data.each do |row|
|
|
11
|
+
keys = row.keys
|
|
12
|
+
keys.each do |key|
|
|
13
|
+
if new_key = @convert_hash[key]
|
|
14
|
+
old_value = row[key]
|
|
15
|
+
row.delete key
|
|
16
|
+
if @force_strings
|
|
17
|
+
new_key = new_key.to_s
|
|
18
|
+
else
|
|
19
|
+
new_key = new_key.to_sym
|
|
20
|
+
end
|
|
21
|
+
row[new_key] = old_value
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'suds/cleaner'
|
|
2
|
+
|
|
3
|
+
class ColumnFilterCleaner < Cleaner
|
|
4
|
+
attr_accessor :exclude_columns, :include_columns
|
|
5
|
+
def initialize exclude_columns:[], include_columns:[]
|
|
6
|
+
@exclude_columns = [exclude_columns].flatten.map(&:to_s)
|
|
7
|
+
@include_columns = [include_columns].flatten.map(&:to_s)
|
|
8
|
+
|
|
9
|
+
raise "You must provide include_columns or exclude_columns." if @exclude_columns.empty? and @include_columns.empty?
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def clean data
|
|
13
|
+
if not @include_columns.empty?
|
|
14
|
+
exclude_columns = data.first.keys.map(&:to_s) - @include_columns
|
|
15
|
+
else
|
|
16
|
+
exclude_columns = @exclude_columns
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
data.each do |row|
|
|
20
|
+
exclude_columns.each do |col|
|
|
21
|
+
row.delete col
|
|
22
|
+
row.delete col.to_sym
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'suds/cleaner'
|
|
2
|
+
|
|
3
|
+
class DowncaseCleaner < Cleaner
|
|
4
|
+
def initialize exclude_columns:[], include_columns:[]
|
|
5
|
+
@exclude_columns = [exclude_columns].flatten
|
|
6
|
+
@include_columns = [include_columns].flatten
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def clean data
|
|
10
|
+
Cleaner.clean_array(data) do |k,v|
|
|
11
|
+
next if v.nil?
|
|
12
|
+
if !@include_columns.empty?
|
|
13
|
+
v.downcase if @include_columns.include?(k)
|
|
14
|
+
elsif !@exclude_columns.empty?
|
|
15
|
+
v.downcase! unless @exclude_columns.include?(k)
|
|
16
|
+
else
|
|
17
|
+
v.downcase!
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'suds/cleaner'
|
|
2
|
+
|
|
3
|
+
class RegexCleaner < Cleaner
|
|
4
|
+
attr_accessor :regex_map
|
|
5
|
+
EMAIL_REGEX = /^[a-zA-Z0-9_.+\-]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-.]+$/
|
|
6
|
+
|
|
7
|
+
def initialize regex_map, destroy_row: false
|
|
8
|
+
@regex_map = {}
|
|
9
|
+
regex_map.each do |column,regex|
|
|
10
|
+
if Array === column
|
|
11
|
+
column.each do |col|
|
|
12
|
+
@regex_map[col] = regex
|
|
13
|
+
end
|
|
14
|
+
else
|
|
15
|
+
@regex_map[column] = regex
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
@columns = @regex_map.keys.map(&:to_s)
|
|
19
|
+
@destroy_row = destroy_row
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def clean data
|
|
23
|
+
ret_data = data.select do |row|
|
|
24
|
+
save_row = true
|
|
25
|
+
row.keys.each do |key|
|
|
26
|
+
if @regex_map[key]
|
|
27
|
+
if !(row[key].to_s =~ @regex_map[key])
|
|
28
|
+
if @destroy_row
|
|
29
|
+
save_row = false
|
|
30
|
+
else
|
|
31
|
+
row.delete key
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
save_row # for select
|
|
37
|
+
end
|
|
38
|
+
return ret_data
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
3
|
+
class Converter
|
|
4
|
+
attr_accessor :outfile, :converter, :converted_data
|
|
5
|
+
|
|
6
|
+
def initialize outfile=nil, &b
|
|
7
|
+
@outfile = outfile
|
|
8
|
+
@converter = b
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def convert data
|
|
12
|
+
raise "A generic Converter can only convert with a block" unless @converter
|
|
13
|
+
@converted_data = @converter.call(data)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def convert! data
|
|
17
|
+
raise "Cannot output to file if outfile is not set." unless @outfile
|
|
18
|
+
fname = File.expand_path(@outfile)
|
|
19
|
+
dir = File.dirname fname
|
|
20
|
+
|
|
21
|
+
if !File.directory?(dir)
|
|
22
|
+
FileUtils.mkdir_p dir
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
File.open(fname, 'w').write(convert(data))
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
class Interpreter
|
|
3
|
+
attr_accessor :headers, :data
|
|
4
|
+
|
|
5
|
+
def initialize
|
|
6
|
+
@headers = []
|
|
7
|
+
@data = []
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def interpret
|
|
12
|
+
raise "No interpretation defined."
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def data
|
|
16
|
+
interpret if @data.nil? || @data.empty?
|
|
17
|
+
@data
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'csv'
|
|
2
|
+
require 'suds/interpreter'
|
|
3
|
+
|
|
4
|
+
class CSVInterpreter < Interpreter
|
|
5
|
+
attr_accessor :filepath
|
|
6
|
+
|
|
7
|
+
def initialize raw_data
|
|
8
|
+
@raw_data = raw_data
|
|
9
|
+
super()
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def interpret
|
|
14
|
+
CSV.parse(@raw_data, headers: true, header_converters: :symbol).each do |row|
|
|
15
|
+
@headers = row.headers if @headers.nil? || @headers.empty?
|
|
16
|
+
interpret_unit row
|
|
17
|
+
end
|
|
18
|
+
@data
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def interpret_unit unit
|
|
22
|
+
raise "Headers have not be set." if @headers.empty?
|
|
23
|
+
raise "Invalid data for current headers." if @headers.size != unit.size
|
|
24
|
+
|
|
25
|
+
@data << unit.to_h
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
data/lib/suds/suds.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'suds/interpreter'
|
|
2
|
+
require 'suds/cleaner'
|
|
3
|
+
require 'suds/converter'
|
|
4
|
+
|
|
5
|
+
class Suds
|
|
6
|
+
|
|
7
|
+
attr_accessor :interpreter, :cleaners, :converters, :data
|
|
8
|
+
|
|
9
|
+
def initialize interpreter
|
|
10
|
+
@interpreter = interpreter
|
|
11
|
+
@converters = []
|
|
12
|
+
@cleaners = []
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def add_converter converter
|
|
16
|
+
raise "#{converter.class} is not a valid Converter." unless converter.is_a?(Converter)
|
|
17
|
+
@converters << converter
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def add_cleaner cleaner
|
|
21
|
+
raise "#{cleaner.class} is not a valid Cleaner." unless cleaner.is_a?(Cleaner)
|
|
22
|
+
@cleaners << cleaner
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def clean
|
|
26
|
+
@data = @cleaners.inject(interpreter.data) do |data,cleaner|
|
|
27
|
+
data = cleaner.clean data
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def convert!
|
|
32
|
+
@converters.each { |converter| converter.convert! data}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def convert
|
|
36
|
+
@converters.map { |converter| converter.convert data}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def raw_data
|
|
40
|
+
interpreter.data
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def data
|
|
44
|
+
@data ||= interpreter.interpret
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/suds/version.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'suds/all'
|
|
3
|
+
|
|
4
|
+
describe "all requires" do
|
|
5
|
+
it { JSONConverter }
|
|
6
|
+
it { CSVInterpreter }
|
|
7
|
+
it { FileInterpreter }
|
|
8
|
+
it { ColumnConverterCleaner }
|
|
9
|
+
it { ColumnFilterCleaner }
|
|
10
|
+
it { DowncaseCleaner }
|
|
11
|
+
it { RegexCleaner }
|
|
12
|
+
it { WhitespaceCleaner }
|
|
13
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'suds/cleaner/column_converter_cleaner'
|
|
3
|
+
|
|
4
|
+
describe ColumnConverterCleaner do
|
|
5
|
+
subject { ColumnConverterCleaner }
|
|
6
|
+
let(:convert_hash) { {company: :name} }
|
|
7
|
+
|
|
8
|
+
describe "#initialize" do
|
|
9
|
+
it "takes a hash of strings mapped to strings" do
|
|
10
|
+
subject.new convert_hash
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe "#clean" do
|
|
15
|
+
let(:data) { [{ company: "uri gorelik" }] }
|
|
16
|
+
let(:cleaner) { cleaner = subject.new convert_hash, false }
|
|
17
|
+
it "converts the keys of a hash" do
|
|
18
|
+
results = cleaner.clean data
|
|
19
|
+
expect(results.first.keys - convert_hash.values).to eq []
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'retains the original key type' do
|
|
23
|
+
results = cleaner.clean data
|
|
24
|
+
expect(results.first.keys.first).to be_a(Symbol)
|
|
25
|
+
results = cleaner.clean([{ "company" => "test"}])
|
|
26
|
+
expect(results.first.keys.first).to be_a(String)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'suds/cleaner/column_filter_cleaner'
|
|
3
|
+
|
|
4
|
+
describe ColumnFilterCleaner do
|
|
5
|
+
subject { ColumnFilterCleaner }
|
|
6
|
+
|
|
7
|
+
describe '#initialize' do
|
|
8
|
+
|
|
9
|
+
it 'raises an error if both exclude and include columns are not present or empty' do
|
|
10
|
+
error_reg = /You must provide include_columns or exclude_columns./
|
|
11
|
+
expect{ subject.new }.to raise_error(error_reg)
|
|
12
|
+
expect{ subject.new include_columns: [] }.to raise_error(error_reg)
|
|
13
|
+
expect{ subject.new exclude_columns: [] }.to raise_error(error_reg)
|
|
14
|
+
expect{ subject.new include_columns: [], exclude_columns: [] }.to raise_error(error_reg)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'makes include columns publicly available' do
|
|
18
|
+
cleaner = subject.new include_columns: [{}]
|
|
19
|
+
expect(cleaner).to respond_to(:include_columns)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'makes exclude columns publicly available' do
|
|
23
|
+
cleaner = subject.new exclude_columns: [{}]
|
|
24
|
+
expect(cleaner).to respond_to(:exclude_columns)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe '#clean' do
|
|
29
|
+
let(:data) { [{row1: 'a', row2: 'b'}] }
|
|
30
|
+
let(:original_data) { data.clone }
|
|
31
|
+
|
|
32
|
+
it 'excludes certain columns' do
|
|
33
|
+
cleaner = subject.new exclude_columns: :row2
|
|
34
|
+
result = cleaner.clean data
|
|
35
|
+
expect(result.first.keys).to include(:row1)
|
|
36
|
+
expect(result.first.keys).to_not include(:row2)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'only includes the listed columns' do
|
|
40
|
+
cleaner = subject.new include_columns: :row2
|
|
41
|
+
result = cleaner.clean data
|
|
42
|
+
expect(result.first.keys).to_not include(:row1)
|
|
43
|
+
expect(result.first.keys).to include(:row2)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'accepts both strings and symbol arrays' do
|
|
47
|
+
cleaner = subject.new include_columns: "row2"
|
|
48
|
+
result = cleaner.clean data
|
|
49
|
+
expect(result.first.keys).to_not include(:row1)
|
|
50
|
+
expect(result.first.keys).to include(:row2)
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'cleaner/downcase_cleaner'
|
|
3
|
+
|
|
4
|
+
describe DowncaseCleaner do
|
|
5
|
+
include_context "shared cleaner"
|
|
6
|
+
subject { DowncaseCleaner }
|
|
7
|
+
|
|
8
|
+
let(:data) { {a: " Test", b: "Double test "} }
|
|
9
|
+
# let!(:original_value) { data.first.last.clone }
|
|
10
|
+
|
|
11
|
+
# it "downcases an array of objects" do
|
|
12
|
+
#expect( modified_value ).to match /[^A-Z]/
|
|
13
|
+
# end
|
|
14
|
+
|
|
15
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'suds/cleaner/regex_cleaner'
|
|
3
|
+
|
|
4
|
+
describe RegexCleaner do
|
|
5
|
+
subject { RegexCleaner }
|
|
6
|
+
|
|
7
|
+
context 'constants' do
|
|
8
|
+
it "has a regex constant for emails" do
|
|
9
|
+
expect(subject).to be_const_defined(:EMAIL_REGEX)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
describe "#initialize" do
|
|
15
|
+
it 'accepts a hash that maps column names to regexes' do
|
|
16
|
+
subject.new({name: /uri/})
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'accepts arrays mapped to regular expressions' do
|
|
20
|
+
cleaner = subject.new({[:first_name, :last_name] => /uri/})
|
|
21
|
+
expect(cleaner.instance_variable_get(:@columns)).to eq(%w[first_name last_name])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'accepts a hash that decides whether or not to delete the entire row' do
|
|
25
|
+
subject.new({name: /uri/}, destroy_row: true)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "#clean" do
|
|
30
|
+
let(:bad_data) { [{email: "uri"}] }
|
|
31
|
+
let(:good_data) { [{email: "uri@healthwave.co"}] }
|
|
32
|
+
let(:cleaner) { subject.new({email: subject::EMAIL_REGEX}) }
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
it 'keeps columns if they match the regex' do
|
|
36
|
+
results = cleaner.clean good_data
|
|
37
|
+
expect(results.first.keys).to include(:email)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'removes columns if they do not match the regex' do
|
|
41
|
+
results = cleaner.clean bad_data
|
|
42
|
+
expect(results.first.keys).to_not include(:email)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "destroys rows if the regex doesn't match" do
|
|
46
|
+
cleaner = subject.new({email: subject::EMAIL_REGEX}, destroy_row: true)
|
|
47
|
+
results = cleaner.clean bad_data
|
|
48
|
+
expect(results).to be_empty
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'cleaner/whitespace_cleaner'
|
|
3
|
+
|
|
4
|
+
describe WhitespaceCleaner do
|
|
5
|
+
include_context "shared cleaner"
|
|
6
|
+
subject { WhitespaceCleaner }
|
|
7
|
+
|
|
8
|
+
let(:data) { {a: " Test", b: "Double test "} }
|
|
9
|
+
# let!(:original_value) { data.first.last.clone }
|
|
10
|
+
|
|
11
|
+
# it "downcases an array of objects" do
|
|
12
|
+
#expect( modified_value ).to match /^[^\s].+[^\s]$/
|
|
13
|
+
# end
|
|
14
|
+
|
|
15
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'cleaner'
|
|
3
|
+
|
|
4
|
+
describe Cleaner do
|
|
5
|
+
subject { Cleaner.new(){} }
|
|
6
|
+
|
|
7
|
+
it { expect(Cleaner).to respond_to(:clean_array) }
|
|
8
|
+
it { expect(Cleaner).to respond_to(:clean_hash) }
|
|
9
|
+
|
|
10
|
+
describe "#clean" do
|
|
11
|
+
let(:data) { [{row1: "TEST"}] }
|
|
12
|
+
|
|
13
|
+
it "runs the provided block" do
|
|
14
|
+
cleaner = Cleaner.new() do |_,v|
|
|
15
|
+
v.downcase!
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
result = cleaner.clean data
|
|
19
|
+
expect( result.first.to_a.flatten.last ).to match(/[^A-Z]/)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context "failure" do
|
|
24
|
+
it "raises an error when an non hash or array is passed in as the data" do
|
|
25
|
+
expect {Cleaner.clean_array double("Fake")}.to raise_error(/Please provide either a hash or an array as the main parameter/)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'converter/json_converter'
|
|
3
|
+
|
|
4
|
+
describe JSONConverter do
|
|
5
|
+
subject { JSONConverter }
|
|
6
|
+
let(:unconverted_data) { [{row1: 1, row2:2}] * 5 }
|
|
7
|
+
it "converts an array to json" do
|
|
8
|
+
converter = subject.new(unconverted_data)
|
|
9
|
+
expect( converter.convert(unconverted_data).class ).to be String
|
|
10
|
+
expect( JSON.parse(converter.converted_data, symbolize_names: true) ).to eq unconverted_data
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'converter'
|
|
3
|
+
|
|
4
|
+
describe Converter do
|
|
5
|
+
subject { Converter }
|
|
6
|
+
|
|
7
|
+
describe "#convert!" do
|
|
8
|
+
it "it raises an error if no output file was specified" do
|
|
9
|
+
expect { Converter.new.convert!(double) }.to raise_error(/Cannot output to file if outfile is not set./)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'interpreter/csv_interpreter'
|
|
3
|
+
|
|
4
|
+
describe CSVInterpreter do
|
|
5
|
+
subject {CSVInterpreter.new("path")}
|
|
6
|
+
|
|
7
|
+
describe "#interpret_unit" do
|
|
8
|
+
let(:headers) { %w{foo} }
|
|
9
|
+
let(:row1) { {"foo" => "bar"} }
|
|
10
|
+
let(:csvint) do
|
|
11
|
+
csvint = CSVInterpreter.new("path")
|
|
12
|
+
csvint.headers = headers
|
|
13
|
+
csvint.interpret_unit row1
|
|
14
|
+
csvint
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context 'success' do
|
|
18
|
+
subject { csvint.data }
|
|
19
|
+
|
|
20
|
+
it {expect( subject.size ).to eq 1 }
|
|
21
|
+
|
|
22
|
+
context "data" do
|
|
23
|
+
subject { csvint.data.first }
|
|
24
|
+
it {expect( subject.keys ).to include(*headers) }
|
|
25
|
+
it {expect( subject.values ).to include(*row1.values) }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'failure' do
|
|
30
|
+
subject { csvint }
|
|
31
|
+
let(:csvint) { CSVInterpreter.new("path") }
|
|
32
|
+
|
|
33
|
+
it "raises an error if the headers aren't set" do
|
|
34
|
+
expect{subject.interpret_unit %w{too many values}}.to raise_error(/Headers have not be set./)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "raises an error if the header doesn't match the data" do
|
|
38
|
+
subject.headers = ["row1"]
|
|
39
|
+
expect{subject.interpret_unit %w{too many values}}.to raise_error(/Invalid data for current headers./)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'suds'
|
|
3
|
+
require 'cleaner'
|
|
4
|
+
require 'converter'
|
|
5
|
+
require 'interpreter'
|
|
6
|
+
|
|
7
|
+
describe Suds do
|
|
8
|
+
subject { Suds }
|
|
9
|
+
|
|
10
|
+
describe '#initialize' do
|
|
11
|
+
subject { Suds.new double("Interpreter") }
|
|
12
|
+
it { should respond_to(:data) }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'plugins' do
|
|
16
|
+
let(:list) { subject.new double("Interpreter") }
|
|
17
|
+
|
|
18
|
+
describe '#add_cleaner' do
|
|
19
|
+
it "adds a cleaner" do
|
|
20
|
+
cleaner = Cleaner.new(){}
|
|
21
|
+
list.add_cleaner cleaner
|
|
22
|
+
expect(list.cleaners ).to_not be_empty
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'raises an error if the added cleaner is not a Cleaner' do
|
|
26
|
+
cleaner = double
|
|
27
|
+
expect { list.add_cleaner cleaner }.to raise_error(Regexp.new("#{cleaner.class} is not a valid Cleaner."))
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe '#add_converter' do
|
|
32
|
+
it 'adds a converter' do
|
|
33
|
+
list.add_converter Converter.new([])
|
|
34
|
+
expect( list.converters ).to_not be_empty
|
|
35
|
+
end
|
|
36
|
+
it 'raises an error if the added converter is not a Converter' do
|
|
37
|
+
converter = double
|
|
38
|
+
expect { list.add_converter converter }.to raise_error(Regexp.new("#{converter.class} is not a valid Converter."))
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context 'data manipulation' do
|
|
45
|
+
let(:data) { {row1: :a, row2: :b} }
|
|
46
|
+
|
|
47
|
+
let(:special_converter) do
|
|
48
|
+
converter = double("SpecialConverter")
|
|
49
|
+
allow(converter).to receive(:is_a?).with(Converter).and_return(true)
|
|
50
|
+
allow(converter).to receive(:convert)
|
|
51
|
+
allow(converter).to receive(:convert!)
|
|
52
|
+
allow(converter).to receive(:data).and_return([{a: '1'}])
|
|
53
|
+
converter
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
let(:special_cleaner) do
|
|
57
|
+
cleaner = double("SpecialCleaner")
|
|
58
|
+
allow(cleaner).to receive(:is_a?).with(Cleaner).and_return(true)
|
|
59
|
+
allow(cleaner).to receive(:clean).and_return({z: "9"})
|
|
60
|
+
cleaner
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
let(:special_interpreter) do
|
|
64
|
+
interpreter = double("SpecialInterpreter")
|
|
65
|
+
allow(interpreter).to receive(:is_a?).with(Interpreter).and_return(true)
|
|
66
|
+
allow(interpreter).to receive(:interpret)
|
|
67
|
+
allow(interpreter).to receive(:data).and_return(data)
|
|
68
|
+
interpreter
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe '#clean' do
|
|
72
|
+
let(:list) { Suds.new(special_interpreter) }
|
|
73
|
+
before do
|
|
74
|
+
list.add_cleaner(special_cleaner)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'cleans the data' do
|
|
78
|
+
expect( special_cleaner ).to receive(:clean)
|
|
79
|
+
list.clean
|
|
80
|
+
expect( list.interpreter.data ).to_not eq( list.data )
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe '#convert' do
|
|
86
|
+
let(:list) { Suds.new(special_interpreter) }
|
|
87
|
+
before do
|
|
88
|
+
list.add_converter special_converter
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it 'converts the data into a portable type' do
|
|
92
|
+
expect( special_converter ).to receive(:convert)
|
|
93
|
+
list.convert
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it 'can convert without cleaning first' do
|
|
97
|
+
allow( special_interpreter ).to receive(:interpret).and_return([])
|
|
98
|
+
list.convert
|
|
99
|
+
expect( list.data ).to_not be_nil
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it 'returns a list of strings' do
|
|
103
|
+
allow( special_converter ).to receive(:convert).and_return("converted data")
|
|
104
|
+
convert = list.convert
|
|
105
|
+
expect( convert ).to be_an( Array )
|
|
106
|
+
expect( convert.first ).to be_a( String )
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe '#convert!' do
|
|
111
|
+
it 'writes out the data to a file' do
|
|
112
|
+
expect( special_converter ).to receive(:convert!)
|
|
113
|
+
|
|
114
|
+
list = Suds.new(special_interpreter)
|
|
115
|
+
list.add_converter special_converter
|
|
116
|
+
list.convert!
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
|
3
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause this
|
|
4
|
+
# file to always be loaded, without a need to explicitly require it in any files.
|
|
5
|
+
#
|
|
6
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
|
7
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
|
8
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
|
9
|
+
# individual file that may not need all of that loaded. Instead, make a
|
|
10
|
+
# separate helper file that requires this one and then use it only in the specs
|
|
11
|
+
# that actually need it.
|
|
12
|
+
#
|
|
13
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
|
14
|
+
# users commonly want.
|
|
15
|
+
#
|
|
16
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
|
17
|
+
|
|
18
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__), *%w{.. lib/suds})
|
|
19
|
+
require 'coveralls'
|
|
20
|
+
require "codeclimate-test-reporter"
|
|
21
|
+
CodeClimate::TestReporter.start
|
|
22
|
+
Coveralls.wear!
|
|
23
|
+
|
|
24
|
+
Dir["./spec/support/**/*.rb"].sort.each { |f| require f}
|
|
25
|
+
|
|
26
|
+
RSpec.configure do |config|
|
|
27
|
+
# The settings below are suggested to provide a good initial experience
|
|
28
|
+
# with RSpec, but feel free to customize to your heart's content.
|
|
29
|
+
=begin
|
|
30
|
+
# These two settings work together to allow you to limit a spec run
|
|
31
|
+
# to individual examples or groups you care about by tagging them with
|
|
32
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
|
33
|
+
# get run.
|
|
34
|
+
config.filter_run :focus
|
|
35
|
+
config.run_all_when_everything_filtered = true
|
|
36
|
+
|
|
37
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
|
38
|
+
# file, and it's useful to allow more verbose output when running an
|
|
39
|
+
# individual spec file.
|
|
40
|
+
if config.files_to_run.one?
|
|
41
|
+
# Use the documentation formatter for detailed output,
|
|
42
|
+
# unless a formatter has already been configured
|
|
43
|
+
# (e.g. via a command-line flag).
|
|
44
|
+
config.default_formatter = 'doc'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Print the 10 slowest examples and example groups at the
|
|
48
|
+
# end of the spec run, to help surface which specs are running
|
|
49
|
+
# particularly slow.
|
|
50
|
+
config.profile_examples = 10
|
|
51
|
+
|
|
52
|
+
# Run specs in random order to surface order dependencies. If you find an
|
|
53
|
+
# order dependency and want to debug it, you can fix the order by providing
|
|
54
|
+
# the seed, which is printed after each run.
|
|
55
|
+
# --seed 1234
|
|
56
|
+
config.order = :random
|
|
57
|
+
|
|
58
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
|
59
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
|
60
|
+
# test failures related to randomization by passing the same `--seed` value
|
|
61
|
+
# as the one that triggered the failure.
|
|
62
|
+
Kernel.srand config.seed
|
|
63
|
+
|
|
64
|
+
# rspec-expectations config goes here. You can use an alternate
|
|
65
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
|
66
|
+
# assertions if you prefer.
|
|
67
|
+
config.expect_with :rspec do |expectations|
|
|
68
|
+
# Enable only the newer, non-monkey-patching expect syntax.
|
|
69
|
+
# For more details, see:
|
|
70
|
+
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
|
71
|
+
expectations.syntax = :expect
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
|
75
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
|
76
|
+
config.mock_with :rspec do |mocks|
|
|
77
|
+
# Enable only the newer, non-monkey-patching expect syntax.
|
|
78
|
+
# For more details, see:
|
|
79
|
+
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
|
80
|
+
mocks.syntax = :expect
|
|
81
|
+
|
|
82
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
|
83
|
+
# a real object. This is generally recommended.
|
|
84
|
+
mocks.verify_partial_doubles = true
|
|
85
|
+
end
|
|
86
|
+
=end
|
|
87
|
+
end
|
data/suds.gemspec
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
2
|
+
require 'suds/version'
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |s|
|
|
5
|
+
s.name = 'suds'
|
|
6
|
+
s.version = Suds::VERSION
|
|
7
|
+
s.licenses = ['MIT']
|
|
8
|
+
s.summary = "Interpret, clean, and convert lists."
|
|
9
|
+
s.description = "Suds is a versatile list manipulation library/dsl. It's meant to interpret various difference formats, apply mutations, and then export to various formats."
|
|
10
|
+
s.authors = ["Uri Gorelik"]
|
|
11
|
+
s.email = 'uri@healthwave.co'
|
|
12
|
+
s.files = `git ls-files`.split("\n")
|
|
13
|
+
s.homepage = 'https://healthwave.co/'
|
|
14
|
+
s.require_paths = ["lib"]
|
|
15
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: suds
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Uri Gorelik
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-10-27 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Suds is a versatile list manipulation library/dsl. It's meant to interpret
|
|
14
|
+
various difference formats, apply mutations, and then export to various formats.
|
|
15
|
+
email: uri@healthwave.co
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- ".coveralls.yml"
|
|
21
|
+
- ".gitignore"
|
|
22
|
+
- ".rspec"
|
|
23
|
+
- ".ruby-version"
|
|
24
|
+
- Gemfile
|
|
25
|
+
- Gemfile.lock
|
|
26
|
+
- Guardfile
|
|
27
|
+
- LICENSE.txt
|
|
28
|
+
- README.md
|
|
29
|
+
- lib/suds.rb
|
|
30
|
+
- lib/suds/all.rb
|
|
31
|
+
- lib/suds/cleaner.rb
|
|
32
|
+
- lib/suds/cleaner/column_converter_cleaner.rb
|
|
33
|
+
- lib/suds/cleaner/column_filter_cleaner.rb
|
|
34
|
+
- lib/suds/cleaner/downcase_cleaner.rb
|
|
35
|
+
- lib/suds/cleaner/regex_cleaner.rb
|
|
36
|
+
- lib/suds/cleaner/whitespace_cleaner.rb
|
|
37
|
+
- lib/suds/converter.rb
|
|
38
|
+
- lib/suds/converter/json_converter.rb
|
|
39
|
+
- lib/suds/interpreter.rb
|
|
40
|
+
- lib/suds/interpreter/csv_interpreter.rb
|
|
41
|
+
- lib/suds/interpreter/file_interpreter.rb
|
|
42
|
+
- lib/suds/suds.rb
|
|
43
|
+
- lib/suds/version.rb
|
|
44
|
+
- spec/lib/suds/all_spec.rb
|
|
45
|
+
- spec/lib/suds/cleaner/column_converter_cleaner_spec.rb
|
|
46
|
+
- spec/lib/suds/cleaner/column_filter_cleaner_spec.rb
|
|
47
|
+
- spec/lib/suds/cleaner/downcase_cleaner_spec.rb
|
|
48
|
+
- spec/lib/suds/cleaner/regex_cleaner_spec.rb
|
|
49
|
+
- spec/lib/suds/cleaner/whitespace_cleaner_spec.rb
|
|
50
|
+
- spec/lib/suds/cleaner_spec.rb
|
|
51
|
+
- spec/lib/suds/converter/json_converter_spec.rb
|
|
52
|
+
- spec/lib/suds/converter_spec.rb
|
|
53
|
+
- spec/lib/suds/interpreter/csv_interpreter_spec.rb
|
|
54
|
+
- spec/lib/suds/interpreter_spec.rb
|
|
55
|
+
- spec/lib/suds/suds_spec.rb
|
|
56
|
+
- spec/spec_helper.rb
|
|
57
|
+
- spec/support/cleaner_context.rb
|
|
58
|
+
- suds.gemspec
|
|
59
|
+
homepage: https://healthwave.co/
|
|
60
|
+
licenses:
|
|
61
|
+
- MIT
|
|
62
|
+
metadata: {}
|
|
63
|
+
post_install_message:
|
|
64
|
+
rdoc_options: []
|
|
65
|
+
require_paths:
|
|
66
|
+
- lib
|
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
68
|
+
requirements:
|
|
69
|
+
- - ">="
|
|
70
|
+
- !ruby/object:Gem::Version
|
|
71
|
+
version: '0'
|
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - ">="
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '0'
|
|
77
|
+
requirements: []
|
|
78
|
+
rubyforge_project:
|
|
79
|
+
rubygems_version: 2.2.2
|
|
80
|
+
signing_key:
|
|
81
|
+
specification_version: 4
|
|
82
|
+
summary: Interpret, clean, and convert lists.
|
|
83
|
+
test_files: []
|