hotwire 0.0.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/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.makrdown +46 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/hotwire.gemspec +77 -0
- data/lib/hotwire.rb +8 -0
- data/lib/hotwire/active_record_mixins.rb +95 -0
- data/lib/hotwire/column_headers.rb +54 -0
- data/lib/hotwire/core_extensions.rb +11 -0
- data/lib/hotwire/row.rb +46 -0
- data/lib/hotwire/table.rb +27 -0
- data/test/active_record_test_helper.rb +14 -0
- data/test/hotwire_test.rb +5 -0
- data/test/test_active_record_mixins.rb +65 -0
- data/test/test_column_headers.rb +20 -0
- data/test/test_core_extensions.rb +26 -0
- data/test/test_helper.rb +14 -0
- data/test/test_row.rb +17 -0
- data/test/test_table.rb +40 -0
- metadata +125 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Les Freeman
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.makrdown
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Hotwire
|
2
|
+
|
3
|
+
Hotwire is designed to ease the pain of creating Google Wire Protocol compatible data source in Ruby. Specifically, Hotwire can make it dead simple to provide data for the Google Visualization API.
|
4
|
+
|
5
|
+
## Basic Usage
|
6
|
+
|
7
|
+
Create a data hash...
|
8
|
+
|
9
|
+
data = {:columns => ['name', 'years', 'location'], :rows => [["Bob", 21, "Baltimore"],
|
10
|
+
["Fred", 11, "Pittsburgh"]]}
|
11
|
+
|
12
|
+
...convert it...
|
13
|
+
|
14
|
+
data.to_wire
|
15
|
+
|
16
|
+
...and savor the results:
|
17
|
+
|
18
|
+
{"table"=>{"rows"=>[{"c"=>[{"v"=>"Bob"}, {"v"=>21}, {"v"=>"Baltimore"}]}, {"c"=>[{"v"=>"Fred"}, {"v"=>11}, {"v"=>"Pittsburgh"}]}], "cols"=>[{"type"=>"string", "id"=>"name", "label"=>"Name"}, {"type"=>"number", "id"=>"years", "label"=>"Years"}, {"type"=>"string", "id"=>"location", "label"=>"Location"}]}}
|
19
|
+
|
20
|
+
## Basic ActiveRecord Usage
|
21
|
+
If your project includes ActiveRecord, Hotwire will automatically included an extension to itself for processing ActiveRecord collections. This allows you to do something like:
|
22
|
+
|
23
|
+
people = Person.all
|
24
|
+
people.to_wire
|
25
|
+
|
26
|
+
Resulting in:
|
27
|
+
|
28
|
+
{"table"=>{"rows"=>[{"c"=>[{"v"=>"Bob"}, {"v"=>21}, {"v"=>"Baltimore"}]}, {"c"=>[{"v"=>"Fred"}, {"v"=>11}, {"v"=>"Pittsburgh"}]}], "cols"=>[{"type"=>"string", "id"=>"name", "label"=>"Name"}, {"type"=>"number", "id"=>"years", "label"=>"Years"}, {"type"=>"string", "id"=>"location", "label"=>"Location"}]}}
|
29
|
+
|
30
|
+
## Advanced Usage ##
|
31
|
+
|
32
|
+
Under the hood, Hotwire is designed to be extended in the future to allow for other construction methods and direct data manipulation. I haven't had a need for these features yet, but if you do and are interested in implementing them, please let me know.
|
33
|
+
|
34
|
+
## Note on Patches/Pull Requests
|
35
|
+
|
36
|
+
* Fork the project.
|
37
|
+
* Make your feature addition or bug fix.
|
38
|
+
* Add tests for it. This is important so I don't break it in a
|
39
|
+
future version unintentionally.
|
40
|
+
* Commit, do not mess with rakefile, version, or history.
|
41
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
42
|
+
* Send me a pull request. Bonus points for topic branches.
|
43
|
+
|
44
|
+
## Copyright
|
45
|
+
|
46
|
+
Copyright (c) 2010 Les Freeman. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "hotwire"
|
8
|
+
gem.summary = %Q{Under the hood data transformations for the Google Wire protocol. }
|
9
|
+
gem.description = %Q{Hotwire is designed to ease the pain of creating Google Wire protocol compatible data source in Ruby.}
|
10
|
+
gem.email = "les@codebenders.com"
|
11
|
+
gem.homepage = "http://github.com/lesfreeman/hotwire"
|
12
|
+
gem.authors = ["Les Freeman"]
|
13
|
+
gem.add_dependency "activesupport", ">= 0"
|
14
|
+
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
15
|
+
gem.add_development_dependency "redgreen", ">= 0"
|
16
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
|
+
end
|
18
|
+
Jeweler::GemcutterTasks.new
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'rake/testtask'
|
24
|
+
Rake::TestTask.new(:test) do |test|
|
25
|
+
test.libs << 'lib' << 'test'
|
26
|
+
test.pattern = 'test/**/test_*.rb'
|
27
|
+
test.verbose = true
|
28
|
+
end
|
29
|
+
|
30
|
+
begin
|
31
|
+
require 'rcov/rcovtask'
|
32
|
+
Rcov::RcovTask.new do |test|
|
33
|
+
test.libs << 'test'
|
34
|
+
test.pattern = 'test/**/test_*.rb'
|
35
|
+
test.verbose = true
|
36
|
+
end
|
37
|
+
rescue LoadError
|
38
|
+
task :rcov do
|
39
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
task :test => :check_dependencies
|
44
|
+
|
45
|
+
task :default => :test
|
46
|
+
|
47
|
+
require 'rake/rdoctask'
|
48
|
+
Rake::RDocTask.new do |rdoc|
|
49
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
50
|
+
|
51
|
+
rdoc.rdoc_dir = 'rdoc'
|
52
|
+
rdoc.title = "hotwire #{version}"
|
53
|
+
rdoc.rdoc_files.include('README*')
|
54
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
55
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
data/hotwire.gemspec
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{hotwire}
|
8
|
+
s.version = "0.0.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Les Freeman"]
|
12
|
+
s.date = %q{2010-10-20}
|
13
|
+
s.description = %q{Hotwire is designed to ease the pain of creating Google Wire protocol compatible data source in Ruby.}
|
14
|
+
s.email = %q{les@codebenders.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.makrdown"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.makrdown",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"hotwire.gemspec",
|
27
|
+
"lib/hotwire.rb",
|
28
|
+
"lib/hotwire/active_record_mixins.rb",
|
29
|
+
"lib/hotwire/column_headers.rb",
|
30
|
+
"lib/hotwire/core_extensions.rb",
|
31
|
+
"lib/hotwire/row.rb",
|
32
|
+
"lib/hotwire/table.rb",
|
33
|
+
"test/active_record_test_helper.rb",
|
34
|
+
"test/hotwire_test.rb",
|
35
|
+
"test/test_active_record_mixins.rb",
|
36
|
+
"test/test_column_headers.rb",
|
37
|
+
"test/test_core_extensions.rb",
|
38
|
+
"test/test_helper.rb",
|
39
|
+
"test/test_row.rb",
|
40
|
+
"test/test_table.rb"
|
41
|
+
]
|
42
|
+
s.homepage = %q{http://github.com/lesfreeman/hotwire}
|
43
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
44
|
+
s.require_paths = ["lib"]
|
45
|
+
s.rubygems_version = %q{1.3.6}
|
46
|
+
s.summary = %q{Under the hood data transformations for the Google Wire protocol.}
|
47
|
+
s.test_files = [
|
48
|
+
"test/active_record_test_helper.rb",
|
49
|
+
"test/hotwire_test.rb",
|
50
|
+
"test/test_active_record_mixins.rb",
|
51
|
+
"test/test_column_headers.rb",
|
52
|
+
"test/test_core_extensions.rb",
|
53
|
+
"test/test_helper.rb",
|
54
|
+
"test/test_row.rb",
|
55
|
+
"test/test_table.rb"
|
56
|
+
]
|
57
|
+
|
58
|
+
if s.respond_to? :specification_version then
|
59
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
60
|
+
s.specification_version = 3
|
61
|
+
|
62
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
63
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
64
|
+
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
65
|
+
s.add_development_dependency(%q<redgreen>, [">= 0"])
|
66
|
+
else
|
67
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
68
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
69
|
+
s.add_dependency(%q<redgreen>, [">= 0"])
|
70
|
+
end
|
71
|
+
else
|
72
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
73
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
74
|
+
s.add_dependency(%q<redgreen>, [">= 0"])
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
data/lib/hotwire.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
module Hotwire #:nodoc:
|
2
|
+
|
3
|
+
##
|
4
|
+
# Hotwire extensions to build from ActiveRecord collections
|
5
|
+
#
|
6
|
+
module ActiveRecordMixins
|
7
|
+
|
8
|
+
##
|
9
|
+
# Extensions to Hotwire::Table
|
10
|
+
#
|
11
|
+
module Table
|
12
|
+
private
|
13
|
+
def self.included base
|
14
|
+
base.class_eval do
|
15
|
+
alias_method_chain :initialize, :active_record_extension
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Parse source data if needed and then pass it along to main initializer
|
21
|
+
#
|
22
|
+
def initialize_with_active_record_extension source
|
23
|
+
source = source_from_active_record_collection(source) if source.is_a?(Array) and source.first.is_a?(ActiveRecord::Base)
|
24
|
+
initialize_without_active_record_extension source
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Parse an ActiveRecord collection into a hash for the initializer
|
29
|
+
#
|
30
|
+
def source_from_active_record_collection source
|
31
|
+
{ :columns => columns_from_active_record_collection(source), :rows => rows_from_active_record_collection(source) }
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Parse an ActiveRecord collection into a column headers array
|
36
|
+
#
|
37
|
+
def columns_from_active_record_collection source
|
38
|
+
source.first.attributes.keys.sort
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Parse an ActiveRecord collection into a rows array
|
43
|
+
#
|
44
|
+
def rows_from_active_record_collection source
|
45
|
+
source.map do |obj|
|
46
|
+
obj.attributes.sort_by{ |key, val| key }.map do |key, val|
|
47
|
+
val
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Extensions to Hotwire::Row
|
55
|
+
#
|
56
|
+
module Row
|
57
|
+
private
|
58
|
+
##
|
59
|
+
# Times pulled from an activerecord attribute hash are not converted to the zone automatically
|
60
|
+
#
|
61
|
+
def format_date_with_time_zone_conversion date
|
62
|
+
date = date.in_time_zone if Time.respond_to?(:zone) and Time.zone and date.respond_to?(:in_time_zone)
|
63
|
+
format_date_without_time_zone_conversion date
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.included base
|
67
|
+
base.class_eval do
|
68
|
+
alias_method_chain :format_date, :time_zone_conversion
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# Extensions to Hotwire::CoreExtensions
|
75
|
+
#
|
76
|
+
module CoreExtensions
|
77
|
+
|
78
|
+
module Array
|
79
|
+
##
|
80
|
+
# Converts an ActiveRecord collection array to a Wire compatible hash
|
81
|
+
#
|
82
|
+
def to_wire
|
83
|
+
raise "to_wire only works on an array of ActiveRecord objects" if self.map {|elem| elem.is_a?(ActiveRecord::Base)}.include?(false)
|
84
|
+
Hotwire::Table.new(self).to_wire
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
Hotwire::Table.send(:include, Hotwire::ActiveRecordMixins::Table)
|
94
|
+
Hotwire::Row.send(:include, Hotwire::ActiveRecordMixins::Row)
|
95
|
+
Array.send(:include, Hotwire::ActiveRecordMixins::CoreExtensions::Array)
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
module Hotwire #:nodoc:
|
4
|
+
|
5
|
+
##
|
6
|
+
# Represents header information for a Hotwire::Table
|
7
|
+
#
|
8
|
+
class ColumnHeaders
|
9
|
+
|
10
|
+
##
|
11
|
+
# Initialize from a hash of data. See Hotwire::Table.initialize for param information.
|
12
|
+
#
|
13
|
+
def initialize data
|
14
|
+
@data = data
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Convert to a Wire compatible Hash
|
19
|
+
#
|
20
|
+
def to_wire
|
21
|
+
returning [] do |columns|
|
22
|
+
@data[:columns].each_with_index do |column, index|
|
23
|
+
columns << {'id' => column, 'label' => column.humanize, 'type' => column_type_for_index(index)}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
##
|
31
|
+
# Determine the column data type by index
|
32
|
+
#
|
33
|
+
def column_type_for_index index
|
34
|
+
column_type(@data[:rows].first[index])
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Determine the column data type for a given value
|
39
|
+
#
|
40
|
+
def column_type sample_value
|
41
|
+
case sample_value.class.name
|
42
|
+
when 'BigDecimal', 'Fixnum'
|
43
|
+
'number'
|
44
|
+
when /Time/
|
45
|
+
'datetime'
|
46
|
+
when 'String'
|
47
|
+
'string'
|
48
|
+
else
|
49
|
+
'string'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
data/lib/hotwire/row.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Hotwire #:nodoc:
|
2
|
+
|
3
|
+
##
|
4
|
+
# Represents a one-dimensional row of data.
|
5
|
+
#
|
6
|
+
class Row
|
7
|
+
|
8
|
+
##
|
9
|
+
# Construct a new Row object from a array of data.
|
10
|
+
#
|
11
|
+
def initialize data
|
12
|
+
raise ArgumentError, "data must be an Array of values" unless data.is_a?(Array)
|
13
|
+
@data = data
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# Convert the row to a Wire compatible Hash
|
18
|
+
#
|
19
|
+
def to_wire
|
20
|
+
{ 'c' => @data.map { |value| {'v' => format_value(value) } } }
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
##
|
26
|
+
# Perform any formatting needed to make value Wire compatible.
|
27
|
+
#
|
28
|
+
def format_value value
|
29
|
+
case value.class.name
|
30
|
+
when /Time/
|
31
|
+
format_date value
|
32
|
+
when /NilClass/
|
33
|
+
0
|
34
|
+
else
|
35
|
+
value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Wire dates seem to expect to have 0 based month.
|
41
|
+
#
|
42
|
+
def format_date value
|
43
|
+
"Date(#{value.year}, #{value.month - 1}, #{value.day}, #{value.hour}, #{value.min}, #{value.sec})"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Hotwire #:nodoc:
|
2
|
+
|
3
|
+
##
|
4
|
+
# Represents a two dimensional table of data that is ready to format for the Wire protocol
|
5
|
+
#
|
6
|
+
class Table
|
7
|
+
##
|
8
|
+
# Create a table from a source hash. The hash must contain these keys:
|
9
|
+
# :columns => A one dimensional array of column labels.
|
10
|
+
# :rows => => A two dimensional array of data. Each row is a one dimensional array.
|
11
|
+
#
|
12
|
+
def initialize source
|
13
|
+
raise ArgumentError, "source data must have a :column key and a :rows key" unless source.has_key?(:columns) && source.has_key?(:rows)
|
14
|
+
@column_headers = Hotwire::ColumnHeaders.new(source)
|
15
|
+
@rows = source[:rows].map { |row| Hotwire::Row.new(row) }
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# Convert the table to a Wire compatible hash
|
20
|
+
#
|
21
|
+
def to_wire
|
22
|
+
{'table' => {'cols' => @column_headers.to_wire, 'rows' => @rows.map {|r| r.to_wire} } }
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
3
|
+
|
4
|
+
ActiveRecord::Schema.define(:version => 1) do
|
5
|
+
create_table :people do |t|
|
6
|
+
t.string :name
|
7
|
+
t.text :bio
|
8
|
+
t.integer :age
|
9
|
+
t.datetime :birth_date
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Person < ActiveRecord::Base
|
14
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'active_record_test_helper'
|
3
|
+
|
4
|
+
|
5
|
+
class TestActiveRecordMixin < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "a Hotwire::Table instance from an ActiveRecord collection" do
|
8
|
+
setup do
|
9
|
+
Person.delete_all
|
10
|
+
Person.create(:name => "Bob", :age => 33, :bio => "A nice Guy", :birth_date => Time.utc(2010, 10, 19, 9, 38, 10))
|
11
|
+
@data = Hotwire::Table.new(Person.all)
|
12
|
+
end
|
13
|
+
|
14
|
+
context "to_wire" do
|
15
|
+
should "return a properly formatted hash" do
|
16
|
+
expected = { "table"=> {"rows"=> [{"c"=> [{"v"=>33},
|
17
|
+
{"v"=>"A nice Guy"},
|
18
|
+
{"v"=>"Date(2010, 9, 19, 9, 38, 10)"},
|
19
|
+
{"v"=>1},#be careful of this id making tests fails
|
20
|
+
{"v"=>"Bob"}]}],
|
21
|
+
"cols"=> [{"type"=>"number", "id"=>"age", "label"=>"Age"},
|
22
|
+
{"type"=>"string", "id"=>"bio", "label"=>"Bio"},
|
23
|
+
{"type"=>"datetime", "id"=>"birth_date", "label"=>"Birth date"},
|
24
|
+
{"type"=>"number", "id"=>"id", "label"=>"Id"},
|
25
|
+
{"type"=>"string", "id"=>"name", "label"=>"Name"}]}}
|
26
|
+
|
27
|
+
assert_equal expected, @data.to_wire
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "an Array of ActiveRecord objects" do
|
33
|
+
setup do
|
34
|
+
Person.delete_all
|
35
|
+
Person.create(:name => "Bob", :age => 33, :bio => "A nice Guy", :birth_date => Time.utc(2010, 10, 19, 9, 38, 10))
|
36
|
+
@people = Person.all
|
37
|
+
end
|
38
|
+
|
39
|
+
context "to_wire" do
|
40
|
+
should "return a properly formatted hash" do
|
41
|
+
expected = { "table"=> {"rows"=> [{"c"=> [{"v"=>33},
|
42
|
+
{"v"=>"A nice Guy"},
|
43
|
+
{"v"=>"Date(2010, 9, 19, 9, 38, 10)"},
|
44
|
+
{"v"=>2}, #be careful of this id making tests fails
|
45
|
+
{"v"=>"Bob"}]}],
|
46
|
+
"cols"=> [{"type"=>"number", "id"=>"age", "label"=>"Age"},
|
47
|
+
{"type"=>"string", "id"=>"bio", "label"=>"Bio"},
|
48
|
+
{"type"=>"datetime", "id"=>"birth_date", "label"=>"Birth date"},
|
49
|
+
{"type"=>"number", "id"=>"id", "label"=>"Id"},
|
50
|
+
{"type"=>"string", "id"=>"name", "label"=>"Name"}]}}
|
51
|
+
|
52
|
+
assert_equal expected, @people.to_wire
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "an Array of non-ActiveRecord objects" do
|
58
|
+
should "raise an error" do
|
59
|
+
assert_raises RuntimeError do
|
60
|
+
["string"].to_wire
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestColumnHeaders < Test::Unit::TestCase
|
4
|
+
context "a Hotwire::ColumnHeaders instance" do
|
5
|
+
setup do
|
6
|
+
time = Time.utc(2010, 10, 19, 9, 38, 10)
|
7
|
+
@headers = Hotwire::ColumnHeaders.new({:columns => ['started at', 'name', 'years', 'location'], :rows => [[time, "bob", 21, nil]]})
|
8
|
+
end
|
9
|
+
|
10
|
+
context "to_wire" do
|
11
|
+
should "return a propperly formatted array" do
|
12
|
+
expected = [{"type"=>"datetime", "id"=>"started at", "label"=>"Started at"},
|
13
|
+
{"type"=>"string", "id"=>"name", "label"=>"Name"},
|
14
|
+
{"type"=>"number", "id"=>"years", "label"=>"Years"},
|
15
|
+
{"type"=>"string", "id"=>"location", "label"=>"Location"}]
|
16
|
+
assert_equal expected, @headers.to_wire
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestCoreExtensions < Test::Unit::TestCase
|
4
|
+
context "a Hash" do
|
5
|
+
context "to_wire" do
|
6
|
+
context "with propper data" do
|
7
|
+
setup do
|
8
|
+
time = Time.local(2010, 10, 19, 9, 38, 10)
|
9
|
+
@hash = {:columns => ['started at', 'name', 'years', 'location'], :rows => [[time, "bob", 21, nil]]}
|
10
|
+
end
|
11
|
+
|
12
|
+
should "return a propperly formatted hash" do
|
13
|
+
expected = { "table"=> { "rows"=> [ {"c"=> [{"v"=>"Date(2010, 9, 19, 9, 38, 10)"},
|
14
|
+
{"v"=>"bob"},
|
15
|
+
{"v"=>21},
|
16
|
+
{"v"=>0}]}],
|
17
|
+
"cols"=> [{"type"=>"datetime", "id"=>"started at", "label"=>"Started at"},
|
18
|
+
{"type"=>"string", "id"=>"name", "label"=>"Name"},
|
19
|
+
{"type"=>"number", "id"=>"years", "label"=>"Years"},
|
20
|
+
{"type"=>"string", "id"=>"location", "label"=>"Location"}]}}
|
21
|
+
assert_equal expected, @hash.to_wire
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'redgreen' unless ENV['TM_MODE']
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
|
9
|
+
require 'active_record'
|
10
|
+
|
11
|
+
require 'hotwire'
|
12
|
+
|
13
|
+
class Test::Unit::TestCase
|
14
|
+
end
|
data/test/test_row.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestRow < Test::Unit::TestCase
|
4
|
+
context "a Hotwire::Row instance" do
|
5
|
+
setup do
|
6
|
+
time = Time.local(2010, 10, 19, 9, 38, 10)
|
7
|
+
@row = Hotwire::Row.new([time, "value1", nil])
|
8
|
+
end
|
9
|
+
|
10
|
+
context "to_wire" do
|
11
|
+
should "return a propperly formatted hash" do
|
12
|
+
expected = { 'c' => [{ 'v' => "Date(2010, 9, 19, 9, 38, 10)" }, { 'v' => "value1" }, { 'v' => 0 } ] }
|
13
|
+
assert_equal expected, @row.to_wire
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/test/test_table.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestTable < Test::Unit::TestCase
|
4
|
+
context "inializing from a Hash" do
|
5
|
+
|
6
|
+
should "raise an ArgumentError if :columns are not specified" do
|
7
|
+
assert_raise ArgumentError do
|
8
|
+
Hotwire::Table.new({:rows => []})
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
should "raise an ArgumentError if :rows are not specified" do
|
13
|
+
assert_raise ArgumentError do
|
14
|
+
Hotwire::Table.new({:columns => []})
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
context "a Hotwire::Date instance" do
|
21
|
+
setup do
|
22
|
+
time = Time.local(2010, 10, 19, 9, 38, 10)
|
23
|
+
@data = Hotwire::Table.new({:columns => ['started at', 'name', 'years', 'location'], :rows => [[time, "bob", 21, nil]]})
|
24
|
+
end
|
25
|
+
|
26
|
+
context "to_wire" do
|
27
|
+
should "return a properly formatted hash" do
|
28
|
+
expected = { "table"=> { "rows"=> [ {"c"=> [{"v"=>"Date(2010, 9, 19, 9, 38, 10)"},
|
29
|
+
{"v"=>"bob"},
|
30
|
+
{"v"=>21},
|
31
|
+
{"v"=>0}]}],
|
32
|
+
"cols"=> [{"type"=>"datetime", "id"=>"started at", "label"=>"Started at"},
|
33
|
+
{"type"=>"string", "id"=>"name", "label"=>"Name"},
|
34
|
+
{"type"=>"number", "id"=>"years", "label"=>"Years"},
|
35
|
+
{"type"=>"string", "id"=>"location", "label"=>"Location"}]}}
|
36
|
+
assert_equal expected, @data.to_wire
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hotwire
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 0.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Les Freeman
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-10-20 00:00:00 -07:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: activesupport
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: thoughtbot-shoulda
|
34
|
+
prerelease: false
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
version: "0"
|
42
|
+
type: :development
|
43
|
+
version_requirements: *id002
|
44
|
+
- !ruby/object:Gem::Dependency
|
45
|
+
name: redgreen
|
46
|
+
prerelease: false
|
47
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
54
|
+
type: :development
|
55
|
+
version_requirements: *id003
|
56
|
+
description: Hotwire is designed to ease the pain of creating Google Wire protocol compatible data source in Ruby.
|
57
|
+
email: les@codebenders.com
|
58
|
+
executables: []
|
59
|
+
|
60
|
+
extensions: []
|
61
|
+
|
62
|
+
extra_rdoc_files:
|
63
|
+
- LICENSE
|
64
|
+
- README.makrdown
|
65
|
+
files:
|
66
|
+
- .document
|
67
|
+
- .gitignore
|
68
|
+
- LICENSE
|
69
|
+
- README.makrdown
|
70
|
+
- Rakefile
|
71
|
+
- VERSION
|
72
|
+
- hotwire.gemspec
|
73
|
+
- lib/hotwire.rb
|
74
|
+
- lib/hotwire/active_record_mixins.rb
|
75
|
+
- lib/hotwire/column_headers.rb
|
76
|
+
- lib/hotwire/core_extensions.rb
|
77
|
+
- lib/hotwire/row.rb
|
78
|
+
- lib/hotwire/table.rb
|
79
|
+
- test/active_record_test_helper.rb
|
80
|
+
- test/hotwire_test.rb
|
81
|
+
- test/test_active_record_mixins.rb
|
82
|
+
- test/test_column_headers.rb
|
83
|
+
- test/test_core_extensions.rb
|
84
|
+
- test/test_helper.rb
|
85
|
+
- test/test_row.rb
|
86
|
+
- test/test_table.rb
|
87
|
+
has_rdoc: true
|
88
|
+
homepage: http://github.com/lesfreeman/hotwire
|
89
|
+
licenses: []
|
90
|
+
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options:
|
93
|
+
- --charset=UTF-8
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
segments:
|
108
|
+
- 0
|
109
|
+
version: "0"
|
110
|
+
requirements: []
|
111
|
+
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 1.3.6
|
114
|
+
signing_key:
|
115
|
+
specification_version: 3
|
116
|
+
summary: Under the hood data transformations for the Google Wire protocol.
|
117
|
+
test_files:
|
118
|
+
- test/active_record_test_helper.rb
|
119
|
+
- test/hotwire_test.rb
|
120
|
+
- test/test_active_record_mixins.rb
|
121
|
+
- test/test_column_headers.rb
|
122
|
+
- test/test_core_extensions.rb
|
123
|
+
- test/test_helper.rb
|
124
|
+
- test/test_row.rb
|
125
|
+
- test/test_table.rb
|