et 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: acf9f6211f8391114cb5a17db584a55e087d793c
4
- data.tar.gz: a55f0b806e22168cb62069f409b66703314eef6f
3
+ metadata.gz: f73dea1999d7fc46db767ea705e6022aceb45a24
4
+ data.tar.gz: 29df46b104d1484f458a5b9e60346a219544b4b7
5
5
  SHA512:
6
- metadata.gz: 2ce3471fc5b7b40cbf0e27fa989d052618893960d9893fa19c07d86e402a9b1a450c907b96d8d4eaf5841c2827e81d0637572dce7c426f99fd0ad8436e229d46
7
- data.tar.gz: 47ae0cafa0613bde14bd37d830fee47b36c1324a6134162494ce5af92bc92828ba88b9bdc939f9378f5ada89eb592707a277dac786817cb8e7620438baca2fce
6
+ metadata.gz: 4835233905faf16607d6fd5a37d264e814827b5be95b4477d43dd04588eaf3dfc03c6104be971f90a7e212a89c068e19dc51992c07582bcbd688c81f7694ac35
7
+ data.tar.gz: 14555a87bf0bd86fef92fcbb5256e7bd4cc82098c653d69566fc3f8aaae99f9dcf3232d34095228430b3e01c37eea759d63b8e7791f54dc59d9c29695cd66cd7
data/.gitignore CHANGED
@@ -1,2 +1,5 @@
1
1
  # Don't include output from gem builds.
2
2
  /*.gem
3
+
4
+ # Exclude a test-area for downloading/submitting challenges.
5
+ /sample
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --require et
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
@@ -3,12 +3,31 @@ PATH
3
3
  specs:
4
4
  et (0.0.1)
5
5
  gli (= 2.11.0)
6
+ rest-client (~> 1.7.2)
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
9
10
  specs:
11
+ diff-lcs (1.2.5)
10
12
  gli (2.11.0)
13
+ mime-types (2.3)
14
+ netrc (0.7.7)
11
15
  rake (10.3.2)
16
+ rest-client (1.7.2)
17
+ mime-types (>= 1.16, < 3.0)
18
+ netrc (~> 0.7)
19
+ rspec (3.0.0)
20
+ rspec-core (~> 3.0.0)
21
+ rspec-expectations (~> 3.0.0)
22
+ rspec-mocks (~> 3.0.0)
23
+ rspec-core (3.0.2)
24
+ rspec-support (~> 3.0.0)
25
+ rspec-expectations (3.0.2)
26
+ diff-lcs (>= 1.2.0, < 2.0)
27
+ rspec-support (~> 3.0.0)
28
+ rspec-mocks (3.0.2)
29
+ rspec-support (~> 3.0.0)
30
+ rspec-support (3.0.2)
12
31
 
13
32
  PLATFORMS
14
33
  ruby
@@ -16,3 +35,5 @@ PLATFORMS
16
35
  DEPENDENCIES
17
36
  et!
18
37
  rake (~> 10.3)
38
+ rspec (~> 3.0.0)
39
+ rspec-mocks (~> 3.0.0)
data/Rakefile CHANGED
@@ -1,41 +1,6 @@
1
1
  require "rake/clean"
2
- require "rubygems"
3
- require "rubygems/package_task"
4
- require "rdoc/task"
5
- require "cucumber"
6
- require "cucumber/rake/task"
2
+ require "rspec/core/rake_task"
7
3
 
8
- Rake::RDocTask.new do |rd|
9
- rd.main = "README.rdoc"
10
- rd.rdoc_files.include("README.rdoc", "lib/**/*.rb", "bin/**/*")
11
- rd.title = "Your application title"
12
- end
4
+ RSpec::Core::RakeTask.new(:spec)
13
5
 
14
- CUKE_RESULTS = "results.html"
15
- CLEAN << CUKE_RESULTS
16
- desc "Run features"
17
- Cucumber::Rake::Task.new(:features) do |t|
18
- opts = "features --format html -o #{CUKE_RESULTS} --format progress -x"
19
- opts += " --tags #{ENV["TAGS"]}" if ENV["TAGS"]
20
- t.cucumber_opts = opts
21
- t.fork = false
22
- end
23
-
24
- desc "Run features tagged as work-in-progress (@wip)"
25
- Cucumber::Rake::Task.new("features:wip") do |t|
26
- tag_opts = " --tags @wip"
27
- t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} " +
28
- "--format pretty -x -s#{tag_opts}"
29
- t.fork = false
30
- end
31
-
32
- task cucumber: :features
33
- task "cucumber:wip" => "features:wip"
34
- task wip: "features:wip"
35
- require "rake/testtask"
36
- Rake::TestTask.new do |t|
37
- t.libs << "test"
38
- t.test_files = FileList["test/*_test.rb"]
39
- end
40
-
41
- task default: [:test, :features]
6
+ task default: [:spec]
data/bin/et CHANGED
@@ -1,11 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- require "gli"
3
2
  require "et"
4
3
 
5
- include GLI::App
6
-
7
- program_desc "Describe your application here"
8
-
9
- version ET::VERSION
10
-
11
- exit run(ARGV)
4
+ runner = ET::Runner.new
5
+ exit runner.go(ARGV)
data/et.gemspec CHANGED
@@ -19,6 +19,9 @@ DESC
19
19
  s.bindir = "bin"
20
20
  s.executables << "et"
21
21
  s.license = "MIT"
22
- s.add_development_dependency("rake", "~> 10.3")
22
+ s.add_development_dependency("rake", "~> 10")
23
+ s.add_development_dependency("rspec", "~> 3.0")
24
+ s.add_development_dependency("rspec-mocks", "~> 3.0")
25
+ s.add_runtime_dependency("rest-client", "~> 1.7")
23
26
  s.add_runtime_dependency("gli", "2.11.0")
24
27
  end
data/lib/et.rb CHANGED
@@ -1,4 +1,5 @@
1
- require "et/version.rb"
2
-
3
- # Add requires for other files you add to your project here, so
4
- # you just need to require this one file in your bin file
1
+ require "et/version"
2
+ require "et/runner"
3
+ require "et/api"
4
+ require "et/config"
5
+ require "et/formatter"
@@ -0,0 +1,83 @@
1
+ require "rest-client"
2
+ require "securerandom"
3
+ require "base64"
4
+ require "json"
5
+
6
+ module ET
7
+ class API
8
+ attr_reader :host, :username, :token
9
+
10
+ def initialize(options)
11
+ @host = options[:host]
12
+ @username = options[:username]
13
+ @token = options[:token]
14
+ end
15
+
16
+ def list_challenges
17
+ response = RestClient.get(challenges_url)
18
+ JSON.parse(response, symbolize_names: true)
19
+ end
20
+
21
+ def get_challenge(slug)
22
+ response = RestClient.get(challenge_url(slug))
23
+ body = JSON.parse(response, symbolize_names: true)
24
+ body[:challenge]
25
+ end
26
+
27
+ def download_file(url)
28
+ uri = URI(url)
29
+ dest = random_filename
30
+
31
+ Net::HTTP.start(uri.host, uri.port,
32
+ use_ssl: uri.scheme == "https") do |http|
33
+
34
+ resp = http.get(uri.path)
35
+
36
+ open(dest, 'wb') do |file|
37
+ file.write(resp.body)
38
+ end
39
+ end
40
+
41
+ dest
42
+ end
43
+
44
+ def submit_challenge(dir)
45
+ Dir.mktmpdir do |tmpdir|
46
+ slug = File.basename(dir)
47
+
48
+ submission_file = File.join(tmpdir, "submission.tar.gz")
49
+ if system("tar zcf #{submission_file} -C #{dir} .")
50
+ RestClient.post(submission_url(slug),
51
+ { submission: { archive: File.new(submission_file) }},
52
+ { "Authorization" => auth_header })
53
+ end
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def challenge_url(slug)
60
+ URI.join(host, "challenges/#{slug}.json").to_s
61
+ end
62
+
63
+ def challenges_url
64
+ URI.join(host, "challenges.json").to_s
65
+ end
66
+
67
+ def submission_url(slug)
68
+ URI.join(host, "challenges/#{slug}/submissions.json").to_s
69
+ end
70
+
71
+ def random_filename
72
+ File.join(Dir.mktmpdir, SecureRandom.hex)
73
+ end
74
+
75
+ def credentials
76
+ Base64.strict_encode64("#{username}:#{token}")
77
+ end
78
+
79
+ def auth_header
80
+ "Basic #{credentials}"
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,60 @@
1
+ module ET
2
+ class Config
3
+ attr_reader :current_dir
4
+
5
+ def initialize(current_dir)
6
+ @current_dir = current_dir
7
+ end
8
+
9
+ def path
10
+ @path ||= find_config_file(current_dir)
11
+ end
12
+
13
+ def host
14
+ if options["host"].start_with?("http")
15
+ options["host"]
16
+ else
17
+ "http://" + options["host"]
18
+ end
19
+ end
20
+
21
+ def username
22
+ options["username"]
23
+ end
24
+
25
+ def token
26
+ options["token"]
27
+ end
28
+
29
+ def exists?
30
+ !path.nil?
31
+ end
32
+
33
+ def [](key)
34
+ options[key]
35
+ end
36
+
37
+ def update(options)
38
+ @options = options
39
+ File.write(path, options.to_yaml)
40
+ end
41
+
42
+ private
43
+
44
+ def options
45
+ @options ||= YAML.load(File.read(path))
46
+ end
47
+
48
+ def find_config_file(dir)
49
+ config_path = File.join(dir, ".et")
50
+
51
+ if File.exists?(config_path)
52
+ config_path
53
+ elsif dir == "/" || dir == "."
54
+ nil
55
+ else
56
+ find_config_file(File.dirname(dir))
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,42 @@
1
+ module ET
2
+ class Formatter
3
+ def self.print_table(data, *headers)
4
+ column_widths = headers.map do |header|
5
+ data.map { |row| row[header].length }.max
6
+ end
7
+
8
+ total_width = column_widths.reduce(0) do |width, sum|
9
+ sum + width + 3
10
+ end
11
+
12
+ header = build_row(headers, column_widths, YELLOW)
13
+
14
+ puts header
15
+ puts "\e[34m" + ("-" * total_width) + "\e[0m"
16
+
17
+ data.each do |row|
18
+ values = headers.map { |header| row[header] }
19
+ puts build_row(values, column_widths, WHITE)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def self.build_row(row, widths, color)
26
+ row.zip(widths).map do |value, width|
27
+ " \e[#{color}m%-#{width}s\e[0m " % value
28
+ end.join("\e[34m|\e[0m")
29
+ end
30
+
31
+ CLEAR = 0
32
+ BOLD = 1
33
+ BLACK = 30
34
+ RED = 31
35
+ GREEN = 32
36
+ YELLOW = 33
37
+ BLUE = 34
38
+ MAGENTA = 35
39
+ CYAN = 36
40
+ WHITE = 37
41
+ end
42
+ end
@@ -0,0 +1,135 @@
1
+ require "gli"
2
+ require "yaml"
3
+
4
+ module ET
5
+ class Runner
6
+ include GLI::App
7
+
8
+ attr_reader :cwd
9
+
10
+ def initialize(cwd = Dir.pwd)
11
+ @cwd = cwd
12
+ end
13
+
14
+ def go(args)
15
+ version VERSION
16
+
17
+ pre { |_, _, _, _| check_config! }
18
+
19
+ desc "Initialize current directory as challenge work area."
20
+ skips_pre
21
+ command :init do |c|
22
+ c.flag [:u, :user], desc: "Username"
23
+ c.flag [:t, :token], desc: "Login token"
24
+ c.flag [:h, :host], desc: "Server hosting the challenges"
25
+
26
+ c.action do |_global_options, options, _cmdargs|
27
+ settings = {
28
+ "username" => options[:user],
29
+ "token" => options[:token],
30
+ "host" => options[:host]
31
+ }
32
+
33
+ settings = prompt_for_missing(settings)
34
+ save_config(settings)
35
+ end
36
+ end
37
+
38
+ desc "List available challenges."
39
+ command :list do |c|
40
+ c.action do |_global_options, _options, _cmdargs|
41
+ Formatter.print_table(api.list_challenges[:challenges], :slug, :title)
42
+ end
43
+ end
44
+
45
+ desc "Download challenge to your working area."
46
+ command :get do |c|
47
+ c.action do |_global_options, _options, cmdargs|
48
+ cmdargs.each do |slug|
49
+ challenge = api.get_challenge(slug)
50
+ archive = api.download_file(challenge[:archive_url])
51
+
52
+ system("tar zxf #{archive} -C #{cwd}")
53
+ system("rm #{archive}")
54
+ end
55
+ end
56
+ end
57
+
58
+ desc "Submit the challenge in this directory."
59
+ command :submit do |c|
60
+ c.action do |_global_options, _options, _cmdargs|
61
+ api.submit_challenge(cwd)
62
+ end
63
+ end
64
+
65
+ run(args)
66
+ end
67
+
68
+ def api
69
+ @api ||= API.new(host: host, username: username, token: token)
70
+ end
71
+
72
+ def host
73
+ config.host
74
+ end
75
+
76
+ def username
77
+ config.username
78
+ end
79
+
80
+ def token
81
+ config.token
82
+ end
83
+
84
+ def setting(key)
85
+ config.exists? && config[key]
86
+ end
87
+
88
+ def config
89
+ @config ||= Config.new(cwd)
90
+ end
91
+
92
+ private
93
+
94
+ def prompt_for_missing(settings)
95
+ settings.each do |key, value|
96
+ if value.nil?
97
+ existing_value = setting(key)
98
+
99
+ if existing_value
100
+ print "#{key.capitalize} (#{existing_value}): "
101
+ else
102
+ print "#{key.capitalize}: "
103
+ end
104
+
105
+ input = gets.chomp
106
+
107
+ if input && !input.empty?
108
+ settings[key] = input
109
+ else
110
+ settings[key] = existing_value
111
+ end
112
+ end
113
+ end
114
+
115
+ settings
116
+ end
117
+
118
+ def check_config!
119
+ if config.exists?
120
+ true
121
+ else
122
+ raise StandardError.new("Could not find configuration file. " +
123
+ "Run `et init` to create one.")
124
+ end
125
+ end
126
+
127
+ def save_config(settings)
128
+ if config.exists?
129
+ config.update(settings)
130
+ else
131
+ File.write(File.join(cwd, ".et"), settings.to_yaml)
132
+ end
133
+ end
134
+ end
135
+ end
@@ -1,3 +1,3 @@
1
1
  module ET
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,42 @@
1
+ describe "get challenge" do
2
+ let(:challenge_info) do
3
+ {
4
+ title: "Some Challenge",
5
+ slug: "some-challenge",
6
+ archive_url: "http://localhost:3000/some-challenge.tar.gz"
7
+ }
8
+ end
9
+
10
+ let(:sample_archive_path) do
11
+ project_root.join("spec/data/some-challenge.tar.gz")
12
+ end
13
+
14
+ context "when in a working area" do
15
+ it "downloads and extracts the challenge" do
16
+ tmp_archive_path = File.join(Dir.tmpdir, "some-challenge.tar.gz")
17
+ system("cp #{sample_archive_path} #{tmp_archive_path}")
18
+
19
+ expect_any_instance_of(ET::API).to receive(:get_challenge).
20
+ with("some-challenge").
21
+ and_return(challenge_info)
22
+
23
+ expect_any_instance_of(ET::API).to receive(:download_file).
24
+ with("http://localhost:3000/some-challenge.tar.gz").
25
+ and_return(tmp_archive_path)
26
+
27
+ Dir.mktmpdir("test") do |tmpdir|
28
+ write_sample_config_to(tmpdir)
29
+
30
+ runner = ET::Runner.new(tmpdir)
31
+ _, _ = capture_output do
32
+ expect(runner.go(["get", "some-challenge"])).to eq(0)
33
+ end
34
+
35
+ ["some-challenge/README.md", "some-challenge/sample.rb"].each do |filename|
36
+ path = File.join(tmpdir, filename)
37
+ expect(File.exist?(path)).to eq(true)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,27 @@
1
+ require "json"
2
+
3
+ describe "init" do
4
+ it "writes the user credentials to a config file" do
5
+ Dir.mktmpdir("test") do |tmpdir|
6
+ arguments = [
7
+ "init",
8
+ "-u", "barry",
9
+ "-t", "foobar",
10
+ "-h", "http://localhost:3000"
11
+ ]
12
+
13
+ runner = ET::Runner.new(tmpdir)
14
+ _, _ = capture_output do
15
+ expect(runner.go(arguments)).to eq(0)
16
+ end
17
+
18
+ filepath = File.join(tmpdir, ".et")
19
+ expect(File.exist?(filepath)).to eq(true)
20
+
21
+ config = YAML.load(File.read(filepath))
22
+ expect(config["username"]).to eq("barry")
23
+ expect(config["token"]).to eq("foobar")
24
+ expect(config["host"]).to eq("http://localhost:3000")
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ describe "list challenges" do
2
+ let(:sample_challenges) do
3
+ {
4
+ challenges: [
5
+ { title: "Guess the Number", slug: "guess-the-number" },
6
+ { title: "Blackjack", slug: "blackjack" }
7
+ ]
8
+ }
9
+ end
10
+
11
+ it "prints the titles and slug" do
12
+ expect_any_instance_of(ET::API).to receive(:list_challenges).
13
+ and_return(sample_challenges)
14
+
15
+ Dir.mktmpdir("test") do |tmpdir|
16
+ write_sample_config_to(tmpdir)
17
+
18
+ runner = ET::Runner.new(tmpdir)
19
+ stdout, _ = capture_output do
20
+ expect(runner.go(["list"])).to eq(0)
21
+ end
22
+
23
+ expect(stdout).to include("Guess the Number")
24
+ expect(stdout).to include("guess-the-number")
25
+
26
+ expect(stdout).to include("Blackjack")
27
+ expect(stdout).to include("blackjack")
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ describe "submit challenge" do
2
+ let(:sample_archive_path) do
3
+ project_root.join("spec/data/archive.tar.gz")
4
+ end
5
+
6
+ context "when in a working area" do
7
+ it "packages and uploads directory" do
8
+ Dir.mktmpdir("test") do |tmpdir|
9
+ write_sample_config_to(tmpdir)
10
+ challenge_dir = write_sample_challenge_to(tmpdir, "some-challenge")
11
+
12
+ expect_any_instance_of(ET::API).to receive(:submit_challenge).
13
+ with(challenge_dir).
14
+ and_return(true)
15
+
16
+ runner = ET::Runner.new(challenge_dir)
17
+ _, _ = capture_output do
18
+ expect(runner.go(["submit"])).to eq(0)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1 @@
1
+ {"challenges":[{"title":"Auto-Guesser","slug":"auto-guesser"},{"title":"Guess the Number","slug":"guess-the-number"}]}
@@ -0,0 +1,21 @@
1
+ describe ET::API do
2
+ let(:api) { ET::API.new(host: "http://localhost:3000") }
3
+
4
+ describe "challenges" do
5
+ let(:challenges_response) do
6
+ File.read("spec/data/challenges.json")
7
+ end
8
+
9
+ it "queries for a list of challenges" do
10
+ expect(RestClient).to receive(:get).
11
+ with("http://localhost:3000/challenges.json").
12
+ and_return(challenges_response)
13
+
14
+ results = api.list_challenges
15
+
16
+ expect(results[:challenges].count).to eq(2)
17
+ expect(results[:challenges][0][:title]).to eq("Auto-Guesser")
18
+ expect(results[:challenges][0][:slug]).to eq("auto-guesser")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,49 @@
1
+ describe ET::Config do
2
+ describe "#path" do
3
+ it "finds the config file in the given directory" do
4
+ Dir.mktmpdir("test") do |tmpdir|
5
+ write_sample_config_to(tmpdir)
6
+
7
+ config = ET::Config.new(tmpdir)
8
+ expect(config.path).to eq(File.join(tmpdir, ".et"))
9
+ end
10
+ end
11
+
12
+ it "finds the config file in parent directories" do
13
+ Dir.mktmpdir("test") do |parent_dir|
14
+ nested_dir = File.join(parent_dir, "nested")
15
+ Dir.mkdir(nested_dir)
16
+
17
+ write_sample_config_to(parent_dir)
18
+
19
+ config = ET::Config.new(nested_dir)
20
+ expect(config.path).to eq(File.join(parent_dir, ".et"))
21
+ end
22
+ end
23
+
24
+ it "returns nil if no config file present" do
25
+ config = ET::Config.new(Dir.tmpdir)
26
+ expect(config.path).to eq(nil)
27
+ end
28
+ end
29
+
30
+ describe "#host" do
31
+ it "reads the host from the config" do
32
+ Dir.mktmpdir("test") do |tmpdir|
33
+ write_sample_config_to(tmpdir, "host" => "http://example.com")
34
+
35
+ config = ET::Config.new(tmpdir)
36
+ expect(config.host).to eq("http://example.com")
37
+ end
38
+ end
39
+
40
+ it "preprends http if scheme not provided" do
41
+ Dir.mktmpdir("test") do |tmpdir|
42
+ write_sample_config_to(tmpdir, "host" => "example.com")
43
+
44
+ config = ET::Config.new(tmpdir)
45
+ expect(config.host).to eq("http://example.com")
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,56 @@
1
+ Dir[File.join(File.dirname(__FILE__), "support/**/*.rb")].each do |f|
2
+ require f
3
+ end
4
+
5
+ RSpec.configure do |config|
6
+ # These two settings work together to allow you to limit a spec run
7
+ # to individual examples or groups you care about by tagging them with
8
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
9
+ # get run.
10
+ config.filter_run :focus
11
+ config.run_all_when_everything_filtered = true
12
+
13
+ # Run specs in random order to surface order dependencies. If you find an
14
+ # order dependency and want to debug it, you can fix the order by providing
15
+ # the seed, which is printed after each run.
16
+ # --seed 1234
17
+ config.order = :random
18
+
19
+ # Seed global randomization in this process using the `--seed` CLI option.
20
+ # Setting this allows you to use `--seed` to deterministically reproduce
21
+ # test failures related to randomization by passing the same `--seed` value
22
+ # as the one that triggered the failure.
23
+ Kernel.srand config.seed
24
+
25
+ # rspec-expectations config goes here. You can use an alternate
26
+ # assertion/expectation library such as wrong or the stdlib/minitest
27
+ # assertions if you prefer.
28
+ config.expect_with :rspec do |expectations|
29
+ # Enable only the newer, non-monkey-patching expect syntax.
30
+ # For more details, see:
31
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
32
+ expectations.syntax = :expect
33
+ end
34
+
35
+ # rspec-mocks config goes here. You can use an alternate test double
36
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
37
+ config.mock_with :rspec do |mocks|
38
+ # Enable only the newer, non-monkey-patching expect syntax.
39
+ # For more details, see:
40
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
41
+ mocks.syntax = :expect
42
+
43
+ # Prevents you from mocking or stubbing a method that does not exist on
44
+ # a real object. This is generally recommended.
45
+ mocks.verify_partial_doubles = true
46
+ end
47
+
48
+ config.include OutputCatcher
49
+ config.include SampleFiles
50
+ config.include PathHelper
51
+
52
+ config.before :each do
53
+ allow(RestClient).to receive(:get)
54
+ allow(RestClient).to receive(:post)
55
+ end
56
+ end
@@ -0,0 +1,17 @@
1
+ module OutputCatcher
2
+ def capture_output
3
+ original_stdout = $stdout
4
+ $stdout = fake_stdout = StringIO.new
5
+ original_stderr = $stderr
6
+ $stderr = fake_stderr = StringIO.new
7
+
8
+ begin
9
+ yield
10
+ ensure
11
+ $stdout = original_stdout
12
+ $stderr = original_stderr
13
+ end
14
+
15
+ [fake_stdout.string, fake_stderr.string]
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ require "pathname"
2
+
3
+ module PathHelper
4
+ def project_root
5
+ Pathname.new(File.join(File.dirname(__FILE__), "../../.."))
6
+ end
7
+ end
@@ -0,0 +1,28 @@
1
+ require "yaml"
2
+
3
+ module SampleFiles
4
+ def write_sample_config_to(dir, additional_settings = nil)
5
+ config = {
6
+ "username" => "bob",
7
+ "token" => "1234",
8
+ "host" => "http://localhost:3000"
9
+ }
10
+
11
+ if additional_settings
12
+ config = config.merge(additional_settings)
13
+ end
14
+
15
+ path = File.join(dir, ".et")
16
+ File.write(path, config.to_yaml)
17
+ end
18
+
19
+ def write_sample_challenge_to(working_dir, slug)
20
+ challenge_dir = File.join(working_dir, slug)
21
+ system("mkdir #{challenge_dir}")
22
+
23
+ readme_path = File.join(challenge_dir, "README.md")
24
+ File.write(readme_path, "# README")
25
+
26
+ challenge_dir
27
+ end
28
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: et
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Sheehan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-09 00:00:00.000000000 Z
11
+ date: 2014-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -16,14 +16,56 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '10.3'
19
+ version: '10'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '10.3'
26
+ version: '10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-mocks
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rest-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.7'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.7'
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: gli
29
71
  requirement: !ruby/object:Gem::Requirement
@@ -48,8 +90,10 @@ extensions: []
48
90
  extra_rdoc_files: []
49
91
  files:
50
92
  - ".gitignore"
93
+ - ".rspec"
51
94
  - ".ruby-gemset"
52
95
  - ".ruby-version"
96
+ - ".travis.yml"
53
97
  - Gemfile
54
98
  - Gemfile.lock
55
99
  - README.md
@@ -57,7 +101,23 @@ files:
57
101
  - bin/et
58
102
  - et.gemspec
59
103
  - lib/et.rb
104
+ - lib/et/api.rb
105
+ - lib/et/config.rb
106
+ - lib/et/formatter.rb
107
+ - lib/et/runner.rb
60
108
  - lib/et/version.rb
109
+ - spec/cli/get_challenge_spec.rb
110
+ - spec/cli/init_spec.rb
111
+ - spec/cli/list_challenges_spec.rb
112
+ - spec/cli/submit_challenge_spec.rb
113
+ - spec/data/challenges.json
114
+ - spec/data/some-challenge.tar.gz
115
+ - spec/lib/api_spec.rb
116
+ - spec/lib/config_spec.rb
117
+ - spec/spec_helper.rb
118
+ - spec/support/helpers/output_catcher.rb
119
+ - spec/support/helpers/path_helper.rb
120
+ - spec/support/helpers/sample_files.rb
61
121
  homepage: http://www.launchacademy.com
62
122
  licenses:
63
123
  - MIT