watch_tower 0.0.0.1 → 0.0.1.beta1

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.
Files changed (106) hide show
  1. data/.todo +3 -0
  2. data/.travis.yml +4 -0
  3. data/Gemfile +0 -4
  4. data/README.md +48 -2
  5. data/TODO +3 -0
  6. data/ci/travis.rb +4 -1
  7. data/lib/watch_tower/appscript.rb +65 -7
  8. data/lib/watch_tower/cli/install.rb +27 -3
  9. data/lib/watch_tower/cli/open.rb +2 -0
  10. data/lib/watch_tower/cli/start.rb +3 -1
  11. data/lib/watch_tower/cli.rb +2 -0
  12. data/lib/watch_tower/config.rb +2 -0
  13. data/lib/watch_tower/core_ext.rb +2 -0
  14. data/lib/watch_tower/editor/base_appscript.rb +28 -1
  15. data/lib/watch_tower/editor/base_ps.rb +25 -0
  16. data/lib/watch_tower/editor/textmate.rb +2 -0
  17. data/lib/watch_tower/editor/xcode.rb +2 -0
  18. data/lib/watch_tower/editor.rb +2 -0
  19. data/lib/watch_tower/errors.rb +2 -0
  20. data/lib/watch_tower/eye.rb +13 -2
  21. data/lib/watch_tower/file_tree.rb +78 -0
  22. data/lib/watch_tower/project/any_based.rb +2 -0
  23. data/lib/watch_tower/project/git_based.rb +2 -0
  24. data/lib/watch_tower/project/init.rb +2 -0
  25. data/lib/watch_tower/project/path_based.rb +2 -0
  26. data/lib/watch_tower/project.rb +2 -0
  27. data/lib/watch_tower/server/app.rb +37 -7
  28. data/lib/watch_tower/server/assets/javascripts/application.js +4 -0
  29. data/lib/watch_tower/server/assets/javascripts/datepicker.coffee +21 -0
  30. data/lib/watch_tower/server/assets/javascripts/file_tree.coffee +30 -0
  31. data/lib/watch_tower/server/assets/javascripts/percentage.coffee +15 -5
  32. data/lib/watch_tower/server/assets/stylesheets/application.css +1 -0
  33. data/lib/watch_tower/server/assets/stylesheets/date.sass +17 -0
  34. data/lib/watch_tower/server/assets/stylesheets/file_tree.sass +42 -0
  35. data/lib/watch_tower/server/assets/stylesheets/global.sass +7 -4
  36. data/lib/watch_tower/server/configurations/asset.rb +2 -0
  37. data/lib/watch_tower/server/configurations.rb +2 -0
  38. data/lib/watch_tower/server/database.rb +2 -0
  39. data/lib/watch_tower/server/db/migrate/001_create_projects.rb +2 -0
  40. data/lib/watch_tower/server/db/migrate/002_create_files.rb +2 -0
  41. data/lib/watch_tower/server/db/migrate/003_create_time_entries.rb +2 -0
  42. data/lib/watch_tower/server/db/migrate/004_create_durations.rb +2 -0
  43. data/lib/watch_tower/server/db/migrate/005_add_hash_to_time_entries.rb +2 -0
  44. data/lib/watch_tower/server/db/migrate/006_add_hash_to_files.rb +2 -0
  45. data/lib/watch_tower/server/db/migrate/007_add_editor_to_times_entries.rb +8 -0
  46. data/lib/watch_tower/server/db/migrate/008_rename_editor_to_editor_name_in_times_entries.rb +5 -0
  47. data/lib/watch_tower/server/db/migrate/009_remove_editor_index_from_time_entries.rb +7 -0
  48. data/lib/watch_tower/server/db/migrate/010_add_editor_version_to_times_entries.rb +7 -0
  49. data/lib/watch_tower/server/helpers/asset.rb +2 -0
  50. data/lib/watch_tower/server/helpers/improved_partials.rb +2 -0
  51. data/lib/watch_tower/server/helpers/presenters.rb +33 -0
  52. data/lib/watch_tower/server/helpers.rb +3 -0
  53. data/lib/watch_tower/server/models/duration.rb +9 -0
  54. data/lib/watch_tower/server/models/file.rb +17 -0
  55. data/lib/watch_tower/server/models/project.rb +30 -0
  56. data/lib/watch_tower/server/models/time_entry.rb +5 -0
  57. data/lib/watch_tower/server/presenters/application_presenter.rb +165 -0
  58. data/lib/watch_tower/server/presenters/file_presenter.rb +10 -0
  59. data/lib/watch_tower/server/presenters/project_presenter.rb +20 -0
  60. data/lib/watch_tower/server/presenters.rb +13 -0
  61. data/lib/watch_tower/server/public/assets/{WatchTower-4d6de11e1bd34165ad91ac46fb711bf3.jpg → WatchTower-58eff0713efffbc6054defddc879e0b1.jpg} +0 -0
  62. data/lib/watch_tower/server/public/assets/application-4e6971066e06aa53b0c8e52c764044d1.css +389 -0
  63. data/lib/watch_tower/server/public/assets/application-6a1be75d4fd6a545faceb638e47a2486.js +23778 -0
  64. data/lib/watch_tower/server/public/assets/calendar-379834cd6e6321a940b662ace47f3032.gif +0 -0
  65. data/lib/watch_tower/server/public/assets/calendar-blue-d6aa74feef7ee4287532761db99a6c0a.gif +0 -0
  66. data/lib/watch_tower/server/public/assets/calendar-green-3752fe2996091379c8d321f759039385.gif +0 -0
  67. data/lib/watch_tower/server/public/assets/jquery.datepick-9c8dfe3a4d40bcafc7b182e194c13836.css +227 -0
  68. data/lib/watch_tower/server/public/assets/{percentage-d8589e21a5fc85d32a445f531ff8ab95.png → percentage-d0176e99520c95e93eee63738ef5d487.png} +0 -0
  69. data/lib/watch_tower/server/vendor/assets/images/calendar-blue.gif +0 -0
  70. data/lib/watch_tower/server/vendor/assets/images/calendar-green.gif +0 -0
  71. data/lib/watch_tower/server/vendor/assets/images/calendar.gif +0 -0
  72. data/lib/watch_tower/server/vendor/assets/javascripts/jquery-datepick-ext.js +266 -0
  73. data/lib/watch_tower/server/vendor/assets/javascripts/jquery-datepick-validation.js +232 -0
  74. data/lib/watch_tower/server/vendor/assets/javascripts/jquery-datepick.js +2092 -0
  75. data/lib/watch_tower/server/vendor/assets/stylesheets/jquery.datepick.css +226 -0
  76. data/lib/watch_tower/server/views/_project.haml +10 -13
  77. data/lib/watch_tower/server/views/index.haml +9 -6
  78. data/lib/watch_tower/server/views/layout.haml +7 -4
  79. data/lib/watch_tower/server/views/project.haml +9 -11
  80. data/lib/watch_tower/server.rb +8 -1
  81. data/lib/watch_tower/templates/{watchtower.plist → watchtower.plist.erb} +5 -6
  82. data/lib/watch_tower/version.rb +12 -3
  83. data/lib/watch_tower.rb +20 -1
  84. data/spec/factories.rb +2 -0
  85. data/spec/watch_tower/appscript_spec.rb +36 -2
  86. data/spec/watch_tower/editor/base_appscript_spec.rb +83 -0
  87. data/spec/watch_tower/editor/textmate_spec.rb +37 -0
  88. data/spec/watch_tower/editor/xcode_spec.rb +6 -0
  89. data/spec/watch_tower/eye_spec.rb +21 -0
  90. data/spec/watch_tower/file_tree_spec.rb +156 -0
  91. data/spec/watch_tower/server/app_spec.rb +64 -20
  92. data/spec/watch_tower/server/models/file_spec.rb +93 -31
  93. data/spec/watch_tower/server/models/project_spec.rb +147 -18
  94. data/spec/watch_tower/server/models/time_entry_spec.rb +10 -0
  95. data/spec/watch_tower/server/{decorator/project_decorator_spec.rb → presenters/application_presenter_spec.rb} +24 -13
  96. data/spec/watch_tower/server/presenters/file_presenter_spec.rb +8 -0
  97. data/spec/watch_tower/server/presenters/project_presenter_spec.rb +130 -0
  98. data/watch_tower.gemspec +10 -4
  99. metadata +114 -74
  100. data/lib/watch_tower/server/decorator/application_decorator.rb +0 -91
  101. data/lib/watch_tower/server/decorator/file_decorator.rb +0 -38
  102. data/lib/watch_tower/server/decorator/project_decorator.rb +0 -51
  103. data/lib/watch_tower/server/decorator.rb +0 -21
  104. data/lib/watch_tower/server/public/assets/application-7829b53b5ece1a16d22dc3d00f329023.css +0 -107
  105. data/lib/watch_tower/server/public/assets/application-e0e6b7731aade460f680331e65cf0682.js +0 -9359
  106. data/lib/watch_tower/server/views/_file.haml +0 -9
@@ -0,0 +1,226 @@
1
+ /* Default styling for jQuery Datepicker v4.0.6. */
2
+ .datepick {
3
+ background-color: #fff;
4
+ color: #000;
5
+ border: 1px solid #444;
6
+ border-radius: 0.25em;
7
+ -moz-border-radius: 0.25em;
8
+ -webkit-border-radius: 0.25em;
9
+ font-family: Arial,Helvetica,Sans-serif;
10
+ font-size: 90%;
11
+ }
12
+ .datepick-rtl {
13
+ direction: rtl;
14
+ }
15
+ .datepick-popup {
16
+ z-index: 1000;
17
+ }
18
+ .datepick-disable {
19
+ position: absolute;
20
+ z-index: 100;
21
+ background-color: white;
22
+ opacity: 0.5;
23
+ filter: alpha(opacity=50);
24
+ }
25
+ .datepick a {
26
+ color: #fff;
27
+ text-decoration: none;
28
+ }
29
+ .datepick a.datepick-disabled {
30
+ color: #888;
31
+ cursor: auto;
32
+ }
33
+ .datepick button {
34
+ margin: 0.25em;
35
+ padding: 0.125em 0em;
36
+ background-color: #fcc;
37
+ border: none;
38
+ border-radius: 0.25em;
39
+ -moz-border-radius: 0.25em;
40
+ -webkit-border-radius: 0.25em;
41
+ font-weight: bold;
42
+ }
43
+ .datepick-nav, .datepick-ctrl {
44
+ float: left;
45
+ width: 100%;
46
+ background-color: #000;
47
+ color: #fff;
48
+ font-size: 90%;
49
+ font-weight: bold;
50
+ }
51
+ .datepick-ctrl {
52
+ background-color: #600;
53
+ }
54
+ .datepick-cmd {
55
+ width: 30%;
56
+ }
57
+ .datepick-cmd:hover {
58
+ background-color: #777;
59
+ }
60
+ .datepick-ctrl .datepick-cmd:hover {
61
+ background-color: #f08080;
62
+ }
63
+ .datepick-cmd-prevJump, .datepick-cmd-nextJump {
64
+ width: 8%;
65
+ }
66
+ a.datepick-cmd {
67
+ height: 1.5em;
68
+ }
69
+ button.datepick-cmd {
70
+ text-align: center;
71
+ }
72
+ .datepick-cmd-prev, .datepick-cmd-prevJump, .datepick-cmd-clear {
73
+ float: left;
74
+ padding-left: 2%;
75
+ }
76
+ .datepick-cmd-current, .datepick-cmd-today {
77
+ float: left;
78
+ width: 35%;
79
+ text-align: center;
80
+ }
81
+ .datepick-cmd-next, .datepick-cmd-nextJump, .datepick-cmd-close {
82
+ float: right;
83
+ padding-right: 2%;
84
+ text-align: right;
85
+ }
86
+ .datepick-rtl .datepick-cmd-prev, .datepick-rtl .datepick-cmd-prevJump,
87
+ .datepick-rtl .datepick-cmd-clear {
88
+ float: right;
89
+ padding-left: 0%;
90
+ padding-right: 2%;
91
+ text-align: right;
92
+ }
93
+ .datepick-rtl .datepick-cmd-current, .datepick-rtl .datepick-cmd-today {
94
+ float: right;
95
+ }
96
+ .datepick-rtl .datepick-cmd-next, .datepick-rtl .datepick-cmd-nextJump,
97
+ .datepick-rtl .datepick-cmd-close {
98
+ float: left;
99
+ padding-left: 2%;
100
+ padding-right: 0%;
101
+ text-align: left;
102
+ }
103
+ .datepick-month-nav {
104
+ float: left;
105
+ background-color: #777;
106
+ text-align: center;
107
+ }
108
+ .datepick-month-nav div {
109
+ float: left;
110
+ width: 12.5%;
111
+ margin: 1%;
112
+ padding: 1%;
113
+ }
114
+ .datepick-month-nav span {
115
+ color: #888;
116
+ }
117
+ .datepick-month-row {
118
+ clear: left;
119
+ }
120
+ .datepick-month {
121
+ float: left;
122
+ width: 15em;
123
+ border: 1px solid #444;
124
+ text-align: center;
125
+ }
126
+ .datepick-month-header, .datepick-month-header select, .datepick-month-header input {
127
+ height: 1.5em;
128
+ background-color: #444;
129
+ color: #fff;
130
+ font-weight: bold;
131
+ }
132
+ .datepick-month-header select, .datepick-month-header input {
133
+ height: 1.4em;
134
+ border: none;
135
+ }
136
+ .datepick-month-header input {
137
+ position: absolute;
138
+ display: none;
139
+ }
140
+ .datepick-month table {
141
+ width: 100%;
142
+ border-collapse: collapse;
143
+ }
144
+ .datepick-month thead {
145
+ border-bottom: 1px solid #aaa;
146
+ }
147
+ .datepick-month th, .datepick-month td {
148
+ margin: 0em;
149
+ padding: 0em;
150
+ font-weight: normal;
151
+ text-align: center;
152
+ }
153
+ .datepick-month th {
154
+ border: 1px solid #777;
155
+ }
156
+ .datepick-month th, .datepick-month th a {
157
+ background-color: #777;
158
+ color: #fff;
159
+ }
160
+ .datepick-month td {
161
+ background-color: #eee;
162
+ border: 1px solid #aaa;
163
+ }
164
+ .datepick-month td.datepick-week {
165
+ border: 1px solid #777;
166
+ }
167
+ .datepick-month td.datepick-week * {
168
+ background-color: #777;
169
+ color: #fff;
170
+ border: none;
171
+ }
172
+ .datepick-month a {
173
+ display: block;
174
+ width: 100%;
175
+ padding: 0.125em 0em;
176
+ background-color: #eee;
177
+ color: #000;
178
+ text-decoration: none;
179
+ }
180
+ .datepick-month span {
181
+ display: block;
182
+ width: 100%;
183
+ padding: 0.125em 0em;
184
+ }
185
+ .datepick-month td span {
186
+ color: #888;
187
+ }
188
+ .datepick-month td .datepick-other-month {
189
+ background-color: #fff;
190
+ }
191
+ .datepick-month td .datepick-weekend {
192
+ background-color: #ddd;
193
+ }
194
+ .datepick-month td .datepick-today {
195
+ background-color: #f0c0c0;
196
+ }
197
+ .datepick-month td .datepick-highlight {
198
+ background-color: #f08080;
199
+ }
200
+ .datepick-month td .datepick-selected {
201
+ background-color: #777;
202
+ color: #fff;
203
+ }
204
+ .datepick-month th.datepick-week {
205
+ background-color: #777;
206
+ color: #fff;
207
+ }
208
+ .datepick-status {
209
+ clear: both;
210
+ background-color: #ddd;
211
+ text-align: center;
212
+ }
213
+ .datepick-clear-fix {
214
+ clear: both;
215
+ }
216
+ .datepick-cover {
217
+ display: none;
218
+ display/**/: block;
219
+ position: absolute;
220
+ z-index: -1;
221
+ filter: mask();
222
+ top: -1px;
223
+ left: -1px;
224
+ width: 100px;
225
+ height: 100px;
226
+ }
@@ -1,13 +1,10 @@
1
- %article.project[project]
2
- .name
3
- %a{href: path_to(:project).with(project.id), alt: project.path}
4
- = project.name.camelcase
5
- .percentage_img_container
6
- .percentage
7
- -# TODO: Move this to the presenter after having resolved the presenter
8
- -# issues, in Draper I can't access helpers for some reason
9
- - max_elapsed = ::WatchTower::Server::Project.order('elapsed_time DESC').first.elapsed_time
10
- - percentage = (project.elapsed_time * 100 / max_elapsed).to_i rescue 100
11
- %img.percentage_img{src: asset_path('percentage.png'), 'data-width' => percentage}/
12
- .elapsed= project.elapsed
13
- .clearfix
1
+ - present project do |presenter|
2
+ %article.project[project]
3
+ .name
4
+ %a{href: path_to(:project).with(presenter.id), alt: presenter.path}
5
+ = presenter.name.camelcase
6
+ .percentage_img_container
7
+ .percentage
8
+ %img.percentage_img{src: asset_path('percentage.png'), alt: "#{presenter.percent}% of total time", 'data-width' => presenter.percent}/
9
+ .elapsed= presenter.elapsed(project.durations.date_range(session[:date_filtering][:from_date], session[:date_filtering][:to_date]).sum(:duration))
10
+ .clearfix
@@ -1,7 +1,10 @@
1
1
  %section#projects
2
- %header
3
- .name Project
4
- .percentage Percentage
5
- .elapsed Total time
6
- .clearfix
7
- = partial('project', collection: @projects)
2
+ - if @projects.any?
3
+ %header
4
+ .name Project
5
+ .percentage Percentage
6
+ .elapsed Total time
7
+ .clearfix
8
+ = partial('project', collection: @projects)
9
+ - else
10
+ No projects available for the selected date range.
@@ -8,6 +8,8 @@
8
8
  %meta{:charset => "utf-8"}/
9
9
  %meta{:content => "IE=edge,chrome=1", "http-equiv" => "X-UA-Compatible"}/
10
10
  %meta{:content => "width=device-width,initial-scale=1", :name => "viewport"}/
11
+ %meta{name: 'date_filtering_from', content: session[:date_filtering][:from_date] }/
12
+ %meta{name: 'date_filtering_to', content: session[:date_filtering][:to_date]}/
11
13
 
12
14
  / Link tags
13
15
  %link{:href => asset_path('application.css'), :rel => "stylesheet"}/
@@ -23,10 +25,11 @@
23
25
  %h1 Watch Tower
24
26
 
25
27
  %section#main
26
- = yield
28
+ %aside#date
29
+ %input{type: 'text'}
30
+ .page= yield
27
31
 
28
32
  %section#footer
29
- WatchTower
30
- -
31
- %a{href: 'http://www.technogate.fr'}
33
+ © Copyright 2011
34
+ %a{href: 'https://github.com/TechnoGate', target: '_blank'}
32
35
  TechnoGate
@@ -1,12 +1,10 @@
1
- %article#project
2
- %header
3
- %h1.project_name= @project.name.camelcase
4
- %h2.project_path= @project.path
5
- %section#files
1
+ - present @project do |presenter|
2
+ %article#project
6
3
  %header
7
- .path
8
- File path
9
- .elapsed
10
- Total Time
11
- .clearfix
12
- = partial('file', collection: FileDecorator.decorate(@project.files.worked_on))
4
+ %h1.project_name= presenter.name.camelcase
5
+ %h2.project_path= presenter.path
6
+ %section#files
7
+ - if @files.any?
8
+ = presenter.file_tree(@files)
9
+ - else
10
+ No files available for the selected date range.
@@ -1,3 +1,5 @@
1
+ # -*- encoding: utf-8 -*-
2
+
1
3
  module WatchTower
2
4
  module Server
3
5
  extend ::ActiveSupport::Autoload
@@ -9,7 +11,7 @@ module WatchTower
9
11
  autoload :TimeEntry, ::File.join(MODELS_PATH, 'time_entry.rb')
10
12
  autoload :Helpers
11
13
  autoload :Configurations
12
- autoload :Decorator
14
+ autoload :Presenters
13
15
  autoload :App
14
16
 
15
17
  # Start the server
@@ -45,6 +47,10 @@ module WatchTower
45
47
  WatchTower.threads[:web_server] = Thread.new do
46
48
  LOG.debug("#{__FILE__}:#{__LINE__}: Starting a new Thread for the web server.")
47
49
 
50
+ # Signal handling
51
+ Signal.trap("INT") { exit }
52
+ Signal.trap("TERM") { exit }
53
+
48
54
  begin
49
55
  LOG.debug("#{__FILE__}:#{__LINE__}: Starting the web server in the new Thread.")
50
56
 
@@ -52,6 +58,7 @@ module WatchTower
52
58
  App.run!(options)
53
59
 
54
60
  LOG.debug("#{__FILE__}:#{__LINE__}: The server has stopped.")
61
+ exit
55
62
  rescue Exception => e
56
63
  LOG.fatal "#{__FILE__}:#{__LINE__ - 4}: #{e}"
57
64
  raise e
@@ -4,19 +4,18 @@
4
4
  <dict>
5
5
  <key>Label</key>
6
6
  <string>fr.technogate.WatchTower</string>
7
-
8
- <key>Program</key>
9
- <string>watchtower</string>
10
-
11
7
  <key>ProgramArguments</key>
12
8
  <array>
9
+ <string><%= ruby_binary %></string>
10
+ <string><%= watch_tower_binary %></string>
13
11
  <string>start</string>
14
12
  <string>--bootloader</string>
13
+ <string>--foreground</string>
15
14
  </array>
16
-
15
+ <key>KeepAlive</key>
16
+ <true/>
17
17
  <key>OnDemand</key>
18
18
  <false/>
19
-
20
19
  <key>RunAtLoad</key>
21
20
  <true/>
22
21
  </dict>
@@ -1,8 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+
1
3
  module WatchTower
2
4
  MAJOR = 0
3
5
  MINOR = 0
4
- PATCH = 0
5
- PRE = 1
6
+ TINY = 1
7
+ PRE = "beta1"
6
8
 
7
- VERSION = [MAJOR, MINOR, PATCH, PRE].join('.')
9
+ def self.version
10
+ # Init the version
11
+ version = [MAJOR, MINOR, TINY]
12
+ # Add the pre if available
13
+ version << PRE unless PRE.nil? || PRE !~ /\S/
14
+ # Return the version joined by a dot
15
+ version.join('.')
16
+ end
8
17
  end
data/lib/watch_tower.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # -*- encoding: utf-8 -*-
2
+
1
3
  # RubyGems is needed at first
2
4
  require 'rubygems'
3
5
 
@@ -33,7 +35,7 @@ FileUtils.mkdir_p LOG_PATH
33
35
  module WatchTower
34
36
 
35
37
  # Create a logger
36
- LOG = Logger.new(File.join(LOG_PATH, 'watch_tower.log'))
38
+ LOG = Logger.new(File.join(LOG_PATH, "#{ENV['WATCH_TOWER_ENV']}.log"))
37
39
 
38
40
  # Threads
39
41
  # Hash
@@ -46,8 +48,24 @@ module WatchTower
46
48
  @@threads
47
49
  end
48
50
 
51
+ # Get WatchTower's environment
52
+ #
53
+ # @return [String] The current environment
54
+ def self.env
55
+ ENV['WATCH_TOWER_ENV']
56
+ end
57
+
58
+ # Set WatchTower's environment
59
+ #
60
+ # @param [String] The environment
61
+ def self.env=(environment)
62
+ ENV['WATCH_TOWER_ENV'] = environment
63
+ end
49
64
  end
50
65
 
66
+ # Make sure we are running UTF-8
67
+ Encoding.default_external = 'utf-8'
68
+
51
69
  # Require watch_tower's libraries
52
70
  require "watch_tower/version"
53
71
  require "watch_tower/errors"
@@ -57,4 +75,5 @@ require "watch_tower/cli"
57
75
  require "watch_tower/editor"
58
76
  require "watch_tower/project"
59
77
  require "watch_tower/eye"
78
+ require "watch_tower/file_tree"
60
79
  require "watch_tower/server"
data/spec/factories.rb CHANGED
@@ -13,6 +13,8 @@ FactoryGirl.define do
13
13
  factory :time_entry, class: Server::TimeEntry do
14
14
  file
15
15
  file_hash
16
+ editor_name "Textmate"
17
+ editor_version "1.5.10"
16
18
  mtime
17
19
  end
18
20
 
@@ -1,6 +1,40 @@
1
1
  require 'spec_helper'
2
2
  require 'watch_tower/appscript'
3
3
 
4
- describe ::Appscript do
5
- it { should be_kind_of(Module) }
4
+ module ::Appscript
5
+ describe "Module" do
6
+ subject do
7
+ Class.new do
8
+ extend ::Appscript
9
+ end
10
+ end
11
+ describe "#app" do
12
+
13
+ it { should respond_to :app }
14
+
15
+ it "should return an instance of Application" do
16
+ subject.app.should be_instance_of ::Appscript::Application
17
+ end
18
+ end
19
+
20
+ describe "#its" do
21
+ it { should respond_to :its }
22
+ end
23
+
24
+ describe "#name" do
25
+ it { should respond_to :name }
26
+ end
27
+ end
28
+
29
+ describe "Application" do
30
+ subject { ::Appscript.app('TextMate') }
31
+
32
+ [:name, :version, :processes, :unix_id, :by_pid, :is_running?].each do |method|
33
+ it "should respond to #{method}" do
34
+ -> {
35
+ subject.send(method)
36
+ }.should_not raise_error NoMethodError
37
+ end
38
+ end
39
+ end
6
40
  end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ module Editor
4
+ describe BaseAppscript do
5
+
6
+ subject do
7
+ Class.new do
8
+ include BaseAppscript
9
+ end.new
10
+ end
11
+
12
+ before(:each) do
13
+ @editor = mock
14
+ @editor.stubs(:is_running?).returns(true)
15
+ @documents = mock
16
+ @document = mock
17
+ @file_path = '/path/to/file.rb'
18
+ @path = mock
19
+ @path.stubs(:get).returns(@file_path)
20
+ @document.stubs(:path).returns(@path)
21
+ @documents.stubs(:get).returns([@document])
22
+ @editor.stubs(:document).returns(@documents)
23
+
24
+ subject.class.any_instance.stubs(:editor).returns(@editor)
25
+ end
26
+
27
+ describe "#is_running" do
28
+ it "should return true if the editor is running" do
29
+ @editor.expects(:is_running?).returns(true).once
30
+
31
+ subject.is_running?.should be_true
32
+ end
33
+
34
+ it "should return false if the editor is running" do
35
+ @editor.expects(:is_running?).returns(false).once
36
+
37
+ subject.is_running?.should be_false
38
+ end
39
+ end
40
+
41
+ describe "#cuurent_path" do
42
+ it { should respond_to :current_path }
43
+
44
+ it "should return the current_path if textmate running" do
45
+ @path.expects(:get).returns(@file_path).once
46
+ @document.expects(:path).returns(@path).once
47
+ @documents.expects(:get).returns([@document]).once
48
+
49
+ subject.current_path.should == @file_path
50
+ end
51
+
52
+ it "should return nil if textmate ain't running" do
53
+ @editor.stubs(:is_running?).returns(false)
54
+
55
+ subject.current_path.should be_nil
56
+ end
57
+ end
58
+
59
+ describe "#cuurent_path" do
60
+ it { should respond_to :current_paths }
61
+
62
+ it "should return the current_paths if textmate running" do
63
+ @path.expects(:get).returns(@file_path).once
64
+ @document.expects(:path).returns(@path).once
65
+ @documents.expects(:get).returns([@document]).once
66
+
67
+ subject.current_paths.should == [@file_path]
68
+ end
69
+
70
+ it "should return nil if textmate ain't running" do
71
+ @editor.stubs(:is_running?).returns(false)
72
+
73
+ subject.current_paths.should be_nil
74
+ end
75
+
76
+ it "should return nil if the application does not respond to document" do
77
+ @editor.stubs(:respond_to?).with(:document).returns(false)
78
+
79
+ subject.current_paths.should be_nil
80
+ end
81
+ end
82
+ end
83
+ end
@@ -4,6 +4,12 @@ module Editor
4
4
  describe Textmate do
5
5
  it { should respond_to :current_path }
6
6
 
7
+ it { should respond_to :name }
8
+ its(:name) { should_not raise_error NotImplementedError }
9
+
10
+ it { should respond_to :version }
11
+ its(:version) { should_not raise_error NotImplementedError }
12
+
7
13
  describe "#is_running?" do
8
14
  it { should respond_to :is_running? }
9
15
 
@@ -14,6 +20,10 @@ module Editor
14
20
 
15
21
  subject.is_running?.should be_true
16
22
  end
23
+ end
24
+
25
+ describe "#cuurent_path" do
26
+ it { should respond_to :current_path }
17
27
 
18
28
  it "should return the current_path if textmate running" do
19
29
  app = mock()
@@ -37,7 +47,34 @@ module Editor
37
47
 
38
48
  subject.current_path.should be_nil
39
49
  end
50
+ end
51
+
52
+ describe "#cuurent_path" do
53
+ it { should respond_to :current_paths }
54
+
55
+ it "should return the current_paths if textmate running" do
56
+ app = mock()
57
+ app.expects(:is_running?).returns(true).once
58
+ documents = mock
59
+ document = mock
60
+ path = mock
61
+ path.expects(:get).returns('/path/to/file.rb')
62
+ document.expects(:path).returns(path).once
63
+ documents.expects(:get).returns([document]).once
64
+ app.expects(:document).returns(documents).once
65
+ Textmate.any_instance.stubs(:editor).returns(app)
66
+
67
+ subject.current_paths.should == ['/path/to/file.rb']
68
+ end
40
69
 
70
+ it "should return nil if textmate ain't running" do
71
+ app = mock()
72
+ app.expects(:is_running?).returns(false).once
73
+ Textmate.any_instance.stubs(:editor).returns(app)
74
+
75
+ subject.current_paths.should be_nil
76
+ end
41
77
  end
78
+
42
79
  end
43
80
  end
@@ -4,6 +4,12 @@ module Editor
4
4
  describe Xcode do
5
5
  it { should respond_to :current_path }
6
6
 
7
+ it { should respond_to :name }
8
+ pending(:name) { should_not raise_error NotImplementedError }
9
+
10
+ it { should respond_to :version }
11
+ pending(:version) { should_not raise_error NotImplementedError }
12
+
7
13
  describe "#is_running?" do
8
14
  it { should respond_to :is_running? }
9
15
 
@@ -9,12 +9,15 @@ describe Eye do
9
9
  @file_path = '/home/user/Code/OpenSource/watch_tower/lib/watch_tower/server/models/time_entries.rb'
10
10
  @project_path = '/home/user/Code/OpenSource/watch_tower'
11
11
  @project_name = 'watch_tower'
12
+ ::File.stubs(:exists?).with(@file_path).returns(true)
12
13
 
13
14
  # Mock the editor
14
15
  @editor = mock
15
16
  @editor.stubs(:new).returns(@editor)
16
17
  @editor.stubs(:is_running?).returns(true)
17
18
  @editor.stubs(:current_paths).returns([@file_path])
19
+ @editor.stubs(:name).returns("Textmate")
20
+ @editor.stubs(:version).returns("1.5.10")
18
21
  Editor.stubs(:editors).returns([@editor])
19
22
 
20
23
  # Mock the project
@@ -65,6 +68,12 @@ describe Eye do
65
68
  subject.start
66
69
  end
67
70
 
71
+ it "should call File.exists?" do
72
+ ::File.expects(:exists?).with(@file_path).returns(true).once
73
+
74
+ subject.start
75
+ end
76
+
68
77
  it "should get the file's hash from Digest::SHA1" do
69
78
  Digest::SHA1.expects(:file).with(@file_path).returns(@file_hash).once
70
79
 
@@ -99,6 +108,18 @@ describe Eye do
99
108
 
100
109
  subject.start
101
110
  end
111
+
112
+ it "should ask the editor for the name" do
113
+ @editor.expects(:name).returns("Textmate").once
114
+
115
+ subject.start
116
+ end
117
+
118
+ it "should ask the editor for the version" do
119
+ @editor.expects(:version).returns("1.5.10").once
120
+
121
+ subject.start
122
+ end
102
123
  end
103
124
 
104
125
  describe "#start database validations" do