marmara 1.0 → 1.0.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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +63 -17
  3. data/lib/marmara/parser.rb +19 -0
  4. data/lib/marmara.rb +38 -21
  5. metadata +31 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: caffd5bb8874fcb945d1afd57aa80bf8f214783a
4
- data.tar.gz: cd9f49013b3b591c9620d1193cb801832375c7d3
3
+ metadata.gz: a30c4afdfc40d807cee2c3e6dd4f2e02bd895530
4
+ data.tar.gz: 675fc30f309c95239b6853e7435fadec407773c4
5
5
  SHA512:
6
- metadata.gz: a6d5ce21997d98f2fc262af141e2bcdc233a03da0c4a23f670f06d0c4d13cb53beb4a831a26e27e2059474ddf4791498721cba33929949e4af094fb1f09344c0
7
- data.tar.gz: f34584cfe0a76c92472e4c14d34e537323165b2bf3107f5e5f0b824e06d665c9ce59dbb246e3a501f59e00af1856c24ff504cb2db3ccec0b9074d1a834a00e98
6
+ metadata.gz: 7c635c1f1e7ad3984ef846f31ac06c5ea469040d99d6f7ef9ffe708cbe8966b9f9da8ab9ccd765bc4e9a12cc3e9a03ebdfcefacc5527f6b845eddd2c127d895f
7
+ data.tar.gz: 7bff9f22acbd90c6c3df8acb5a7712b943449da663b73ff17c1b0f0ab6d9599e0355ab41643156e35c432ac21d1f017ec57e65c7f6db9efba9ecee70d2962e49
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Marmara
2
2
  Marmara is a Ruby Gem that analyses your css during UI testing and generates a code coverage report.
3
3
 
4
- ![Alt text](https://i.imgur.com/zX9SSuF.png)
4
+ ![Example screenshot of Marmara output](https://i.imgur.com/N7J6wjD.png)
5
5
 
6
6
  ## Why is CSS code coverage important?
7
7
  CSS code coverage is a little different than traditional code coverage.
@@ -67,20 +67,6 @@ AfterStep do
67
67
  end
68
68
  ```
69
69
 
70
- Since I also want to capture used selectors for mobile, my after step looks more like this:
71
-
72
- ```ruby
73
- AfterStep do
74
- if Marmara.recording?
75
- Marmara.record(page)
76
- old_size = page.driver.browser.client.window_size
77
- page.driver.resize_window(600, 400)
78
- Marmara.record(page)
79
- page.driver.resize_window(*old_size)
80
- end
81
- end
82
- ```
83
-
84
70
  ### 3. Stop recording and generate your output
85
71
 
86
72
  ```ruby
@@ -89,5 +75,65 @@ at_exit do
89
75
  end
90
76
  ```
91
77
 
92
- ## Development plan
93
- This project is currently in a "works in my project" stage, there's still work to be done to make it more vendable so I welcome pull requests. In addition, there are probably a lot of tweaks required to the parser and a lot of features that would be nice to have.
78
+ You can also integrate with your existing tests to run all of the time if you like. To do that you can simply include `Marmara.start_recording` near the top of your `env.rb` file.
79
+
80
+ ## Execution
81
+
82
+ If you're using a rake task like I have described above, simply execute:
83
+
84
+ ```bash
85
+ rake css:cover
86
+ ```
87
+
88
+ You should see your tests exceute normally but after your tests complete you should see:
89
+
90
+ ```bash
91
+ Compiling CSS coverage report...
92
+
93
+ application.css:
94
+ Rules: 50/100 (50.00%)
95
+ Selectors: 75/200 (37.50%)
96
+ Declarations: 333/500 (66.67%)
97
+
98
+ fonts.css:
99
+ Rules: 2/2 (100.00%)
100
+ Selectors: 0/0 (NaN%)
101
+ Declarations: 2/2 (100.00%)
102
+
103
+ Overall:
104
+ Rules: 52/102 (50.98%)
105
+ Selectors: 75/200 (37.50%)
106
+ Declarations: 2/2 (66.73%)
107
+ ```
108
+
109
+ A **rule** is matched whenever at least one selector is covered, each **selector** within a rule is covered independently, **declarations** are each property and value pair within a rule.
110
+
111
+ You should now be able to find coverage report in your `log/css` directory. In the example above you should expect to find the files:
112
+
113
+ ```PowerShell
114
+ [my_app]
115
+ ├ [app]
116
+ │ └ # ...
117
+ ├ [log]
118
+ │ ├ [css]
119
+ │ │ ├ application.css.html
120
+ │ │ └ fonts.css.html
121
+ │ ├ # application.log
122
+ │ └ # ...
123
+ └ [spec]
124
+ └ # ...
125
+ ```
126
+
127
+ Open `application.css.html` or `fonts.css.html` in your browser to display your line coverage report.
128
+
129
+ ## Configuration
130
+
131
+ ### Output location
132
+ You can change the output location of your coverage reports by setting:
133
+
134
+ ```Ruby
135
+ Marmara.output_directory = '../build/logs'
136
+ Marmara.start_recording
137
+ ```
138
+
139
+ Set the `output_directory` before you start recording and you should find your HTML reports located in the directory you provided. *Note that this directory will removed and re-created each time the tests are run.*
@@ -0,0 +1,19 @@
1
+ require 'css_parser'
2
+
3
+ module CssParser
4
+ class MarmaraParser < Parser
5
+ attr_reader :last_file_contents
6
+
7
+ def read_remote_file(uri)
8
+ if Gem.win_platform? && uri.scheme == 'file' && uri.path =~ /^\/[a-zA-Z]:\/[a-zA-Z]:\//
9
+ # file scheme seems to be broken for windows, do some fixing
10
+ uri.path = uri.path.gsub(/^\/[a-zA-Z]:\/([a-zA-Z]:\/.*)$/, '\1')
11
+ end
12
+
13
+ # save the output
14
+ result = super(uri)
15
+ @last_file_contents = result.first
16
+ return result
17
+ end
18
+ end
19
+ end
data/lib/marmara.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  require 'open-uri'
2
2
  require 'cgi'
3
- require 'cgi'
4
- require 'css_parser'
3
+ require 'marmara/parser'
5
4
 
6
5
  module Marmara
7
6
 
@@ -61,9 +60,11 @@ module Marmara
61
60
 
62
61
  parser = nil
63
62
  begin
64
- parser = CssParser::Parser.new
63
+ parser = CssParser::MarmaraParser.new
65
64
  parser.load_uri!(sheet, capture_offsets: true)
66
- rescue
65
+ rescue Exception => e
66
+ puts e.to_s
67
+ puts "\t" + e.backtrace.join("\n\t")
67
68
  log "Error reading #{sheet}"
68
69
  end
69
70
 
@@ -74,7 +75,7 @@ module Marmara
74
75
  rule.each_selector do |sel, dec, spec|
75
76
  if sel.length > 0
76
77
  # we need to look for @keyframes and @font-face coverage differently
77
- if sel.first == '@'
78
+ if sel[0] == '@'
78
79
  rule_type = sel[1..-1]
79
80
  at_rule = {
80
81
  rule: rule,
@@ -89,12 +90,17 @@ module Marmara
89
90
  at_rule[:property] = ["#{$1}animation-name", "#{$1}animation"]
90
91
  at_rule[:value] = $2
91
92
  at_rule[:valueRegex] = [/(?:^|,)\s*(?:#{Regexp.escape(at_rule[:value])})\s*(?:,|;?$)/, /(?:^|\s)(?:#{Regexp.escape(at_rule[:value])})(?:\s|;?$)/]
93
+ when /^(\-moz\-document|supports)/
94
+ # ignore these types
95
+ at_rule[:used] = true
92
96
  end
93
97
 
94
- at_rule[:valueRegex] ||= /(?:^|,)\s*(?:#{Regexp.escape(at_rule[:value])}|\"#{Regexp.escape(at_rule[:value])}\")\s*(?:,|;?$)/
98
+ if at_rule[:value]
99
+ at_rule[:valueRegex] ||= /(?:^|,)\s*(?:#{Regexp.escape(at_rule[:value])}|\"#{Regexp.escape(at_rule[:value])}\")\s*(?:,|;?$)/
95
100
 
96
- # store all the info that we collected about the rule
97
- @style_sheet_rules[sheet] << at_rule
101
+ # store all the info that we collected about the rule
102
+ @style_sheet_rules[sheet] << at_rule
103
+ end
98
104
  else
99
105
  # just a regular selector, collect it
100
106
  selectors << {
@@ -123,7 +129,7 @@ module Marmara
123
129
 
124
130
  # store info about the stylesheet
125
131
  @style_sheets[sheet] = {
126
- css: download_style_sheet(sheet),
132
+ css: parser.last_file_contents,
127
133
  all_selectors: all_selectors,
128
134
  all_at_rules: all_at_rules,
129
135
  included_with: Set.new
@@ -285,7 +291,7 @@ module Marmara
285
291
  end
286
292
 
287
293
  def get_report_filename(uri)
288
- File.basename(uri)
294
+ File.basename(uri).gsub(/^(.*?)\?.*$/, '\1')
289
295
  end
290
296
 
291
297
  def is_property_covered(sheets, property, valueRegex)
@@ -361,21 +367,25 @@ module Marmara
361
367
  covered_selectors += rule[:used_selectors].count
362
368
  else
363
369
  original_selectors, = @style_sheets[uri][:css].byteslice(rule[:rule].offset).split(/\s*\{/, 2)
364
- selector_i = 0
365
370
 
366
- original_selectors.scan(/(?<=^|,)\s*(.*?)\s*(?=,|$)/m) do |match|
371
+ selectors_length = 0
372
+ original_selectors.split(/,/m).each_with_index do |sel, selector_i|
373
+ sel_length = sel.length
374
+ sel_length += 1 unless selector_i == (rule[:used_selectors].length - 1)
375
+
367
376
  is_covered = rule[:used_selectors][selector_i] ? :covered : :not_covered
368
377
  covered_selectors += 1 if is_covered
369
378
  sheet_covered_rules << {
370
379
  offset: [
371
- coverage[:offset][0] + Regexp.last_match.offset(0).first,
372
- coverage[:offset][0] + Regexp.last_match.offset(0).last
380
+ coverage[:offset][0] + selectors_length,
381
+ coverage[:offset][0] + selectors_length + sel_length
373
382
  ],
374
383
  state: is_covered
375
384
  }
376
- selector_i += 1
385
+ selectors_length += sel_length
377
386
  end
378
- coverage[:offset][0] += original_selectors.length + 1
387
+
388
+ coverage[:offset][0] += original_selectors.length
379
389
  end
380
390
  else
381
391
  rule[:rule].each_declaration do
@@ -457,13 +467,20 @@ module Marmara
457
467
  # collect the sheet html
458
468
  coverage.each do |rule|
459
469
  sheet_html += wrap_code(original_sheet.byteslice(last_index...rule[:offset][0]), :ignored)
460
- sheet_html += wrap_code(original_sheet.byteslice(rule[:offset][0]..rule[:offset][1]), rule[:state])
461
- last_index = rule[:offset][1] + 1
470
+ sheet_html += wrap_code(original_sheet.byteslice(rule[:offset][0]...rule[:offset][1]), rule[:state])
471
+ last_index = rule[:offset][1]
472
+ end
473
+
474
+ # finish off the rest of the file
475
+ if last_index < original_sheet.length
476
+ sheet_html += wrap_code(original_sheet[last_index...original_sheet.length], :ignored)
462
477
  end
463
478
 
464
- sheet_html += wrap_code(original_sheet[last_index..original_sheet.length], :ignored)
465
- sheet_html.gsub!(/\n/, '<br>')
466
- lines = (1..original_sheet.lines.count).to_a.map do |line|
479
+ # replace line returns with HTML line breaks
480
+ sheet_html.gsub!(/\r?\n/, '<br>')
481
+
482
+ # build the lines section
483
+ lines = (1..original_sheet.lines.count + 1).to_a.map do |line|
467
484
  "<a href=\"#L#{line}\" id=\"L#{line}\">#{line}</a>"
468
485
  end
469
486
  get_style_sheet_html.gsub('%{lines}', lines.join('')).gsub('%{style_sheet}', sheet_html)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marmara
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.0'
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Godwin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-14 00:00:00.000000000 Z
11
+ date: 2017-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: css_parser
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: capybara
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: poltergeist
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  description: Generates a CSS coverage report
84
112
  email:
85
113
  - goodgodwin@hotmail.com
@@ -91,6 +119,7 @@ files:
91
119
  - README.md
92
120
  - Rakefile
93
121
  - lib/marmara.rb
122
+ - lib/marmara/parser.rb
94
123
  - lib/marmara/style-sheet.html
95
124
  homepage: http://bikecollectives.org
96
125
  licenses: