├── .gitignore ├── .rspec ├── .rubocop.yml ├── .stickler.yml ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── bin └── main ├── example.css ├── images ├── check.png ├── microverse.png └── rspec.png ├── lib ├── buffer.rb └── checks.rb └── spec ├── checks_spec.rb ├── spec_helper.rb └── test_files ├── indent_test.css ├── line_form_test.css └── spacing_test.css /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | /.config 4 | /coverage/ 5 | /InstalledFiles 6 | /pkg/ 7 | /spec/reports/ 8 | /spec/examples.txt 9 | /test/tmp/ 10 | /test/version_tmp/ 11 | /tmp/ 12 | 13 | # Used by dotenv library to load environment variables. 14 | # .env 15 | 16 | # Ignore Byebug command history file. 17 | .byebug_history 18 | 19 | ## Specific to RubyMotion: 20 | .dat* 21 | .repl_history 22 | build/ 23 | *.bridgesupport 24 | build-iPhoneOS/ 25 | build-iPhoneSimulator/ 26 | 27 | ## Specific to RubyMotion (use of CocoaPods): 28 | # 29 | # We recommend against adding the Pods directory to your .gitignore. However 30 | # you should judge for yourself, the pros and cons are mentioned at: 31 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 32 | # 33 | # vendor/Pods/ 34 | 35 | ## Documentation cache and generated files: 36 | /.yardoc/ 37 | /_yardoc/ 38 | /doc/ 39 | /rdoc/ 40 | 41 | ## Environment normalization: 42 | /.bundle/ 43 | /vendor/bundle 44 | /lib/bundler/man/ 45 | 46 | # for a library or gem, you might want to ignore these files since the code is 47 | # intended to run in multiple environments; otherwise, check them in: 48 | # Gemfile.lock 49 | # .ruby-version 50 | # .ruby-gemset 51 | 52 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 53 | .rvmrc 54 | 55 | # Used by RuboCop. Remote config files pulled in from inherit_from directive. 56 | # .rubocop-https?--* 57 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --require spec_helper 3 | --format documentation -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | Exclude: 3 | - "README.md" 4 | - "Guardfile" 5 | - "Rakefile" 6 | 7 | DisplayCopNames: true 8 | 9 | Layout/LineLength: 10 | Max: 120 11 | Metrics/MethodLength: 12 | Max: 20 13 | Metrics/AbcSize: 14 | Max: 50 15 | Metrics/ClassLength: 16 | Max: 150 17 | Metrics/BlockLength: 18 | ExcludedMethods: ['describe'] 19 | Max: 30 20 | 21 | 22 | Style/Documentation: 23 | Enabled: false 24 | Style/ClassAndModuleChildren: 25 | Enabled: false 26 | Style/EachForSimpleLoop: 27 | Enabled: false 28 | Style/AndOr: 29 | Enabled: false 30 | Style/DefWithParentheses: 31 | Enabled: false 32 | Style/FrozenStringLiteralComment: 33 | EnforcedStyle: never 34 | 35 | Layout/HashAlignment: 36 | EnforcedColonStyle: key 37 | Layout/ExtraSpacing: 38 | AllowForAlignment: false 39 | Layout/MultilineMethodCallIndentation: 40 | Enabled: true 41 | EnforcedStyle: indented -------------------------------------------------------------------------------- /.stickler.yml: -------------------------------------------------------------------------------- 1 | # add the linters you want stickler to use for this project 2 | linters: 3 | rubocop: 4 | display_cop_names: true 5 | # indicate where is the config file for stylelint 6 | config: "./rubocop.yml" 7 | 8 | files: 9 | ignore: 10 | - "Guardfile" 11 | - "Rakefile" 12 | - "node_modules/**/*" 13 | 14 | # PLEASE DO NOT enable auto fixing options 15 | # if you need extra support from you linter - do it in your local env as described in README for this config 16 | # find full documentation here: https://stickler-ci.com/docs 17 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | gem 'strscan' 2 | gem 'rspec' 3 | gem 'colorize' -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | specs: 3 | colorize (0.8.1) 4 | diff-lcs (1.3) 5 | rspec (3.9.0) 6 | rspec-core (~> 3.9.0) 7 | rspec-expectations (~> 3.9.0) 8 | rspec-mocks (~> 3.9.0) 9 | rspec-core (3.9.1) 10 | rspec-support (~> 3.9.1) 11 | rspec-expectations (3.9.1) 12 | diff-lcs (>= 1.2.0, < 2.0) 13 | rspec-support (~> 3.9.0) 14 | rspec-mocks (3.9.1) 15 | diff-lcs (>= 1.2.0, < 2.0) 16 | rspec-support (~> 3.9.0) 17 | rspec-support (3.9.2) 18 | strscan (1.0.0) 19 | 20 | PLATFORMS 21 | ruby 22 | 23 | DEPENDENCIES 24 | colorize 25 | rspec 26 | strscan 27 | 28 | BUNDLED WITH 29 | 2.1.4 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Alex 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 16 | [![Contributors][contributors-shield]][contributors-url] 17 | [![Forks][forks-shield]][forks-url] 18 | [![Stargazers][stars-shield]][stars-url] 19 | [![Issues][issues-shield]][issues-url] 20 | 21 | 22 |
23 |

24 | 25 | Logo 26 | 27 | 28 |

CSS Linter

29 | 30 |

Ruby Capstone Project --> Build your own linter

31 |

32 | Explore the docs » 33 |
34 |
35 | - 36 | Report Bug 37 | - 38 | Request Feature 39 | - 40 |

41 |

42 | 43 | 44 | ## Table of Contents 45 | 46 | * [About the Project](#about-the-project) 47 | * [Built With](#built-with) 48 | * [Rules](#rules) 49 | * [Usage](#usage) 50 | * [Automated Test](#autoamted-test) 51 | * [Video Presentation](#video-presentation) 52 | * [Contributors](#contributors) 53 | * [Contributing](#contributing) 54 | * [Acknowledgements](#acknowledgements) 55 | * [License](#license) 56 | 57 | 58 | ## About The Project 59 | 60 | This is the **Ruby Capstone Project** required at the end of **Ruby** module in Microverse Curriculum. 61 | Specifically is a **CSS Linter** with the purpose to check for spacing, indentation and format errors. 62 | 63 | ## Rules 64 | 65 | **Indentation** 66 | * 2 space indentation rule 67 | 68 | bad code: 69 | ```css 70 | img { 71 | width: 700px; 72 | max-width: 100%; 73 | } 74 | ``` 75 | 76 | good code: 77 | ```css 78 | img { 79 | width: 700px; 80 | max-width: 100%; 81 | } 82 | ``` 83 | 84 | **Line Format** 85 | * One line checking 86 | * Line missing between css blocks 87 | 88 | bad code: 89 | ```css 90 | p { 91 | font-family: Helvetica, Arial, sans-serif; 92 | font-size: 14px; 93 | } 94 | a { 95 | color: #111111; 96 | font-size: 16px; 97 | } 98 | ``` 99 | 100 | good code: 101 | ```css 102 | p { 103 | font-family: Helvetica, Arial, sans-serif; 104 | font-size: 14px; 105 | } 106 | 107 | a { 108 | color: #111111; 109 | font-size: 16px; 110 | } 111 | ``` 112 | 113 | **Spacing** 114 | * Checking for missing spacing after **:** or **,** 115 | * Checking for missing spacing after **{** or **}** 116 | * Checking for line break after **{** or **}** and after each property declaration 117 | 118 | bad code: 119 | 120 | ```css 121 | a,p{color: #111111; font-size: 16px;} 122 | div{color: #222222; font-size: 18px;} 123 | ``` 124 | 125 | good code: 126 | ```css 127 | a { 128 | color: #111111; 129 | font-size: 16px; 130 | } 131 | 132 | div { 133 | color: #222222; 134 | font-size: 18px; 135 | } 136 | ``` 137 | 138 | 139 | 140 | ## Usage 141 | 142 | The **_CSS Linter_** does basic syntax checking, as well as applying a set of rules to the code and throws back an error if bad syntax is found. 143 | The throwback error is being printed out indicating the line and column of the specific syntax issue. 144 | 145 | **Examples** 146 | - Wrong Indentation, expected **_n_** spaces 147 | - Spacing, expected single space before **'{'** and **'('** 148 | - Spacing, expected single space after **')'** and **':'** and **','** 149 | - Line Format, Expected line break after **'{'** and **'}'** and **';'** 150 | - Line Format, Expected one empty line after **'}'** 151 | 152 | To test out **CSS Linter** you need to: 153 | * have **Ruby** installed on your computer 154 | * [download](https://github.com/rammazzoti2000/Ruby-capstone-project/archive/feature/readme_instructions.zip) or clone this repo: 155 | - Clone with SSH: 156 | ``` 157 | git@github.com:rammazzoti2000/Ruby-capstone-project.git 158 | ``` 159 | - Clone with HTTPS: 160 | ``` 161 | https://github.com/rammazzoti2000/Ruby-capstone-project.git 162 | ``` 163 | * Navigate to root directory of the repo and run: 164 | ``` 165 | $ bin/main path_to_file.css (path_to_file being the file you want to check for linters) 166 | ``` 167 | ![Screenshot](images/check.png) 168 | 169 | **Automated Test** 170 | * Run the command and see the output 171 | ``` 172 | $ bundle exec rspec 173 | ``` 174 | ![Screenshot](images/rspec.png) 175 | 176 | ### Built With 177 | This project was built using these technologies. 178 | * Ruby 179 | * Rspec 180 | * Rubocop 181 | * Atom :atom: 182 | 183 | 184 | ## Video Presentation 185 | 186 | Check out full presentation [here](https://www.loom.com/share/f17077929b4b484a8531d24ee1092598) 187 | 188 | ## Potential future features 189 | - Extend the linter to more complex syntax 190 | - Improve the terminal interaction 191 | - Make it an installable gem 192 | 193 | 194 | ## Contributors 195 | 196 | 👤 **Alexandru Bangau** 197 | 198 | - LinkedIn: [Alexandru Bangau](https://www.linkedin.com/in/alexandru-bangau/) 199 | - GitHub: [@rammazzoti2000](https://github.com/rammazzoti2000) 200 | - E-mail: bangau.alexandru@gmail.com 201 | 202 | ## :handshake: Contributing 203 | Contributions, issues and feature requests are welcome! 204 | Feel free to check the [issues page](https://github.com/rammazzoti2000/Ruby-capstone-project/issues) 205 | 206 | ## Show your support 207 | Give a :star: if you like this project! 208 | 209 | 210 | 211 | ## Acknowledgements 212 | * [Microverse](https://www.microverse.org/) 213 | * [The Odin Project](https://www.theodinproject.com/) 214 | * [Ruby Documentation](https://www.ruby-lang.org/en/documentation/) 215 | 216 | 217 | 218 | [contributors-shield]: https://img.shields.io/github/contributors/rammazzoti2000/Ruby-capstone-project.svg?style=flat-square 219 | [contributors-url]: https://github.com/rammazzoti2000/Ruby-capstone-project/graphs/contributors 220 | [forks-shield]: https://img.shields.io/github/forks/rammazzoti2000/Ruby-capstone-project.svg?style=flat-square 221 | [forks-url]: https://github.com/rammazzoti2000/Ruby-capstone-project/network/members 222 | [stars-shield]: https://img.shields.io/github/stars/rammazzoti2000/Ruby-capstone-project.svg?style=flat-square 223 | [stars-url]: https://github.com/rammazzoti2000/Ruby-capstone-project/stargazers 224 | [issues-shield]: https://img.shields.io/github/issues/rammazzoti2000/Ruby-capstone-project.svg?style=flat-square 225 | [issues-url]: https://github.com/rammazzoti2000/Ruby-capstone-project/issues 226 | 227 | ## 📝 License 228 | 229 | This project is [MIT](https://opensource.org/licenses/MIT) licensed. 230 | -------------------------------------------------------------------------------- /bin/main: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require_relative '../lib/buffer.rb' 4 | require_relative '../lib/checks.rb' 5 | 6 | # rubocop: disable Style/MixinUsage 7 | include Checks 8 | 9 | file_path = ARGV.shift 10 | k_open = '{' 11 | k_close = '}' 12 | b = Buffer.new(file_path) 13 | 14 | line_format_cop(b.content_s) 15 | spacing_cop(b.content_s) 16 | indent_cop(b.content_s, k_open, k_close) 17 | # rubocop: enable Style/MixinUsage 18 | -------------------------------------------------------------------------------- /example.css: -------------------------------------------------------------------------------- 1 | div { 2 | font-size: 18pt; 3 | color: #222222; 4 | } 5 | 6 | img { 7 | width: 50%; 8 | } 9 | 10 | p { 11 | font-family: Helvetica, Arial, sans-serif; 12 | font-size: 14pt; 13 | } 14 | 15 | a { 16 | color: #111111; 17 | font-size: 16pt; 18 | } 19 | 20 | div { 21 | color: #222222; 22 | font-size: 18pt; 23 | } 24 | 25 | p { 26 | font-family: Helvetica, Arial, sans-serif; 27 | } 28 | 29 | a { 30 | color: #111111; 31 | font-size: 16pt; 32 | } 33 | 34 | 35 | div { 36 | color: #222222; 37 | font-size: 18pt; 38 | } 39 | p { 40 | font-family: Helvetica, Arial, sans-serif; 41 | } 42 | p,h1 { 43 | color:red; 44 | font-family:serif; 45 | font-size:16pt;} 46 | a {text-decoration:none} -------------------------------------------------------------------------------- /images/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rammazzoti2000/Ruby-capstone-project/6d037b02d10da5463191165771f2de45753a1400/images/check.png -------------------------------------------------------------------------------- /images/microverse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rammazzoti2000/Ruby-capstone-project/6d037b02d10da5463191165771f2de45753a1400/images/microverse.png -------------------------------------------------------------------------------- /images/rspec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rammazzoti2000/Ruby-capstone-project/6d037b02d10da5463191165771f2de45753a1400/images/rspec.png -------------------------------------------------------------------------------- /lib/buffer.rb: -------------------------------------------------------------------------------- 1 | class Buffer 2 | attr_reader :file_path, :content_s 3 | 4 | def initialize(file_path) 5 | @file_path = file_path 6 | @content_s = get_file_content(@file_path) 7 | end 8 | 9 | # rubocop: disable Lint/UselessAssignment 10 | def get_file_content(file_path) 11 | content_s = '' 12 | File.open(file_path, 'r') { |f| content_s = f.readlines.map(&:chomp) } 13 | content_scan = content_s.map { |v| v = StringScanner.new(v) } 14 | content_scan 15 | end 16 | # rubocop: enable Lint/UselessAssignment 17 | end 18 | -------------------------------------------------------------------------------- /lib/checks.rb: -------------------------------------------------------------------------------- 1 | require 'strscan' 2 | require 'colorize' 3 | 4 | # rubocop: disable Metrics/ModuleLength 5 | module Checks 6 | def indent_cop(content_s, k_open, k_close) 7 | lev = check_indent_level(content_s, k_open, k_close) 8 | content_s.each_with_index do |s, i| 9 | s.reset 10 | s.scan(/\s+/) 11 | sp = if s.matched? 12 | s.matched.length 13 | else 14 | 0 15 | end 16 | log_error(1, i + 1, nil, nil, lev[i] * 2) unless sp == lev[i] * 2 17 | end 18 | end 19 | 20 | def spacing_cop(content_s) 21 | content_s.each_with_index do |s, i| 22 | spc_check_before(i + 1, s, '{') 23 | spc_check_before(i + 1, s, '\(') 24 | spc_check_after(i + 1, s, '\)') 25 | spc_check_after(i + 1, s, ',') 26 | spc_check_after(i + 1, s, ':') 27 | end 28 | end 29 | 30 | def line_format_cop(content_s) 31 | content_s.each_with_index do |s, i| 32 | check_ret_after(i + 1, s, '{') 33 | check_ret_after(i + 1, s, '}') 34 | check_ret_after(i + 1, s, ';') 35 | end 36 | check_lines_bet_blocks(content_s, '}') 37 | end 38 | 39 | private 40 | 41 | def check_indent_level(content_s, k_open, k_close) 42 | levels = [] 43 | level = 0 44 | content_s.each_with_index do |s, i| 45 | s.reset 46 | levels << level 47 | level += 1 if s.exist?(Regexp.new(k_open)) 48 | next unless s.exist?(Regexp.new(k_close)) 49 | 50 | level -= 1 51 | levels[i] = level 52 | end 53 | levels 54 | end 55 | 56 | def spc_check_before(line, str, char) 57 | str.reset 58 | s = str.scan_until(Regexp.new(char)) 59 | while str.matched? 60 | s = StringScanner.new(s.reverse) 61 | s.skip(Regexp.new(char)) 62 | s.scan(/\s+/) 63 | log_error(3, line, char, s.string.length - s.pos) if s.matched != ' ' 64 | s = str.scan_until(Regexp.new(char)) 65 | end 66 | end 67 | 68 | def spc_check_after(line, str, char) 69 | str.reset 70 | str.scan_until(Regexp.new(char)) 71 | while str.matched? 72 | str.scan(/\s+/) 73 | log_error(2, line, char, str.pos) if str.matched != ' ' 74 | str.scan_until(Regexp.new(char)) 75 | end 76 | end 77 | 78 | def check_ret_after(line, str, char) 79 | str.reset 80 | str.scan_until(Regexp.new(char)) 81 | while str.matched? 82 | log_error(4, line, char, str.pos) unless str.eos? 83 | str.scan_until(Regexp.new(char)) 84 | end 85 | end 86 | 87 | # rubocop: disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity 88 | def check_lines_bet_blocks(content_s, char) 89 | found = false 90 | counter = 0 91 | 0.upto(content_s.length - 1) do |i| 92 | content_s[i].reset 93 | if found && content_s[i].string == '' 94 | counter += 1 95 | log_error(5, i + 1, char) if counter > 1 96 | elsif found && content_s[i].string != '' 97 | log_error(5, i + 1, char) if counter.zero? && !content_s[i].exist?(/}/) 98 | found = false 99 | else 100 | found = false 101 | end 102 | if content_s[i].exist?(/}/) 103 | found = true 104 | counter = 0 105 | end 106 | end 107 | end 108 | 109 | def log_error(type, line, char = nil, pos = nil, lev = nil) 110 | err_string = "Error: line #{line}" 111 | err_string += ", col: #{pos}" unless pos.nil? 112 | case type 113 | when 1 114 | puts "#{err_string}, Wrong Indentation, expected #{lev} spaces " 115 | when 2 116 | puts "#{err_string}, Spacing, expected single space after #{char}" 117 | when 3 118 | puts "#{err_string}, Spacing, expected single space before #{char}" 119 | when 4 120 | puts "#{err_string}, Line Format, Expected line break after #{char}" 121 | when 5 122 | puts "#{err_string}, Line Format, Expected one empty line after #{char}" 123 | else 124 | puts "#{err_string}, Other" 125 | end 126 | type 127 | end 128 | end 129 | # rubocop: enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/ModuleLength 130 | -------------------------------------------------------------------------------- /spec/checks_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/buffer.rb' 2 | require_relative '../lib/checks.rb' 3 | 4 | describe Checks do 5 | include Checks 6 | 7 | let(:k_open) { '{' } 8 | let(:k_close) { '}' } 9 | 10 | describe '#check_indent_level' do 11 | it 'should return an array with the expected levels of indentation for each line' do 12 | file_path = 'spec/test_files/indent_test.css' 13 | b = Buffer.new(file_path) 14 | expect(check_indent_level(b.content_s, k_open, k_close)).to eql([0, 1, 0]) 15 | end 16 | end 17 | 18 | describe '#log_error' do 19 | it 'returns an error message based on the received parameters' do 20 | expect do 21 | log_error(1, 10, nil, nil, 2) 22 | end.to output("Error: line 10, Wrong Indentation, expected 2 spaces \n").to_stdout 23 | end 24 | end 25 | 26 | describe '#indent_cop' do 27 | it 'should return an error message for line 1 due to wrong indentation' do 28 | file_path = 'spec/test_files/indent_test.css' 29 | b = Buffer.new(file_path) 30 | expect do 31 | indent_cop(b.content_s, k_open, k_close) 32 | end.to output("Error: line 1, Wrong Indentation, expected 0 spaces \n").to_stdout 33 | end 34 | end 35 | 36 | describe '#spc_check_before' do 37 | it 'should return an error for line 1,due to wrong spacing' do 38 | file_path = 'spec/test_files/spacing_test.css' 39 | b = Buffer.new(file_path) 40 | expect do 41 | spc_check_before(1, b.content_s[0], '{') 42 | end.to output("Error: line 1, col: 5, Spacing, expected single space before {\n").to_stdout 43 | end 44 | end 45 | 46 | describe '#spc_check_after' do 47 | it 'should return an error for line 3,due to wrong spacing' do 48 | file_path = 'spec/test_files/spacing_test.css' 49 | b = Buffer.new(file_path) 50 | expect do 51 | spc_check_after(3, b.content_s[2], ':') 52 | end.to output("Error: line 3, col: 14, Spacing, expected single space after :\n").to_stdout 53 | end 54 | end 55 | 56 | describe '#check_ret_after' do 57 | it 'should return an error on line 2 due to wrong line format' do 58 | expect do 59 | file_path = 'spec/test_files/line_form_test.css' 60 | b = Buffer.new(file_path) 61 | check_ret_after(2, b.content_s[1], ';') 62 | end.to output("Error: line 2, col: 12, Line Format, Expected line break after ;\n").to_stdout 63 | end 64 | end 65 | 66 | describe '#check_ret_after' do 67 | it 'should return an error on line 5 due to wrong line format' do 68 | expect do 69 | file_path = 'spec/test_files/line_form_test.css' 70 | b = Buffer.new(file_path) 71 | check_lines_bet_blocks(b.content_s, '}') 72 | end.to output("Error: line 5, Line Format, Expected one empty line after }\n").to_stdout 73 | end 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # This file was generated by the `rspec --init` command. Conventionally, all 2 | # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. 3 | # The generated `.rspec` file contains `--require spec_helper` which will cause 4 | # this file to always be loaded, without a need to explicitly require it in any 5 | # files. 6 | # 7 | # Given that it is always loaded, you are encouraged to keep this file as 8 | # light-weight as possible. Requiring heavyweight dependencies from this file 9 | # will add to the boot time of your test suite on EVERY test run, even for an 10 | # individual file that may not need all of that loaded. Instead, consider making 11 | # a separate helper file that requires the additional dependencies and performs 12 | # the additional setup, and require it from the spec files that actually need 13 | # it. 14 | # 15 | # The `.rspec` file also contains a few flags that are not defaults but that 16 | # users commonly want. 17 | # 18 | # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration 19 | RSpec.configure do |config| 20 | # rspec-expectations config goes here. You can use an alternate 21 | # assertion/expectation library such as wrong or the stdlib/minitest 22 | # assertions if you prefer. 23 | config.expect_with :rspec do |expectations| 24 | # This option will default to `true` in RSpec 4. It makes the `description` 25 | # and `failure_message` of custom matchers include text for helper methods 26 | # defined using `chain`, e.g.: 27 | # be_bigger_than(2).and_smaller_than(4).description 28 | # # => "be bigger than 2 and smaller than 4" 29 | # ...rather than: 30 | # # => "be bigger than 2" 31 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true 32 | end 33 | 34 | # rspec-mocks config goes here. You can use an alternate test double 35 | # library (such as bogus or mocha) by changing the `mock_with` option here. 36 | config.mock_with :rspec do |mocks| 37 | # Prevents you from mocking or stubbing a method that does not exist on 38 | # a real object. This is generally recommended, and will default to 39 | # `true` in RSpec 4. 40 | mocks.verify_partial_doubles = true 41 | end 42 | 43 | # The settings below are suggested to provide a good initial experience 44 | # with RSpec, but feel free to customize to your heart's content. 45 | # These two settings work together to allow you to limit a spec run 46 | # to individual examples or groups you care about by tagging them with 47 | # `:focus` metadata. When nothing is tagged with `:focus`, all examples 48 | # get run. 49 | # config.filter_run :focus 50 | # config.run_all_when_everything_filtered = true 51 | 52 | # Limits the available syntax to the non-monkey patched syntax that is 53 | # recommended. For more details, see: 54 | # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax 55 | # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ 56 | # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching 57 | # config.disable_monkey_patching! 58 | 59 | # This setting enables warnings. It's recommended, but in some cases may 60 | # be too noisy due to issues in dependencies. 61 | # config.warnings = true 62 | 63 | # Many RSpec users commonly either run the entire suite or an individual 64 | # file, and it's useful to allow more verbose output when running an 65 | # individual spec file. 66 | # if config.files_to_run.one? 67 | # Use the documentation formatter for detailed output, 68 | # unless a formatter has already been configured 69 | # (e.g. via a command-line flag). 70 | # config.default_formatter = 'doc' 71 | # end 72 | 73 | # Print the 10 slowest examples and example groups at the 74 | # end of the spec run, to help surface which specs are running 75 | # particularly slow. 76 | # config.profile_examples = 10 77 | 78 | # Run specs in random order to surface order dependencies. If you find an 79 | # order dependency and want to debug it, you can fix the order by providing 80 | # the seed, which is printed after each run. 81 | # --seed 1234 82 | # config.order = :random 83 | 84 | # Seed global randomization in this process using the `--seed` CLI option. 85 | # Setting this allows you to use `--seed` to deterministically reproduce 86 | # test failures related to randomization by passing the same `--seed` value 87 | # as the one that triggered the failure. 88 | # Kernel.srand config.seed 89 | end 90 | -------------------------------------------------------------------------------- /spec/test_files/indent_test.css: -------------------------------------------------------------------------------- 1 | img { 2 | width: 50%; 3 | } -------------------------------------------------------------------------------- /spec/test_files/line_form_test.css: -------------------------------------------------------------------------------- 1 | p, h1{ 2 | color:red; 3 | font-family:serif; font-size:16pt; 4 | } 5 | a { 6 | color: #fff; 7 | } -------------------------------------------------------------------------------- /spec/test_files/spacing_test.css: -------------------------------------------------------------------------------- 1 | p, h1{ 2 | color: red; 3 | font-family:serif; 4 | font-size: 16pt; 5 | } --------------------------------------------------------------------------------