brototype 0.9.3 → 0.9.4
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 +37 -1
- data/lib/brototype/bro.rb +35 -21
- data/lib/brototype/bromise.rb +16 -26
- data/lib/brototype/version.rb +1 -1
- data/spec/brototype_spec.rb +70 -59
- data/spec/spec_helper.rb +1 -22
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 561dc3fa18d9ea9deafa6c0705f9c98b3d1a2b19
|
4
|
+
data.tar.gz: 4493e85454485305e5ad7addcc3c051c07d4af5e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12e05b53f108807f5d61ad19af04e763df9f322a6a88a48053cad41b58b9a2d500657270445a9495f8019d7500bd7fec8b09dcf4b2a9cf7ec2b1a3e95fa99772
|
7
|
+
data.tar.gz: 3f9d6def8ebaf0c26754c2e20f98cb5d8f901bd233ef1292d3dda6136399fd727cb43a22da4bd063c7aa1bba6f68dfefe614c82ddf96b6f4066ff7be98045aaa
|
data/README.md
CHANGED
@@ -5,7 +5,43 @@ Bro, do you even Ruby?
|
|
5
5
|
This is a ruby port of the popular brototype.js library that can be found here:
|
6
6
|
https://github.com/letsgetrandy/brototype
|
7
7
|
|
8
|
+
## Features
|
8
9
|
|
10
|
+
You've got a deeply-nested set of objects that may or may not always be there.
|
11
|
+
We've all seen something like this:
|
12
|
+
|
13
|
+
```
|
14
|
+
if params && params[:model] && params[:model][:id]
|
15
|
+
# do something
|
16
|
+
end
|
17
|
+
```
|
18
|
+
|
19
|
+
We all hate that, don't we?
|
20
|
+
|
21
|
+
So what if you could just type:
|
22
|
+
```
|
23
|
+
Brototype::Bro.new(params).i_can_haz(:model,:id)
|
24
|
+
```
|
25
|
+
|
26
|
+
Or better yet, how about:
|
27
|
+
```
|
28
|
+
Brototype::Bro.new(params).i_dont_always(:model,:id).but_when_i do |id|
|
29
|
+
puts id
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
Fetch nested properties by string or key:
|
34
|
+
```
|
35
|
+
Brototype::Bro.new(:foo => {:bar => 1}).i_can_haz(:foo,:bar)
|
36
|
+
Brototype::Bro.new('foo' => {'bar' => 1}).i_can_haz('foo','bar')
|
37
|
+
```
|
38
|
+
|
39
|
+
### Handling exceptions
|
40
|
+
```
|
41
|
+
Brototype::Bro.new(@anon_class).brace_yourself('throws_error').here_come_the_errors do |e|
|
42
|
+
puts 'error ' + e + ' happened.'
|
43
|
+
end
|
44
|
+
```
|
9
45
|
|
10
46
|
## Installation
|
11
47
|
|
@@ -26,7 +62,7 @@ Or install it yourself as:
|
|
26
62
|
## Rspec is used to run the tests, just do:
|
27
63
|
|
28
64
|
```
|
29
|
-
|
65
|
+
rake spec
|
30
66
|
```
|
31
67
|
|
32
68
|
## Contributing
|
data/lib/brototype/bro.rb
CHANGED
@@ -3,40 +3,54 @@ module Brototype
|
|
3
3
|
|
4
4
|
TOTALLY = true
|
5
5
|
NOWAY = false
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def sup?(obj)
|
9
|
+
self.new(obj)
|
10
|
+
end
|
11
|
+
|
12
|
+
def is_that_even_a_thing?(obj)
|
13
|
+
!(obj.nil? || obj.empty?)
|
14
|
+
end
|
15
|
+
end
|
6
16
|
|
7
17
|
def initialize(obj)
|
8
18
|
@obj = obj;
|
9
19
|
end
|
10
20
|
|
11
|
-
def is_that_even_a_thing
|
12
|
-
|
21
|
+
def is_that_even_a_thing?
|
22
|
+
self.class.is_that_even_a_thing?(@obj)
|
13
23
|
end
|
14
24
|
|
15
|
-
def do_you_even(
|
16
|
-
|
17
|
-
bro = self.i_can_haz(key)
|
18
|
-
if Bro.new(bro).is_that_even_a_thing == TOTALLY
|
19
|
-
TOTALLY;
|
20
|
-
else
|
21
|
-
NOWAY
|
22
|
-
end
|
23
|
-
|
25
|
+
def do_you_even?(*args)
|
26
|
+
self.class.is_that_even_a_thing? self.i_can_haz(*args)
|
24
27
|
end
|
25
28
|
|
26
|
-
def i_can_haz(
|
29
|
+
def i_can_haz(*args)
|
27
30
|
# TODO if key is an array, return all
|
28
31
|
if @obj.is_a?(Hash)
|
29
|
-
|
30
|
-
|
32
|
+
# split up the incoming keys and dig into the hash to find the last value
|
33
|
+
args.inject(@obj) do |memo, k|
|
34
|
+
# make sure it's a hash (could be nil from the last iteration) and that is the key in either format
|
35
|
+
if memo.is_a? Hash and (memo.has_key?(k) or memo.has_key?(k.to_sym))
|
36
|
+
# use ternary operator instead of straight "this || that" so that if the key's value is nil or false it'll still return
|
37
|
+
memo.has_key?(k) ? memo[k] : memo[k.to_sym]
|
38
|
+
else
|
39
|
+
# nothing found, get out of here
|
40
|
+
nil
|
41
|
+
end
|
31
42
|
end
|
32
|
-
|
33
|
-
|
43
|
+
elsif args.count > 0
|
44
|
+
key = args.first
|
45
|
+
if @obj.respond_to? key
|
34
46
|
@obj.send(key)
|
35
47
|
elsif key.start_with?("@")
|
36
|
-
@obj.instance_variable_get
|
48
|
+
@obj.instance_variable_get key
|
37
49
|
else
|
38
50
|
nil
|
39
51
|
end
|
52
|
+
else
|
53
|
+
nil
|
40
54
|
end
|
41
55
|
end
|
42
56
|
|
@@ -44,12 +58,12 @@ module Brototype
|
|
44
58
|
# TODO
|
45
59
|
end
|
46
60
|
|
47
|
-
def i_dont_always(methodString)
|
48
|
-
Bromise.new(@obj, methodString)
|
61
|
+
def i_dont_always(*methodString)
|
62
|
+
Bromise.new(@obj, *methodString)
|
49
63
|
end
|
50
64
|
|
51
|
-
def brace_yourself(methodString)
|
52
|
-
Bromise.new(@obj, methodString)
|
65
|
+
def brace_yourself(*methodString)
|
66
|
+
Bromise.new(@obj, *methodString)
|
53
67
|
end
|
54
68
|
|
55
69
|
end
|
data/lib/brototype/bromise.rb
CHANGED
@@ -2,42 +2,32 @@ module Brototype
|
|
2
2
|
|
3
3
|
# Bromise... it's stronger than a Promise
|
4
4
|
class Bromise
|
5
|
-
|
6
|
-
def initialize(object,
|
5
|
+
|
6
|
+
def initialize(object, *args)
|
7
7
|
@object = object
|
8
|
-
|
9
|
-
@args = args
|
8
|
+
#@method = method
|
9
|
+
@args = args
|
10
10
|
end
|
11
|
-
|
12
|
-
def
|
13
|
-
return_value =
|
14
|
-
if @object.respond_to? @method
|
15
|
-
return_value = @object.send(@method)
|
16
|
-
else
|
17
|
-
return_value = Bro.new(@object).i_can_haz @method
|
18
|
-
end
|
11
|
+
|
12
|
+
def but_when_i(&block)
|
13
|
+
return_value = Bro.new(@object).i_can_haz(*@args)
|
19
14
|
if return_value
|
20
|
-
(
|
15
|
+
(block || {}).call return_value
|
21
16
|
end
|
22
17
|
end
|
23
|
-
|
24
|
-
def here_come_the_errors(
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
callback.call e
|
30
|
-
end
|
31
|
-
else
|
32
|
-
callback(@method + ' is not a proc');
|
18
|
+
|
19
|
+
def here_come_the_errors(&block)
|
20
|
+
begin
|
21
|
+
Bro.new(@object).i_can_haz(*@args)
|
22
|
+
rescue Exception => e
|
23
|
+
block.call e
|
33
24
|
end
|
34
25
|
end
|
35
|
-
|
26
|
+
|
36
27
|
def errors_are_coming
|
37
28
|
self.here_come_the_errors.call
|
38
29
|
end
|
39
|
-
|
30
|
+
|
40
31
|
end
|
41
|
-
|
42
32
|
end
|
43
33
|
|
data/lib/brototype/version.rb
CHANGED
data/spec/brototype_spec.rb
CHANGED
@@ -10,15 +10,15 @@ describe Brototype do
|
|
10
10
|
describe '#do_you_even' do
|
11
11
|
|
12
12
|
it 'should return true for defined properties' do
|
13
|
-
expect(@bro.do_you_even
|
13
|
+
expect(@bro.do_you_even? 'foo' ).to be true
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should return true for nested properties' do
|
17
|
-
expect(@bro.do_you_even
|
17
|
+
expect(@bro.do_you_even? 'foo','bar').to be true
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'should return false for undefined properties' do
|
21
|
-
expect(@bro.do_you_even
|
21
|
+
expect(@bro.do_you_even? 'foo','nada').to be false
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
@@ -26,11 +26,11 @@ describe Brototype do
|
|
26
26
|
describe '#i_can_haz' do
|
27
27
|
|
28
28
|
it 'should return the value of the deep property' do
|
29
|
-
expect(@bro.i_can_haz
|
29
|
+
expect(@bro.i_can_haz 'foo','bar').to eq('baz')
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'should return nil for missing property' do
|
33
|
-
expect(@bro.i_can_haz
|
33
|
+
expect(@bro.i_can_haz 'foo','nada').to be_nil
|
34
34
|
end
|
35
35
|
|
36
36
|
end
|
@@ -51,56 +51,46 @@ describe Brototype do
|
|
51
51
|
|
52
52
|
describe '#i_dont_always' do
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
success = true
|
95
|
-
})
|
96
|
-
expect(success).to be false
|
97
|
-
|
98
|
-
@bro.i_dont_always('foo.bar').but_when_i_do(lambda { |x|
|
99
|
-
success = true
|
100
|
-
result = x
|
101
|
-
})
|
102
|
-
expect(result).to eq("baz")
|
103
|
-
|
54
|
+
context '#but_when_i do' do
|
55
|
+
it 'should check that the requested method is a function' do
|
56
|
+
success = false
|
57
|
+
@anon_bro = Brototype::Bro.new(@anon_class)
|
58
|
+
|
59
|
+
@anon_bro.i_dont_always('foo.bar').but_when_i do |x|
|
60
|
+
success = true
|
61
|
+
end
|
62
|
+
expect(success).to be false
|
63
|
+
|
64
|
+
@anon_bro.i_dont_always('foo').but_when_i do |x|
|
65
|
+
success = true
|
66
|
+
end
|
67
|
+
expect(success).to be true
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should pass the method\'s return value as param to callback' do
|
71
|
+
param = nil
|
72
|
+
Brototype::Bro.new(@anon_class).i_dont_always('foo').but_when_i do |x|
|
73
|
+
param = x
|
74
|
+
end
|
75
|
+
expect(param).to be 91
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should work with hash keys too' do
|
79
|
+
success = false
|
80
|
+
result = nil
|
81
|
+
|
82
|
+
@bro.i_dont_always('foo','baz').but_when_i do |x|
|
83
|
+
puts "OH HAI!"
|
84
|
+
success = true
|
85
|
+
end
|
86
|
+
expect(success).to be false
|
87
|
+
|
88
|
+
@bro.i_dont_always('foo','bar').but_when_i do |x|
|
89
|
+
success = true
|
90
|
+
result = x
|
91
|
+
end
|
92
|
+
expect(result).to eq("baz")
|
93
|
+
end
|
104
94
|
end
|
105
95
|
|
106
96
|
end
|
@@ -109,20 +99,41 @@ describe Brototype do
|
|
109
99
|
|
110
100
|
it 'should fire the callback when an exception is thrown' do
|
111
101
|
success = false
|
112
|
-
Brototype::Bro.new(@anon_class).brace_yourself('throws_error').here_come_the_errors
|
102
|
+
Brototype::Bro.new(@anon_class).brace_yourself('throws_error').here_come_the_errors do |x|
|
113
103
|
success = true
|
114
|
-
|
104
|
+
end
|
115
105
|
expect(success).to be true
|
116
106
|
end
|
117
107
|
|
118
108
|
it 'should pass the error to the callback' do
|
119
109
|
error = nil
|
120
|
-
Brototype::Bro.new(@anon_class).brace_yourself('throws_error').here_come_the_errors
|
110
|
+
Brototype::Bro.new(@anon_class).brace_yourself('throws_error').here_come_the_errors do |x|
|
121
111
|
error = x
|
122
|
-
|
112
|
+
end
|
123
113
|
expect(error.class).to eq(ArgumentError)
|
124
114
|
end
|
125
115
|
|
126
116
|
end
|
127
117
|
|
118
|
+
end
|
119
|
+
|
120
|
+
class Foo
|
121
|
+
attr_accessor :fired
|
122
|
+
|
123
|
+
def initialize
|
124
|
+
@fired = false
|
125
|
+
@success = false
|
126
|
+
@param = nil
|
127
|
+
@bar = 3
|
128
|
+
end
|
129
|
+
|
130
|
+
def foo
|
131
|
+
@fired = true
|
132
|
+
91
|
133
|
+
end
|
134
|
+
|
135
|
+
def throws_error
|
136
|
+
throw :an_error
|
137
|
+
end
|
138
|
+
|
128
139
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,22 +1 @@
|
|
1
|
-
require 'brototype'
|
2
|
-
|
3
|
-
class Foo
|
4
|
-
attr_accessor :fired
|
5
|
-
|
6
|
-
def initialize
|
7
|
-
@fired = false
|
8
|
-
@success = false
|
9
|
-
@param = nil
|
10
|
-
@bar = 3
|
11
|
-
end
|
12
|
-
|
13
|
-
def foo
|
14
|
-
@fired = true
|
15
|
-
91
|
16
|
-
end
|
17
|
-
|
18
|
-
def throws_error
|
19
|
-
throw :an_error
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
1
|
+
require 'brototype'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brototype
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -92,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
92
|
version: '0'
|
93
93
|
requirements: []
|
94
94
|
rubyforge_project:
|
95
|
-
rubygems_version: 2.
|
95
|
+
rubygems_version: 2.2.2
|
96
96
|
signing_key:
|
97
97
|
specification_version: 4
|
98
98
|
summary: Bro, do you even Ruby?
|