spanish_inquisition 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Pat Allan and Inspire9
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,83 @@
1
+ h1. SpanishInquisition
2
+
3
+ Nobody expects the Spanish Inquisition!
4
+
5
+ h2. Installation
6
+
7
+ It's a gem - so, like any other gem, add it to your app's Gemfile:
8
+
9
+ <pre><code>gem 'spanish_inquisition'</code></pre>
10
+
11
+ And then execute:
12
+
13
+ <pre><code>$ bundle</code></pre>
14
+
15
+ Or install it yourself as:
16
+
17
+ <pre><code>$ gem install spanish_inquisition</code></pre>
18
+
19
+ h2. Usage
20
+
21
+ Firstly, you'll want to define your surveys in files within @app/surveys@. Here's a quick example:
22
+
23
+ <pre><code>SpanishInquisition::Survey.new :inquisition do |survey|
24
+ survey.page do |page|
25
+ page.question :weapon do |question|
26
+ question.text = 'What is your chief weapon?''
27
+ question.style = :one
28
+ question.answers = ['fear', 'surprise', 'ruthless efficency']
29
+ end
30
+
31
+ page.question :torture do |question|
32
+ question.text = 'What do you torture with?'
33
+ question.style = :one
34
+ question.answers = ['The Rack', 'The Cushions', 'The Comfy Chair']
35
+ end
36
+ end
37
+
38
+ survey.page do |page|
39
+ page.question :comments do |question|
40
+ question.text = 'Do you have any suggestions for better torture devices?'
41
+ question.style = :text
42
+ question.required = false
43
+ end
44
+
45
+ page.question :cardinal do |question|
46
+ question.text = 'Who is your favourite Cardinal: Ximinex, Biggles or Fang?'
47
+ question.style = :string
48
+ end
49
+ end
50
+ end</code></pre>
51
+
52
+ Questions are required by default, and currently only three question styles are supported: :string (a standard text field), :text (a multi-line text field, aka the textarea HTML element), and :one (many options, single choice, aka radio inputs). The @answers@ value can be anything that Formtastic accepts as a collection (so both arrays and hashes are valid settings).
53
+
54
+ Rendering the form is done via a presenter:
55
+
56
+ <pre><code>survey = SpanishInquisition::Presenter.new :inquisition, params[:survey]</code></pre>
57
+
58
+ And then, this presenter can be used within a Formtastic-built form in your views:
59
+
60
+ <pre><code><%= semantic_form_for survey do |form| %>
61
+ <%= survey.render_to form %>
62
+ <%= form.actions do %>
63
+ <%= form.action :submit, :label => 'Save my answers' %>
64
+ <%- end %>
65
+ <%- end %></code></pre>
66
+
67
+ When the form is posted back, you will have to persist the results somewhere - they can be obtained via the @answers@ method on the presenter. It will return a hash with each question's identifier as the keys, and the supplied answers as the values.
68
+
69
+ There's a few more optoins available with questions, but the source is simple and uncomplicated - I'd recommend reading it.
70
+
71
+ h2. Contributing
72
+
73
+ This gem is built using "git-flow":https://github.com/nvie/gitflow - so keep in mind that the master branch is the release branch, develop is work-in-progress, and any in-progress features get their own feature branches.
74
+
75
+ # Fork it
76
+ # Create your feature branch (`git checkout -b feature/name`)
77
+ # Commit your changes (`git commit -am 'Add some feature'`)
78
+ # Push to the branch (`git push origin feature/name`)
79
+ # Create new Pull Request
80
+
81
+ h2. Licence
82
+
83
+ Copyright (c) 2013, Spanish Inquisition is developed and maintained by Pat Allan and Inspire9, and is released under the open MIT Licence.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,14 @@
1
+ class SpanishInquisition::Page
2
+ attr_reader :questions
3
+
4
+ def initialize(&block)
5
+ @questions = []
6
+
7
+ block.call self
8
+ end
9
+
10
+ def question(identifier = nil, &block)
11
+ identifier ||= "question_#{questions.length}".to_sym
12
+ questions << SpanishInquisition::Question.new(identifier, &block)
13
+ end
14
+ end
@@ -0,0 +1,81 @@
1
+ require 'active_model/naming'
2
+ require 'active_model/conversion'
3
+ require 'active_model/validations'
4
+
5
+ class SpanishInquisition::Presenter
6
+ include ActiveModel::Conversion
7
+ include ActiveModel::Validations
8
+
9
+ validate :required_answers
10
+
11
+ delegate :heading, :description, to: :survey
12
+
13
+ def self.model_name
14
+ ActiveModel::Name.new(self, nil, 'Survey')
15
+ end
16
+
17
+ def initialize(identifier, attributes = {})
18
+ @survey = SpanishInquisition.surveys[identifier]
19
+ @attributes = attributes || {}
20
+
21
+ raise SpanishInquisition::SurveyNotFound if @survey.nil?
22
+ end
23
+
24
+ def answers
25
+ questions.inject({}) do |hash, question|
26
+ if question.capture?(attributes)
27
+ hash[question.identifier] = attributes[question.identifier]
28
+ end
29
+
30
+ hash
31
+ end
32
+ end
33
+
34
+ def id
35
+ survey.identifier
36
+ end
37
+
38
+ def persisted?
39
+ true
40
+ end
41
+
42
+ def render_to(form)
43
+ survey.pages.collect { |page|
44
+ SpanishInquisition::Presenters::PagePresenter.new(form, page).to_html
45
+ }.join.html_safe
46
+ end
47
+
48
+ def to_json
49
+ questions.collect { |question|
50
+ SpanishInquisition::Presenters::QuestionPresenter.new(nil, question).to_json(attributes)
51
+ }
52
+ end
53
+
54
+ private
55
+
56
+ attr_reader :survey, :attributes
57
+
58
+ def invalid_question?(question)
59
+ question.capture?(attributes) &&
60
+ question.required? &&
61
+ attributes[question.identifier].blank?
62
+ end
63
+
64
+ def method_missing(method, *arguments, &block)
65
+ return attributes[method] if survey.question_identifiers.include?(method)
66
+
67
+ super
68
+ end
69
+
70
+ def questions
71
+ @questions ||= survey.pages.collect(&:questions).flatten
72
+ end
73
+
74
+ def required_answers
75
+ questions.each do |question|
76
+ next unless invalid_question?(question)
77
+
78
+ errors.add question.identifier, 'must be answered'
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,23 @@
1
+ class SpanishInquisition::Presenters::PagePresenter
2
+ def initialize(form, page)
3
+ @form, @page = form, page
4
+ end
5
+
6
+ def to_html
7
+ form.inputs do
8
+ question_presenters.each do |presenter|
9
+ form.template.concat presenter.to_html
10
+ end
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :form, :page
17
+
18
+ def question_presenters
19
+ @question_presenters ||= page.questions.collect { |question|
20
+ SpanishInquisition::Presenters::QuestionPresenter.new(form, question)
21
+ }
22
+ end
23
+ end
@@ -0,0 +1,31 @@
1
+ class SpanishInquisition::Presenters::QuestionPresenter
2
+ def initialize(form, question)
3
+ @form, @question = form, question
4
+ end
5
+
6
+ def to_html
7
+ case question.style
8
+ when :one
9
+ form.input question.identifier, as: :radio, collection: question.answers, label: question.text
10
+ when :string
11
+ form.input question.identifier, as: :string, label: question.text
12
+ when :text
13
+ form.input question.identifier, as: :text, label: question.text
14
+ else
15
+ raise "Unknown question style: #{question.style}"
16
+ end
17
+ end
18
+
19
+ def to_json(responses = [])
20
+ {
21
+ 'identifier' => question.identifier,
22
+ 'text' => question.text,
23
+ 'required' => question.required,
24
+ 'capture' => question.capture?(responses)
25
+ }
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :form, :question
31
+ end
@@ -0,0 +1,17 @@
1
+ class SpanishInquisition::Question
2
+ attr_reader :identifier
3
+ attr_accessor :text, :style, :answers, :capture, :required
4
+
5
+ alias_method :required?, :required
6
+
7
+ def initialize(identifier, &block)
8
+ @identifier = identifier
9
+ @required = true
10
+
11
+ block.call self
12
+ end
13
+
14
+ def capture?(responses)
15
+ @capture.nil? || @capture.call(responses)
16
+ end
17
+ end
@@ -0,0 +1,32 @@
1
+ class SpanishInquisition::Survey
2
+ attr_reader :identifier, :pages
3
+ attr_accessor :heading, :description
4
+
5
+ def initialize(identifier, &block)
6
+ @identifier = identifier
7
+ @pages = []
8
+
9
+ block.call self if block
10
+
11
+ SpanishInquisition.surveys[identifier] = self
12
+ end
13
+
14
+ def duplicate_to(identifier)
15
+ duplicate = self.class.new(identifier)
16
+
17
+ duplicate.pages.replace pages.dup
18
+ duplicate.heading = heading.dup
19
+ duplicate.description = description.dup
20
+
21
+ duplicate
22
+ end
23
+
24
+ def page(&block)
25
+ pages << SpanishInquisition::Page.new(&block)
26
+ end
27
+
28
+ def question_identifiers
29
+ @question_identifiers ||= pages.collect(&:questions).flatten.
30
+ collect(&:identifier)
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ class SpanishInquisition::SurveyNotFound < StandardError
2
+ #
3
+ end
@@ -0,0 +1,26 @@
1
+ module SpanishInquisition
2
+ def self.load
3
+ return if @loaded
4
+
5
+ Dir[Rails.root.join('app', 'surveys', '*.rb')].each do |file|
6
+ ActiveSupport::Dependencies.require_or_load file
7
+ end
8
+
9
+ @loaded = true
10
+ end
11
+
12
+ def self.surveys
13
+ load
14
+ @surveys ||= {}
15
+ end
16
+
17
+ module Presenters; end
18
+ end
19
+
20
+ require 'spanish_inquisition/page'
21
+ require 'spanish_inquisition/presenter'
22
+ require 'spanish_inquisition/presenters/page_presenter'
23
+ require 'spanish_inquisition/presenters/question_presenter'
24
+ require 'spanish_inquisition/question'
25
+ require 'spanish_inquisition/survey'
26
+ require 'spanish_inquisition/survey_not_found'
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ Gem::Specification.new do |gem|
3
+ gem.name = 'spanish_inquisition'
4
+ gem.version = '1.0.0'
5
+ gem.authors = ['Pat Allan']
6
+ gem.email = ['pat@freelancing-gods.com']
7
+ gem.summary = 'Simple Ruby survey DSL'
8
+ gem.description = 'A simple Ruby survey DSL which handles questions and answers. You need to manage persistence yourself.'
9
+ gem.homepage = 'https://github.com/inspire9/spanish_inquisition'
10
+
11
+ gem.files = `git ls-files`.split($/)
12
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
13
+ gem.require_paths = ['lib']
14
+
15
+ gem.add_runtime_dependency 'activemodel', '~> 3.2'
16
+ gem.add_runtime_dependency 'formtastic', '~> 2.2'
17
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spanish_inquisition
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Pat Allan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activemodel
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.2'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.2'
30
+ - !ruby/object:Gem::Dependency
31
+ name: formtastic
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '2.2'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.2'
46
+ description: A simple Ruby survey DSL which handles questions and answers. You need
47
+ to manage persistence yourself.
48
+ email:
49
+ - pat@freelancing-gods.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - Gemfile
56
+ - LICENSE.txt
57
+ - README.textile
58
+ - Rakefile
59
+ - lib/spanish_inquisition.rb
60
+ - lib/spanish_inquisition/page.rb
61
+ - lib/spanish_inquisition/presenter.rb
62
+ - lib/spanish_inquisition/presenters/page_presenter.rb
63
+ - lib/spanish_inquisition/presenters/question_presenter.rb
64
+ - lib/spanish_inquisition/question.rb
65
+ - lib/spanish_inquisition/survey.rb
66
+ - lib/spanish_inquisition/survey_not_found.rb
67
+ - spanish_inquisition.gemspec
68
+ homepage: https://github.com/inspire9/spanish_inquisition
69
+ licenses: []
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 1.8.23
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Simple Ruby survey DSL
92
+ test_files: []
93
+ has_rdoc: