Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@balinterdi
Created September 1, 2009 16:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save balinterdi/179186 to your computer and use it in GitHub Desktop.
Save balinterdi/179186 to your computer and use it in GitHub Desktop.
class Story
attr_reader :forked_stories, :id
class << self
def get_id
last_id = instance_variable_get("@last_id")
next_id = last_id.nil? ? :a : last_id.to_s.succ.to_sym
instance_variable_set("@last_id", next_id)
# puts "XXX Returning #{next_id}"
next_id
end
end
def initialize
@forked_stories = []
@id = self.class.get_id
end
def fork!
forked_story = Story.new
@forked_stories << forked_story
forked_story
end
def fork_tree
forked = forked_stories
forked_from_children = forked.inject([]) do |fstories, fstory|
fstories + fstory.fork_tree
end
forked + forked_from_children
end
def inspect
"<#{object_id}:#{@id}>"
end
private
def get_next_id
last_story = forked_stories.empty? ? self : forked_stories.last
last_story.id.to_s.succ
end
end
require "story"
describe Story do
before do
@story = Story.new
end
describe "when assigning ids" do
it "the first node should receive 'a'" do
@story.id.should == :a
end
end
describe "when not forked" do
it "should not have any forked stories" do
@story.forked_stories.should == []
end
it "its fork tree should be empty" do
@story.fork_tree.should == []
end
end
describe "when forked" do
before do
@forked_story = @story.fork!
end
it "should create a new story" do
@forked_story.should_not be_nil
end
it "should have the new story as the only forked story" do
@story.forked_stories.should == [@forked_story]
end
end
describe "when forked multiple times" do
before do
@story_1 = @story.fork!
@story_2 = @story.fork!
@story_3 = @story.fork!
end
it "should contain all the forked stories in the order of their forking" do
@story.forked_stories.should == [@story_1, @story_2, @story_3]
end
end
describe "when asked about its fork tree" do
before(:all) do
# see my fork tree sketch on the paper
@a = Story.new
@b = @a.fork!
@c = @b.fork!
@d = @b.fork!
@e = @b.fork!
@f = @d.fork!
@g = @d.fork!
@h = @e.fork!
@i = @h.fork!
@j = @h.fork!
@k = @h.fork!
@l = @h.fork!
# and http://gist.github.com/179186
end
it "the leaves should return an empty collection" do
%w[c f g i j k l].each do |leaf|
instance_variable_get("@#{leaf}").send(:fork_tree).should == []
end
end
it "first level nodes should return their forked stories" do
@d.fork_tree.should == [@f, @g]
@h.fork_tree.should == [@i, @j, @k, @l]
end
it "higher level nodes should return the ensemble of the forked stories of their children" do
@e.fork_tree.should == [@h, @i, @j, @k, @l]
@b.fork_tree.should == [@c, @d, @e, @f, @g, @h, @i, @j, @k, @l]
@a.fork_tree.should == [@b, @c, @d, @e, @f, @g, @h, @i, @j, @k, @l]
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment