acts_as_graph 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,4 @@
1
+ acts_as_graph-*.gem
2
+ .rspec_status
3
+ tags
4
+ .byebug_history
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -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
@@ -0,0 +1,3 @@
1
+ # acts_as_graph
2
+
3
+ working in progress
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env rake
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: [:spec]
@@ -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,3 @@
1
+ module ActsAsGraph
2
+ VERSION = '0.0.1'
3
+ 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
@@ -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: []