xmvc 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +63 -0
- data/VERSION +1 -0
- data/bin/xmvc +13 -0
- data/lib/xmvc/README +20 -0
- data/lib/xmvc/builder.rb +72 -0
- data/lib/xmvc/builders/all_builder.rb +13 -0
- data/lib/xmvc/builders/app_builder.rb +36 -0
- data/lib/xmvc/builders/base.rb +138 -0
- data/lib/xmvc/builders/css_builder.rb +34 -0
- data/lib/xmvc/builders/docs_builder.rb +20 -0
- data/lib/xmvc/builders/mvc_builder.rb +33 -0
- data/lib/xmvc/builders/plugin_builder.rb +53 -0
- data/lib/xmvc/cli.rb +58 -0
- data/lib/xmvc/environment.rb +9 -0
- data/lib/xmvc/generator.rb +79 -0
- data/lib/xmvc/generators/app.rb +94 -0
- data/lib/xmvc/generators/base.rb +90 -0
- data/lib/xmvc/generators/controller.rb +41 -0
- data/lib/xmvc/generators/model.rb +40 -0
- data/lib/xmvc/generators/scaffold.rb +15 -0
- data/lib/xmvc/generators/templates/Controller.js +10 -0
- data/lib/xmvc/generators/templates/Model.js +9 -0
- data/lib/xmvc/generators/templates/ModelSpec.js +12 -0
- data/lib/xmvc/generators/templates/View.js +17 -0
- data/lib/xmvc/generators/templates/_Action.js +7 -0
- data/lib/xmvc/generators/templates/app/README.rdoc +152 -0
- data/lib/xmvc/generators/templates/app/app/App.js +64 -0
- data/lib/xmvc/generators/templates/app/app/controllers/application_controller.js +10 -0
- data/lib/xmvc/generators/templates/app/app/controllers/home_controller.js +10 -0
- data/lib/xmvc/generators/templates/app/app/views/home/index.js +17 -0
- data/lib/xmvc/generators/templates/app/app/views/layout/menu.js +23 -0
- data/lib/xmvc/generators/templates/app/config/application.js +1 -0
- data/lib/xmvc/generators/templates/app/config/boot.js +66 -0
- data/lib/xmvc/generators/templates/app/config/database.js +4 -0
- data/lib/xmvc/generators/templates/app/config/environment.json +62 -0
- data/lib/xmvc/generators/templates/app/config/environments/development.json +1 -0
- data/lib/xmvc/generators/templates/app/config/environments/production.json +4 -0
- data/lib/xmvc/generators/templates/app/config/routes.js +27 -0
- data/lib/xmvc/generators/templates/app/config/settings.yml +3 -0
- data/lib/xmvc/generators/templates/app/public/index.html +19 -0
- data/lib/xmvc/generators/templates/app/public/stylesheets/extjs-mvc-all.css +49 -0
- data/lib/xmvc/generators/templates/app/spec/SpecHelper.js +0 -0
- data/lib/xmvc/generators/templates/app/spec/index.html +66 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/EXAMPLE.html +68 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/LICENSE +22 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/README.markdown +307 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/jquery-1.2.3.js +3408 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/jquery.fn.js +29 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/jquery.print.js +108 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.assets.js +36 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.behaviors.js +91 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.builder.js +80 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.css +90 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.events.js +42 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.matchers.js +145 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/lib/screw.server.js +21 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/spec/behaviors_spec.js +178 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/spec/matchers_spec.js +237 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/spec/print_spec.js +119 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/spec/spec_helper.js +0 -0
- data/lib/xmvc/generators/templates/app/vendor/screw-unit/spec/suite.html +18 -0
- data/lib/xmvc/generators/templates/scaffold/ScaffoldController.js +18 -0
- data/lib/xmvc/generators/view.rb +33 -0
- data/lib/xmvc/plugin.rb +102 -0
- data/lib/xmvc/settings.rb +75 -0
- data/lib/xmvc/stats.rb +259 -0
- data/lib/xmvc/test.rb +9 -0
- data/lib/xmvc/testserver.ru +95 -0
- data/lib/xmvc/ui.rb +55 -0
- data/lib/xmvc/update.rb +71 -0
- data/lib/xmvc.rb +79 -0
- data/test/helper.rb +10 -0
- data/test/test_extjs-core.rb +7 -0
- data/xmvc.gemspec +142 -0
- metadata +237 -0
data/lib/xmvc/plugin.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# Is this really required??
|
2
|
+
#
|
3
|
+
#require 'ftools'
|
4
|
+
module Xmvc
|
5
|
+
class Plugin
|
6
|
+
def self.dispatch
|
7
|
+
meth = ARGV.shift.downcase
|
8
|
+
name = ARGV.shift
|
9
|
+
|
10
|
+
if name == 'all'
|
11
|
+
self.send("#{meth}_all")
|
12
|
+
else
|
13
|
+
ExtMVC::Plugin.new(name).send(meth)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.install_all
|
18
|
+
self.all_plugins.each {|pluginName| ExtMVC::Plugin.new(pluginName).install}
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.uninstall_all
|
22
|
+
self.all_plugins.each {|pluginName| ExtMVC::Plugin.new(pluginName).uninstall}
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.all_plugins
|
26
|
+
pluginsDir = 'vendor/plugins'
|
27
|
+
|
28
|
+
#Gets the name of each plugin directory inside vendor/plugins and calls self.plugin with it
|
29
|
+
Dir.entries(pluginsDir).select {|fileName|
|
30
|
+
File.directory?("#{pluginsDir}/#{fileName}") && (fileName =~ /^\./) != 0
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
attr_reader :name, :type, :directory
|
35
|
+
|
36
|
+
def initialize name
|
37
|
+
@name = @directory = name
|
38
|
+
@type = @name =~ /git:\/\// ? 'git' : 'dir'
|
39
|
+
|
40
|
+
@public_directory = "vendor/plugins/#{@name}/public"
|
41
|
+
end
|
42
|
+
|
43
|
+
def install
|
44
|
+
install_assets
|
45
|
+
end
|
46
|
+
|
47
|
+
def install_assets
|
48
|
+
install_assets_from_directory(@public_directory) if File.exists?(@public_directory)
|
49
|
+
end
|
50
|
+
|
51
|
+
def uninstall
|
52
|
+
if File.exists?(@public_directory)
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
#installs all assets from the given directory and subdirs into the main /public folder
|
59
|
+
def install_assets_from_directory(directory)
|
60
|
+
directory ||= @public_directory
|
61
|
+
|
62
|
+
find_assets_in_directory(directory).each do |f|
|
63
|
+
new_asset = asset_new_location_name(f)
|
64
|
+
if File.directory?(f)
|
65
|
+
unless File.exists?(new_asset)
|
66
|
+
Dir.mkdir(new_asset)
|
67
|
+
puts "Created directory: " + new_asset
|
68
|
+
end
|
69
|
+
else
|
70
|
+
action = File.exists?(new_asset) ? 'Updated' : 'Installed'
|
71
|
+
File.copy(f, new_asset)
|
72
|
+
puts action + " file: " + new_asset
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
#recursively finds assets in directories under /public inside the plugin
|
78
|
+
def find_assets_in_directory(directory)
|
79
|
+
files = []
|
80
|
+
|
81
|
+
Dir.entries(directory).each do |e|
|
82
|
+
filename = File.join(directory, e)
|
83
|
+
next if ['.', '..'].include?(filename.split('/').last.to_s)
|
84
|
+
|
85
|
+
files.push(filename)
|
86
|
+
files.concat(find_assets_in_directory(filename)) if File.directory?(filename)
|
87
|
+
end
|
88
|
+
|
89
|
+
return files
|
90
|
+
end
|
91
|
+
|
92
|
+
#i.e. vendor/plugins/MyPlugin/public/images/image.gif becomes public/images/image.gif
|
93
|
+
def asset_new_location_name(filename)
|
94
|
+
pieces = filename.split("/")
|
95
|
+
if index = pieces.index('public')
|
96
|
+
File.join(pieces.slice(index, pieces.size))
|
97
|
+
else
|
98
|
+
filename
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module ExtJS
|
2
|
+
module MVC
|
3
|
+
|
4
|
+
# extracts settings from the config/settings.yml file
|
5
|
+
def self.settings
|
6
|
+
@config ||= YAML.load_file('config/settings.yml')
|
7
|
+
end
|
8
|
+
|
9
|
+
# returns environment settings
|
10
|
+
def self.environment
|
11
|
+
settings['environment']
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.namespace
|
15
|
+
environment["namespace"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.show_settings
|
19
|
+
puts environment.inspect
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.application_files_for(environment)
|
23
|
+
files = []
|
24
|
+
|
25
|
+
[
|
26
|
+
environment["plugins"].collect {|o| "vendor/plugins/#{o}/#{o}-all.js"},
|
27
|
+
environment["overrides"].collect {|o| "config/overrides/#{o}.js"},
|
28
|
+
environment["config"].collect {|o| "#{o}.js"},
|
29
|
+
environment["models"].collect {|o| "app/models/#{o}.js"},
|
30
|
+
environment["controllers"].collect {|o| "app/controllers/#{o}Controller.js"},
|
31
|
+
environment["views"].collect {|o| o.collect {|dir, fileList| fileList.collect {|fileName| "app/views/#{dir}/#{fileName}.js"}.flatten}}.flatten
|
32
|
+
].each {|f| files.concat(f)}
|
33
|
+
|
34
|
+
files
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.css_files_for(environment)
|
38
|
+
environment['stylesheets'].collect {|s| "public/stylesheets/#{s}.css"}
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.mvc_development_environment
|
42
|
+
environment = {}
|
43
|
+
|
44
|
+
default = JSON::Parser.new(File.read('public/config/environment.json')).parse()
|
45
|
+
development = JSON::Parser.new(File.read('public/config/environments/development.json')).parse()
|
46
|
+
|
47
|
+
environment.merge!(default)
|
48
|
+
environment.merge!(development)
|
49
|
+
|
50
|
+
environment
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.mvc_production_environment
|
54
|
+
environment = {
|
55
|
+
'pluginsDir' => '../vendor/plugins',
|
56
|
+
'libDir' => '../lib',
|
57
|
+
'configDir' => '../config',
|
58
|
+
'overridesDir' => '../config/overrides',
|
59
|
+
'appDir' => '../app',
|
60
|
+
'vendor' => ['mvc'],
|
61
|
+
'mvcFilename' => 'ext-mvc-all-min',
|
62
|
+
'config' => ['app/App', 'config/routes'],
|
63
|
+
'stylesheets' => ['ext-all']
|
64
|
+
}
|
65
|
+
|
66
|
+
default = JSON::Parser.new(File.read('public/config/environment.json')).parse()
|
67
|
+
production = JSON::Parser.new(File.read('public/config/environments/production.json')).parse()
|
68
|
+
|
69
|
+
environment.merge!(default)
|
70
|
+
environment.merge!(production)
|
71
|
+
|
72
|
+
environment
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/xmvc/stats.rb
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
##
|
2
|
+
# Your code-stats generator
|
3
|
+
#
|
4
|
+
# +----------------------+-------+-------+---------+---------+-----+-------+
|
5
|
+
# | Name | Lines | LOC | Classes | Methods | M/C | LOC/M |
|
6
|
+
# +----------------------+-------+-------+---------+---------+-----+-------+
|
7
|
+
# | Controllers | 1479 | 1172 | 26 | 152 | 5 | 5 |
|
8
|
+
# | Helpers | 113 | 47 | 0 | 6 | 0 | 5 |
|
9
|
+
# | Models | 1239 | 869 | 32 | 93 | 2 | 7 |
|
10
|
+
# | Libraries | 609 | 367 | 2 | 54 | 27 | 4 |
|
11
|
+
# | Model specs | 1361 | 989 | 0 | 3 | 0 | 327 |
|
12
|
+
# | Controller specs | 3372 | 2319 | 1 | 73 | 73 | 29 |
|
13
|
+
# | Helper specs | 159 | 148 | 0 | 0 | 0 | 0 |
|
14
|
+
# +----------------------+-------+-------+---------+---------+-----+-------+
|
15
|
+
# | Total | 8332 | 5911 | 61 | 381 | 6 | 13 |
|
16
|
+
# +----------------------+-------+-------+---------+---------+-----+-------+
|
17
|
+
# Code LOC: 2455 Test LOC: 3456 Code to Test Ratio: 1:1.4
|
18
|
+
#
|
19
|
+
module Xmvc
|
20
|
+
module Stats
|
21
|
+
def self.dispatch
|
22
|
+
Statistics.new.output
|
23
|
+
end
|
24
|
+
|
25
|
+
class Statistics
|
26
|
+
|
27
|
+
# Gathers and aggregates all project statistics
|
28
|
+
def statistics
|
29
|
+
@statistics ||= begin
|
30
|
+
stats = {}
|
31
|
+
|
32
|
+
# Calculate requested stats
|
33
|
+
line_order.each do |line|
|
34
|
+
stats[line] = array_statistics(self.send(line))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Calculate totals
|
38
|
+
stats[:total_code_loc] = project_code_arrays.inject(0) {|sum, e| sum + stats[e][:loc_count]}
|
39
|
+
stats[:total_spec_loc] = project_spec_arrays.inject(0) {|sum, e| sum + stats[e][:loc_count]}
|
40
|
+
|
41
|
+
stats
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Prints statistics to the console
|
46
|
+
def output
|
47
|
+
print_headings
|
48
|
+
|
49
|
+
line_order.each do |line_name|
|
50
|
+
stats = statistics[line_name]
|
51
|
+
|
52
|
+
arr = [line_headings[line_name]] + column_order.collect {|col| stats[col]}
|
53
|
+
print_line(arr)
|
54
|
+
end
|
55
|
+
|
56
|
+
print_separator
|
57
|
+
print_summary
|
58
|
+
end
|
59
|
+
|
60
|
+
# Prints a headings line based on column_order
|
61
|
+
def print_headings
|
62
|
+
puts
|
63
|
+
print_separator
|
64
|
+
|
65
|
+
columns = ["Name"];
|
66
|
+
column_order.each {|heading| columns.push(column_headings[heading])}
|
67
|
+
print_line(columns)
|
68
|
+
|
69
|
+
print_separator
|
70
|
+
end
|
71
|
+
|
72
|
+
def print_totals
|
73
|
+
# columns = ["Totals"]
|
74
|
+
# column_order.collect {|c| statistics}
|
75
|
+
|
76
|
+
# print_line(columns)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Prints a summary line with total LOC
|
80
|
+
def print_summary
|
81
|
+
stats = [statistics[:total_code_loc], statistics[:total_spec_loc]]
|
82
|
+
stats.push(stats[1].to_f / stats[0].to_f)
|
83
|
+
|
84
|
+
puts " Code LOC: %s Test LOC: %s Code to Test Ratio: 1:%1.1f" % stats
|
85
|
+
puts
|
86
|
+
end
|
87
|
+
|
88
|
+
# Prints a separator line
|
89
|
+
def print_separator
|
90
|
+
str = "+" + "-" * (title_width + 2)
|
91
|
+
|
92
|
+
column_order.length.times do
|
93
|
+
str += "+" + "-" * (column_width + 2)
|
94
|
+
end
|
95
|
+
|
96
|
+
puts str + '+'
|
97
|
+
end
|
98
|
+
|
99
|
+
# Prints an array of string as a line
|
100
|
+
def print_line(line_elements)
|
101
|
+
str = "| "
|
102
|
+
|
103
|
+
line_elements.each_with_index do |element, index|
|
104
|
+
if index == 0
|
105
|
+
str += element.to_s.ljust(title_width) + " | "
|
106
|
+
else
|
107
|
+
str += element.to_s.rjust(column_width) + " | "
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
puts str
|
112
|
+
end
|
113
|
+
|
114
|
+
# Calculates the width of the first column. Elements will be padded to this width
|
115
|
+
def title_width
|
116
|
+
line_headings.values.collect {|l| l.to_s.length}.max + 8
|
117
|
+
end
|
118
|
+
|
119
|
+
# Calculates the width of all columns but the first. Elements will be padded to this width
|
120
|
+
def column_width
|
121
|
+
column_headings.values.collect {|l| l.to_s.length}.max + 2
|
122
|
+
end
|
123
|
+
|
124
|
+
# The statistics columns to show, in order
|
125
|
+
def column_order
|
126
|
+
[:line_count, :loc_count, :file_count, :class_length]
|
127
|
+
end
|
128
|
+
|
129
|
+
# The lines to show, in order
|
130
|
+
def line_order
|
131
|
+
[:controller_files, :model_files, :view_files, :lib_files, :controller_specs, :model_specs, :view_specs]
|
132
|
+
end
|
133
|
+
|
134
|
+
# The arrays to use when calculating totals for project LOC etc
|
135
|
+
def project_code_arrays
|
136
|
+
[:controller_files, :model_files, :view_files, :lib_files]
|
137
|
+
end
|
138
|
+
|
139
|
+
# The arrays to use when calculating totals for project spec LOC etc
|
140
|
+
def project_spec_arrays
|
141
|
+
[:controller_specs, :model_specs, :view_specs]
|
142
|
+
end
|
143
|
+
|
144
|
+
# Mappings between method and human names for line headings
|
145
|
+
def line_headings
|
146
|
+
{
|
147
|
+
:controller_files => "Controllers",
|
148
|
+
:model_files => "Models",
|
149
|
+
:view_files => "Views",
|
150
|
+
:lib_files => "Libraries",
|
151
|
+
:plugin_files => "Plugins",
|
152
|
+
:controller_specs => "Controller Specs",
|
153
|
+
:model_specs => "Model Specs",
|
154
|
+
:view_specs => "View Specs"
|
155
|
+
}
|
156
|
+
end
|
157
|
+
|
158
|
+
# Mappings between method and human names for column headings
|
159
|
+
def column_headings
|
160
|
+
{
|
161
|
+
:line_count => "Lines",
|
162
|
+
:loc_count => "LOC",
|
163
|
+
:file_count => "Classes",
|
164
|
+
:method_count => "Methods",
|
165
|
+
:average_methods => "M/C",
|
166
|
+
:method_length => "LOC/M",
|
167
|
+
:class_length => "LOC/C"
|
168
|
+
}
|
169
|
+
end
|
170
|
+
|
171
|
+
def controller_files
|
172
|
+
files_in('app/controllers') + ['app/App.js']
|
173
|
+
end
|
174
|
+
|
175
|
+
def model_files
|
176
|
+
files_in('app/models')
|
177
|
+
end
|
178
|
+
|
179
|
+
def view_files
|
180
|
+
files_in('app/views')
|
181
|
+
end
|
182
|
+
|
183
|
+
def lib_files
|
184
|
+
files_in('lib')
|
185
|
+
end
|
186
|
+
|
187
|
+
def plugin_files
|
188
|
+
files_in('vendor/plugins')
|
189
|
+
end
|
190
|
+
|
191
|
+
def controller_specs
|
192
|
+
files_in('spec/controllers')
|
193
|
+
end
|
194
|
+
|
195
|
+
def model_specs
|
196
|
+
files_in('spec/models')
|
197
|
+
end
|
198
|
+
|
199
|
+
def view_specs
|
200
|
+
files_in('spec/views')
|
201
|
+
end
|
202
|
+
|
203
|
+
private
|
204
|
+
def files_in(directory)
|
205
|
+
Dir.glob("#{directory}/**/*.js")
|
206
|
+
end
|
207
|
+
|
208
|
+
#calculates aggregated statistics for an array of files
|
209
|
+
def array_statistics(files_array)
|
210
|
+
file_count = 0; line_count = 0; loc_count = 0;
|
211
|
+
|
212
|
+
files_array.collect {|f| file_statistics(f)}.each do |stats|
|
213
|
+
file_count += 1
|
214
|
+
line_count += stats[:line_count]
|
215
|
+
loc_count += stats[:loc_count]
|
216
|
+
end
|
217
|
+
|
218
|
+
{
|
219
|
+
:file_count => file_count,
|
220
|
+
:line_count => line_count,
|
221
|
+
:loc_count => loc_count,
|
222
|
+
:class_length => file_count == 0 ? 0 : loc_count / file_count
|
223
|
+
}
|
224
|
+
end
|
225
|
+
= extjs-core
|
226
|
+
|
227
|
+
Description goes here.
|
228
|
+
|
229
|
+
== Note on Patches/Pull Requests
|
230
|
+
|
231
|
+
* Fork the project.
|
232
|
+
* Make your feature addition or bug fix.
|
233
|
+
* Add tests for it. This is important so I don't break it in a
|
234
|
+
future version unintentionally.
|
235
|
+
* Commit, do not mess with rakefile, version, or history.
|
236
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
237
|
+
* Send me a pull request. Bonus points for topic branches.
|
238
|
+
|
239
|
+
== Copyright
|
240
|
+
|
241
|
+
Copyright (c) 2010 Christocracy. See LICENSE for details.
|
242
|
+
|
243
|
+
#calculates statistics on a given file
|
244
|
+
def file_statistics(filename)
|
245
|
+
line_count = 0; loc_count = 0;
|
246
|
+
|
247
|
+
File.new(filename, 'r').each_line do |line|
|
248
|
+
line.strip!
|
249
|
+
line_count += 1
|
250
|
+
|
251
|
+
# don't count blank lines or comment lines in LOC
|
252
|
+
loc_count += 1 if line.gsub(/[\/\*\s]/i, "").length > 1 && line.match(/^\/\//).nil?
|
253
|
+
end
|
254
|
+
|
255
|
+
{:line_count => line_count, :loc_count => loc_count}
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
data/lib/xmvc/test.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'vendor/mvc/scripts/settings'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
# Rack adapter - each time a file changes, it gets given a sequential ID by builder. Browsers can then
|
5
|
+
# poll request all tests to perform since the last test they ran, based on its ID. Browsers report back
|
6
|
+
# to the Rack server, and amalgamated results can be retrieved:
|
7
|
+
#
|
8
|
+
# GET localhost:5000/changes?since=someDateTime
|
9
|
+
# POST localhost:5000/results <= POST to with json object of success/fail data
|
10
|
+
# GET localhost:5000/results?since=someDateTime
|
11
|
+
module Rack
|
12
|
+
class ExtMVCSpecServer
|
13
|
+
def initialize
|
14
|
+
super
|
15
|
+
|
16
|
+
@files = ExtMVC.application_files_for(ExtMVC.mvc_production_environment)
|
17
|
+
end
|
18
|
+
|
19
|
+
def call env
|
20
|
+
path = env["REQUEST_PATH"].gsub(/^\//, '')
|
21
|
+
path = 'index' if path == '/'
|
22
|
+
|
23
|
+
@params = {}
|
24
|
+
env["QUERY_STRING"].split("&").each do |query|
|
25
|
+
@params[query.split("=")[0]] = query.split("=")[1]
|
26
|
+
end
|
27
|
+
|
28
|
+
[200, { 'Content-Type' => 'text/html' }, jsonp_encode(self.send(path, env))]
|
29
|
+
end
|
30
|
+
|
31
|
+
def jsonp_encode(obj)
|
32
|
+
@params["callback"] + "(" + JSON.generate(obj) + ")"
|
33
|
+
end
|
34
|
+
|
35
|
+
def session env
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
def index env
|
40
|
+
'index'
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns an array of all test files to run
|
44
|
+
def all_test_files env
|
45
|
+
{"files" => scope_files(file_list)}
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns true if any files have changed since the date given
|
49
|
+
def changes env
|
50
|
+
{"files" => changes_since(@params["since"].to_i)}
|
51
|
+
end
|
52
|
+
|
53
|
+
# Called when a client sends results to the server. Growls and adds to recent results array
|
54
|
+
def results env
|
55
|
+
puts @params
|
56
|
+
puts "Results!"
|
57
|
+
|
58
|
+
if @params["failures"].to_i == 0
|
59
|
+
notify("All Tests Passed")
|
60
|
+
else
|
61
|
+
notify("#{@params['failures']} of #{@params['specsFinished']} Tests Failed")
|
62
|
+
end
|
63
|
+
|
64
|
+
@params
|
65
|
+
end
|
66
|
+
|
67
|
+
# Notifies of test passes/failures using Growl
|
68
|
+
def notify message
|
69
|
+
system('growlnotify -m "' + message + '"')
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns an array of all watched files that have changed since the given timestamp
|
73
|
+
def changes_since(mtime)
|
74
|
+
files = file_list.inject({}) {|m, f| m.merge({f => Kernel.const_get("File").mtime(f)})}
|
75
|
+
|
76
|
+
changed_files = file_list.select { |file, last_changed|
|
77
|
+
Kernel.const_get("File").mtime(file).to_i > mtime
|
78
|
+
}
|
79
|
+
|
80
|
+
scope_files(changed_files)
|
81
|
+
end
|
82
|
+
|
83
|
+
# prepends each file in an array with '../'
|
84
|
+
def scope_files files
|
85
|
+
files.collect {|f| "../#{f}"}
|
86
|
+
end
|
87
|
+
|
88
|
+
def file_list
|
89
|
+
Dir["spec/models/*.js"].concat(Dir["spec/controllers/*.js"]) #.concat(Dir["spec/views/**/*.js"])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
app = Rack::ExtMVCSpecServer.new
|
95
|
+
run app
|
data/lib/xmvc/ui.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
module Xmvc
|
2
|
+
class UI
|
3
|
+
def warn(message)
|
4
|
+
end
|
5
|
+
|
6
|
+
def error(message)
|
7
|
+
end
|
8
|
+
|
9
|
+
def info(message)
|
10
|
+
end
|
11
|
+
|
12
|
+
def confirm(message)
|
13
|
+
end
|
14
|
+
|
15
|
+
class Shell < UI
|
16
|
+
def initialize(shell)
|
17
|
+
@shell = shell
|
18
|
+
end
|
19
|
+
|
20
|
+
# TODO: Add debug mode
|
21
|
+
def debug(msg)
|
22
|
+
end
|
23
|
+
|
24
|
+
def info(msg)
|
25
|
+
@shell.say(msg)
|
26
|
+
end
|
27
|
+
|
28
|
+
def confirm(msg)
|
29
|
+
@shell.say(msg, :green)
|
30
|
+
end
|
31
|
+
|
32
|
+
def warn(msg)
|
33
|
+
@shell.say(msg, :yellow)
|
34
|
+
end
|
35
|
+
|
36
|
+
def error(msg)
|
37
|
+
@shell.say(msg, :red)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class RGProxy < Gem::SilentUI
|
42
|
+
def initialize(ui)
|
43
|
+
@ui = ui
|
44
|
+
end
|
45
|
+
|
46
|
+
def say(message)
|
47
|
+
if message =~ /native extensions/
|
48
|
+
@ui.info "with native extensions "
|
49
|
+
else
|
50
|
+
@ui.debug(message)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/xmvc/update.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# run ruby script/update to update MVC files used inside the baseapp,
|
2
|
+
# such as ensuring the files in the 'script' folder are up to date`
|
3
|
+
module Xmvc
|
4
|
+
module Update
|
5
|
+
def self.dispatch
|
6
|
+
Updater.new
|
7
|
+
end
|
8
|
+
|
9
|
+
class Updater
|
10
|
+
def initialize
|
11
|
+
[:build, :generate, :info, :setup, :stats].each do |script|
|
12
|
+
self.send("ensure_#{script}")
|
13
|
+
end
|
14
|
+
|
15
|
+
# Updates from 0.6a1 to 0.6b1... this is a bit shit :(
|
16
|
+
changes = [
|
17
|
+
{:old => 'ExtMVC.Model', :new => 'ExtMVC.model'},
|
18
|
+
{:old => 'ExtMVC.Controller', :new => 'ExtMVC.controller.Controller'},
|
19
|
+
{:old => 'ExtMVC.CrudController', :new => 'ExtMVC.controller.CrudController'},
|
20
|
+
{:old => 'ExtMVC.Route', :new => 'ExtMVC.router.Route'},
|
21
|
+
{:old => 'ExtMVC.Router', :new => 'ExtMVC.router.Router'}
|
22
|
+
]
|
23
|
+
|
24
|
+
changes.each do |pair|
|
25
|
+
system("find ./app/**/*.js | xargs perl -wi -pe 's/#{pair[:old]}/#{pair[:new]}/g'")
|
26
|
+
system("find ./config/*js | xargs perl -wi -pe 's/#{pair[:old]}/#{pair[:new]}/g'")
|
27
|
+
end
|
28
|
+
# End updates from 0.6a1 to 0.6b... it's still shit
|
29
|
+
end
|
30
|
+
|
31
|
+
def ensure_build
|
32
|
+
install_file('build', 'ExtMVC::Builder.dispatch')
|
33
|
+
end
|
34
|
+
|
35
|
+
def ensure_generate
|
36
|
+
install_file('generate', 'ExtMVC::Generator.dispatch')
|
37
|
+
end
|
38
|
+
|
39
|
+
def ensure_info
|
40
|
+
install_file('info', 'ExtMVC.show_settings')
|
41
|
+
end
|
42
|
+
|
43
|
+
def ensure_setup
|
44
|
+
install_file('setup', 'ExtMVC.setup(ARGV.shift)')
|
45
|
+
end
|
46
|
+
|
47
|
+
def ensure_stats
|
48
|
+
install_file('stats', 'ExtMVC::Stats.dispatch')
|
49
|
+
end
|
50
|
+
|
51
|
+
def ensure_update
|
52
|
+
install_file('update', 'ExtMVC::Update.dispatch')
|
53
|
+
end
|
54
|
+
|
55
|
+
def delete_file filename
|
56
|
+
File.delete()
|
57
|
+
rescue
|
58
|
+
end
|
59
|
+
|
60
|
+
def install_file filename, contents
|
61
|
+
filename = "script/#{filename}"
|
62
|
+
|
63
|
+
delete_file filename
|
64
|
+
str = "require 'vendor/mvc/scripts/scripts'\n\n" + contents
|
65
|
+
|
66
|
+
FileUtils.touch(filename)
|
67
|
+
File.open(filename, "w") {|f| f.puts str}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|