jobim 0.5.0 → 0.6.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: fac1f285dd7910f146c63dcad408ce2351dbe456
4
- data.tar.gz: 32036107d6d25b517648aa1f2a07b539f1e77b45
3
+ metadata.gz: bfa8178336f50e709e059a336e5c6591369dec55
4
+ data.tar.gz: 3b493302ce532f7253b9cb479928c55acf171675
5
5
  SHA512:
6
- metadata.gz: 8356e9b1d0ae90852a69e1cd3debc4178d63da25acbecf828845fe1d0be7989fcad06ecdd85979752af833b843f42c4a9af644ba7bd7c622eca72810441eb68b
7
- data.tar.gz: 8cc2ddb3c4dd8cb1f2228918360cfb5e29967d1812b2fd64f83fdda977961edb5d974ce7a2ef328a049ce892ccdbf4f9bbc043ea3ac62612c5a49175f44bb1b0
6
+ metadata.gz: b7088b4464eb2a73c88a1d36273426b00bacdedc2e62d41861e67cff013dbe7fe6834cfd9e6fe82561097d3a5c4e9ec387db003f0133f0bf9c83aaf4f4f626b4
7
+ data.tar.gz: 19e8af1b48aa7ef99ffbeb9eae774a31e772a8d471628c102eb9cf18f9c7ac8533492e84a400886393384b0436bb8c0f7f80817c9f5109684925ca5807c89173
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,2 @@
1
+ MethodLength:
2
+ Enabled: false
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.0.0
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Jobim
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/jobim.png)](http://badge.fury.io/rb/jobim)
4
+ [![Build Status](https://secure.travis-ci.org/zellio/jobim.png?branch=master)](http://travis-ci.org/zellio/jobim)
4
5
  [![Dependency Status](https://gemnasium.com/zellio/jobim.png)](https://gemnasium.com/zellio/jobim)
5
6
  [![Code Climate](https://codeclimate.com/github/zellio/jobim.png)](https://codeclimate.com/github/zellio/jobim)
6
7
 
@@ -8,7 +9,8 @@
8
9
  for rapid website design and development without the hassle and security risk
9
10
  of a full web-server installation. `jobim` leverages
10
11
  [Thin](//github.com/macournoyer/thin/) and exposes a limited subset of the
11
- `thin` executable command flags for your convenience.
12
+ `thin` executable command flags for your convenience in addition to a set of
13
+ flags for its own configuration.
12
14
 
13
15
  ## Installation
14
16
 
@@ -26,8 +28,9 @@ Usage: jobim [OPTION]... [DIRECTORY]
26
28
 
27
29
  Specific options:
28
30
  -a, --address HOST bind to HOST address (default: 0.0.0.0)
31
+ -c, --[no-]config [PATH] Disable config loading or specify path to load from
29
32
  -d, --daemonize Run as a daemon process
30
- -p, --port PORT use PORT (default: 5634)
33
+ -p, --port PORT use PORT (default: 3000)
31
34
  -P, --prefix PATH Mount the app under PATH
32
35
  -q, --quiet Silence all logging
33
36
 
@@ -40,14 +43,36 @@ Report bugs to: <https://github.com/zellio/jobim/issues>
40
43
  ```
41
44
 
42
45
  `jobim` is run like `thin` but does not require a configuration script. By
43
- default `jobim` will bind to `0.0.0.0:5634` and serve the current working
46
+ default `jobim` will bind to `0.0.0.0:3000` and serve the current working
44
47
  directory.
45
48
 
46
49
  ``` shell
47
50
  jobim path/to/webroot
48
51
  ```
49
52
 
50
- The site can be viewed at `http://localhost:5634` via a normal web browser.
53
+ The site can be viewed at `http://localhost:3000` via a normal web browser.
54
+
55
+ ### Configuration Files
56
+
57
+ `jobim` also allows for the use of a configuration file `.jobim.yml`. This can
58
+ be used to set sane defaults for the `jobim` program to use in every
59
+ execution. `jobim` will search up from the current working directory until it
60
+ reaches `/` in the pursuit of configuration files, with the configuration
61
+ options cascading from root to the current working directory. Options passed
62
+ as command flags to `jobim` always win.
63
+
64
+ ```
65
+ # Example config file
66
+ ---
67
+ :dir: /web_root
68
+ :prefix: /foo
69
+ :port: 300
70
+ ```
71
+
72
+ All options must be specified as key value pairs in a depth one hash. The keys
73
+ must be ruby symbols (For historical reasons capitalization of these keys is
74
+ irrelevant but they should be all downcase). The valid options are
75
+ `:daemonize`, `:dir`, `:host`, `:port`, `:prefix`, `:quiet`, and `:conf_dir`.
51
76
 
52
77
  ## Contributing
53
78
 
@@ -59,4 +84,5 @@ The site can be viewed at `http://localhost:5634` via a normal web browser.
59
84
 
60
85
  ## Copyright
61
86
 
62
- Copyright (c) 2013 Zachary Elliott. See [LICENSE](/LICENSE) for further details.
87
+ Copyright (c) 2013-2014 Zachary Elliott. See [LICENSE](/LICENSE) for further
88
+ details.
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/jobim CHANGED
@@ -3,8 +3,8 @@
3
3
  require 'pathname'
4
4
  file = Pathname.new(__FILE__).realpath
5
5
 
6
- $:.unshift File.expand_path("../../lib", file)
6
+ $LOAD_PATH.unshift File.expand_path('../../lib', file)
7
7
 
8
8
  require 'jobim'
9
9
 
10
- Jobim::CLI.run!(*ARGV)
10
+ Jobim::Application.run(*ARGV)
@@ -25,9 +25,13 @@ Gem::Specification.new do |spec|
25
25
 
26
26
  spec.add_development_dependency "bundler", "~> 1.3"
27
27
  spec.add_development_dependency "rake", "~> 10.1"
28
+ spec.add_development_dependency "rspec"
29
+ spec.add_development_dependency "simplecov"
28
30
  spec.add_development_dependency 'yard', "~> 0.8"
29
31
  spec.add_development_dependency 'redcarpet', "~> 3.0"
30
32
  spec.add_development_dependency 'github-markup', "~> 0.7"
33
+ spec.add_development_dependency 'fakefs', '~> 0.5'
34
+ spec.add_development_dependency 'rack-test'
31
35
 
32
36
  spec.add_runtime_dependency "thin", "~> 1.5"
33
37
  spec.add_runtime_dependency "rack-rewrite", "~> 1.2"
@@ -1,9 +1,8 @@
1
-
1
+ # Jobim application container
2
2
  module Jobim
3
-
4
- require "jobim/version"
5
- require "jobim/settings"
6
- require "jobim/server"
7
- require "jobim/cli"
8
-
3
+ require 'jobim/version'
4
+ require 'jobim/settings'
5
+ require 'jobim/server'
6
+ require 'jobim/cli'
7
+ require 'jobim/application'
9
8
  end
@@ -0,0 +1,26 @@
1
+ # Application container for initialization and execution of Jobim's
2
+ # resources. Generates a new `Jobim::CLI` instance, and then passes it off to
3
+ # a `Jobim::Server`. Good chance this will change in the future.
4
+ module Jobim::Application
5
+ # Initializes and runs the CLI and Server
6
+ #
7
+ # @param args [Array<String>] list of args passed to the application
8
+ # @param block [Block] dummy block object (Not used)
9
+ def self.run(*args, &block)
10
+ cli = Jobim::CLI.new
11
+ begin
12
+ cli.parse(args)
13
+
14
+ exit if cli.exit
15
+
16
+ Jobim::Server.start!(cli.settings)
17
+ rescue OptionParser::InvalidOption => invalid_option
18
+ $stderr.puts ">>> Error: #{invalid_option}"
19
+ $stderr.puts cli.help
20
+
21
+ rescue RuntimeError => runtime_error
22
+ $stderr.puts '>>> Failed to start server'
23
+ $stderr.puts ">> #{runtime_error}"
24
+ end
25
+ end
26
+ end
@@ -1,91 +1,108 @@
1
1
  require 'optparse'
2
2
 
3
+ # Command line interface for the Jobim application. Utilizes optparse to
4
+ # manage user arguments and populates a `Jobim::Settings` object.
3
5
  class Jobim::CLI
6
+ attr_reader :parser, :settings, :exit, :options
4
7
 
5
- attr_reader :parser, :settings
6
-
7
- def self.run!(*args, &opts)
8
- cli = Jobim::CLI.new
9
- begin
10
- cli.parse(args)
11
-
12
- exit if cli.options.nil?
13
-
14
- Jobim::Server.start cli.options
15
-
16
- rescue OptionParser::InvalidOption => invalid_option
17
- puts ">>> Error: #{invalid_option}"
18
- puts cli.help
19
-
20
- rescue RuntimeError => runtime_error
21
- puts ">>> Failed to start server"
22
- puts ">> #{runtime_error}"
23
- end
24
- end
25
-
8
+ # Memoized, lazy accessor for the settings object.
9
+ #
10
+ # @return [Jobim::Settings]
26
11
  def settings
27
- @settings ||= Jobim::Settings.new
12
+ @settings ||= Jobim::Settings.new(options)
28
13
  end
29
14
 
15
+ # Memoized, lazy accessor for the options hash.
16
+ #
17
+ # @return [Hash] options generated from #parse
30
18
  def options
31
- settings.options
19
+ @options ||= {
20
+ daemonize: false,
21
+ dir: Dir.pwd,
22
+ host: '0.0.0.0',
23
+ port: 3000,
24
+ prefix: '/',
25
+ quiet: false,
26
+ conf_dir: Dir.pwd
27
+ }
32
28
  end
33
29
 
30
+ # Memoized accessor for the `OptionParser` object. It is generated only when
31
+ # called upon. See the readme for information about the command flags.
32
+ #
33
+ # @return [OptionParser]
34
34
  def parser
35
35
  @parser ||= OptionParser.new do |o|
36
- o.banner = "Usage: jobim [OPTION]... [DIRECTORY]"
36
+ o.banner = 'Usage: jobim [OPTION]... [DIRECTORY]'
37
+
38
+ o.separator ''
39
+ o.separator 'Specific options:'
37
40
 
38
- o.separator ""
39
- o.separator "Specific options:"
41
+ o.on('-a', '--address HOST',
42
+ 'bind to HOST address (default: 0.0.0.0)') do |host|
43
+ options[:host] = host
44
+ end
40
45
 
41
- o.on("-a", "--address HOST",
42
- "bind to HOST address (default: 0.0.0.0)") do |host|
43
- options[:Host] = host
46
+ o.on('-c', '--[no-]config [PATH]',
47
+ 'Disable config loading or specify path to load from') do |v|
48
+ options[:conf_dir] = v.nil? ? Dir.pwd : v
44
49
  end
45
50
 
46
- o.on "-d", "--daemonize", "Run as a daemon process" do
47
- options[:Daemonize] = true
51
+ o.on '-d', '--daemonize', 'Run as a daemon process' do
52
+ options[:daemonize] = true
48
53
  end
49
54
 
50
- o.on "-p", "--port PORT", "use PORT (default: 5634)" do |port|
51
- options[:Port] = port
55
+ o.on('-p', '--port PORT', OptionParser::DecimalInteger,
56
+ 'use PORT (default: 3000)') do |port|
57
+ fail OptionParser::InvalidArgument if port == 0
58
+ options[:port] = port
52
59
  end
53
60
 
54
- o.on "-P", "--prefix PATH", "Mount the app under PATH" do |path|
55
- options[:Prefix] = path
61
+ o.on '-P', '--prefix PATH', 'Mount the app under PATH' do |path|
62
+ options[:prefix] = path
56
63
  end
57
64
 
58
- o.on "-q", "--quiet", "Silence all logging" do
59
- options[:Quiet] = true
65
+ o.on '-q', '--quiet', 'Silence all logging' do
66
+ options[:quiet] = true
60
67
  end
61
68
 
62
- o.separator ""
63
- o.separator "General options:"
69
+ o.separator ''
70
+ o.separator 'General options:'
64
71
 
65
- o.on "-h", "--help", "Display this help message." do
72
+ o.on '-h', '--help', 'Display this help message.' do
73
+ @exit = true
66
74
  puts help
67
- exit
68
75
  end
69
- o.on "--version", "Display the version number" do
70
- options[:version] = Jobim::VERSION
71
- puts options[:version]
72
- exit
76
+ o.on '--version', 'Display the version number' do
77
+ @exit = true
78
+ puts "#{Jobim::VERSION}\n"
73
79
  end
74
80
 
75
- o.separator ""
76
- o.separator "Jobim home page: <https://github.com/zellio/jobim/>"
77
- o.separator "Report bugs to: <https://github.com/zellio/jobim/issues>"
78
- o.separator ""
81
+ o.separator ''
82
+ o.separator 'Jobim home page: <https://github.com/zellio/jobim/>'
83
+ o.separator 'Report bugs to: <https://github.com/zellio/jobim/issues>'
84
+ o.separator ''
79
85
  end
80
86
  end
81
87
 
88
+ # Runs the parse method of the value returned by the `#parser` method. This
89
+ # is done in a manner destructive to the passed args `Array`. If there is a
90
+ # trailing value after parsing is completed it is treated as the `:dir`
91
+ # option.
92
+ #
93
+ # @param [Array<String>] args to be paresed
94
+ # @return [NilClass] sentitinal nil value
82
95
  def parse(args)
83
96
  parser.parse!(args)
84
- options[:Dir] = File.expand_path(args[0]) if args.length == 1
97
+ options[:dir] = File.expand_path(args[0]) if args.length == 1
98
+
99
+ nil
85
100
  end
86
101
 
102
+ # Help documentation of the program.
103
+ #
104
+ # @return [String]
87
105
  def help
88
106
  parser.to_s
89
107
  end
90
-
91
108
  end
@@ -1,21 +1,94 @@
1
+ require 'thin'
1
2
  require 'rack'
2
3
  require 'rack/rewrite'
3
4
 
4
- module Jobim::Server
5
+ # HTTP Server container. Contains the Rack application definition and routing
6
+ # tables. Class explicitly leverages `::Thin::Server` to create the HTTP
7
+ # server, this should possibly be changed.
8
+ class Jobim::Server
9
+ # Utitly wrapper to create and start a new `Jobim::Server` instnace.
10
+ #
11
+ # @param opts [Hash] option hash for server configuration
12
+ # @return [Jobim::Server] new running server instance
13
+ def self.start!(opts)
14
+ Jobim::Server.new(opts).start
15
+ end
16
+
17
+ attr_accessor :app, :settings, :server
18
+
19
+ def initialize(settings, &block)
20
+ @settings = settings
21
+
22
+ yield self if block_given?
23
+ end
24
+
25
+ # Memoized accessor for the server Rack application.
26
+ #
27
+ # NB. This has been split into a memoized called to `#build_app` becuase of
28
+ # the way the `Rack::Builder` class handles scope in the context of
29
+ # `instance_eval` instead of `yield`.
30
+ #
31
+ # @return [Rack::Builder]
32
+ def app
33
+ @app ||= build_app(settings)
34
+ end
35
+
36
+ # Memoized accessor for the internal server instance.
37
+ #
38
+ # This is currently explicitly a `::Thin::Server`, possibly should change
39
+ # into a more generic form.
40
+ #
41
+ # @return [Thin::Server]
42
+ def server
43
+ if @server.nil?
44
+ thin_app = Rack::Chunked.new(Rack::ContentLength.new(app))
45
+ server = ::Thin::Server.new(settings.host, settings.port, thin_app)
5
46
 
6
- def self.start(opts)
7
- app = Rack::Builder.new do
47
+ if settings.daemonize
48
+ server.pid_file = 'jobim.pid'
49
+ server.log_file = 'jobim.log'
50
+ end
51
+
52
+ @server = server
53
+ end
54
+
55
+ @server
56
+ end
57
+
58
+ # Pass through delegation to the internal server object's start method.
59
+ # Handles daemonizing the server before starting it if nessesary.
60
+ def start
61
+ Thin::Logging.silent = settings.quiet
62
+
63
+ puts ">>> Serving #{settings.dir}"
64
+
65
+ server.daemonize if settings.daemonize
66
+ server.start
67
+ end
68
+
69
+ private
70
+
71
+ # Method to create a new instance of the Rack application. The creation
72
+ # functionality has been broken out into its own method for scope
73
+ # reason. `Rack::Builder` uses instance_eval which makes generating
74
+ # applicaitons a pain.
75
+ #
76
+ # @param opts [Hash] option hash for server configuration
77
+ # @return [Rack::Builder] Rack::Builder instance for application routing
78
+ def build_app(opts)
79
+ Rack::Builder.new do
8
80
  use Rack::Rewrite do
9
- rewrite(%r{(.*)}, lambda do |match, env|
10
- request_path = env["REQUEST_PATH"]
81
+ rewrite(/(.*)/, lambda do |match, env|
82
+ request_path = env['PATH_INFO']
11
83
 
12
- return match[1] if opts[:Prefix].length > request_path.length
84
+ return match[1] if opts.prefix.length > request_path.length
13
85
 
14
- local_path = File.join(opts[:Dir], request_path[opts[:Prefix].length..-1])
86
+ local_path = File.join(opts.dir,
87
+ request_path[opts.prefix.length..-1])
15
88
 
16
- if File.directory?(local_path) and
17
- File.exists?(File.join(local_path, "index.html"))
18
- File.join(request_path, "index.html")
89
+ if File.directory?(local_path) &&
90
+ File.exists?(File.join(local_path, 'index.html'))
91
+ File.join(request_path, 'index.html')
19
92
  else
20
93
  match[1]
21
94
  end
@@ -24,22 +97,9 @@ module Jobim::Server
24
97
 
25
98
  use Rack::CommonLogger, STDOUT
26
99
 
27
- map opts[:Prefix] do
28
- run Rack::Directory.new(opts[:Dir])
29
- end
30
- end
31
-
32
- puts ">>> Serving #{opts[:Dir]}"
33
-
34
- Rack::Handler::Thin.run(app, opts) do |server|
35
- if opts[:Daemonize]
36
- server.pid_file = 'jobim.pid'
37
- server.log_file = 'jobim.log'
38
- server.daemonize
100
+ map opts.prefix do
101
+ run Rack::Directory.new(opts.dir)
39
102
  end
40
-
41
- Thin::Logging.silent = opts[:Quiet]
42
103
  end
43
104
  end
44
-
45
105
  end
@@ -1,56 +1,70 @@
1
1
  require 'yaml'
2
2
 
3
+ # Manages applications settings and configuration. Handles sane defaults and
4
+ # the loading / merging of configuration from files.
3
5
  class Jobim::Settings
6
+ VALID_KEYS = [:daemonize, :dir, :host, :port, :prefix, :quiet, :conf_dir]
4
7
 
5
- attr_reader :options
8
+ attr_accessor *VALID_KEYS
6
9
 
7
- def initialize
8
- load
10
+ def initialize(defaults = {})
11
+ update(defaults)
12
+ load if conf_dir
9
13
  end
10
14
 
11
- def options
12
- @options ||= {
13
- :Daemonize => false,
14
- :Dir => Dir.pwd,
15
- :Host => '0.0.0.0',
16
- :Port => 5634,
17
- :Prefix => '/',
18
- :Quiet => false
19
- }
15
+ def update(opts)
16
+ VALID_KEYS.each { |key| send("#{key}=", opts[key]) unless opts[key].nil? }
17
+ self
20
18
  end
21
19
 
20
+ # Loads a configuration file in the yaml format into the settings object.
21
+ #
22
+ # @param [String] file path to the configuration file
23
+ # @return [Jobim::Settings] self
22
24
  def load_file(file)
23
- opts = YAML.load_file(file)
25
+ opts = YAML.load_file(file) || {}
24
26
  opts.keys.each do |key|
25
- opts[(key.to_s.capitalize.to_sym rescue key) || key] = opts.delete(key)
27
+ begin
28
+ opts[key.to_s.downcase.to_sym || key] = opts.delete(key)
29
+ rescue
30
+ opts[key] = opts.delete(key)
31
+ end
26
32
  end
27
33
 
28
- if opts[:Dir]
29
- unless Pathname.new(opts[:Dir]).absolute?
30
- opts[:Dir] = File.expand_path("../#{opts[:Dir]}", file)
34
+ if opts[:dir]
35
+ unless Pathname.new(opts[:dir]).absolute?
36
+ opts[:dir] = File.expand_path("../#{opts[:dir]}", file)
31
37
  end
32
38
  end
33
39
 
34
- options.merge!(opts)
40
+ update(opts)
35
41
  end
36
42
 
37
- def load
38
- dir = Pathname('.').realpath
43
+ # Loads all configuration files from provided directory up. Defaults to the
44
+ # current working directory of the program.
45
+ #
46
+ # @param [String] directory to load files from (defaults to Dir.pwd)
47
+ # @return [Jobim::Settings] self
48
+ def load(dir = conf_dir)
49
+ dir = Pathname(File.expand_path(dir))
39
50
  files = []
40
51
 
41
52
  loop do
42
- file = File.expand_path('.jobim.yaml', dir)
43
-
44
- files.unshift(file) if File.exists? file
53
+ file = File.expand_path('.jobim.yml', dir)
54
+ if File.exists? file
55
+ files.unshift(file)
56
+ else
57
+ file = File.expand_path('.jobim.yaml', dir)
58
+ files.unshift(file) if File.exists? file
59
+ end
45
60
 
46
61
  break if dir.root?
47
62
 
48
63
  dir = dir.parent
49
64
  end
50
65
 
51
- files.each {|file| self.load_file(file)}
66
+ files.each { |file| load_file(file) }
52
67
 
53
- options
68
+ self
54
69
  end
55
-
56
70
  end
@@ -1,3 +1,4 @@
1
1
  module Jobim
2
- VERSION = "0.5.0"
2
+ # Applcation version number
3
+ VERSION = '0.6.0'
3
4
  end
@@ -0,0 +1 @@
1
+ ---
@@ -0,0 +1,2 @@
1
+ ---
2
+ :prefix: '/jobim'
@@ -0,0 +1,3 @@
1
+ ---
2
+ :daemonize: true
3
+ :dir: '/pub'
@@ -0,0 +1,4 @@
1
+ ---
2
+ :port: 1234
3
+ :dir: 'public_html'
4
+ :prefix: '/web_root'
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jobim::Application, fakefs: true do
4
+
5
+ describe '::run' do
6
+ before(:each) do
7
+ Jobim::Server.stub(:start!)
8
+ $stdout.stub(:write)
9
+ $stderr.stub(:write)
10
+ end
11
+
12
+ it 'exits on --help command flag' do
13
+ expect { Jobim::Application.run('--help') }.to raise_error SystemExit
14
+ end
15
+
16
+ it 'exits on --version command flags' do
17
+ expect { Jobim::Application.run('--version') }.to raise_error SystemExit
18
+ end
19
+
20
+ it 'starts the server' do
21
+ expect(Jobim::Server).to receive(:start!)
22
+ Jobim::Application.run
23
+ end
24
+
25
+ it 'catches InvalidOption and reports to stderr' do
26
+ expect($stderr).to receive(:write)
27
+ Jobim::Application.run('--foo')
28
+ end
29
+
30
+ it 'catches RuntimeError and reports to stderr' do
31
+ expect($stderr).to receive(:write)
32
+ Jobim::Server.unstub(:start!)
33
+ Jobim::Application.run('--port', '1')
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,130 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jobim::CLI, fakefs: true do
4
+
5
+ let(:cli) { Jobim::CLI.new }
6
+
7
+ describe 'options' do
8
+ it 'defaults conf_dir to Dir.pwd' do
9
+ expect(cli.options[:conf_dir]).to eql Dir.pwd
10
+ end
11
+
12
+ it 'defaults daemonize to false' do
13
+ expect(cli.options[:daemonize]).to be_false
14
+ end
15
+
16
+ it 'defaults dir to current working directory' do
17
+ expect(cli.options[:dir]).to eql Dir.pwd
18
+ end
19
+
20
+ it 'defaults host to 0.0.0.0' do
21
+ expect(cli.options[:host]).to eql '0.0.0.0'
22
+ end
23
+
24
+ it 'defaults port to 3000' do
25
+ expect(cli.options[:port]).to eql 3000
26
+ end
27
+
28
+ it 'defaults prefix to /' do
29
+ expect(cli.options[:prefix]).to eql '/'
30
+ end
31
+
32
+ it 'defaults quiet to false' do
33
+ expect(cli.options[:quiet]).to be_false
34
+ end
35
+ end
36
+
37
+ describe '#parser' do
38
+ describe '-a, --address' do
39
+ it 'sets the host address' do
40
+ cli.parse(%w[--address foo])
41
+ expect(cli.options[:host]).to eql 'foo'
42
+ end
43
+ end
44
+
45
+ describe '-c, --[no-]config' do
46
+ it 'sets the conf_dir value' do
47
+ cli.parse(%w[--no-config])
48
+ expect(cli.options[:conf_dir]).to be_false
49
+
50
+ cli.parse(%w[--config foo/bar])
51
+ expect(cli.options[:conf_dir]).to eql 'foo/bar'
52
+ end
53
+ end
54
+
55
+ describe '-d, --daemonize' do
56
+ it 'sets the daemonize flag' do
57
+ cli.parse(%w[--daemonize])
58
+ expect(cli.options[:host]).to be_true
59
+ end
60
+ end
61
+
62
+ describe '-p, --port' do
63
+ it 'takes an Integer' do
64
+ expect do
65
+ cli.parse(%w[--port foo])
66
+ end.to raise_error OptionParser::InvalidArgument
67
+ end
68
+
69
+ it 'considers 0 to be an invalid argument' do
70
+ expect do
71
+ cli.parse(%w[--port 0])
72
+ end.to raise_error OptionParser::InvalidArgument
73
+ end
74
+
75
+ it 'sets the binding port' do
76
+ cli.parse(%w[--port 3333])
77
+ expect(cli.options[:port]).to eql 3333
78
+ end
79
+ end
80
+
81
+ describe '-P, --prefix' do
82
+ it 'sets the path to mount the app under' do
83
+ cli.parse(%w[--prefix /foo])
84
+ expect(cli.options[:prefix]).to eql '/foo'
85
+ end
86
+ end
87
+
88
+ describe '-q, --quiet' do
89
+ it 'sets the quiet flag' do
90
+ cli.parse(%w[--quiet])
91
+ expect(cli.options[:quiet]).to be_true
92
+ end
93
+ end
94
+
95
+ describe '-h, --help' do
96
+ it 'displays the help message' do
97
+ expect($stdout).to receive(:write).with(cli.help)
98
+ cli.parse(%w[--help])
99
+ end
100
+ end
101
+
102
+ describe '--version' do
103
+ it 'displays the version number' do
104
+ expect($stdout).to receive(:write).with("#{Jobim::VERSION}\n")
105
+ cli.parse(%w[--version])
106
+ end
107
+ end
108
+ end
109
+
110
+ describe '#parse', fakefs: true do
111
+ it 'parses the cli option array' do
112
+ args = %w[--port 3333 --prefix /foo]
113
+ cli.parse(args)
114
+ expect(args).to eql []
115
+ end
116
+
117
+ it 'sets the Directory option to its trailing argument' do
118
+ args = %w[dir]
119
+ cli.parse(args)
120
+ expect(cli.options[:dir]).to eql '/dir'
121
+ end
122
+ end
123
+
124
+ describe '#help' do
125
+ it 'returns the help message' do
126
+ expect(cli.help).to include('Usage: jobim [OPTION]... [DIRECTORY]')
127
+ end
128
+ end
129
+
130
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jobim::Server, fakefs: true do
4
+
5
+ before(:each) do
6
+ Dir.mkdir('/web_app')
7
+ Dir.mkdir('/web_app/trail_test')
8
+ Dir.mkdir('/web_app/index_test')
9
+
10
+ File.open('/web_app/index_test/index.html', 'w') { |f| f.write(index) }
11
+ File.open('/web_app/trail_test/foo.html', 'w') { |f| f.write(index) }
12
+ File.open('/web_app/trail_test/foo', 'w') { |f| f.write(index) }
13
+ end
14
+
15
+ let(:index) { "<!DOCTYPE html>\n<html />\n" }
16
+ let(:settings) { Jobim::CLI.new.settings }
17
+
18
+ describe 'app', rack_test: true do
19
+ before(:each) { $stdout.stub(:write) }
20
+
21
+ let(:server) do
22
+ settings.dir = '/web_app'
23
+ Jobim::Server.new(settings)
24
+ end
25
+
26
+ let(:app) { server.app }
27
+
28
+ it 'returns index.html from dirs when it exists' do
29
+ get '/index_test/'
30
+ expect(last_response).to be_ok
31
+ expect(last_response.body).to eql index
32
+ end
33
+
34
+ it 'treats bare urls as directories when they are' do
35
+ get '/trail_test'
36
+ expect(last_response).to be_ok
37
+ expect(last_response.body).to include '/trail_test/foo.html'
38
+ end
39
+
40
+ it 'treats bare urls as files when they are' do
41
+ get '/trail_test/foo'
42
+ expect(last_response).to be_ok
43
+ expect(last_response.body).to eql index
44
+ end
45
+ end
46
+
47
+ describe 'server' do
48
+ let(:server) do
49
+ settings.daemonize = true
50
+ Jobim::Server.new(settings)
51
+ end
52
+
53
+ it 'sets server.pid_file if :daemonize is true' do
54
+ expect(server.server.pid_file).to eql('jobim.pid')
55
+ end
56
+
57
+ it 'sets server.log_file if :daemonize is true' do
58
+ expect(server.server.log_file).to eql('jobim.log')
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jobim::Settings, fakefs: true do
4
+
5
+ before(:each) do
6
+ unless example.metadata[:no_conf]
7
+ Dir.mkdir('/home')
8
+ Dir.mkdir('/home/jobim')
9
+ Dir.mkdir('/home/jobim/public_html')
10
+ Dir.mkdir('/home/jobim/projects')
11
+
12
+ Dir.chdir('/home/jobim/projects')
13
+
14
+ file = RealFile.expand_path(__FILE__)
15
+ config_dir = RealFile.expand_path('../configs', file)
16
+
17
+ r_cfg = RealFile.read(RealFile.expand_path('root_conf.yml', config_dir))
18
+ u_cfg = RealFile.read(RealFile.expand_path('user_conf.yml', config_dir))
19
+ l_cfg = RealFile.read(RealFile.expand_path('local_conf.yml', config_dir))
20
+ e_cfg = RealFile.read(RealFile.expand_path('empty_conf.yml', config_dir))
21
+
22
+ File.open('/.jobim.yml', 'w') { |f| f.write r_cfg }
23
+ File.open('/home/.jobim.yml', 'w') { |f| f.write e_cfg }
24
+ File.open('/home/jobim/.jobim.yaml', 'w') { |f| f.write u_cfg }
25
+ File.open('/home/jobim/projects/.jobim.yaml', 'w') do |f|
26
+ f.write l_cfg
27
+ end
28
+ end
29
+ end
30
+
31
+ let(:settings) do
32
+ cli = Jobim::CLI.new
33
+ cli.parse(%w[--no-config])
34
+
35
+ settings = cli.settings
36
+ settings.conf_dir = Dir.pwd
37
+ settings
38
+ end
39
+
40
+ describe '#initialize' do
41
+
42
+ end
43
+
44
+ describe '#load_file' do
45
+ it 'loads config data into settings' do
46
+ settings.load_file('/.jobim.yml')
47
+ expect(settings.daemonize).to be_true
48
+ end
49
+
50
+ it 'only changes configured options' do
51
+ settings.load_file('/.jobim.yml')
52
+ expect(settings.port).to eql 3000
53
+ end
54
+
55
+ it 'expands directories relative to the config file location' do
56
+ settings.load_file('/home/jobim/.jobim.yaml')
57
+ expect(settings.dir).to eql '/home/jobim/public_html'
58
+ end
59
+
60
+ it 'overrides only specified options' do
61
+ settings.load_file('/home/jobim/.jobim.yaml')
62
+ expect(settings.quiet).to be_false
63
+ end
64
+
65
+ it 'handles empty configuration files' do
66
+ expect { settings.load_file('/home/.jobim.yml') }.to_not raise_error
67
+ end
68
+ end
69
+
70
+ describe '#load' do
71
+ before(:each) { settings.load }
72
+
73
+ it 'loads all config files from CWD to root by default' do
74
+ expect(settings.daemonize).to be_true
75
+ expect(settings.port).to eql 1234
76
+ expect(settings.dir).to eql '/home/jobim/public_html'
77
+ end
78
+
79
+ it 'overrides previous directory options with current ones' do
80
+ expect(settings.dir).to eql '/home/jobim/public_html'
81
+ end
82
+
83
+ it 'will check for yaml files only if there is no yml file' do
84
+ expect(settings.prefix).to eql '/jobim'
85
+ end
86
+
87
+ it 'can handle absolute directories' do
88
+ expect(settings.daemonize).to be_true
89
+ expect(settings.port).to eql 1234
90
+ expect(settings.dir).to eql '/home/jobim/public_html'
91
+ end
92
+
93
+ it 'can handle relative directories' do
94
+ settings.load('../')
95
+ expect(settings.prefix).to eql '/web_root'
96
+ expect(settings.port).to eql 1234
97
+ end
98
+ end
99
+
100
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jobim do
4
+
5
+ it 'has a version number' do
6
+ expect(Jobim::VERSION).to_not be_nil
7
+ end
8
+
9
+ end
@@ -0,0 +1,13 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
5
+ require 'jobim'
6
+
7
+ require 'fakefs/spec_helpers'
8
+ require 'rack/test'
9
+
10
+ RSpec.configure do |config|
11
+ config.include FakeFS::SpecHelpers, fakefs: true
12
+ config.include Rack::Test::Methods, rack_test: true
13
+ end
metadata CHANGED
@@ -1,111 +1,167 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jobim
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zachary Elliott
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-19 00:00:00.000000000 Z
11
+ date: 2014-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
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
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '10.1'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: yard
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
- - - ~>
73
+ - - "~>"
46
74
  - !ruby/object:Gem::Version
47
75
  version: '0.8'
48
76
  type: :development
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
- - - ~>
80
+ - - "~>"
53
81
  - !ruby/object:Gem::Version
54
82
  version: '0.8'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: redcarpet
57
85
  requirement: !ruby/object:Gem::Requirement
58
86
  requirements:
59
- - - ~>
87
+ - - "~>"
60
88
  - !ruby/object:Gem::Version
61
89
  version: '3.0'
62
90
  type: :development
63
91
  prerelease: false
64
92
  version_requirements: !ruby/object:Gem::Requirement
65
93
  requirements:
66
- - - ~>
94
+ - - "~>"
67
95
  - !ruby/object:Gem::Version
68
96
  version: '3.0'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: github-markup
71
99
  requirement: !ruby/object:Gem::Requirement
72
100
  requirements:
73
- - - ~>
101
+ - - "~>"
74
102
  - !ruby/object:Gem::Version
75
103
  version: '0.7'
76
104
  type: :development
77
105
  prerelease: false
78
106
  version_requirements: !ruby/object:Gem::Requirement
79
107
  requirements:
80
- - - ~>
108
+ - - "~>"
81
109
  - !ruby/object:Gem::Version
82
110
  version: '0.7'
111
+ - !ruby/object:Gem::Dependency
112
+ name: fakefs
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.5'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.5'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rack-test
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
83
139
  - !ruby/object:Gem::Dependency
84
140
  name: thin
85
141
  requirement: !ruby/object:Gem::Requirement
86
142
  requirements:
87
- - - ~>
143
+ - - "~>"
88
144
  - !ruby/object:Gem::Version
89
145
  version: '1.5'
90
146
  type: :runtime
91
147
  prerelease: false
92
148
  version_requirements: !ruby/object:Gem::Requirement
93
149
  requirements:
94
- - - ~>
150
+ - - "~>"
95
151
  - !ruby/object:Gem::Version
96
152
  version: '1.5'
97
153
  - !ruby/object:Gem::Dependency
98
154
  name: rack-rewrite
99
155
  requirement: !ruby/object:Gem::Requirement
100
156
  requirements:
101
- - - ~>
157
+ - - "~>"
102
158
  - !ruby/object:Gem::Version
103
159
  version: '1.2'
104
160
  type: :runtime
105
161
  prerelease: false
106
162
  version_requirements: !ruby/object:Gem::Requirement
107
163
  requirements:
108
- - - ~>
164
+ - - "~>"
109
165
  - !ruby/object:Gem::Version
110
166
  version: '1.2'
111
167
  description: Popup HTTP Server for serving static content.
@@ -116,7 +172,10 @@ executables:
116
172
  extensions: []
117
173
  extra_rdoc_files: []
118
174
  files:
119
- - .gitignore
175
+ - ".gitignore"
176
+ - ".rspec"
177
+ - ".rubocop.yml"
178
+ - ".travis.yml"
120
179
  - Gemfile
121
180
  - LICENSE
122
181
  - README.md
@@ -124,10 +183,21 @@ files:
124
183
  - bin/jobim
125
184
  - jobim.gemspec
126
185
  - lib/jobim.rb
186
+ - lib/jobim/application.rb
127
187
  - lib/jobim/cli.rb
128
188
  - lib/jobim/server.rb
129
189
  - lib/jobim/settings.rb
130
190
  - lib/jobim/version.rb
191
+ - spec/configs/empty_conf.yml
192
+ - spec/configs/local_conf.yml
193
+ - spec/configs/root_conf.yml
194
+ - spec/configs/user_conf.yml
195
+ - spec/jobim_application_spec.rb
196
+ - spec/jobim_cli_spec.rb
197
+ - spec/jobim_server_spec.rb
198
+ - spec/jobim_settings_spec.rb
199
+ - spec/jobim_spec.rb
200
+ - spec/spec_helper.rb
131
201
  homepage: https://github.com/zellio/jobim
132
202
  licenses:
133
203
  - MIT
@@ -138,19 +208,29 @@ require_paths:
138
208
  - lib
139
209
  required_ruby_version: !ruby/object:Gem::Requirement
140
210
  requirements:
141
- - - '>='
211
+ - - ">="
142
212
  - !ruby/object:Gem::Version
143
213
  version: '0'
144
214
  required_rubygems_version: !ruby/object:Gem::Requirement
145
215
  requirements:
146
- - - '>='
216
+ - - ">="
147
217
  - !ruby/object:Gem::Version
148
218
  version: '0'
149
219
  requirements: []
150
220
  rubyforge_project:
151
- rubygems_version: 2.1.5
221
+ rubygems_version: 2.2.2
152
222
  signing_key:
153
223
  specification_version: 4
154
224
  summary: Popup HTTP Server
155
- test_files: []
225
+ test_files:
226
+ - spec/configs/empty_conf.yml
227
+ - spec/configs/local_conf.yml
228
+ - spec/configs/root_conf.yml
229
+ - spec/configs/user_conf.yml
230
+ - spec/jobim_application_spec.rb
231
+ - spec/jobim_cli_spec.rb
232
+ - spec/jobim_server_spec.rb
233
+ - spec/jobim_settings_spec.rb
234
+ - spec/jobim_spec.rb
235
+ - spec/spec_helper.rb
156
236
  has_rdoc: