OSDN Git Service

Prevent SystemStackError on Issue#all_dependent_issues with circular dependency ...
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sat, 15 Jan 2011 14:12:18 +0000 (14:12 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sat, 15 Jan 2011 14:12:18 +0000 (14:12 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4723 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/models/issue.rb
test/unit/issue_test.rb

index abea0b8..4892a71 100644 (file)
@@ -456,11 +456,14 @@ class Issue < ActiveRecord::Base
     (relations_from + relations_to).sort
   end
   
-  def all_dependent_issues
+  def all_dependent_issues(except=nil)
+    except ||= self
     dependencies = []
     relations_from.each do |relation|
-      dependencies << relation.issue_to
-      dependencies += relation.issue_to.all_dependent_issues
+      if relation.issue_to && relation.issue_to != except
+        dependencies << relation.issue_to
+        dependencies += relation.issue_to.all_dependent_issues(except)
+      end
     end
     dependencies
   end
index 4d771d9..d284c74 100644 (file)
@@ -618,6 +618,25 @@ class IssueTest < ActiveSupport::TestCase
     end
   end
 
+  def test_all_dependent_issues
+    IssueRelation.delete_all
+    assert IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => IssueRelation::TYPE_PRECEDES)
+    assert IssueRelation.create!(:issue_from => Issue.find(2), :issue_to => Issue.find(3), :relation_type => IssueRelation::TYPE_PRECEDES)
+    assert IssueRelation.create!(:issue_from => Issue.find(3), :issue_to => Issue.find(8), :relation_type => IssueRelation::TYPE_PRECEDES)
+    
+    assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
+  end
+
+  def test_all_dependent_issues_with_persistent_circular_dependency
+    IssueRelation.delete_all
+    assert IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => IssueRelation::TYPE_PRECEDES)
+    assert IssueRelation.create!(:issue_from => Issue.find(2), :issue_to => Issue.find(3), :relation_type => IssueRelation::TYPE_PRECEDES)
+    # Validation skipping
+    assert IssueRelation.new(:issue_from => Issue.find(3), :issue_to => Issue.find(1), :relation_type => IssueRelation::TYPE_PRECEDES).save(false)
+    
+    assert_equal [2, 3], Issue.find(1).all_dependent_issues.collect(&:id).sort
+  end
+  
   context "#done_ratio" do
     setup do
       @issue = Issue.find(1)