set_builder 1.0.2

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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +35 -0
  6. data/Rakefile +14 -0
  7. data/assets/javascripts/array.js +100 -0
  8. data/assets/javascripts/set_builder.js +415 -0
  9. data/init.rb +1 -0
  10. data/install.rb +1 -0
  11. data/lib/set_builder.rb +58 -0
  12. data/lib/set_builder/constraint.rb +67 -0
  13. data/lib/set_builder/modifier.rb +134 -0
  14. data/lib/set_builder/modifier/adverb.rb +11 -0
  15. data/lib/set_builder/modifier/base.rb +105 -0
  16. data/lib/set_builder/modifier/verb.rb +24 -0
  17. data/lib/set_builder/modifier_collection.rb +41 -0
  18. data/lib/set_builder/modifiers.rb +3 -0
  19. data/lib/set_builder/modifiers/date_modifier.rb +83 -0
  20. data/lib/set_builder/modifiers/number_modifier.rb +48 -0
  21. data/lib/set_builder/modifiers/string_modifier.rb +81 -0
  22. data/lib/set_builder/query_builders/string.rb +0 -0
  23. data/lib/set_builder/set.rb +81 -0
  24. data/lib/set_builder/trait.rb +74 -0
  25. data/lib/set_builder/traits.rb +42 -0
  26. data/lib/set_builder/value_map.rb +62 -0
  27. data/lib/set_builder/version.rb +3 -0
  28. data/set_builder.gemspec +25 -0
  29. data/spec/commands/example_command.rb +19 -0
  30. data/spec/dom.html +24 -0
  31. data/spec/lib/images/bg.png +0 -0
  32. data/spec/lib/images/hr.png +0 -0
  33. data/spec/lib/images/loading.gif +0 -0
  34. data/spec/lib/images/sprites.bg.png +0 -0
  35. data/spec/lib/images/sprites.png +0 -0
  36. data/spec/lib/images/vr.png +0 -0
  37. data/spec/lib/jspec.css +149 -0
  38. data/spec/lib/jspec.growl.js +115 -0
  39. data/spec/lib/jspec.jquery.js +88 -0
  40. data/spec/lib/jspec.js +1908 -0
  41. data/spec/lib/jspec.nodejs.js +18 -0
  42. data/spec/lib/jspec.shell.js +39 -0
  43. data/spec/lib/jspec.timers.js +154 -0
  44. data/spec/lib/jspec.xhr.js +210 -0
  45. data/spec/node.js +10 -0
  46. data/spec/rhino.js +10 -0
  47. data/spec/server.html +18 -0
  48. data/spec/server.rb +4 -0
  49. data/spec/unit/array.spec.js +82 -0
  50. data/spec/unit/set_builder.spec.js +166 -0
  51. data/spec/unit/spec.helper.js +0 -0
  52. data/test/date_modifier_test.rb +13 -0
  53. data/test/inflector_test.rb +27 -0
  54. data/test/modifier_test.rb +90 -0
  55. data/test/set_test.rb +96 -0
  56. data/test/test_helper.rb +79 -0
  57. data/test/trait_test.rb +49 -0
  58. data/test/traits_test.rb +41 -0
  59. data/test/value_map_test.rb +30 -0
  60. data/uninstall.rb +1 -0
  61. metadata +191 -0
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'set_builder'
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,58 @@
1
+ require 'active_record'
2
+ require 'active_support/core_ext'
3
+ require 'set_builder/traits'
4
+ require 'set_builder/modifiers'
5
+ require 'set_builder/value_map'
6
+ require 'set_builder/set'
7
+
8
+
9
+ module SetBuilder
10
+
11
+
12
+ def self.extended(base)
13
+ base.instance_variable_set("@traits", SetBuilder::Traits.new)
14
+ base.send(:include, SetBuilder::Modifiers)
15
+ end
16
+
17
+
18
+ attr_reader :traits
19
+
20
+
21
+ def modifiers
22
+ traits.modifiers
23
+ end
24
+
25
+
26
+ def that_belong_to(set)
27
+ SetBuilder::Set.new(self, set)
28
+ end
29
+
30
+
31
+ protected
32
+
33
+
34
+
35
+ def trait(*args, &block)
36
+ part_of_speech = get_part_of_speech(args.shift)
37
+ name = args.shift
38
+ traits << Trait.new(name, part_of_speech, *args, &block)
39
+ end
40
+
41
+
42
+ def get_part_of_speech(arg)
43
+ case arg
44
+ when :is, :are, :reflexive
45
+ :reflexive
46
+ when nil, :active
47
+ :active
48
+ when :was, :were, :passive
49
+ :passive
50
+ when :has, :have, :perfect
51
+ :perfect
52
+ when :whose, :noun
53
+ :noun
54
+ end
55
+ end
56
+
57
+
58
+ end
@@ -0,0 +1,67 @@
1
+ require 'set_builder/modifier'
2
+
3
+
4
+ module SetBuilder
5
+ class Constraint
6
+
7
+
8
+ #
9
+ # Sample constraints:
10
+ #
11
+ # [:awesome],
12
+ # [:attended, "school"],
13
+ # [:died],
14
+ # [:name, {:is => "Jerome"}]]
15
+ #
16
+ def initialize(trait, *args, &block)
17
+ @trait, @block = trait, block
18
+ @direct_object = args.shift if trait.requires_direct_object?
19
+ @modifiers = trait.modifiers.collect {|modifier_type| modifier_type.new(args.shift)}
20
+ end
21
+
22
+
23
+
24
+ attr_reader :trait, :direct_object, :modifiers, :negative
25
+
26
+
27
+
28
+ delegate :direct_object_required?,
29
+ :direct_object_type,
30
+ :to => :trait
31
+
32
+
33
+
34
+ def valid?
35
+ (!direct_object_required? or !direct_object.nil?) and modifiers.all?(&:valid?)
36
+ end
37
+
38
+
39
+
40
+ def to_s
41
+ # p "ValueMap.to_s(#{direct_object_type} (#{direct_object_type.class}), #{direct_object} (#{direct_object.class}))"
42
+ @description ||= begin
43
+ description = trait.to_s(@negative)
44
+ description << " #{ValueMap.to_s(direct_object_type, direct_object)}" if direct_object_required?
45
+ description << " #{modifiers.collect{|m| m.to_s(@negative)}.join(" ")}" unless modifiers.empty?
46
+ description
47
+ end
48
+ end
49
+
50
+
51
+
52
+ def negate(value)
53
+ @negative = value
54
+ @negative = false if trait.noun?
55
+ self
56
+ end
57
+
58
+
59
+
60
+ def perform(scope)
61
+ scope.scoped(@block.call(self, scope))
62
+ end
63
+
64
+
65
+
66
+ end
67
+ end
@@ -0,0 +1,134 @@
1
+ require 'set_builder/modifiers'
2
+ require 'set_builder/modifier/adverb'
3
+ require 'set_builder/modifier/verb'
4
+
5
+ module SetBuilder
6
+ module Modifier
7
+
8
+
9
+
10
+ @registered_modifiers = {}
11
+
12
+
13
+
14
+ def self.registered?(klass)
15
+ @registered_modifiers.values.member?(klass)
16
+ end
17
+
18
+
19
+
20
+ def self.name(klass)
21
+ @registered_modifiers.each do |key, value|
22
+ return key if (value == klass)
23
+ end
24
+ klass.name
25
+ end
26
+
27
+
28
+
29
+ def self.for(type)
30
+ type = get_type(type)
31
+ @registered_modifiers[type] || raise(ArgumentError, "A modifier has not been registered for #{type}")
32
+ end
33
+
34
+
35
+
36
+ def self.[](klass_or_symbol)
37
+ klass_or_symbol.is_a?(Class) ? SetBuilder::Modifier.valid_modifier!(klass_or_symbol) : SetBuilder::Modifier.for(klass_or_symbol)
38
+ end
39
+
40
+
41
+
42
+ #
43
+ # Usage
44
+ # register(type, modifier)
45
+ # register([type, modifier], [type, modifier])
46
+ # register(type, modifier, type, modifier)
47
+ #
48
+ def self.register(*args)
49
+ args, i = args.flatten, 0
50
+ while args[i+1]
51
+ type, modifier_klass = get_type(args[i]), args[i+1]
52
+ valid_modifier!(modifier_klass) # || raise(ArgumentError, "#{modifier_klass} is not a valid modifier")
53
+ @registered_modifiers[type] = modifier_klass
54
+ i += 2
55
+ end
56
+ end
57
+
58
+
59
+
60
+ def self.valid_modifier!(klass)
61
+ raise(ArgumentError, "#{klass} must inherit from either `SetBuilder::Modifier::Verb` or `SetBuilder::Modifier::Adverb`") unless (is_subclass_of?(klass, SetBuilder::Modifier::Adverb) or is_subclass_of?(klass, SetBuilder::Modifier::Verb))
62
+ raise(ArgumentError, "#{klass} must respond to `operators`") unless klass.respond_to?(:operators)
63
+ raise(ArgumentError, "#{klass}.operators must not be empty") if klass.operators.empty?
64
+ klass
65
+ end
66
+
67
+
68
+
69
+ private
70
+
71
+
72
+
73
+ def self.get_type(type)
74
+ if type.is_a?(Symbol)
75
+ type
76
+ else
77
+ type.to_s.downcase.to_sym
78
+ end
79
+ end
80
+
81
+
82
+
83
+ def self.is_subclass_of?(klass, superklass)
84
+ sc = klass
85
+ while (sc = sc.superclass)
86
+ return true if (sc == superklass)
87
+ end
88
+ false
89
+ end
90
+
91
+
92
+
93
+ end
94
+
95
+
96
+
97
+ #
98
+ # Force predefined modifiers to pass `valid_modifier?`
99
+ #
100
+ Modifier.register(
101
+ [:date, Modifiers::DateModifier],
102
+ [:number, Modifiers::NumberModifier],
103
+ [:string, Modifiers::StringModifier]
104
+ )
105
+
106
+
107
+
108
+ end
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+ #
117
+ # Why is the below not working?
118
+ #
119
+
120
+ # class Class
121
+ #
122
+ #
123
+ #
124
+ # def is_subclass_of?(klass)
125
+ # sc = self
126
+ # while (sc = sc.superclass)
127
+ # return true if (sc == klass)
128
+ # end
129
+ # false
130
+ # end
131
+ #
132
+ #
133
+ #
134
+ # end
@@ -0,0 +1,11 @@
1
+ require 'set_builder/modifier/base'
2
+
3
+
4
+ module SetBuilder
5
+ module Modifier
6
+ class Adverb < Base
7
+
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,105 @@
1
+ module SetBuilder
2
+ module Modifier
3
+ class Base
4
+
5
+
6
+
7
+ def initialize(hash)
8
+ @operator, @values = (hash.is_a?(Hash) ? [hash.first[0].to_sym, hash.first[1]] : [nil, nil])
9
+ @values ||= []
10
+ @values = [@values] unless @values.is_a?(Array)
11
+ end
12
+
13
+
14
+
15
+ attr_reader :operator, :values
16
+
17
+
18
+
19
+ def valid?
20
+ valid_operator?(self.operator) && valid_arguments?(self.values)
21
+ end
22
+
23
+
24
+
25
+ def valid_operator?(operator)
26
+ !operator.nil? && self.class.operators.key?(operator)
27
+ end
28
+
29
+
30
+
31
+ def valid_arguments?(values)
32
+ argument_types = self.class.operators[operator] || []
33
+ return false unless (values.length == argument_types.length)
34
+ values.each_with_index do |value, i|
35
+ return false unless valid_argument_of_type?(value, argument_types[i])
36
+ end
37
+ true
38
+ end
39
+
40
+
41
+
42
+ def valid_argument_of_type?(argument, type)
43
+ validator = "valid_#{type}_argument?"
44
+ if respond_to?(validator)
45
+ send(validator, argument)
46
+ else
47
+ true
48
+ end
49
+ end
50
+
51
+
52
+
53
+ def valid_date_argument?(string)
54
+ begin
55
+ Date.parse(string)
56
+ true
57
+ rescue
58
+ false
59
+ end
60
+ end
61
+
62
+
63
+ def valid_number_argument?(number)
64
+ !(number.to_s =~ /\A\d+\Z/).nil?
65
+ end
66
+
67
+
68
+
69
+ def to_s(negative=false)
70
+ words = negative ? [self.class.negate(operator).to_s.gsub(/_/, " ")] : [operator.to_s.gsub(/_/, " ")]
71
+ arguments = self.class.operators[operator] || []
72
+ (0...arguments.length).each do |i|
73
+ # p "ValueMap.to_s(#{arguments[i]} (#{arguments[i].class}), #{values[i]} (#{values[i].class})): #{ValueMap.to_s(arguments[i], values[i])}"
74
+ words << ValueMap.to_s(arguments[i], values[i])
75
+ end
76
+ words.join(" ")
77
+ end
78
+
79
+
80
+
81
+ def self.negate(operator)
82
+ operator
83
+ end
84
+
85
+
86
+
87
+ def self.to_hash
88
+ hash = {}
89
+ operators.each do |operator, array|
90
+ hash[operator.to_s] = array.map {|type| type.to_s }
91
+ end
92
+ hash
93
+ end
94
+
95
+
96
+
97
+ def self.to_json
98
+ to_hash.to_json
99
+ end
100
+
101
+
102
+
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,24 @@
1
+ require 'set_builder/modifier/base'
2
+
3
+
4
+ module SetBuilder
5
+ module Modifier
6
+ class Verb < Base
7
+
8
+
9
+
10
+ protected
11
+
12
+
13
+
14
+ def negate(selector, operator)
15
+ conditions = build_conditions_for(selector, operator)
16
+ conditions[0] = "NOT(#{conditions[0]})"
17
+ conditions
18
+ end
19
+
20
+
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,41 @@
1
+ module SetBuilder
2
+ class ModifierCollection < Array
3
+
4
+
5
+
6
+ # def [](index)
7
+ # case index
8
+ # when Symbol, String
9
+ # index = index.to_s
10
+ # self.find {|trait| trait.name == index}
11
+ # else
12
+ # super
13
+ # end
14
+ # end
15
+
16
+
17
+
18
+ def to_hash
19
+ hash = {}
20
+ each do |modifier|
21
+ hash[Modifier.name(modifier).to_s] = modifier.to_hash
22
+ end
23
+ hash
24
+ end
25
+
26
+
27
+
28
+ def to_json
29
+ to_hash.to_json
30
+ end
31
+
32
+
33
+
34
+ # def modifiers
35
+ # inject([]) {|modifiers, trait| modifiers.concat(trait.modifiers)}.uniq
36
+ # end
37
+
38
+
39
+
40
+ end
41
+ end