mirror of
				https://gitea.invidious.io/iv-org/shard-ameba.git
				synced 2024-08-15 00:53:29 +00:00 
			
		
		
		
	Merge pull request #292 from crystal-ameba/Sija/lint-static-comparison
This commit is contained in:
		
						commit
						23ca87ff0e
					
				
					 2 changed files with 117 additions and 0 deletions
				
			
		
							
								
								
									
										59
									
								
								spec/ameba/rule/lint/static_comparison_spec.cr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								spec/ameba/rule/lint/static_comparison_spec.cr
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | ||||||
|  | require "../../../spec_helper" | ||||||
|  | 
 | ||||||
|  | module Ameba::Rule::Lint | ||||||
|  |   subject = StaticComparison.new | ||||||
|  | 
 | ||||||
|  |   describe StaticComparison do | ||||||
|  |     it "passes for valid cases" do | ||||||
|  |       expect_no_issues subject, <<-CRYSTAL | ||||||
|  |         "foo" == foo | ||||||
|  |         "foo" != foo | ||||||
|  |         foo == "foo" | ||||||
|  |         foo != "foo" | ||||||
|  |         CRYSTAL | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     it "reports if there is a static comparison evaluating to the same" do | ||||||
|  |       expect_issue subject, <<-CRYSTAL | ||||||
|  |         "foo" === "foo" | ||||||
|  |         # ^^^^^^^^^^^^^ error: Comparison always evaluates to the same | ||||||
|  |         CRYSTAL | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     it "reports if there is a static comparison evaluating to true (2)" do | ||||||
|  |       expect_issue subject, <<-CRYSTAL | ||||||
|  |         "foo" == "foo" | ||||||
|  |         # ^^^^^^^^^^^^ error: Comparison always evaluates to true | ||||||
|  |         CRYSTAL | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     it "reports if there is a static comparison evaluating to false" do | ||||||
|  |       expect_issue subject, <<-CRYSTAL | ||||||
|  |         "foo" != "foo" | ||||||
|  |         # ^^^^^^^^^^^^ error: Comparison always evaluates to false | ||||||
|  |         CRYSTAL | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     context "macro" do | ||||||
|  |       it "reports in macro scope" do | ||||||
|  |         expect_issue subject, <<-CRYSTAL | ||||||
|  |           {{ "foo" == "foo" }} | ||||||
|  |            # ^^^^^^^^^^^^^^ error: Comparison always evaluates to true | ||||||
|  |           CRYSTAL | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     it "reports rule, pos and message" do | ||||||
|  |       s = Source.new %( | ||||||
|  |         "foo" == "foo" | ||||||
|  |       ), "source.cr" | ||||||
|  |       subject.catch(s).should_not be_valid | ||||||
|  |       issue = s.issues.first | ||||||
|  | 
 | ||||||
|  |       issue.rule.should_not be_nil | ||||||
|  |       issue.location.to_s.should eq "source.cr:1:1" | ||||||
|  |       issue.end_location.to_s.should eq "source.cr:1:14" | ||||||
|  |       issue.message.should eq "Comparison always evaluates to true" | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										58
									
								
								src/ameba/rule/lint/static_comparison.cr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/ameba/rule/lint/static_comparison.cr
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,58 @@ | ||||||
|  | module Ameba::Rule::Lint | ||||||
|  |   # This rule is used to identify static comparisons - | ||||||
|  |   # the ones that will always have the same result. | ||||||
|  |   # | ||||||
|  |   # For example, this will be always false: | ||||||
|  |   # | ||||||
|  |   # ``` | ||||||
|  |   # "foo" == 42 | ||||||
|  |   # ``` | ||||||
|  |   # | ||||||
|  |   # YAML configuration example: | ||||||
|  |   # | ||||||
|  |   # ``` | ||||||
|  |   # Lint/StaticComparison: | ||||||
|  |   #   Enabled: true | ||||||
|  |   # ``` | ||||||
|  |   class StaticComparison < Base | ||||||
|  |     include AST::Util | ||||||
|  | 
 | ||||||
|  |     properties do | ||||||
|  |       description "Identifies static comparisons" | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     OP_NAMES = %w(=== == !=) | ||||||
|  |     MSG      = "Comparison always evaluates to %s" | ||||||
|  | 
 | ||||||
|  |     PRIMITIVES = { | ||||||
|  |       Crystal::NilLiteral, | ||||||
|  |       Crystal::BoolLiteral, | ||||||
|  |       Crystal::NumberLiteral, | ||||||
|  |       Crystal::CharLiteral, | ||||||
|  |       Crystal::StringLiteral, | ||||||
|  |       Crystal::SymbolLiteral, | ||||||
|  |       Crystal::RangeLiteral, | ||||||
|  |       Crystal::RegexLiteral, | ||||||
|  |       Crystal::TupleLiteral, | ||||||
|  |       Crystal::NamedTupleLiteral, | ||||||
|  |       Crystal::ArrayLiteral, | ||||||
|  |       Crystal::HashLiteral, | ||||||
|  |       Crystal::ProcLiteral, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     def test(source, node : Crystal::Call) | ||||||
|  |       return unless node.name.in?(OP_NAMES) | ||||||
|  |       return unless (obj = node.obj) && (arg = node.args.first?) | ||||||
|  |       return unless obj.class.in?(PRIMITIVES) && arg.class.in?(PRIMITIVES) | ||||||
|  | 
 | ||||||
|  |       what = | ||||||
|  |         case node.name | ||||||
|  |         when "===" then "the same" | ||||||
|  |         when "=="  then (obj.to_s == arg.to_s).to_s | ||||||
|  |         when "!="  then (obj.to_s != arg.to_s).to_s | ||||||
|  |         end | ||||||
|  | 
 | ||||||
|  |       issue_for node, MSG % what | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue