exercism 0.0.18 → 0.0.19

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.
data/exercism.gemspec CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_dependency "json"
21
22
  spec.add_dependency "faraday"
22
23
  spec.add_dependency "thor"
23
24
  spec.add_development_dependency "bundler", "~> 1.3"
@@ -28,7 +29,6 @@ Gem::Specification.new do |spec|
28
29
 
29
30
 
30
31
  if RUBY_VERSION <= "1.8.7"
31
- spec.add_dependency "json"
32
32
  spec.add_development_dependency "nokogiri", "~>1.5.0"
33
33
  else
34
34
  spec.add_development_dependency "nokogiri", "~>1.6.0"
data/lib/cli.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'rubygems' if RUBY_VERSION == '1.8.7'
1
2
  require 'thor'
2
3
 
3
4
  class Exercism
@@ -50,12 +51,22 @@ class Exercism
50
51
  def submit(file)
51
52
  require 'exercism'
52
53
 
53
- path = File.join(FileUtils.pwd, file)
54
+ submission = Submission.new(file)
55
+
56
+ if submission.test?
57
+ say "It looks like this is a test, you probably don't want to do that."
58
+ if no?("Do you want to submit it anyway? [y/n]")
59
+ return
60
+ end
61
+ end
62
+
54
63
  begin
55
- response = Exercism::Api.new(options[:host], Exercism.user).submit(file)
56
- puts "Your assignment has been submitted."
57
- url = submission_url(response.body, options[:host])
58
- puts "For feedback on your submission visit #{url}"
64
+ response = Exercism::Api.new(options[:host], Exercism.user).submit(submission.file)
65
+ say "Your assignment has been submitted."
66
+
67
+ body = JSON.parse(response.body)
68
+ url = "#{options[:host]}/#{Exercism.user.github_username}/#{body['language']}/#{body['exercise']}"
69
+ say "For feedback on your submission visit #{url}"
59
70
  rescue Exception => e
60
71
  puts "There was an issue with your submission."
61
72
  puts e.message
@@ -68,13 +79,24 @@ class Exercism
68
79
 
69
80
  username = ask("Your GitHub username:")
70
81
  key = ask("Your exercism.io API key:")
71
- default_path = FileUtils.pwd
72
- path = ask("What is your exercism exercises project path? (#{default_path})")
73
- if path.empty?
74
- path = default_path
82
+ default_dir = FileUtils.pwd
83
+ say "What is your exercism exercises project path?"
84
+ say "Press Enter to select the default (#{default_dir}):\n"
85
+ dir = ask ">"
86
+ if dir.empty?
87
+ dir = default_dir
88
+ end
89
+ project_dir = File.expand_path(dir)
90
+
91
+ say "Where do you want your configuration stored? (type a number)"
92
+ say "1. #{File.join(Exercism.home, '.exercism')}"
93
+ say "2. #{File.join(Exercism.home, '.config', 'exercism')}"
94
+
95
+ if ask(">").to_i == 2
96
+ Exercism.login username, key, project_dir, File.join(Exercism.home, '.config')
97
+ else
98
+ Exercism.login username, key, project_dir, Exercism.home
75
99
  end
76
- path = File.expand_path(path)
77
- Exercism.login(username, key, path)
78
100
 
79
101
  say("Your credentials have been written to #{Exercism.config.file}")
80
102
  end
@@ -95,22 +117,20 @@ class Exercism
95
117
  puts "You are not logged in."
96
118
  end
97
119
 
98
- private
120
+ private
121
+
99
122
  def api(host = options[:host])
100
123
  Exercism::Api.new(host, Exercism.user, Exercism.project_dir)
101
124
  end
102
125
 
103
- def submission_url(response_body, host)
104
- body = JSON.parse(response_body)
105
- "#{host}/user/#{body['language']}/#{body['exercise']}"
106
- end
107
-
108
126
  def report(assignments)
109
127
  if assignments.empty?
110
- puts "No assignments fetched."
128
+ say "No assignments fetched."
111
129
  else
112
130
  assignments.each do |assignment|
113
- puts "Fetched #{File.join(assignment.assignment_dir)}"
131
+ say "\nFetched #{assignment.exercise}"
132
+ say File.join(assignment.exercise, 'README.md')
133
+ say File.join(assignment.exercise, assignment.test_file)
114
134
  end
115
135
  end
116
136
  end
data/lib/exercism.rb CHANGED
@@ -3,36 +3,35 @@ require 'etc'
3
3
  require 'json'
4
4
  require 'yaml'
5
5
  require 'fileutils'
6
- require 'faraday'
6
+
7
+ old_warn, $-w = $-w, nil
8
+ begin
9
+ require 'faraday'
10
+ ensure
11
+ $-w = old_warn
12
+ end
13
+
7
14
  require 'exercism/version'
15
+ require 'exercism/env'
8
16
  require 'exercism/config'
9
17
  require 'exercism/user'
10
18
  require 'exercism/assignment'
19
+ require 'exercism/submission'
11
20
  require 'exercism/api'
12
21
 
13
22
  class Exercism
14
23
 
15
24
  def self.home
16
- if ENV["OS"] == 'Windows_NT' then
17
- ENV["HOMEDRIVE"]+ENV["HOMEPATH"]
18
- else
19
- return File.expand_path('~') if RUBY_VERSION <= "1.8.7"
20
- Dir.home(Etc.getlogin)
21
- end
25
+ @home ||= Env.home
22
26
  end
23
27
 
24
- def self.login(github_username, key, dir)
28
+ def self.login(github_username, key, dir, config_path)
25
29
  data = {
26
30
  'github_username' => github_username,
27
31
  'key' => key,
28
32
  'project_dir' => dir
29
33
  }
30
- Config.write(home, data)
31
- User.new(github_username, key)
32
- end
33
-
34
- def self.config
35
- Config.read(home)
34
+ Config.write(config_path, data)
36
35
  end
37
36
 
38
37
  def self.user
@@ -44,4 +43,11 @@ class Exercism
44
43
  config.project_dir
45
44
  end
46
45
 
46
+ def self.alternate_config_path
47
+ Config.alternate_path
48
+ end
49
+
50
+ def self.config
51
+ Config.read(home)
52
+ end
47
53
  end
@@ -3,7 +3,7 @@ class Exercism
3
3
 
4
4
  def self.save(data, path)
5
5
  data['assignments'].map do |attributes|
6
- Assignment.new(attributes.merge('project_dir' => path)).save
6
+ new(attributes.merge('project_dir' => path)).save
7
7
  end
8
8
  end
9
9
 
@@ -18,6 +18,10 @@ class Exercism
18
18
  @project_dir = attributes['project_dir']
19
19
  end
20
20
 
21
+ def exercise
22
+ File.join(track, slug)
23
+ end
24
+
21
25
  def save
22
26
  FileUtils.mkdir_p assignment_dir
23
27
  save_readme
@@ -1,8 +1,15 @@
1
1
  class Exercism
2
2
  class Config
3
3
 
4
+ def self.alternate_path
5
+ File.join(Env.home, '.config')
6
+ end
7
+
4
8
  def self.read(path)
5
- new(path)
9
+ config = new(path)
10
+ return config if config.exists?
11
+
12
+ new(alternate_path) unless config.exists?
6
13
  end
7
14
 
8
15
  def self.write(path, data)
@@ -13,11 +20,11 @@ class Exercism
13
20
  config.save
14
21
  end
15
22
 
16
- attr_reader :file
23
+ attr_reader :path
17
24
  attr_writer :github_username, :key, :project_dir
18
25
 
19
26
  def initialize(path)
20
- @file = File.join(path, '.exercism')
27
+ @path = path
21
28
  end
22
29
 
23
30
  def github_username
@@ -34,6 +41,8 @@ class Exercism
34
41
 
35
42
  def save
36
43
  FileUtils.mkdir_p(project_dir)
44
+ FileUtils.mkdir_p(path)
45
+
37
46
  File.open file, 'w' do |f|
38
47
  data = {
39
48
  'github_username' => github_username,
@@ -46,11 +55,27 @@ class Exercism
46
55
  end
47
56
 
48
57
  def delete
49
- FileUtils.rm(file) if File.exists?(file)
58
+ FileUtils.rm(file) if exists?
59
+ end
60
+
61
+ def exists?
62
+ File.exists?(file)
63
+ end
64
+
65
+ def file
66
+ @file ||= File.join(path, filename)
50
67
  end
51
68
 
52
69
  private
53
70
 
71
+ def filename
72
+ default? ? ".exercism" : "exercism"
73
+ end
74
+
75
+ def default?
76
+ path !~ /\.config/
77
+ end
78
+
54
79
  def from_yaml
55
80
  unless @data
56
81
  @data = YAML.load(File.read(file))
@@ -0,0 +1,21 @@
1
+ class Exercism
2
+ class Env
3
+ def self.home
4
+ if windows_nt?
5
+ ENV["HOMEDRIVE"] + ENV["HOMEPATH"]
6
+ elsif ruby18?
7
+ File.expand_path('~')
8
+ else
9
+ Dir.home(Etc.getlogin)
10
+ end
11
+ end
12
+
13
+ def self.windows_nt?
14
+ ENV["OS"] == 'Windows_NT'
15
+ end
16
+
17
+ def self.ruby18?
18
+ RUBY_VERSION == '1.8.7'
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,28 @@
1
+ class Exercism
2
+ class Submission
3
+
4
+ def self.test?(file)
5
+ new(file).test?
6
+ end
7
+
8
+ attr_reader :file
9
+ def initialize(file)
10
+ @file = file
11
+ end
12
+
13
+ def test?
14
+ test_identifiers.any? do |_, suffix|
15
+ file.end_with?(suffix)
16
+ end
17
+ end
18
+
19
+ def test_identifiers
20
+ {
21
+ :ruby => '_test.rb',
22
+ :js => '.spec.js',
23
+ :elixir => '_test.exs'
24
+ }
25
+ end
26
+
27
+ end
28
+ end
@@ -1,3 +1,3 @@
1
1
  class Exercism
2
- VERSION = "0.0.18"
2
+ VERSION = "0.0.19"
3
3
  end
@@ -6,8 +6,20 @@ class ConfigTest < Minitest::Test
6
6
  './test/fixtures'
7
7
  end
8
8
 
9
+ def data
10
+ {
11
+ 'github_username' => 'bob',
12
+ 'key' => '7a7096c',
13
+ 'project_dir' => '/tmp'
14
+ }
15
+ end
16
+
9
17
  def key
10
- '7a7096c'
18
+ data['key']
19
+ end
20
+
21
+ def write_config_file(path, info = {})
22
+ Exercism::Config.write(path, data.merge!(info))
11
23
  end
12
24
 
13
25
  def teardown
@@ -15,6 +27,10 @@ class ConfigTest < Minitest::Test
15
27
  FileUtils.rm('./test/fixtures/.exercism')
16
28
  end
17
29
 
30
+ if File.exists?('./test/fixtures/.config/exercism')
31
+ FileUtils.rm_r('./test/fixtures/.config')
32
+ end
33
+
18
34
  if File.exists?('./test/fixtures/some/project/dir')
19
35
  FileUtils.rm_r('./test/fixtures/some')
20
36
  end
@@ -27,39 +43,34 @@ class ConfigTest < Minitest::Test
27
43
  assert_equal '/tmp', config.project_dir
28
44
  end
29
45
 
46
+ def test_reads_from_alternate_path_config_file_when_default_is_missing
47
+ write_config_file('./test/fixtures/.config')
48
+ Exercism::Config.stub(:alternate_path, './test/fixtures/.config') do
49
+ config = Exercism::Config.read(path)
50
+ assert_equal 'bob', config.github_username
51
+ assert_equal key, config.key
52
+ assert_equal '/tmp', config.project_dir
53
+ end
54
+ end
55
+
30
56
  def test_write_config_file
31
- data = {
32
- 'github_username' => 'bob',
33
- 'key' => key,
34
- 'project_dir' => '/tmp'
35
- }
36
- config = Exercism::Config.write(path, data)
57
+ config = write_config_file(path)
37
58
  assert_equal 'bob', config.github_username
38
59
  assert_equal key, config.key
39
60
  assert_equal '/tmp', config.project_dir
40
61
  end
41
62
 
42
63
  def test_delete_config_file
43
- data = {
44
- 'github_username' => 'bob',
45
- 'key' => key,
46
- 'project_dir' => '/tmp'
47
- }
48
- config = Exercism::Config.write(path, data)
64
+ config = write_config_file(path)
49
65
  filename = config.file
50
66
  config.delete
51
67
  assert !File.exists?(filename)
52
68
  end
53
69
 
54
70
  def test_write_directory_if_missing
55
- project_dir = './test/fixtures/some/project/dir'
56
- data = {
57
- 'github_username' => 'bob',
58
- 'key' => key,
59
- 'project_dir' => project_dir
60
- }
61
- Exercism::Config.write(path, data)
62
- assert File.exist? project_dir
71
+ data = {'project_dir' => './test/fixtures/some/project/dir'}
72
+ write_config_file(path, data)
73
+ assert File.exist?(data['project_dir'])
63
74
  end
64
75
 
65
76
  end
@@ -0,0 +1,28 @@
1
+ require './test/test_helper'
2
+ require 'exercism/submission'
3
+
4
+ class SubmissionTest < Minitest::Test
5
+ def test_knows_ruby_code
6
+ refute Exercism::Submission.test?('queens.rb')
7
+ end
8
+
9
+ def test_identifies_ruby_tests
10
+ assert Exercism::Submission.test?('queens_test.rb')
11
+ end
12
+
13
+ def test_knows_elixir_code
14
+ refute Exercism::Submission.test?('queens.exs')
15
+ end
16
+
17
+ def test_identifies_elixir_tests
18
+ assert Exercism::Submission.test?('queens_test.exs')
19
+ end
20
+
21
+ def test_knows_javascript_code
22
+ refute Exercism::Submission.test?('queens.js')
23
+ end
24
+
25
+ def test_identifies_javascript_tests
26
+ assert Exercism::Submission.test?('queens.spec.js')
27
+ end
28
+ end
@@ -17,19 +17,11 @@ class ExercismTest < Minitest::Test
17
17
  end
18
18
  end
19
19
 
20
- def test_login_gives_you_a_user
21
- Exercism.stub(:home, './test/fixtures') do
22
- key = '97e9975'
23
- user = Exercism.login('bob', key, '/tmp')
24
- assert_equal 'bob', user.github_username
25
- assert_equal key, user.key
26
- end
27
- end
28
-
29
20
  def test_login_writes_the_config_file
30
- Exercism.stub(:home, './test/fixtures') do
21
+ home = './test/fixtures'
22
+ Exercism.stub(:home, home) do
31
23
  key = '97e9975'
32
- Exercism.login('bob', key, '/tmp')
24
+ Exercism.login('bob', key, '/tmp', home)
33
25
  user = Exercism.user
34
26
  assert_equal 'bob', user.github_username
35
27
  assert_equal key, user.key
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exercism
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.18
4
+ version: 0.0.19
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-25 00:00:00.000000000 Z
12
+ date: 2013-07-28 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: faraday
16
32
  requirement: !ruby/object:Gem::Requirement
@@ -176,11 +192,14 @@ files:
176
192
  - lib/exercism/api.rb
177
193
  - lib/exercism/assignment.rb
178
194
  - lib/exercism/config.rb
195
+ - lib/exercism/env.rb
196
+ - lib/exercism/submission.rb
179
197
  - lib/exercism/user.rb
180
198
  - lib/exercism/version.rb
181
199
  - test/exercism/api_test.rb
182
200
  - test/exercism/assignment_test.rb
183
201
  - test/exercism/config_test.rb
202
+ - test/exercism/submission_test.rb
184
203
  - test/exercism_test.rb
185
204
  - test/fixtures/approvals/alice_gets_bob_readme.approved.txt
186
205
  - test/fixtures/approvals/alice_gets_bob_tests.approved.txt
@@ -221,6 +240,7 @@ test_files:
221
240
  - test/exercism/api_test.rb
222
241
  - test/exercism/assignment_test.rb
223
242
  - test/exercism/config_test.rb
243
+ - test/exercism/submission_test.rb
224
244
  - test/exercism_test.rb
225
245
  - test/fixtures/approvals/alice_gets_bob_readme.approved.txt
226
246
  - test/fixtures/approvals/alice_gets_bob_tests.approved.txt