question_chain 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +18 -0
  3. data/Licence.txt +20 -0
  4. data/README.rdoc +34 -0
  5. data/Rakefile +2 -0
  6. data/config/initializers/mustache.rb +2 -0
  7. data/lib/question_chain/answerable.rb +142 -0
  8. data/lib/question_chain/answers.rb +290 -0
  9. data/lib/question_chain/models/answers/question_view.rb +21 -0
  10. data/lib/question_chain/models/answers/ui_object_view.rb +67 -0
  11. data/lib/question_chain/models/answers/ui_objects_check_box_view.rb +17 -0
  12. data/lib/question_chain/models/answers/ui_objects_drop_down_view.rb +16 -0
  13. data/lib/question_chain/models/answers/ui_objects_hidden_field_view.rb +8 -0
  14. data/lib/question_chain/models/answers/ui_objects_object_reference_drop_down_view.rb +18 -0
  15. data/lib/question_chain/models/answers/ui_objects_object_search_view.rb +22 -0
  16. data/lib/question_chain/models/answers/ui_objects_relatable_category_drop_down_view.rb +18 -0
  17. data/lib/question_chain/models/answers/ui_objects_text_field_view.rb +8 -0
  18. data/lib/question_chain/models/chain_template.rb +43 -0
  19. data/lib/question_chain/models/question.rb +37 -0
  20. data/lib/question_chain/models/relatable_category_filter.rb +15 -0
  21. data/lib/question_chain/models/rule.rb +27 -0
  22. data/lib/question_chain/models/rules/attribute_change.rb +28 -0
  23. data/lib/question_chain/models/rules/choice_genenerator.rb +5 -0
  24. data/lib/question_chain/models/rules/populate_drop_down.rb +30 -0
  25. data/lib/question_chain/models/rules/search.rb +19 -0
  26. data/lib/question_chain/models/rules/value_change.rb +22 -0
  27. data/lib/question_chain/models/ui_group.rb +71 -0
  28. data/lib/question_chain/models/ui_object.rb +92 -0
  29. data/lib/question_chain/models/ui_object_answer.rb +17 -0
  30. data/lib/question_chain/models/ui_objects/check_box.rb +8 -0
  31. data/lib/question_chain/models/ui_objects/drop_down.rb +17 -0
  32. data/lib/question_chain/models/ui_objects/hidden_field.rb +5 -0
  33. data/lib/question_chain/models/ui_objects/object_reference_drop_down.rb +67 -0
  34. data/lib/question_chain/models/ui_objects/object_search.rb +44 -0
  35. data/lib/question_chain/models/ui_objects/radio_button.rb +5 -0
  36. data/lib/question_chain/models/ui_objects/radio_button_group.rb +5 -0
  37. data/lib/question_chain/models/ui_objects/relatable_category_drop_down.rb +70 -0
  38. data/lib/question_chain/models/ui_objects/text_field.rb +11 -0
  39. data/lib/question_chain/mongo_serialization.rb +62 -0
  40. data/lib/question_chain/mustache_handler.rb +16 -0
  41. data/lib/question_chain/mustache_rails.rb +50 -0
  42. data/lib/question_chain/state_machine.rb +29 -0
  43. data/lib/question_chain/stored_template.rb +30 -0
  44. data/lib/question_chain/version.rb +3 -0
  45. data/lib/question_chain/views/answers/_edit.html.haml +62 -0
  46. data/lib/question_chain/views/answers/_new.html.haml +62 -0
  47. data/lib/question_chain/views/answers/_question.html.mustache +11 -0
  48. data/lib/question_chain/views/answers/_ui_objects_check_box.html.mustache +19 -0
  49. data/lib/question_chain/views/answers/_ui_objects_drop_down.html.mustache +26 -0
  50. data/lib/question_chain/views/answers/_ui_objects_hidden_field.html.mustache +3 -0
  51. data/lib/question_chain/views/answers/_ui_objects_object_reference_drop_down.html.mustache +27 -0
  52. data/lib/question_chain/views/answers/_ui_objects_object_search.html.mustache +20 -0
  53. data/lib/question_chain/views/answers/_ui_objects_relatable_category_drop_down.html.mustache +26 -0
  54. data/lib/question_chain/views/answers/_ui_objects_text_field.html.mustache +19 -0
  55. data/lib/question_chain/views/layouts/application.html.haml +10 -0
  56. data/lib/question_chain.rb +35 -0
  57. data/question_chain.gemspec +31 -0
  58. data/test_app/.gitignore +4 -0
  59. data/test_app/Gemfile +29 -0
  60. data/test_app/Rakefile +16 -0
  61. data/test_app/app/controllers/answers_controller.rb +13 -0
  62. data/test_app/app/controllers/application_controller.rb +4 -0
  63. data/test_app/app/models/container.rb +10 -0
  64. data/test_app/app/models/flight.rb +20 -0
  65. data/test_app/app/views/answers/edit.html.haml +1 -0
  66. data/test_app/app/views/answers/new.html.haml +1 -0
  67. data/test_app/config/application.rb +18 -0
  68. data/test_app/config/boot.rb +13 -0
  69. data/test_app/config/database.yml +15 -0
  70. data/test_app/config/environment.rb +5 -0
  71. data/test_app/config/initializers/app.rb +5 -0
  72. data/test_app/config/initializers/cookie_verification_secret.rb +7 -0
  73. data/test_app/config/initializers/mongodb.rb +2 -0
  74. data/test_app/config/initializers/session_store.rb +3 -0
  75. data/test_app/config/routes.rb +30 -0
  76. data/test_app/config.ru +2 -0
  77. data/test_app/environments/development.rb +19 -0
  78. data/test_app/environments/test.rb +30 -0
  79. data/test_app/lib/tasks/rspec.rake +69 -0
  80. data/test_app/lib/tasks/yard.rake +4 -0
  81. data/test_app/public/.gitkeep +0 -0
  82. data/test_app/script/rails +10 -0
  83. data/test_app/spec/acceptance/new_spec +30 -0
  84. data/test_app/spec/factories.rb +81 -0
  85. data/test_app/spec/models/chain_template_spec.rb +53 -0
  86. data/test_app/spec/models/flight_spec.rb +101 -0
  87. data/test_app/spec/models/question_spec.rb +13 -0
  88. data/test_app/spec/models/rules/value_change_spec.rb +31 -0
  89. data/test_app/spec/models/ui_group_spec.rb +55 -0
  90. data/test_app/spec/models/ui_object_spec.rb +33 -0
  91. data/test_app/spec/models/ui_objects/drop_down_spec.rb +28 -0
  92. data/test_app/spec/models/ui_objects/relatable_category_drop_down_spec.rb +13 -0
  93. data/test_app/spec/spec_helper.rb +25 -0
  94. metadata +325 -0
@@ -0,0 +1,11 @@
1
+ module UiObjects
2
+ class TextField < UiObject
3
+
4
+ # == keys
5
+
6
+ # == Validations
7
+
8
+ # == Association
9
+
10
+ end
11
+ end
@@ -0,0 +1,62 @@
1
+ module MongoMapper
2
+ module Serialize
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ def self.attributes_for_api; []; end
7
+ def self.attributes_for_columns;[]; end
8
+ def self.columns
9
+ self.attributes_for_columns.map{|c| {:name => c}}
10
+ end
11
+ end
12
+
13
+ module InstanceMethods
14
+ # this is how we serialize man
15
+ def attributes_for_api_resource
16
+ result = {self.api_name => {}}
17
+ self.class.attributes_for_api.each do |key|
18
+ attribute = self.send(key)
19
+ if attribute.is_a?(Array) || attribute.is_a?(Set)
20
+ attribute.map! do |attr|
21
+ attr.respond_to?(:attributes_for_api_resources) ? attr.attributes_for_api_resources : attr
22
+ end
23
+ attribute = attribute.to_a
24
+ end
25
+ if attribute.nil? || attribute.is_a?(Array) || attribute.is_a?(Set)
26
+ result[self.api_name][key] = attribute
27
+ else
28
+ result[self.api_name][key] = (attribute.is_a?(BSON::ObjectId)) ? attribute.to_s : attribute
29
+ end
30
+ end
31
+ result
32
+ end
33
+
34
+ def attributes_for_api_resources
35
+ result = {}
36
+ self.class.attributes_for_api.each do |key|
37
+ attribute = self.send(key)
38
+ if attribute.is_a?(Array) || attribute.is_a?(Set)
39
+ attribute.map! do |attr|
40
+ attr.respond_to?(:attributes_for_api_resources) ? attr.attributes_for_api_resources : attr
41
+ end
42
+ attribute = attribute.to_a
43
+ end
44
+ if attribute.nil?
45
+ result[key] = attribute
46
+ else
47
+ result[key] = (attribute.is_a?(BSON::ObjectId)) ? attribute.to_s : attribute
48
+ end
49
+ end
50
+ result
51
+ end
52
+
53
+ def api_name
54
+ self.class.name.demodulize.underscore
55
+ end
56
+
57
+ def to_json
58
+ attributes_for_api_resource.to_json
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,16 @@
1
+ class MustacheHandler < ActionView::Template::Handler
2
+ include ActionView::Template::Handlers::Compilable
3
+
4
+ self.default_format = :mustache
5
+
6
+ # this string given is evaled in the context of the view_context
7
+ # therefore we can generate from that basis
8
+ def compile(template)
9
+ # virtual path is just a method in the new version of rails so can update from there!
10
+ virtual_path = template.respond_to?(:virtual_path) ? template.virtual_path : template.details[:virtual_path]
11
+ mustache_class_name = "#{virtual_path}_view".classify
12
+ mustache_class = mustache_class_name.constantize
13
+ "#{mustache_class}.new(self, %Q(#{template.source})).render.html_safe"
14
+ end
15
+
16
+ end
@@ -0,0 +1,50 @@
1
+ # @todo Change from a just outright hack!
2
+ class MustacheRails < Mustache
3
+
4
+ def initialize(view_context, template_source)
5
+ @view_context = view_context
6
+ self.template = template_source
7
+ assign_variables!
8
+ end
9
+
10
+ def respond_to?(method_sym, include_private = false)
11
+ if @view_context.respond_to?(method_sym)
12
+ true
13
+ else
14
+ super
15
+ end
16
+ end
17
+
18
+ def method_missing(method_name, *args, &block)
19
+ if self.respond_to?(method_name.to_sym)
20
+ @view_context.send(method_name,*args, &block)
21
+ else
22
+ super
23
+ end
24
+ end
25
+
26
+ def template=(template)
27
+ @raw_template = template
28
+ @template = templateify(template)
29
+ end
30
+
31
+ def render(data = template, ctx = {})
32
+ if self[:_raw] == true
33
+ @raw_template
34
+ else
35
+ templateify(data).render(context.update(ctx))
36
+ end
37
+ end
38
+
39
+
40
+ # we wish to add instance vars from the view_context only
41
+ # none funcky ones
42
+ private
43
+ def assign_variables!
44
+ variables = @view_context.instance_variable_names.select{|name| name =~ /^@[^_]/}
45
+ variables.each do |name|
46
+ assign_name = name.gsub(/@/, "_")
47
+ self[assign_name.to_sym] = @view_context.instance_variable_get(name)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,29 @@
1
+ module MongoMapper
2
+ module StateMachine
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include ::Transitions
7
+ key :model_state, String
8
+ before_validation_on_create :set_initial_state
9
+ validates_presence_of :model_state
10
+ end
11
+
12
+ def model_state
13
+ read_attribute(:model_state) || self.class.state_machine.initial_state.to_s
14
+ end
15
+
16
+ protected
17
+ def write_state(state_machine, state)
18
+ update_attributes! :model_state => state.to_s
19
+ end
20
+
21
+ def read_state(state_machine)
22
+ self.model_state.to_sym
23
+ end
24
+
25
+ def set_initial_state
26
+ self.model_state ||= self.class.state_machine.initial_state.to_s
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ module QuestionChain
2
+ class StoredResolver < ActionView::Resolver
3
+ def find_templates(name, prefix, partial, details)
4
+ scope = {:name => name, :prefix => prefix}
5
+ if formats = details[:formats]
6
+ formats = formats.map { |f| f.to_s }
7
+ scope.merge!(:format => formats)
8
+ end
9
+
10
+ if locales = details[:locales]
11
+ locales = locales.map { |f| f.to_s }
12
+ scope. merge!(:locale => locales)
13
+ end
14
+
15
+ StoredTemplate.all(scope).map do |r|
16
+ handler = ActionView::Template.handler_class_for_extension(r.handler)
17
+ details = { :locale => r.locale, :format => r.format, :partial => r.partial }
18
+ ActionView::Template.new(r.source, "Template Generated From DB: #{details.inspect}: Source #{r.source}", handler, details)
19
+ end
20
+ end
21
+ end
22
+
23
+ module TemplateResolver
24
+ extend ActiveSupport::Concern
25
+
26
+ included do
27
+ view_paths.unshift StoredResolver.new
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module QuestionChain
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,62 @@
1
+ - @raw = true
2
+ :javascript
3
+ questionBundle = #{@question.to_json}
4
+ uiObjectsDropDownTemplate = "#{escape_javascript(render(:partial => "ui_objects_drop_down"))}"
5
+ uiObjectsCheckboxTemplate = "#{escape_javascript(render(:partial => "ui_objects_check_box"))}"
6
+ uiObjectsTextFieldTemplate = "#{escape_javascript(render(:partial => "ui_objects_text_field"))}"
7
+ uiObjectsObjectReferenceDropDownTemplate = "#{escape_javascript(render(:partial => "ui_objects_object_reference_drop_down"))}"
8
+ uiObjectsRelatableCategoryDropDownTemplate = "#{escape_javascript(render(:partial => "ui_objects_relatable_category_drop_down"))}"
9
+ uiObjectsObjectSearchTemplate = "#{escape_javascript(render(:partial => "ui_objects_object_search"))}"
10
+ uiObjectsHiddenFieldTemplate = "#{escape_javascript(render(:partial => "ui_objects_hidden_field"))}"
11
+ - @raw = false
12
+
13
+ #loader
14
+
15
+ #global_notice
16
+
17
+ = yield :before_question
18
+
19
+ #question
20
+ = yield :before_question_partial
21
+ = render :partial => "question"
22
+ = yield :after_question_partial
23
+
24
+ = form_tag question_chain_update_answer_path, :class => "generic_form", :id => "question_#{@question.id}", :method => :put do |form|
25
+ = render :partial => "/shared/error_messages", :locals => {:resource => @answer}
26
+ = yield :before_ui_objects
27
+ .ui_groups
28
+ - @question.ui_groups.each do |ui_group|
29
+ .ui_group{:class => "#{ui_group.css_classes}", :id => "ui_object_#{ui_group.id}", :style => "#{ui_group.default_styles}"}
30
+ %fieldset
31
+ #ui_objects
32
+ - ui_group.ui_objects.each do |ui_object|
33
+ - case ui_object._type
34
+ - when "UiObjects::DropDown"
35
+ - @ui_object = ui_object
36
+ = render :partial => "ui_objects_drop_down"
37
+ - when "UiObjects::CheckBox"
38
+ - @ui_object = ui_object
39
+ = render :partial => "ui_objects_check_box"
40
+ - when "UiObjects::TextField"
41
+ - @ui_object = ui_object
42
+ = render :partial => "ui_objects_text_field"
43
+ - when "UiObjects::ObjectSearch"
44
+ - @ui_object = ui_object
45
+ = render :partial => "ui_objects_object_search"
46
+ - when "UiObjects::HiddenField"
47
+ - @ui_object = ui_object
48
+ = render :partial => "ui_objects_hidden_field"
49
+ - when "UiObjects::ObjectReferenceDropDown"
50
+ - @ui_object = ui_object
51
+ = render :partial => "ui_objects_object_reference_drop_down"
52
+ - when "UiObjects::RelatableCategoryDropDown"
53
+ - @ui_object = ui_object
54
+ = render :partial => "ui_objects_relatable_category_drop_down"
55
+
56
+ .buttons
57
+ %ul
58
+ %li
59
+ %input{:type => "submit", :value => "Submit", :class => "submit"}
60
+ = yield :after_ui_objects
61
+
62
+ = yield :after_question
@@ -0,0 +1,62 @@
1
+ - @raw = true
2
+ :javascript
3
+ questionBundle = #{@question.to_json}
4
+ uiObjectsDropDownTemplate = "#{escape_javascript(render(:partial => "ui_objects_drop_down"))}"
5
+ uiObjectsCheckboxTemplate = "#{escape_javascript(render(:partial => "ui_objects_check_box"))}"
6
+ uiObjectsTextFieldTemplate = "#{escape_javascript(render(:partial => "ui_objects_text_field"))}"
7
+ uiObjectsObjectReferenceDropDownTemplate = "#{escape_javascript(render(:partial => "ui_objects_object_reference_drop_down"))}"
8
+ uiObjectsRelatableCategoryDropDownTemplate = "#{escape_javascript(render(:partial => "ui_objects_relatable_category_drop_down"))}"
9
+ uiObjectsObjectSearchTemplate = "#{escape_javascript(render(:partial => "ui_objects_object_search"))}"
10
+ uiObjectsHiddenFieldTemplate = "#{escape_javascript(render(:partial => "ui_objects_hidden_field"))}"
11
+ - @raw = false
12
+
13
+ #loader
14
+
15
+ #global_notice
16
+
17
+ = yield :before_question
18
+
19
+ #question
20
+ = yield :before_question_partial
21
+ = render :partial => "question"
22
+ = yield :after_question_partial
23
+
24
+ = form_tag question_chain_answer_path, :class => "generic_form", :id => "question_#{@question.id}" do |form|
25
+ = render :partial => "/shared/error_messages", :locals => {:resource => @answer}
26
+ = yield :before_ui_objects
27
+ .ui_groups
28
+ - @question["ui_groups"].each do |ui_group|
29
+ .ui_group{:class => "#{ui_group.css_classes}", :id => "ui_object_#{ui_group.id}", :style => "#{ui_group.default_styles}"}
30
+ %fieldset
31
+ #ui_objects
32
+ - ui_group["ui_objects"].each do |ui_object|
33
+ - case ui_object._type
34
+ - when "UiObjects::DropDown"
35
+ - @ui_object = ui_object
36
+ = render :partial => "ui_objects_drop_down"
37
+ - when "UiObjects::CheckBox"
38
+ - @ui_object = ui_object
39
+ = render :partial => "ui_objects_check_box"
40
+ - when "UiObjects::TextField"
41
+ - @ui_object = ui_object
42
+ = render :partial => "ui_objects_text_field"
43
+ - when "UiObjects::ObjectSearch"
44
+ - @ui_object = ui_object
45
+ = render :partial => "ui_objects_object_search"
46
+ - when "UiObjects::HiddenField"
47
+ - @ui_object = ui_object
48
+ = render :partial => "ui_objects_hidden_field"
49
+ - when "UiObjects::ObjectReferenceDropDown"
50
+ - @ui_object = ui_object
51
+ = render :partial => "ui_objects_object_reference_drop_down"
52
+ - when "UiObjects::RelatableCategoryDropDown"
53
+ - @ui_object = ui_object
54
+ = render :partial => "ui_objects_relatable_category_drop_down"
55
+
56
+ .buttons
57
+ %ul
58
+ %li
59
+ %input{:type => "submit", :value => "Submit", :class => "submit"}
60
+ = yield(:after_ui_objects)
61
+
62
+ = yield :after_question
@@ -0,0 +1,11 @@
1
+ <dl class="question-template">
2
+ <dt>Question</dt>
3
+ <dd class="question_title">
4
+ {{label}}
5
+ </dd>
6
+
7
+ <dt>Description</dt>
8
+ <dd class="question_description">
9
+ {{description}}
10
+ </dd>
11
+ </dl>
@@ -0,0 +1,19 @@
1
+ <dl class="ui-objects-checkbox-template {{css_classes}}" id="{{dom_id}}" style={{default_styles}}>
2
+ <dt>
3
+ <label for="{{input_id}}">
4
+ {{label}}
5
+ </label>
6
+ {{#has_extra_info}}
7
+ <span class="tooltip">
8
+ Extended Information
9
+ <span class="description">
10
+ {{extra_info}}
11
+ </span>
12
+ </span>
13
+ {{/has_extra_info}}
14
+ </dt>
15
+
16
+ <dd>
17
+ <input type="checkbox" name="{{name}}" {{#checked}}checked="checked"{{/checked}} id="{{input_id}}">
18
+ </dd>
19
+ </dl>
@@ -0,0 +1,26 @@
1
+ <dl class="ui-objects-drop-down-template {{css_classes}}" id="{{dom_id}}" style={{default_styles}}>
2
+ <dt>
3
+ <label for="{{input_id}}">
4
+ {{label}}
5
+ </label>
6
+ {{#has_extra_info}}
7
+ <span class="tooltip">
8
+ Extended Information
9
+ <span class="description">
10
+ {{extra_info}}
11
+ </span>
12
+ </span>
13
+ {{/has_extra_info}}
14
+ </dt>
15
+
16
+ <dd>
17
+ <select name="{{name}}" id="{{input_id}}">
18
+ {{#prompt}}
19
+ <option value="">{{prompt}}</option>
20
+ {{/prompt}}
21
+ {{#options}}
22
+ <option value="{{value}}" {{#selected}}selected="selected"{{/selected}} title="{{name}}">{{name}}</option>
23
+ {{/options}}
24
+ </select>
25
+ </dd>
26
+ </dl>
@@ -0,0 +1,3 @@
1
+ <div id="{{dom_id}}">
2
+ <input type="hidden" name="{{name}}" value="{{value}}" id="{{input_id}}">
3
+ </div>
@@ -0,0 +1,27 @@
1
+ <dl class="ui-objects-object_reference-drop-down-template {{css_classes}}" id="{{dom_id}}" style={{default_styles}}>
2
+ <dt>
3
+ <label for="{{input_id}}">
4
+ {{label}}
5
+ </label>
6
+ {{#has_extra_info}}
7
+ <span class="tooltip">
8
+ Extended Information
9
+ <span class="description">
10
+ {{extra_info}}
11
+ </span>
12
+ </span>
13
+ {{/has_extra_info}}
14
+ </dt>
15
+
16
+
17
+ <dd>
18
+ <select name="{{name}}" id="{{input_id}}">
19
+ {{#prompt}}
20
+ <option value="">{{prompt}}</option>
21
+ {{/prompt}}
22
+ {{#options}}
23
+ <option value="{{value}}" {{#selected}}selected="selected"{{/selected}} title="{{name}}">{{name}}</option>
24
+ {{/options}}
25
+ </select>
26
+ </dd>
27
+ </dl>
@@ -0,0 +1,20 @@
1
+ <dl class="ui-objects-object-search-template {{css_classes}}" id="{{dom_id}}" style={{default_styles}}>
2
+ <dt>
3
+ <label for="{{input_id}}">
4
+ {{label}}
5
+ </label>
6
+ {{#has_extra_info}}
7
+ <span class="tooltip">
8
+ Extended Information
9
+ <span class="description">
10
+ {{extra_info}}
11
+ </span>
12
+ </span>
13
+ {{/has_extra_info}}
14
+ </dt>
15
+
16
+ <dd>
17
+ <input type="text" name="{{search_name}}" id="{{search_id}}" value="{{search_value}}">
18
+ <input type="hidden" name="{{name}}" value="{{value}}" id="{{input_id}}">
19
+ </dd>
20
+ </dl>
@@ -0,0 +1,26 @@
1
+ <dl class="ui-objects-related-category-drop-down {{css_classes}}" id="{{dom_id}}" style={{default_styles}}>
2
+ <dt>
3
+ <label for="{{input_id}}">
4
+ {{label}}
5
+ </label>
6
+ {{#has_extra_info}}
7
+ <span class="tooltip">
8
+ Extended Information
9
+ <span class="description">
10
+ {{extra_info}}
11
+ </span>
12
+ </span>
13
+ {{/has_extra_info}}
14
+ </dt>
15
+
16
+ <dd>
17
+ <select name="{{name}}" id="{{input_id}}">
18
+ {{#prompt}}
19
+ <option value="">{{prompt}}</option>
20
+ {{/prompt}}
21
+ {{#options}}
22
+ <option value="{{value}}" {{#selected}}selected="selected"{{/selected}} title="{{name}}">{{name}}</option>
23
+ {{/options}}
24
+ </select>
25
+ </dd>
26
+ </dl>
@@ -0,0 +1,19 @@
1
+ <dl class="ui-objects-text-field-template {{css_classes}}" id="{{dom_id}}" style={{default_styles}}>
2
+ <dt>
3
+ <label for="{{input_id}}">
4
+ {{label}}
5
+ </label>
6
+ {{#has_extra_info}}
7
+ <span class="tooltip">
8
+ Extended Information
9
+ <span class="description">
10
+ {{extra_info}}
11
+ </span>
12
+ </span>
13
+ {{/has_extra_info}}
14
+ </dt>
15
+
16
+ <dd>
17
+ <input type="text" name="{{name}}" value="{{value}}" id="{{input_id}}">
18
+ </dd>
19
+ </dl>
@@ -0,0 +1,10 @@
1
+ !!! 5
2
+ %html.no-js{:lang => "en"}
3
+
4
+ %head
5
+ %meta{:charset => "utf-8"}
6
+ %title QuestionChain
7
+
8
+ %body
9
+ = yield
10
+
@@ -0,0 +1,35 @@
1
+ # == Default requires
2
+ require 'rubygems'
3
+ require "crack"
4
+ require "hashie"
5
+ require "mustache"
6
+ require "calculated"
7
+
8
+ # == Carbon cal specific
9
+ require "question_chain/mongo_serialization"
10
+ require "question_chain/state_machine"
11
+ require "question_chain/mustache_handler"
12
+ require "question_chain/stored_template"
13
+ require "question_chain/mustache_rails"
14
+ require "question_chain/answerable"
15
+
16
+ # == Answers Controller
17
+ require "question_chain/answers"
18
+
19
+ module QuestionChain
20
+ class Engine < Rails::Engine
21
+
22
+ config.carbon_calculated = ActiveSupport::OrderedOptions.new
23
+ paths.app.controllers << "lib/question_chain/controllers"
24
+ paths.app.views << "lib/question_chain/views"
25
+ paths.app.models << "lib/question_chain/models"
26
+
27
+ config.after_initialize do
28
+ QuestionChain.class_eval do
29
+ def self.calculated_session
30
+ @calculated_session ||= Rails.application.class.to_s.gsub(/::.*/,"").constantize.calculated_session
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "question_chain/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "question_chain"
7
+ s.version = QuestionChain::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Richard Hooker"]
10
+ s.email = ["richard.hooker@carboncalculated.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Rails3 Gem to Generate Carbon Calculated Application}
13
+ s.description = %q{Rails3 Gem to Generate Carbon Calculated Application}
14
+
15
+ s.rubyforge_project = "question_chain"
16
+
17
+ s.add_dependency 'mustache', '>= 0.98.0'
18
+ s.add_dependency 'mongo_mapper', '>= 0.8.1'
19
+ s.add_dependency 'mustache', '>= 0.98.0'
20
+ s.add_dependency 'hashie', ">= 0.2.1"
21
+ s.add_dependency 'crack', ">= 0.1.8"
22
+ s.add_dependency 'calculated', ">= 0.1.5"
23
+ s.add_dependency 'rails', "~> 3.0.0"
24
+ s.add_dependency 'inherited_resources', "~> 1.2.0"
25
+ s.add_dependency 'hunt', "~> 0.3.0"
26
+
27
+ s.files = `git ls-files`.split("\n")
28
+ s.test_files = `git ls-files -- {test,spec,features,test_app}/*`.split("\n")
29
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
30
+ s.require_paths = ["lib"]
31
+ end
@@ -0,0 +1,4 @@
1
+ .bundle
2
+ db/*.sqlite3
3
+ log/*.log
4
+ tmp/**/*
data/test_app/Gemfile ADDED
@@ -0,0 +1,29 @@
1
+ source 'http://rubygems.org'
2
+
3
+ ## Bundle the gems you use:
4
+ gem "rails", "3.0.5"
5
+
6
+ gem "bson_ext", "1.2.4"
7
+ gem "inherited_resources"
8
+ gem "mongo_mapper", "0.8.6"
9
+ gem "hunt"
10
+ gem "transitions"
11
+ gem "question_chain", :path =>File.expand_path("../../", __FILE__), :require => "question_chain"
12
+ gem "yard"
13
+
14
+ gem "haml", "3.0.21"
15
+ gem "mustache"
16
+ gem "canable"
17
+
18
+ group :test, :cucumber do
19
+ gem "database_cleaner", "0.6"
20
+ gem 'capybara', :git => 'git://github.com/jnicklas/capybara.git'
21
+ gem 'selenium-webdriver', '0.1.2'
22
+ gem 'factory_girl', '~> 1.3'
23
+ gem "rake"
24
+ gem "rspec", "2.5.0"
25
+ gem "rspec-rails", "~> 2.5.0"
26
+ gem 'vcr', '~> 1.5', :require => false
27
+ gem 'webmock', '~> 1.6', :require => false
28
+ gem "autotest"
29
+ end
data/test_app/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ require 'rake'
7
+ require 'rake/testtask'
8
+ require 'rake/rdoctask'
9
+
10
+ TestApp::Application.load_tasks
11
+
12
+ namespace :ci do
13
+ desc "Prepare for CI and run entire test suite"
14
+ task :build => ['spec'] do
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ class AnswersController < ApplicationController
2
+ inherit_resources
3
+ include Canable::Enforcers
4
+ belongs_to :container, :polymorphic => true
5
+ include QuestionChain::Answers
6
+
7
+ private
8
+ # I will not go into however this is required but not from the include
9
+ def collection_path
10
+ polymorphic_path(@contexts[0..-1] << @context.to_sym)
11
+ end
12
+ end
13
+
@@ -0,0 +1,4 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery
3
+ include Canable::Enforcers
4
+ end
@@ -0,0 +1,10 @@
1
+ class Container
2
+ include MongoMapper::Document
3
+
4
+ # == Keys
5
+ key :name, String
6
+
7
+ # == Associations
8
+ has_many :flights
9
+
10
+ end