learn-test 1.1.0

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 (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +23 -0
  6. data/README.md +38 -0
  7. data/Rakefile +2 -0
  8. data/bin/learn-test +78 -0
  9. data/learn-test.gemspec +30 -0
  10. data/lib/learn_test.rb +26 -0
  11. data/lib/learn_test/file_finder.rb +12 -0
  12. data/lib/learn_test/github_interactor.rb +23 -0
  13. data/lib/learn_test/jasmine/boot.js +184 -0
  14. data/lib/learn_test/jasmine/console.js +161 -0
  15. data/lib/learn_test/jasmine/formatters/jasmine2-junit.js +199 -0
  16. data/lib/learn_test/jasmine/helpers/ConsoleHelper.js +12 -0
  17. data/lib/learn_test/jasmine/helpers/ConsoleHelperNoColor.js +12 -0
  18. data/lib/learn_test/jasmine/initializer.rb +27 -0
  19. data/lib/learn_test/jasmine/jasmine-html.js +360 -0
  20. data/lib/learn_test/jasmine/jasmine-jquery.js +813 -0
  21. data/lib/learn_test/jasmine/jasmine.css +56 -0
  22. data/lib/learn_test/jasmine/jasmine.js +2403 -0
  23. data/lib/learn_test/jasmine/jasmine_favicon.png +0 -0
  24. data/lib/learn_test/jasmine/jquery-1.8.0.min.js +2 -0
  25. data/lib/learn_test/jasmine/jquery-ui-1.8.23.custom.min.js +125 -0
  26. data/lib/learn_test/jasmine/phantom_checker.rb +55 -0
  27. data/lib/learn_test/jasmine/runner.rb +129 -0
  28. data/lib/learn_test/jasmine/runners/SpecRunner.html +35 -0
  29. data/lib/learn_test/jasmine/runners/run-jasmine.js +228 -0
  30. data/lib/learn_test/jasmine/templates/SpecRunnerTemplate.html.erb +35 -0
  31. data/lib/learn_test/jasmine/templates/SpecRunnerTemplateNoColor.html.erb +35 -0
  32. data/lib/learn_test/jasmine/templates/requires.yml.example +7 -0
  33. data/lib/learn_test/jasmine/vendor/require.js +2077 -0
  34. data/lib/learn_test/netrc_interactor.rb +18 -0
  35. data/lib/learn_test/python_unittest/nose_installer.rb +35 -0
  36. data/lib/learn_test/python_unittest/requirements_checker.rb +57 -0
  37. data/lib/learn_test/python_unittest/runner.rb +89 -0
  38. data/lib/learn_test/repo_parser.rb +22 -0
  39. data/lib/learn_test/rspec/runner.rb +113 -0
  40. data/lib/learn_test/spec_type_parser.rb +26 -0
  41. data/lib/learn_test/user_id_parser.rb +9 -0
  42. data/lib/learn_test/username_parser.rb +19 -0
  43. data/lib/learn_test/version.rb +3 -0
  44. data/spec/features/jasmine_jquery_fixtures_spec.rb +10 -0
  45. data/spec/features/rspec_unit_spec.rb +10 -0
  46. data/spec/fixtures/jasmine-jquery-fixtures/index.html +10 -0
  47. data/spec/fixtures/jasmine-jquery-fixtures/requires.yml +4 -0
  48. data/spec/fixtures/jasmine-jquery-fixtures/spec/jasmine-jquery-fixtures-spec.js +11 -0
  49. data/spec/fixtures/rspec-unit-spec/.rspec +2 -0
  50. data/spec/fixtures/rspec-unit-spec/lib/dog.rb +2 -0
  51. data/spec/fixtures/rspec-unit-spec/spec/dog_spec.rb +7 -0
  52. data/spec/fixtures/rspec-unit-spec/spec/spec_helper.rb +93 -0
  53. data/spec/repo_parser_spec.rb +25 -0
  54. data/spec/spec_helper.rb +10 -0
  55. metadata +237 -0
@@ -0,0 +1,18 @@
1
+ require 'netrc'
2
+
3
+ module LearnTest
4
+ class NetrcInteractor
5
+ attr_reader :username, :user_id, :netrc
6
+
7
+ def initialize
8
+ @netrc = Netrc.read
9
+ @username, @user_id = netrc["flatiron-push"]
10
+ end
11
+
12
+ def write(username, user_id)
13
+ netrc["flatiron-push"] = username, user_id
14
+ netrc.save
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,35 @@
1
+ module LearnTest
2
+ module PythonUnittest
3
+ class NoseInstaller
4
+ def self.install
5
+ new.install
6
+ end
7
+
8
+ def install
9
+ install_nose
10
+ install_nose_json
11
+ end
12
+
13
+ def install_nose
14
+ if !nose_installed?
15
+ `pip install nose`
16
+ end
17
+ end
18
+
19
+ def nose_installed?
20
+ !`which nosetests`.empty?
21
+ end
22
+
23
+ def install_nose_json
24
+ if !nose_json_installed?
25
+ `pip install nose-json`
26
+ end
27
+ end
28
+
29
+ def nose_json_installed?
30
+ !`pip show nose-json`.empty?
31
+ end
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,57 @@
1
+ require 'open3'
2
+
3
+ module LearnTest
4
+ module PythonUnittest
5
+ class RequirementsChecker
6
+ def self.check_installation
7
+ new.check_installation
8
+ end
9
+
10
+ def check_installation
11
+ PythonChecker.check
12
+ PipChecker.check
13
+ end
14
+ end
15
+
16
+ class PythonChecker
17
+ def self.check
18
+ new.check
19
+ end
20
+
21
+ def check
22
+ if !python_installed? || !correct_python_version?
23
+ puts "Please install python 2.7.x or 3.x.x"
24
+ exit
25
+ end
26
+ end
27
+
28
+ def python_installed?
29
+ !`which python`.empty?
30
+ end
31
+
32
+ def correct_python_version?
33
+ output = Open3.popen3('python', '--version')
34
+ version = output[2].read.strip
35
+ !!version.match(/ 2.7.*| 3.*/)
36
+ end
37
+ end
38
+
39
+ class PipChecker
40
+ def self.check
41
+ new.check
42
+ end
43
+
44
+ def check
45
+ if !pip_installed?
46
+ puts "Please ensure pip is installed"
47
+ exit
48
+ end
49
+ end
50
+
51
+ def pip_installed?
52
+ !`which pip`.empty?
53
+ end
54
+ end
55
+ end
56
+ end
57
+
@@ -0,0 +1,89 @@
1
+ module LearnTest
2
+ module PythonUnittest
3
+ class Runner
4
+ attr_accessor :parsed_output, :json_output, :formatted_results
5
+ attr_reader :username, :user_id, :repo_name, :options, :connection
6
+
7
+ def initialize(username, user_id, repo_name, options)
8
+ @username = username
9
+ @user_id = user_id
10
+ @repo_name = repo_name
11
+ @options = options
12
+ @json_output = ""
13
+ @parsed_output = nil
14
+ @formatted_results = {}
15
+ @connection = Faraday.new(url: SERVICE_URL) do |faraday|
16
+ faraday.adapter Faraday.default_adapter
17
+ end
18
+ end
19
+
20
+ def run
21
+ run_nose
22
+ if !options.include?('-h') && !options.include?('--help')
23
+ set_json_output
24
+ jsonify
25
+ format_results
26
+ push_results
27
+ cleanup
28
+ end
29
+ end
30
+
31
+ def run_nose
32
+ system("nosetests #{options.join(' ')} --verbose --with-json --json-file='./.results.json'")
33
+ end
34
+
35
+ def set_json_output
36
+ self.json_output = File.read('.results.json')
37
+ end
38
+
39
+ def jsonify
40
+ self.parsed_output = Oj.load(json_output, symbol_keys: true)
41
+ end
42
+
43
+ def format_results
44
+ self.formatted_results.merge!({
45
+ username: username,
46
+ github_user_id: user_id,
47
+ repo_name: repo_name,
48
+ build: {
49
+ test_suite: [{
50
+ framework: 'unittest',
51
+ formatted_output: parsed_output,
52
+ duration: calculate_duration
53
+ }]
54
+ },
55
+ examples: parsed_output[:stats][:total],
56
+ passing_count: parsed_output[:stats][:passes],
57
+ pending_count: parsed_output[:stats][:skipped],
58
+ failure_count: parsed_output[:stats][:errors],
59
+ failure_descriptions: concat_failure_descriptions
60
+ })
61
+ end
62
+
63
+ def calculate_duration
64
+ parsed_output[:results].map do |example|
65
+ example[:time]
66
+ end.inject(:+)
67
+ end
68
+
69
+ def concat_failure_descriptions
70
+ parsed_output[:results].select do |example|
71
+ example[:type] == 'failure'
72
+ end.map { |ex| ex[:tb] }.join(';')
73
+ end
74
+
75
+ def push_results
76
+ connection.post do |req|
77
+ req.url SERVICE_ENDPOINT
78
+ req.headers['Content-Type'] = 'application/json'
79
+ req.body = Oj.dump(formatted_results, mode: :compat)
80
+ end
81
+ end
82
+
83
+ def cleanup
84
+ FileUtils.rm('.results.json')
85
+ end
86
+ end
87
+ end
88
+ end
89
+
@@ -0,0 +1,22 @@
1
+ require 'git'
2
+
3
+ module LearnTest
4
+ class RepoParser
5
+ def self.get_repo
6
+ begin
7
+ repo = Git.open(FileUtils.pwd)
8
+ rescue
9
+ puts "Not a valid Git repository"
10
+ die
11
+ end
12
+
13
+ url = repo.remote.url
14
+ url.match(/(?:https:\/\/|git@).*\/(.+?)(?:\.git)?$/)[1]
15
+ end
16
+
17
+ def self.die
18
+ exit
19
+ end
20
+ end
21
+ end
22
+
@@ -0,0 +1,113 @@
1
+ module LearnTest
2
+ module RSpec
3
+ class Runner
4
+ attr_accessor :parsed_output, :json_output, :formatted_results
5
+ attr_reader :username, :user_id, :repo_name, :options, :connection
6
+
7
+ def initialize(username, user_id, repo_name, options)
8
+ @username = username
9
+ @user_id = user_id
10
+ @repo_name = repo_name
11
+ @options = options
12
+ @json_output = ""
13
+ @parsed_output = nil
14
+ @formatted_results = {}
15
+ @connection = Faraday.new(url: SERVICE_URL) do |faraday|
16
+ faraday.adapter Faraday.default_adapter
17
+ end
18
+ end
19
+
20
+ def run
21
+ check_options
22
+ run_rspec
23
+ if !options.include?('-h') && !options.include?('--help')
24
+ set_json_output
25
+ jsonify
26
+ format_results
27
+ push_results
28
+ cleanup
29
+ end
30
+ end
31
+
32
+ def check_options
33
+ options_has_format = options.include?('--format') || options.include?('-f')
34
+ if dot_rspec = read_dot_rspec
35
+ if options_has_format
36
+ if dot_rspec.any? {|dot_opt| dot_opt.match(/--format|-f/)}
37
+ options << dot_rspec.reject {|dot_opt| dot_opt.match(/--format|-f/)}
38
+ else
39
+ options << dot_rspec
40
+ end
41
+ end
42
+ end
43
+
44
+ if options_has_format
45
+ self.options.flatten!
46
+ else
47
+ options.unshift('--format documentation')
48
+ end
49
+
50
+ # Don't pass the test/local flag from learn binary to rspec runner.
51
+ options.delete("--test")
52
+ options.delete("-t")
53
+ options.delete("-l")
54
+ options.delete("--local")
55
+ end
56
+
57
+ def read_dot_rspec
58
+ if File.exist?('.rspec')
59
+ File.readlines('.rspec').map(&:strip)
60
+ else
61
+ nil
62
+ end
63
+ end
64
+
65
+ def run_rspec
66
+ system("rspec #{options.join(' ')} --format j --out .results.json")
67
+ end
68
+
69
+ def set_json_output
70
+ self.json_output = File.read('.results.json')
71
+ end
72
+
73
+ def jsonify
74
+ self.parsed_output = Oj.load(json_output, symbol_keys: true)
75
+ end
76
+
77
+ def format_results
78
+ self.formatted_results.merge!({
79
+ username: username,
80
+ github_user_id: user_id,
81
+ repo_name: repo_name,
82
+ build: {
83
+ test_suite: [{
84
+ framework: 'rspec',
85
+ formatted_output: parsed_output,
86
+ duration: parsed_output[:summary][:duration]
87
+ }]
88
+ },
89
+ examples: parsed_output[:summary][:example_count],
90
+ passing_count: parsed_output[:summary][:example_count] - parsed_output[:summary][:failure_count] - parsed_output[:summary][:pending_count],
91
+ pending_count: parsed_output[:summary][:pending_count],
92
+ failure_count: parsed_output[:summary][:failure_count],
93
+ failure_descriptions: parsed_output[:examples].select do |example|
94
+ example[:status] == "failed"
95
+ end.map { |ex| ex[:full_description] }.join(";")
96
+ })
97
+ end
98
+
99
+ def push_results
100
+ connection.post do |req|
101
+ req.url SERVICE_ENDPOINT
102
+ req.headers['Content-Type'] = 'application/json'
103
+ req.body = Oj.dump(formatted_results, mode: :compat)
104
+ end
105
+ end
106
+
107
+ def cleanup
108
+ FileUtils.rm('.results.json')
109
+ end
110
+ end
111
+ end
112
+ end
113
+
@@ -0,0 +1,26 @@
1
+ module LearnTest
2
+ class SpecTypeParser
3
+ attr_reader :spec_type
4
+
5
+ def initialize
6
+ @spec_type = parse_spec_type
7
+ end
8
+
9
+ private
10
+
11
+ def parse_spec_type
12
+ files = Dir.entries('.')
13
+
14
+ if files.include?('requires.yml')
15
+ 'jasmine'
16
+ elsif files.any? {|f| f.match(/.*.py$/) }
17
+ 'python_unittest'
18
+ elsif files.include?('spec')
19
+ spec_files = Dir.entries('./spec')
20
+ if spec_files.include?('spec_helper.rb') || spec_files.include?('rails_helper.rb')
21
+ 'rspec'
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ module LearnTest
2
+ class UserIdParser
3
+ def self.get_user_id
4
+ parser = LearnTest::NetrcInteractor.new
5
+ parser.user_id
6
+ end
7
+ end
8
+ end
9
+
@@ -0,0 +1,19 @@
1
+ module LearnTest
2
+ class UsernameParser
3
+ def self.get_username
4
+ parser = LearnTest::NetrcInteractor.new
5
+ username = parser.username
6
+ user_id = parser.user_id
7
+
8
+ if !username || user_id == 'none'
9
+ print "Enter your github username: "
10
+ username = gets.strip
11
+ user_id = LearnTest::GithubInteractor.get_user_id_for(username)
12
+ parser.write(username, user_id)
13
+ end
14
+
15
+ username
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,3 @@
1
+ module LearnTest
2
+ VERSION = "1.1.0"
3
+ end
@@ -0,0 +1,10 @@
1
+ describe "Running a Jasmine jQuery Specs with Fixtures" do
2
+ context 'without a browser through PhantomJS' do
3
+ it 'runs the spec with 0 failures' do
4
+ output = `cd ./spec/fixtures/jasmine-jquery-fixtures && ./../../../bin/learn-test --local --test`
5
+
6
+ expect(output).to include('1 spec, 0 failures')
7
+ expect(output).to_not include('1 failures')
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ describe "Running a RSpec Unit Test" do
2
+ context 'a basic rspec unit test' do
3
+ it 'runs the spec with 0 failures' do
4
+ output = `cd ./spec/fixtures/rspec-unit-spec && ./../../../bin/learn-test --local --test`
5
+
6
+ expect(output).to include('1 example, 0 failures')
7
+ expect(output).to_not include('1 failures')
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Jasmine Jquery Fixture Test</title>
6
+ </head>
7
+ <body>
8
+ <h1>Hello World</h1>
9
+ </body>
10
+ </html>
@@ -0,0 +1,4 @@
1
+ # A list of javascript files required for the project, in dependency order
2
+ javascripts:
3
+ specs:
4
+ - spec/jasmine-jquery-fixtures-spec.js
@@ -0,0 +1,11 @@
1
+ 'use-strict';
2
+
3
+ describe('Using a local HTML fixture with jQuery', function() {
4
+ beforeEach(function() {
5
+ loadFixtures('index.html');
6
+ });
7
+
8
+ it('can use jQuery against a local fixture', function() {
9
+ expect($('h1').text()).toBe('Hello World');
10
+ });
11
+ });