├── .rspec ├── .rubocop.yml ├── .stickler.yml ├── README.md ├── app_screenshot.png ├── app_video.png ├── bin └── main.rb ├── lib ├── error.rb ├── line.rb ├── modules │ ├── check_global_syntax_helper.rb │ ├── check_naming_helper.rb │ ├── check_syntax_helper.rb │ ├── file_check.rb │ ├── lines_check.rb │ ├── lint_helper.rb │ └── preference_helper.rb └── ruby_file.rb └── spec ├── error_spec.rb ├── line_spec.rb ├── modules_spec ├── check_global_syntax_helper_spec.rb ├── check_naming_helper_spec.rb ├── check_syntax_helper_spec.rb ├── file_check_helper_spec.rb ├── lines_check_spec.rb ├── lint_helper_spec.rb └── preference_helper_spec.rb ├── ruby_file_spec.rb └── spec_helper.rb /.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | -------------------------------------------------------------------------------- /.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 42 | -------------------------------------------------------------------------------- /.stickler.yml: -------------------------------------------------------------------------------- 1 | # add the linters you want stickler to use for this project 2 | linters: 3 | stylelint: 4 | # indicate where is the config file for stylelint 5 | config: 'stylelint.config.js' 6 | 7 | # PLEASE DO NOT enable auto fixing options 8 | # if you need extra support from you linter - do it in your local env as described in README for this config 9 | 10 | # find full documentation here: https://stickler-ci.com/docs -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ruby Capstone project 2 | 3 | > Ruby code linter 4 | 5 | ![screenshot](./app_screenshot.png) 6 | 7 | This is a basic and simple linter to help you check your ruby code. These are the good and bad it checks on: 8 | #### Respect of CamelCase and namespacing for modules, class and method name 9 | ** Bad ** 10 | `class myClass` 11 | ** Good ** 12 | `class MyClass` 13 | #### Respect of syntax for condition and itteration declaration 14 | ** Bad ** 15 | `ifmycondition` or `myarray .times do {|i| print i}` 16 | ** Good ** 17 | `if mycondition` or `myarray.times do |i|` or `myarray.times {|i| print i}` 18 | #### Corresponding end for each oppening line 19 | ** Bad ** 20 | `class MyClass def my_function end` 21 | ** Good ** 22 | `class MyClass def my_function end end` 23 | 24 | > Watch the presentation video. 25 | 26 | [![screenshot](./app_video.png)](https://www.loom.com/share/926ffc82fdad473f9539cfca7a89eeb9) 27 | 28 | ## Built With 29 | 30 | - Ruby 31 | - VSCode, Linters, Rubocop 32 | 33 | 34 | ## Getting Started 35 | 36 | **This is an example of how you may give instructions on setting up your project locally.** 37 | **Modify this file to match your project, remove sections that don't apply. For example: delete the testing section if the currect project doesn't require testing.** 38 | 39 | 40 | To get a local copy up and running follow these simple example steps. 41 | 42 | ### Prerequisites 43 | 44 | - Get ruby latest version installed 45 | 46 | ### Setup 47 | 48 | - Clone the repository on your local machine 49 | 50 | ### Install 51 | 52 | - type this in order to install colorize gem: `gem install colorize` 53 | - Install Ruby(most recent version) 54 | - Run this command on your terminal in order to install rubocop: gem install rubocop 55 | - Run this command in order to get make the project file runable: 56 | `chmod +x path_to_the_linter_project/bin/main.rb` 57 | 58 | ### Usage 59 | 60 | ### Run tests 61 | 62 | You can run the linter on a file, a folder or the current folder by typing this command: 63 | - `./path_to_the_linter_project/bin/main.rb myfile.rb` for a particular file 64 | - `./path_to_the_linter_project/bin/main.rb myfolder` for all the ruby files in a particular folder 65 | - `./path_to_the_linter_project/bin/main.rb` for all the ruby files in the current folder 66 | 67 | 68 | ## Authors 69 | 70 | 👤 **Manezeu Patricia Chrystelle** 71 | 72 | - Github: [@githubhandle](https://github.com/patriciachrysy) 73 | - Twitter: [@twitterhandle](https://twitter.com/ManezeuP) 74 | - Linkedin: [linkedin](https://www.linkedin.com/in/manezeu-patricia-chrystelle-095072118/) 75 | 76 | ## 🤝 Contributing 77 | 78 | Contributions, issues and feature requests are welcome! 79 | 80 | Feel free to check the [issues page](). 81 | 82 | ## Show your support 83 | 84 | Give a ⭐️ if you like this project! 85 | 86 | ## Acknowledgments 87 | 88 | - Hat tip to anyone whose code was used 89 | - Inspiration 90 | - etc 91 | 92 | ## 📝 License 93 | 94 | -------------------------------------------------------------------------------- /app_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patriciachrysy/ruby-linter/b8efb16381728cea53bcb626129298706aadd92c/app_screenshot.png -------------------------------------------------------------------------------- /app_video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patriciachrysy/ruby-linter/b8efb16381728cea53bcb626129298706aadd92c/app_video.png -------------------------------------------------------------------------------- /bin/main.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require_relative '../lib/modules/file_check' 4 | require_relative '../lib/modules/lint_helper' 5 | 6 | errors = [] 7 | if ARGV.length.positive? 8 | path = ARGV[0] 9 | regex = /^[\W|\w]+.rb$/ 10 | if regex.match?(path) 11 | LintHelper.start_linting_file(path, errors) 12 | else 13 | LintHelper.start_linting_dir(path, errors) 14 | end 15 | else 16 | files = FileCheck.content_ruby_files 17 | if !files.is_a?(String) 18 | LintHelper.lint_local(files, errors) 19 | else 20 | puts files 21 | end 22 | end 23 | 24 | if errors 25 | errors.each do |err| 26 | puts "#{err.type} in file #{err.line.filename}:on line #{err.line.number}, #{err.message}" 27 | end 28 | puts "#{errors.length} errors found" 29 | end 30 | -------------------------------------------------------------------------------- /lib/error.rb: -------------------------------------------------------------------------------- 1 | require 'colorize' 2 | 3 | class Error 4 | attr_reader :line, :type, :message 5 | 6 | def initialize(line) 7 | @line = line 8 | end 9 | 10 | def raise_line_length_warn 11 | @type = 'Warning' 12 | @message = 'The line is too long' 13 | colour_it 14 | end 15 | 16 | def raise_syntax_error(precision) 17 | @type = 'Error' 18 | @message = "Syntax error: #{precision}" 19 | colour_it 20 | end 21 | 22 | def raise_naming_error(precision) 23 | @type = 'Warning' 24 | @message = "Naming error: #{precision}" 25 | colour_it 26 | end 27 | 28 | def raise_preference(precision) 29 | @type = 'Warning' 30 | @message = "Preference: #{precision}" 31 | colour_it 32 | end 33 | 34 | def raise_closure_error(precision) 35 | @type = 'Error' 36 | @message = "Incoherent closures: #{precision}" 37 | colour_it 38 | end 39 | 40 | private 41 | 42 | def colour_it 43 | @type = if @type == 'Error' 44 | @type.red 45 | else 46 | @type.yellow 47 | end 48 | self 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /lib/line.rb: -------------------------------------------------------------------------------- 1 | class Line 2 | attr_reader :number, :content, :max_length, :filename 3 | 4 | def initialize(number, content, filename) 5 | @number = number 6 | @content = content 7 | @filename = filename 8 | @max_length = 160 9 | end 10 | 11 | def words 12 | @content.split 13 | end 14 | 15 | def check_syntax(regex) 16 | regex.match?(@content) 17 | end 18 | 19 | def check_include(word) 20 | @content.include?(word) 21 | end 22 | 23 | def check_length 24 | count = 0 25 | words.each { |word| count += word.length } 26 | count <= @max_length 27 | end 28 | 29 | def opening_line? 30 | ans = false 31 | pattern_one = /^[\s]*(module|class|def)[\s]+/ 32 | pattern_two = /^[\s]*[\W|\w]+\sdo/ 33 | array = %w[while loop if unless until for] 34 | first = words[0] 35 | is_cond = /^[\s]*(\w|\W)+=[\s]*(if|unless)/.match?(@content) 36 | ans = true if pattern_one.match?(@content) || pattern_two.match?(@content) || array.include?(first) || is_cond 37 | ans 38 | end 39 | 40 | def closing_line? 41 | pattern = /^[\s]*end[\s]*$/ 42 | pattern.match?(@content) ? true : false 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /lib/modules/check_global_syntax_helper.rb: -------------------------------------------------------------------------------- 1 | require_relative '../error' 2 | 3 | module CheckGlobalSyntaxHelper 4 | def self.error_shooter(line, message) 5 | error = Error.new(line) 6 | error.raise_closure_error(message) 7 | end 8 | 9 | def self.check_open_end(file) 10 | open_lines = 0 11 | close_lines = 0 12 | state = false 13 | file.lines.each do |line| 14 | if line.opening_line? 15 | open_lines += 1 16 | elsif line.closing_line? 17 | close_lines += 1 18 | end 19 | end 20 | last_line = file.lines[file.lines.length - 1] 21 | if open_lines > close_lines 22 | state = error_shooter(last_line, "Missing a 'end' closure in this file") 23 | elsif open_lines < close_lines 24 | state = error_shooter(last_line, "Useless 'end' closure in this file") 25 | end 26 | state 27 | end 28 | 29 | def self.check_spaces(line) 30 | state = false 31 | pattern = /^[\s]+(class|module|require|require_relative)[\s]+/ 32 | state = error_shooter(line, 'Useless space before class/module/require declaration') if pattern.match?(line.content) 33 | state 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/modules/check_naming_helper.rb: -------------------------------------------------------------------------------- 1 | require_relative '../error' 2 | 3 | module CheckNamingHelper 4 | def self.error_shooter(line, message) 5 | error = Error.new(line) 6 | error.raise_naming_error(message) 7 | end 8 | 9 | def self.check_class_module(line) 10 | reg = /^[\s]*(class|module)\s[A-Z]{1}[a-z,A-Z]+[\s]*$/ 11 | state = false 12 | unless reg.match?(line.content) 13 | state = error_shooter(line, 'The module and class names should repect the CamelCase, check it again') 14 | end 15 | state 16 | end 17 | 18 | def self.check_method_naming(line) 19 | reg = /^[\s]*def\s[a-z]+(_[a-z]+)*/ 20 | state = false 21 | unless reg.match?(line.content) 22 | state = error_shooter(line, 'The method name should respect the namespacing syntax, check it again') 23 | end 24 | state 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/modules/check_syntax_helper.rb: -------------------------------------------------------------------------------- 1 | require_relative '../error' 2 | 3 | module CheckSyntaxHelper 4 | def self.error_shooter(line, message) 5 | error = Error.new(line) 6 | error.raise_syntax_error(message) 7 | end 8 | 9 | def self.state_prec(tool) 10 | "The #{tool} declaration is incorrect, check it again" 11 | end 12 | 13 | def self.check_cond_syntax(line) 14 | reg = /^[\s|\w|\W]*(if|unless)\s[\w|\W]+[\s]*$/ 15 | state = false 16 | state = error_shooter(line, state_prec('condition')) unless reg.match?(line.content) 17 | state 18 | end 19 | 20 | def self.check_loop_syntax(line) 21 | reg = /^[\s]*(loop)\s(do|{(\W|\w)+})[\s]*$/ 22 | state = false 23 | state = error_shooter(line, state_prec('loop')) unless reg.match?(line.content) 24 | state 25 | end 26 | 27 | def self.check_while_until_syntax(line) 28 | reg = /^[\s]*(while|until)\s(\w|\W)+[\s]*$/ 29 | state = false 30 | state = error_shooter(line, state_prec('while/until')) unless reg.match?(line.content) 31 | state 32 | end 33 | 34 | def self.check_for_syntax(line) 35 | reg = /^[\s]*(for)\s(\w|\W)+\s(in)\s(\w|\W)+[\s]*$/ 36 | state = false 37 | state = error_shooter(line, state_prec('for')) unless reg.match?(line.content) 38 | state 39 | end 40 | 41 | def self.check_times_syntax(line) 42 | reg = /^[\s]*(\W|\w)+\.times\s(do\s\|(\W|\w)+\||{(\W|\w)+})[\s]*$/ 43 | state = false 44 | state = error_shooter(line, state_prec('times')) unless reg.match?(line.content) 45 | state 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /lib/modules/file_check.rb: -------------------------------------------------------------------------------- 1 | require_relative './check_global_syntax_helper' 2 | require_relative './preference_helper' 3 | require_relative '../error' 4 | 5 | module FileCheck 6 | def self.check_file(errors, file) 7 | res = CheckGlobalSyntaxHelper.check_open_end(file) 8 | errors << res if res 9 | res = PreferenceHelper.check_module(file) 10 | errors << res if res 11 | errors 12 | end 13 | 14 | def self.file_exist(path) 15 | File.exist?(path) ? true : "Could not find #{path} file" 16 | end 17 | 18 | def self.dir_exist(path) 19 | Dir.exist?(path) ? true : "Could not find #{path} directory" 20 | end 21 | 22 | def self.content_ruby_files(path = nil) 23 | if path 24 | files = Dir["#{path}/**/*.rb"] 25 | !files.empty? ? files : "No ruby files found in #{path} directory" 26 | else 27 | files = Dir['./**/*.rb'] 28 | !files.empty? ? files : 'No ruby files found in this directory' 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /lib/modules/lines_check.rb: -------------------------------------------------------------------------------- 1 | require_relative './check_naming_helper' 2 | require_relative './check_syntax_helper' 3 | require_relative './preference_helper' 4 | require_relative './check_global_syntax_helper' 5 | 6 | module LinesCheck 7 | def self.check_all(errors, line) 8 | check_length(errors, line) 9 | check_spacing(errors, line) 10 | check_endings(errors, line) 11 | check_syntax(errors, line) 12 | check_pref(errors, line) 13 | errors 14 | end 15 | 16 | def self.check_length(errors, line) 17 | unless line.check_length 18 | error = Error.new(line) 19 | errors << error.raise_line_length_warn 20 | end 21 | errors 22 | end 23 | 24 | def self.check_spacing(errors, line) 25 | line_res = CheckGlobalSyntaxHelper.check_spaces(line) 26 | errors << line_res if line_res 27 | end 28 | 29 | def self.check_endings(errors, line) 30 | if line.opening_line? 31 | class_patt = /^[\s]*(module|class)/ 32 | if line.content.match?(class_patt) 33 | line_res = CheckNamingHelper.check_class_module(line) 34 | errors << line_res if line_res 35 | elsif line.content.match?(/^[\s]*(def)/) 36 | line_res = CheckNamingHelper.check_method_naming(line) 37 | errors << line_res if line_res 38 | end 39 | end 40 | errors 41 | end 42 | 43 | # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Style/RegexpLiteral 44 | def self.check_syntax(errors, line) 45 | if /^([^"\/_-]*(\s|=))*(if|unless)/.match?(line.content) 46 | line_res = CheckSyntaxHelper.check_cond_syntax(line) 47 | errors << line_res if line_res 48 | elsif /^[^\w"\/_-]*(loop)/.match?(line.content) 49 | line_res = CheckSyntaxHelper.check_loop_syntax(line) 50 | errors << line_res if line_res 51 | elsif /^[^\w"\/_-]*(while|until)/.match?(line.content) 52 | line_res = CheckSyntaxHelper.check_while_until_syntax(line) 53 | errors << line_res if line_res 54 | elsif /^[^\w"\/_-]*(for)/.match?(line.content) 55 | line_res = CheckSyntaxHelper.check_for_syntax(line) 56 | errors << line_res if line_res 57 | elsif /^[^"\/_-]*(\.times)({|\s)+/.match?(line.content) 58 | line_res = CheckSyntaxHelper.check_times_syntax(line) 59 | errors << line_res if line_res 60 | end 61 | errors 62 | end 63 | # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Style/RegexpLiteral 64 | 65 | def self.check_pref(errors, line) 66 | line_res = PreferenceHelper.each_against_for(line) 67 | errors << line_res if line_res 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /lib/modules/lint_helper.rb: -------------------------------------------------------------------------------- 1 | require_relative '../ruby_file' 2 | require_relative './file_check' 3 | require_relative './lines_check' 4 | 5 | module LintHelper 6 | def self.start_linting_file(path, errors) 7 | if FileCheck.file_exist(path) == true 8 | linting(path, errors) 9 | else 10 | puts FileCheck.file_exist(path) 11 | end 12 | end 13 | 14 | def self.start_linting_dir(path, errors) 15 | if FileCheck.dir_exist(path) == true 16 | files = FileCheck.content_ruby_files(path) 17 | if !files.is_a?(String) 18 | files.each { |file| linting(file, errors) } 19 | else 20 | puts files 21 | end 22 | else 23 | puts FileCheck.dir_exist(path) 24 | end 25 | end 26 | 27 | def self.lint_local(files, errors) 28 | files.each { |file| linting(file, errors) } 29 | end 30 | 31 | def self.linting(path, errors) 32 | file = RubyFile.new(path) 33 | FileCheck.check_file(errors, file) 34 | file.lines.each { |line| errors = LinesCheck.check_all(errors, line) } 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/modules/preference_helper.rb: -------------------------------------------------------------------------------- 1 | require_relative '../error' 2 | 3 | module PreferenceHelper 4 | def self.error_shooter(line, message) 5 | error = Error.new(line) 6 | error.raise_preference(message) 7 | end 8 | 9 | def self.each_against_for(line) 10 | state = false 11 | state = error_shooter(line, "Prefer using 'each' instead of for") if line.words.include?('for') 12 | state 13 | end 14 | 15 | def self.check_module(file) 16 | state = false 17 | pattern = /^[\s]*(class|module)[\s]+/ 18 | count = 0 19 | file.lines.each { |line| count += 1 if pattern.match?(line.content) } 20 | if count > 1 21 | last_line = file.lines[file.lines.length - 1] 22 | state = error_shooter(last_line, 'Do not define more than one class/module per file') 23 | end 24 | state 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/ruby_file.rb: -------------------------------------------------------------------------------- 1 | require_relative 'line' 2 | 3 | class RubyFile 4 | attr_reader :name, :lines 5 | def initialize(filename) 6 | @name = filename 7 | @lines = [] 8 | set_lines 9 | end 10 | 11 | def close_file 12 | File.close(@name) 13 | end 14 | 15 | private 16 | 17 | def open_file 18 | File.open(@name) 19 | end 20 | 21 | def set_lines 22 | file = open_file 23 | all_lines = file.readlines.map(&:chomp) 24 | all_lines.each_with_index do |value, index| 25 | line = Line.new(index + 1, value, @name) 26 | @lines << line 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/error_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/line' 2 | require_relative '../lib/error' 3 | 4 | describe Line do 5 | let(:line) { Line.new(1, 'class my_class', 'my_class.rb') } 6 | let(:error) { Error.new(line) } 7 | describe '#raise_naming_error' do 8 | it 'returns an error object with warning type' do 9 | expect(error.raise_naming_error('respect camel case').class).to eql(Error) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/line_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/line' 2 | require_relative '../lib/ruby_file' 3 | 4 | describe Line do 5 | let(:file) { RubyFile.new('./bin/main.rb') } 6 | describe '#words' do 7 | it 'Split the line into an array to strings' do 8 | expect(file.lines[0].words).to eql(%w[#!/usr/bin/env ruby]) 9 | end 10 | end 11 | 12 | describe '#check_syntax' do 13 | it 'Check if the line does not match a regex' do 14 | expect(file.lines[0].check_syntax(/^[a-z]/)).not_to eql(true) 15 | end 16 | end 17 | 18 | describe '#check_include' do 19 | it 'Check if a word does not appear on a line' do 20 | expect(file.lines[0].check_include('class')).not_to eql(true) 21 | end 22 | end 23 | 24 | describe '#check_length' do 25 | it 'checks if a line is not longer than require' do 26 | expect(file.lines[0].check_length).to eql(true) 27 | end 28 | end 29 | 30 | describe '#opening_line?' do 31 | it 'Checks if the line is an oppening line' do 32 | expect(file.lines[0].opening_line?).not_to eql(true) 33 | end 34 | end 35 | 36 | describe '#closing_line?' do 37 | it 'Checks if the line is a closing line' do 38 | expect(file.lines[13].closing_line?).to eql(true) 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /spec/modules_spec/check_global_syntax_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative '../../lib/line' 2 | require_relative '../../lib/modules/check_global_syntax_helper' 3 | require_relative '../../lib/ruby_file' 4 | 5 | describe CheckGlobalSyntaxHelper do 6 | let(:line_class) { Line.new(1, ' class MyClass', 'class.rb') } 7 | let(:file) { RubyFile.new('./lib/line.rb') } 8 | describe '#check_open_end' do 9 | it 'returns false if the blocks are well closed in the file' do 10 | expect(CheckGlobalSyntaxHelper.check_open_end(file)).to eql(false) 11 | end 12 | end 13 | 14 | describe '#check_spaces' do 15 | it 'Returns a string if the class is preceeded by a space character' do 16 | expect(CheckGlobalSyntaxHelper.check_spaces(line_class)).not_to eql(false) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/modules_spec/check_naming_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative '../../lib/line' 2 | require_relative '../../lib/modules/check_naming_helper' 3 | require_relative '../../lib/ruby_file' 4 | 5 | describe CheckNamingHelper do 6 | let(:line_class) { Line.new(1, ' class MyClass', 'class.rb') } 7 | let(:line_meth) { Line.new(1, ' def MyMethod', 'class.rb') } 8 | describe '#check_class_module' do 9 | it 'returns false if the class name repects the camel case' do 10 | expect(CheckNamingHelper.check_class_module(line_class)).to eql(false) 11 | end 12 | end 13 | 14 | describe '#check_method_naming' do 15 | it 'Returns a string if the method name does not respect the namespacing rule' do 16 | expect(CheckNamingHelper.check_method_naming(line_meth)).not_to eql(false) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/modules_spec/check_syntax_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative '../../lib/line' 2 | require_relative '../../lib/modules/check_syntax_helper' 3 | require_relative '../../lib/ruby_file' 4 | 5 | describe CheckSyntaxHelper do 6 | let(:line_cond) { Line.new(1, ' if age==32', 'my_class.rb') } 7 | let(:line_loop) { Line.new(1, 'loop {}', 'my_class.rb') } 8 | let(:line_while) { Line.new(1, 'while age==32', 'my_class.rb') } 9 | let(:line_for) { Line.new(1, ' for age in ages', 'my_class.rb') } 10 | let(:line_time) { Line.new(1, '3.times do {}', 'my_class.rb') } 11 | describe '#check_cond_syntax' do 12 | it 'returns false if the syntax of the if correct' do 13 | expect(CheckSyntaxHelper.check_cond_syntax(line_cond)).to eql(false) 14 | end 15 | end 16 | 17 | describe '#check_loop_syntax' do 18 | it 'returns a string if the syntax of the loop is not correct' do 19 | expect(CheckSyntaxHelper.check_loop_syntax(line_loop)).not_to eql(false) 20 | end 21 | end 22 | 23 | describe '#check_while_until_syntax' do 24 | it 'returns false if the syntax of the while correct' do 25 | expect(CheckSyntaxHelper.check_while_until_syntax(line_while)).to eql(false) 26 | end 27 | end 28 | 29 | describe '#check_for_syntax' do 30 | it 'returns a string if the syntax of the for is not correct' do 31 | expect(CheckSyntaxHelper.check_for_syntax(line_for)).to eql(false) 32 | end 33 | end 34 | 35 | describe '#check_times_syntax' do 36 | it 'returns a string if the syntax of the times is not correct' do 37 | expect(CheckSyntaxHelper.check_times_syntax(line_time)).not_to eql(false) 38 | end 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /spec/modules_spec/file_check_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative '../../lib/line' 2 | require_relative '../../lib/modules/file_check' 3 | require_relative '../../lib/ruby_file' 4 | 5 | describe FileCheck do 6 | let(:errors) { [] } 7 | let(:line) { Line.new(1, ' class myclass', 'my_class.rb') } 8 | let(:file) { RubyFile.new('./lib/line.rb') } 9 | let(:dir) { './libs' } 10 | describe '#check_file' do 11 | it 'returns the same error array passed if the file syntax is ok' do 12 | expect(FileCheck.check_file(errors, file)).to eql(errors) 13 | end 14 | end 15 | 16 | describe '#file_exist' do 17 | it 'Returns true if the file do exist' do 18 | expect(FileCheck.file_exist('./lib/line.rb')).not_to eql(false) 19 | end 20 | end 21 | 22 | describe '#dir_exist' do 23 | it 'Returns a string if the folder does not exist' do 24 | expect(FileCheck.dir_exist(dir).class).to eql(String) 25 | end 26 | end 27 | 28 | describe '#content_ruby_files' do 29 | it 'Returns an array of filenames when the the folder contains ruby files' do 30 | expect(FileCheck.content_ruby_files('./lib').class).to eql(Array) 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /spec/modules_spec/lines_check_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative '../../lib/line' 2 | require_relative '../../lib/modules/lines_check' 3 | require_relative '../../lib/ruby_file' 4 | 5 | describe PreferenceHelper do 6 | let(:errors) { [] } 7 | let(:line) { Line.new(1, ' class myclass', 'my_class.rb') } 8 | let(:file) { RubyFile.new('./lib/line.rb') } 9 | describe '#LinesCheck' do 10 | it 'returns the same error array passed if the line lenght is ok' do 11 | expect(LinesCheck.check_length(errors, line)).to eql(errors) 12 | end 13 | end 14 | 15 | describe '#check_spacing' do 16 | it 'Returns an error in the array if there is a space before class declaration' do 17 | expect(LinesCheck.check_spacing(errors, line)).not_to eql(true) 18 | end 19 | end 20 | 21 | describe '#check_syntax' do 22 | it 'Returns the same error array if the syntax is ok' do 23 | expect(LinesCheck.check_syntax(errors, line)).to eql(errors) 24 | end 25 | end 26 | 27 | describe '#check_syntax' do 28 | it 'Returns the same error array if the syntax is ok' do 29 | expect(LinesCheck.check_syntax(errors, line)).to eql(errors) 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /spec/modules_spec/lint_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative '../../lib/line' 2 | require_relative '../../lib/modules/lint_helper' 3 | require 'colorize' 4 | require_relative '../../lib/ruby_file' 5 | 6 | describe LintHelper do 7 | let(:errors) { [] } 8 | let(:file) { './lib/line.rb' } 9 | let(:dir) { './libs' } 10 | describe '#start_linting_file' do 11 | it 'returns an empty errors array when the file is clean' do 12 | LintHelper.start_linting_file(file, errors) 13 | expect(errors.empty?).to eql(true) 14 | end 15 | end 16 | 17 | describe '#start_linting_dir' do 18 | it 'Returns nothing when the folder is empty' do 19 | expect(LintHelper.start_linting_file(dir, errors).class).not_to eql(String) 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /spec/modules_spec/preference_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative '../../lib/line' 2 | require_relative '../../lib/modules/preference_helper' 3 | require 'colorize' 4 | require_relative '../../lib/ruby_file' 5 | 6 | describe PreferenceHelper do 7 | let(:line) { Line.new(1, 'for file in files', 'my_class.rb') } 8 | let(:file) { RubyFile.new('./lib/line.rb') } 9 | describe '#each_against_for' do 10 | it 'suggest warning to use each when it meets a for in the code line' do 11 | expect(PreferenceHelper.each_against_for(line).type).to eql('Warning'.yellow) 12 | end 13 | end 14 | 15 | describe '#check_module' do 16 | it 'Returns false if there is only one class or module defined in the file' do 17 | expect(PreferenceHelper.check_module(file).class).not_to eql(String) 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/ruby_file_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/ruby_file' 2 | 3 | describe RubyFile do 4 | describe '#set_lines' do 5 | it 'It turn the file content into an array of lines' do 6 | file = RubyFile.new('./bin/main.rb') 7 | expect(file.lines[0].content).to eql('#!/usr/bin/env ruby') 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.expect_with :rspec do |expectations| 3 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true 4 | end 5 | config.mock_with :rspec do |mocks| 6 | mocks.verify_partial_doubles = true 7 | end 8 | config.shared_context_metadata_behavior = :apply_to_host_groups 9 | end 10 | --------------------------------------------------------------------------------