shoestrap 1.0.0.pre1 → 1.0.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|