dataview 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []