crosstab 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Manifest.txt +23 -0
- data/README.txt +133 -0
- data/Rakefile +17 -0
- data/lib/crosstab.rb +25 -0
- data/lib/crosstab/banner.rb +90 -0
- data/lib/crosstab/cell.rb +162 -0
- data/lib/crosstab/column.rb +64 -0
- data/lib/crosstab/crosstab.rb +243 -0
- data/lib/crosstab/extensions.rb +26 -0
- data/lib/crosstab/generic.rb +83 -0
- data/lib/crosstab/group.rb +28 -0
- data/lib/crosstab/row.rb +65 -0
- data/lib/crosstab/table.rb +85 -0
- data/test/test_banner.rb +81 -0
- data/test/test_cell.rb +95 -0
- data/test/test_column.rb +60 -0
- data/test/test_crosstab.rb +214 -0
- data/test/test_extensions.rb +12 -0
- data/test/test_group.rb +67 -0
- data/test/test_missing.rb +75 -0
- data/test/test_row.rb +60 -0
- data/test/test_table.rb +67 -0
- metadata +87 -0
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift "../lib" if __FILE__ == $0
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'crosstab'
|
5
|
+
|
6
|
+
class ExtensionTests < Test::Unit::TestCase
|
7
|
+
def test_array_to_freq_chart
|
8
|
+
@array = [nil, "a", "a", "a", "b", "b", "b", nil, "c"]
|
9
|
+
assert_equal [[1,nil],[3,"a"],[3,"b"],[1,nil],[1,"c"]], @array.to_freq_chart
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
data/test/test_group.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
$LOAD_PATH.unshift "../lib" if __FILE__ == $0
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class GroupTests < Test::Unit::TestCase
|
6
|
+
# Same tests as Crosstab::Row
|
7
|
+
def setup
|
8
|
+
@group = Crosstab::Group.new
|
9
|
+
end
|
10
|
+
|
11
|
+
# Responds to these public methods
|
12
|
+
def test_respond_method
|
13
|
+
[:title, :qualifies?, :cells, :children, :printed?].each do |method|
|
14
|
+
assert_respond_to @group, method, "Hey, an instantiated group should have a `#{method}` method."
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Test defaults for reader methods
|
19
|
+
def test_default_title
|
20
|
+
assert_nil @group.title
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_default_cells
|
24
|
+
assert_equal [], @group.cells
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_default_children
|
28
|
+
assert_equal [], @group.cells
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_default_printed?
|
32
|
+
assert_equal false, @group.printed?
|
33
|
+
end
|
34
|
+
|
35
|
+
# Test behavior of setter methods
|
36
|
+
def test_set_title
|
37
|
+
@group.title "Test Title"
|
38
|
+
assert_equal "Test Title", @group.title
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_qualifies?
|
42
|
+
# So lazy. Totally cheating.
|
43
|
+
@group.children << Crosstab::Row.new("Male", :a => 1)
|
44
|
+
@group.children << Crosstab::Row.new("Female", :a => 2)
|
45
|
+
|
46
|
+
assert_equal true, @group.qualifies?(:a => 1)
|
47
|
+
assert_equal true, @group.qualifies?(:a => 2)
|
48
|
+
assert_equal false, @group.qualifies?(:a => 3)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_set_cells
|
52
|
+
@group.cells [Crosstab::Cell.new(:base => 100, :frequency => 50)]
|
53
|
+
assert_equal 1, @group.cells.length
|
54
|
+
assert_equal 0.5, @group.cells.first.percentage
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_set_children
|
58
|
+
@group.children [Crosstab::Row.new("Row title", :a => 4)]
|
59
|
+
assert_equal "Row title", @group.children.first.title
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_set_printed?
|
63
|
+
@group.printed? true
|
64
|
+
assert_equal true, @group.printed?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
$LOAD_PATH.unshift "../lib" if __FILE__ == $0
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class TestMissing < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_missing_ranking
|
8
|
+
assert false
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_missing_norank
|
12
|
+
assert false
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_missing_mean
|
16
|
+
assert false
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_missing_std_dev
|
20
|
+
assert false
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_missing_std_err
|
24
|
+
assert false
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_missing_median
|
28
|
+
assert false
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_missing_populate
|
32
|
+
assert false
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_recoding
|
36
|
+
assert false
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_not_happy_with_column
|
40
|
+
assert false
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_not_happy_with_crosstab_adding_cells_to_rows
|
44
|
+
# Why did I intersperse the report with the rows and columns? It would be much cleaner to simply return an array of results
|
45
|
+
# from the calculate method. Then we can add the detailed reporting shit later, or to another gem like crosstab::detailed.
|
46
|
+
#
|
47
|
+
# like...
|
48
|
+
#
|
49
|
+
# my_crosstab.report true
|
50
|
+
# [:table, "Table 1"],
|
51
|
+
# [:title, "Q.A Gender:"],
|
52
|
+
# [:headers, nil,"Male","Female"],
|
53
|
+
# [:baseline, "(Base)",[10],[10]],
|
54
|
+
# [:row, "Male",[10,"100%"],[0,"0%"]],
|
55
|
+
# [:row, "Female",[0,"0%"],[10,"100%"]]]
|
56
|
+
#
|
57
|
+
# or the default...
|
58
|
+
#
|
59
|
+
# my_crosstab.report false
|
60
|
+
#
|
61
|
+
# ["Table 1",
|
62
|
+
# "Q.A Gender:",
|
63
|
+
# [nil,"Male","Female"],
|
64
|
+
# ["(Base)",[10],[10]],
|
65
|
+
# ["Male",[10,"100%"],[0,"0%"]],
|
66
|
+
# ["Female",[0,"0%"],[10,"100%"]]]
|
67
|
+
#
|
68
|
+
# Add in mean, median, std. dev., std. error, sigtesting and you've got yourself a lightweight crosstab system.
|
69
|
+
# Next version, add the Uncle-style report.
|
70
|
+
#
|
71
|
+
# Also keep in mind that each class is its own library. None of the classes get to talk to any others except for Crosstab,
|
72
|
+
# which ties them together. And it shouldn't get to write data to any of them in the calculate or report methods.
|
73
|
+
assert false
|
74
|
+
end
|
75
|
+
end
|
data/test/test_row.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
$LOAD_PATH.unshift "../lib" if __FILE__ == $0
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
|
6
|
+
class RowTests < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@row = Crosstab::Row.new
|
9
|
+
end
|
10
|
+
|
11
|
+
# Responds to these public methods
|
12
|
+
def test_respond_methods
|
13
|
+
[:title, :qualification, :qualifies?, :cells, :group].each do |method|
|
14
|
+
assert_respond_to @row, method, "Hey, an instantiated row should have a `#{method}` method."
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Test defaults for reader methods
|
19
|
+
def test_default_title
|
20
|
+
assert_nil @row.title
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_default_qualifies?
|
24
|
+
assert_equal true, @row.qualifies?(Hash.new)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_default_cells
|
28
|
+
assert_equal [], @row.cells
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_default_group
|
32
|
+
assert_equal nil, @row.group
|
33
|
+
end
|
34
|
+
|
35
|
+
# Test behavior of setter methods
|
36
|
+
def test_set_title
|
37
|
+
@row.title "Test Title"
|
38
|
+
assert_equal "Test Title", @row.title
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_set_qualification
|
42
|
+
@row.qualification :a => 1
|
43
|
+
|
44
|
+
assert_equal true, @row.qualifies?(:a => 1, :b => 1)
|
45
|
+
assert_equal false, @row.qualifies?(:a => 2, :b => 1)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_set_cells
|
49
|
+
@row.cells [Crosstab::Cell.new(:base => 100, :frequency => 50)]
|
50
|
+
assert_equal 1, @row.cells.length
|
51
|
+
assert_equal 0.5, @row.cells.first.percentage
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_set_group
|
55
|
+
@row.group Crosstab::Group.new("Group Title")
|
56
|
+
assert_equal "Group Title", @row.group.title
|
57
|
+
assert_equal [ @row ], @row.group.children
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
data/test/test_table.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
$LOAD_PATH.unshift "../lib" if __FILE__ == $0
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class Test__CrosstabTable < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@table = Crosstab::Table.new
|
8
|
+
end
|
9
|
+
|
10
|
+
# Responds to these public methods
|
11
|
+
def test_respond_methods
|
12
|
+
[:title, :qualification, :qualifies?, :rows, :row, :group].each do |method|
|
13
|
+
assert_respond_to @table, method, "Hey, an instantiated table should have a `#{method}` method."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Test defaults for reader methods
|
18
|
+
def test_default_title
|
19
|
+
assert_nil @table.title
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_default_qualifies?
|
23
|
+
assert_equal true, @table.qualifies?(Hash.new)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_default_rows
|
27
|
+
assert_equal [], @table.rows
|
28
|
+
end
|
29
|
+
|
30
|
+
# Test behavior of setter methods
|
31
|
+
def test_set_title
|
32
|
+
@table.title "Test Title"
|
33
|
+
assert_equal "Test Title", @table.title
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_set_qualification
|
37
|
+
@table.qualification :a => 1
|
38
|
+
|
39
|
+
assert_equal true, @table.qualifies?(:a => 1, :b => 1)
|
40
|
+
assert_equal false, @table.qualifies?(:a => 2, :b => 1)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_set_row
|
44
|
+
@table.row "New Row", :a => 2
|
45
|
+
|
46
|
+
assert_equal 1, @table.rows.length
|
47
|
+
assert_kind_of Crosstab::Row, @table.rows.first
|
48
|
+
assert_equal "New Row", @table.rows.first.title
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_set_group
|
52
|
+
@table.group "Gender" do
|
53
|
+
row "Male", :a => 1
|
54
|
+
row "Female", :a => 2
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_equal 2, @table.rows.length
|
58
|
+
assert_kind_of Crosstab::Row, @table.rows.first
|
59
|
+
assert_kind_of Crosstab::Row, @table.rows.last
|
60
|
+
|
61
|
+
assert_equal "Male", @table.rows.first.title
|
62
|
+
assert_equal "Female", @table.rows.last.title
|
63
|
+
|
64
|
+
assert_equal "Gender", @table.rows.first.group.title
|
65
|
+
assert_equal "Gender", @table.rows.last.group.title
|
66
|
+
end
|
67
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.3
|
3
|
+
specification_version: 1
|
4
|
+
name: crosstab
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2007-10-18 00:00:00 -07:00
|
8
|
+
summary: Crosstab is a library for generating formatted pivot tables.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: mjudge@surveycomplete.com
|
12
|
+
homepage: " by Michael Judge <mjudge@surveycomplete.com>"
|
13
|
+
rubyforge_project: crosstab
|
14
|
+
description: "== FEATURES: * Input your data as an array of hashes * Input a report layout, built using a Ruby DSL * Outputs ASCII pivot tables suitable for fast reports * Pretty fast: takes less than a second to process 1,000 records of data by a report with 100 rows and 10 columns. == SYNOPSIS: require 'crosstab' data = [{:gender => \"M\", :age => 1}, {:gender => \"F\", :age => 2}, {:gender => \"M\", :age => 3}] my_crosstab = crosstab data do table do title \"Q.A Gender:\" row \"Male\", :gender => \"M\" row \"Female\", :gender => \"F\" end table do title \"Q.B Age:\" group \"18 - 54\" do row \"18 - 34\", :age => 1 row \"35 - 54\", :age => 2 end row \"55 or older\", :age => 3 end banner do column \"Total\" group \"Gender\" do column \"Male\", :gender => \"M\" column \"Female\", :gender => \"F\" end end end puts my_crosstab.to_s == REPORT: # puts my_crosstab.to_s Table 1 Q.A Gender: Gender ---------------- Total Male Female (A) (B) (C) ------- ------- ------- (BASE) 3 2 1 Male 2 2 -- 67% 100% Female 1 -- 1 33% 100% ------------------------------------------------------------------------ Table 2 Q.B Age: Gender ---------------- Total Male Female (A) (B) (C) ------- ------- ------- (BASE) 3 2 1 18 - 54 2 1 1 ----------------------------- 67% 50% 100% 18 - 34 1 1 -- 33% 50% 35 - 54 1 -- 1 33% 100% 55 or older 1 1 -- 33% 50%"
|
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
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Ryan Davis
|
31
|
+
files:
|
32
|
+
- History.txt
|
33
|
+
- Manifest.txt
|
34
|
+
- README.txt
|
35
|
+
- Rakefile
|
36
|
+
- lib/crosstab.rb
|
37
|
+
- lib/crosstab/banner.rb
|
38
|
+
- lib/crosstab/cell.rb
|
39
|
+
- lib/crosstab/column.rb
|
40
|
+
- lib/crosstab/crosstab.rb
|
41
|
+
- lib/crosstab/extensions.rb
|
42
|
+
- lib/crosstab/generic.rb
|
43
|
+
- lib/crosstab/group.rb
|
44
|
+
- lib/crosstab/row.rb
|
45
|
+
- lib/crosstab/table.rb
|
46
|
+
- test/test_banner.rb
|
47
|
+
- test/test_cell.rb
|
48
|
+
- test/test_column.rb
|
49
|
+
- test/test_crosstab.rb
|
50
|
+
- test/test_extensions.rb
|
51
|
+
- test/test_group.rb
|
52
|
+
- test/test_missing.rb
|
53
|
+
- test/test_row.rb
|
54
|
+
- test/test_table.rb
|
55
|
+
test_files:
|
56
|
+
- test/test_banner.rb
|
57
|
+
- test/test_cell.rb
|
58
|
+
- test/test_column.rb
|
59
|
+
- test/test_crosstab.rb
|
60
|
+
- test/test_extensions.rb
|
61
|
+
- test/test_group.rb
|
62
|
+
- test/test_missing.rb
|
63
|
+
- test/test_row.rb
|
64
|
+
- test/test_table.rb
|
65
|
+
rdoc_options:
|
66
|
+
- --main
|
67
|
+
- README.txt
|
68
|
+
extra_rdoc_files:
|
69
|
+
- History.txt
|
70
|
+
- Manifest.txt
|
71
|
+
- README.txt
|
72
|
+
executables: []
|
73
|
+
|
74
|
+
extensions: []
|
75
|
+
|
76
|
+
requirements: []
|
77
|
+
|
78
|
+
dependencies:
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: hoe
|
81
|
+
version_requirement:
|
82
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 1.2.1
|
87
|
+
version:
|