bloc 0.0.10 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/bloc CHANGED
@@ -4,11 +4,12 @@ require "rubygems"
4
4
  require "bloc"
5
5
 
6
6
  commands = {
7
- 'validate' => proc { Bloc::Command::Validate.run },
8
- 'create' => proc { Bloc::Command::Create.run },
9
- 'test' => proc { Bloc::Command::Test.run },
10
- 'patch' => proc { Bloc::Command::Patch.run }
7
+ 'validate' => proc { Bloc::Command::Validate.run },
8
+ 'test' => proc { Bloc::Command::Test.run },
9
+ 'authenticate' => proc { Bloc::Command::Authenticate.run },
10
+ 'tasks' => proc { Bloc::Command::Tasks.run }
11
11
  }
12
+
12
13
  if commands.keys.include?(ARGV.first.downcase)
13
14
  begin
14
15
  commands[ARGV.first.downcase].call
@@ -25,6 +26,7 @@ else
25
26
  create["Course name"] Create a course manifest with the specified name prefilled
26
27
  test [chapter-number] If chapter number is specified, run tests for that chapter. If not, run all tests in order.
27
28
  patch [chapter-number] Same as "test", except apply patches first (if present)
29
+ authenticate Authenticate by entering your Bloc email and password
28
30
  eos
29
31
  puts helpstring
30
32
  end
@@ -21,4 +21,6 @@ Gem::Specification.new do |s|
21
21
  s.add_development_dependency "ruby-debug19"
22
22
  s.add_runtime_dependency "json"
23
23
  s.add_runtime_dependency "colorize"
24
+ s.add_runtime_dependency "rest-client"
25
+ s.add_runtime_dependency "hashie"
24
26
  end
@@ -1,11 +1,14 @@
1
- $:.push File.expand_path("../lib", __FILE__)
1
+ $:.push File.expand_path("./lib")
2
2
 
3
3
  require "colorize"
4
4
  require "json"
5
+ require "hashie"
5
6
 
6
7
  require "bloc/version"
7
8
  require "bloc/command"
8
- require "bloc/models"
9
+ require "bloc/client"
10
+ require "bloc/manifest"
11
+ require "bloc/runner"
9
12
 
10
13
  module Bloc
11
14
  end
@@ -0,0 +1,29 @@
1
+ require "rest-client"
2
+
3
+ require "bloc/client/authenticate"
4
+ require "bloc/client/course"
5
+ require "bloc/client/enrollment"
6
+
7
+ module Bloc
8
+ class Client
9
+ include Authenticate
10
+
11
+ def self.client
12
+ @client ||= Bloc::Client.new
13
+ end
14
+
15
+ def self.credentials
16
+ @credentials ||= JSON.parse(File.read(Bloc::Command::Authenticate::CREDENTIALS_PATH))
17
+ end
18
+
19
+ def self.credentials=(credentials)
20
+ @credentials = credentials
21
+ end
22
+
23
+ private
24
+
25
+ def bloc_url(path)
26
+ "http://www.trybloc.com/api/v1#{path}"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ require "json"
2
+
3
+ module Bloc
4
+ class Client
5
+ module Authenticate
6
+ def authenticate(options)
7
+ raise "Must Provide an Email" unless options[:email]
8
+ raise "Must Provide a Password" unless options[:password]
9
+
10
+ response = RestClient.post(bloc_url("/api_keys"), {
11
+ :email => options[:email],
12
+ :password => options[:password]
13
+ })
14
+
15
+ credentials = JSON.parse(response.body)
16
+
17
+ Bloc::Client.credentials = credentials
18
+
19
+ credentials
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ module Bloc
2
+ class Client
3
+ class Course
4
+ def self.find(options={})
5
+ response = RestClient.get "http://www.trybloc.com/api/v1/courses/find", :params => options.merge(:api_key => Bloc::Client.credentials["api_key"])
6
+ self.new JSON.parse(response.body)
7
+ end
8
+
9
+ def initialize(attributes)
10
+ @attributes = attributes
11
+ end
12
+
13
+ def method_missing(method)
14
+ method = method.to_s
15
+
16
+ if @attributes[method]
17
+ return @attributes[method]
18
+ else
19
+ super(method)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,40 @@
1
+ module Bloc
2
+ class Client
3
+ class Enrollment
4
+ def self.create(attributes)
5
+ raise "Must Provide a Course Id" unless attributes[:course_id]
6
+ course_id = attributes.delete(:course_id)
7
+
8
+ response = RestClient.post("http://www.trybloc.com/api/v1/courses/#{course_id}/enrollments", {
9
+ :enrollment => attributes,
10
+ :api_key => Bloc::Client.credentials["api_key"]
11
+ })
12
+
13
+ self.new JSON.parse(response.body)
14
+ end
15
+
16
+ def initialize(attributes)
17
+ @attributes = attributes
18
+ end
19
+
20
+ def update(attributes)
21
+ response = RestClient.put("http://www.trybloc.com/api/v1/courses/#{course_id}/enrollments/#{id}", {
22
+ :enrollment => attributes,
23
+ :api_key => Bloc::Client.credentials["api_key"]
24
+ })
25
+
26
+ @attributes = JSON.parse(response.body)
27
+ end
28
+
29
+ def method_missing(method)
30
+ method = method.to_s
31
+
32
+ if @attributes[method]
33
+ return @attributes[method]
34
+ else
35
+ super(method)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,13 +1,10 @@
1
- require "bloc/command/validate.rb"
2
- require "bloc/command/create.rb"
3
- require "bloc/command/test.rb"
4
- require "bloc/command/patch.rb"
5
- require "bloc/models.rb"
6
- require "bloc/manifest.rb"
1
+ require "bloc/command/validate"
2
+ require "bloc/command/test"
3
+ require "bloc/command/tasks"
4
+ require "bloc/command/authenticate"
7
5
 
8
6
  module Bloc
9
7
  module Command
10
- end
11
-
12
8
 
9
+ end
13
10
  end
@@ -0,0 +1,43 @@
1
+ require "colorize"
2
+
3
+ module Bloc
4
+ module Command
5
+ class Authenticate
6
+ CREDENTIALS_PATH = File.join(ENV["HOME"], ".bloc", "credentials.json")
7
+ def self.run(*args)
8
+ login
9
+ end
10
+
11
+ def self.login
12
+ print "Email: "
13
+ email = $stdin.gets.chomp
14
+
15
+ print "Password: "
16
+ system "stty -echo"
17
+ password = $stdin.gets.chomp
18
+ system "stty echo"
19
+
20
+ print "\n"
21
+
22
+ client = Bloc::Client.new
23
+
24
+ begin
25
+ credentials = client.authenticate(:email => email, :password => password)
26
+ write_credentials(credentials)
27
+ puts "saved your credentials".green
28
+ rescue
29
+ puts "invalid email or password".red
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def self.write_credentials(credentials)
36
+ FileUtils.mkdir_p(File.dirname(CREDENTIALS_PATH))
37
+ FileUtils.touch(CREDENTIALS_PATH)
38
+
39
+ File.open(CREDENTIALS_PATH, "w+") { |file| file << credentials.to_json }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,37 @@
1
+ require "bloc/command/tasks/formatter"
2
+
3
+ module Bloc
4
+ module Command
5
+ class Tasks
6
+ def self.run
7
+ course = Client::Course.find(:scaffold_clone_url => git_remotes.first)
8
+ enrollment = Client::Enrollment.create(:course_id => course.id)
9
+
10
+ manifest = Manifest.parse
11
+
12
+ puts "Running Chapter #{enrollment.current_step} Tasks".green
13
+
14
+ results = Runner.run(manifest.chapters[enrollment.current_step - 1].command)
15
+
16
+ puts Formatter.format(results["tests"])
17
+
18
+ if results["tests"].all? {|result| result["passed"] }
19
+ puts "Chapter #{enrollment.current_step} Complete!"
20
+
21
+ if manifest.chapters.size == enrollment.current_step
22
+ enrollment.update(:completed => true)
23
+ else
24
+ enrollment.update(:current_step => enrollment.current_step + 1)
25
+ end
26
+ end
27
+ end
28
+
29
+ def self.git_remotes
30
+ `git remote -v`.split("\n").map do |remote|
31
+ name, url, method = remote.split(/\s/)
32
+ url
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,11 @@
1
+ module Bloc
2
+ module Command
3
+ class Tasks
4
+ module Formatter
5
+ def self.format(results)
6
+ results.to_yaml
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -3,11 +3,7 @@ module Bloc
3
3
  class Test
4
4
  def self.run(*args)
5
5
  manifest = Manifest.parse
6
- if ARGV[1].nil?
7
- manifest.run_tests
8
- else
9
- manifest.run_tests(:chapter => ARGV[1].to_i)
10
- end
6
+ results = Runner.run(manifest.chapters.first.command)
11
7
  end
12
8
  end
13
9
  end
@@ -47,7 +47,9 @@ module Bloc
47
47
  def self.check_patches(manifest)
48
48
  # TODO: ensure all chapters have patches
49
49
  manifest.chapters.each do |chapter|
50
- if chapter.patch_exists?
50
+ if chapter.patch.nil?
51
+
52
+ elsif File.exists? chapter.patch
51
53
  puts PATCH_EXISTS % chapter.patch
52
54
  else
53
55
  raise NO_SUCH_PATCH % chapter.patch
@@ -1,40 +1,12 @@
1
- require "bloc/hash_constructed.rb"
2
- require "bloc/temp_git.rb"
3
- require "bloc/models.rb"
4
-
5
1
  module Bloc
6
- class Manifest
2
+ class Manifest < Hashie::Mash
7
3
  MANIFEST_NOT_FOUND = "Unable to find Bloc Manifest in bloc/bloc_manifest.json".red
8
4
  MANIFEST_PATH = File.join("bloc", "bloc_manifest.json")
9
5
  INVALID_MANIFEST = "Invalid JSON in Bloc Manifest: #{MANIFEST_PATH}".red
10
6
  VALID_MANIFEST = "Valid Bloc Manifest".green
11
7
  NO_SUCH_CHAPTER = "No such chapter.".red
12
-
13
- include TempGit
14
-
15
- attr_accessor :course, :chapters, :deployable
16
-
17
- def initialize(options)
18
- @course = options["course"]
19
- @chapters = options["chapters"]
20
- end
21
-
22
- def write
23
- Dir.mkdir(File.dirname(MANIFEST_PATH))
24
- File.open(MANIFEST_PATH, "w") do |file|
25
- file.write(JSON.pretty_generate(to_h))
26
- end
27
- end
28
-
29
- def to_h
30
- hash = {}
31
- hash["course"] = @course.to_h
32
- hash["chapters"] = []
33
- @chapters.each do |chapter|
34
- hash["chapters"] << chapter.to_h
35
- end
36
- hash
37
- end
8
+ NO_COURSE = "Missing: course".red
9
+ NO_CHAPTERS = "Missing: chapters".red
38
10
 
39
11
  def self.parse
40
12
  raise MANIFEST_NOT_FOUND unless File.exists?(MANIFEST_PATH)
@@ -46,30 +18,16 @@ module Bloc
46
18
  rescue
47
19
  raise INVALID_MANIFEST
48
20
  end
49
- course = Bloc::Models::Course.new(manifest["course"])
50
- chapters = []
51
- manifest["chapters"].each do |chapter|
52
- chapters << Bloc::Models::Chapter.new(chapter)
53
- end
54
- Manifest.new({"course" => course, "chapters" => chapters})
21
+ Manifest.new(manifest)
55
22
  end
56
23
 
57
- def run_tests(options = {})
58
- defaults = {:chapter => nil, :apply_patch => false}
59
- options = defaults.merge(options)
60
-
61
- in_tmp_git do
62
- if options[:chapter].nil?
63
- @chapters.each do |chapter|
64
- chapter.apply_patch if options[:apply_patch]
65
- chapter.run_tests
66
- end
67
- else
68
- index = options[:chapter] - 1
69
- raise NO_SUCH_CHAPTER if @chapters[index].nil?
70
- @chapters[index].apply_patch if options[:apply_patch]
71
- @chapters[index].run_tests
72
- end
24
+ def write
25
+ begin
26
+ Dir.mkdir(File.dirname(MANIFEST_PATH))
27
+ rescue
28
+ end
29
+ File.open(MANIFEST_PATH, "w") do |file|
30
+ file.write(JSON.pretty_generate(to_hash))
73
31
  end
74
32
  end
75
33
  end
@@ -0,0 +1,10 @@
1
+ module Bloc
2
+ class Runner
3
+ def self.run(command)
4
+ `#{command}`
5
+ results = JSON.parse(File.read("results.json"))
6
+ File.delete("results.json")
7
+ results
8
+ end
9
+ end
10
+ end
@@ -1,3 +1,3 @@
1
1
  module Bloc
2
- VERSION = "0.0.10"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1 @@
1
+ bundle exec rspec spec
@@ -0,0 +1,43 @@
1
+ require "./spec/spec_helper"
2
+
3
+ describe Bloc::Client do
4
+ describe "#authenticate" do
5
+ let(:client) { Bloc::Client.new }
6
+ let(:email) { "bob@loblaw.com" }
7
+ let(:password) { "super_secret" }
8
+ let(:fake_response) { RestClient::Response.create(%Q({ "key" : "value" }), nil, nil) }
9
+
10
+ before do
11
+ RestClient.stub(:post).and_return(fake_response)
12
+ end
13
+
14
+ it "raises an error if no email is provided" do
15
+ lambda { client.authenticate(:password => password) }.should raise_error
16
+ end
17
+
18
+ it "raises an error if no password is provided" do
19
+ lambda { client.authenticate(:email => email) }.should raise_error
20
+ end
21
+
22
+ it "POSTs the email and password to the API keys endpoint" do
23
+ RestClient.should_receive(:post).with(anything, {
24
+ :email => email,
25
+ :password => password
26
+ }).and_return(fake_response)
27
+
28
+ client.authenticate(:password => password, :email => email)
29
+ end
30
+
31
+ it "adds the api key as a param to all RestClient calls" do
32
+ Bloc::Client.should_receive(:credentials=).with(JSON.parse(fake_response.body))
33
+ client.authenticate(:password => password, :email => email)
34
+ end
35
+
36
+ it "returns a parsed JSON hash" do
37
+ RestClient.should_receive(:post).and_return(fake_response)
38
+
39
+ result = client.authenticate(:password => password, :email => email)
40
+ result.should be_a(Hash)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,20 @@
1
+ require "./spec/spec_helper"
2
+
3
+ describe Bloc::Client::Course do
4
+ describe ".find" do
5
+ let(:query) { { :scaffold_code_url => "some-url" } }
6
+ let(:fake_response) { RestClient::Response.create(%Q({ "key" : "value" }), nil, nil) }
7
+
8
+ before { RestClient.stub(:get).and_return(fake_response) }
9
+
10
+ it "queries the Bloc API by the conditions passed in" do
11
+ RestClient.should_receive(:get).with(anything, :params => hash_including(query)).and_return(fake_response)
12
+ Bloc::Client::Course.find(query)
13
+ end
14
+
15
+ it "returns a new instance of itself" do
16
+ course = Bloc::Client::Course.find(query)
17
+ course.should be_a(Bloc::Client::Course)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,42 @@
1
+ require "./spec/spec_helper"
2
+
3
+ describe Bloc::Client::Enrollment do
4
+ let(:attributes) { { :id => 1, :current_step => 3, :completed => false , :course_id => 1} }
5
+ let(:fake_response) { RestClient::Response.create(attributes.to_json, nil, nil) }
6
+ before { RestClient.stub(:post).and_return(fake_response) }
7
+
8
+ describe ".create" do
9
+ it "raises an exception if no course_id is provided" do
10
+ lambda { Bloc::Client::Enrollment.create attributes.delete(:course_id) }.should raise_error
11
+ end
12
+
13
+ it "creates an Enrollment through the API" do
14
+ RestClient.should_receive(:post).with(anything, hash_including(:enrollment => attributes)).and_return(fake_response)
15
+ Bloc::Client::Enrollment.create(attributes)
16
+ end
17
+
18
+ it "returns an instance of itself" do
19
+ enrollment = Bloc::Client::Enrollment.create(attributes)
20
+ enrollment.should be_a(Bloc::Client::Enrollment)
21
+ end
22
+ end
23
+
24
+ describe "#update" do
25
+ let(:enrollment) { Bloc::Client::Enrollment.create(attributes) }
26
+ let(:update_attributes) { { "current_step" => "4" } }
27
+ let(:fake_update_response) { RestClient::Response.create(attributes.merge(:current_step => 4).to_json, nil, nil) }
28
+
29
+ before { RestClient.stub(:put).and_return(fake_update_response) }
30
+
31
+ it "updates the enrollment through the API" do
32
+ RestClient.should_receive(:put).with(anything, hash_including(:enrollment => update_attributes)).and_return(fake_response)
33
+ enrollment.update(update_attributes)
34
+ end
35
+
36
+ it "updates the enrollments attributes" do
37
+ enrollment.current_step.should == 3
38
+ enrollment.update(update_attributes)
39
+ enrollment.current_step.should == 4
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ require "./spec/spec_helper"
2
+ require "fakefs"
3
+
4
+ describe Bloc::Command::Authenticate do
5
+ before do
6
+ $stdout = StringIO.new
7
+ $stdin.stub(:gets).and_return(email, password)
8
+ Bloc::Client.any_instance.should_receive(:authenticate).with({
9
+ :email => email, :password => password
10
+ }).and_return(credentials)
11
+ end
12
+
13
+ after { $stdout = STDOUT }
14
+
15
+ let(:email) { "bob@loblaw.com" }
16
+ let(:password) { "super_secret" }
17
+ let(:credentials) { {"credentials" => true} }
18
+
19
+ describe ".login" do
20
+ it "asks for user credentials" do
21
+ STDIN.should_receive(:gets).and_return(email, password)
22
+ Bloc::Command::Authenticate.login
23
+ end
24
+
25
+ it "writes the credentials to a dotfile" do
26
+ Bloc::Command::Authenticate.login
27
+ JSON.parse(File.read(Bloc::Command::Authenticate::CREDENTIALS_PATH)).should == credentials
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,57 @@
1
+ require "./spec/spec_helper"
2
+ require "stringio"
3
+ require "fakefs"
4
+
5
+ module Bloc
6
+ describe Bloc::Command::Tasks do
7
+ describe ".run" do
8
+ let(:enrollment) { Client::Enrollment.new("id" => 1, "current_step" => 1, "completed" => false) }
9
+ let(:course) { Client::Course.new({"id" => "1", "slug" => "url-shortener" }) }
10
+ let(:git_remote) { "git://github.com/Bloc/URL-Shortener.git" }
11
+ let(:passed_results) { { "tests" => [{"passed" => true }, { "passed" => true }] } }
12
+ let(:failed_results) { { "tests" => [{"passed" => false }, { "passed" => true }] } }
13
+
14
+ before do
15
+ FileUtils.mkdir_p(File.dirname(Manifest::MANIFEST_PATH))
16
+ File.open(Manifest::MANIFEST_PATH, "w+") do |f|
17
+ f << %Q({"course": {"name" : "CatNap"}, "chapters": [{ "command": "whatever" }, {"command": "stuff"}]})
18
+ end
19
+ Command::Tasks.stub(:git_remotes).and_return([git_remote])
20
+ Client::Course.stub(:find).and_return(course)
21
+ Client::Enrollment.stub(:create).and_return(enrollment)
22
+ Runner.stub(:run).and_return(failed_results)
23
+
24
+ $stdout = StringIO.new
25
+ end
26
+
27
+ after { $stdout = STDOUT }
28
+
29
+ it "runs the tasks command for the current chapter" do
30
+ Runner.should_receive(:run).with("whatever")
31
+ Command::Tasks.run
32
+ end
33
+
34
+ context "if the tests pass" do
35
+ before do
36
+ Runner.stub(:run).and_return(passed_results)
37
+ Client::Course.stub(:find).with(:scaffold_clone_url => git_remote).and_return(course)
38
+ Client::Enrollment.stub(:create).with(:course_id => course.id).and_return(enrollment)
39
+ end
40
+
41
+ it "increments the current chapter of the enrollment" do
42
+ enrollment.should_receive(:update).with(:current_step => (enrollment.current_step + 1))
43
+ Command::Tasks.run
44
+ end
45
+
46
+ context "on the last chapter" do
47
+ let(:enrollment) { Client::Enrollment.new("id" => 1, "current_step" => 2, "completed" => false) }
48
+
49
+ it "sets the enrollment to 'completed' if there are no more chapters" do
50
+ enrollment.should_receive(:update).with(:completed => true)
51
+ Command::Tasks.run
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -5,25 +5,33 @@ require "stringio"
5
5
  module Bloc::Command
6
6
  describe Validate do
7
7
  it "raises an exception if the Bloc manifest can not be found" do
8
- lambda { Validate.run() }.should raise_error(Validate::MANIFEST_NOT_FOUND)
8
+ lambda { Validate.run() }.should raise_error(Bloc::Manifest::MANIFEST_NOT_FOUND)
9
9
  end
10
10
 
11
11
  it "raises an exception if the Bloc manifest has invalid JSON" do
12
12
  FileUtils.mkdir_p("bloc")
13
- File.open(Validate::MANIFEST_PATH, 'w+') {|f| f.write "<<invalid json>>" }
13
+ File.open(Bloc::Manifest::MANIFEST_PATH, 'w+') {|f| f.write "<<invalid json>>" }
14
14
 
15
- lambda { Validate.run() }.should raise_error(Validate::INVALID_MANIFEST)
15
+ lambda { Validate.run() }.should raise_error(Bloc::Manifest::INVALID_MANIFEST)
16
16
  end
17
17
 
18
18
  it "prints a success message if the manifest is valid" do
19
19
  FileUtils.mkdir_p("bloc")
20
- File.open(Validate::MANIFEST_PATH, 'w+') {|f| f.write %Q({"json": "true" }) }
20
+ File.open(Bloc::Manifest::MANIFEST_PATH, 'w+') {|f| f.write <<-eos
21
+ {
22
+ "course": {
23
+ "name": "Foobar",
24
+ "description": ""
25
+ },
26
+ "chapters": []
27
+ }
28
+ eos
29
+ }
21
30
 
22
31
  out = StringIO.new
23
32
  $stdout = out
24
33
  Validate.run()
25
34
  $stdout = STDOUT
26
- out.string.chomp.should == Validate::VALID_MANIFEST
27
35
  end
28
36
  end
29
37
  end
@@ -0,0 +1,39 @@
1
+ require './spec/spec_helper.rb'
2
+ require 'fakefs/safe'
3
+
4
+ module Bloc
5
+ describe Manifest do
6
+ it "writes valid JSON" do
7
+ FakeFS do
8
+ Bloc::Manifest.new(@options).write
9
+ lambda { JSON.parse File.read(Bloc::Manifest::MANIFEST_PATH) }.should_not raise_error
10
+ end
11
+ end
12
+
13
+ it "can parse its own output" do
14
+ FakeFS do
15
+ Bloc::Manifest.new(@options).write
16
+ lambda { Bloc::Manifest.parse }.should_not raise_error
17
+ end
18
+ end
19
+
20
+ it "parses a valid manifest" do
21
+ valid_manifests = Dir['spec/valid_manifests/*'].map {|path| File.read(path)}
22
+ valid_manifests.each do |manifest|
23
+ FakeFS do
24
+ FileUtils.mkdir_p 'bloc'
25
+ File.open(Bloc::Manifest::MANIFEST_PATH, "w") do |file|
26
+ file.write manifest
27
+ end
28
+ STDOUT.should_receive(:puts).and_return(Bloc::Manifest::VALID_MANIFEST)
29
+ lambda { Bloc::Manifest.parse }.should_not raise_error
30
+ end
31
+ end
32
+ end
33
+
34
+ it "to_hash produces a valid ruby hash" do
35
+ manifest = Bloc::Manifest.new(@options)
36
+ manifest.to_hash.class.should be(Hash)
37
+ end
38
+ end
39
+ end
@@ -1,3 +1,21 @@
1
1
  $:.push File.expand_path("../lib", __FILE__)
2
2
 
3
3
  require "bloc"
4
+
5
+ module Helpers
6
+ # Replace standard input with faked one StringIO.
7
+ def fake_stdin(text)
8
+ begin
9
+ $stdin = StringIO.new
10
+ $stdin.puts(text)
11
+ $stdin.rewind
12
+ yield
13
+ ensure
14
+ $stdin = STDIN
15
+ end
16
+ end
17
+ end
18
+
19
+ RSpec.configure do |conf|
20
+ conf.include(Helpers)
21
+ end
@@ -0,0 +1,7 @@
1
+ {
2
+ "course": {
3
+ "name": "Foobar",
4
+ "description": ""
5
+ },
6
+ "chapters": []
7
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bloc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-03-06 00:00:00.000000000Z
13
+ date: 2012-03-10 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
17
- requirement: &70339116316320 !ruby/object:Gem::Requirement
17
+ requirement: &70122279915300 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *70339116316320
25
+ version_requirements: *70122279915300
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: fakefs
28
- requirement: &70339116315900 !ruby/object:Gem::Requirement
28
+ requirement: &70122279914880 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *70339116315900
36
+ version_requirements: *70122279914880
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: ruby-debug19
39
- requirement: &70339116315480 !ruby/object:Gem::Requirement
39
+ requirement: &70122279914460 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *70339116315480
47
+ version_requirements: *70122279914460
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: json
50
- requirement: &70339116315060 !ruby/object:Gem::Requirement
50
+ requirement: &70122279914040 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: '0'
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *70339116315060
58
+ version_requirements: *70122279914040
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: colorize
61
- requirement: &70339116314640 !ruby/object:Gem::Requirement
61
+ requirement: &70122279913620 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,7 +66,29 @@ dependencies:
66
66
  version: '0'
67
67
  type: :runtime
68
68
  prerelease: false
69
- version_requirements: *70339116314640
69
+ version_requirements: *70122279913620
70
+ - !ruby/object:Gem::Dependency
71
+ name: rest-client
72
+ requirement: &70122279913200 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: *70122279913200
81
+ - !ruby/object:Gem::Dependency
82
+ name: hashie
83
+ requirement: &70122279912780 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: *70122279912780
70
92
  description: A command-line tool for Bloc
71
93
  email:
72
94
  - roshan.choxi@gmail.com
@@ -85,19 +107,31 @@ files:
85
107
  - bin/bloc
86
108
  - bloc.gemspec
87
109
  - lib/bloc.rb
110
+ - lib/bloc/client.rb
111
+ - lib/bloc/client/authenticate.rb
112
+ - lib/bloc/client/course.rb
113
+ - lib/bloc/client/enrollment.rb
88
114
  - lib/bloc/command.rb
89
- - lib/bloc/command/create.rb
90
- - lib/bloc/command/patch.rb
115
+ - lib/bloc/command/authenticate.rb
116
+ - lib/bloc/command/tasks.rb
117
+ - lib/bloc/command/tasks/formatter.rb
91
118
  - lib/bloc/command/test.rb
92
119
  - lib/bloc/command/validate.rb
93
- - lib/bloc/hash_constructed.rb
94
120
  - lib/bloc/manifest.rb
95
- - lib/bloc/models.rb
121
+ - lib/bloc/runner.rb
96
122
  - lib/bloc/temp_git.rb
97
123
  - lib/bloc/to_hash.rb
98
124
  - lib/bloc/version.rb
125
+ - script/test
126
+ - spec/client/authenticate_spec.rb
127
+ - spec/client/course_spec.rb
128
+ - spec/client/enrollment_spec.rb
129
+ - spec/command/authenticate_spec.rb
130
+ - spec/command/tasks_spec.rb
99
131
  - spec/command/validate_spec.rb
132
+ - spec/manifest_spec.rb
100
133
  - spec/spec_helper.rb
134
+ - spec/valid_manifests/1.json
101
135
  homepage:
102
136
  licenses: []
103
137
  post_install_message:
@@ -123,5 +157,12 @@ signing_key:
123
157
  specification_version: 3
124
158
  summary: A CLI For Bloc
125
159
  test_files:
160
+ - spec/client/authenticate_spec.rb
161
+ - spec/client/course_spec.rb
162
+ - spec/client/enrollment_spec.rb
163
+ - spec/command/authenticate_spec.rb
164
+ - spec/command/tasks_spec.rb
126
165
  - spec/command/validate_spec.rb
166
+ - spec/manifest_spec.rb
127
167
  - spec/spec_helper.rb
168
+ - spec/valid_manifests/1.json
@@ -1,21 +0,0 @@
1
- module Bloc
2
- module Command
3
- class Create
4
- def self.run(*args)
5
- name = ARGV[1]
6
- if name.nil?
7
- raise "Please specify a name.".red
8
- end
9
- course = Bloc::Models::Course.new(:name => name, :description => "")
10
- chapters = []
11
- manifest = Bloc::Manifest.new({"course" => course, "chapters" => chapters})
12
- begin
13
- manifest.write
14
- puts "Wrote manifest.".green
15
- rescue Exception => e
16
- raise e.to_s.red
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,14 +0,0 @@
1
- module Bloc
2
- module Command
3
- class Patch
4
- def self.run(*args)
5
- manifest = Manifest.parse
6
- if ARGV[1].nil?
7
- manifest.run_tests(:apply_patch => true)
8
- else
9
- manifest.run_tests(:chapter => ARGV[1].to_i, :apply_patch => true)
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,5 +0,0 @@
1
- module HashConstructed
2
- def initialize(h)
3
- h.each {|k,v| send("#{k}=",v)}
4
- end
5
- end
@@ -1,55 +0,0 @@
1
- require 'bloc/hash_constructed.rb'
2
- require 'bloc/to_hash.rb'
3
-
4
- module Bloc
5
- module Models
6
- class Course
7
- include HashConstructed
8
- include ToHash
9
- attr_accessor :name, :description, :default_file
10
-
11
-
12
- end
13
-
14
- class Chapter
15
- include HashConstructed
16
- include ToHash
17
- attr_accessor :name, :command, :markdown, :default_file, :patch, :cursor_row, :cursor_column
18
-
19
- TEST_FAILURE = "Failed test:\n%s".red
20
- TEST_PASSED = "Passed: %s".green
21
-
22
- def run_tests
23
- unless @patch.nil?
24
- results = test
25
- results["tests"].each do |test_result|
26
- if test_result["passed"]
27
- puts TEST_PASSED % test_result["name"]
28
- else
29
- raise TEST_FAILURE % test_result["name"]
30
- end
31
- end
32
- end
33
- end
34
-
35
- def patch_exists?
36
- File.exists?("bloc/#{@patch}")
37
- end
38
-
39
- def apply_patch
40
- unless @patch.nil?
41
- `patch < bloc/#{@patch}`
42
- end
43
- end
44
-
45
- private
46
-
47
- def test
48
- `#{@command}`
49
- results = JSON.parse(File.read("results.json"))
50
- File.delete("results.json")
51
- results
52
- end
53
- end
54
- end
55
- end