quby-compiler 0.6.6 → 0.6.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96a88dc734b7b4dcec4c90b1a296ce1daa1db155b7c07c6e8211f510d6f6d6a8
4
- data.tar.gz: d7f5255fc362997ed992b3a8fa5b3b7419e6944d5ec33275c968e8fa41eed6e8
3
+ metadata.gz: 01cfba3183d5a4279b2c73b3c9cee99b676bb878fe4fb41750966dff9f3cee05
4
+ data.tar.gz: b73b3f4426dc2a4f995fd03164a49ef65d27a723d7de870fdeceaebf26efecc0
5
5
  SHA512:
6
- metadata.gz: be0139d2d2fb49f4d282fe2ff0bf8eecfcfadf0e54ac5a5f7ed5c05b1797e687690666bba7cc8cd4504bff8860d3c4353b23fa99fc7296e6763758a5d603ee17
7
- data.tar.gz: cc9c0bea2deb15f53da4a299f63117a93cce53326e333cba11e1ce08d5047ad968eb0d91cc1393b4620adfa945affc93f1049cfb2f18a5f9aa9a471260318da3
6
+ metadata.gz: 7babf0bc0256ed62390f442b34104eaf64778ad04a563fa3ffd239091bcca67f0d3058a42a67df4b8db50a12a8e6bd064636f290cc519233065c7d0a18175e9f
7
+ data.tar.gz: c65d1f03ed2219c8b3704a843323ef92bb019baef95889ee86d40ecc67fb4f4eda5a2bdb5905adf652178657b783232c85353db0fb726076efbaad1ea342ce21
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ # 0.6.8
2
+
3
+ * dsl_quby2.json: Add count_selected to s-expressions.
4
+ * dsl_quby2.json: Add cond, true and false to s-expressions. cond evaluates the body of the first clause whose test is true; each body must have the same type.
5
+ * dsl_quby2.json: single_select_label variables (also via cond) must be declared `type: :quest_i18n_key` and are serialized with that type.
6
+
7
+ # 0.6.7
8
+
9
+ * dsl_quby2.json: Add single_select_label to s-expressions.
10
+
1
11
  # 0.6.6
2
12
 
3
13
  * dsl: Add Question#subtype (iso_country_number).
@@ -49,7 +49,7 @@ module Quby
49
49
 
50
50
  content = sources.map { |url, ext| tag.source src: url, type: "video/#{ext}" }
51
51
  .append(I18n.t('video_not_supported'))
52
- .yield_self(&tag.method(:safe_join))
52
+ .then { safe_join(_1) }
53
53
 
54
54
  content_tag(:video, content, options)
55
55
  end
@@ -19,6 +19,14 @@ module Quby::Compiler
19
19
  Entities::SexpVariables::StringValue.new(op: :string_value, key: key)
20
20
  end
21
21
 
22
+ def single_select_label(key)
23
+ Entities::SexpVariables::SingleSelectLabel.new(op: :single_select_label, key: key)
24
+ end
25
+
26
+ def count_selected(key)
27
+ Entities::SexpVariables::CountSelected.new(key: key)
28
+ end
29
+
22
30
  def number_value(key)
23
31
  Entities::SexpVariables::NumberValue.new(op: :number_value, key: key)
24
32
  end
@@ -49,6 +57,16 @@ module Quby::Compiler
49
57
  Entities::SexpVariables::NumberMethod.new(op: :round, value: value)
50
58
  end
51
59
 
60
+ # cond(clause(gt(left: number_value(:v_1), right: 2), 4), clause(true, 0))
61
+ # evaluates the body of the first clause whose test is true, so `clause(true, ...)` acts as the default case.
62
+ def cond(*clauses)
63
+ Entities::SexpVariables::Cond.new(op: :cond, clauses:)
64
+ end
65
+
66
+ def clause(test, body)
67
+ Entities::SexpVariables::Cond::Clause.new(test: wrap_scalars(test), body: wrap_scalars(body))
68
+ end
69
+
52
70
  def build
53
71
  Entities::SexpVariable.new(key:, calculation:, type:)
54
72
  end
@@ -63,9 +81,15 @@ module Quby::Compiler
63
81
  case value
64
82
  when Numeric
65
83
  Entities::SexpVariables::Number.new(op: :number, value: value)
84
+ when true
85
+ Entities::SexpVariables::True.new
86
+ when false
87
+ Entities::SexpVariables::False.new
88
+ when String
89
+ fail ArgumentError, "string literals are not supported in sexp_variables (they can't be translated), use string_value(:key) to reference a string question."
66
90
  else
67
91
  value
68
- end
92
+ end
69
93
  end
70
94
  end
71
95
  end
@@ -14,7 +14,11 @@ module Quby::Compiler::Entities
14
14
  def validate(questionnaire, calculation: self.calculation)
15
15
  validate_node(calculation, questionnaire:, type:)
16
16
  end
17
-
17
+
18
+ def as_json(options = nil)
19
+ {key:, type: node_type(calculation), calculation:}.as_json(options)
20
+ end
21
+
18
22
  private
19
23
 
20
24
  def validate_node(node, questionnaire:, type:)
@@ -27,6 +31,12 @@ module Quby::Compiler::Entities
27
31
  when SexpVariables::StringValue
28
32
  validate_question_exist(questionnaire, node)
29
33
  validate_value_is_string(questionnaire, node)
34
+ when SexpVariables::SingleSelectLabel
35
+ validate_question_exist(questionnaire, node)
36
+ validate_value_is_single_select(questionnaire, node)
37
+ when SexpVariables::CountSelected
38
+ validate_question_exist(questionnaire, node)
39
+ validate_value_is_multi_select(questionnaire, node)
30
40
  when SexpVariables::NumberReducer
31
41
  node.values.each do |value|
32
42
  validate_node(value, questionnaire:, type: :number)
@@ -38,13 +48,17 @@ module Quby::Compiler::Entities
38
48
  when SexpVariables::Comparer
39
49
  validate_node(node.left, questionnaire:, type: :number)
40
50
  validate_node(node.right, questionnaire:, type: :number)
51
+ when SexpVariables::Cond
52
+ node.clauses.each do |clause|
53
+ validate_node(clause.test, questionnaire:, type: :boolean)
54
+
55
+ validate_node(clause.body, questionnaire:, type: type)
56
+ end
41
57
  end
42
58
  end
43
59
 
44
60
  def validate_type(node, type:)
45
- return if type == :number && SexpVariables::NumericType === node
46
- return if type == :boolean && SexpVariables::BooleanType === node
47
- return if type == :string && SexpVariables::StringValue === node
61
+ return if type == node_type(node)
48
62
 
49
63
  fail "sexp_variable #{key} has invalid type #{node.class} for expected type #{type}."
50
64
  end
@@ -65,6 +79,23 @@ module Quby::Compiler::Entities
65
79
  fail "sexp_variable #{key} uses non-numeric question #{sexp.key} for number_value."
66
80
  end
67
81
 
82
+ def validate_value_is_single_select(questionnaire, sexp)
83
+ question = questionnaire.question_hash[sexp.key]
84
+ case question
85
+ when Questions::RadioQuestion, Questions::SelectQuestion
86
+ return
87
+ end
88
+
89
+ fail "sexp_variable #{key} uses non-single-select question #{sexp.key} for single_select_label."
90
+ end
91
+
92
+ def validate_value_is_multi_select(questionnaire, sexp)
93
+ question = questionnaire.question_hash[sexp.key]
94
+ return if Questions::CheckboxQuestion === question
95
+
96
+ fail "sexp_variable #{key} uses non-multi-select question #{sexp.key} for count_selected."
97
+ end
98
+
68
99
  def validate_value_is_string(questionnaire, sexp)
69
100
  question = questionnaire.question_hash[sexp.key]
70
101
  case question
@@ -74,5 +105,20 @@ module Quby::Compiler::Entities
74
105
 
75
106
  fail "sexp_variable #{key} uses non-string question #{sexp.key} for string_value."
76
107
  end
108
+
109
+ def node_type(node)
110
+ case(node)
111
+ when SexpVariables::Cond # match first, since it's in all types.
112
+ node_type(node.clauses.first.body)
113
+ when SexpVariables::BooleanType
114
+ :boolean
115
+ when SexpVariables::NumericType
116
+ :number
117
+ when SexpVariables::StringType
118
+ :string
119
+ when SexpVariables::QuestI18nKeyType
120
+ :quest_i18n_key
121
+ end
122
+ end
77
123
  end
78
124
  end
@@ -4,28 +4,62 @@ module Quby::Compiler::Entities
4
4
  end
5
5
 
6
6
  # recursive dependencies, we so we define the classes first.
7
+ class Cond < Base; end
8
+
7
9
  class NumberValue < Base; end
8
10
  class Number < Base; end
9
11
  class NumberReducer < Base; end
10
12
  class NumberMethod < Base; end
13
+ class CountSelected < Base; end
14
+
11
15
  class BooleanReducer < Base; end
12
16
  class Comparer < Base; end
17
+ class True < Base; end
18
+ class False < Base; end
13
19
 
14
- NumericType = Number | NumberReducer | NumberMethod | NumberValue
15
- BooleanType = BooleanReducer | Comparer
20
+ class StringValue < Base; end
21
+ class SingleSelectLabel < Base; end
22
+
23
+ NumericType = Number | NumberReducer | NumberMethod | NumberValue | CountSelected | Cond
24
+ BooleanType = BooleanReducer | Comparer | True | False | Cond
25
+ StringType = StringValue | Cond
26
+ QuestI18nKeyType = SingleSelectLabel | Cond
27
+ AllTypes = NumericType | BooleanType | StringType | QuestI18nKeyType
16
28
 
17
29
  class NumberValue
18
30
  attribute :op, Quby::Types::Symbol.enum(:number_value)
19
31
  attribute :key, Quby::Types::Symbol
20
32
  end
21
33
 
22
- class StringValue < Base
34
+ class StringValue
23
35
  attribute :op, Quby::Types::Symbol.enum(:string_value)
24
36
  attribute :key, Quby::Types::Symbol
25
37
  end
26
38
 
39
+ # label of the selected option of a single-select (radio, scale, select) question.
40
+ class SingleSelectLabel
41
+ attribute :op, Quby::Types::Symbol.enum(:single_select_label)
42
+ attribute :key, Quby::Types::Symbol
43
+ end
44
+
45
+ # returning a Boolean: always true. Used as the default case of a cond.
46
+ class True
47
+ attribute :op, Quby::Types::Symbol.default(:true).enum(:true)
48
+ end
49
+
50
+ # returning a Boolean: always false.
51
+ class False
52
+ attribute :op, Quby::Types::Symbol.default(:false).enum(:false)
53
+ end
54
+
55
+ # number of selected options of a multi-select (check_box) question.
56
+ class CountSelected
57
+ attribute :op, Quby::Types::Symbol.default(:count_selected).enum(:count_selected)
58
+ attribute :key, Quby::Types::Symbol
59
+ end
60
+
27
61
  class Number
28
- attribute :op, Quby::Types::Symbol.enum(:number)
62
+ attribute :op, Quby::Types::Symbol.enum(:number)
29
63
  attribute :value, Quby::Types::Integer | Quby::Types::Float
30
64
  end
31
65
 
@@ -50,8 +84,20 @@ module Quby::Compiler::Entities
50
84
 
51
85
  # returning a Number
52
86
  class NumberMethod
53
- attribute :op, Quby::Types::Symbol.enum(:round)
87
+ attribute :op, Quby::Types::Symbol.enum(:round)
54
88
  attribute :value, NumericType
55
89
  end
90
+
91
+ # evaluates the body of the first clause whose test is true.
92
+ # Each body should have the same type, which determines the result type.
93
+ class Cond
94
+ class Clause < Base
95
+ attribute :test, BooleanType
96
+ attribute :body, AllTypes
97
+ end
98
+
99
+ attribute :op, Quby::Types::Symbol.enum(:cond)
100
+ attribute :clauses, Quby::Types::Array.of(Clause).constrained(min_size: 1)
101
+ end
56
102
  end
57
103
  end
@@ -1,5 +1,5 @@
1
1
  module Quby
2
2
  module Compiler
3
- VERSION = "0.6.6"
3
+ VERSION = "0.6.8"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quby-compiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.6
4
+ version: 0.6.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marten Veldthuis
@@ -13,44 +13,62 @@ dependencies:
13
13
  name: activemodel
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - ">="
16
+ - - ">"
17
+ - !ruby/object:Gem::Version
18
+ version: '7.1'
19
+ - - "<"
17
20
  - !ruby/object:Gem::Version
18
- version: '5.0'
21
+ version: '8.2'
19
22
  type: :runtime
20
23
  prerelease: false
21
24
  version_requirements: !ruby/object:Gem::Requirement
22
25
  requirements:
23
- - - ">="
26
+ - - ">"
24
27
  - !ruby/object:Gem::Version
25
- version: '5.0'
28
+ version: '7.1'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '8.2'
26
32
  - !ruby/object:Gem::Dependency
27
33
  name: actionview
28
34
  requirement: !ruby/object:Gem::Requirement
29
35
  requirements:
30
- - - ">="
36
+ - - ">"
37
+ - !ruby/object:Gem::Version
38
+ version: '7.1'
39
+ - - "<"
31
40
  - !ruby/object:Gem::Version
32
- version: '5.0'
41
+ version: '8.2'
33
42
  type: :runtime
34
43
  prerelease: false
35
44
  version_requirements: !ruby/object:Gem::Requirement
36
45
  requirements:
37
- - - ">="
46
+ - - ">"
47
+ - !ruby/object:Gem::Version
48
+ version: '7.1'
49
+ - - "<"
38
50
  - !ruby/object:Gem::Version
39
- version: '5.0'
51
+ version: '8.2'
40
52
  - !ruby/object:Gem::Dependency
41
53
  name: activesupport
42
54
  requirement: !ruby/object:Gem::Requirement
43
55
  requirements:
44
- - - ">="
56
+ - - ">"
45
57
  - !ruby/object:Gem::Version
46
- version: '5.0'
58
+ version: '7.1'
59
+ - - "<"
60
+ - !ruby/object:Gem::Version
61
+ version: '8.2'
47
62
  type: :runtime
48
63
  prerelease: false
49
64
  version_requirements: !ruby/object:Gem::Requirement
50
65
  requirements:
51
- - - ">="
66
+ - - ">"
67
+ - !ruby/object:Gem::Version
68
+ version: '7.1'
69
+ - - "<"
52
70
  - !ruby/object:Gem::Version
53
- version: '5.0'
71
+ version: '8.2'
54
72
  - !ruby/object:Gem::Dependency
55
73
  name: csv
56
74
  requirement: !ruby/object:Gem::Requirement
@@ -149,6 +167,20 @@ dependencies:
149
167
  - - ">="
150
168
  - !ruby/object:Gem::Version
151
169
  version: '0'
170
+ - !ruby/object:Gem::Dependency
171
+ name: appraisal
172
+ requirement: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - ">="
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
177
+ type: :development
178
+ prerelease: false
179
+ version_requirements: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ version: '0'
152
184
  email:
153
185
  - marten@veldthuis.com
154
186
  executables: