easytest 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 402f9f4048f129fbd845bc46cd92eb06e9345dff23355ffa9003bd59b88f6e0e
4
+ data.tar.gz: 1f59c66816c8fbbabb77c36a0bf6f0ec2114aad792e3aa7fa69c3b1517e314c1
5
+ SHA512:
6
+ metadata.gz: 320e1266f83153d7695b216d6d9f13832bdcd3e373c35297efb778e9fd75c0471eeeb484ad07b418771b528b1db91b8579f826099fa10550c80b10b2614e5f66
7
+ data.tar.gz: ec873b3bfb646766acaebfbb44fe866227491b3653a86fe85e402b156314306491ea0ffd37a3d5141b16a1e022dca77d046b4a68f9b5f7b3812adde5501cbc7a
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## 0.1.0
6
+
7
+ Initial release.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Masafumi Koba
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.
data/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # Easytest
2
+
3
+ > makes you write tests easily
4
+
5
+ Easytest is a tiny testing framework with a familiar DSL.
6
+
7
+ ## Installation
8
+
9
+ via Bundler:
10
+
11
+ ```shell
12
+ bundle add easytest
13
+ ```
14
+
15
+ via gem:
16
+
17
+ ```shell
18
+ gem install easytest
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ Here is a very easy example.
24
+
25
+ First, put `test/addition_test.rb` as below:
26
+
27
+ ```ruby
28
+ require "easytest"
29
+
30
+ using Easytest::DSL
31
+
32
+ test "addition" do
33
+ expect(1 + 2).to_eq 2
34
+ end
35
+ ```
36
+
37
+ Then, run `easytest`:
38
+
39
+ ```console
40
+ $ bundle exec easytest
41
+ FAIL test/addition_test.rb
42
+ ● addition (should equal)
43
+
44
+ Expected: 2
45
+ Received: 3
46
+
47
+ at test/addition_test.rb:6:in `block in <top (required)>'
48
+
49
+
50
+ Tests: 1 failed, 0 passed, 1 total (1 files)
51
+ Time: 0.00087 seconds
52
+ ```
53
+
54
+ Oops. Let's fix the failure:
55
+
56
+ ```diff
57
+ - expect(1 + 2).to_eq 2
58
+ + expect(1 + 2).to_eq 3
59
+ ```
60
+
61
+ Then, run it again:
62
+
63
+ ```console
64
+ $ bundle exec easytest
65
+ PASS test/addition_test.rb
66
+
67
+ Tests: 1 passed, 1 total (1 files)
68
+ Time: 0.00077 seconds
69
+ ```
70
+
71
+ The test passes! 🎉
data/exe/easytest ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.expand_path("../lib", __dir__)
4
+ $LOAD_PATH << File.join(Dir.pwd, "test")
5
+
6
+ require "easytest"
7
+
8
+ test_files = Dir.glob("test/**/*_test.rb").filter do |file|
9
+ ARGV.empty? || ARGV.any? { |pattern| file.include?(pattern) }
10
+ end
11
+ test_files.each { |file| load file }
@@ -0,0 +1,24 @@
1
+ module Easytest
2
+ class Case
3
+ attr_reader :name
4
+ attr_reader :file
5
+ attr_reader :block
6
+ attr_accessor :report
7
+
8
+ def initialize(name:, file:, &block)
9
+ @name = name
10
+ @file = file
11
+ @block = block
12
+ @report = nil
13
+ end
14
+
15
+ def run
16
+ block.call
17
+ true
18
+ rescue UnmatchedError => error
19
+ loc = error.backtrace_locations[2]
20
+ self.report = Reporter.new(error: error, file: loc.absolute_path, location: loc.to_s).report(name)
21
+ false
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ module Easytest
2
+ module DSL
3
+ refine Kernel do
4
+ def test(name, &block)
5
+ file = caller_locations(1, 1).first.absolute_path
6
+ Easytest.add_case Case.new(name: name, file: file, &block)
7
+ end
8
+
9
+ def expect(actual)
10
+ Expectation.new(actual)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Easytest
2
+ class Error < StandardError; end
3
+
4
+ class UnmatchedError < Error
5
+ attr_reader :actual
6
+ attr_reader :expected
7
+
8
+ def initialize(message:, actual:, expected:)
9
+ super(message)
10
+ @actual = actual
11
+ @expected = expected
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module Easytest
2
+ class Expectation
3
+ def initialize(actual)
4
+ @actual = actual
5
+ end
6
+
7
+ def to_eq(expected)
8
+ Matcher::Equal.new(actual: @actual, expected: expected).match!
9
+ end
10
+
11
+ def to_be(expected)
12
+ Matcher::Be.new(actual: @actual, expected: expected).match!
13
+ end
14
+
15
+ def to_be_nil
16
+ Matcher::BeNil.new(actual: @actual).match!
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Easytest
2
+ module Matcher
3
+ class Base
4
+ attr_reader :actual
5
+
6
+ def initialize(actual:)
7
+ @actual = actual
8
+ end
9
+
10
+ def match?
11
+ raise NotImplementedError
12
+ end
13
+
14
+ def match!
15
+ raise NotImplementedError
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ module Easytest
2
+ module Matcher
3
+ class Be < Base
4
+ attr_reader :expected
5
+
6
+ def initialize(actual:, expected:)
7
+ super(actual: actual)
8
+ @expected = expected
9
+ end
10
+
11
+ def match?
12
+ actual.equal? expected
13
+ end
14
+
15
+ def match!
16
+ unless match?
17
+ raise UnmatchedError.new(message: "should be same", actual: actual, expected: expected)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module Easytest
2
+ module Matcher
3
+ class BeNil < Base
4
+ def match?
5
+ actual.nil?
6
+ end
7
+
8
+ def match!
9
+ unless match?
10
+ raise UnmatchedError.new(message: "should be `nil`", actual: actual, expected: nil)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ module Easytest
2
+ module Matcher
3
+ class Equal < Base
4
+ attr_reader :expected
5
+
6
+ def initialize(actual:, expected:)
7
+ super(actual: actual)
8
+ @expected = expected
9
+ end
10
+
11
+ def match?
12
+ actual == expected
13
+ end
14
+
15
+ def match!
16
+ unless match?
17
+ raise UnmatchedError.new(message: "should equal", actual: actual, expected: expected)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ module Easytest
2
+ class Reporter
3
+ def initialize(error:, file:, location:)
4
+ @error = error
5
+ @file = file
6
+ @location = location
7
+ end
8
+
9
+ def report(test_name)
10
+ <<~MSG
11
+ #{Rainbow("● #{test_name}").red.bright} #{Rainbow("(#{@error.message})").dimgray}
12
+
13
+ #{Rainbow("Expected: #{@error.expected.inspect}").green}
14
+ #{Rainbow("Received: #{@error.actual.inspect}").red}
15
+
16
+ #{Rainbow("at #{@location}").dimgray}
17
+ MSG
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ module Easytest
2
+ module Utils
3
+ module_function
4
+
5
+ def terminal_hyperlink(absolute_path)
6
+ path = Pathname(absolute_path)
7
+ dir = path.relative_path_from(Dir.pwd).dirname.to_s + File::SEPARATOR
8
+ base = path.basename
9
+
10
+ # https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
11
+ "\e]8;;file://#{path}\e\\#{Rainbow(dir).dimgray}#{base}\e]8;;\e\\"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module Easytest
2
+ VERSION = "0.1.0"
3
+ end
data/lib/easytest.rb ADDED
@@ -0,0 +1,86 @@
1
+ require "pathname"
2
+ require "rainbow"
3
+
4
+ require_relative "easytest/version"
5
+
6
+ require_relative "easytest/case"
7
+ require_relative "easytest/dsl"
8
+ require_relative "easytest/errors"
9
+ require_relative "easytest/expectation"
10
+ require_relative "easytest/matcher/base"
11
+ require_relative "easytest/matcher/be"
12
+ require_relative "easytest/matcher/be_nil"
13
+ require_relative "easytest/matcher/equal"
14
+ require_relative "easytest/reporter"
15
+ require_relative "easytest/utils"
16
+
17
+ module Easytest
18
+ def self.run
19
+ passed_count = 0
20
+ failed_count = 0
21
+ file_count = 0
22
+
23
+ cases_by_file = cases.group_by { |c| c.file }
24
+ cases_by_file.each do |file, cases|
25
+ file_count += 1
26
+ reports = []
27
+
28
+ cases.each do |c|
29
+ passed = c.run
30
+
31
+ if passed
32
+ passed_count += 1
33
+ else
34
+ failed_count += 1
35
+ reports << c.report.gsub(/^/, " ")
36
+ end
37
+ end
38
+
39
+ link = Utils.terminal_hyperlink(file)
40
+ if reports.empty?
41
+ puts "#{Rainbow(" PASS ").bright.bg(:green)} #{link}"
42
+ else
43
+ puts "#{Rainbow(" FAIL ").bright.bg(:red)} #{link}"
44
+ reports.each { |report| puts report ; puts "" }
45
+ end
46
+ end
47
+
48
+ [passed_count, failed_count, file_count]
49
+ end
50
+
51
+ def self.cases
52
+ @cases ||= []
53
+ end
54
+
55
+ def self.add_case(new_case)
56
+ cases << new_case
57
+ end
58
+ end
59
+
60
+ start_time = Time.now
61
+
62
+ at_exit do
63
+ passed_count, failed_count, file_count = Easytest.run
64
+ total_count = passed_count + failed_count
65
+
66
+ time = Time.now - start_time
67
+
68
+ if total_count == 0
69
+ puts Rainbow("A test suite should have at least one test case!").red.bright
70
+ puts ""
71
+ puts "Please put `test/**/*_test.rb` files or specify valid patterns to the `easytest` command."
72
+ else
73
+ summary = ""
74
+ if failed_count == 0
75
+ summary << Rainbow("#{passed_count} passed").green.bright
76
+ else
77
+ summary << Rainbow("#{failed_count} failed").red.bright
78
+ summary << ", #{Rainbow("#{passed_count} passed").green.bright}"
79
+ end
80
+ summary << ", #{total_count} total #{Rainbow("(#{file_count} files)").dimgray}"
81
+
82
+ puts ""
83
+ puts " #{Rainbow('Tests:').bright} #{summary}"
84
+ puts " #{Rainbow('Time:').bright} #{time.round(5)} seconds"
85
+ end
86
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: easytest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Masafumi Koba
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-10-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rainbow
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ description: Easytest is a tiny testing framework for Ruby with a familiar DSL.
28
+ email:
29
+ - ybiquitous@gmail.com
30
+ executables:
31
+ - easytest
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - CHANGELOG.md
36
+ - LICENSE
37
+ - README.md
38
+ - exe/easytest
39
+ - lib/easytest.rb
40
+ - lib/easytest/case.rb
41
+ - lib/easytest/dsl.rb
42
+ - lib/easytest/errors.rb
43
+ - lib/easytest/expectation.rb
44
+ - lib/easytest/matcher/base.rb
45
+ - lib/easytest/matcher/be.rb
46
+ - lib/easytest/matcher/be_nil.rb
47
+ - lib/easytest/matcher/equal.rb
48
+ - lib/easytest/reporter.rb
49
+ - lib/easytest/utils.rb
50
+ - lib/easytest/version.rb
51
+ homepage: https://github.com/ybiquitous/easytest
52
+ licenses:
53
+ - MIT
54
+ metadata:
55
+ homepage_uri: https://github.com/ybiquitous/easytest
56
+ source_code_uri: https://github.com/ybiquitous/easytest
57
+ changelog_uri: https://github.com/ybiquitous/easytest/blob/main/CHANGELOG.md
58
+ rubygems_mfa_required: 'true'
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '2.7'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubygems_version: 3.3.7
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: Easy testing for Ruby.
78
+ test_files: []