strata 0.0.1

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.
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in strata.gemspec
4
+ gemspec
5
+
6
+ gem 'rspec'
@@ -0,0 +1,31 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ strata (0.0.1)
5
+ activesupport
6
+ i18n
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ activesupport (3.2.2)
12
+ i18n (~> 0.6)
13
+ multi_json (~> 1.0)
14
+ diff-lcs (1.1.3)
15
+ i18n (0.6.0)
16
+ multi_json (1.1.0)
17
+ rspec (2.8.0)
18
+ rspec-core (~> 2.8.0)
19
+ rspec-expectations (~> 2.8.0)
20
+ rspec-mocks (~> 2.8.0)
21
+ rspec-core (2.8.0)
22
+ rspec-expectations (2.8.0)
23
+ diff-lcs (~> 1.1.2)
24
+ rspec-mocks (2.8.0)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ rspec
31
+ strata!
data/README ADDED
@@ -0,0 +1 @@
1
+ A gem for defining string-based records.
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ # If you want to make this the default task
7
+ task :default => :spec
@@ -0,0 +1,9 @@
1
+ require "strata/version"
2
+ require "active_support/core_ext/string"
3
+ require "yaml"
4
+
5
+ module Strata
6
+ CONFIG_DIR = File.expand_path(File.dirname(__FILE__)) + "/config"
7
+ end
8
+
9
+ require 'strata/record_writer'
@@ -0,0 +1,199 @@
1
+ module Strata
2
+ module RecordWriter
3
+
4
+ def layout_rules
5
+ @layout_rules ||= self.class.class_layout_rules
6
+ end
7
+
8
+ def exposed_rules
9
+ layout_rules.select {|key, rule| !(rule["expose"] == false && rule.has_key?("expose")) }
10
+ end
11
+
12
+ def filler_rules
13
+ @filler_rules ||= self.class.filler_layout_rules
14
+ end
15
+
16
+ def set_layout_variables(options = {})
17
+ self.class.define_attribute_accessors
18
+
19
+ options.each do |k,v|
20
+ raise "#{k}: Argument is not a string" unless v.is_a? String
21
+ self.class.send :attr_accessor, k
22
+ self.send "#{k}=", v.upcase
23
+ end
24
+
25
+ layout_rules.each do |k,v|
26
+ self.class.send(:attr_accessor, k) unless (v["expose"] && v["expose"] == false)
27
+ # self.send "#{k}=", v['fixed_val'] if v.has_key? ""
28
+ end
29
+ end
30
+
31
+ def set_filler(string)
32
+ filler_rules.each do |key, value|
33
+ string[(value["offset"] - 1), value["length"]] = value["fixed_val"]
34
+ end
35
+
36
+ return string
37
+ end
38
+
39
+ def record_length
40
+ self.class.class_variable_get(:@@record_length) || 0
41
+ end
42
+
43
+ def record_delimiter
44
+ self.class.class_variable_get(:@@record_delimiter) || ""
45
+ end
46
+
47
+ def allowed_characters
48
+ if self.class.class_variable_defined?(:@@record_allowed_characters)
49
+ self.class.class_variable_get(:@@record_allowed_characters)
50
+ end
51
+ end
52
+
53
+ def to_s
54
+ @string = " " * record_length + record_delimiter
55
+ @string = set_filler(@string)
56
+
57
+ @string = "#{@string}"
58
+
59
+ self.exposed_rules.each do |field_name,rule|
60
+ value = self.send(field_name) || ""
61
+
62
+ value = value.rjust(rule['length'], "0") if rule['data_type'] == 'N'
63
+ value = value.ljust(rule['length'], " ") if rule['data_type'] == 'A'
64
+
65
+ offset = rule['offset'] - 1
66
+ length = rule['length']
67
+
68
+ @string[(offset), length] = value
69
+ end
70
+
71
+ @string
72
+ end
73
+
74
+ def valid_characters(string)
75
+ return true unless allowed_characters
76
+ string.each_char.all? {|c| allowed_characters.include?(c)}
77
+ end
78
+
79
+ def validate_field(field_name, field_value)
80
+ if field_name != :user_ref
81
+ raise "#{field_name}: Invalid character used in #{field_value}" unless valid_characters(field_value)
82
+ end
83
+
84
+ raise "#{field_name}: Argument is not a string" unless field_value.is_a? String
85
+ end
86
+
87
+ def validate!(options)
88
+ options.each do |k,v|
89
+ rule = layout_rules[k.to_s]
90
+
91
+ validate_field(k, v)
92
+ raise "#{k}: Input too long" if v.length > rule['length']
93
+ raise "#{k}: Invalid data" if rule['regex'] && ((v =~ /#{rule['regex']}/) != 0)
94
+ raise "#{k}: Invalid data - expected #{rule['fixed_val']}, got #{v}" if rule['fixed_val'] && (v != rule['fixed_val'])
95
+ raise "#{k}: Numeric value required" if (rule['data_type'] == 'N') && !(Float(v) rescue false)
96
+ end
97
+ end
98
+
99
+ module ClassMethods
100
+
101
+ def set_record_length(length)
102
+ class_variable_set(:@@record_length, length)
103
+ end
104
+
105
+ def set_delimiter(delimiter)
106
+ class_variable_set(:@@record_delimiter, delimiter)
107
+ end
108
+
109
+ def set_allowed_characters(chars)
110
+ class_variable_set(:@@record_allowed_characters, chars)
111
+ end
112
+
113
+ # TODO: remove this method or require config path to be specified OR.. make it redundant by refactoring behind an add_rule method
114
+ def class_layout_rules
115
+ file_name = "#{Absa::H2h::CONFIG_DIR}/#{self.name.split("::")[-2].underscore}.yml"
116
+ record_type = self.name.split("::")[-1].underscore
117
+
118
+ YAML.load(File.open(file_name))[record_type]
119
+ end
120
+
121
+ def exposed_class_layout_rules
122
+ self.class_layout_rules.select {|key, rule| !(rule["expose"] == false && rule.has_key?("expose")) }
123
+ end
124
+
125
+ def filler_layout_rules
126
+ class_layout_rules.select {|key, rule| rule.has_key?("expose") && rule["expose"] == false && rule.has_key?("fixed_val")}
127
+ end
128
+
129
+ def define_attribute_accessors
130
+ self.class_layout_rules.each do |k,v|
131
+ (class << self; self; end).send :attr_accessor, k
132
+ self.send :attr_accessor, k
133
+ end
134
+ end
135
+
136
+ def template_options
137
+ hash = {}
138
+
139
+ self.exposed_class_layout_rules.each do |field, rule|
140
+ value = rule.has_key?('fixed_val') ? rule['fixed_val'] : nil
141
+
142
+ if value
143
+ value = value.rjust(rule['length'], "0") if rule['data_type'] == 'N'
144
+ value = value.ljust(rule['length'], " ") if rule['data_type'] == 'A'
145
+ end
146
+
147
+ hash[field.to_sym] = value
148
+ end
149
+
150
+ hash
151
+ end
152
+
153
+ def retrieve_field_value(string, field, rule)
154
+ offset = rule['offset'] - 1
155
+ length = rule['length']
156
+ field_type = rule['data_type']
157
+
158
+ value = string[offset, length]
159
+
160
+ unless rule['fixed_val'] || rule['no_strip']
161
+ value = value.rstrip if field_type == 'A'
162
+ value = value.to_i.to_s if field_type == 'N'
163
+ end
164
+
165
+ value
166
+ end
167
+
168
+ def matches_definition?(string)
169
+ self.class_layout_rules.each do |field, rule|
170
+ regex = rule['regex']
171
+ fixed_val = rule['fixed_val']
172
+ value = self.retrieve_field_value(string, field, rule)
173
+
174
+ return false if fixed_val and value != fixed_val
175
+ return false if regex and not value =~ /#{regex}/
176
+ end
177
+
178
+ true
179
+ end
180
+
181
+ def string_to_hash(string)
182
+ hash = {}
183
+
184
+ self.exposed_class_layout_rules.each do |field, rule|
185
+ hash[field.to_sym] = self.retrieve_field_value(string, field, rule)
186
+ end
187
+
188
+ hash
189
+ end
190
+
191
+ def from_s(string)
192
+ options = self.string_to_hash(string)
193
+ record = self.new(options)
194
+ end
195
+
196
+ end
197
+
198
+ end
199
+ end
@@ -0,0 +1,3 @@
1
+ module Strata
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe Strata::RecordWriter do
4
+
5
+ it "should allow the record length to be specified" do
6
+
7
+ class String
8
+ include Strata::RecordWriter
9
+ extend Strata::RecordWriter::ClassMethods
10
+
11
+ set_record_length 200
12
+ end
13
+
14
+ string = "test1234"
15
+ string.record_length.should == 200
16
+ end
17
+
18
+ it "should not validate characters if no character set was specified" do
19
+ class String
20
+ include Strata::RecordWriter
21
+ extend Strata::RecordWriter::ClassMethods
22
+
23
+ set_record_length 200
24
+
25
+ string = "test1234"
26
+ string.valid_characters("ADAWVDAWVGr#&^ @").should == true
27
+ end
28
+ end
29
+
30
+ it "should validate that a record contains only valid characters" do
31
+ class String
32
+ include Strata::RecordWriter
33
+ extend Strata::RecordWriter::ClassMethods
34
+
35
+ set_record_length 200
36
+ set_allowed_characters ('A'..'Z').to_a
37
+
38
+ string = "test1234"
39
+ string.valid_characters("ADAWVDAWVGR").should == true
40
+ string.valid_characters("ADAWVDAWVGr").should == false
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'strata'
5
+
6
+ RSpec.configure do |config|
7
+ # some (optional) config here
8
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "strata/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "strata"
7
+ s.version = Strata::VERSION
8
+ s.authors = ["Douglas Anderson", "Jeffrey van Aswegen"]
9
+ s.email = ["i.am.douglas.anderson@gmail.com, jeffmess@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{A gem for manipulating string-based records.}
12
+ s.description = %q{A gem for manipulating string-based records.}
13
+
14
+ s.rubyforge_project = "strata"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency "activesupport"
22
+ s.add_dependency "i18n"
23
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: strata
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Douglas Anderson
9
+ - Jeffrey van Aswegen
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-04-04 00:00:00.000000000Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ requirement: &70149324763260 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *70149324763260
26
+ - !ruby/object:Gem::Dependency
27
+ name: i18n
28
+ requirement: &70149324762840 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *70149324762840
37
+ description: A gem for manipulating string-based records.
38
+ email:
39
+ - i.am.douglas.anderson@gmail.com, jeffmess@gmail.com
40
+ executables: []
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - Gemfile
45
+ - Gemfile.lock
46
+ - README
47
+ - Rakefile
48
+ - lib/strata.rb
49
+ - lib/strata/record_writer.rb
50
+ - lib/strata/version.rb
51
+ - spec/lib/record_writer_spec.rb
52
+ - spec/spec_helper.rb
53
+ - strata.gemspec
54
+ homepage: ''
55
+ licenses: []
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project: strata
74
+ rubygems_version: 1.8.6
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: A gem for manipulating string-based records.
78
+ test_files:
79
+ - spec/lib/record_writer_spec.rb
80
+ - spec/spec_helper.rb