acts_as_graph 0.0.1
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 +7 -0
- data/.gitignore +4 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +32 -0
- data/README.md +3 -0
- data/Rakefile +8 -0
- data/acts_as_graph.gemspec +26 -0
- data/lib/acts_as_graph.rb +60 -0
- data/lib/acts_as_graph/version.rb +3 -0
- data/spec/acts_as_graph_spec.rb +101 -0
- data/spec/spec_helper.rb +14 -0
- metadata +68 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 85713371daed2a84ea58c068c10a373165ad9b3b
|
4
|
+
data.tar.gz: 448fd7508d466a053e8568e3958326f0115bd68f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: da1fe3794e4b6d89fe824908f1d1767e3a45dad7206dcf1cb3b4dee9926ff253c6085e7e3067608f2a795dbee6362463a65fc8dc4cbf8346d33573fb43ff6cc5
|
7
|
+
data.tar.gz: 6f2f24d36ca3530c70f9d2a3f700e93fcb6b216b6305ee4a4d8e634445273b91427da69745eaa3f12ba0d0117845ad31438ac6367576f7a133649c342fc6a021
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
acts_as_graph (0.0.1)
|
5
|
+
rspec
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
diff-lcs (1.3)
|
11
|
+
rspec (3.7.0)
|
12
|
+
rspec-core (~> 3.7.0)
|
13
|
+
rspec-expectations (~> 3.7.0)
|
14
|
+
rspec-mocks (~> 3.7.0)
|
15
|
+
rspec-core (3.7.1)
|
16
|
+
rspec-support (~> 3.7.0)
|
17
|
+
rspec-expectations (3.7.0)
|
18
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
19
|
+
rspec-support (~> 3.7.0)
|
20
|
+
rspec-mocks (3.7.0)
|
21
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
22
|
+
rspec-support (~> 3.7.0)
|
23
|
+
rspec-support (3.7.1)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
ruby
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
acts_as_graph!
|
30
|
+
|
31
|
+
BUNDLED WITH
|
32
|
+
1.16.1
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
lib = File.expand_path('../lib/', __FILE__)
|
2
|
+
$:.unshift lib unless $:.include?(lib)
|
3
|
+
|
4
|
+
require 'acts_as_graph/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'acts_as_graph'
|
8
|
+
s.version = ActsAsGraph::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ['Zhichao Feng']
|
11
|
+
s.email = ['flankerfc@gmail.com']
|
12
|
+
s.homepage = 'https://github.com/flanker'
|
13
|
+
s.summary = 'A very simple acts as graph for your model'
|
14
|
+
s.description = 'A very simple acts as graph for your model'
|
15
|
+
s.license = 'MIT'
|
16
|
+
|
17
|
+
s.required_ruby_version = '>= 2.3'
|
18
|
+
s.required_rubygems_version = '>= 1.3.6'
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
22
|
+
s.require_path = ['lib']
|
23
|
+
|
24
|
+
s.add_runtime_dependency 'rspec'
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module ActsAsGraph
|
2
|
+
|
3
|
+
def self.included base
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
def acts_as_graph children: nil
|
10
|
+
@children_method_name = children
|
11
|
+
|
12
|
+
define_method "descendant_#{children}" do
|
13
|
+
descendant_vertices
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def children_method_name
|
18
|
+
@children_method_name
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
def descendant_vertices
|
24
|
+
vertices_found = []
|
25
|
+
collect_child_vertices vertices_found, starting_vertice: self
|
26
|
+
vertices_found
|
27
|
+
end
|
28
|
+
|
29
|
+
def collect_child_vertices vertices_found, starting_vertice: nil
|
30
|
+
child_vertices.each do |child_vertice|
|
31
|
+
next if vertices_found.include?(child_vertice) || child_vertice == starting_vertice
|
32
|
+
vertices_found << child_vertice
|
33
|
+
child_vertice.collect_child_vertices vertices_found, starting_vertice: starting_vertice
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def has_circular_reference?
|
38
|
+
vertices_found = []
|
39
|
+
has_circular_reference_in_child_vertices? vertices_found, starting_vertice: self
|
40
|
+
end
|
41
|
+
|
42
|
+
def has_circular_reference_in_child_vertices? vertices_found, starting_vertice: nil
|
43
|
+
child_vertices.any? do |child_vertice|
|
44
|
+
return true if vertices_found.include?(child_vertice) || child_vertice == starting_vertice
|
45
|
+
vertices_found << child_vertice
|
46
|
+
child_vertice.has_circular_reference_in_child_vertices? vertices_found, starting_vertice: starting_vertice
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def children_method_name
|
53
|
+
self.class.children_method_name
|
54
|
+
end
|
55
|
+
|
56
|
+
def child_vertices
|
57
|
+
self.send children_method_name
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ActsAsGraph do
|
4
|
+
|
5
|
+
class Task
|
6
|
+
|
7
|
+
include ActsAsGraph
|
8
|
+
|
9
|
+
acts_as_graph children: :depended_tasks
|
10
|
+
|
11
|
+
attr_reader :title
|
12
|
+
attr_accessor :depended_tasks
|
13
|
+
|
14
|
+
def initialize title, depended_tasks = []
|
15
|
+
@title = title
|
16
|
+
@depended_tasks = depended_tasks
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
context '#descendant_depended_tasks' do
|
22
|
+
|
23
|
+
it 'should get all descendant tasks' do
|
24
|
+
task_1 = Task.new 'task_1'
|
25
|
+
task_2 = Task.new 'task_2'
|
26
|
+
task_3 = Task.new 'task_3', [task_1, task_2]
|
27
|
+
|
28
|
+
descendant_depended_tasks = task_3.descendant_depended_tasks
|
29
|
+
expect(descendant_depended_tasks.length).to eq(2)
|
30
|
+
expect(descendant_depended_tasks).to match_array([task_1, task_2])
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should handle the circular reference' do
|
34
|
+
task_1 = Task.new 'task_1'
|
35
|
+
task_2 = Task.new 'task_2', [task_1]
|
36
|
+
task_3 = Task.new 'task_3', [task_2]
|
37
|
+
task_1.depended_tasks = [task_3]
|
38
|
+
|
39
|
+
descendant_depended_tasks = task_3.descendant_depended_tasks
|
40
|
+
expect(descendant_depended_tasks.length).to eq(2)
|
41
|
+
expect(descendant_depended_tasks).to match_array([task_1, task_2])
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should handle a more complex case' do
|
45
|
+
task_1 = Task.new 'task_1'
|
46
|
+
task_2 = Task.new 'task_2'
|
47
|
+
task_3 = Task.new 'task_3'
|
48
|
+
task_4 = Task.new 'task_4'
|
49
|
+
task_5 = Task.new 'task_5'
|
50
|
+
task_6 = Task.new 'task_6'
|
51
|
+
task_1.depended_tasks = [task_2]
|
52
|
+
task_2.depended_tasks = [task_3, task_4]
|
53
|
+
task_3.depended_tasks = [task_1, task_5, task_6]
|
54
|
+
task_4.depended_tasks = [task_5]
|
55
|
+
|
56
|
+
descendant_depended_tasks = task_1.descendant_depended_tasks
|
57
|
+
expect(descendant_depended_tasks.length).to eq(5)
|
58
|
+
expect(descendant_depended_tasks).to match_array([task_2, task_3, task_4, task_5, task_6])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context '#has_circular_reference?' do
|
63
|
+
|
64
|
+
it 'works if there is no circular reference' do
|
65
|
+
task_1 = Task.new 'task_1'
|
66
|
+
task_2 = Task.new 'task_2'
|
67
|
+
task_3 = Task.new 'task_3', [task_1, task_2]
|
68
|
+
|
69
|
+
expect(task_3.has_circular_reference?).to be false
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'works if there is a child vertice references the starting vertice' do
|
73
|
+
task_1 = Task.new 'task_1'
|
74
|
+
task_2 = Task.new 'task_2'
|
75
|
+
task_3 = Task.new 'task_3'
|
76
|
+
|
77
|
+
task_1.depended_tasks = [task_2]
|
78
|
+
task_2.depended_tasks = [task_3]
|
79
|
+
task_3.depended_tasks = [task_1]
|
80
|
+
|
81
|
+
expect(task_1.has_circular_reference?).to be true
|
82
|
+
expect(task_2.has_circular_reference?).to be true
|
83
|
+
expect(task_3.has_circular_reference?).to be true
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'works if there are two vertices reference with each other' do
|
87
|
+
task_1 = Task.new 'task_1'
|
88
|
+
task_2 = Task.new 'task_2'
|
89
|
+
task_3 = Task.new 'task_3'
|
90
|
+
|
91
|
+
task_1.depended_tasks = [task_2]
|
92
|
+
task_2.depended_tasks = [task_3]
|
93
|
+
task_3.depended_tasks = [task_2]
|
94
|
+
|
95
|
+
expect(task_1.has_circular_reference?).to be true
|
96
|
+
expect(task_2.has_circular_reference?).to be true
|
97
|
+
expect(task_3.has_circular_reference?).to be true
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'acts_as_graph'
|
3
|
+
|
4
|
+
RSpec.configure do |config|
|
5
|
+
# Enable flags like --only-failures and --next-failure
|
6
|
+
config.example_status_persistence_file_path = '.rspec_status'
|
7
|
+
|
8
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
9
|
+
config.disable_monkey_patching!
|
10
|
+
|
11
|
+
config.expect_with :rspec do |c|
|
12
|
+
c.syntax = :expect
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: acts_as_graph
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Zhichao Feng
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-05-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: A very simple acts as graph for your model
|
28
|
+
email:
|
29
|
+
- flankerfc@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- ".gitignore"
|
35
|
+
- Gemfile
|
36
|
+
- Gemfile.lock
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- acts_as_graph.gemspec
|
40
|
+
- lib/acts_as_graph.rb
|
41
|
+
- lib/acts_as_graph/version.rb
|
42
|
+
- spec/acts_as_graph_spec.rb
|
43
|
+
- spec/spec_helper.rb
|
44
|
+
homepage: https://github.com/flanker
|
45
|
+
licenses:
|
46
|
+
- MIT
|
47
|
+
metadata: {}
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '2.3'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.3.6
|
62
|
+
requirements: []
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 2.6.14
|
65
|
+
signing_key:
|
66
|
+
specification_version: 4
|
67
|
+
summary: A very simple acts as graph for your model
|
68
|
+
test_files: []
|