'
148 | else
149 | folder_name = ::File.basename(tree.base_path)
150 | html = %(
)
151 | end
152 | # Open the wrapper
153 | html << '
'
154 | # Add the collapsed span
155 | html << '
+'
156 | # Add the name
157 | if root
158 | html << '
Project'
159 | else
160 | html << %(
#{folder_name})
161 | end
162 | # Add the elapsed time
163 | html << %(
#{elapsed(tree.elapsed_time)})
164 | # End with a clearfix element
165 | html << '
'
166 | # Close the wrapper
167 | html << '
'
168 | # Add the nested_tree if available
169 | if tree.nested_tree.any?
170 | tree.nested_tree.each_pair do |folder, nested_tree|
171 | html << parse_file_tree(nested_tree)
172 | end
173 | end
174 | # Add the files
175 | if tree.files.any?
176 | # Open the files 's ul
177 | html << '
'
178 | tree.files.each do |file|
179 | # Open the file's li
180 | html << '- '
181 | # Add the path
182 | html << %(#{file[:path]})
183 | # Add the elapsed time
184 | html << %(#{elapsed(file[:elapsed_time])})
185 | # End with a clearfix element
186 | html << ''
187 | # Close the file's li
188 | html << '
'
189 | end
190 | # Close the files 's ul
191 | html << '
'
192 | end
193 | # Close the root div
194 | html << "
"
195 | # Clode the article if it is the root element
196 | html << "" if root
197 | # Finally return the whole thing
198 | html
199 | end
200 | end
201 | end
202 | end
203 | end
--------------------------------------------------------------------------------
/spec/watch_tower/server/presenters/project_presenter_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | module Server
4 | module Presenters
5 | describe ProjectPresenter do
6 |
7 | describe "#elapsed" do
8 | before(:each) do
9 | @project = FactoryGirl.create :project
10 | end
11 |
12 | subject { ProjectPresenter.new(@project, nil) }
13 |
14 | it "should return a formatted elapsed time" do
15 | time = 1.day + 2.hours + 3.minutes + 34.seconds
16 | model = mock
17 | model.stubs(:elapsed_time).returns(time)
18 | subject.stubs(:model).returns(model)
19 | subject.elapsed.should == '1 day, 2 hours, 3 minutes and 34 seconds'
20 | end
21 | end
22 |
23 | describe "#approximate_elapsed" do
24 | before(:each) do
25 | @project = FactoryGirl.create :project
26 | end
27 |
28 | subject { ProjectPresenter.new(@project, nil) }
29 |
30 | it { should respond_to :approximate_elapsed }
31 |
32 | it "should return 1 minutes for elapsed_times less than a minute" do
33 | time = 0.minutes + 3.seconds
34 | subject.approximate_elapsed(time).should == '1 minute'
35 | end
36 |
37 | it "should return 10 minutes for elapsed_times equal to 10m30s" do
38 | time = 10.minutes + 30.seconds
39 | subject.approximate_elapsed(time).should == '10 minutes'
40 | end
41 |
42 | it "should return 1 day for elapsed_times equal to 1 day and 2 hours" do
43 | time = 1.day + 2.hours
44 | subject.approximate_elapsed(time).should == '1 day'
45 | end
46 |
47 | it "should return 1 day and a half for elapsed_times equal to 1 day and 5 hours" do
48 | time = 1.day + 7.hours
49 | subject.approximate_elapsed(time).should == '1 day and a half'
50 | end
51 |
52 | it "should return 1 hour for elapsed_times equal to 1 hour and 2 minutes" do
53 | time = 1.hour + 2.minutes
54 | subject.approximate_elapsed(time).should == '1 hour'
55 | end
56 |
57 | it "should return 1 hour and a half for elapsed_times equal to 1 hour and 25 minutes" do
58 | time = 1.hour + 25.minutes
59 | subject.approximate_elapsed(time).should == '1 hour and a half'
60 | end
61 |
62 | it "should display 2 hours if elapsed_times equal 1 hour and 50 minutes" do
63 | time = 1.hour + 50.minutes
64 | subject.approximate_elapsed(time).should == '2 hours'
65 | end
66 |
67 | it "should display 2 days if elapsed_times equal 1 day and 20 hours" do
68 | time = 1.day + 20.hours
69 | subject.approximate_elapsed(time).should == '2 days'
70 | end
71 | end
72 |
73 |
74 | describe "File tree" do
75 | before(:each) do
76 | @project = FactoryGirl.create :project
77 | @project_path = @project.path
78 | @file_paths = [
79 | "#{@project_path}/file1.rb",
80 | "#{@project_path}/file2.rb",
81 | "#{@project_path}/folder/file_under_folder1.rb",
82 | "#{@project_path}/folder/file_under_folder2.rb",
83 | ]
84 | @file_paths.each do |fp|
85 | f = FactoryGirl.create :file, project: @project, path: fp
86 | 2.times do
87 | Timecop.freeze(Time.now + 1)
88 | FactoryGirl.create :time_entry, file: f, mtime: Time.now
89 | end
90 | end
91 |
92 | @files = @project.reload.files
93 | @tree = FileTree.new(@project_path, @project.reload.files)
94 | @elapsed_time = @project.elapsed_time
95 | end
96 |
97 | subject { ProjectPresenter.new(@project, nil) }
98 |
99 | describe "#parse_file_tree" do
100 | it { should respond_to :parse_file_tree }
101 |
102 | it "should nest everything under an article with class file_tree" do
103 | subject.send(:parse_file_tree, @tree, true).should =~ %r(^
]*>.*$)
104 | end
105 |
106 | it "shouldn't nest everything under an article with class file_tree if it is not the root element" do
107 | subject.send(:parse_file_tree, @tree.nested_tree['folder']).should_not =~ %r(^
]*>.*$)
108 | end
109 |
110 | it "should return a div with id root" do
111 | subject.send(:parse_file_tree, @tree, true).should =~ %r(
]*>.*
)
112 | end
113 |
114 | it "should return a div with id nested_folder" do
115 | subject.send(:parse_file_tree, @tree.nested_tree['folder']).should =~ %r(^
]*>.*
$)
116 | end
117 |
118 | it "should return a span for the expand/collapse for the root" do
119 | subject.send(:parse_file_tree, @tree, true).should =~
120 | %r(
]*>.*\s*\+\s*.*
)
121 | end
122 |
123 | it "should return a span for the expand/collapse for the nested_folder" do
124 | subject.send(:parse_file_tree, @tree.nested_tree['folder']).should =~
125 | %r(
]*>.*\s*\+\s*.*
)
126 | end
127 |
128 | it "should return a span for the name, Project for the root" do
129 | subject.send(:parse_file_tree, @tree, true).should =~
130 | %r(
]*>.*\s*Project\s*.*
)
131 | end
132 |
133 | it "should return a span for the name, folder for the nested folder" do
134 | subject.send(:parse_file_tree, @tree.nested_tree['folder']).should =~
135 | %r(^
]*>.*\s*folder\s*.*
$)
136 | end
137 |
138 | it "should return a span for the elapsed time (root)" do
139 | subject.send(:parse_file_tree, @tree, true).should =~
140 | %r(
]*>.*\s*#{subject.elapsed(@elapsed_time)}\s*.*
)
141 | end
142 |
143 | it "should return a span for the elapsed time (folder)" do
144 | subject.send(:parse_file_tree, @tree.nested_tree['folder']).should =~
145 | %r(^
]*>.*\s*#{subject.elapsed(@elapsed_time / 2)}\s*.*
$)
146 | end
147 |
148 | it "should return the folder tree inside the tree" do
149 | subject.send(:parse_file_tree, @tree, true).should =~
150 | %r(
]*>.*
]*>.*
)
151 | end
152 |
153 | it "should return the files" do
154 | subject.send(:parse_file_tree, @tree, true).should =~
155 | %r(
)
156 | end
157 |
158 | it "should return the path of the files" do
159 | subject.send(:parse_file_tree, @tree, true).should =~
160 | %r(
)
161 | end
162 |
163 | it "should return the elapsed time of the files" do
164 | subject.send(:parse_file_tree, @tree, true).should =~
165 | %r(
)
166 | end
167 | end
168 |
169 | describe "#file_tree" do
170 | it { should respond_to :file_tree }
171 |
172 | it "should return a div with id root" do
173 | regex = %r(.*root.*name.*elapsed_time.*nested_folder.*files.*file_under_folder(1|2).*files.*file(1|2).*)
174 |
175 | subject.file_tree(@files).should =~ regex
176 | end
177 | end
178 | end
179 | end
180 | end
181 | end
--------------------------------------------------------------------------------
/lib/watch_tower/cli/install.rb:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 |
3 | module WatchTower
4 | module CLI
5 | module Install
6 |
7 | def self.included(base)
8 | base.send :include, InstanceMethods
9 | end
10 |
11 | module InstanceMethods
12 | def self.included(base)
13 | base.class_eval <<-END, __FILE__, __LINE__ + 1
14 | # This module needs Thor::Actions
15 | include ::Thor::Actions
16 |
17 | # Mappings (aliases)
18 | map "-i" => :install
19 |
20 | # Install WatchTower
21 | desc "install", "Install Watch Tower"
22 | def install
23 | # Install the configuration file
24 | install_config_file
25 | # Install the bootloader
26 | install_bootloader
27 | end
28 |
29 | # Install bootloader
30 | desc "install_bootloader", "Install Watch Tower's bootloader"
31 | method_option :force,
32 | type: :boolean,
33 | required: false,
34 | aliases: "-f",
35 | default: false,
36 | desc: "Force the installation of the bootloader"
37 | def install_bootloader
38 | # Install the bootloader
39 | install_bootloader_on_os
40 | end
41 |
42 | # Load bootloader
43 | desc "load_bootloader", "Load Watch Tower's bootloader"
44 | def load_bootloader
45 | # Load the bootloader
46 | load_bootloader_on_os
47 | end
48 |
49 | # Unload bootloader
50 | desc "unload_bootloader", "Unload Watch Tower's bootloader"
51 | def unload_bootloader
52 | # Unload the bootloader
53 | unload_bootloader_on_os
54 | end
55 |
56 | # Load bootloader
57 | desc "reload_bootloader", "Reload Watch Tower's bootloader"
58 | def reload_bootloader
59 | # Reload the bootloader
60 | reload_bootloader_on_os
61 | end
62 |
63 | protected
64 | # Install the configuration file
65 | def install_config_file
66 | self.class.source_root(TEMPLATE_PATH)
67 | copy_file 'config.yml', File.join(USER_PATH, 'config.yml')
68 | end
69 |
70 | # Install bootloader
71 | def install_bootloader_on_os
72 | require 'rbconfig'
73 | case RbConfig::CONFIG['target_os']
74 | when /darwin/
75 | install_bootloader_on_mac
76 | when /linux/
77 | install_bootloader_on_linux
78 | else
79 | puts bootloader_not_supported_on_current_os
80 | end
81 | end
82 |
83 | # Install bootloader on Mac OS X
84 | def install_bootloader_on_mac
85 | self.class.source_root(TEMPLATE_PATH)
86 | create_file bootloader_path_on_mac, force: options[:force] do
87 | template = File.expand_path(find_in_source_paths('watchtower.plist.erb'))
88 | ERB.new(File.read(template)).result(binding)
89 | end
90 |
91 | puts "\nCreated. Now run:\n watchtower load_bootloader\n\n"
92 | end
93 |
94 | # Install bootloader on linux
95 | def install_bootloader_on_linux
96 | require 'cronedit'
97 | # Remove any old entries
98 | uninstall_bootloader_on_linux
99 | # Define the crontab command
100 | crontab_command = "\#{ruby_binary} \#{watch_tower_binary} start --bootloader"
101 | # Create a crontab instance
102 | crontab = CronEdit::Crontab.new
103 | # Add the command
104 | crontab.add Time.now.strftime('%s'), { minute: "@reboot", hour: '', day: '', month: '', weekday: '', command: crontab_command }
105 | # Commit changes
106 | crontab.commit
107 | end
108 |
109 | # Uninstall bootloader on linux
110 | def uninstall_bootloader_on_linux
111 | require 'cronedit'
112 | # Create a crontab instance
113 | crontab = CronEdit::Crontab.new
114 | # Iterate over crontab entries and remove any command having watchtower start
115 | crontab.list.each_pair do |k, c|
116 | if c =~ /watchtower start/
117 | crontab.remove(k)
118 | end
119 | end
120 | # Commit changes
121 | crontab.commit
122 | end
123 |
124 | # Returns the absolute path to the ruby binary
125 | #
126 | # @return [String] The path to ruby
127 | def ruby_binary
128 | WatchTower.which('ruby')
129 | end
130 |
131 | # Returns the absolute path to the watchtower binary
132 | #
133 | # @return [String] The path to watch tower binary
134 | def watch_tower_binary
135 | File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'bin', 'watchtower'))
136 | end
137 |
138 | # Load bootloader
139 | def load_bootloader_on_os
140 | require 'rbconfig'
141 | case RbConfig::CONFIG['target_os']
142 | when /darwin/
143 | load_bootloader_on_mac
144 | else
145 | puts bootloader_not_supported_on_current_os
146 | end
147 | end
148 |
149 | # Unload bootloader
150 | def unload_bootloader_on_os
151 | require 'rbconfig'
152 | case RbConfig::CONFIG['target_os']
153 | when /darwin/
154 | unload_bootloader_on_mac
155 | else
156 | puts bootloader_not_supported_on_current_os
157 | end
158 | end
159 |
160 | # Reload bootloader
161 | def reload_bootloader_on_os
162 | require 'rbconfig'
163 | case RbConfig::CONFIG['target_os']
164 | when /darwin/
165 | reload_bootloader_on_mac
166 | else
167 | puts bootloader_not_supported_on_current_os
168 | end
169 | end
170 | # Load the bootloader
171 | def load_bootloader_on_mac
172 | system "launchctl load \#{bootloader_path_on_mac}"
173 | end
174 |
175 | # Unload the bootloader
176 | def unload_bootloader_on_mac
177 | system "launchctl unload \#{bootloader_path_on_mac}"
178 | end
179 |
180 | # Reload the bootloader
181 | def reload_bootloader_on_mac
182 | # Unload bootloader
183 | unload_bootloader_on_mac
184 | # Load bootloader
185 | load_bootloader_on_mac
186 | end
187 |
188 | # Returns the path of the bootloader on mac
189 | #
190 | # @return [String] The path to the bootloader
191 | def bootloader_path_on_mac
192 | File.join(ENV['HOME'], 'Library', 'LaunchAgents', 'fr.technogate.WatchTower.plist')
193 | end
194 |
195 | def bootloader_not_supported_on_current_os
196 | <<-MSG
197 | WatchTower bootloader is not supported on your OS, you'd have to run it manually
198 | for the time being. Support for many editors and many OSes is planned for the
199 | future, if you would like to help, or drop in an issue please don't hesitate to
200 | do so on the project's Github page: https://github.com/TechnoGate/watch_tower
201 | MSG
202 | end
203 | END
204 | end
205 | end
206 | end
207 | end
208 | end
209 |
--------------------------------------------------------------------------------
/spec/watch_tower/editor/vim_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | def mock_pipe(out)
4 | pipe = mock
5 | pipe.stubs(:read).returns(out)
6 | pipe.stubs(:close)
7 | pipe
8 | end
9 |
10 | module Editor
11 | describe Vim do
12 | before(:each) do
13 | # Stubs which
14 | WatchTower.stubs(:which).with('vim').returns('/usr/bin/vim')
15 | WatchTower.stubs(:which).with('gvim').returns('/usr/bin/gvim')
16 | WatchTower.stubs(:which).with('mvim').returns(nil)
17 |
18 | # Stub systemu
19 | Open3.stubs(:popen2).with("/usr/bin/vim --help").returns([mock_pipe(""), mock_pipe(""), mock_pipe("")])
20 | Open3.stubs(:popen2).with("/usr/bin/gvim --help").returns([mock_pipe(""), mock_pipe("--remote-send"), mock_pipe("")])
21 | Open3.stubs(:popen2).with("/usr/bin/gvim --servername VIM --remote-send ':source #{Vim::VIM_EXTENSION_PATH}
'").returns([mock_pipe(""), mock_pipe(""), mock_pipe("")])
22 | Open3.stubs(:popen3).with("/usr/bin/gvim --servername VIM --remote-expr 'watchtower#ls()'").returns([mock_pipe(""), mock_pipe(<<-EOS), mock_pipe('')])
23 | /path/to/file.rb
24 | EOS
25 | Open3.stubs(:popen2).with('/usr/bin/gvim --serverlist').yields([mock_pipe(""), mock_pipe(<<-EOC), mock_pipe('')])
26 | VIM
27 | EOC
28 | version_output = <<-EOV
29 | VIM - Vi IMproved 7.3 (2010 Aug 15)
30 | Included patches: 1-202, 204-222, 224-322
31 | Compiled by 'http://www.opensuse.org/'
32 | Huge version without GUI. Features included (+) or not (-):
33 | +arabic +autocmd -balloon_eval -browse ++builtin_terms +byte_offset +cindent
34 | -clientserver -clipboard +cmdline_compl +cmdline_hist +cmdline_info +comments
35 | +conceal +cryptv +cscope +cursorbind +cursorshape +dialog_con +diff +digraphs
36 | -dnd -ebcdic +emacs_tags +eval +ex_extra +extra_search +farsi +file_in_path
37 | +find_in_path +float +folding -footer +fork() +gettext -hangul_input +iconv
38 | +insert_expand +jumplist +keymap +langmap +libcall +linebreak +lispindent
39 | +listcmds +localmap -lua +menu +mksession +modify_fname +mouse -mouseshape
40 | +mouse_dec -mouse_gpm -mouse_jsbterm +mouse_netterm -mouse_sysmouse
41 | +mouse_xterm +multi_byte +multi_lang -mzscheme +netbeans_intg +path_extra -perl
42 | +persistent_undo +postscript +printer +profile -python -python3 +quickfix
43 | +reltime +rightleft -ruby +scrollbind +signs +smartindent +sniff +startuptime
44 | +statusline -sun_workshop +syntax +tag_binary +tag_old_static -tag_any_white
45 | -tcl +terminfo +termresponse +textobjects +title -toolbar +user_commands
46 | +vertsplit +virtualedit +visual +visualextra +viminfo +vreplace +wildignore
47 | +wildmenu +windows +writebackup -X11 -xfontset -xim -xsmp -xterm_clipboard
48 | -xterm_save
49 | system vimrc file: "/etc/vimrc"
50 | user vimrc file: "$HOME/.vimrc"
51 | user exrc file: "$HOME/.exrc"
52 | fall-back for $VIM: "/etc"
53 | f-b for $VIMRUNTIME: "/usr/share/vim/current"
54 | Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -I/usr/local/include -fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -g -Wall -pipe -fno-strict-aliasing -fstack-protector-all
55 | Linking: gcc -L/usr/local/lib -Wl,--as-needed -o vim -lm -lnsl -lncurses -lacl -lattr -ldl
56 | EOV
57 |
58 | Open3.stubs(:popen2).with("/usr/bin/vim --version").
59 | yields [mock_pipe(""), mock_pipe(version_output), mock_pipe('')]
60 | Open3.stubs(:popen2).with("/usr/bin/gvim --version").
61 | yields [mock_pipe(""), mock_pipe(version_output), mock_pipe('')]
62 | end
63 |
64 | it { should respond_to :name }
65 | its(:name) { should_not raise_error NotImplementedError }
66 | its(:name) { should_not be_empty }
67 |
68 | describe "#fetch_version" do
69 | it { should respond_to :fetch_version }
70 |
71 | it "should be called on initialize" do
72 | Vim.any_instance.expects(:fetch_version).once
73 | Vim.new
74 | end
75 |
76 | it "should return 7.3" do
77 | subject.send(:fetch_version).should == '7.3'
78 | end
79 | end
80 |
81 | it { should respond_to :version }
82 | its(:version) { should_not raise_error NotImplementedError }
83 | its(:version) { should_not be_empty }
84 | its(:version) { should == '7.3' }
85 |
86 | describe "#supported_vims" do
87 | it { should respond_to :supported_vims }
88 |
89 | it "should return gvim" do
90 | WatchTower.expects(:which).with('vim').returns('/usr/bin/vim').once
91 | WatchTower.expects(:which).with('gvim').returns('/usr/bin/gvim').once
92 | WatchTower.expects(:which).with('mvim').returns(nil).once
93 | Open3.expects(:popen2).with("/usr/bin/vim --help").returns([mock_pipe(""), mock_pipe(""), mock_pipe("")]).once
94 | Open3.expects(:popen2).with("/usr/bin/gvim --help").returns([mock_pipe(""), mock_pipe("--remote-send"), mock_pipe("")]).once
95 |
96 | subject.send :supported_vims
97 | subject.instance_variable_get('@vims').should == ['/usr/bin/gvim']
98 | end
99 | end
100 |
101 | describe "#editor" do
102 | it { should respond_to :editor }
103 |
104 | it "should return /usr/bin/gvim" do
105 | subject.send(:editor).should == '/usr/bin/gvim'
106 | end
107 |
108 | it "should return nil if @vims is []" do
109 | subject.instance_variable_set('@vims', [])
110 |
111 | subject.send(:editor).should == nil
112 | end
113 |
114 | it "should return nil if @vims is nil" do
115 | subject.instance_variable_set('@vims', nil)
116 |
117 | subject.send(:editor).should == nil
118 | end
119 | end
120 |
121 | describe "#servers" do
122 | it { should respond_to :servers }
123 |
124 | it "should return VIM" do
125 | Open3.expects(:popen2).with('/usr/bin/gvim --serverlist').yields([mock_pipe(""), mock_pipe(<<-EOC), mock_pipe('')]).once
126 | VIM
127 | EOC
128 | subject.send(:servers).should == ['VIM']
129 | end
130 | end
131 |
132 | describe "#send_extensions_to_editor" do
133 | it { should respond_to :send_extensions_to_editor }
134 |
135 | it "should send the extensions to vim" do
136 | Open3.expects(:popen2).with("/usr/bin/gvim --servername VIM --remote-send ':source #{Vim::VIM_EXTENSION_PATH}'").once
137 |
138 | subject.send :send_extensions_to_editor
139 | end
140 | end
141 |
142 | describe "#is_running?" do
143 | it { should respond_to :is_running? }
144 |
145 | it "should return true if ViM is running" do
146 | subject.is_running?.should be_true
147 | end
148 |
149 | it "should return false if servers is []" do
150 | Vim.any_instance.stubs(:servers).returns([])
151 |
152 | subject.is_running?.should be_false
153 | end
154 |
155 | it "should return false if servers is nil" do
156 | Vim.any_instance.stubs(:servers).returns(nil)
157 |
158 | subject.is_running?.should be_false
159 | end
160 | end
161 |
162 | describe "#current_paths" do
163 | it { should respond_to :current_paths }
164 |
165 | it "should call is_running?" do
166 | Vim.any_instance.expects(:is_running?).returns(false).once
167 |
168 | subject.current_paths
169 | end
170 |
171 | it "should not call send_extensions_to_editor if the function is already loaded" do
172 | Vim.any_instance.expects(:send_extensions_to_editor).never
173 |
174 | subject.current_paths
175 | end
176 |
177 | it "should call send_extensions_to_editor only if the remote did not evaluate the command" do
178 | Open3.expects(:popen3).with("/usr/bin/gvim --servername VIM --remote-expr 'watchtower#ls()'").returns([mock_pipe(""), mock_pipe(""), mock_pipe(<<-EOS)]).twice
179 | E449: Invalid expression received: Send expression failed.
180 | EOS
181 | Vim.any_instance.expects(:send_extensions_to_editor).once
182 |
183 | subject.current_paths
184 | end
185 |
186 | it "should be nil if is_running? is false" do
187 | Vim.any_instance.stubs(:is_running?).returns(false)
188 |
189 | subject.current_paths.should be_nil
190 | end
191 |
192 | it "should be able to parse ls output" do
193 | Open3.expects(:popen3).with("/usr/bin/gvim --servername VIM --remote-expr 'watchtower#ls()'").returns([mock_pipe(""), mock_pipe(<<-EOS), mock_pipe('')]).once
194 | /path/to/file.rb
195 | /path/to/file2.rb
196 | EOS
197 |
198 | documents = subject.current_paths
199 | documents.should include("/path/to/file.rb")
200 | documents.should include("/path/to/file2.rb")
201 | end
202 |
203 | it "should not return duplicate documents" do
204 | Open3.expects(:popen3).with("/usr/bin/gvim --servername VIM --remote-expr 'watchtower#ls()'").returns([mock_pipe(""), mock_pipe(<<-EOS), mock_pipe('')]).once
205 | /path/to/file.rb
206 | /path/to/file.rb
207 | /path/to/file.rb
208 | /path/to/file.rb
209 | /path/to/file.rb
210 | EOS
211 |
212 | documents = subject.current_paths
213 | documents.should include("/path/to/file.rb")
214 | documents.size.should == 1
215 | end
216 | end
217 |
218 | end
219 | end
220 |
--------------------------------------------------------------------------------