robut-quiz 0.1.0 → 0.2.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/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