robut-quiz 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,6 +1,7 @@
1
1
  source :rubygems
2
2
 
3
- gem 'robut'
3
+ gem 'robut', :git => 'git://github.com/substantial/robut.git',
4
+ :ref => '37de65af7c42ea691f3e76e8952a5821b8170be0'
4
5
 
5
6
  group :test do
6
7
  gem 'rspec'
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ === 0.2.0 / 2011-10-26
2
+
3
+ * Changed the question syntax
4
+ * Added a range question (1..5)
5
+
1
6
  === 0.1.0 / 2011-10-23
2
7
 
3
8
  * Initial Release
data/lib/polar.rb CHANGED
@@ -32,8 +32,8 @@ class Robut::Plugin::Quiz::Polar
32
32
  "#{yes_votes} YES vote#{yes_votes != 1 ? 's' : ''} and #{no_votes} NO vote#{no_votes != 1 ? 's' : ''}"
33
33
  end
34
34
 
35
- def captured_results
36
- @captured_results ||= {}
35
+ def ask
36
+ "@all Question '#{@question}' (yes/no)"
37
37
  end
38
38
 
39
39
  def store_positive_response_for sender_nick
data/lib/question.rb CHANGED
@@ -2,38 +2,63 @@
2
2
 
3
3
  module Robut::Plugin::Quiz::Question
4
4
 
5
- # @see ask%20%3F(choice%7Cpolar%7Cscale)%3F%20(%3F%3Aquestion%20)%3F'(%5B%5E'%5D%2B)'%5B%5Cs%2C%5D*((%3F%3A'%5B%5E'%5D%2B'%5B%5Cs%2C%5D*)*)%2B(%3F%3A(%3F%3Afor%20)%3F(%5Cd%2B)%20minutes%3F)%3F
6
- #
7
- # 1st: question type - choice, polar, scale
8
- # 2nd: question
9
- # 3rd: choices
10
- #
11
- QUESTION_REGEX = /^ask ?(choice|polar|scale)? (?:question )?['"]([^'"]+)['"][\s,]*((?:['"][^'"]+['"][\s,]*)*)*(?:(?:for )?(\d+) minutes?)?$/
12
-
13
5
  # This regex will find all the questions and parameters specified with the question
14
6
  GROUP_REGEX = /['"]([^'"]+)['"]/
15
7
 
16
- def initialize(sender,request)
8
+ #
9
+ # Initialize the question with the asker of the question and the details about
10
+ # question that is being asked.
11
+ #
12
+ # @param [String] sender the name of the person asking the question.
13
+ # @param [String] question_with_parameters this is the remaining question and
14
+ # parameters left on the question posed to the chat room.
15
+ #
16
+ def initialize(sender,question_with_parameters)
17
17
  @sender = sender
18
- process_question(request)
18
+ process_question(question_with_parameters)
19
19
  end
20
20
 
21
- def process_question(request)
21
+ #
22
+ # This is used internally to process the the question and parameters that sent
23
+ # to the question.
24
+ #
25
+ # @param [String] question_with_parameters this is the remaining question and
26
+ # parameters left on the question posed to the chat room.
27
+ #
28
+ def process_question(question_with_parameters)
22
29
 
23
- request =~ QUESTION_REGEX
24
- @question = Regexp.last_match(2)
30
+ parsed_elements = question_with_parameters.scan(GROUP_REGEX)
31
+
32
+ @question = parsed_elements.first.first
25
33
  # After the target, question type, question, and answer length has been determined
26
34
  # look at all the single quoted items to find the list of parameters if there are any
27
- @parameters = request.scan(GROUP_REGEX)[1..-1].flatten
35
+ @parameters = Array(parsed_elements[1..-1].flatten)
28
36
 
29
37
  end
30
38
 
39
+ #
40
+ # @return [String] the question that is being asked.
31
41
  def to_s
32
42
  @question
33
43
  end
34
44
 
45
+ #
46
+ # Ask the question that has been proposed.
47
+ #
48
+ # @return [String] a string that asks the question in the chat room.
35
49
  def ask
36
50
  "@all Question '#{@question}'"
37
51
  end
38
52
 
53
+ #
54
+ # Maintains a list of the results that have been captured for the question.
55
+ # The hash that is maintained would be used with the user's nickname as the
56
+ # key and the value as a response to the question.
57
+ #
58
+ # @return [Hash] used for storing responses from the various senders.
59
+ #
60
+ def captured_results
61
+ @captured_results ||= {}
62
+ end
63
+
39
64
  end
data/lib/quiz.rb CHANGED
@@ -4,12 +4,23 @@ require 'robut'
4
4
  class Robut::Plugin::Quiz
5
5
  include Robut::Plugin
6
6
 
7
+ #
8
+ # @return [Array<String>] contains the various types of responses that are
9
+ # valid usage examples that would be returned by the Help Plugin
10
+ #
7
11
  def usage
8
12
  [
9
- "#{at_nick} ask polar 'Should I continue the presentation?' for 3 minutes",
13
+ "#{at_nick} ask 'Should we break for lunch?'",
14
+ "#{at_nick} ask for 3 minutes 'Should I continue the presentation?'",
15
+ "#{at_nick} answer yes"
10
16
  ]
11
17
  end
12
18
 
19
+ #
20
+ # @param [Time] time at which the message has arrived
21
+ # @param [String] sender_nick the sender
22
+ # @param [String] message the message that was sent
23
+ #
13
24
  def handle(time, sender_nick, message)
14
25
 
15
26
  # check to see if the user is asking the bot a question
@@ -29,7 +40,7 @@ class Robut::Plugin::Quiz
29
40
 
30
41
  end
31
42
 
32
- QUESTION_REGEX = /^ask ?(choice|polar|scale)? (?:question )?.+(?:(?:for )?(\d+) minutes?)$/
43
+ QUESTION_REGEX = /^ask ?(choice|polar|range)? (?:question )?(?:(?:for )?(\d+) minutes?)?(.+)$/
33
44
 
34
45
  def is_a_valid_question? message
35
46
  QUESTION_REGEX =~ message
@@ -45,8 +56,15 @@ class Robut::Plugin::Quiz
45
56
  (store["quiz::question::queue"] ||= []) << [sender,question]
46
57
  end
47
58
 
59
+ #
60
+ # Return a new thread which will pop questions in the queue of questions
61
+ #
48
62
  def quizmaster
49
- @@quizmaster ||= Thread.new { pop_the_question until there_are_no_more_questions_to_pop }
63
+ if not defined?(@@quizmaster) or @@quizmaster.nil? or !@@quizmaster.alive?
64
+ @@quizmaster = Thread.new { pop_the_question until there_are_no_more_questions_to_pop }
65
+ end
66
+
67
+ @@quizmaster
50
68
  end
51
69
 
52
70
  def pop_the_question
@@ -63,13 +81,17 @@ class Robut::Plugin::Quiz
63
81
  defined? @@current_question and @@current_question
64
82
  end
65
83
 
84
+ #
85
+ # @param [String] sender the user proposing the question
86
+ # @param [String] request the data related to the asking and the question data itself.
87
+ #
66
88
  def process_the_question(sender,request)
67
-
68
89
  request =~ QUESTION_REGEX
69
90
  type = Regexp.last_match(1) || 'polar'
70
- question_length = Regexp.last_match(2) || '2'
91
+ question_length = Regexp.last_match(2) || '2'
92
+ question_data = Regexp.last_match(3)
71
93
 
72
- set_current_question create_the_question_based_on_type(type,sender,request), question_length
94
+ set_current_question create_the_question_based_on_type(type,sender,question_data), question_length
73
95
  end
74
96
 
75
97
  #
@@ -95,6 +117,9 @@ class Robut::Plugin::Quiz
95
117
  reply "The results are in for '#{question}':"
96
118
  reply question.results
97
119
 
120
+ # allow some time between the results and asking the next question
121
+ sleep 10
122
+
98
123
  end
99
124
 
100
125
  def start_accepting_responses_for_this_question(question)
@@ -105,8 +130,13 @@ class Robut::Plugin::Quiz
105
130
  @@current_question = nil
106
131
  end
107
132
 
108
- def process_response_for_active_question(sender_nick, request)
109
- if @@current_question.handle_response sender_nick, request
133
+ #
134
+ # @param [String] sender_nick the name of the person that is responding to
135
+ # the question.
136
+ # @param [String] response is the answer to the question proposed.
137
+ #
138
+ def process_response_for_active_question(sender_nick, response)
139
+ if @@current_question.handle_response sender_nick, response[/^answer (.+)$/,1]
110
140
  reply "Thank you, @#{sender_nick}, I have recorded your response."
111
141
  else
112
142
  reply "Sorry, @#{sender_nick}, I was unable to record that answer"
@@ -117,4 +147,5 @@ end
117
147
 
118
148
 
119
149
  require_relative 'question'
120
- require_relative 'polar'
150
+ require_relative 'polar'
151
+ require_relative 'range'
data/lib/range.rb ADDED
@@ -0,0 +1,73 @@
1
+ # encoding: UTF-8
2
+
3
+ class Robut::Plugin::Quiz::Range
4
+ include Robut::Plugin::Quiz::Question
5
+
6
+ RANGE_VALUES = /(\d+)(?:-|\.\.)(\d+)/
7
+
8
+ def handle_response(sender_nick,response)
9
+
10
+ if within_range? response
11
+ store_range_response_for sender_nick, response
12
+ true
13
+ else
14
+ false
15
+ end
16
+
17
+ end
18
+
19
+ def start_value
20
+ if Array(@parameters).first.to_s =~ RANGE_VALUES
21
+ Regexp.last_match(1).to_i
22
+ else
23
+ 1
24
+ end
25
+ end
26
+
27
+ def highest_value
28
+ if Array(@parameters).first.to_s =~ RANGE_VALUES
29
+ Regexp.last_match(2).to_i
30
+ else
31
+ 5
32
+ end
33
+ end
34
+
35
+ def within_range?(value)
36
+ value.to_i >= start_value and value.to_i <= highest_value
37
+ end
38
+
39
+ def ask
40
+ "@all Question '#{@question}' (#{start_value}..#{highest_value})"
41
+ end
42
+
43
+ def results
44
+ return "I'm sorry, not enough votes were cast to be create a summary." if captured_results.length == 0
45
+
46
+ result_values = captured_results.values.extend Robut::Plugin::Quiz::Range::Averages
47
+ "#{result_values.length} votes with a mean of #{result_values.mean}"
48
+ end
49
+
50
+ def store_range_response_for(sender_nick,value)
51
+ captured_results[sender_nick] = value.to_i
52
+ end
53
+
54
+
55
+ module Averages
56
+
57
+ def sum
58
+ inject(:+)
59
+ end
60
+
61
+ def mean
62
+ return 0 if length == 0
63
+ sum.to_f / length.to_f
64
+ end
65
+
66
+ def mode
67
+ frequency = inject(Hash.new(0)) { |hash,value| hash[value] += 1; hash }
68
+ sort_by {|value| frequency[value] }.last
69
+ end
70
+
71
+ end
72
+
73
+ end
data/lib/robut_quiz.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require 'robut'
4
4
 
5
5
  class Robut::Plugin::Quiz
6
- VERSION = "0.1.0"
6
+ VERSION = "0.2.0"
7
7
  end
8
8
 
9
9
  require_relative 'quiz'
data/spec/polar_spec.rb CHANGED
@@ -3,7 +3,7 @@ require_relative 'spec_helper'
3
3
  describe Robut::Plugin::Quiz::Polar do
4
4
 
5
5
  subject do
6
- Robut::Plugin::Quiz::Polar.new 'person',"ask polar 'Should I continue the presentation?' for 3 minutes"
6
+ Robut::Plugin::Quiz::Polar.new 'person',"'Should I continue the presentation?'"
7
7
  end
8
8
 
9
9
  let(:time) { Time.now }
@@ -0,0 +1,64 @@
1
+ require "spec_helper"
2
+
3
+ describe Robut::Plugin::Quiz::Question do
4
+
5
+ class TestQuestion
6
+ include Robut::Plugin::Quiz::Question
7
+
8
+ attr_accessor :question, :parameters, :captured_results
9
+
10
+ end
11
+
12
+ let(:question) { "Do you like questions?" }
13
+ let(:question_with_params) { "'#{question}', 'yes', 'no' 'maybe'" }
14
+
15
+ subject { TestQuestion.new "sender", question_with_params }
16
+
17
+ describe "#to_s" do
18
+
19
+ it "should be the question that was asked" do
20
+ subject.to_s.should == question
21
+ end
22
+
23
+ end
24
+
25
+ describe "#ask" do
26
+
27
+ it "should be the default statement to ask question" do
28
+ subject.ask.should == "@all Question '#{question}'"
29
+ end
30
+
31
+ end
32
+
33
+ describe "#process_question" do
34
+
35
+ context "when a question with parameters" do
36
+
37
+ it "should find the question" do
38
+ subject.process_question question_with_params
39
+ subject.question.should == question
40
+ end
41
+
42
+ it "should find the parameters" do
43
+ subject.process_question question_with_params
44
+ subject.parameters.should == [ 'yes', 'no', 'maybe' ]
45
+ end
46
+
47
+ end
48
+
49
+ context "when only a question has been provided" do
50
+
51
+ it "should find the question" do
52
+ subject.process_question "'Ask more questions?'"
53
+ subject.question.should == 'Ask more questions?'
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+
60
+ describe "subject" do
61
+
62
+ end
63
+
64
+ end
data/spec/quiz_spec.rb CHANGED
@@ -15,11 +15,11 @@ describe Robut::Plugin::Quiz do
15
15
  let(:time) { Time.now }
16
16
 
17
17
  [
18
- "ask choice 'What do you want for lunch?', 'pizza', 'sandwich', 'salad' for 1 minute",
19
- "ask polar 'Should I continue the presentation?' for 3 minutes",
20
- "ask scale question 'how much did you like the presentation?', '1..5' for 10 minutes",
21
- "ask 'Should I continue the presentation?', 'y|yes', 'n|no' for 1 minutes",
22
- "ask polar 'Should I continue the presentation?' for 3 minutes"
18
+ "ask 'Should I continue the presentation?'",
19
+ "ask for 3 minutes 'Should I continue the presentation?'",
20
+ "ask polar for 3 minutes 'Should I continue the presentation?'",
21
+ "ask choice 1 minute 'What do you want for lunch?', 'pizza', 'sandwich', 'salad'",
22
+ "ask scale question for 10 minutes 'how much did you like the presentation?', '1..5'"
23
23
 
24
24
  ].each do |question|
25
25
 
@@ -55,7 +55,7 @@ describe Robut::Plugin::Quiz do
55
55
 
56
56
  subject.should_not_receive(:process_response_for_active_question)
57
57
 
58
- subject.handle time,'person',"@quizmaster ask polar 'Should I continue the presentation?' for 3 minutes"
58
+ subject.handle time,'person',"@quizmaster ask polar for 3 minutes 'Should I continue the presentation?'"
59
59
 
60
60
  end
61
61
 
@@ -70,7 +70,7 @@ describe Robut::Plugin::Quiz do
70
70
 
71
71
  subject.should_receive(:process_response_for_active_question)
72
72
 
73
- subject.handle time,'person',"@quizmaster ask polar 'Should I continue the presentation?' for 3 minutes"
73
+ subject.handle time,'person',"@quizmaster ask polar for 3 minutes 'Should I continue the presentation?'"
74
74
 
75
75
  end
76
76
 
@@ -93,7 +93,7 @@ describe Robut::Plugin::Quiz do
93
93
  subject.should_receive(:create_the_question_based_on_type).and_return(expected_question)
94
94
 
95
95
  subject.should_receive(:set_current_question).with(expected_question,'3')
96
- subject.process_the_question 'person',"ask polar 'Should I continue the presentation?' for 3 minutes"
96
+ subject.process_the_question 'person',"ask polar for 3 minutes 'Should I continue the presentation?'"
97
97
 
98
98
  end
99
99
 
@@ -109,7 +109,7 @@ describe Robut::Plugin::Quiz do
109
109
  end
110
110
 
111
111
  let(:question) do
112
- Robut::Plugin::Quiz::Polar.new 'person',"ask polar 'Should I continue the presentation?' for 3 minutes"
112
+ Robut::Plugin::Quiz::Polar.new 'person',"'Should I continue the presentation?'"
113
113
  end
114
114
 
115
115
  it "should place robut in the mode where it is asking a question" do
@@ -0,0 +1,100 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe Robut::Plugin::Quiz::Range do
4
+
5
+ subject do
6
+ Robut::Plugin::Quiz::Range.new 'person',"ask range for 3 minutes 'Should I continue the presentation?'"
7
+ end
8
+
9
+ describe "#start_value" do
10
+
11
+ context "when no range has been specified" do
12
+
13
+ it "should default to the value 1" do
14
+ subject.start_value.should == 1
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+
21
+ describe "#highest_value" do
22
+
23
+ context "when no range has been specified" do
24
+
25
+ it "should default to the value of 5" do
26
+ subject.highest_value.should == 5
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
33
+ describe "#within_range?" do
34
+
35
+ context "when the value is within range" do
36
+
37
+ it "should respond with true" do
38
+ subject.within_range?(3).should be_true
39
+ end
40
+
41
+ end
42
+
43
+ context "when the value is not within range" do
44
+
45
+ it "should respond with false" do
46
+ subject.within_range?(6).should be_false
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+
53
+ describe "#handle_response" do
54
+
55
+ context "with a valid response" do
56
+
57
+ it "should return true" do
58
+ subject.should_receive(:store_range_response_for).with("sender","1")
59
+ subject.handle_response("sender","1").should be_true
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+
66
+ describe Robut::Plugin::Quiz::Range::Averages do
67
+
68
+ subject do
69
+ array = [1,1,2,2,2,3,4,5]
70
+ array.extend Robut::Plugin::Quiz::Range::Averages
71
+ end
72
+
73
+
74
+ describe "#sum" do
75
+
76
+ it "should return the correct value" do
77
+ subject.sum.should == 20
78
+ end
79
+
80
+ end
81
+
82
+ describe "#mean" do
83
+
84
+ it "should return the correct value" do
85
+ subject.mean.should == 2.5
86
+ end
87
+
88
+ end
89
+
90
+ describe "#mode" do
91
+
92
+ it "should return the correct value" do
93
+ subject.mode.should == 2
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+
100
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: robut-quiz
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.0
5
+ version: 0.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Franklin Webber
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-10-23 00:00:00 Z
13
+ date: 2011-10-27 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: robut
@@ -40,16 +40,19 @@ files:
40
40
  - lib/polar.rb
41
41
  - lib/question.rb
42
42
  - lib/quiz.rb
43
+ - lib/range.rb
43
44
  - lib/robut_quiz.rb
44
45
  - robut-quiz.gemspec
45
46
  - spec/polar_spec.rb
47
+ - spec/question_spec.rb
46
48
  - spec/quiz_spec.rb
49
+ - spec/range_spec.rb
47
50
  - spec/spec_helper.rb
48
51
  homepage: http://github.com/burtlo/robut-quiz
49
52
  licenses: []
50
53
 
51
54
  post_install_message: "\n\
52
- --------------------------------------------------------------------------------\n ___\n !(O-0)! ~ Thank you for installing robut-quiz 0.1.0 / 2011-10-23\n >==[ ]==<\n @ @\n\n Changes:\n \n * Initial Release\n * User is able to ask polar question\n\n\
55
+ --------------------------------------------------------------------------------\n ___\n !(O-0)! ~ Thank you for installing robut-quiz 0.2.0 / 2011-10-26\n >==[ ]==<\n @ @\n\n Changes:\n \n * Changed the question syntax\n * Added a range question (1..5)\n \n\n\
53
56
  --------------------------------------------------------------------------------"
54
57
  rdoc_options:
55
58
  - --charset=UTF-8