drain 0.3.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +25 -0
- data/.travis.yml +7 -3
- data/ChangeLog.md +159 -2
- data/Gemfile +4 -1
- data/LICENSE.txt +1 -1
- data/README.md +14 -3
- data/Rakefile +15 -10
- data/drain.gemspec +1 -0
- data/gemspec.yml +3 -3
- data/lib/dr/base/delegate.rb +28 -0
- data/lib/dr/base/graph.rb +26 -9
- data/lib/dr/base/uri.rb +224 -192
- data/lib/dr/base/utils.rb +39 -8
- data/lib/dr/parse/simple_keywords.rb +1 -1
- data/lib/dr/parse/time_parse.rb +29 -23
- data/lib/dr/ruby_ext/core_modules.rb +5 -3
- data/lib/dr/version.rb +1 -1
- data/test/helper.rb +12 -2
- data/test/test_converter.rb +7 -7
- data/test/test_core_ext.rb +24 -24
- data/test/test_date_parse.rb +8 -4
- data/test/test_graph.rb +26 -26
- data/test/test_meta.rb +3 -3
- data/test/test_simple_keywords.rb +6 -6
- data/test/test_simple_parser.rb +9 -9
- data/test/test_time_parse.rb +43 -0
- data/test/test_uri.rb +35 -0
- metadata +20 -16
@@ -20,7 +20,7 @@ module DR
|
|
20
20
|
edelim= delims[1] || bdelim
|
21
21
|
keywords=@keywords.keys
|
22
22
|
keywords_r="(?:"+keywords.map {|k| "(?:"+k+")"}.join("|")+")"
|
23
|
-
reg = %r{(?<kw>#{keywords_r})(?<re>#{'\\'+bdelim}(?:(?>[^#{'\\'+bdelim}#{'\\'+edelim}]+)|\g<re>)*#{'\\'+edelim})}
|
23
|
+
reg = %r{(?<kw>#{keywords_r})(?<re>#{'\\'+bdelim}(?:(?>[^#{'\\'+bdelim}#{edelim == bdelim ? '' : '\\'+edelim}]+)|\g<re>)*#{'\\'+edelim})}
|
24
24
|
if (m=reg.match(msg))
|
25
25
|
arg=m[:re][1...m[:re].length-1]
|
26
26
|
arg=parse(arg, **opts)
|
data/lib/dr/parse/time_parse.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'chronic'
|
2
2
|
require 'chronic_duration'
|
3
|
-
require 'active_support/time'
|
3
|
+
# require 'active_support/time'
|
4
4
|
|
5
5
|
module DR
|
6
6
|
module TimeParse
|
@@ -8,17 +8,17 @@ module DR
|
|
8
8
|
def time_to_day_range(t)
|
9
9
|
return Chronic.parse(t.to_date, guess:false)
|
10
10
|
end
|
11
|
-
def parse(s, opt
|
11
|
+
def parse(s, **opt)
|
12
12
|
return s if Date===s or Time===s
|
13
13
|
|
14
|
-
|
15
|
-
first
|
16
|
-
second
|
14
|
+
!opt[:norange] and s.match(/(.*)\.\.(.*)/) do |m|
|
15
|
+
first=m[1]
|
16
|
+
second=m[2]
|
17
17
|
opt[:norange]=true
|
18
|
-
return Chronic::Span.new(self.parse(first, opt),self.parse(second,opt))
|
18
|
+
return Chronic::Span.new(self.parse(first, **opt),self.parse(second, **opt))
|
19
19
|
end
|
20
20
|
|
21
|
-
if
|
21
|
+
if s.match(/\A[[:space:]]*\z/) # blank
|
22
22
|
t=Time.now
|
23
23
|
elsif s[0] =~ /[+-]/
|
24
24
|
#if s=+3.years-1.minutes
|
@@ -53,19 +53,25 @@ module DR
|
|
53
53
|
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
56
|
+
|
57
|
+
=begin Examples:
|
58
|
+
|
59
|
+
DR::TimeParse.parse("+100..tomorrow") #first: +100, second: tomorrow
|
60
|
+
=> 2014-08-22 11:20:31 +0200..2014-08-23 12:00:00 +0200
|
61
|
+
|
62
|
+
DR::TimeParse.parse("now..in seven days") #first: now, second: in seven days
|
63
|
+
=> 2014-08-22 11:20:25 +0200..2014-08-29 11:20:25 +0200
|
64
|
+
|
65
|
+
DR::TimeParse.parse("today")
|
66
|
+
=> 2014-08-22 17:30:00 +0200
|
67
|
+
|
68
|
+
DR::TimeParse.parse("today",range: true)
|
69
|
+
=> 2014-08-22 11:00:00 +0200..2014-08-23 00:00:00 +0200
|
70
|
+
|
71
|
+
DR::TimeParse.parse("-3 years 2 minutes") #-94672920
|
72
|
+
=> 2011-08-22 20:01:34 +0200
|
73
|
+
|
74
|
+
require 'active_support/time'
|
75
|
+
DR::TimeParse.parse("+3.years+2.days")
|
76
|
+
=> 2017-08-24 14:04:08 +0200
|
77
|
+
=end
|
@@ -2,9 +2,9 @@ module DR
|
|
2
2
|
module CoreExt
|
3
3
|
#[Hash, Array].each {|m| m.include(Enumerable)} #to reinclude
|
4
4
|
module Enumerable
|
5
|
-
#Ex: [1,2,3,4].
|
5
|
+
#Ex: [1,2,3,4].classify({odd: [1,3], default: :even})
|
6
6
|
#=> {:odd=>[1, 3], :even=>[2, 4]}
|
7
|
-
def
|
7
|
+
def classify(h)
|
8
8
|
invh=h.inverse
|
9
9
|
default=h[:default]
|
10
10
|
r={}
|
@@ -36,7 +36,7 @@ module DR
|
|
36
36
|
|
37
37
|
# Same as +deep_merge+, but modifies +self+.
|
38
38
|
def deep_merge!(other_hash, append: :auto, &block)
|
39
|
-
return unless other_hash
|
39
|
+
return self unless other_hash
|
40
40
|
other_hash.each_pair do |k,v|
|
41
41
|
tv = self[k]
|
42
42
|
case
|
@@ -301,6 +301,8 @@ module DR
|
|
301
301
|
end
|
302
302
|
|
303
303
|
module CoreRef
|
304
|
+
# warning, this only works for methods that don't need to call other
|
305
|
+
# refined methods
|
304
306
|
CoreExt.constants.select {|c| const_get("::#{c}").is_a?(Class)}.each do |c|
|
305
307
|
refine const_get("::#{c}") do
|
306
308
|
include CoreExt.const_get(c)
|
data/lib/dr/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -1,11 +1,21 @@
|
|
1
|
+
## Uncomment if you want to run a test directly without running
|
2
|
+
## `bundle exec ruby -I test test/test_...rb`
|
3
|
+
## (another solution if 'bundler/setup' is called on the Rakefile is to use
|
4
|
+
## `rake test TEST=test/test_...rb`)
|
5
|
+
# begin
|
6
|
+
# require 'bundler/setup'
|
7
|
+
# rescue LoadError => error
|
8
|
+
# warn "Could not setup bundler: #{error.message}"
|
9
|
+
# end
|
10
|
+
|
1
11
|
require 'minitest/autorun'
|
2
12
|
|
3
13
|
## Uncomment to launch pry on a failure
|
4
14
|
#require 'pry-rescue/minitest'
|
5
15
|
|
6
16
|
begin
|
7
|
-
|
8
|
-
|
17
|
+
require 'minitest/reporters'
|
18
|
+
Minitest::Reporters.use! Minitest::Reporters::DefaultReporter.new
|
9
19
|
#Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
10
20
|
#Minitest::Reporters.use! Minitest::Reporters::ProgressReporter.new
|
11
21
|
rescue LoadError => error
|
data/test/test_converter.rb
CHANGED
@@ -17,26 +17,26 @@ describe DR::Converter do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "Output a hash with the attributes" do
|
20
|
-
DR::Converter.to_hash(@obj1, methods: [:a,:h]).must_equal({@obj1 => {a: @obj1.a, h: @obj1.h}})
|
20
|
+
_(DR::Converter.to_hash(@obj1, methods: [:a,:h])).must_equal({@obj1 => {a: @obj1.a, h: @obj1.h}})
|
21
21
|
end
|
22
22
|
|
23
23
|
it ":compact compress the values when there is only one method" do
|
24
|
-
DR::Converter.to_hash(@obj1, methods: [:a,:h], compact: true).must_equal({@obj1 => {a: @obj1.a, h: @obj1.h}})
|
25
|
-
DR::Converter.to_hash(@obj1, methods: [:a], compact: true).must_equal({@obj1 => @obj1.a})
|
24
|
+
_(DR::Converter.to_hash(@obj1, methods: [:a,:h], compact: true)).must_equal({@obj1 => {a: @obj1.a, h: @obj1.h}})
|
25
|
+
_(DR::Converter.to_hash(@obj1, methods: [:a], compact: true)).must_equal({@obj1 => @obj1.a})
|
26
26
|
end
|
27
27
|
|
28
28
|
it ":check checks that the method exists" do
|
29
|
-
-> {DR::Converter.to_hash(@obj1, methods: [:none], check: false)}.must_raise NoMethodError
|
30
|
-
DR::Converter.to_hash(@obj1, methods: [:none], check: true).must_equal({@obj1 => {}})
|
29
|
+
_(-> {DR::Converter.to_hash(@obj1, methods: [:none], check: false)}).must_raise NoMethodError
|
30
|
+
_(DR::Converter.to_hash(@obj1, methods: [:none], check: true)).must_equal({@obj1 => {}})
|
31
31
|
end
|
32
32
|
|
33
33
|
it "accepts a list" do
|
34
|
-
DR::Converter.to_hash([@obj1,@obj2], methods: [:a,:h]).must_equal({@obj1 => {a: @obj1.a, h: @obj1.h}, @obj2 => {a: @obj2.a, h: @obj2.h}})
|
34
|
+
_(DR::Converter.to_hash([@obj1,@obj2], methods: [:a,:h])).must_equal({@obj1 => {a: @obj1.a, h: @obj1.h}, @obj2 => {a: @obj2.a, h: @obj2.h}})
|
35
35
|
end
|
36
36
|
|
37
37
|
#this test also test that cycles work
|
38
38
|
it ":recursive generate the hash on the values" do
|
39
|
-
DR::Converter.to_hash(@obj3, methods: [:a,:h], recursive: true).must_equal({@obj1 => {a: @obj1.a, h: @obj1.h}, @obj2 => {a: @obj2.a, h: @obj2.h}, @obj3 => {a: @obj3.a, h: @obj3.h}})
|
39
|
+
_(DR::Converter.to_hash(@obj3, methods: [:a,:h], recursive: true)).must_equal({@obj1 => {a: @obj1.a, h: @obj1.h}, @obj2 => {a: @obj2.a, h: @obj2.h}, @obj3 => {a: @obj3.a, h: @obj3.h}})
|
40
40
|
end
|
41
41
|
|
42
42
|
end
|
data/test/test_core_ext.rb
CHANGED
@@ -10,8 +10,8 @@ module TestCoreExt
|
|
10
10
|
require 'dr/ruby_ext/core_ext'
|
11
11
|
describe DR::CoreExt do
|
12
12
|
describe Enumerable do
|
13
|
-
it "Can
|
14
|
-
[1,2,3,4].
|
13
|
+
it "Can classify enumerable" do
|
14
|
+
_([1,2,3,4].classify({odd: [1,3], default: :even})).must_equal({:odd=>[1, 3], :even=>[2, 4]})
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -19,48 +19,48 @@ module TestCoreExt
|
|
19
19
|
it "Implements Hash#deep_merge" do
|
20
20
|
h1 = { x: { y: [4,5,6] }, z: [7,8,9] }
|
21
21
|
h2 = { x: { y: [7,8,9] }, z: 'xyz' }
|
22
|
-
h1.deep_merge(h2).must_equal({x: {y: [7, 8, 9]}, z: "xyz"})
|
23
|
-
h2.deep_merge(h1).must_equal({x: {y: [4, 5, 6]}, z: [7, 8, 9]})
|
24
|
-
h1.deep_merge(h2) { |key, old, new| Array(old) + Array(new) }.must_equal({:x=>{:y=>[4, 5, 6, 7, 8, 9]}, :z=>[7, 8, 9, "xyz"]})
|
22
|
+
_(h1.deep_merge(h2)).must_equal({x: {y: [7, 8, 9]}, z: "xyz"})
|
23
|
+
_(h2.deep_merge(h1)).must_equal({x: {y: [4, 5, 6]}, z: [7, 8, 9]})
|
24
|
+
_(h1.deep_merge(h2) { |key, old, new| Array(old) + Array(new) }).must_equal({:x=>{:y=>[4, 5, 6, 7, 8, 9]}, :z=>[7, 8, 9, "xyz"]})
|
25
25
|
end
|
26
26
|
|
27
27
|
it "Hash#deep_merge merge array when they start with nil" do
|
28
28
|
h1 = { x: { y: [4,5,6] }, z: [7,8,9] }
|
29
29
|
h2 = { x: { y: [nil, 7,8,9] }, z: 'xyz' }
|
30
|
-
h1.deep_merge(h2).must_equal({x: {y: [4,5,6,7, 8, 9]}, z: "xyz"})
|
31
|
-
{x: { y: []} }.deep_merge(h2).must_equal({x: {y: [7, 8, 9]}, z: "xyz"})
|
32
|
-
{z: "foo"}.deep_merge(h2).must_equal({x: {y: [7, 8, 9]}, z: "xyz"})
|
30
|
+
_(h1.deep_merge(h2)).must_equal({x: {y: [4,5,6,7, 8, 9]}, z: "xyz"})
|
31
|
+
_({x: { y: []} }.deep_merge(h2)).must_equal({x: {y: [7, 8, 9]}, z: "xyz"})
|
32
|
+
_({z: "foo"}.deep_merge(h2)).must_equal({x: {y: [7, 8, 9]}, z: "xyz"})
|
33
33
|
end
|
34
34
|
|
35
35
|
it "Implements Hash#inverse" do
|
36
36
|
h={ploum: 2, plim: 2, plam: 3}
|
37
|
-
h.inverse.must_equal({2=>[:ploum, :plim], 3=>[:plam]})
|
37
|
+
_(h.inverse).must_equal({2=>[:ploum, :plim], 3=>[:plam]})
|
38
38
|
end
|
39
39
|
|
40
40
|
it "Implements Hash#keyed_value" do
|
41
41
|
h = { x: { y: { z: "foo" } } }
|
42
|
-
h.keyed_value("x/y/z").must_equal("foo")
|
42
|
+
_(h.keyed_value("x/y/z")).must_equal("foo")
|
43
43
|
end
|
44
44
|
|
45
45
|
it "Implements Hash#set_keyed_value" do
|
46
46
|
h = { x: { y: { z: "foo" } } }
|
47
|
-
h.set_keyed_value("x/y/z","bar").must_equal({ x: { y: { z: "bar" } } })
|
48
|
-
h.set_keyed_value("x/y","bar2").must_equal({ x: { y: "bar2" } })
|
49
|
-
h.set_keyed_value("z/y","bar3").must_equal({ x: { y: "bar2" } , z: {y: "bar3"}})
|
47
|
+
_(h.set_keyed_value("x/y/z","bar")).must_equal({ x: { y: { z: "bar" } } })
|
48
|
+
_(h.set_keyed_value("x/y","bar2")).must_equal({ x: { y: "bar2" } })
|
49
|
+
_(h.set_keyed_value("z/y","bar3")).must_equal({ x: { y: "bar2" } , z: {y: "bar3"}})
|
50
50
|
end
|
51
51
|
|
52
52
|
it "Implements Hash#leafs" do
|
53
|
-
{foo: [:bar, :baz], bar: [:plum, :qux]}.leafs([:foo]).must_equal([:plum, :qux, :baz])
|
53
|
+
_({foo: [:bar, :baz], bar: [:plum, :qux]}.leafs([:foo])).must_equal([:plum, :qux, :baz])
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
57
|
describe UnboundMethod do
|
58
58
|
it "Can be converted to a proc" do
|
59
59
|
m=String.instance_method(:length)
|
60
|
-
["foo", "ploum"].map(&m).must_equal([3,5])
|
60
|
+
_(["foo", "ploum"].map(&m)).must_equal([3,5])
|
61
61
|
end
|
62
62
|
it "Can call" do
|
63
|
-
String.instance_method(:length).call("foo").must_equal(3)
|
63
|
+
_(String.instance_method(:length).call("foo")).must_equal(3)
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
@@ -73,34 +73,34 @@ module TestCoreExt
|
|
73
73
|
it "Can do rcurry" do
|
74
74
|
l=->(x,y) {"#{x}: #{y}"}
|
75
75
|
m=l.rcurry("foo")
|
76
|
-
m.call("bar").must_equal("bar: foo")
|
76
|
+
_(m.call("bar")).must_equal("bar: foo")
|
77
77
|
end
|
78
78
|
|
79
79
|
it "Can compose functions" do
|
80
80
|
somme=->(x,y) {x+y}
|
81
81
|
carre=->(x) {x*x}
|
82
|
-
carre.compose(somme).(2,3).must_equal(25)
|
82
|
+
_(carre.compose(somme).(2,3)).must_equal(25)
|
83
83
|
end
|
84
84
|
|
85
85
|
it "Can uncurry functions" do
|
86
|
-
(->(x) {->(y) {x+y}}).uncurry.(2,3).must_equal(5)
|
87
|
-
(->(x,y) {x+y}).curry.uncurry.(2,3).must_equal(5)
|
86
|
+
_((->(x) {->(y) {x+y}}).uncurry.(2,3)).must_equal(5)
|
87
|
+
_((->(x,y) {x+y}).curry.uncurry.(2,3)).must_equal(5)
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
91
|
describe Array do
|
92
92
|
it "Can be converted to proc (providing extra arguments)" do
|
93
|
-
["ploum","plam"].map(&[:+,"foo"]).must_equal(["ploumfoo", "plamfoo"])
|
93
|
+
_(["ploum","plam"].map(&[:+,"foo"])).must_equal(["ploumfoo", "plamfoo"])
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
97
|
describe Object do
|
98
98
|
it "this can change the object" do
|
99
|
-
"foo".this {|s| s.size}.+(1).must_equal(4)
|
99
|
+
_("foo".this {|s| s.size}.+(1)).must_equal(4)
|
100
100
|
end
|
101
101
|
|
102
102
|
it "and_this emulates the Maybe Monad" do
|
103
|
-
"foo".and_this {|s| s.size}.must_equal(3)
|
103
|
+
_("foo".and_this {|s| s.size}).must_equal(3)
|
104
104
|
assert_nil nil.and_this {|s| s.size}
|
105
105
|
end
|
106
106
|
end
|
@@ -109,7 +109,7 @@ module TestCoreExt
|
|
109
109
|
it "Generates keys when needed" do
|
110
110
|
h=DR::RecursiveHash.new
|
111
111
|
h[:foo][:bar]=3
|
112
|
-
h.must_equal({foo: {bar: 3}})
|
112
|
+
_(h).must_equal({foo: {bar: 3}})
|
113
113
|
end
|
114
114
|
end
|
115
115
|
end
|
data/test/test_date_parse.rb
CHANGED
@@ -3,23 +3,27 @@ require 'dr/parse/date_parse'
|
|
3
3
|
|
4
4
|
describe DR::DateRange do
|
5
5
|
before do
|
6
|
+
@tz=ENV['TZ']
|
6
7
|
ENV['TZ']='GMT'
|
7
8
|
@daterange=DR::DateRange.parse("2014-01-02 -> 2014-01-03, 2014-01-05, 2014-02 -> :now")
|
8
9
|
end
|
10
|
+
after do
|
11
|
+
ENV['TZ']=@tz
|
12
|
+
end
|
9
13
|
|
10
14
|
it "Can parse dates" do
|
11
|
-
@daterange.d.must_equal [["2014-01-02", "2014-01-03"], ["2014-01-05"], ["2014-02", :now]]
|
15
|
+
_(@daterange.d).must_equal [["2014-01-02", "2014-01-03"], ["2014-01-05"], ["2014-02", :now]]
|
12
16
|
end
|
13
17
|
|
14
18
|
it "Can output a date range" do
|
15
|
-
@daterange.to_s.must_equal "Jan. 2014 – Jan. 2014, Jan. 2014, Feb. 2014 – Present"
|
19
|
+
_(@daterange.to_s).must_equal "Jan. 2014 – Jan. 2014, Jan. 2014, Feb. 2014 – Present"
|
16
20
|
end
|
17
21
|
|
18
22
|
it "Can output a date range with full time information" do
|
19
|
-
@daterange.to_s(output_date_length: :all).must_equal "02 Jan. 2014 – 03 Jan. 2014, 05 Jan. 2014, Feb. 2014 – Present"
|
23
|
+
_(@daterange.to_s(output_date_length: :all)).must_equal "02 Jan. 2014 – 03 Jan. 2014, 05 Jan. 2014, Feb. 2014 – Present"
|
20
24
|
end
|
21
25
|
|
22
26
|
it "Has time information" do
|
23
|
-
@daterange.t[0].to_s.must_equal "[2014-01-02 00:00:00 +0000, 2014-01-03 00:00:00 +0000]".encode('US-ASCII')
|
27
|
+
_(@daterange.t[0].to_s).must_equal "[2014-01-02 00:00:00 +0000, 2014-01-03 00:00:00 +0000]".encode('US-ASCII')
|
24
28
|
end
|
25
29
|
end
|
data/test/test_graph.rb
CHANGED
@@ -8,53 +8,53 @@ describe DR::Graph do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
it "builds the graph" do
|
11
|
-
@graph.nodes.length.must_equal 3
|
11
|
+
_(@graph.nodes.length).must_equal 3
|
12
12
|
end
|
13
13
|
|
14
14
|
it "accepts :to_a" do
|
15
|
-
@graph.to_a.map(&:name).must_equal(["foo", "bar", "baz"])
|
15
|
+
_(@graph.to_a.map(&:name)).must_equal(["foo", "bar", "baz"])
|
16
16
|
end
|
17
17
|
|
18
18
|
it "accepts :to_hash" do
|
19
|
-
@graph.to_hash.first[1].keys.must_equal [:children, :parents, :attributes]
|
19
|
+
_(@graph.to_hash.first[1].keys).must_equal [:children, :parents, :attributes]
|
20
20
|
end
|
21
21
|
|
22
22
|
it "can be converted to a hash" do
|
23
|
-
@graph.to_h.must_equal ({"foo"=> ["bar","baz"], "bar" => ["baz"], "baz" => []})
|
23
|
+
_(@graph.to_h).must_equal ({"foo"=> ["bar","baz"], "bar" => ["baz"], "baz" => []})
|
24
24
|
end
|
25
25
|
|
26
26
|
it "can give a node" do
|
27
|
-
@graph["foo"].class.must_equal DR::Node
|
27
|
+
_(@graph["foo"].class).must_equal DR::Node
|
28
28
|
end
|
29
29
|
|
30
30
|
it "can give descendants of a node" do
|
31
|
-
@graph["foo"].descendants.map(&:to_s).must_equal(["bar", "baz"])
|
31
|
+
_(@graph["foo"].descendants.map(&:to_s)).must_equal(["bar", "baz"])
|
32
32
|
end
|
33
33
|
|
34
34
|
it "can give ancestors of a node" do
|
35
|
-
@graph["baz"].ancestors.map(&:to_s).must_equal(["foo", "bar"])
|
35
|
+
_(@graph["baz"].ancestors.map(&:to_s)).must_equal(["foo", "bar"])
|
36
36
|
end
|
37
37
|
|
38
38
|
it "can give the root nodes" do
|
39
|
-
@graph.roots.map(&:name).must_equal(["foo"])
|
39
|
+
_(@graph.roots.map(&:name)).must_equal(["foo"])
|
40
40
|
end
|
41
41
|
|
42
42
|
it "can give the bottom nodes" do
|
43
|
-
@graph.bottom.map(&:name).must_equal(["baz"])
|
43
|
+
_(@graph.bottom.map(&:name)).must_equal(["baz"])
|
44
44
|
end
|
45
45
|
|
46
46
|
it "can show all ancestors of nodes" do
|
47
|
-
@graph.ancestors("baz","bar").map(&:to_s).must_equal(["baz", "bar", "foo"])
|
48
|
-
@graph.ancestors("baz","bar", ourselves: false).map(&:to_s).must_equal(["foo"])
|
47
|
+
_(@graph.ancestors("baz","bar").map(&:to_s)).must_equal(["baz", "bar", "foo"])
|
48
|
+
_(@graph.ancestors("baz","bar", ourselves: false).map(&:to_s)).must_equal(["foo"])
|
49
49
|
end
|
50
50
|
|
51
51
|
it "can show all descendants of nodes" do
|
52
|
-
@graph.descendants("foo","bar").map(&:to_s).must_equal(["foo", "bar", "baz"])
|
53
|
-
@graph.descendants("foo","bar", ourselves: false).map(&:to_s).must_equal(["baz"])
|
52
|
+
_(@graph.descendants("foo","bar").map(&:to_s)).must_equal(["foo", "bar", "baz"])
|
53
|
+
_(@graph.descendants("foo","bar", ourselves: false).map(&:to_s)).must_equal(["baz"])
|
54
54
|
end
|
55
55
|
|
56
56
|
it "can give a hash of children" do
|
57
|
-
@graph.to_children.must_equal({"foo"=>["bar", "baz"], "bar"=>["baz"], "baz"=>[]})
|
57
|
+
_(@graph.to_children).must_equal({"foo"=>["bar", "baz"], "bar"=>["baz"], "baz"=>[]})
|
58
58
|
end
|
59
59
|
|
60
60
|
describe "build" do
|
@@ -64,11 +64,11 @@ describe DR::Graph do
|
|
64
64
|
end
|
65
65
|
|
66
66
|
it "detects unneeded nodes" do
|
67
|
-
@graph.unneeded("foo","bar").map(&:name).must_equal ["foo","bar"]
|
68
|
-
@graph.unneeded("bar").map(&:name).must_equal []
|
67
|
+
_(@graph.unneeded("foo","bar").map(&:name)).must_equal ["foo","bar"]
|
68
|
+
_(@graph.unneeded("bar").map(&:name)).must_equal []
|
69
69
|
end
|
70
70
|
it "detects unneeded descendants" do
|
71
|
-
@graph.unneeded_descendants("foo").map(&:name).must_equal ["foo", "bar", "baz"]
|
71
|
+
_(@graph.unneeded_descendants("foo").map(&:name)).must_equal ["foo", "bar", "baz"]
|
72
72
|
end
|
73
73
|
|
74
74
|
describe "It works with a cycle" do
|
@@ -77,7 +77,7 @@ describe DR::Graph do
|
|
77
77
|
end
|
78
78
|
|
79
79
|
it "It builds the graph" do
|
80
|
-
@graph.nodes.length.must_equal 3
|
80
|
+
_(@graph.nodes.length).must_equal 3
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
@@ -97,9 +97,9 @@ describe DR::Graph do
|
|
97
97
|
end
|
98
98
|
|
99
99
|
it "It builds the graph" do
|
100
|
-
@graph.nodes.length.must_equal 3
|
101
|
-
@graph.to_h.must_equal({"foo"=>["bar", "baz"], "bar"=>["baz"], "baz"=>["foo"]})
|
102
|
-
@graph['baz'].attributes.must_equal(real: true)
|
100
|
+
_(@graph.nodes.length).must_equal 3
|
101
|
+
_(@graph.to_h).must_equal({"foo"=>["bar", "baz"], "bar"=>["baz"], "baz"=>["foo"]})
|
102
|
+
_(@graph['baz'].attributes).must_equal(real: true)
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
@@ -109,18 +109,18 @@ describe DR::Graph do
|
|
109
109
|
end
|
110
110
|
|
111
111
|
it "Graph2 is well defined" do
|
112
|
-
@graph2.nodes.map(&:name).must_equal(%w(foo bar baz qux))
|
112
|
+
_(@graph2.nodes.map(&:name)).must_equal(%w(foo bar baz qux))
|
113
113
|
end
|
114
114
|
|
115
115
|
it "Can be merged in place" do
|
116
|
-
@graph | @graph2
|
117
|
-
@graph.to_h.must_equal({"foo"=>["bar", "baz"], "bar"=>["baz"], "baz"=>["bar", "qux"], "qux"=>[]})
|
116
|
+
@graph.merge!(@graph2) #alias @graph | @graph2
|
117
|
+
_(@graph.to_h).must_equal({"foo"=>["bar", "baz"], "bar"=>["baz"], "baz"=>["bar", "qux"], "qux"=>[]})
|
118
118
|
end
|
119
119
|
|
120
120
|
it "Can be merged" do
|
121
121
|
@graph3 = @graph + @graph2
|
122
|
-
@graph.to_h.must_equal({"foo"=>["bar", "baz"], "bar"=>["baz"], "baz"=>[]})
|
123
|
-
@graph3.to_h.must_equal({"foo"=>["bar", "baz"], "bar"=>["baz"], "baz"=>["bar", "qux"], "qux"=>[]})
|
122
|
+
_(@graph.to_h).must_equal({"foo"=>["bar", "baz"], "bar"=>["baz"], "baz"=>[]})
|
123
|
+
_(@graph3.to_h).must_equal({"foo"=>["bar", "baz"], "bar"=>["baz"], "baz"=>["bar", "qux"], "qux"=>[]})
|
124
124
|
end
|
125
125
|
end
|
126
126
|
end
|