set_builder 2.0.0.beta2 → 2.0.0.beta3
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 +4 -4
- data/README.md +6 -6
- data/Rakefile +2 -2
- data/init.rb +1 -1
- data/lib/assets/javascripts/set_builder.js +122 -125
- data/lib/set_builder/constraint.rb +66 -50
- data/lib/set_builder/errors/trait_not_found.rb +3 -0
- data/lib/set_builder/modifier/adverb.rb +4 -4
- data/lib/set_builder/modifier/base.rb +74 -67
- data/lib/set_builder/modifier/verb.rb +1 -16
- data/lib/set_builder/modifier.rb +49 -49
- data/lib/set_builder/modifier_collection.rb +16 -16
- data/lib/set_builder/modifiers/date_preposition.rb +6 -48
- data/lib/set_builder/modifiers/number_preposition.rb +4 -25
- data/lib/set_builder/modifiers/string_preposition.rb +9 -43
- data/lib/set_builder/modifiers.rb +3 -3
- data/lib/set_builder/set.rb +48 -8
- data/lib/set_builder/trait.rb +75 -49
- data/lib/set_builder/traits.rb +13 -4
- data/lib/set_builder/value_map.rb +30 -30
- data/lib/set_builder/version.rb +1 -1
- data/lib/set_builder.rb +8 -7
- data/set_builder.gemspec +4 -2
- data/spec/commands/example_command.rb +2 -2
- data/spec/lib/jspec.css +4 -4
- data/spec/lib/jspec.growl.js +11 -11
- data/spec/lib/jspec.jquery.js +14 -14
- data/spec/lib/jspec.js +210 -210
- data/spec/lib/jspec.nodejs.js +2 -2
- data/spec/lib/jspec.shell.js +11 -11
- data/spec/lib/jspec.timers.js +23 -23
- data/spec/rhino.js +1 -1
- data/spec/server.rb +1 -1
- data/spec/unit/array.spec.js +9 -9
- data/spec/unit/set_builder.spec.js +71 -82
- data/spec/unit/spec.helper.js +1 -0
- data/test/constraint_test.rb +84 -0
- data/test/date_preposition_test.rb +17 -7
- data/test/modifier_test.rb +26 -1
- data/test/set_test.rb +51 -28
- data/test/string_preposition_test.rb +10 -9
- data/test/test_helper.rb +17 -15
- data/test/trait_test.rb +49 -30
- data/test/traits_test.rb +35 -30
- data/test/value_map_test.rb +1 -1
- metadata +37 -15
- data/lib/set_builder/query_builders/string.rb +0 -0
- data/test/inflector_test.rb +0 -27
data/lib/set_builder/set.rb
CHANGED
@@ -4,9 +4,11 @@ module SetBuilder
|
|
4
4
|
|
5
5
|
|
6
6
|
def initialize(traits, scope, raw_data)
|
7
|
+
traits = Traits.new(traits) if traits.is_a?(Array)
|
8
|
+
raise ArgumentError, "Expected traits to be an instance of SetBuilder::Traits" unless traits.is_a?(Traits)
|
7
9
|
@traits = traits
|
8
10
|
@scope = scope
|
9
|
-
@set = raw_data
|
11
|
+
@set = self.class.normalize(raw_data)
|
10
12
|
end
|
11
13
|
|
12
14
|
|
@@ -25,7 +27,14 @@ module SetBuilder
|
|
25
27
|
# Returns true if all of the constraints in this set are valid
|
26
28
|
#
|
27
29
|
def valid?
|
28
|
-
|
30
|
+
errors.none?
|
31
|
+
end
|
32
|
+
|
33
|
+
def errors
|
34
|
+
@errors ||= constraints.each_with_object({}) do |constraint, hash|
|
35
|
+
errors = constraint.errors
|
36
|
+
hash[constraint.trait.name] = errors if errors.any?
|
37
|
+
end
|
29
38
|
end
|
30
39
|
|
31
40
|
|
@@ -37,6 +46,13 @@ module SetBuilder
|
|
37
46
|
constraints.to_sentence
|
38
47
|
end
|
39
48
|
|
49
|
+
#
|
50
|
+
# Exports this set in raw data
|
51
|
+
#
|
52
|
+
def to_a
|
53
|
+
set
|
54
|
+
end
|
55
|
+
|
40
56
|
|
41
57
|
|
42
58
|
#
|
@@ -49,19 +65,43 @@ module SetBuilder
|
|
49
65
|
|
50
66
|
|
51
67
|
|
52
|
-
|
68
|
+
def self.normalize(constraints)
|
69
|
+
hash_to_array(constraints).map do |constraint|
|
70
|
+
constraint = constraint.symbolize_keys
|
71
|
+
if constraint[:modifiers]
|
72
|
+
constraint[:modifiers] = hash_to_array(constraint[:modifiers]).map do |modifier|
|
73
|
+
modifier = modifier.symbolize_keys
|
74
|
+
modifier[:values] = hash_to_array(modifier[:values]) if modifier[:values]
|
75
|
+
modifier
|
76
|
+
end
|
77
|
+
end
|
78
|
+
constraint[:enums] = hash_to_array(constraint[:enums]) if constraint[:enums]
|
79
|
+
constraint
|
80
|
+
end
|
81
|
+
end
|
53
82
|
|
54
83
|
|
55
84
|
|
85
|
+
private
|
56
86
|
attr_reader :set
|
57
87
|
|
88
|
+
|
89
|
+
|
90
|
+
def self.hash_to_array(hash)
|
91
|
+
return hash.values if hash.is_a?(Hash)
|
92
|
+
Array(hash)
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
|
58
97
|
def get_constraints
|
59
|
-
set.
|
60
|
-
|
61
|
-
|
98
|
+
set.map do |constraint|
|
99
|
+
trait_name = constraint.fetch(:trait) do
|
100
|
+
raise ArgumentError, ":trait is missing from the given constraint`"
|
101
|
+
end
|
62
102
|
trait = traits[trait_name]
|
63
|
-
raise
|
64
|
-
|
103
|
+
raise SetBuilder::TraitNotFound, "\"#{trait_name}\" is not a trait in `traits`" unless trait
|
104
|
+
trait.apply(constraint)
|
65
105
|
end
|
66
106
|
end
|
67
107
|
|
data/lib/set_builder/trait.rb
CHANGED
@@ -1,76 +1,102 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "set_builder/constraint"
|
2
|
+
require "set_builder/modifier"
|
3
3
|
|
4
4
|
|
5
5
|
module SetBuilder
|
6
6
|
class Trait
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
modifier: /(<\w+>)/
|
15
|
-
}.freeze
|
16
|
-
|
17
|
-
def initialize(trait_expression, &block)
|
18
|
-
@parsed_expression = parse(trait_expression)
|
19
|
-
@name, @direct_object_type = find(:name), find(:direct_object_type)
|
7
|
+
attr_reader :expression, :tokens, :name, :modifiers, :direct_object_type, :enums
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
def initialize(expression, &block)
|
12
|
+
@expression = expression.to_s.strip
|
13
|
+
@tokens = parse(expression)
|
20
14
|
@block = block
|
21
|
-
|
15
|
+
|
16
|
+
names = find_all(:name)
|
17
|
+
raise ArgumentError, "A trait must be defined with a name" if names.none?
|
18
|
+
raise ArgumentError, "A trait must be defined with only one name" if names.length > 1
|
19
|
+
@name = names[0]
|
20
|
+
|
21
|
+
direct_object_types = find_all(:direct_object_type)
|
22
|
+
raise ArgumentError, "A trait may define only one direct object" if direct_object_types.length > 1
|
23
|
+
@direct_object_type = direct_object_types[0].to_sym if direct_object_types[0]
|
24
|
+
|
25
|
+
@enums = find_all(:enum)
|
26
|
+
raise ArgumentError, "An enum must define more than one option" if enums.any? { |options| options.length < 2 }
|
27
|
+
|
28
|
+
@modifiers = find_all(:modifier).map { |modifier_type| Modifier[modifier_type] }
|
22
29
|
end
|
23
|
-
|
30
|
+
|
31
|
+
|
32
|
+
|
24
33
|
def requires_direct_object?
|
25
34
|
!@direct_object_type.nil?
|
26
35
|
end
|
27
36
|
alias :direct_object_required? :requires_direct_object?
|
28
|
-
|
29
|
-
|
30
|
-
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
expression
|
31
42
|
end
|
32
43
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
44
|
+
def as_json(*)
|
45
|
+
tokens.map { |(token, value)| [token.to_s, value] }
|
46
|
+
end
|
47
|
+
|
48
|
+
def apply(constraint)
|
49
|
+
SetBuilder::Constraint.new(self, constraint, &@block)
|
39
50
|
end
|
40
|
-
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
|
57
|
+
|
41
58
|
def find_all(token)
|
42
|
-
|
59
|
+
tokens.select { |(_token, _)| _token == token }.map { |(_, value)| value }
|
43
60
|
end
|
44
|
-
|
61
|
+
|
45
62
|
def find(token)
|
46
63
|
find_all(token).first
|
47
64
|
end
|
48
|
-
|
49
|
-
def as_json(*)
|
50
|
-
parsed_expression.map { |(token, value)| [token.to_s, value] }
|
51
|
-
end
|
52
65
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
[token_for(lexeme), value_for(lexeme)] unless lexeme.strip.empty?
|
63
|
-
end.compact
|
66
|
+
|
67
|
+
|
68
|
+
def parse(expression)
|
69
|
+
tokenizer = Regexp.union(LEXER.values)
|
70
|
+
expression.split(tokenizer).each_with_object([]) do |lexeme, output|
|
71
|
+
next if lexeme.empty?
|
72
|
+
token = token_for(lexeme)
|
73
|
+
output.push [token, value_for(token, lexeme)]
|
74
|
+
end
|
64
75
|
end
|
65
|
-
|
76
|
+
|
66
77
|
def token_for(lexeme)
|
67
78
|
LEXER.each { |token, pattern| return token if pattern.match(lexeme) }
|
68
|
-
|
79
|
+
:string
|
69
80
|
end
|
70
|
-
|
71
|
-
def value_for(lexeme)
|
72
|
-
|
81
|
+
|
82
|
+
def value_for(token, lexeme)
|
83
|
+
case token
|
84
|
+
when :name then lexeme[1...-1]
|
85
|
+
when :enum then lexeme[1...-1].split("|")
|
86
|
+
when :modifier then lexeme[1...-1]
|
87
|
+
when :direct_object_type then lexeme[1..-1]
|
88
|
+
else lexeme
|
89
|
+
end
|
73
90
|
end
|
74
91
|
|
92
|
+
LEXER = {
|
93
|
+
name: /("[^"]+")/,
|
94
|
+
direct_object_type: /(:[\w\-\.]+)/,
|
95
|
+
enum: /(\[[^\]]+\])/,
|
96
|
+
modifier: /(<\w+>)/
|
97
|
+
}.freeze
|
98
|
+
|
99
|
+
|
100
|
+
|
75
101
|
end
|
76
102
|
end
|
data/lib/set_builder/traits.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "set_builder/trait"
|
2
|
+
require "set_builder/trait_builder"
|
3
|
+
require "set_builder/modifier_collection"
|
4
|
+
require "delegate"
|
5
5
|
|
6
6
|
|
7
7
|
module SetBuilder
|
@@ -51,6 +51,15 @@ module SetBuilder
|
|
51
51
|
self.class.new(self.__getobj__.concat other_traits.__getobj__)
|
52
52
|
end
|
53
53
|
|
54
|
+
def sort_by(&block)
|
55
|
+
self.class.new(self.__getobj__.sort_by(&block))
|
56
|
+
end
|
57
|
+
|
58
|
+
def <<(trait)
|
59
|
+
super
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
54
63
|
|
55
64
|
|
56
65
|
def modifiers
|
@@ -1,19 +1,19 @@
|
|
1
1
|
module SetBuilder
|
2
2
|
module ValueMap
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
|
4
|
+
|
5
|
+
|
6
6
|
@registered_value_maps = {}
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
|
8
|
+
|
9
|
+
|
10
10
|
def self.registered?(name)
|
11
11
|
name = name.to_sym
|
12
12
|
@registered_value_maps.key?(name)
|
13
13
|
end
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
|
15
|
+
|
16
|
+
|
17
17
|
def self.to_s(name, value)
|
18
18
|
if value.is_a?(Array)
|
19
19
|
values = value.map { |value| to_s(name, value) }
|
@@ -23,8 +23,8 @@ module SetBuilder
|
|
23
23
|
when 2 then return "#{values.first} or #{values.last}"
|
24
24
|
else return "#{values[0..-2].join(', ')}, or #{values.last}"
|
25
25
|
end
|
26
|
-
end
|
27
|
-
|
26
|
+
end
|
27
|
+
|
28
28
|
name = name.to_sym
|
29
29
|
map = @registered_value_maps[name]
|
30
30
|
if map
|
@@ -34,43 +34,43 @@ module SetBuilder
|
|
34
34
|
value.to_s
|
35
35
|
end
|
36
36
|
end
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
|
38
|
+
|
39
|
+
|
40
40
|
def self.for(name)
|
41
41
|
name = name.to_sym
|
42
42
|
@registered_value_maps[name] || raise(ArgumentError, "A value map has not been registered for #{value}")
|
43
43
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
|
45
|
+
|
46
|
+
|
47
47
|
def self.register_collection(name, collection, name_method = :name, id_method = :id)
|
48
48
|
map = collection.map { |i| [i.send(id_method).to_s, i.send(name_method)] }
|
49
49
|
register(name, map)
|
50
50
|
end
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
|
52
|
+
|
53
|
+
|
54
54
|
def self.register(name, map)
|
55
55
|
raise "map is expected to be an array of pairs" unless map.is_a?(Array)
|
56
56
|
name = name.to_sym
|
57
57
|
@registered_value_maps[name] = map
|
58
58
|
end
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
|
60
|
+
|
61
|
+
|
62
62
|
def self.as_json(options={})
|
63
63
|
@registered_value_maps.dup
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
def self.to_json
|
67
67
|
@registered_value_maps.to_json
|
68
68
|
end
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
|
70
|
+
|
71
|
+
|
72
72
|
end
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
|
74
|
+
|
75
|
+
|
76
76
|
end
|
data/lib/set_builder/version.rb
CHANGED
data/lib/set_builder.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
1
|
+
require "active_record"
|
2
|
+
require "active_support/core_ext"
|
3
|
+
require "set_builder/traits"
|
4
|
+
require "set_builder/errors/trait_not_found"
|
5
|
+
require "set_builder/modifiers"
|
6
|
+
require "set_builder/value_map"
|
7
|
+
require "set_builder/set"
|
8
|
+
require "set_builder/engine"
|
8
9
|
|
9
10
|
|
10
11
|
module SetBuilder
|
data/set_builder.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require "set_builder/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "set_builder"
|
@@ -18,11 +18,13 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "rails", "
|
21
|
+
spec.add_dependency "rails", "~> 4.2.0"
|
22
22
|
spec.add_dependency "arel"
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.3"
|
24
24
|
spec.add_development_dependency "rake"
|
25
25
|
spec.add_development_dependency "jspec"
|
26
26
|
spec.add_development_dependency "pry"
|
27
|
+
spec.add_development_dependency "shoulda-context"
|
27
28
|
spec.add_development_dependency "minitest-reporters"
|
29
|
+
spec.add_development_dependency "timecop"
|
28
30
|
end
|
data/spec/lib/jspec.css
CHANGED
@@ -90,7 +90,7 @@ body.jspec {
|
|
90
90
|
margin: 0;
|
91
91
|
padding: 0 0 5px 25px;
|
92
92
|
}
|
93
|
-
#jspec-report tr.even:hover + tr.body,
|
93
|
+
#jspec-report tr.even:hover + tr.body,
|
94
94
|
#jspec-report tr.odd:hover + tr.body {
|
95
95
|
display: block;
|
96
96
|
}
|
@@ -101,7 +101,7 @@ body.jspec {
|
|
101
101
|
font-weight: normal;
|
102
102
|
color: #7B8D9B;
|
103
103
|
}
|
104
|
-
#jspec-report tr.even:hover,
|
104
|
+
#jspec-report tr.even:hover,
|
105
105
|
#jspec-report tr.odd:hover {
|
106
106
|
text-shadow: 1px 1px 1px #fff;
|
107
107
|
background: #F2F5F7;
|
@@ -130,7 +130,7 @@ body.jspec {
|
|
130
130
|
color: #1a1a1a;
|
131
131
|
}
|
132
132
|
#jspec-report tr.description:first-child td {
|
133
|
-
border-top: none;
|
133
|
+
border-top: none;
|
134
134
|
}
|
135
135
|
#jspec-report .assertion {
|
136
136
|
display: block;
|
@@ -146,4 +146,4 @@ body.jspec {
|
|
146
146
|
}
|
147
147
|
.jspec-sandbox {
|
148
148
|
display: none;
|
149
|
-
}
|
149
|
+
}
|
data/spec/lib/jspec.growl.js
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
// JSpec - Growl - Copyright TJ Holowaychuk <tj@vision-media.ca> (MIT Licensed)
|
3
3
|
|
4
4
|
;(function(){
|
5
|
-
|
5
|
+
|
6
6
|
Growl = {
|
7
|
-
|
7
|
+
|
8
8
|
// --- Version
|
9
|
-
|
9
|
+
|
10
10
|
version: '1.0.0',
|
11
|
-
|
11
|
+
|
12
12
|
/**
|
13
13
|
* Execute the given _cmd_, returning an array of lines from stdout.
|
14
14
|
*
|
@@ -28,11 +28,11 @@
|
|
28
28
|
var stream = new DataInputStream(proccess.getInputStream())
|
29
29
|
while (line = stream.readLine())
|
30
30
|
lines.push(line + '')
|
31
|
-
stream.close()
|
31
|
+
stream.close()
|
32
32
|
}
|
33
33
|
return lines
|
34
34
|
},
|
35
|
-
|
35
|
+
|
36
36
|
/**
|
37
37
|
* Return the extension of the given _path_ or null.
|
38
38
|
*
|
@@ -40,9 +40,9 @@
|
|
40
40
|
* @return {string}
|
41
41
|
* @api private
|
42
42
|
*/
|
43
|
-
|
43
|
+
|
44
44
|
extname: function(path) {
|
45
|
-
return path.lastIndexOf('.') != -1 ?
|
45
|
+
return path.lastIndexOf('.') != -1 ?
|
46
46
|
path.slice(path.lastIndexOf('.') + 1, path.length) :
|
47
47
|
null
|
48
48
|
},
|
@@ -102,7 +102,7 @@
|
|
102
102
|
this.exec.apply(this, args)
|
103
103
|
}
|
104
104
|
}
|
105
|
-
|
105
|
+
|
106
106
|
JSpec.include({
|
107
107
|
name: 'Growl',
|
108
108
|
reporting: function(options){
|
@@ -111,5 +111,5 @@
|
|
111
111
|
else Growl.notify('passed ' + stats.passes + ' assertions', { title: 'JSpec' })
|
112
112
|
}
|
113
113
|
})
|
114
|
-
|
115
|
-
})()
|
114
|
+
|
115
|
+
})()
|
data/spec/lib/jspec.jquery.js
CHANGED
@@ -5,15 +5,15 @@ JSpec
|
|
5
5
|
.requires('jQuery', 'when using jspec.jquery.js')
|
6
6
|
.include({
|
7
7
|
name: 'jQuery',
|
8
|
-
|
8
|
+
|
9
9
|
// --- Initialize
|
10
|
-
|
10
|
+
|
11
11
|
init : function() {
|
12
12
|
jQuery.ajaxSetup({ async: false })
|
13
13
|
},
|
14
|
-
|
14
|
+
|
15
15
|
// --- Utilities
|
16
|
-
|
16
|
+
|
17
17
|
utilities : {
|
18
18
|
element: jQuery,
|
19
19
|
elements: jQuery,
|
@@ -21,10 +21,10 @@ JSpec
|
|
21
21
|
return jQuery('<div class="sandbox"></div>')
|
22
22
|
}
|
23
23
|
},
|
24
|
-
|
24
|
+
|
25
25
|
// --- Matchers
|
26
|
-
|
27
|
-
matchers : {
|
26
|
+
|
27
|
+
matchers : {
|
28
28
|
have_tag : "jQuery(expected, actual).length === 1",
|
29
29
|
have_one : "alias have_tag",
|
30
30
|
have_tags : "jQuery(expected, actual).length > 1",
|
@@ -36,18 +36,18 @@ JSpec
|
|
36
36
|
have_value : "jQuery(actual).val() === expected",
|
37
37
|
be_enabled : "!jQuery(actual).attr('disabled')",
|
38
38
|
have_class : "jQuery(actual).hasClass(expected)",
|
39
|
-
be_animated : "jQuery(actual).queue().length > 0",
|
40
|
-
|
39
|
+
be_animated : "jQuery(actual).queue().length > 0",
|
40
|
+
|
41
41
|
be_visible : function(actual) {
|
42
42
|
return jQuery(actual).css('display') != 'none' &&
|
43
43
|
jQuery(actual).css('visibility') != 'hidden' &&
|
44
44
|
jQuery(actual).attr('type') != 'hidden'
|
45
45
|
},
|
46
|
-
|
46
|
+
|
47
47
|
be_hidden : function(actual) {
|
48
48
|
return !JSpec.does(actual, 'be_visible')
|
49
49
|
},
|
50
|
-
|
50
|
+
|
51
51
|
have_classes : function(actual) {
|
52
52
|
return !JSpec.any(JSpec.toArray(arguments, 1), function(arg){
|
53
53
|
return !JSpec.does(actual, 'have_class', arg)
|
@@ -58,7 +58,7 @@ JSpec
|
|
58
58
|
return value ? jQuery(actual).attr(attr) == value:
|
59
59
|
jQuery(actual).attr(attr)
|
60
60
|
},
|
61
|
-
|
61
|
+
|
62
62
|
have_event_handlers : function(actual, expected) {
|
63
63
|
if (jQuery(actual).data('events') && jQuery(actual).data('events').hasOwnProperty(expected)) {
|
64
64
|
return true;
|
@@ -73,11 +73,11 @@ JSpec
|
|
73
73
|
}
|
74
74
|
return false;
|
75
75
|
},
|
76
|
-
|
76
|
+
|
77
77
|
'be disabled selected checked' : function(attr) {
|
78
78
|
return 'jQuery(actual).attr("' + attr + '")'
|
79
79
|
},
|
80
|
-
|
80
|
+
|
81
81
|
'have type id title alt href src sel rev name target' : function(attr) {
|
82
82
|
return function(actual, value) {
|
83
83
|
return JSpec.does(actual, 'have_attr', attr, value)
|