census 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +5 -0
  3. data/Rakefile +70 -0
  4. data/VERSION +1 -0
  5. data/app/controllers/census/data_groups_controller.rb +44 -0
  6. data/app/helpers/census_helper.rb +15 -0
  7. data/app/models/answer.rb +43 -0
  8. data/app/models/choice.rb +9 -0
  9. data/app/models/data_group.rb +10 -0
  10. data/app/models/question.rb +54 -0
  11. data/app/views/census/_question_fields.html.erb +40 -0
  12. data/app/views/census/_user_answers.html.erb +10 -0
  13. data/app/views/census/_user_questions.html.erb +10 -0
  14. data/app/views/census/data_groups/_choice_fields.html.erb +4 -0
  15. data/app/views/census/data_groups/_form.html.erb +11 -0
  16. data/app/views/census/data_groups/_question_fields.html.erb +22 -0
  17. data/app/views/census/data_groups/edit.html.erb +7 -0
  18. data/app/views/census/data_groups/index.html.erb +10 -0
  19. data/app/views/census/data_groups/new.html.erb +7 -0
  20. data/config/routes.rb +8 -0
  21. data/generators/census/USAGE +1 -0
  22. data/generators/census/census_generator.rb +39 -0
  23. data/generators/census/lib/insert_commands.rb +33 -0
  24. data/generators/census/lib/rake_commands.rb +22 -0
  25. data/generators/census/templates/README +29 -0
  26. data/generators/census/templates/census.js +10 -0
  27. data/generators/census/templates/census.rb +14 -0
  28. data/generators/census/templates/factories.rb +24 -0
  29. data/generators/census/templates/migrations/with_users.rb +60 -0
  30. data/generators/census/templates/migrations/without_users.rb +54 -0
  31. data/generators/census/templates/user.rb +3 -0
  32. data/lib/census/data_type.rb +33 -0
  33. data/lib/census/user.rb +85 -0
  34. data/lib/census.rb +1 -0
  35. data/rails/init.rb +7 -0
  36. data/shoulda_macros/census.rb +35 -0
  37. data/test/controllers/data_groups_controller_test.rb +165 -0
  38. data/test/models/answer_test.rb +44 -0
  39. data/test/models/choice_test.rb +24 -0
  40. data/test/models/data_group_test.rb +12 -0
  41. data/test/models/question_test.rb +213 -0
  42. data/test/models/user_test.rb +9 -0
  43. data/test/rails_root/app/controllers/application_controller.rb +10 -0
  44. data/test/rails_root/app/helpers/application_helper.rb +3 -0
  45. data/test/rails_root/app/models/user.rb +3 -0
  46. data/test/rails_root/config/boot.rb +110 -0
  47. data/test/rails_root/config/environment.rb +8 -0
  48. data/test/rails_root/config/environments/development.rb +17 -0
  49. data/test/rails_root/config/environments/production.rb +28 -0
  50. data/test/rails_root/config/environments/test.rb +32 -0
  51. data/test/rails_root/config/initializers/backtrace_silencers.rb +7 -0
  52. data/test/rails_root/config/initializers/census.rb +14 -0
  53. data/test/rails_root/config/initializers/inflections.rb +10 -0
  54. data/test/rails_root/config/initializers/mime_types.rb +5 -0
  55. data/test/rails_root/config/initializers/new_rails_defaults.rb +21 -0
  56. data/test/rails_root/config/initializers/session_store.rb +15 -0
  57. data/test/rails_root/config/routes.rb +43 -0
  58. data/test/rails_root/db/migrate/20100406160306_create_census_tables.rb +60 -0
  59. data/test/rails_root/db/schema.rb +58 -0
  60. data/test/rails_root/test/factories/census.rb +24 -0
  61. data/test/rails_root/test/performance/browsing_test.rb +9 -0
  62. data/test/rails_root/test/test_helper.rb +38 -0
  63. data/test/rails_root/vendor/gems/acts_as_list-0.1.2/lib/acts_as_list.rb +254 -0
  64. data/test/rails_root/vendor/gems/acts_as_list-0.1.2/test/list_test.rb +369 -0
  65. data/test/rails_root/vendor/gems/inverse_of-0.0.1/install.rb +1 -0
  66. data/test/rails_root/vendor/gems/inverse_of-0.0.1/lib/inverse_of.rb +293 -0
  67. data/test/rails_root/vendor/gems/inverse_of-0.0.1/rails/init.rb +1 -0
  68. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/cases/helper.rb +28 -0
  69. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/cases/inverse_associations_test.rb +567 -0
  70. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/club.rb +13 -0
  71. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/face.rb +7 -0
  72. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/interest.rb +5 -0
  73. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/man.rb +9 -0
  74. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/sponsor.rb +4 -0
  75. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/models/zine.rb +3 -0
  76. data/test/rails_root/vendor/gems/inverse_of-0.0.1/test/schema/schema.rb +32 -0
  77. data/test/rails_root/vendor/gems/inverse_of-0.0.1/uninstall.rb +1 -0
  78. data/test/test_helper.rb +19 -0
  79. metadata +190 -0
@@ -0,0 +1,54 @@
1
+ class CreateCensusTables < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :data_groups do |t|
4
+ t.string :name
5
+ t.integer :position
6
+ t.timestamps
7
+ end
8
+
9
+ create_table :questions do |t|
10
+ t.integer :data_group_id
11
+ t.string :data_type
12
+ t.string :prompt
13
+ t.boolean :multiple
14
+ t.boolean :other
15
+ t.integer :position
16
+ t.timestamps
17
+ end
18
+
19
+ add_index :questions, :data_group_id
20
+
21
+ create_table :choices do |t|
22
+ t.integer :question_id
23
+ t.string :value
24
+ t.integer :position
25
+ t.timestamps
26
+ end
27
+
28
+ add_index :choices, :question_id
29
+
30
+ create_table :answers do |t|
31
+ t.integer :question_id
32
+ t.integer :user_id
33
+ t.string :data
34
+ end
35
+
36
+ add_index :answers, :question_id
37
+ add_index :answers, :user_id
38
+
39
+ end
40
+
41
+ def self.down
42
+ remove_index :answers, :question_id
43
+ remove_index :answers, :user_id
44
+ drop_table :answers
45
+
46
+ remove_index :choices, :question_id
47
+ drop_table :choices
48
+
49
+ remove_index :questions, :data_group_id
50
+ drop_table :questions
51
+
52
+ drop_table :data_groups
53
+ end
54
+ end
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ include Census::User
3
+ end
@@ -0,0 +1,33 @@
1
+ module Census
2
+ class DataType
3
+ attr_accessor :name
4
+ attr_accessor :sql_transform
5
+ attr_accessor :format_data
6
+ attr_accessor :validate_data
7
+
8
+ @@data_types = []
9
+
10
+ def self.all
11
+ @@data_types
12
+ end
13
+
14
+ def self.define(name, options = {})
15
+ @@data_types << DataType.new(name, options)
16
+ end
17
+
18
+ def self.find(name)
19
+ @@data_types.select {|dt| dt.name == name}.try(:first)
20
+ end
21
+
22
+ def initialize(name, options)
23
+ @name = name
24
+ @sql_transform = options[:sql_transform] || lambda {|column_name| "#{column_name}"}
25
+ @format_data = options[:format_data] || lambda {|data| data}
26
+ @validate_data = options[:validate_data] || lambda {|data| nil}
27
+ end
28
+
29
+ def to_s
30
+ @name
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,85 @@
1
+ module Census
2
+ module User
3
+
4
+ # Hook for all Census::User modules.
5
+ #
6
+ # If you need to override parts of Census::User,
7
+ # extend and include à la carte.
8
+ #
9
+ # @example
10
+ # extend ClassMethods
11
+ # include InstanceMethods
12
+ # include Callbacks
13
+ #
14
+ # @see ClassMethods
15
+ # @see InstanceMethods
16
+ # @see Callbacks
17
+ def self.included(model)
18
+ model.extend(ClassMethods)
19
+
20
+ model.send(:include, InstanceMethods)
21
+ model.send(:include, Associations)
22
+ model.send(:include, Callbacks)
23
+ end
24
+
25
+ module Associations
26
+ # Hook for defining associations.
27
+ def self.included(model)
28
+ model.class_eval do
29
+ has_many :answers, :dependent => :destroy
30
+ accepts_nested_attributes_for :answers, :reject_if => lambda { |a| a[:data].blank? }
31
+ end
32
+ end
33
+ end
34
+
35
+ module Callbacks
36
+ # Hook for callbacks.
37
+ #
38
+ # empty answers are removed after_save.
39
+ def self.included(model)
40
+ model.class_eval do
41
+ after_save :remove_empty_answers
42
+ end
43
+ end
44
+ end
45
+
46
+ module InstanceMethods
47
+ #
48
+ # Returns this user's first answer for the given question, or a new empty
49
+ # answer if the user has not answered the question.
50
+ #
51
+ def first_answer_for(question)
52
+ answers.select {|a| a.question == question}.first || answers.build(:question => question, :data => '')
53
+ end
54
+
55
+ #
56
+ # Returns an array of this user's answers for the given question. The returned
57
+ # array will be empty if the user has not answered this question.
58
+ #
59
+ def all_answers_for(question)
60
+ answers.select {|a| a.question == question}
61
+ end
62
+
63
+ #
64
+ # Returns this user's answer for a specific choice under a multiple-choice
65
+ # question, or a new empty answer if the user did not select the given choice.
66
+ #
67
+ def answer_for_choice(choice)
68
+ answers.select {|a| a.question == choice.question && a.data == choice.value}.first || answers.build(:question => choice.question, :data => '')
69
+ end
70
+
71
+ private
72
+
73
+ #
74
+ # After save callback, used to remove blank answers
75
+ #
76
+ def remove_empty_answers
77
+ answers.each {|answer| answer.destroy if answer.data.blank? }
78
+ end
79
+ end
80
+
81
+ module ClassMethods
82
+ end
83
+
84
+ end
85
+ end
data/lib/census.rb ADDED
@@ -0,0 +1 @@
1
+ require 'census/user'
data/rails/init.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'acts_as_list'
2
+ require 'inverse_of'
3
+ require 'census'
4
+
5
+ config.to_prepare do
6
+ ApplicationController.helper(CensusHelper)
7
+ end
@@ -0,0 +1,35 @@
1
+ module Census
2
+ module Shoulda
3
+
4
+ def should_accept_nested_attributes_for(*attr_names)
5
+ klass = self.name.gsub(/Test$/, '').constantize
6
+
7
+ context "#{klass}" do
8
+ attr_names.each do |association_name|
9
+ should "accept nested attrs for #{association_name}" do
10
+ meth = "#{association_name}_attributes="
11
+ assert ([meth,meth.to_sym].any?{ |m| klass.instance_methods.include?(m) }),
12
+ "#{klass} does not accept nested attributes for #{association_name}"
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ def should_act_as_list
19
+ klass = self.name.gsub(/Test$/, '').constantize
20
+
21
+ context "To support acts_as_list" do
22
+ should_have_db_column('position', :type => :integer)
23
+ end
24
+
25
+ should "include ActsAsList methods" do
26
+ assert klass.include?(ActsAsList::InstanceMethods)
27
+ end
28
+
29
+ should_have_instance_methods :acts_as_list_class, :position_column, :scope_condition
30
+ end
31
+
32
+ end
33
+ end
34
+
35
+ Test::Unit::TestCase.extend(Census::Shoulda)
@@ -0,0 +1,165 @@
1
+ require 'test_helper'
2
+
3
+ class DataGroupsControllerTest < ActionController::TestCase
4
+
5
+ tests Census::DataGroupsController
6
+
7
+ should_route :get, '/census/admin',
8
+ :controller => 'census/data_groups', :action => 'index'
9
+
10
+ should_route :get, '/census/data_groups/new',
11
+ :controller => 'census/data_groups', :action => 'new'
12
+
13
+ should_route :post, '/census/data_groups',
14
+ :controller => 'census/data_groups', :action => 'create'
15
+
16
+ should_route :get, '/census/data_groups/1/edit',
17
+ :controller => 'census/data_groups', :action => 'edit', :id => '1'
18
+
19
+ should_route :put, '/census/data_groups/1',
20
+ :controller => 'census/data_groups', :action => 'update', :id => '1'
21
+
22
+ should_route :delete, '/census/data_groups/1',
23
+ :controller => 'census/data_groups', :action => 'destroy', :id => '1'
24
+
25
+ context 'The Census::DataGroupsController' do
26
+
27
+ context 'using GET to index' do
28
+
29
+ setup do
30
+ @group = Factory(:data_group)
31
+ get :index
32
+ end
33
+
34
+ should_respond_with :success
35
+ should_respond_with_content_type :html
36
+ should_render_template :index
37
+ should_assign_to :data_groups
38
+
39
+ end
40
+
41
+ context 'using GET to new' do
42
+
43
+ setup do
44
+ get :new
45
+ end
46
+
47
+ should_respond_with :success
48
+ should_respond_with_content_type :html
49
+ should_render_template :new
50
+ should_assign_to :data_group
51
+
52
+ should 'have a new data group record' do
53
+ assert assigns(:data_group).new_record?
54
+ end
55
+
56
+ end
57
+
58
+ context 'using POST to create' do
59
+
60
+ context 'with invalid attributes' do
61
+
62
+ setup do
63
+ DataGroup.any_instance.stubs(:valid?).returns(false)
64
+ post :create, :data_group => Factory.attributes_for(:data_group)
65
+ end
66
+
67
+ should_respond_with :unprocessable_entity
68
+ should_respond_with_content_type :html
69
+ should_render_template :new
70
+ should_assign_to :data_group
71
+
72
+ should 'not create the data group' do
73
+ assert assigns(:data_group).new_record?
74
+ end
75
+
76
+ end
77
+
78
+ context 'with valid attributes' do
79
+
80
+ setup do
81
+ post :create, :data_group => Factory.attributes_for(:data_group)
82
+ end
83
+
84
+ should_respond_with :redirect
85
+ should_assign_to :data_group
86
+ should_redirect_to('census admin page') { census_admin_url }
87
+
88
+ should 'create the data group' do
89
+ assert !assigns(:data_group).new_record?
90
+ end
91
+
92
+ end
93
+
94
+ end
95
+
96
+ context 'using GET to edit' do
97
+
98
+ setup do
99
+ @group = Factory(:data_group)
100
+ get :edit, :id => @group.to_param
101
+ end
102
+
103
+ should_respond_with :success
104
+ should_respond_with_content_type :html
105
+ should_render_template :edit
106
+ should_assign_to(:data_group) { @group }
107
+
108
+ end
109
+
110
+ context 'using PUT to update' do
111
+
112
+ context 'with valid attributes' do
113
+
114
+ setup do
115
+ @group = Factory(:data_group)
116
+ put :update, :id => @group.to_param, :data_group => {:name => 'CHANGED'}
117
+ end
118
+
119
+ should_respond_with :redirect
120
+ should_assign_to(:data_group) { @group }
121
+ should_redirect_to('census admin page') { census_admin_url }
122
+
123
+ should 'update the data group' do
124
+ assert_equal('CHANGED', @group.reload.name)
125
+ end
126
+
127
+ end
128
+
129
+ context 'with invalid attributes' do
130
+
131
+ setup do
132
+ @group = Factory(:data_group)
133
+ DataGroup.any_instance.stubs(:valid? => false)
134
+ put :update, :id => @group.to_param, :data_group => {:name => 'CHANGED'}
135
+ end
136
+
137
+ should_respond_with :unprocessable_entity
138
+ should_respond_with_content_type :html
139
+ should_assign_to(:data_group) { @group }
140
+ should_render_template :edit
141
+
142
+ end
143
+
144
+ end
145
+
146
+ context 'using DELETE to destroy' do
147
+
148
+ setup do
149
+ @group = Factory(:data_group)
150
+ delete :destroy, :id => @group.to_param
151
+ end
152
+
153
+ should_respond_with :redirect
154
+ should_assign_to(:data_group) { @group }
155
+ should_redirect_to('census admin page') { census_admin_url }
156
+
157
+ should 'destroy the data group' do
158
+ assert_nil(DataGroup.find_by_id(@group.id))
159
+ end
160
+
161
+ end
162
+
163
+ end
164
+
165
+ end
@@ -0,0 +1,44 @@
1
+ require 'test_helper'
2
+
3
+ class AnswerTest < ActiveSupport::TestCase
4
+
5
+ context "An Answer" do
6
+
7
+ setup do
8
+ @answer = Factory(:answer)
9
+ end
10
+
11
+ subject { @answer }
12
+
13
+ should_belong_to :question
14
+ should_belong_to :user
15
+
16
+ should_validate_presence_of :question,
17
+ :user
18
+
19
+ should_allow_mass_assignment_of :data
20
+
21
+ context "getting formatted data" do
22
+
23
+ should "format strings" do
24
+ a = Factory(:answer, :question => Factory(:question, :data_type => 'String'), :data => 'abc123')
25
+ assert_equal 'abc123', a.formatted_data
26
+ end
27
+
28
+ should "format numbers" do
29
+ a = Factory(:answer, :question => Factory(:question, :data_type => 'Number'), :data => '5389')
30
+ assert_equal 5389, a.formatted_data
31
+ end
32
+
33
+ should "format booleans" do
34
+ a = Factory(:answer, :question => Factory(:question, :data_type => 'Yes/No'), :data => '0')
35
+ assert_equal false, a.formatted_data
36
+ a.data = '1'
37
+ assert_equal true, a.formatted_data
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ class ChoiceTest < ActiveSupport::TestCase
4
+
5
+ context "A Choice" do
6
+
7
+ setup do
8
+ @choice = Factory(:choice)
9
+ end
10
+
11
+ subject { @choice }
12
+
13
+ should_belong_to :question
14
+
15
+ should_act_as_list
16
+
17
+ should_validate_presence_of :value,
18
+ :question
19
+
20
+ should_allow_mass_assignment_of :value
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,12 @@
1
+ require 'test_helper'
2
+
3
+ class DataGroupTest < ActiveSupport::TestCase
4
+
5
+ should_have_many :questions, :dependent => :destroy
6
+ should_accept_nested_attributes_for :questions
7
+
8
+ should_validate_presence_of :name
9
+
10
+ should_act_as_list
11
+
12
+ end
@@ -0,0 +1,213 @@
1
+ require 'test_helper'
2
+
3
+ class QuestionTest < ActiveSupport::TestCase
4
+
5
+ context "A Question" do
6
+
7
+ setup do
8
+ @question = Factory(:question)
9
+ end
10
+
11
+ subject { @question }
12
+
13
+ should_belong_to :data_group
14
+ should_have_many :choices, :dependent => :destroy
15
+ should_have_many :answers, :dependent => :destroy
16
+
17
+ should_act_as_list
18
+
19
+ should_validate_presence_of :prompt,
20
+ :data_group
21
+
22
+ should_allow_mass_assignment_of :data_type,
23
+ :prompt,
24
+ :multiple,
25
+ :other
26
+
27
+ should_accept_nested_attributes_for :choices
28
+
29
+ should "return a default sql transform" do
30
+ assert '"?"', @question.sql_transform
31
+ end
32
+
33
+ context "with choices" do
34
+
35
+ setup do
36
+ @choice1 = Factory(:choice, :value => 'Choice 1', :question => @question)
37
+ @choice2 = Factory(:choice, :value => 'Choice 2', :question => @question)
38
+ @choice3 = Factory(:choice, :value => 'Choice 3', :question => @question)
39
+ end
40
+
41
+ should "allow answers that match the choices" do
42
+ assert Factory.build(:answer, :question => @question, :data => 'Choice 1').valid?
43
+ assert Factory.build(:answer, :question => @question, :data => 'Choice 3').valid?
44
+ end
45
+
46
+ should "not allow answers that don't match the choices" do
47
+ assert !Factory.build(:answer, :question => @question, :data => 'Blah').valid?
48
+ end
49
+
50
+ context "that allows user-supplied 'other' answer" do
51
+
52
+ setup do
53
+ @question.update_attribute(:other, true)
54
+ end
55
+
56
+ should "allow answers that don't match the choices" do
57
+ assert Factory.build(:answer, :question => @question, :data => 'Blah').valid?
58
+ end
59
+
60
+ end
61
+
62
+ end
63
+
64
+ context "that can't have multiple answers" do
65
+
66
+ setup do
67
+ @question.update_attribute(:multiple, false)
68
+ @user = Factory(:user)
69
+ end
70
+
71
+ should "not be able to create multiple answers" do
72
+ assert @question.answers.create(:data => 'Answer 1', :user => @user)
73
+ assert !Factory.build(:answer, :question => @question, :data => 'Answer 2', :user => @user).valid?
74
+ end
75
+
76
+ end
77
+
78
+ context "that can have multiple answers" do
79
+
80
+ setup do
81
+ @question.update_attribute(:multiple, true)
82
+ end
83
+
84
+ should "be able to create multiple answers" do
85
+ assert @question.answers.create(:data => 'Answer 1')
86
+ assert @question.answers.create(:data => 'Answer 2')
87
+ end
88
+
89
+ end
90
+
91
+ context "with String data type" do
92
+
93
+ setup do
94
+ @question.data_type = 'String'
95
+ end
96
+
97
+ should "return a default sql transform" do
98
+ assert_equal "?", @question.sql_transform
99
+ end
100
+
101
+ context "with answers" do
102
+
103
+ setup do
104
+ @answer1 = Factory(:answer, :question => @question, :data => 'findme')
105
+ @answer2 = Factory(:answer, :question => @question, :data => 'dont_findme')
106
+ @answer3 = Factory(:answer, :question => @question, :data => 'findme_too')
107
+ end
108
+
109
+ should "find answers matching a given string" do
110
+ assert @question.find_answers_matching('findme').include?(@answer1)
111
+ end
112
+
113
+ should "not find answers not matching the given string" do
114
+ assert !@question.find_answers_matching('findme').include?(@answer2)
115
+ end
116
+
117
+ should "find answers matching an array of strings" do
118
+ result = @question.find_answers_matching(['findme', 'findme_too'])
119
+ assert result.include?(@answer1)
120
+ assert result.include?(@answer3)
121
+ assert !result.include?(@answer2)
122
+ end
123
+
124
+ end
125
+
126
+ end
127
+
128
+ context "with Number data type" do
129
+
130
+ setup do
131
+ @question.data_type = 'Number'
132
+ end
133
+
134
+ should "return an integer sql transform" do
135
+ assert_equal "CAST(? AS SIGNED INTEGER)", @question.sql_transform
136
+ end
137
+
138
+ context "with answers" do
139
+
140
+ setup do
141
+ @answer1 = Factory(:answer, :question => @question, :data => '123')
142
+ @answer2 = Factory(:answer, :question => @question, :data => '125')
143
+ @answer3 = Factory(:answer, :question => @question, :data => '127')
144
+ end
145
+
146
+ should "find answers matching a given string" do
147
+ assert @question.find_answers_matching('123').include?(@answer1)
148
+ end
149
+
150
+ should "not find answers not matching the given string" do
151
+ assert !@question.find_answers_matching('123').include?(@answer2)
152
+ end
153
+
154
+ should "find answers matching a given number" do
155
+ assert @question.find_answers_matching(123).include?(@answer1)
156
+ end
157
+
158
+ should "not find answers not matching the given number" do
159
+ assert !@question.find_answers_matching(123).include?(@answer2)
160
+ end
161
+
162
+ should "find answers in a given range" do
163
+ result = @question.find_answers_matching(123..126)
164
+ assert result.include?(@answer1)
165
+ assert result.include?(@answer2)
166
+ assert !result.include?(@answer3)
167
+ end
168
+
169
+ end
170
+
171
+ end
172
+
173
+ context "with Yes/No data type" do
174
+
175
+ setup do
176
+ @question.data_type = 'Yes/No'
177
+ end
178
+
179
+ should "return a boolean sql transform" do
180
+ assert_equal "CAST(? AS CHAR)", @question.sql_transform
181
+ end
182
+
183
+ context "with answers" do
184
+
185
+ setup do
186
+ @answer1 = Factory(:answer, :question => @question)
187
+ @answer1.update_attribute(:data, false)
188
+ @answer2 = Factory(:answer, :question => @question, :data => true)
189
+ end
190
+
191
+ should "find answers matching true" do
192
+ assert @question.find_answers_matching(true).include?(@answer2)
193
+ end
194
+
195
+ should "not find answers not matching true" do
196
+ assert !@question.find_answers_matching(true).include?(@answer1)
197
+ end
198
+
199
+ should "find answers matching false" do
200
+ assert @question.find_answers_matching(false).include?(@answer1)
201
+ end
202
+
203
+ should "not find answers not matching false" do
204
+ assert !@question.find_answers_matching(false).include?(@answer2)
205
+ end
206
+
207
+ end
208
+
209
+ end
210
+
211
+ end
212
+
213
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ class UserTest < ActiveSupport::TestCase
4
+
5
+ should_have_many :answers, :dependent => :destroy
6
+ should_accept_nested_attributes_for :answers
7
+ should_allow_mass_assignment_of :answers_attributes
8
+
9
+ end