set_builder 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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