balinterdi-acts_as_trivia 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ v0.1 Initial release.
data/Manifest ADDED
@@ -0,0 +1,24 @@
1
+ CHANGELOG
2
+ generators/acts_as_trivia/acts_as_trivia_generator.rb
3
+ generators/acts_as_trivia/templates/answers_controller.rb
4
+ generators/acts_as_trivia/templates/controller.rb
5
+ generators/acts_as_trivia/templates/trivias_migration.rb
6
+ generators/acts_as_trivia/templates/view.html.erb
7
+ generators/acts_as_trivia/USAGE
8
+ generators/acts_as_trivia_record/acts_as_trivia_record_generator.rb
9
+ generators/acts_as_trivia_record/templates/migration.rb
10
+ generators/acts_as_trivia_record/USAGE
11
+ lib/acts_as_trivia/trivia.rb
12
+ lib/acts_as_trivia/trivia_answer.rb
13
+ lib/acts_as_trivia/trivia_answers_controller.rb
14
+ lib/acts_as_trivia/trivias_helper.rb
15
+ lib/acts_as_trivia/user.rb
16
+ lib/acts_as_trivia.rb
17
+ Manifest
18
+ Rakefile
19
+ README.markdown
20
+ spec/acts_as_trivia_spec.rb
21
+ spec/database.yml
22
+ spec/spec_helper.rb
23
+ tasks/acts_as_trivia.rake
24
+ todos.markdown
data/README.markdown ADDED
@@ -0,0 +1,97 @@
1
+ * NoMethodError (undefined method `acts\_as\_trivia' for #<Class:0x253e9fc>):
2
+
3
+ Make sure you have the config.gem "acts\_as\_trivia" line in your environment.rb
4
+
5
+ * Trivia will have its own model:
6
+
7
+ create_table :trivias, :force => true do |t|
8
+ t.string :on, :null => false
9
+ t.string :about, :null => false
10
+ end
11
+
12
+ e.g
13
+
14
+ Trivia.new(:on => "country", :about => "hdi")
15
+
16
+ class Trivia < ActionRecord::Base
17
+
18
+ def to\_param
19
+ #{on}-#{about} # e.g country-hdi
20
+ end
21
+
22
+ And requests to trivias will have a routing like this:
23
+
24
+ /trivias/1, or which is the same
25
+ /trivias/country-hdi (and that latter will be generated)
26
+
27
+
28
+ * The User class will have the following added associations:
29
+
30
+ class User < ActiveRecord::Base
31
+
32
+ has_many :trivia_answers
33
+ has_many :trivias, :through => :trivia_answers
34
+ has_many :correct_trivia_answers, :through => :trivia_answers, :condition => { "state = ?", 'correct' }
35
+
36
+ * And the join model will be the TriviaAnswers class:
37
+
38
+ create_table :trivia_answers, :force => true do |t|
39
+ t.string :trivia_id, :null => false
40
+ t.string :user_id, :null => false
41
+ t.integer :points # how many points the user received for his answer
42
+ end
43
+
44
+ * when the geneation script is called with the following:
45
+
46
+ ./script/generate acts_as_trivia country hdi
47
+
48
+ then the following things will be generated:
49
+
50
+ * a new trivia model OK
51
+
52
+ class Trivia < ActiveRecord::Base
53
+ def to\_param
54
+ #{on}-#{about} # e.g country-hdi
55
+ end
56
+ end
57
+
58
+ * a new controller (if it does not exist yet) OK
59
+
60
+ class TriviaController
61
+ end
62
+
63
+ * new resource routes for trivia OK
64
+
65
+ map.resources :trivias
66
+
67
+ * in the model (country.rb) OK:
68
+
69
+ class Country < ActiveRecord::Base
70
+ acts_as_trivia :hdi
71
+ ...
72
+ end
73
+
74
+ * added associations in the user model OK
75
+
76
+ has_many :trivia_answers
77
+ has_many :trivias, :through => :trivia_answers
78
+ <!-- has_many :correct_trivia_answers, :through => :trivia_answers, :condition => { "state = ?", 'correct' } -->
79
+
80
+ * db migrations
81
+
82
+ * for the trivia class itself OK
83
+
84
+ create_table :trivias, :force => true do |t|
85
+ t.string :on, :null => false
86
+ t.string :about, :null => false
87
+ t.timestamps
88
+ end
89
+
90
+ * for the join model between the user and the trivia OK
91
+
92
+ create_table :trivia_answers, :force => true do |t|
93
+ t.string :trivia_id, :null => false
94
+ t.string :user_id, :null => false
95
+ t.integer :points # how many points the user received for his answer
96
+ end
97
+
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('acts_as_trivia', '0.1') do |p|
6
+ p.description = <<-EOS
7
+ This gem will add the possibility to turn your Rails application into a trivia game with the ease of generating a migration. The only thing you need is a model class with a sortable attribute and this gem.
8
+ EOS
9
+ p.url = "http://github.com/balinterdi/acts_as_trivia"
10
+ p.author = "Balint Erdi"
11
+ p.email = "balint.erdi@gmail.com"
12
+ p.ignore_pattern = ["tmp/*", "script/*"]
13
+ p.development_dependencies = []
14
+ end
15
+
16
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{acts_as_trivia}
5
+ s.version = "0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Balint Erdi"]
9
+ s.date = %q{2009-05-04}
10
+ s.description = %q{This gem will add the possibility to turn your Rails application into a trivia game with the ease of generating a migration. The only thing you need is a model class with a sortable attribute and this gem.}
11
+ s.email = %q{balint.erdi@gmail.com}
12
+ s.extra_rdoc_files = ["CHANGELOG", "lib/acts_as_trivia/trivia.rb", "lib/acts_as_trivia/trivia_answer.rb", "lib/acts_as_trivia/trivia_answers_controller.rb", "lib/acts_as_trivia/trivias_helper.rb", "lib/acts_as_trivia/user.rb", "lib/acts_as_trivia.rb", "README.markdown", "tasks/acts_as_trivia.rake"]
13
+ s.files = ["CHANGELOG", "generators/acts_as_trivia/acts_as_trivia_generator.rb", "generators/acts_as_trivia/templates/answers_controller.rb", "generators/acts_as_trivia/templates/controller.rb", "generators/acts_as_trivia/templates/trivias_migration.rb", "generators/acts_as_trivia/templates/view.html.erb", "generators/acts_as_trivia/USAGE", "generators/acts_as_trivia_record/acts_as_trivia_record_generator.rb", "generators/acts_as_trivia_record/templates/migration.rb", "generators/acts_as_trivia_record/USAGE", "lib/acts_as_trivia/trivia.rb", "lib/acts_as_trivia/trivia_answer.rb", "lib/acts_as_trivia/trivia_answers_controller.rb", "lib/acts_as_trivia/trivias_helper.rb", "lib/acts_as_trivia/user.rb", "lib/acts_as_trivia.rb", "Manifest", "Rakefile", "README.markdown", "spec/acts_as_trivia_spec.rb", "spec/database.yml", "spec/spec_helper.rb", "tasks/acts_as_trivia.rake", "todos.markdown", "acts_as_trivia.gemspec"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/balinterdi/acts_as_trivia}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Acts_as_trivia", "--main", "README.markdown"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{acts_as_trivia}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{This gem will add the possibility to turn your Rails application into a trivia game with the ease of generating a migration. The only thing you need is a model class with a sortable attribute and this gem.}
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 2
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ else
28
+ end
29
+ else
30
+ end
31
+ end
@@ -0,0 +1,22 @@
1
+ Description:
2
+
3
+ The acts_as_trivia generator will generate a controller for the model class that is given as the first parameter. For each action (trivia question) passed in the command line it will also generate a view with the corresponding name, a route in the routes file and the acts_as_trivia line itself in the model.
4
+
5
+ Example:
6
+ ./script/generate acts_as_trivia country hdi name
7
+ ...
8
+ create app/controllers/country_trivia_controller.rb
9
+ create app/views/country_trivia/hdi.html.erb
10
+ create app/views/country_trivia/population.html.erb
11
+ create app/views/country_trivia/gdp.html.erb
12
+ route map.with_options(:controller => 'country_trivia') do ...
13
+
14
+ In routes.rb it will add the following:
15
+
16
+ ActionController::Routing::Routes.draw do |map|
17
+
18
+ map.with_options(:controller => 'country_trivia') do |trivia|
19
+ trivia.country_hdi_trivia '/countries/trivia/hdi', :action => "hdi"
20
+ trivia.country_hdi_trivia '/countries/trivia/population', :action => "population"
21
+ trivia.country_hdi_trivia '/countries/trivia/hdi', :action => "gdp"
22
+ end
@@ -0,0 +1,110 @@
1
+ require 'rails_generator'
2
+
3
+ module ActsAsTriviaAddedContent
4
+
5
+ def route_trivia_answers_as_nested_resource
6
+ sentinel = "ActionController::Routing::Routes.draw do |map|"
7
+ unless options[:pretend]
8
+ gsub_file "config/routes.rb", /(#{Regexp.escape(sentinel)})/mi do |match|
9
+ <<-EOS
10
+ #{match}
11
+ map.resources :users do |users|
12
+ users.resources :trivias do |trivias|
13
+ trivias.resources :trivia_answers
14
+ end
15
+ end
16
+
17
+ EOS
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ def model_acts_as_trivia_includes(questions)
24
+ acts_as_trivia_calls = questions.map do |question|
25
+ "acts_as_trivia :#{question}"
26
+ end
27
+ logger.modify acts_as_trivia_calls.join(", ")
28
+
29
+ sentinel = "class #{class_name} < ActiveRecord::Base"
30
+ unless options[:pretend]
31
+ gsub_file File.join("app/models", class_path, "#{singular_name}.rb"), /(#{Regexp.escape(sentinel)})/mi do |match|
32
+ <<-EOS
33
+ #{match}
34
+ #{acts_as_trivia_calls.join("\n")}
35
+ EOS
36
+ end
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ class ActsAsTriviaGenerator < Rails::Generator::NamedBase # ControllerGenerator
43
+
44
+ # this is snatched from the resource generator in the Rails source
45
+ default_options :skip_timestamps => false, :skip_migration => false
46
+
47
+ attr_reader :controller_name,
48
+ :controller_class_path,
49
+ :controller_file_path,
50
+ :controller_class_nesting,
51
+ :controller_class_nesting_depth,
52
+ :controller_class_name,
53
+ :controller_singular_name,
54
+ :controller_plural_name
55
+ alias_method :controller_file_name, :controller_singular_name
56
+ alias_method :controller_table_name, :controller_plural_name
57
+
58
+ def initialize(runtime_args, runtime_options = {})
59
+ super
60
+
61
+ @controller_name = @name.pluralize
62
+
63
+ base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
64
+ @controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
65
+
66
+ if @controller_class_nesting.empty?
67
+ @controller_class_name = @controller_class_name_without_nesting
68
+ else
69
+ @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
70
+ end
71
+ end
72
+
73
+ def manifest
74
+ record do |m|
75
+ # Check whether the given class names are already taken by
76
+ # Ruby or Rails. In the future, expand to check other namespaces
77
+ # such as the rest of the user's app.
78
+ # m.class_collisions "Trivia", "TriviaAnswer"
79
+ # m.class_collisions "TriviasController", "TriviaAnswersController"
80
+ m.class_collisions "TriviaTest"
81
+
82
+ # Controller directories.
83
+ m.directory 'app/views/trivias'
84
+ m.directory 'app/views/trivia_answers'
85
+
86
+ # Controllers
87
+ m.template 'controller.rb', 'app/controllers/trivias_controller.rb'
88
+ m.template 'answers_controller.rb', 'app/controllers/trivia_answers_controller.rb'
89
+
90
+ m.route_resources "trivias"
91
+ m.route_trivia_answers_as_nested_resource
92
+
93
+ m.model_acts_as_trivia_includes actions
94
+
95
+ unless options[:skip_migration]
96
+ m.migration_template 'trivias_migration.rb', 'db/migrate', :assigns => {
97
+ :migration_name => "CreateTrivias",
98
+ :trivia_on => singular_name,
99
+ :trivia_about => actions.first,
100
+ :trivia_displayed => actions.last,
101
+ }, :migration_file_name => "create_trivias"
102
+ end
103
+
104
+ path = File.join('app/views/trivias/show.html.erb')
105
+ m.template 'view.html.erb', path
106
+ end
107
+ end
108
+ end
109
+
110
+ Rails::Generator::Commands::Base.send(:include, ActsAsTriviaAddedContent)
@@ -0,0 +1,6 @@
1
+ class TriviaAnswersController < ApplicationController
2
+ def new
3
+ end
4
+ def create
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ class TriviasController < ApplicationController
2
+ def show
3
+ end
4
+ end
@@ -0,0 +1,29 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :trivias do |t|
4
+ t.string :on, :null => false
5
+ t.string :about, :null => false
6
+ t.string :displayed, :null => false
7
+ t.integer :length, :default => 3, :null => false
8
+ <% unless options[:skip_timestamps] %>
9
+ t.timestamps
10
+ <% end -%>
11
+ end
12
+
13
+ create_table :trivia_answers, :force => true do |t|
14
+ t.string :trivia_id, :null => false
15
+ t.string :user_id, :null => false
16
+ t.integer :points
17
+ <% unless options[:skip_timestamps] %>
18
+ t.timestamps
19
+ <% end -%>
20
+ end
21
+
22
+ Trivia.create(:on => <%= %("#{trivia_on}") %>, :about => <%= %("#{trivia_about}") %>, :displayed => <%= %("#{trivia_displayed}") %>)
23
+ end
24
+
25
+ def self.down
26
+ drop_table :trivias
27
+ drop_table :trivia_answers
28
+ end
29
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+
3
+ The acts_as_trivia_record generator creates a trivia record in the database. It should be passed the class on which the trivia operates, the attribute which is the basis of the ranking and the attribute which is displayed when the trivia question is presented.
4
+
5
+ Example:
6
+ ./script/generate acts_as_trivia_record country population name
7
+ ...
8
+
@@ -0,0 +1,12 @@
1
+ class ActsAsTriviaRecordGenerator < Rails::Generator::NamedBase
2
+ def manifest
3
+ record do |m|
4
+ m.migration_template 'migration.rb', 'db/migrate', :assigns => {
5
+ :migration_name => "CreateTriviaFor#{plural_name.capitalize}#{actions.first.capitalize}",
6
+ :trivia_on => singular_name,
7
+ :trivia_about => actions.first,
8
+ :trivia_displayed => actions.last
9
+ }, :migration_file_name => "create_trivia_for_#{plural_name}_#{actions.first}"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ class <%= migration_name %> < ActiveRecord::Migration
2
+ def self.up
3
+ Trivia.create(:on => <%= %("#{trivia_on}") %>, :about => <%= %("#{trivia_about}") %>, :displayed => <%= %("#{trivia_displayed}") %>)
4
+ end
5
+
6
+ def self.down
7
+ end
8
+ end
@@ -0,0 +1,40 @@
1
+ require "acts_as_trivia/trivia"
2
+ require "acts_as_trivia/trivia_answer"
3
+ require "acts_as_trivia/user"
4
+ require "acts_as_trivia/trivias_helper"
5
+
6
+ module ActsAsTrivia
7
+ module ClassMethods
8
+ def acts_as_trivia(method)
9
+ class << self
10
+ define_method(:trivia_answer_for) do |name|
11
+ self.scoped(:order => "#{name} DESC")
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ class << self
18
+ def included(base)
19
+ base.extend(ClassMethods)
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ if Object.const_defined?("ActiveRecord")
26
+ ActiveRecord::Base.send(:include, ActsAsTrivia)
27
+ end
28
+
29
+ #NOTE: at this point, the controllers of the app (e.g TriviaAnswersController) are not yet defined
30
+ # so the helpers can not be included. On the other hand, if I define the controller class here
31
+ # the controller will not be defined in the app and so the actions will not be available.
32
+ # Thus the autoload solution.
33
+ #NOTE: autoload does not play well with the class reloading that Rails does in the dev. environment
34
+ # the helper methods that TriviaAnswersController includes will only be available
35
+ # at the first request after the server request (when autoload is executed)
36
+ # autoload :TriviaAnswersController, "acts_as_trivia/trivia_answers_controller"
37
+
38
+ if Object.const_defined?("ActionView")
39
+ ActionView::Base.send(:include, TriviasHelper)
40
+ end
@@ -0,0 +1,37 @@
1
+ class Trivia < ActiveRecord::Base
2
+ has_many :trivia_answers
3
+
4
+ def to_param
5
+ "#{id}-#{on}-#{about}"
6
+ end
7
+
8
+ def assess_answer_ids(answer_ids)
9
+ assess_answer(trivia_link_class.find(answer_ids))
10
+ end
11
+
12
+ def assess_answer(answer)
13
+ correct_answer = get_solution.scoped(:limit => answer.length)
14
+ score = 0
15
+ answer.each_with_index do |elt, idx|
16
+ score += elt == correct_answer[idx] ? 1 : 0
17
+ end
18
+ score
19
+ end
20
+
21
+ def get_subjects
22
+ trivia_link_class.find(:all)
23
+ end
24
+
25
+ def get_solution_values
26
+ solution = get_solution.scoped(:limit => length)
27
+ solution.map { |elt| [elt.send(displayed.to_sym), elt.send(about.to_sym)] }
28
+ end
29
+
30
+ private
31
+ def get_solution
32
+ trivia_link_class.trivia_answer_for(about.to_sym)
33
+ end
34
+ def trivia_link_class
35
+ on.capitalize.constantize
36
+ end
37
+ end
@@ -0,0 +1,8 @@
1
+ class TriviaAnswer < ActiveRecord::Base
2
+ belongs_to :trivia
3
+ belongs_to :user
4
+
5
+ def assess(answer)
6
+ trivia.assess_answer_ids(answer)
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.join((File.dirname(__FILE__)), 'trivias_helper'))
2
+
3
+ TriviaAnswersController.send(:helper, TriviasHelper)
4
+ # TriviasController.send(:helper, TriviasHelper)
@@ -0,0 +1,18 @@
1
+ module TriviasHelper
2
+ def trivia_user_panel(trivia)
3
+ (1..trivia.length).inject("") { |out, i| out + content_tag(:div, "#{i}. #{trivia_dropdown(trivia)}")}
4
+ # (1..trivia.length).map { content_tag(:div, trivia_dropdown(trivia)) }
5
+ end
6
+ def trivia_dropdown(trivia)
7
+ #TODO: the get_subjects call will query all instances of a model class (e.g Country.find(:all))
8
+ #That may be too exhaustive
9
+ select_tag("#{trivia.on}[#{trivia.about}][]", options_from_collection_for_select(trivia.get_subjects, :id, trivia.displayed.to_sym))
10
+ end
11
+
12
+ def with_each_solution_value(trivia)
13
+ trivia.get_solution_values.each_with_index do |name_and_value, i|
14
+ name, value = name_and_value
15
+ yield i+1, name, value
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ class User < ActiveRecord::Base
2
+ has_many :trivia_answers
3
+ has_many :trivias, :through => :trivia_answers
4
+
5
+ def add_trivia(trivia)
6
+ trivia_answers.create(:trivia => trivia)
7
+ end
8
+
9
+ def played_trivia?(trivia)
10
+ trivias.include?(trivia)
11
+ end
12
+
13
+ def trivia_points
14
+ trivia_answers.sum(:points)
15
+ end
16
+ end
@@ -0,0 +1,144 @@
1
+ require "rubygems"
2
+ require "spec"
3
+ require "mocha"
4
+
5
+ require File.join(File.dirname(__FILE__), 'spec_helper')
6
+
7
+ # use mocha for mocking instead of
8
+ # Rspec's own mock framework
9
+ Spec::Runner.configure do |config|
10
+ config.mock_with :mocha
11
+ end
12
+
13
+ class Country < ActiveRecord::Base
14
+ include ActsAsTrivia
15
+ end
16
+
17
+ describe "A Trivia" do
18
+ before do
19
+ rebuild_trivias_table
20
+ rebuild_countries_table
21
+ @trivia = Trivia.create(:on => "country", :about => "hdi", :displayed => "name", :length => 3)
22
+ Country.class_eval do
23
+ acts_as_trivia :hdi
24
+ end
25
+ @iceland = Country.create(:hdi => 0.968, :name => "Iceland")
26
+ @canada = Country.create(:hdi => 0.967, :name => "Canada")
27
+ @new_zealand = Country.create(:hdi => 0.944, :name => "New Zealand")
28
+ @cyprus = Country.create(:hdi => 0.903, :name => "Cyprus")
29
+ end
30
+
31
+ describe "when assessing" do
32
+ before do
33
+ Country.expects(:find).returns([@iceland, @canada, @new_zealand])
34
+ end
35
+
36
+ it "should give top score for the correct one" do
37
+ score = @trivia.assess_answer([@iceland, @canada, @new_zealand])
38
+ score.should equal(3)
39
+ end
40
+
41
+ it "should give a point for each correct position" do
42
+ score = @trivia.assess_answer([@canada, @iceland, @new_zealand])
43
+ score.should equal(1)
44
+ end
45
+
46
+ it "should return zero if none of the positions is asserted" do
47
+ score = @trivia.assess_answer([@canada, @new_zealand, @iceland])
48
+ score.should equal(0)
49
+ end
50
+ end
51
+
52
+ it "should get the trivia subjects of the right class" do
53
+ Country.expects(:find).with(:all).returns([@iceland, @canada, @new_zealand])
54
+ @trivia.get_subjects
55
+ end
56
+
57
+ describe "fetching the solution" do
58
+ before do
59
+ @solution = @trivia.get_solution_values
60
+ end
61
+ it "should have the length of the trivia" do
62
+ @solution.should have(3).items
63
+ end
64
+ it "should fetch the correct one" do
65
+ @solution.should eql([["Iceland", 0.968], ["Canada", 0.967], ["New Zealand", 0.944]])
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+ describe "A TriviaAnswer" do
72
+ before do
73
+ rebuild_all_tables
74
+ @user = User.create(:login => "bob")
75
+ @trivia = Trivia.create(:on => "country", :about => "hdi", :displayed => "name", :length => 3)
76
+ @trivia_answer = TriviaAnswer.create(:user => @user, :trivia => @trivia)
77
+
78
+ @iceland = Country.create(:hdi => 0.968)
79
+ @canada = Country.create(:hdi => 0.967)
80
+ @new_zealand = Country.create(:hdi => 0.944)
81
+ end
82
+
83
+ describe "being assessed" do
84
+ describe "by ids" do
85
+ it "should return the correct score" do
86
+ @trivia_answer.assess([@iceland.id, @canada.id, @new_zealand.id]).should equal(3)
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "An acts_as_trivia enabled model class" do
93
+ before do
94
+ Country.class_eval do
95
+ acts_as_trivia :hdi
96
+ end
97
+ end
98
+
99
+ it "should respond to the generated trivia accessor" do
100
+ Country.should respond_to(:trivia_answer_for)
101
+ end
102
+ end
103
+
104
+ describe "a user" do
105
+ before do
106
+ rebuild_all_tables
107
+ class User < ActiveRecord::Base
108
+ has_many :trivia_answers
109
+ has_many :trivias, :through => :trivia_answers
110
+ end
111
+ @user = User.create(:login => "bob")
112
+ @trivia = Trivia.create(:on => "country", :about => "hdi", :displayed => "name", :length => 3)
113
+ end
114
+
115
+ it "should be easily added a trivia he played" do
116
+ @user.add_trivia(@trivia)
117
+ @user.trivias.should include(@trivia)
118
+ end
119
+
120
+ it "should return true when asked if played a trivia he played" do
121
+ @user.trivias << @trivia
122
+ @user.played_trivia?(@trivia).should be_true
123
+ end
124
+
125
+ it "should return false when asked if played a trivia he did not play" do
126
+ another_trivia = Trivia.create(:on => "country", :about => "population")
127
+ @user.played_trivia?(another_trivia).should be_false
128
+ end
129
+
130
+ it "should have 0 trivia points when he has not played any trivia" do
131
+ @user.trivia_answers = []
132
+ @user.trivia_points.should eql(0)
133
+ end
134
+
135
+ it "should be able to tell the total trivia points he earned" do
136
+ a_trivia = Trivia.create(:on => "country", :about => "hdi")
137
+ another_trivia = Trivia.create(:on => "country", :about => "population")
138
+ @user.trivia_answers.create(:trivia => a_trivia, :points => 2)
139
+ @user.trivia_answers.create(:trivia => another_trivia, :points => 3)
140
+ @user.trivia_points.should eql(5)
141
+ end
142
+
143
+ end
144
+
data/spec/database.yml ADDED
@@ -0,0 +1,3 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: ":memory:"
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require "active_record"
3
+
4
+ # setting up test environment is snatched from how Paperclip does it
5
+ ROOT = File.join(File.dirname(__FILE__), '..')
6
+ $LOAD_PATH << File.join(ROOT, 'lib')
7
+ $LOAD_PATH << File.join(ROOT, 'lib', 'acts_as_trivia')
8
+
9
+ require File.join(ROOT, "lib", "acts_as_trivia.rb")
10
+
11
+ ENV['RAILS_ENV'] ||= 'test'
12
+
13
+ config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
14
+ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
15
+ ActiveRecord::Base.establish_connection(config['test'])
16
+
17
+ def rebuild_trivias_table
18
+ ActiveRecord::Base.connection.create_table :trivias, :force => true do |table|
19
+ table.column :on, :string
20
+ table.column :about, :string
21
+ table.column :displayed, :string
22
+ table.column :length, :integer
23
+ end
24
+ end
25
+
26
+ def rebuild_trivia_answers_table
27
+ ActiveRecord::Base.connection.create_table :trivia_answers, :force => true do |table|
28
+ table.column :user_id, :string
29
+ table.column :trivia_id, :string
30
+ table.column :points, :integer, :default => 0
31
+ end
32
+ end
33
+
34
+ def rebuild_countries_table
35
+ ActiveRecord::Base.connection.create_table :countries, :force => true do |table|
36
+ table.column :hdi, :float
37
+ table.column :population, :integer
38
+ table.column :area, :integer
39
+ table.column :name, :string
40
+ end
41
+ end
42
+
43
+ def rebuild_users_table
44
+ ActiveRecord::Base.connection.create_table :users, :force => true do |table|
45
+ table.column :login, :string
46
+ end
47
+ end
48
+
49
+ def rebuild_all_tables
50
+ rebuild_trivias_table
51
+ rebuild_trivia_answers_table
52
+ rebuild_countries_table
53
+ rebuild_users_table
54
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec/rake/spectask'
2
+
3
+ desc "Run all specs"
4
+ Spec::Rake::SpecTask.new('spec') do |t|
5
+ t.spec_files = FileList['spec/**/*spec.rb']
6
+ end
data/todos.markdown ADDED
@@ -0,0 +1,26 @@
1
+ TODO
2
+ ====
3
+
4
+ * the show action of the trivia should only be shown to users who have already played that trivia.
5
+ * set up a template to generate a country-trivia site for quick testing
6
+ * find a solution so that the methods defined in TriviasHelper are only available to the trivias and trivia_answers controller. Currently, it is available to all controllers. Maybe set up an app structure in the gem like in tog plugins? (In tog plugins, controllers in the host app can extend/overwrite those defined in the plugin)
7
+
8
+ DONE
9
+ ====
10
+
11
+ * a user should not be able to answer a question more than once
12
+ * rewrite the trivia_answer/assess spec to actually test the result, not the delegation
13
+ * the @trivia.length.times <%= trivia_dropdown(@trivia) %> could be rewritten into a simpler <%= trivia_panel(@trivia) %> helper.
14
+ * autoload does not play well with Rails's autoload in dev. environment, so it has to be rewritten
15
+ * the show action of the trivia should show the correct solution and the page should
16
+ * the trivia will have to include how many items have to be asserted (that is, the length of the trivia) since that has to be known on many screens. A sensitive default can be three. Rewrite methods where an actual number is written instead of this value.
17
+ * get the trivia and trivia answer views use the trivias_helper.rb file and so helper.rb does not have to be generated into the host app's code
18
+ * the show page of the trivia answer should show the solution of the trivia and mark which ones the user got right. After a user answered a trivia question, the redirect should land here. So does the answer have to be stored in the TriviaAnswer instance to make this detailed assessment? The other solution is to tell him how many he got right and then have a link to the trivia where the solution is presented.
19
+ The solution should not be stored in the trivia answer. Rather, the show action of the trivia should show the correct solution and the page should only be shown to users who have already played that trivia.
20
+
21
+ * generate a migration that creates the trivia record(s) itself (themselves)
22
+
23
+ e.g Trivia.create(:on => "country", :about => "hdi")
24
+
25
+ This generator can be another one since this one should be called for each subsequent trivia question the developer comes up with.
26
+
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: balinterdi-acts_as_trivia
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Balint Erdi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-05-04 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: This gem will add the possibility to turn your Rails application into a trivia game with the ease of generating a migration. The only thing you need is a model class with a sortable attribute and this gem.
17
+ email: balint.erdi@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - CHANGELOG
24
+ - lib/acts_as_trivia/trivia.rb
25
+ - lib/acts_as_trivia/trivia_answer.rb
26
+ - lib/acts_as_trivia/trivia_answers_controller.rb
27
+ - lib/acts_as_trivia/trivias_helper.rb
28
+ - lib/acts_as_trivia/user.rb
29
+ - lib/acts_as_trivia.rb
30
+ - README.markdown
31
+ - tasks/acts_as_trivia.rake
32
+ files:
33
+ - CHANGELOG
34
+ - generators/acts_as_trivia/acts_as_trivia_generator.rb
35
+ - generators/acts_as_trivia/templates/answers_controller.rb
36
+ - generators/acts_as_trivia/templates/controller.rb
37
+ - generators/acts_as_trivia/templates/trivias_migration.rb
38
+ - generators/acts_as_trivia/templates/view.html.erb
39
+ - generators/acts_as_trivia/USAGE
40
+ - generators/acts_as_trivia_record/acts_as_trivia_record_generator.rb
41
+ - generators/acts_as_trivia_record/templates/migration.rb
42
+ - generators/acts_as_trivia_record/USAGE
43
+ - lib/acts_as_trivia/trivia.rb
44
+ - lib/acts_as_trivia/trivia_answer.rb
45
+ - lib/acts_as_trivia/trivia_answers_controller.rb
46
+ - lib/acts_as_trivia/trivias_helper.rb
47
+ - lib/acts_as_trivia/user.rb
48
+ - lib/acts_as_trivia.rb
49
+ - Manifest
50
+ - Rakefile
51
+ - README.markdown
52
+ - spec/acts_as_trivia_spec.rb
53
+ - spec/database.yml
54
+ - spec/spec_helper.rb
55
+ - tasks/acts_as_trivia.rake
56
+ - todos.markdown
57
+ - acts_as_trivia.gemspec
58
+ has_rdoc: true
59
+ homepage: http://github.com/balinterdi/acts_as_trivia
60
+ post_install_message:
61
+ rdoc_options:
62
+ - --line-numbers
63
+ - --inline-source
64
+ - --title
65
+ - Acts_as_trivia
66
+ - --main
67
+ - README.markdown
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "1.2"
81
+ version:
82
+ requirements: []
83
+
84
+ rubyforge_project: acts_as_trivia
85
+ rubygems_version: 1.2.0
86
+ signing_key:
87
+ specification_version: 2
88
+ summary: This gem will add the possibility to turn your Rails application into a trivia game with the ease of generating a migration. The only thing you need is a model class with a sortable attribute and this gem.
89
+ test_files: []
90
+