Permalink
Browse files

use Erector for QuestionForm and AnswerKey builders

  • Loading branch information...
1 parent 84f8847 commit b67551127e44c10b8a9ab188cdd2822fa4fe532d @alexch committed Jul 24, 2011
View
1 .rspec
@@ -0,0 +1 @@
+--color
View
17 Gemfile
@@ -1,7 +1,16 @@
source "http://rubygems.org"
+
gem 'nokogiri'
-gem 'jeweler'
-gem 'webmock'
gem 'rest-client'
-gem 'rspec', "~>2"
-gem 'fakeweb'
+gem "erector", ">= 0.9.0.pre"
+
+group :development do
+ gem 'jeweler'
+end
+
+group :development, :test do
+ gem 'webmock'
+ gem 'rspec', "~>2"
+ gem 'fakeweb'
+ gem "wrong"
+end
@@ -0,0 +1,39 @@
+require "erector/xml_widget"
+
+# see http://docs.amazonwebservices.com/AWSMechTurk/2008-08-02/AWSMturkAPI/index.html?ApiReference_CreateQualificationTypeOperation.html
+class RTurk::AnswerKey < Erector::XMLWidget
+
+ XMLNS = "http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2005-10-01/AnswerKey.xsd"
+
+ %w{
+ AnswerKey
+ Question
+ QuestionIdentifier
+ AnswerOption
+ SelectionIdentifier
+ AnswerScore
+ DefaultScore
+ QualificationValueMapping
+ PercentageMapping
+ MaximumSummedScore
+ ScaleMapping
+ SummedScoreMultiplier
+ RangeMapping
+ SummedScoreRange
+ InclusiveLowerBound
+ InclusiveUpperBound
+ QualificationValue
+ OutOfRangeQualificationValue
+ }.uniq.each do |element_name|
+ tag element_name
+ tag element_name, :snake_case
+ end
+
+ def content
+ answer_key :xmlns => XMLNS do
+ answer_key_content
+ end
+ end
+
+end
+
@@ -1,33 +1,86 @@
require 'cgi'
require 'uri'
+require "erector/xml_widget"
module RTurk
- class QuestionForm
+ # see http://docs.amazonwebservices.com/AWSMechTurk/2008-08-02/AWSMturkAPI/ApiReference_QuestionFormDataStructureArticle.html
+ # @param options hash (optional)
+ # ::xml:: raw xml (optional). If it starts with \&lt;QuestionForm then it's used as the full QuestionForm value. Otherwise it is wrapped in a \&lt;QuestionForm\&gt; element. If it is nil then we use Erector to call its subclass' #question_form_content method.
+ class QuestionForm < Erector::XMLWidget
XMLNS = "http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2005-10-01/QuestionForm.xsd"
- # The QuestionForm data structure is hella complicated, so we're just treating it as a string for now. See
- # http://docs.amazonwebservices.com/AWSMechTurk/2008-08-02/AWSMturkAPI/ApiReference_QuestionFormDataStructureArticle.html
+ needs :xml => nil
- attr_accessor :text
+ def to_params
+ to_xml # create a new output string and call 'content' via Erector
+ end
- def initialize(text)
- @text = text
+ # todo: fill out Application subelements
+ # todo: fill out EmbeddedBinary subelements
+ %w{
+ QuestionForm
+ Overview
+ Title
+ List
+ Binary
+ MimeType
+ Type
+ SubType
+ DataURL
+ AltText
+ Application
+ EmbeddedBinary
+ FormattedContent
+
+ Question
+ QuestionIdentifier
+ DisplayName
+ IsRequired
+ QuestionContent
+ AnswerSpecification
+ FreeTextAnswer
+ Constraints
+ IsNumeric
+ Length
+ AnswerFormatRegex
+ DefaultText
+ NumberOfLinesSuggestion
+ SelectionAnswer
+ MinSelectionCount
+ MaxSelectionCount
+ StyleSuggestion
+ Selections
+ Selection
+ SelectionIdentifier
+ Text
+ FormattedContent
+ Binary
+ OtherSelection
+ FileUploadAnswer
+ MaxFileSizeInBytes
+ MinFileSizeInBytes
+ }.uniq.each do |element_name|
+ tag element_name
+ tag element_name, :snake_case unless element_name == 'Text'
end
- def to_params
- if text =~ /^<QuestionForm/
- text
+ tag "Text", "text_element" # very sticky since 'text' is a core Erector method
+
+ def content
+ if @xml and @xml.strip =~ /^<QuestionForm/
+ rawtext @xml
else
- <<-XML
-<QuestionForm xmlns="#{XMLNS}">
-#{text}
-</QuestionForm>
- XML
+ question_form :xmlns => XMLNS do
+ question_form_content
+ end
end
end
- end
+ def question_form_content
+ rawtext @xml # by default, use the parameter
+ end
+ end
end
@@ -20,8 +20,12 @@ def question(*args)
end
end
- def question_form(text)
- @question = RTurk::QuestionForm.new(text)
+ def question_form(text_or_widget)
+ if text_or_widget.is_a? Erector::XMLWidget
+ @question = text_or_widget
+ else
+ @question = RTurk::QuestionForm.new(:xml => text)
+ end
end
def to_params
@@ -0,0 +1,26 @@
+require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
+require 'rturk/builders/answer_key_builder'
+
+module RTurk
+ describe AnswerKey do
+
+ before(:all) do
+ end
+
+ class SillyAnswerKey < AnswerKey
+ def answer_key_content
+ Question "Why did the chicken cross the road?"
+ end
+ end
+
+ it "is an abstract base class that calls down to 'answer_key_content' in its concrete subclasses" do
+ RTurk::SillyAnswerKey.new.to_xml.should ==
+ "<AnswerKey xmlns=\"#{RTurk::AnswerKey::XMLNS}\">" +
+ "<Question>Why did the chicken cross the road?</Question>" +
+ "</AnswerKey>"
+ end
+
+ # todo: test more
+
+ end
+end
@@ -1,18 +1,75 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
+require 'rturk/builders/question_form_builder'
-describe RTurk::QuestionForm do
+module RTurk
+ describe QuestionForm do
- before(:all) do
- end
+ before(:all) do
+ end
- it "should build a question" do
- question = RTurk::QuestionForm.new("[...]")
- question.text.should == "[...]"
- question.to_params.should == <<-XML
-<QuestionForm xmlns="#{RTurk::QuestionForm::XMLNS}">
-[...]
-</QuestionForm>
- XML
- end
+ it "should build a question, using its xml param as the full QuestionForm since it starts with <QuestionForm" do
+ xml = <<-XML
+ <QuestionForm xmlns="#{RTurk::QuestionForm::XMLNS}">
+ [...]
+ </QuestionForm>
+ XML
+ question = RTurk::QuestionForm.new(:xml => xml)
+ question.to_params.should == xml
+ end
+
+ it "should build a question, using its xml param as the QuestionForm content" do
+ question = RTurk::QuestionForm.new(:xml => "[...]")
+ question.to_params.should ==
+ "<QuestionForm xmlns=\"#{RTurk::QuestionForm::XMLNS}\">[...]</QuestionForm>"
+ end
+
+ class SillyQuestionForm < QuestionForm
+ def question_form_content
+ Question "Why did the chicken cross the road?"
+ end
+ end
+ it "is an abstract base class that calls down to 'question_form_content' in its concrete subclasses" do
+ RTurk::SillyQuestionForm.new.to_xml.should ==
+ "<QuestionForm xmlns=\"#{RTurk::QuestionForm::XMLNS}\">" +
+ "<Question>Why did the chicken cross the road?</Question>" +
+ "</QuestionForm>"
+ end
+
+ class AnotherSillyQuestionForm < QuestionForm
+ def question_form_content
+ question {
+ question_content {
+ Text "How many licks?" # note: Text vs text vs text_element gotcha
+ }
+ answer_specification {
+ free_text_answer {
+ constraints {
+ is_numeric true
+ }
+ }
+ }
+ }
+ end
+ end
+
+ it "allows snake_case element names" do
+ RTurk::AnotherSillyQuestionForm.new.to_xml.should ==
+ "<QuestionForm xmlns=\"#{RTurk::QuestionForm::XMLNS}\">" +
+ "<Question>" +
+ "<QuestionContent>" +
+ "<Text>How many licks?</Text>" +
+ "</QuestionContent>" +
+ "<AnswerSpecification>" +
+ "<FreeTextAnswer>" +
+ "<Constraints>" +
+ "<IsNumeric>true</IsNumeric>" +
+ "</Constraints>" +
+ "</FreeTextAnswer>" +
+ "</AnswerSpecification>" +
+ "</Question>" +
+ "</QuestionForm>"
+ end
+
+ end
end
Oops, something went wrong.

0 comments on commit b675511

Please sign in to comment.