drain 0.3.0 → 0.7.0
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/.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
|