quirkey-qadmin 0.1.0
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.
- data/History.txt +4 -0
- data/Manifest.txt +44 -0
- data/PostInstall.txt +1 -0
- data/README.rdoc +64 -0
- data/Rakefile +28 -0
- data/init.rb +1 -0
- data/lib/qadmin/controller.rb +121 -0
- data/lib/qadmin/helper.rb +59 -0
- data/lib/qadmin/views/edit.html.erb +12 -0
- data/lib/qadmin/views/index.html.erb +31 -0
- data/lib/qadmin/views/new.html.erb +12 -0
- data/lib/qadmin/views/show.html.erb +14 -0
- data/lib/qadmin.rb +13 -0
- data/rails/init.rb +4 -0
- data/rails_generators/qadmin/USAGE +5 -0
- data/rails_generators/qadmin/qadmin_generator.rb +94 -0
- data/rails_generators/qadmin/templates/_form.html.erb +7 -0
- data/rails_generators/qadmin/templates/controller.rb +6 -0
- data/rails_generators/qadmin/templates/functional_test.rb +77 -0
- data/rails_generators/qadmin/templates/images/icon_destroy.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_down.gif +0 -0
- data/rails_generators/qadmin/templates/images/icon_edit.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_export.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_find.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_import.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_list.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_new.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_next.gif +0 -0
- data/rails_generators/qadmin/templates/images/icon_prev.gif +0 -0
- data/rails_generators/qadmin/templates/images/icon_show.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_sort.png +0 -0
- data/rails_generators/qadmin/templates/images/icon_up.gif +0 -0
- data/rails_generators/qadmin/templates/images/indicator_medium.gif +0 -0
- data/rails_generators/qadmin/templates/layout.html.erb +45 -0
- data/rails_generators/qadmin/templates/shoulda_functional_test.rb +33 -0
- data/rails_generators/qadmin/templates/style.css +683 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +71 -0
- data/test/test_generator_helper.rb +29 -0
- data/test/test_helper.rb +70 -0
- data/test/test_qadmin_controller.rb +138 -0
- data/test/test_qadmin_generator.rb +61 -0
- metadata +130 -0
data/script/txt2html
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
load File.dirname(__FILE__) + "/../Rakefile"
|
4
|
+
require 'rubyforge'
|
5
|
+
require 'redcloth'
|
6
|
+
require 'syntax/convertors/html'
|
7
|
+
require 'erb'
|
8
|
+
|
9
|
+
download = "http://rubyforge.org/projects/#{$hoe.rubyforge_name}"
|
10
|
+
version = $hoe.version
|
11
|
+
|
12
|
+
def rubyforge_project_id
|
13
|
+
RubyForge.new.configure.autoconfig["group_ids"][$hoe.rubyforge_name]
|
14
|
+
end
|
15
|
+
|
16
|
+
class Fixnum
|
17
|
+
def ordinal
|
18
|
+
# teens
|
19
|
+
return 'th' if (10..19).include?(self % 100)
|
20
|
+
# others
|
21
|
+
case self % 10
|
22
|
+
when 1: return 'st'
|
23
|
+
when 2: return 'nd'
|
24
|
+
when 3: return 'rd'
|
25
|
+
else return 'th'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Time
|
31
|
+
def pretty
|
32
|
+
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def convert_syntax(syntax, source)
|
37
|
+
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
38
|
+
end
|
39
|
+
|
40
|
+
if ARGV.length >= 1
|
41
|
+
src, template = ARGV
|
42
|
+
template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
|
43
|
+
else
|
44
|
+
puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
|
45
|
+
exit!
|
46
|
+
end
|
47
|
+
|
48
|
+
template = ERB.new(File.open(template).read)
|
49
|
+
|
50
|
+
title = nil
|
51
|
+
body = nil
|
52
|
+
File.open(src) do |fsrc|
|
53
|
+
title_text = fsrc.readline
|
54
|
+
body_text_template = fsrc.read
|
55
|
+
body_text = ERB.new(body_text_template).result(binding)
|
56
|
+
syntax_items = []
|
57
|
+
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
|
58
|
+
ident = syntax_items.length
|
59
|
+
element, syntax, source = $1, $2, $3
|
60
|
+
syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
|
61
|
+
"syntax-temp-#{ident}"
|
62
|
+
}
|
63
|
+
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
64
|
+
body = RedCloth.new(body_text).to_html
|
65
|
+
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
66
|
+
end
|
67
|
+
stat = File.stat(src)
|
68
|
+
created = stat.ctime
|
69
|
+
modified = stat.mtime
|
70
|
+
|
71
|
+
$stdout << template.result(binding)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
begin
|
2
|
+
require File.dirname(__FILE__) + '/test_helper'
|
3
|
+
rescue LoadError
|
4
|
+
require 'test/unit'
|
5
|
+
end
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
# Must set before requiring generator libs.
|
9
|
+
TMP_ROOT = File.dirname(__FILE__) + "/tmp" unless defined?(TMP_ROOT)
|
10
|
+
PROJECT_NAME = "myproject" unless defined?(PROJECT_NAME)
|
11
|
+
app_root = File.join(TMP_ROOT, PROJECT_NAME)
|
12
|
+
if defined?(APP_ROOT)
|
13
|
+
APP_ROOT.replace(app_root)
|
14
|
+
else
|
15
|
+
APP_ROOT = app_root
|
16
|
+
end
|
17
|
+
# if defined?(RAILS_ROOT)
|
18
|
+
# RAILS_ROOT.replace(app_root)
|
19
|
+
# else
|
20
|
+
# RAILS_ROOT = app_root
|
21
|
+
# end
|
22
|
+
|
23
|
+
begin
|
24
|
+
require 'rubigen'
|
25
|
+
rescue LoadError
|
26
|
+
require 'rubygems'
|
27
|
+
require 'rubigen'
|
28
|
+
end
|
29
|
+
require 'rubigen/helpers/generator_test_helper'
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'stringio'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'mocha'
|
5
|
+
require 'shoulda'
|
6
|
+
|
7
|
+
# mock AR::BASE
|
8
|
+
module ActiveRecord
|
9
|
+
class Base
|
10
|
+
class << self
|
11
|
+
attr_accessor :pluralize_table_names
|
12
|
+
|
13
|
+
def protected_attributes
|
14
|
+
[]
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
self.pluralize_table_names = true
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require File.dirname(__FILE__) + '/../lib/qadmin'
|
23
|
+
|
24
|
+
|
25
|
+
class MockColumn
|
26
|
+
attr_accessor :name, :type
|
27
|
+
|
28
|
+
def initialize(name, type)
|
29
|
+
self.name = name
|
30
|
+
self.type = type
|
31
|
+
end
|
32
|
+
|
33
|
+
def human_name
|
34
|
+
name.to_s.humanize
|
35
|
+
end
|
36
|
+
|
37
|
+
def default
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Item < ActiveRecord::Base
|
43
|
+
|
44
|
+
class << self
|
45
|
+
|
46
|
+
def content_columns
|
47
|
+
columns = {
|
48
|
+
:name => :string,
|
49
|
+
:sku => :string,
|
50
|
+
:description => :text,
|
51
|
+
:made_at => :datetime,
|
52
|
+
:price => :float,
|
53
|
+
:created_at => :datetime,
|
54
|
+
:updated_at => :datetime
|
55
|
+
}
|
56
|
+
columns.collect do |name, type|
|
57
|
+
MockColumn.new(name, type)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class MockController
|
64
|
+
class << self
|
65
|
+
def append_view_paths(paths)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
extend Qadmin::Controller::Macros
|
70
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestQadminController < Test::Unit::TestCase
|
4
|
+
|
5
|
+
protected
|
6
|
+
def crud_actions
|
7
|
+
[:index, :show, :new, :create, :edit, :update, :destroy]
|
8
|
+
end
|
9
|
+
|
10
|
+
def assert_defines_actions(*actions)
|
11
|
+
[actions].flatten.each do |action|
|
12
|
+
assert @controller.respond_to?(action), "Should define ##{action}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def assert_does_not_define_actions(*actions)
|
17
|
+
[actions].flatten.each do |action|
|
18
|
+
assert !@controller.respond_to?(action), "Should not define ##{action}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
public
|
22
|
+
|
23
|
+
context "QadminController" do
|
24
|
+
context "Macros" do
|
25
|
+
context "#qadmin" do
|
26
|
+
|
27
|
+
context "with no options" do
|
28
|
+
setup do
|
29
|
+
class NoOptionsController < MockController
|
30
|
+
qadmin
|
31
|
+
end
|
32
|
+
@controller = NoOptionsController.new
|
33
|
+
end
|
34
|
+
|
35
|
+
should "define all CRUD actions" do
|
36
|
+
assert_defines_actions(crud_actions)
|
37
|
+
end
|
38
|
+
|
39
|
+
should "set model_name from controller name" do
|
40
|
+
assert_equal 'NoOption', @controller.send(:model_name)
|
41
|
+
end
|
42
|
+
|
43
|
+
should "set model_instance_name to underscored version" do
|
44
|
+
assert_equal 'no_option', @controller.send(:model_instance_name)
|
45
|
+
end
|
46
|
+
|
47
|
+
should "set human_name to model.humanize" do
|
48
|
+
assert_equal 'No option', @controller.send(:model_human_name)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with hashed options" do
|
53
|
+
context "with :exclude" do
|
54
|
+
setup do
|
55
|
+
class ExcludeController < MockController
|
56
|
+
qadmin :exclude => [:show, :destroy]
|
57
|
+
end
|
58
|
+
@controller = ExcludeController.new
|
59
|
+
end
|
60
|
+
|
61
|
+
should "define CRUD actions" do
|
62
|
+
assert_defines_actions(crud_actions - [:show, :destroy])
|
63
|
+
end
|
64
|
+
|
65
|
+
should "not define actions in exclude" do
|
66
|
+
assert_does_not_define_actions([:show, :destroy])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "with :only" do
|
71
|
+
setup do
|
72
|
+
class OnlyController < MockController
|
73
|
+
qadmin :only => [:index, :show]
|
74
|
+
end
|
75
|
+
@controller = OnlyController.new
|
76
|
+
end
|
77
|
+
|
78
|
+
should "define CRUD actions" do
|
79
|
+
assert_defines_actions(:index, :show)
|
80
|
+
end
|
81
|
+
|
82
|
+
should "not define actions in exclude" do
|
83
|
+
assert_does_not_define_actions(crud_actions - [:index, :show])
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "with :model_name" do
|
88
|
+
should "set #model_name" do
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "with :human_name" do
|
94
|
+
|
95
|
+
should "set the human name" do
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
should "not effect the existing model name" do
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "with two instances in different controllers" do
|
105
|
+
setup do
|
106
|
+
class NewExcludeController < MockController
|
107
|
+
qadmin :exclude => [:show, :new]
|
108
|
+
end
|
109
|
+
@exclude_controller = NewExcludeController.new
|
110
|
+
class NewOnlyController < MockController
|
111
|
+
qadmin :only => [:index, :show]
|
112
|
+
end
|
113
|
+
@only_controller = NewOnlyController.new
|
114
|
+
end
|
115
|
+
|
116
|
+
should "not include actions for :exclude" do
|
117
|
+
@controller = @exclude_controller
|
118
|
+
assert_does_not_define_actions(:show, :new)
|
119
|
+
assert_defines_actions(crud_actions - [:show, :new])
|
120
|
+
end
|
121
|
+
|
122
|
+
should "include actions for :only" do
|
123
|
+
@controller = @only_controller
|
124
|
+
assert_does_not_define_actions(crud_actions - [:index, :show])
|
125
|
+
assert_defines_actions([:index, :show])
|
126
|
+
end
|
127
|
+
|
128
|
+
should "set model name independently" do
|
129
|
+
assert_equal 'NewOnly', @only_controller.send(:model_name)
|
130
|
+
assert_equal 'NewExclude', @exclude_controller.send(:model_name)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "test_generator_helper.rb")
|
2
|
+
|
3
|
+
require 'rails_generator'
|
4
|
+
|
5
|
+
class TestQadminGenerator < Test::Unit::TestCase
|
6
|
+
include RubiGen::GeneratorTestHelper
|
7
|
+
|
8
|
+
def setup
|
9
|
+
bare_setup
|
10
|
+
base_files.each do |file|
|
11
|
+
full_path = File.join(APP_ROOT, file)
|
12
|
+
FileUtils.mkdir_p(File.dirname(full_path))
|
13
|
+
File.open(full_path, 'w') {|f| f << '' }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
bare_teardown
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_generator_with_model_without_options
|
22
|
+
name = 'Item'
|
23
|
+
run_generator('qadmin', [name], sources, :destination => APP_ROOT)
|
24
|
+
assert_generated_class('app/controllers/items_controller') do |body|
|
25
|
+
assert_match(/qadmin/, body)
|
26
|
+
end
|
27
|
+
assert_generated_class('test/functional/items_controller_test')
|
28
|
+
assert_directory_exists('app/views/items')
|
29
|
+
assert_generated_file('app/views/items/_form.html.erb')
|
30
|
+
assert_generated_file('app/views/layouts/admin.html.erb')
|
31
|
+
assert_directory_exists('public/images/admin/')
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def sources
|
36
|
+
[RubiGen::PathSource.new(:test, File.join(File.dirname(__FILE__),"..", generator_path))
|
37
|
+
]
|
38
|
+
end
|
39
|
+
|
40
|
+
def generator_path
|
41
|
+
"rails_generators"
|
42
|
+
end
|
43
|
+
|
44
|
+
def base_files
|
45
|
+
[
|
46
|
+
'public/stylesheets/style.css',
|
47
|
+
'app/views/layouts/main.html.erb',
|
48
|
+
'config/routes.rb'
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
def silence_generator
|
53
|
+
logger_original = Rails::Generator::Base.logger
|
54
|
+
myout = StringIO.new
|
55
|
+
Rails::Generator::Base.logger = Rails::Generator::SimpleLogger.new(myout)
|
56
|
+
yield if block_given?
|
57
|
+
Rails::Generator::Base.logger = logger_original
|
58
|
+
myout.string
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: quirkey-qadmin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aaron Quint
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-08 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activesupport
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.2.0
|
23
|
+
version:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: newgem
|
26
|
+
version_requirement:
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ">="
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 1.2.3
|
32
|
+
version:
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: hoe
|
35
|
+
version_requirement:
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.8.0
|
41
|
+
version:
|
42
|
+
description: An [almost] one command solution for adding admin interfaces/resources to a Rails app.
|
43
|
+
email:
|
44
|
+
- aaron@quirkey.com
|
45
|
+
executables: []
|
46
|
+
|
47
|
+
extensions: []
|
48
|
+
|
49
|
+
extra_rdoc_files:
|
50
|
+
- History.txt
|
51
|
+
- Manifest.txt
|
52
|
+
- PostInstall.txt
|
53
|
+
- README.rdoc
|
54
|
+
files:
|
55
|
+
- History.txt
|
56
|
+
- Manifest.txt
|
57
|
+
- PostInstall.txt
|
58
|
+
- README.rdoc
|
59
|
+
- Rakefile
|
60
|
+
- init.rb
|
61
|
+
- lib/qadmin.rb
|
62
|
+
- lib/qadmin/controller.rb
|
63
|
+
- lib/qadmin/helper.rb
|
64
|
+
- lib/qadmin/views/edit.html.erb
|
65
|
+
- lib/qadmin/views/index.html.erb
|
66
|
+
- lib/qadmin/views/new.html.erb
|
67
|
+
- lib/qadmin/views/show.html.erb
|
68
|
+
- rails/init.rb
|
69
|
+
- rails_generators/qadmin/USAGE
|
70
|
+
- rails_generators/qadmin/qadmin_generator.rb
|
71
|
+
- rails_generators/qadmin/templates/_form.html.erb
|
72
|
+
- rails_generators/qadmin/templates/controller.rb
|
73
|
+
- rails_generators/qadmin/templates/functional_test.rb
|
74
|
+
- rails_generators/qadmin/templates/images/icon_destroy.png
|
75
|
+
- rails_generators/qadmin/templates/images/icon_down.gif
|
76
|
+
- rails_generators/qadmin/templates/images/icon_edit.png
|
77
|
+
- rails_generators/qadmin/templates/images/icon_export.png
|
78
|
+
- rails_generators/qadmin/templates/images/icon_find.png
|
79
|
+
- rails_generators/qadmin/templates/images/icon_import.png
|
80
|
+
- rails_generators/qadmin/templates/images/icon_list.png
|
81
|
+
- rails_generators/qadmin/templates/images/icon_new.png
|
82
|
+
- rails_generators/qadmin/templates/images/icon_next.gif
|
83
|
+
- rails_generators/qadmin/templates/images/icon_prev.gif
|
84
|
+
- rails_generators/qadmin/templates/images/icon_show.png
|
85
|
+
- rails_generators/qadmin/templates/images/icon_sort.png
|
86
|
+
- rails_generators/qadmin/templates/images/icon_up.gif
|
87
|
+
- rails_generators/qadmin/templates/images/indicator_medium.gif
|
88
|
+
- rails_generators/qadmin/templates/layout.html.erb
|
89
|
+
- rails_generators/qadmin/templates/shoulda_functional_test.rb
|
90
|
+
- rails_generators/qadmin/templates/style.css
|
91
|
+
- script/console
|
92
|
+
- script/destroy
|
93
|
+
- script/generate
|
94
|
+
- script/txt2html
|
95
|
+
- test/test_generator_helper.rb
|
96
|
+
- test/test_helper.rb
|
97
|
+
- test/test_qadmin_controller.rb
|
98
|
+
- test/test_qadmin_generator.rb
|
99
|
+
has_rdoc: true
|
100
|
+
homepage: http://github.com/quirkey/qadmin
|
101
|
+
post_install_message: PostInstall.txt
|
102
|
+
rdoc_options:
|
103
|
+
- --main
|
104
|
+
- README.rdoc
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: "0"
|
112
|
+
version:
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: "0"
|
118
|
+
version:
|
119
|
+
requirements: []
|
120
|
+
|
121
|
+
rubyforge_project: quirkey
|
122
|
+
rubygems_version: 1.2.0
|
123
|
+
signing_key:
|
124
|
+
specification_version: 2
|
125
|
+
summary: An [almost] one command solution for adding admin interfaces/resources to a Rails app.
|
126
|
+
test_files:
|
127
|
+
- test/test_generator_helper.rb
|
128
|
+
- test/test_helper.rb
|
129
|
+
- test/test_qadmin_controller.rb
|
130
|
+
- test/test_qadmin_generator.rb
|