shoestrap 1.0.0.pre1 → 1.0.0.pre2
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -2
- data/CHANGELOG.md +12 -1
- data/Guardfile +1 -0
- data/Rakefile +1 -1
- data/circle.yml +3 -0
- data/features/command_wrapper_helper.rb +94 -0
- data/features/custom_matcher.rb +23 -0
- data/features/features_helper.rb +76 -29
- data/features/postgres_helper.rb +69 -0
- data/features/shoestrap/commands/new_command_spec.rb +234 -0
- data/features/shoestrap/generators/{bdd_generator_feature.rb → bdd_generator_spec.rb} +7 -5
- data/features/shoestrap/generators/bootstrap_generator_spec.rb +21 -0
- data/features/shoestrap/generators/cms_generator_spec.rb +149 -0
- data/features/shoestrap/generators/{coffee_files_generator_feature.rb → coffee_files_generator_spec.rb} +0 -0
- data/features/shoestrap/generators/{foundation_generator_feature.rb → foundation_generator_spec.rb} +7 -0
- data/features/shoestrap/generators/kuhsaft_generator_spec.rb +57 -0
- data/features/shoestrap/generators/{smacss_files_generator_feature.rb → smacss_files_generator_spec.rb} +0 -0
- data/features/shoestrap/generators/view_files_generator_spec.rb +20 -0
- data/lib/generators/shoestrap/base_generator.rb +41 -0
- data/lib/generators/shoestrap/bdd_generator.rb +1 -5
- data/lib/generators/shoestrap/bootstrap_generator.rb +3 -0
- data/lib/generators/shoestrap/cms_generator.rb +59 -0
- data/lib/generators/shoestrap/coffee_files_generator.rb +1 -5
- data/lib/generators/shoestrap/foundation_generator.rb +5 -5
- data/lib/generators/shoestrap/kuhsaft_generator.rb +6 -5
- data/lib/generators/shoestrap/mailcatcher_generator.rb +12 -0
- data/lib/generators/shoestrap/simple_navigation_generator.rb +14 -0
- data/lib/generators/shoestrap/smacss_file_generator.rb +1 -5
- data/lib/generators/shoestrap/view_files_generator.rb +11 -0
- data/lib/shoestrap/application_generator.rb +14 -38
- data/lib/shoestrap/shell.rb +1 -0
- data/lib/shoestrap/version.rb +1 -1
- data/shoestrap.gemspec +12 -3
- data/spec/shoestrap/application_generator_spec.rb +37 -20
- data/spec/spec_helper.rb +1 -1
- data/templates/application_generator/_typekit.html.haml +4 -0
- data/templates/application_generator/application.html.haml +10 -10
- data/templates/application_generator/application_template.rb +19 -3
- data/templates/bdd_generator/active_record_spec_helper.rb +1 -1
- data/templates/cms_generator/base_controller.rb +2 -0
- data/templates/{coffee_generator → coffee_files_generator}/application.js.coffee +0 -0
- data/templates/simple_navigation_generator/navigation.rb +76 -0
- data/templates/{smacss_generator → smacss_files_generator}/application.css.sass +0 -0
- metadata +39 -21
- data/features/shoestrap/commands/new_command_feature.rb +0 -191
- data/features/shoestrap/generators/bootstrap_generator_feature.rb +0 -11
- data/features/shoestrap/generators/kuhsaft_generator_feature.rb +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12d033c7ad061cb445baf6857013f73d608fb015
|
4
|
+
data.tar.gz: 943e058c89295660e1e5680aef2149d1bc623295
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52d6779e7fbd340f7ecb3c670070af01c71b10a0eb19857a39a4c50f83a9cc6e01b8789c930aa354a6e787d69942c950cb48dc52f78dac01dfb7ee168d70a536
|
7
|
+
data.tar.gz: 4781dec71bd2e0b45566e2bb309760c3e333f18dcc1915f6e0a080cce972899866526246c6f7f4a7825e39f2bc9ec68815a2bc2fd14d533c2717b4dda5fe2d5b
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
---
|
2
1
|
rvm:
|
3
2
|
- 2.0.0
|
4
3
|
notifications:
|
5
4
|
hipchat:
|
6
|
-
secure: "
|
5
|
+
secure: "hXZoShKmIMVc9kEvqJBkNAd3xba2LA64rB6Ra5mXPxHfp5wPTg2vx9GSeyuPUdpJlnSOGZB/SuTd7TMypn8Cd3TLBdKfepR8I68HH8YxZ1UCwZEoWLj8/iEoYdGZXqKbfiH/Vd7fnY+zSM9ucSpW/GZhDLLNSJwq8VXkBKqGrFM="
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## master
|
4
|
+
|
5
|
+
- Minor improvements on generating application layout
|
6
|
+
- make typekit key configurable
|
7
|
+
|
8
|
+
- Add minor tweaks to generated Gemfile
|
9
|
+
- remove hardcoded kuhsaft in template
|
10
|
+
- specify current shoestrap version
|
11
|
+
- add js runtime
|
12
|
+
- fix conditional tags for IE (thx to @kuschti)
|
13
|
+
|
3
14
|
## 1.0.0.pre1 - 2013-07-17
|
4
15
|
|
5
16
|
Started from scratch for a clean, test driven implementation.
|
@@ -81,7 +92,7 @@ A few notable changes:
|
|
81
92
|
* use human_attribute_name as label in 'show' template
|
82
93
|
* remove title (h1) on 'show' template
|
83
94
|
* use '[index_path_name].new' as translation key for new button on 'index' template
|
84
|
-
|
95
|
+
|
85
96
|
## 0.0.4
|
86
97
|
|
87
98
|
* fix update/create actions in generated controller
|
data/Guardfile
CHANGED
@@ -3,5 +3,6 @@ guard :rspec, :cli => "--color --format nested --fail-fast" do
|
|
3
3
|
watch(%r|^lib/shoestrap.rb|) { "spec" }
|
4
4
|
watch(%r|^spec/(.*)_spec\.rb|)
|
5
5
|
watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
6
|
+
# watch(%r{^features/.+_feature\.rb})
|
6
7
|
watch(%r|^spec/spec_helper\.rb|) { "spec" }
|
7
8
|
end
|
data/Rakefile
CHANGED
data/circle.yml
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require_relative '../lib/shoestrap/application_generator'
|
2
|
+
|
3
|
+
def generate_test_app_with_shoestrap(options=nil)
|
4
|
+
ENV['SHOESTRAP_PATH'] = File.join(File.dirname(__FILE__), '..')
|
5
|
+
|
6
|
+
if options.is_a?(Hash)
|
7
|
+
aggregated_options = []
|
8
|
+
options.each_pair {|k,v| aggregated_options << "--#{k}=#{v}" }
|
9
|
+
options = aggregated_options.join(' ')
|
10
|
+
aggregated_options = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
app_identifier = test_app_key(options)
|
14
|
+
puts if debug_shoestrap?
|
15
|
+
dbg_comment "[ app with options #{options.inspect} will be known as #{app_identifier.inspect} ]"
|
16
|
+
dbg_comment "[ app without any options would be known as #{test_app_key(nil).inspect} ]" unless options.blank?
|
17
|
+
if Postgres.create_user app_identifier
|
18
|
+
dbg_comment "successfully created postgres user #{app_identifier.inspect}"
|
19
|
+
else
|
20
|
+
dbg_comment "Won't create user #{app_identifier.inspect} while he already exists."
|
21
|
+
end
|
22
|
+
|
23
|
+
app_path = test_app_path(options)
|
24
|
+
result = nil
|
25
|
+
|
26
|
+
if target_app_path || File.exists?(app_path)
|
27
|
+
if File.exists?(app_path)
|
28
|
+
dbg_comment "Application path exists. I will just create the databases now. Pay attention if you have a task that makes something database related."
|
29
|
+
Dir.chdir(app_path) do
|
30
|
+
reload_application_gemfile options
|
31
|
+
Postgres.create_user app_identifier
|
32
|
+
|
33
|
+
# destroy all scaffolds
|
34
|
+
Dir['app/models/*.rb','app/models/cms/*.rb'].each do |path|
|
35
|
+
model_name = File.basename(path).gsub(File.extname(path),'')
|
36
|
+
drop_shoestrap_scaffold_for model_name, options
|
37
|
+
end
|
38
|
+
|
39
|
+
result = bundle_exec 'rake db:drop db:create db:migrate db:seed'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
else
|
43
|
+
dbg_comment "generating test app in #{app_path}"
|
44
|
+
result = bundle_exec shoestrap_new(options)
|
45
|
+
end
|
46
|
+
puts if debug_shoestrap?
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
50
|
+
def shoestrap_new(options = nil)
|
51
|
+
"#{shoestrap_bin_path} new #{test_app_path(options)} #{options}"
|
52
|
+
end
|
53
|
+
|
54
|
+
[:rails, :rake].each do |command|
|
55
|
+
define_method command do |task, options = nil|
|
56
|
+
app_path = test_app_path(options)
|
57
|
+
Dir.chdir(app_path) do
|
58
|
+
dbg_comment "cd #{app_path}"
|
59
|
+
reload_application_gemfile options
|
60
|
+
bundle_exec "#{command} #{task}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def bundle_exec(command)
|
66
|
+
if debug_shoestrap?
|
67
|
+
puts "#{ts} $ bundle exec #{command}"
|
68
|
+
outstr, errstr, status = Open3.capture3('bundle', 'exec', command)
|
69
|
+
|
70
|
+
# a²: why are info-messages in error out?
|
71
|
+
errstr = errstr.split("\n").select{|l| !l.blank? && !(l =~ /^\s*\d\d?:\d\d?:\d\d? - INFO -/) }.join("\n")
|
72
|
+
|
73
|
+
if errstr.present?
|
74
|
+
puts "there where errors while executing the command"
|
75
|
+
puts "\e[0;31m"+errstr.strip+"\e[0m"
|
76
|
+
puts
|
77
|
+
caller.select{|cl| !cl =~ /\/ruby\/gems\// }.each{|called_line| puts called_line }
|
78
|
+
puts
|
79
|
+
end
|
80
|
+
outstr
|
81
|
+
# dbg_comment "command #{command.inspect} finished"
|
82
|
+
else
|
83
|
+
`bundle exec #{command}`
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def dbg_comment( msg )
|
88
|
+
return unless debug_shoestrap?
|
89
|
+
puts " # #{ts} - #{msg}"
|
90
|
+
end
|
91
|
+
|
92
|
+
def ts
|
93
|
+
Time.now.strftime('%H:%M:%S')
|
94
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module FeatureMatcher
|
2
|
+
|
3
|
+
RSpec::Matchers.define :include_gem do |gem_name|
|
4
|
+
match do |gemfile|
|
5
|
+
if gem_name.include? ','
|
6
|
+
gem_name, gem_version = gem_name.split(',').map(&:strip)
|
7
|
+
# gem "shoestrap", "1.0.0.pre1"
|
8
|
+
gemfile =~ /gem\s+['"]#{gem_name}['"]\s*,\s*['"]#{gem_version}['"]/m
|
9
|
+
else
|
10
|
+
gemfile =~ /gem\s+['"]#{gem_name}['"]/m
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
failure_message_for_should do |gemfile|
|
15
|
+
"#{gem_name} should be in Gemfile"
|
16
|
+
end
|
17
|
+
|
18
|
+
failure_message_for_should_not do |gemfile|
|
19
|
+
"#{gem_name} should not be found in Gemfile"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/features/features_helper.rb
CHANGED
@@ -1,44 +1,49 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require 'pry'
|
1
|
+
[
|
2
|
+
'rspec', 'fileutils', 'digest', 'pry', 'open3'
|
3
|
+
].each {|lib| require lib }
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
end
|
5
|
+
[
|
6
|
+
'./postgres_helper', './custom_matcher', './command_wrapper_helper'
|
7
|
+
].each {|lib| require_relative lib }
|
11
8
|
|
12
9
|
# TODO: spec these helpers!
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
11
|
+
JUST_GENERATE_NEW_APP_IF_THESE_ARE_CHANGED = [
|
12
|
+
'lib',
|
13
|
+
'templates'
|
14
|
+
]
|
15
|
+
|
16
|
+
def filetree_fingerprint(dirlist = JUST_GENERATE_NEW_APP_IF_THESE_ARE_CHANGED)
|
17
|
+
aggregated_hashes = ''
|
18
|
+
[dirlist].flatten.sort.each do |dir|
|
19
|
+
Dir[File.join(shoestrap_path, dir, '**/**')].sort.each do |f|
|
20
|
+
aggregated_hashes << (File.directory?(f) ? filetree_fingerprint(f) : Digest::MD5.hexdigest(File.read f).to_s)
|
23
21
|
end
|
24
22
|
end
|
23
|
+
Digest::MD5.hexdigest(aggregated_hashes).to_s
|
25
24
|
end
|
26
25
|
|
27
26
|
def reload_application_gemfile(options=nil)
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
gemfile_path = File.join(application_path(options), 'Gemfile')
|
28
|
+
# dbg_comment "loading Gemfile #{gemfile_path.inspect}; given options #{options.inspect}"
|
29
|
+
ENV['BUNDLE_GEMFILE'] = gemfile_path
|
31
30
|
end
|
32
31
|
|
33
32
|
def clean_up
|
34
33
|
puts
|
35
34
|
puts 'cleaning up...'
|
36
35
|
remove_test_dbs
|
37
|
-
|
36
|
+
drop_database_from_dummy_apps
|
37
|
+
remove_test_apps if on_ci_system?
|
38
|
+
ENV.delete 'SHOESTRAP_PATH'
|
38
39
|
puts
|
39
40
|
puts
|
40
41
|
end
|
41
42
|
|
43
|
+
def drop_database_from_dummy_apps
|
44
|
+
Postgres.drop_users_like 'test_app%'
|
45
|
+
end
|
46
|
+
|
42
47
|
def test_apps
|
43
48
|
Dir.entries(File.join(File.dirname(__FILE__))).select do |entry|
|
44
49
|
entry.include? 'test_app'
|
@@ -55,11 +60,33 @@ end
|
|
55
60
|
def remove_test_dbs
|
56
61
|
test_apps.each do |app|
|
57
62
|
Dir.chdir app do
|
58
|
-
|
63
|
+
next unless Postgres.database_exists?(app.split('/').last + '_test')
|
64
|
+
puts "dropping test db for #{app}" if debug_shoestrap?
|
59
65
|
ENV['BUNDLE_GEMFILE'] = File.join(Dir.pwd, 'Gemfile')
|
60
66
|
require 'bundler'
|
61
67
|
Bundler.require(:default)
|
62
|
-
|
68
|
+
bundle_exec 'rake db:drop'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
Postgres.drop_databases_like('test_app_%')
|
72
|
+
end
|
73
|
+
|
74
|
+
def drop_shoestrap_scaffold_for(name, options = nil)
|
75
|
+
%w(production development test).each do |db_env|
|
76
|
+
app_path = test_app_path(options)
|
77
|
+
unless File.exists? app_path
|
78
|
+
dbg_comment "won't destroy scaffold for #{name.inspect} while app #{app_path} doesn't exist."
|
79
|
+
return
|
80
|
+
end
|
81
|
+
|
82
|
+
Dir.chdir(app_path) do
|
83
|
+
database_name = app_path.split('/').last
|
84
|
+
rails "destroy scaffold #{name}", options
|
85
|
+
rails "destroy scaffold cms/#{name}", options
|
86
|
+
database = "#{database_name}_#{db_env}"
|
87
|
+
next unless Postgres.database_exists? database
|
88
|
+
# Postgres.select_database database
|
89
|
+
Postgres.drop_table database_name, database, name
|
63
90
|
end
|
64
91
|
end
|
65
92
|
end
|
@@ -68,6 +95,14 @@ def application_path(options = nil)
|
|
68
95
|
target_app_path || test_app_path(options)
|
69
96
|
end
|
70
97
|
|
98
|
+
def shoestrap_path
|
99
|
+
File.expand_path(File.join(File.dirname(__FILE__),'../'))
|
100
|
+
end
|
101
|
+
|
102
|
+
def shoestrap_bin_path
|
103
|
+
File.join(shoestrap_path, 'bin/shoestrap')
|
104
|
+
end
|
105
|
+
|
71
106
|
def target_app_path
|
72
107
|
ENV['TARGET_APP']
|
73
108
|
end
|
@@ -81,11 +116,23 @@ def application_file(file, options = nil)
|
|
81
116
|
end
|
82
117
|
|
83
118
|
def test_app_key(options)
|
84
|
-
|
119
|
+
app_hash = options.to_s.strip.gsub(/\W+/,'') + filetree_fingerprint
|
120
|
+
# a²: we need to limit the size due to maximum database name sizes in postgres
|
121
|
+
"test_app_#{(app_hash.size > 42) ? Digest::MD5.hexdigest(app_hash) : app_hash}"[0..42]
|
85
122
|
end
|
86
123
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
124
|
+
def debug_shoestrap?; !!ENV['DEBUG'] end
|
125
|
+
|
126
|
+
def on_ci_system?
|
127
|
+
ENV['TRAVIS'] || ENV['CI'] || ENV['CIRCLECI']
|
91
128
|
end
|
129
|
+
|
130
|
+
RSpec.configure do |config|
|
131
|
+
config.include(FeatureMatcher)
|
132
|
+
config.after(:suite) do
|
133
|
+
clean_up
|
134
|
+
end
|
135
|
+
config.before(:suite) do
|
136
|
+
remove_test_apps if ENV['REMOVE_CACHE_AT_FIRST']
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Postgres
|
2
|
+
class << self
|
3
|
+
def exec(query, opts = {})
|
4
|
+
command = ["psql -tAc \"#{query}\""]
|
5
|
+
|
6
|
+
if opts.is_a?(Hash)
|
7
|
+
opts.each_pair {|k,v| command << "--#{k}=#{v}" }
|
8
|
+
else
|
9
|
+
command << opts
|
10
|
+
end
|
11
|
+
|
12
|
+
command = command.join(' ')
|
13
|
+
puts "#{ts} $ #{command}" if debug_shoestrap?
|
14
|
+
result = `#{command}`
|
15
|
+
if result.match(/psql: FATAL: database .+ does not exist/)
|
16
|
+
if result.include?("psql: FATAL: database \"#{`whoami`.strip}\" does not exist")
|
17
|
+
`createdb`
|
18
|
+
dbg_comment "user database was missing. I created it for you and recall the postgres command again. :)"
|
19
|
+
`#{command}`
|
20
|
+
end
|
21
|
+
else
|
22
|
+
result
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def user_exists?(username)
|
27
|
+
exec("SELECT 1 FROM pg_user WHERE usename='#{username}'", {dbname: 'postgres'}).strip == '1'
|
28
|
+
end
|
29
|
+
|
30
|
+
def database_exists?(name)
|
31
|
+
exec("SELECT 1 from pg_database WHERE datname='#{name}'", {dbname: 'postgres'}).strip == '1'
|
32
|
+
end
|
33
|
+
|
34
|
+
def drop_user(username)
|
35
|
+
puts "#{ts} $ dropuser #{username}" if debug_shoestrap?
|
36
|
+
`dropuser #{username}`
|
37
|
+
end
|
38
|
+
|
39
|
+
def drop_table(user, database, name)
|
40
|
+
exec("SET client_min_messages TO WARNING; DROP TABLE IF EXISTS #{name};", {username: user, dbname: database})
|
41
|
+
end
|
42
|
+
|
43
|
+
def select_users_like(username)
|
44
|
+
exec("SELECT usename FROM pg_user where usename LIKE '#{username}'", {dbname: 'postgres'}).split("\n").map{|u| u.strip }
|
45
|
+
end
|
46
|
+
|
47
|
+
def select_databases_like(name)
|
48
|
+
exec("SELECT datname FROM pg_database WHERE datistemplate = false AND datname LIKE '#{name}';", {dbname: 'postgres'}).split("\n").map{|u| u.strip }
|
49
|
+
end
|
50
|
+
|
51
|
+
def drop_databases_like(name)
|
52
|
+
select_databases_like(name).each{|dbname| `dropdb #{dbname}` }
|
53
|
+
end
|
54
|
+
|
55
|
+
def drop_users_like(username)
|
56
|
+
select_users_like(username).each{|u| drop_user u if user_exists?(u) }
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_user(username)
|
60
|
+
if user_exists?(username)
|
61
|
+
false
|
62
|
+
else
|
63
|
+
puts "#{ts} $ createuser -s #{username}" if debug_shoestrap?
|
64
|
+
`createuser -s #{username}`
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,234 @@
|
|
1
|
+
require_relative '../../features_helper'
|
2
|
+
|
3
|
+
describe 'application generated with shoestrap new <application_name>' do
|
4
|
+
before :all do
|
5
|
+
generate_test_app_with_shoestrap
|
6
|
+
end
|
7
|
+
|
8
|
+
let (:gemfile_content) { application_file('Gemfile') }
|
9
|
+
let (:application_rb_content) { application_file('config/application.rb') }
|
10
|
+
let (:application_layout) { application_file('app/views/layouts/application.html.haml') }
|
11
|
+
let (:application_layout_typekit) { application_file('app/views/layouts/_typekit.html.haml') }
|
12
|
+
let (:application_helper) { application_file('app/helpers/application_helper.rb') }
|
13
|
+
let (:development_rb_content) { application_file('config/environments/development.rb') }
|
14
|
+
|
15
|
+
it 'has timezone set for switzerland' do
|
16
|
+
expect(application_rb_content).to match(/config.time_zone = 'Bern'/)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'has :de as default locale' do
|
20
|
+
expect(application_rb_content).to match(/config.i18n.default_locale = :de/)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'has :de as only available locale for a satrt' do
|
24
|
+
expect(application_rb_content).to match(/config.i18n.available_locales = \[:de\]/)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'has translation files load path' do
|
28
|
+
expect(application_rb_content).to match(/config.i18n.load_path \+= Dir\[Rails.root.join\('config', 'locales', '\*\*', '\*.{rb,yml}'\).to_s\]/)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'has the shoestrap version in test set to the current path in Gemfile' do
|
32
|
+
expect(gemfile_content.split("\n")).to include("gem \"shoestrap\", path: \"#{Dir.pwd + '/features/..'}\"")
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'has the typekit key set to false' do
|
36
|
+
expect(application_rb_content).to match(/config.typekit_key = false/)
|
37
|
+
end
|
38
|
+
|
39
|
+
# TODO: fix this in rails. Gems added with gem method of app template have double quotes!
|
40
|
+
|
41
|
+
%w[
|
42
|
+
simple_form
|
43
|
+
haml
|
44
|
+
haml-rails
|
45
|
+
simple-navigation
|
46
|
+
mail
|
47
|
+
fabrication
|
48
|
+
kuhsaft
|
49
|
+
selectivizr-rails
|
50
|
+
modernizr-rails
|
51
|
+
bourbon
|
52
|
+
therubyracer
|
53
|
+
shoestrap
|
54
|
+
inherited_resources
|
55
|
+
].each do |gem_name|
|
56
|
+
it "has #{gem_name} in the Gemfile" do
|
57
|
+
expect(gemfile_content).to include_gem(gem_name)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
%w[
|
62
|
+
pry
|
63
|
+
database_cleaner
|
64
|
+
guard-rspec
|
65
|
+
guard-spring
|
66
|
+
rspec-rails
|
67
|
+
mailcatcher
|
68
|
+
].each do |gem_name|
|
69
|
+
it "has #{gem_name} in the Gemfile" do
|
70
|
+
expect(gemfile_content).to include_gem(gem_name)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'has the pg gem in the Gemfile' do
|
75
|
+
expect(gemfile_content).to include_gem('pg')
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'application layout' do
|
79
|
+
it 'has no application layout written in erb' do
|
80
|
+
expect { application_file('app/views/layouts/application.html.erb') }.to raise_error(Errno::ENOENT)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'has an application layout written in haml' do
|
84
|
+
expect(application_layout).not_to be_nil
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'sets the html lang' do
|
88
|
+
expect(application_layout).to match "%html.no-js{ lang: I18n.locale }"
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'sets a page title' do
|
92
|
+
expect(application_layout).to match(/%title=\ content_for\?\(:title\)\ \?\ yield\(:title\)\ :\ 'Untitled'/)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'has meta tags' do
|
96
|
+
expect(application_layout).to match "%meta{ charset: 'utf-8' }"
|
97
|
+
expect(application_layout).to match "%meta{ 'http-equiv' => 'X-UA-Compatible', content: 'IE=edge,chrome=1' }"
|
98
|
+
expect(application_layout).to match "%meta{ name: 'keywords', content: '' }"
|
99
|
+
expect(application_layout).to match "%meta{ name: 'description', content: '' }"
|
100
|
+
expect(application_layout).to match "%meta{ name: 'viewport', content: 'width=device-width, initial-scale=1.0' }"
|
101
|
+
expect(application_layout).to match "= csrf_meta_tags"
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'has favicons' do
|
105
|
+
expect(application_layout).to match(/favicon_link_tag\('favicons\/favicon\-sc\-129x129\.png',\ rel:\ 'apple\-touch\-icon',\ type:\ 'image\/png'\)/)
|
106
|
+
expect(application_layout).to match(/favicon_link_tag\('favicons\/favicon\-sc\-32x32\.png',\ rel:\ 'icon',\ type:\ 'image\/png'\)/)
|
107
|
+
expect(application_layout).to match(/favicon_link_tag\('favicons\/favicon\-sc\-16x16\.ico'\)/)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'has an application stylehseet link' do
|
111
|
+
expect(application_layout).to match "= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true"
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'has javascript links' do
|
115
|
+
expect(application_layout).to match "= javascript_include_tag 'modernizr', 'data-turbolinks-track' => true"
|
116
|
+
expect(application_layout).to match "= javascript_include_tag 'application', 'data-turbolinks-track' => true"
|
117
|
+
expect(application_layout).to match "= javascript_include_tag 'selectivizr'"
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'has a body class helper included' do
|
121
|
+
expect(application_layout).to match "%body{ class: body_class }"
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'renders the navigation' do
|
125
|
+
expect(application_layout).to match "= render_navigation"
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'renders the content' do
|
129
|
+
expect(application_layout).to match "= yield"
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'renders the typekit' do
|
133
|
+
expect(application_layout).to match "= render 'layouts/typekit'"
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'has google analytics integrated' do
|
137
|
+
expect(application_layout).to match(/var\ _gaq=\[\['_setAccount','UA\-XXXXX\-X'\],\['_trackPageview'\],\['_trackPageLoadTime'\]\];/)
|
138
|
+
expect(application_layout).to match(/\(function\(d,t\)\{var\ g=d\.createElement\(t\),s=d\.getElementsByTagName\(t\)\[0\];g\.async=1;/)
|
139
|
+
expect(application_layout).to match(/g\.src=\('https:'==location\.protocol\?'\/\/ssl':'\/\/www'\)\+'\.google\-analytics\.com\/ga\.js';/)
|
140
|
+
expect(application_layout).to match(/s\.parentNode\.insertBefore\(g,s\)\}\(document,'script'\)\);/)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context 'documentation file' do
|
145
|
+
|
146
|
+
it 'contains proper documentation' do
|
147
|
+
pending "implement proper readme template"
|
148
|
+
expect(application_file('README.md')).not_to match('README would normally document whatever steps are necessary to get the')
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'favicons' do
|
153
|
+
it 'has a favicon' do
|
154
|
+
expect(application_file('app/assets/images/favicons/favicon-sc-32x32.png')).not_to be_nil
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'has a favicon for iDevices' do
|
158
|
+
expect(application_file('app/assets/images/favicons/favicon-sc-129x129.png')).not_to be_nil
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'has a favicton for IE' do
|
162
|
+
expect(application_file('app/assets/images/favicons/favicon-sc-16x16.ico')).not_to be_nil
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'layout partials' do
|
167
|
+
it 'has a typekit partial' do
|
168
|
+
expect(application_layout_typekit).not_to be_nil
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'typekit partial' do
|
172
|
+
it 'checks for typekit_key configuration' do
|
173
|
+
expect(application_layout_typekit).to match "- if Rails.application.config.typekit_key.present?"
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'has the typekit js integrated' do
|
177
|
+
expect(application_layout_typekit).to match(/javascript_include_tag\ "\/\/use\.typekit\.net\/\#\{Rails\.application\.config\.typekit_key\}\.js",\ :media\ =>\ 'all'/)
|
178
|
+
expect(application_layout_typekit).to match(/try\{Typekit\.load\(\);\}catch\(e\)\{\}/)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'application helper' do
|
184
|
+
it 'has an application layout written in haml' do
|
185
|
+
expect(application_helper).not_to be_nil
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'has a body_class method' do
|
189
|
+
expect(application_helper).to match "def body_class"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context 'generators' do
|
194
|
+
it 'use haml as a template engine' do
|
195
|
+
expect(application_rb_content).to match "g.template_engine :haml"
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'use rspec as test framework' do
|
199
|
+
expect(application_rb_content).to match "test_framework :rspec"
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'do not generate stylesheets' do
|
203
|
+
expect(application_rb_content).to match "g.stylesheets false"
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'do not generate javascripts' do
|
207
|
+
expect(application_rb_content).to match "g.javascripts false"
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'do not generate assets' do
|
211
|
+
expect(application_rb_content).to match "g.assets false"
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'does not generate helpers' do
|
215
|
+
expect(application_rb_content).to match "g.helper false"
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'uses simple_form as form builder' do
|
219
|
+
expect(application_rb_content).to match(/form_builder :simple_form/)
|
220
|
+
end
|
221
|
+
|
222
|
+
|
223
|
+
context 'mailcatcher' do
|
224
|
+
it 'is configured for development environment' do
|
225
|
+
expect(development_rb_content).to match(/config\.action_mailer\.delivery_method = :smtp/)
|
226
|
+
expect(development_rb_content).to match(/config\.action_mailer\.smtp_settings = { address: 'localhost', port: 1025 }/)
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'is documented in the readme' do
|
230
|
+
expect(application_file('README.md')).to match(/This application uses Mailcatcher/)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|