maximus 0.1.5.1 → 0.1.6.1

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.
@@ -1,4 +1,5 @@
1
1
  module Maximus
2
+ # Evaluates quality of scss
2
3
  # @since 0.1.0
3
4
  class Scsslint < Maximus::Lint
4
5
 
@@ -6,8 +7,7 @@ module Maximus
6
7
  # @see Lint#initialize
7
8
  def result
8
9
  @task = 'scsslint'
9
- @path = is_rails? ? "#{@settings[:root_dir]}/app/assets/stylesheets" : "#{@settings[:root_dir]}/source/assets/stylesheets" if @path.blank?
10
-
10
+ @path = discover_path(@config.working_dir, 'stylesheets')
11
11
  return unless temp_config(@task) && path_exists?(@path)
12
12
 
13
13
  scss = `scss-lint #{@path} -c #{temp_config(@task)} --format=JSON`
@@ -1,7 +1,6 @@
1
1
  #!/bin/bash
2
2
 
3
3
  # http://stackoverflow.com/questions/8259851/using-git-diff-how-can-i-get-added-and-modified-lines-numbers
4
- # @todo this function is tricky because I don't fully understand regex in BASH. Also, getting line hunks from git is tricky. This will likely need to be refactored
5
4
  function lines-added(){
6
5
  local path=
7
6
  local line=
@@ -64,10 +64,8 @@ module Maximus
64
64
  stats = JSON.parse(stats_cli)
65
65
  @output[:statistics][file_path.to_s] ||= {}
66
66
 
67
- # @todo is there a better way to do this?
68
67
  fp = @output[:statistics][file_path.to_s]
69
68
 
70
- # @todo Can I do like a self << thing here?
71
69
  stats.each do |stat, value|
72
70
  fp[stat.to_sym] = value
73
71
  end
@@ -1,9 +1,9 @@
1
1
  module Maximus
2
+ # Evaluate page performance
2
3
  # @since 0.1.0
3
4
  class Phantomas < Maximus::Statistic
4
5
 
5
- # Phantomas evaluates page performance with phantomjs and node
6
- #
6
+ # Run phantomas through the command line
7
7
  # @see Statistic#initialize
8
8
  def result
9
9
 
@@ -18,7 +18,7 @@ module Maximus
18
18
  # Phantomas doesn't actually skip the skip-modules defined in the config BUT here's to hoping for future support
19
19
  phantomas_cli = "phantomas --config=#{@settings[:phantomas]} "
20
20
  phantomas_cli += @config.is_dev? ? '--colors' : '--reporter=json:no-skip'
21
- phantomas_cli += " --proxy=#{@domain}"
21
+ phantomas_cli << " --proxy=#{@domain}" if @domain.include?('localhost')
22
22
  @path.is_a?(Hash) ? @path.each { |label, url| phantomas_by_url(url, phantomas_cli) } : phantomas_by_url(@path, phantomas_cli)
23
23
  @output
24
24
  end
@@ -1,8 +1,9 @@
1
1
  module Maximus
2
+ # Produce CSS statistics
2
3
  # @since 0.1.0
3
4
  class Stylestats < Maximus::Statistic
4
5
 
5
- # Produces CSS statistics
6
+ # Requires node
6
7
  # @see Statistic#initialize
7
8
  def result
8
9
 
@@ -11,7 +12,7 @@ module Maximus
11
12
  node_module_exists('stylestats')
12
13
 
13
14
  if @path.blank?
14
- @path = is_rails? ? "#{@settings[:root_dir]}/public/assets/**/*.css" : "#{@settings[:root_dir]}/**/*.css"
15
+ @path = is_rails? ? "#{@config.working_dir}/public/assets/**/*.css" : "#{@config.working_dir}/**/*.css"
15
16
  end
16
17
 
17
18
  if @path.is_a?(Array)
@@ -21,20 +22,7 @@ module Maximus
21
22
  css_files = find_css
22
23
  end
23
24
 
24
- css_files.each do |file|
25
-
26
- # For Rails, we only want the name of the compiled asset, because we know it'll live in public/assets.
27
- # If this isn't Rails, sure, give me the full path because the directory structure is likely unique
28
- pretty_name = is_rails? ? file.split('/').pop.gsub(/(-{1}[a-z0-9]{32}*\.{1}){1}/, '.') : file
29
-
30
- puts "#{'stylestats'.color(:green)}: #{pretty_name}\n\n"
31
-
32
- # include JSON formatter unless we're in dev
33
- stylestats = `stylestats #{file} --config=#{@settings[:stylestats]} #{'--type=json' unless @config.is_dev?}`
34
- refine(stylestats, pretty_name)
35
-
36
- File.delete(file)
37
- end
25
+ css_files.each { |file| stylestats_report(file) }
38
26
 
39
27
  destroy_assets if @settings[:compile_assets]
40
28
  @output
@@ -94,23 +82,22 @@ module Maximus
94
82
  # @return [Array] compiled css files
95
83
  def compile_scss_rails
96
84
  searched_files = []
97
- # @todo I'd rather Rake::Task but it's not working in different directories
98
- Dir.chdir(@settings[:root_dir]) do
99
- if @config.is_dev?
100
- # @todo review that this may not be best practice, but it's really noisy in the console
101
- quietly { `rake assets:precompile` }
102
- else
103
- `rake assets:precompile`
104
- end
85
+ # I'd rather Rake::Task but it's not working in different directories
86
+ if @config.is_dev?
87
+ # @todo review that this may not be best practice, but it's really noisy in the console
88
+ quietly { `rake -f #{@config.working_dir}/Rakefile assets:precompile` }
89
+ else
90
+ `rake -f #{@config.working_dir}/Rakefile assets:precompile`
105
91
  end
106
92
  end
107
93
 
108
94
  # Turn scss files into css files
95
+ # Skips if the file starts with an underscore
109
96
  # @see find_css_files
110
97
  # @since 0.1.5
111
98
  def compile_scss_normal
112
99
  Dir["#{@path}.scss"].select { |f| File.file? f }.each do |file|
113
- # @todo don't compile file if it starts with an underscore
100
+ next if File.basename(file).chr == '_'
114
101
  scss_file = File.open(file, 'rb') { |f| f.read }
115
102
 
116
103
  output_file = File.open( file.split('.').reverse.drop(1).reverse.join('.'), "w" )
@@ -124,14 +111,12 @@ module Maximus
124
111
  def destroy_assets
125
112
 
126
113
  if is_rails?
127
- # @todo I'd rather Rake::Task but it's not working in different directories
128
- Dir.chdir(@settings[:root_dir]) do
129
- if @config.is_dev?
130
- # @todo review that this may not be best practice, but it's really noisy in the console
131
- quietly { `rake assets:clobber` }
132
- else
133
- `rake assets:clobber`
134
- end
114
+ # I'd rather Rake::Task but it's not working in different directories
115
+ if @config.is_dev?
116
+ # @todo review that this may not be best practice, but it's really noisy in the console
117
+ quietly { `rake -f #{@config.working_dir}/Rakefile assets:clobber` }
118
+ else
119
+ `rake -f #{@config.working_dir}/Rakefile assets:clobber`
135
120
  end
136
121
  end
137
122
 
@@ -144,5 +129,24 @@ module Maximus
144
129
  Dir.glob(path).select { |f| File.file? f }.map { |file| file }
145
130
  end
146
131
 
132
+ # Present stylestat result of a CSS file
133
+ # Deletes file at end
134
+ # @since 0.1.6
135
+ # @see #result
136
+ # @param file [String] path to file
137
+ def stylestats_report(file)
138
+ # For Rails, we only want the name of the compiled asset, because we know it'll live in public/assets.
139
+ # If this isn't Rails, sure, give me the full path because the directory structure is likely unique
140
+ pretty_name = is_rails? ? file.split('/').pop.gsub(/(-{1}[a-z0-9]{32}*\.{1}){1}/, '.') : file
141
+
142
+ puts "#{'stylestats'.color(:green)}: #{pretty_name}\n\n"
143
+
144
+ # include JSON formatter unless we're in dev
145
+ stylestats = `stylestats #{file} --config=#{@settings[:stylestats]} #{'--type=json' unless @config.is_dev?}`
146
+ refine(stylestats, pretty_name)
147
+
148
+ File.delete(file)
149
+ end
150
+
147
151
  end
148
152
  end
@@ -1,9 +1,9 @@
1
1
  module Maximus
2
+ # Generates screenshots for visual regression testing
2
3
  # @since 0.1.0
3
4
  class Wraith < Maximus::Statistic
4
5
 
5
- # Generates screenshots for visual regression testing
6
- #
6
+ # Runs Wraith through command line
7
7
  # WARNING: If you call this class from a script,
8
8
  # you should delete the images generated after they've been
9
9
  # created.
@@ -30,20 +30,8 @@ module Maximus
30
30
  # in each wraith config file.
31
31
  # @yieldparam browser [String] headless browser name
32
32
  # @yieldparam configpath [String] path to temp config file (see Config#wraith_setup)
33
- @settings[:wraith].each do |browser, configpath|
34
- next unless File.file?(configpath) # prevents abortive YAML error if it can't find the file
35
- wraith_yaml = YAML.load_file(configpath)
36
- if File.directory?("#{@settings[:root_dir]}/#{wraith_yaml['history_dir']}")
37
- puts `wraith latest #{configpath}`
33
+ @settings[:wraith].each { |browser, configpath| wraith_report(browser, configpath) }
38
34
 
39
- # Reset history dir
40
- # It puts the new shots in the history folder, even with absolute paths in the config.
41
- # Could be a bug in wraith.
42
- FileUtils.remove_dir("#{@settings[:root_dir]}/#{wraith_yaml['history_dir']}")
43
- end
44
- wraith_parse browser unless @config.is_dev?
45
- puts `wraith history #{configpath}`
46
- end
47
35
  @output
48
36
 
49
37
  end
@@ -57,7 +45,7 @@ module Maximus
57
45
  # @param browser [String] headless browser used to generate the gallery
58
46
  # @return [Hash] { path: { browser, path_label, percent_changed: { size: percent_diff ] } }
59
47
  def wraith_parse(browser)
60
- Dir.glob("#{@settings[:root_dir]}/maximus_wraith_#{browser}/**/*").select { |f| File.file? f }.each do |file|
48
+ Dir.glob("#{@config.working_dir}/maximus_wraith_#{browser}/**/*").select { |f| File.file? f }.each do |file|
61
49
  extension = File.extname(file)
62
50
  next unless extension == '.png' || extension == '.txt'
63
51
 
@@ -116,5 +104,26 @@ module Maximus
116
104
  image.path
117
105
  end
118
106
 
107
+ # Generate thumbnails and history for each browser in the wraith config
108
+ # @since 0.1.6
109
+ # @see #result
110
+ # @param browser [String]
111
+ # @param configpath [String]
112
+ def wraith_report(browser, configpath)
113
+ return unless File.file?(configpath) # prevents abortive YAML error if it can't find the file
114
+ wraith_yaml = YAML.load_file(configpath)
115
+ if File.directory?(File.join(@config.working_dir, wraith_yaml['history_dir']))
116
+ puts `wraith latest #{configpath}`
117
+
118
+ # Reset history dir
119
+ # It puts the new shots in the history folder, even with absolute paths in the config.
120
+ # Could be a bug in wraith.
121
+ FileUtils.remove_dir(File.join(@config.working_dir, wraith_yaml['history_dir']))
122
+ end
123
+
124
+ wraith_parse browser unless @config.is_dev?
125
+ puts `wraith history #{configpath}`
126
+ end
127
+
119
128
  end
120
129
  end
@@ -1,3 +1,3 @@
1
1
  module Maximus
2
- VERSION = "0.1.5.1"
2
+ VERSION = "0.1.6.1"
3
3
  end
@@ -19,16 +19,17 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_runtime_dependency "git", "~> 1.2.9"
22
- spec.add_runtime_dependency "scss-lint", "~> 0.33.0"
22
+ spec.add_runtime_dependency "scss-lint", "~> 0.34.0"
23
23
  spec.add_runtime_dependency "rainbow", "2.0.0"
24
- spec.add_runtime_dependency "rubocop", "~> 0.28"
24
+ spec.add_runtime_dependency "rubocop", "~> 0.29"
25
25
  spec.add_runtime_dependency "rails_best_practices", "~> 1.15"
26
26
  spec.add_runtime_dependency "brakeman", "~> 3.0.1"
27
- spec.add_runtime_dependency "wraith", "~> 2.3"
27
+ spec.add_runtime_dependency "wraith", "~> 2.3.2"
28
28
  spec.add_runtime_dependency "activesupport"
29
29
  spec.add_runtime_dependency "thor"
30
30
 
31
31
  spec.add_development_dependency "bundler", "~> 1.6"
32
+ spec.add_development_dependency "pry-byebug", "~> 3.0"
32
33
  spec.add_development_dependency "yard", "~> 0.8"
33
34
  spec.add_development_dependency "rspec", "~> 3.0"
34
35
  spec.add_development_dependency "coveralls", "~> 0.7.8"
data/roadmap.md CHANGED
@@ -1,17 +1,12 @@
1
1
  # Roadmap
2
2
 
3
- * Check for custom lint or stat hooks in a lib/maximus folder. Add custom lint path and script execution support to maximus.yml config file
4
- * Use PhantomJS 2.0 with webfont support
5
3
  * Resolve/review @todos
6
- * Convert ruby-git to rugged (MAYBE - rugged requires libgit2)
7
- * Add SCSS specificity graph
8
- * Add HAML lint (maybe)
9
4
  * Add CSS lint (maybe)
10
5
  * Add JSLint (maybe)
11
6
  * Add W3 validator (maybe)
12
- * Add Markdown lint (maybe)
13
7
  * Add Flog support (maybe)
14
8
  * Add Flay support (maybe)
15
- * Regex path names on phantomas and wraith to defend against injection and bad characters
16
- * Test for < ruby 2.0 or require 2.0 < in gemspec
9
+ * Add PHP CodeSniffer (maybe)
10
+ * Add PHPMetrics (maybe)
11
+ * Use PHP's built-in linter (maybe)
17
12
  * If no files to inspect in working, say so
@@ -1,15 +1,78 @@
1
1
  require 'spec_helper'
2
+ require 'support/config_helper'
2
3
 
3
4
  describe Maximus::Config do
4
- let(:config_path) { '.maximus.yml' }
5
5
 
6
+ include ConfigHelper
7
+
8
+ let(:config_body) { '' }
6
9
  subject(:config) do
7
- File.write(config_path, config_body)
8
- config_contents = config_body.blank? ? {} : { config_file: config_path }
9
- described_class.new(config_contents)
10
+ create_config(config_body)
11
+ end
12
+
13
+ after(:each) { destroy_config }
14
+
15
+ describe 'options in general', :isolated_environment do
16
+ context 'options are passed directly' do
17
+ it 'should read the options as is' do
18
+ conf = described_class.new({port: 1000})
19
+
20
+ expect(conf.settings[:port]).to eq 1000
21
+ end
22
+ end
23
+
24
+ context 'options are passed through a file' do
25
+ let(:config_body) { 'port: 1000' }
26
+ it 'should parse the file accurately' do
27
+ expect(config.settings[:port]).to eq 1000
28
+ end
29
+ end
30
+
31
+ context 'options are passed through a file and directly' do
32
+ let(:config_body) { 'port: 1000' }
33
+ it 'should prefer the direct options' do
34
+ conf = described_class.new({port: 1001, config_file: '.maximus.yml'})
35
+ expect(conf.settings[:port]).to eq 1001
36
+ end
37
+ end
38
+
10
39
  end
11
40
 
12
- describe '#is_dev?', :isolated_environment do
41
+ describe 'config file loading (load_confg_file)', :isolated_environment do
42
+
43
+ context 'only maximus.yml is available' do
44
+ it 'should take the settings in maximus.yml' do
45
+ create_config('port: 1001', 'maximus.yml')
46
+ conf = described_class.new
47
+
48
+ expect(conf.settings[:port]).to eq 1001
49
+ destroy_config('maximus.yml')
50
+ end
51
+ end
52
+
53
+ context '.maximus.yml and maximus.yml are available' do
54
+ it 'should prefer .maximus.yml' do
55
+ create_config('port: 1000', '.maximus.yml')
56
+ create_config('port: 1001', 'maximus.yml')
57
+ conf = described_class.new
58
+
59
+ expect(conf.settings[:port]).to eq 1000
60
+ destroy_config('maximus.yml')
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ describe '.working_dir', :isolated_environment do
67
+ context 'root_dir is applied in the config' do
68
+ let(:config_body) { 'root_dir: some/fake/directory' }
69
+ it 'should equal the config setting' do
70
+ expect(config.working_dir).to eq 'some/fake/directory'
71
+ end
72
+ end
73
+ end
74
+
75
+ describe '.is_dev?', :isolated_environment do
13
76
  context 'setting root value is_dev to true' do
14
77
  let(:config_body) { 'is_dev: true' }
15
78
  it 'should be true' do
@@ -18,32 +81,30 @@ describe Maximus::Config do
18
81
  end
19
82
 
20
83
  context 'is blank/not supplied' do
21
- let(:config_body) { '' }
22
84
  it 'should default to false' do
23
85
  expect(config.is_dev?).to be false
24
86
  end
25
87
  end
26
88
  end
27
89
 
28
- describe '#initialize', :isolated_environment do
90
+ describe '.initialize', :isolated_environment do
29
91
 
30
92
  context 'setting a linter to be true' do
31
93
  let(:config_body) { 'scsslint: true' }
32
94
  it 'scsslint should exist' do
33
- expect(config.settings.has_key?(:scsslint)).to be true
95
+ expect(config.settings.key?(:scsslint)).to be true
34
96
  end
35
97
  end
36
98
 
37
99
  context 'not supplying a linter but relying on the default' do
38
- let(:config_body) { '' }
39
100
  it 'should include a linter' do
40
- expect(config.settings.has_key?(:scsslint)).to be true
101
+ expect(config.settings.key?(:scsslint)).to be true
41
102
  end
42
103
  end
43
104
 
44
105
  end
45
106
 
46
- describe '#domain', :isolated_environment do
107
+ describe '.domain', :isolated_environment do
47
108
 
48
109
  context 'domain is provided' do
49
110
 
@@ -83,7 +144,7 @@ describe Maximus::Config do
83
144
 
84
145
  end
85
146
 
86
- describe '#split_paths', :isolated_environment do
147
+ describe '.split_paths', :isolated_environment do
87
148
 
88
149
  context 'an array is provided' do
89
150
  let(:config_body) { "paths: \n - '/'\n - '/about'"}
@@ -100,7 +161,6 @@ describe Maximus::Config do
100
161
  end
101
162
 
102
163
  context 'nothing is provided' do
103
- let(:config_body) { '' }
104
164
  it 'should return the default path with label' do
105
165
  expect( config.settings[:paths] ).to eq ({ 'home' => '/'})
106
166
  end
@@ -111,10 +171,29 @@ describe Maximus::Config do
111
171
  describe '#load_config', :isolated_environment do
112
172
 
113
173
  context 'a file path is provided' do
114
- let(:config_body) { 'rubocop: spec/support/rubocop.yml' }
115
- it 'should load the file' do
116
- expect( YAML.load_file(config.settings[:rubocop])['Rubolinter'] ).to be true
174
+
175
+ context 'at a local address' do
176
+ let(:config_body) { 'rubocop: spec/support/rubocop.yml' }
177
+ it 'should load the file' do
178
+ expect( YAML.load_file(config.settings[:rubocop])['Rubolinter'] ).to be true
179
+ end
180
+ end
181
+
182
+ context 'at an available remote address' do
183
+ let(:config_body) { 'rubocop: "https://raw.githubusercontent.com/wearefine/standards/master/linters/.rubocop.yml" ' }
184
+ it 'should load the file' do
185
+ expect( YAML.load_file(config.settings[:rubocop]) ).to be_a(Hash)
186
+ end
117
187
  end
188
+
189
+ context 'at an unavailable remote address' do
190
+ let(:config_body) { 'rubocop: "http://raw.githubusercontent.com/wearefine/standards/master/linters/nonexistent_file.yml" ' }
191
+ it 'should report an error and return an empty hash' do
192
+ STDOUT.should_receive(:puts).with('http://raw.githubusercontent.com/wearefine/standards/master/linters/nonexistent_file.yml not accessible')
193
+ expect( YAML.load_file(config.settings[:rubocop]) ).to eq({})
194
+ end
195
+ end
196
+
118
197
  end
119
198
 
120
199
  context 'settings are provided' do