dataview 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.
data/README ADDED
@@ -0,0 +1,58 @@
1
+ Data View is copyrighted free software by Brian Takita <brian.takita@gmail.com>.
2
+ You can redistribute it and/or modify it under either the terms of the GPL, or the conditions below:
3
+
4
+ 1. You may make and give away verbatim copies of the source form of the
5
+ software without restriction, provided that you duplicate all of the
6
+ original copyright notices and associated disclaimers.
7
+
8
+ 2. You may modify your copy of the software in any way, provided that
9
+ you do at least ONE of the following:
10
+
11
+ a) place your modifications in the Public Domain or otherwise
12
+ make them Freely Available, such as by posting said
13
+ modifications to Usenet or an equivalent medium, or by allowing
14
+ the author to include your modifications in the software.
15
+
16
+ b) use the modified software only within your corporation or
17
+ organization.
18
+
19
+ c) rename any non-standard executables so the names do not conflict
20
+ with standard executables, which must also be provided.
21
+
22
+ d) make other distribution arrangements with the author.
23
+
24
+ 3. You may distribute the software in object code or executable
25
+ form, provided that you do at least ONE of the following:
26
+
27
+ a) distribute the executables and library files of the software,
28
+ together with instructions (in the manual page or equivalent)
29
+ on where to get the original distribution.
30
+
31
+ b) accompany the distribution with the machine-readable source of
32
+ the software.
33
+
34
+ c) give non-standard executables non-standard names, with
35
+ instructions on where to get the original software distribution.
36
+
37
+ d) make other distribution arrangements with the author.
38
+
39
+ 4. You may modify and include the part of the software into any other
40
+ software (possibly commercial). But some files in the distribution
41
+ are not written by the author, so that they are not under this terms.
42
+
43
+ They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
44
+ files under the ./missing directory. See each file for the copying
45
+ condition.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
57
+
58
+
data/lib/data_view.rb ADDED
@@ -0,0 +1,158 @@
1
+ module DataView
2
+
3
+ # DataView is intended to reduce coupling between the Controller and View layers in a MVC application. The Controller can send a DataView to the View layer. The View layer does not need to have access to the Model.
4
+ class DataView
5
+ class Row
6
+ public
7
+ include Enumerable
8
+ attr_accessor :data_view
9
+ def initialize(data_view, values = [])
10
+ @data_view = data_view
11
+ @values = values
12
+ end
13
+ def [](key)
14
+ return @values[get_index(key)]
15
+ end
16
+ def []=(key, value)
17
+ @values[get_index(key)] = value
18
+ end
19
+ def each
20
+ @values.each_with_index do |v, i|
21
+ yield(data_view.fields[i], v)
22
+ end
23
+ end
24
+ def length
25
+ @values.length
26
+ end
27
+ private
28
+ def get_index(key)
29
+ return data_view.fields.index(key) if data_view.fields.include?(key)
30
+ raise 'key must either be an array index integer or a field key' unless key.respond_to?(:to_i)
31
+ return key
32
+ end
33
+ end
34
+ public
35
+ include Enumerable
36
+ attr_reader :fields, :titles, :delegates
37
+ # Initializes the DataView.
38
+ # ===Model
39
+ # The DataView supports a model that contains an array of hashes. The keys in these hashes much be symbols of the field names. This is based off of the ActiveRecord interface.
40
+ # ===Params
41
+ # Params is a symbol keyed Hash of parameters to be passed.
42
+ # ====:fields
43
+ # An array of the fields, on order, that will be used from the model. A field value should be a Symbol or a Proc that accepts the @model and row_index and returns the value to access the value.
44
+ # ====:titles
45
+ # A Hash of the titles for the fields. The field symbol is the key, and the title is the value.
46
+ # ====:values
47
+ # A hash of Procs that get nondefault values of a field in a particular row. By default, the value is taken by looking at the field in the model. The Proc must accept a Hash of parameters and return the transformed value. The Hash contains the following keys:
48
+ # * :sender - The DataView sending the call
49
+ # * :row_index - The Index of the current row.
50
+ # * :column_index - The Index of the current column.
51
+ # * :field - The field of the current value.
52
+ # ====:value_transforms
53
+ # A Hash of the delegates that will process the values. The field symbol is the key, and the Proc or array of Procs to transform the value. The Proc must accept a Hash of parameters and return the transformed value. The Hash contains the following keys:
54
+ # * :sender - The DataView sending the call
55
+ # * :row_index - The Index of the current row.
56
+ # * :column_index - The Index of the current column.
57
+ # * :value - The current value.
58
+ # * :field - The field of the current value.
59
+ def initialize(model, params = {})
60
+ @model = model.respond_to?(:each_index) ? model : [model]
61
+
62
+ # @fields is an ordered array of the fields that will be shown
63
+ @fields = get_param_value(params, :fields)
64
+ @fields = Array.new() if @fields == nil
65
+
66
+ # @titles is a hash with the field as the key and the title as the value
67
+ @titles = get_param_value(params, :titles)
68
+ @titles = Hash.new() if @titles == nil
69
+
70
+ # @values is a hash of Procs that get nondefault values of a field in a particular row. By default, the value is taken by looking at the field in the model.
71
+ @values = get_param_value(params, :values)
72
+ @values = Hash.new() if @values == nil
73
+
74
+ # @value_transforms is a hash with the field as the key and a Proc or array of procs that transforms the value into the proper format as the value
75
+ # The Proc that is the value must accept a hash that has the following keys:
76
+ # :sender, :row_index, :column_index, :value, :field
77
+ value_transforms = get_param_value(params, :value_transforms)
78
+ value_transforms = Hash.new() if value_transforms == nil
79
+ @value_transforms = format_value_transforms(value_transforms)
80
+ end
81
+ # Gets a particular row of the view.
82
+ def [](index)
83
+ get_view_row(index)
84
+ end
85
+ # The number of rows in the result.
86
+ def length
87
+ @model.length
88
+ end
89
+ # Iterates through each row of the view.
90
+ def each
91
+ @model.each_index do |row_index|
92
+ yield(get_view_row(row_index))
93
+ end
94
+ end
95
+ # Iterates through each title of the fields.
96
+ def each_title
97
+ @fields.each do |field|
98
+ if @titles.include?(field)
99
+ yield(field, @titles[field])
100
+ else
101
+ yield(field, nil)
102
+ end
103
+ end
104
+ end
105
+ # Iterates through each title of the fields with the index.
106
+ def each_title_with_index
107
+ i = 0
108
+ each_title do |f, t|
109
+ yield(f, t, i)
110
+ i = i + 1
111
+ end
112
+ end
113
+ private
114
+ def get_view_row(row_index)
115
+ model_row = @model[row_index]
116
+ view_row_values = []
117
+ @fields.each_with_index do |field, field_index|
118
+ if @values.include?(field)
119
+ actual_value = @values[field].call(@model, row_index, field)
120
+ else
121
+ actual_value = model_row[field]
122
+ end
123
+ view_value = actual_value
124
+
125
+ if @value_transforms.include?(field)
126
+ delegate_value = actual_value
127
+ @value_transforms[field].each do |delegate|
128
+ delegate_params = {
129
+ :sender => self,
130
+ :row_index => row_index,
131
+ :column_index => field_index,
132
+ :value => delegate_value,
133
+ :field => field
134
+ }
135
+ delegate_value = delegate.call(delegate_params)
136
+ end
137
+ view_value = delegate_value
138
+ end
139
+ view_row_values << view_value
140
+ end
141
+ Row.new(self, view_row_values)
142
+ end
143
+ def get_param_value(param, key)
144
+ return nil if param == nil
145
+ return param[key]
146
+ end
147
+ def format_value_transforms(delegates)
148
+ delegates.each do |k, *items|
149
+ delegates[k] = items.flatten
150
+ delegates[k].each do |d|
151
+ raise ":delegate must respond to call" unless d.respond_to?(:call)
152
+ end
153
+ end
154
+ delegates
155
+ end
156
+ end
157
+
158
+ end
data/lib/dataview.rb ADDED
@@ -0,0 +1 @@
1
+ require 'data_view'
@@ -0,0 +1,138 @@
1
+ this_dir = File.dirname(__FILE__)
2
+ require this_dir << '/../lib/data_view'
3
+ require 'test/unit'
4
+
5
+ class DataViewTest < Test::Unit::TestCase
6
+ include DataView
7
+ public
8
+ def test_brackets
9
+ do_test_brackets(mock_model)
10
+ do_test_brackets(singular_mock_model)
11
+ end
12
+ def test_each
13
+ do_test_each(mock_model)
14
+ do_test_each(singular_mock_model)
15
+ end
16
+ def test_each_title
17
+ do_test_each_title(mock_model)
18
+ do_test_each_title(singular_mock_model)
19
+ end
20
+ def test_each_title_with_index
21
+ do_test_each_title_with_index(mock_model)
22
+ do_test_each_title_with_index(singular_mock_model)
23
+ end
24
+ def test_length
25
+ assert_equal(mock_model.length, get_data_view(mock_model).length)
26
+ assert_equal(1, get_data_view(singular_mock_model).length)
27
+ end
28
+ private
29
+ def do_test_brackets(model)
30
+ data_view = get_data_view(model)
31
+
32
+ test_model = model.respond_to?(:each_index) ? model : [model]
33
+ test_model.each_with_index do |r, i|
34
+ fields.each_with_index do |f, j|
35
+ v = (f == :model_value_field) ? get_model_value(model, i, f) : r[f]
36
+ assert_equal(expected_altered_value(v), data_view[i][f])
37
+ end
38
+ end
39
+ end
40
+ def do_test_each(model)
41
+ data_view = get_data_view(model)
42
+ data_view.each_with_index do |row, i|
43
+ expected_row = model.respond_to?(:each_index) ? model[i] : model
44
+ assert_equal(expected_row.length, row.to_a.length)
45
+
46
+ expected_row.each do |k, expected_value|
47
+ expected_value = get_model_value(model, i, k) if k == :model_value_field
48
+ assert_equal(expected_altered_value(expected_value), row[k])
49
+ end
50
+ end
51
+ end
52
+ def do_test_each_title(model)
53
+ data_view = get_data_view(model)
54
+ i = 0
55
+ data_view.each_title do |f, t|
56
+ assert_equal(titles[f], t)
57
+ i = i + 1
58
+ end
59
+ end
60
+ def do_test_each_title_with_index(model)
61
+ data_view = get_data_view(model)
62
+ ei = 0
63
+ data_view.each_title_with_index do |f, t, i|
64
+ assert_equal(titles[fields[ei]], t)
65
+ assert_equal(ei, i)
66
+ ei = ei + 1
67
+ end
68
+ end
69
+ def expected_altered_value(v)
70
+ "altered " << v
71
+ end
72
+ def get_data_view(model)
73
+ DataView.new(
74
+ model,
75
+ :fields => fields,
76
+ :titles => titles,
77
+ :values => values,
78
+ :value_transforms => value_transforms
79
+ )
80
+ end
81
+ def get_model_value_method
82
+ return @get_model_value_method if defined?(@get_model_value_method)
83
+ @get_model_value_method = method(:get_model_value)
84
+ end
85
+ def get_model_value(model, row_index, field)
86
+ row_index.to_s << ' : Custom ' << field.to_s
87
+ end
88
+ def fields
89
+ return @fields if defined?(@fields)
90
+ @fields = [:model_value_field , :field1, :field2, :field3]
91
+ end
92
+ def titles
93
+ return @titles if defined?(@titles)
94
+ t = Hash.new()
95
+ fields.each do |f|
96
+ t[f] = f.to_s << ' Title'
97
+ end
98
+ @titles = t
99
+ end
100
+ def singular_mock_model
101
+ return @singular_mock_model if defined?(@singular_mock_model)
102
+ @singular_mock_model = get_mock_model_row(0)
103
+ end
104
+ def mock_model
105
+ return @mock_model if defined?(@mock_model)
106
+ m = Array.new
107
+ (0..2).each do |i|
108
+ row = get_mock_model_row(i)
109
+ m << row
110
+ end
111
+ @mock_model = m
112
+ end
113
+ def get_mock_model_row(i)
114
+ row = Hash.new
115
+ fields.each do |f|
116
+ next if f.respond_to?(:call)
117
+ row[f] = i.to_s << ' : ' << f.to_s
118
+ end
119
+ row
120
+ end
121
+ def values
122
+ return @values if defined?(@values)
123
+ v = Hash.new
124
+ v[:model_value_field] = get_model_value_method
125
+ @values = v
126
+ end
127
+ def value_transforms
128
+ return @value_transforms if defined?(@value_transforms)
129
+ t = Hash.new()
130
+ fields.each do |f|
131
+ t[f] = lambda { |h|
132
+ 'altered ' << h[:value].to_s
133
+ }
134
+ end
135
+ @value_transforms = t
136
+ end
137
+ end
138
+
@@ -0,0 +1,2 @@
1
+ this_dir = File.dirname(__FILE__)
2
+ require this_dir << '/tc_data_view'
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: dataview
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2005-07-25 00:00:00 -07:00
8
+ summary: Data View is a library that creates a view of a data model. The view can transform the data of the data model without changing the data. Supports ActiveRecord models and other data models that have a similar interface.
9
+ require_paths:
10
+ - lib
11
+ email: brian.takita@gmail.com
12
+ homepage: http://DataView.rubyforge.org
13
+ rubyforge_project:
14
+ description:
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ signing_key:
28
+ cert_chain:
29
+ authors:
30
+ - Brian Takita
31
+ files:
32
+ - test/tc_data_view.rb
33
+ - test/ts_data_view.rb
34
+ - lib/dataview.rb
35
+ - lib/data_view.rb
36
+ - README
37
+ test_files:
38
+ - test/ts_data_view.rb
39
+ rdoc_options: []
40
+ extra_rdoc_files:
41
+ - README
42
+ executables: []
43
+ extensions: []
44
+ requirements: []
45
+ dependencies: []