jagger 0.0.1

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/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # -*- ruby -*-
2
+ source 'http://rubygems.org'
3
+ gemspec
4
+
5
+ gem 'sprockets'
6
+ gem 'sinatra'
7
+ gem 'rack'
8
+ gem 'rake'
9
+
10
+ group :development do
11
+ gem 'rspec'
12
+ gem 'mocha'
13
+ gem 'rack-test'
14
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,54 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ jagger (0.0.1)
5
+ rack
6
+ sinatra
7
+ sprockets
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ diff-lcs (1.1.3)
13
+ hike (1.2.1)
14
+ metaclass (0.0.1)
15
+ mocha (0.10.5)
16
+ metaclass (~> 0.0.1)
17
+ multi_json (1.2.0)
18
+ rack (1.4.1)
19
+ rack-protection (1.2.0)
20
+ rack
21
+ rack-test (0.6.1)
22
+ rack (>= 1.0)
23
+ rake (0.9.2.2)
24
+ rspec (2.9.0)
25
+ rspec-core (~> 2.9.0)
26
+ rspec-expectations (~> 2.9.0)
27
+ rspec-mocks (~> 2.9.0)
28
+ rspec-core (2.9.0)
29
+ rspec-expectations (2.9.0)
30
+ diff-lcs (~> 1.1.3)
31
+ rspec-mocks (2.9.0)
32
+ sinatra (1.3.2)
33
+ rack (~> 1.3, >= 1.3.6)
34
+ rack-protection (~> 1.2)
35
+ tilt (~> 1.3, >= 1.3.3)
36
+ sprockets (2.4.0)
37
+ hike (~> 1.2)
38
+ multi_json (~> 1.0)
39
+ rack (~> 1.0)
40
+ tilt (~> 1.1, != 1.3.0)
41
+ tilt (1.3.3)
42
+
43
+ PLATFORMS
44
+ ruby
45
+
46
+ DEPENDENCIES
47
+ jagger!
48
+ mocha
49
+ rack
50
+ rack-test
51
+ rake
52
+ rspec
53
+ sinatra
54
+ sprockets
data/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # Jagger is your frontman!
2
+
3
+ ![Mick Jagger](http://i.imgur.com/xW8XW.jpg)
4
+
5
+ Jagger is a frontman for your frontend application. Mixing frontend and
6
+ backend in one Rails applicaiton sucks, let's say it stright! We have
7
+ bunch of unrelated things mixed together, why? With Jagger you gonna
8
+ rock your frontend application management!
9
+
10
+ ## Philosophy
11
+
12
+ Backend and frontend of web application are in fact two different
13
+ applications, ususaly utilizing different languages and tools.
14
+ The main point of Jagger's philosophy is to split backend and
15
+ frontend into separated applications.
16
+
17
+ **Frontend** - ususally a JavaScript (eg. Backbone) application
18
+ with set of templates and GUI integration tests.
19
+
20
+ **Backend** - an app written with Sinatra, Rails or whatever else,
21
+ which provices an unified API required by the _Frontend_ app.
22
+
23
+ ## Controversy
24
+
25
+ _Are you insane? I have to write two apps instead of one, and everytime
26
+ I change something in the backend then I have to adjust frontend one?_
27
+
28
+ Um... Well, you do the same every single day. You change something in
29
+ your Rails model, then you going to the view and editing it, then you
30
+ going to the (Java|Coffee)Script part and keep adjusting to the changes
31
+ you made in the model.
32
+
33
+ **The biggest advantages of this layout**:
34
+
35
+ * Frontend people can work on frontend without dealing with overwhelming
36
+ backend code.
37
+ * Backend people may don't give a shit about frontend stuff.
38
+ * Application has unified API which can be reused further by other
39
+ views (iPhone or Android app, external consumers, etc.)
40
+ * Frontend may be written totally without thinking about the databases
41
+ and other delivery methods. It can focus only on the look and feel
42
+ by accessing all the data from mocks.
43
+ * It's briliant for the designers, thus they don't need to install all
44
+ the development stuff (usually, you have to install it for them).
45
+ * After all, you can serve everything as one application anyway...
46
+
47
+ **This layout also have disadvantages**:
48
+
49
+ * It has no server side generated views - so it is not well suitable
50
+ for the applications which tend to be crawlable eg. by Googlebot.
51
+ * It requires good communication in your team in case of defining
52
+ and maintaining the API. Hmm, if you improve your communication thanks
53
+ to this then it may be considered as an advantage.
54
+ * It forces you to think different and abstract... some people don't like
55
+ this :P
56
+
57
+ ## Installation
58
+
59
+ Like always, via rubygems:
60
+
61
+ $ gem install jagger
62
+
63
+ Or by adding dependency to your gemfile:
64
+
65
+ gem 'jagger'
66
+
67
+ ## Usage
68
+
69
+ Jagger comes with set of conventions to make your life easier. Here's
70
+ the frontend app directory structure:
71
+
72
+ + your_frontend/
73
+ |-- lib/ - External, static JavaScript libraries (eg. jQuery).
74
+ |-+ src/ - Dynamic sources.
75
+ | |-- styles/ - Your CSS, SASS, LESS or God knows what styles.
76
+ | |-- sprites/ - Source images for your sprites.
77
+ | |-- main/ - Your application's (Java|Coffee)Script files.
78
+ | |-- test/ - Your GUI test files (i.a. QUnit, Selenium).
79
+ |-- static/ - Static images, javascripts, fonts, etc.
80
+ |-- templates/ - All the template files.
81
+ |-- config.ru - Rack configuration.
82
+
83
+ You can set ther up a Gemfile with `jagger` listed as a dependency and
84
+ add this code to `config.ru`
85
+
86
+ # *snip*
87
+
88
+ run Jagger::Builder.new
89
+
90
+ If you want to mount it within your backend application, no problem!
91
+ You can do it this way:
92
+
93
+ # *snip*
94
+
95
+ map '/api' do
96
+ run MyBackendApp.new
97
+ end
98
+
99
+ map '/' do
100
+ run Jagger::Builder.new
101
+ end
102
+
103
+ You can serve your frontend app simply like any other rack app using
104
+ `thin`, `rackup` or whatever you want.
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ # -*- ruby -*-
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+ require 'rake'
5
+
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new(:spec) do |t|
8
+ t.rspec_opts = ENV['RSPEC_OPTS']
9
+ end
10
+
11
+ task :test => :spec
12
+ task :default => :test
13
+
14
+ desc "Opens console with loaded env."
15
+ task :console do
16
+ $LOAD_PATH.unshift("./lib")
17
+ require 'jagger'
18
+ require 'irb'
19
+ ARGV.clear
20
+ IRB.start
21
+ end
data/jagger.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- ruby -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'jagger'
5
+ s.rubyforge_project = 'jagger'
6
+ s.version = '0.0.1'
7
+
8
+ s.authors = ['Chris Kowalik']
9
+ s.email = ['chris@nu7hat.ch']
10
+ s.homepage = 'http://github.com/nu7hatch/jagger'
11
+ s.summary = 'Jagger is your frontman!'
12
+ s.description = <<-END
13
+ Jagger an frontman for your applications. It serves dynamically
14
+ generated assets via sprockets pipeline, static files and all the
15
+ templates. All that makes your life much easier.'
16
+ END
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
20
+ s.require_paths = ['lib']
21
+
22
+ s.add_dependency 'sprockets'
23
+ s.add_dependency 'sinatra'
24
+ s.add_dependency 'rack'
25
+ s.add_development_dependency 'rspec'
26
+ s.add_development_dependency 'mocha'
27
+ end
data/lib/jagger.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'jagger/assets'
2
+ require 'jagger/app'
3
+ require 'jagger/builder'
data/lib/jagger/app.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'sinatra/base'
2
+
3
+ module Jagger
4
+ # Internal: App is a Sinatra application used to serve static
5
+ # files and index, and to keep Jagger's configuration.
6
+ class App < Sinatra::Application
7
+ set :asset_paths, %w(src/main/ src/test/ src/look/ lib/)
8
+ set :public_folder, 'static'
9
+ set :views, 'templates'
10
+ set :layout, false
11
+
12
+ helpers do
13
+ # Public: Returns whether requests' mocks should be skipped
14
+ # or not.
15
+ def mock_requests?
16
+ ENV['USE_REAL_REQUESTS'].to_i == 0
17
+ end
18
+ end
19
+
20
+ get '/' do
21
+ erb :index
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ require 'sprockets'
2
+
3
+ module Jagger
4
+ # Internal: Assets serves all dynamically generated asssets
5
+ # through sprockets pipeline.
6
+ class Assets
7
+ # Public: Constructor. Initializes sprockets environment.
8
+ def initialize
9
+ @sprockets = Sprockets::Environment.new
10
+ end
11
+
12
+ # Public: Registers given load paths in sprockets' env.
13
+ #
14
+ # dir - The Array of dirs to register
15
+ #
16
+ def append_paths(dirs = [])
17
+ dirs.each { |dir| @sprockets.append_path(dir) }
18
+ end
19
+
20
+ # Public: Serves assets
21
+ #
22
+ # env - The Hash HTTP environment.
23
+ #
24
+ # Returns HTTP response data.
25
+ def call(env)
26
+ @sprockets.call(env)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,53 @@
1
+ module Jagger
2
+ # Public: Builder creates rack compatible application which gathers
3
+ # and serves static sinatra app and sprockets pipeline together.
4
+ #
5
+ # Example
6
+ #
7
+ # app = Jagger::Builder.new do
8
+ # set :asset_paths, %w(src/main/ src/test/ src/look/ lib/)
9
+ # set :views, 'templates'
10
+ # set :public_folder, 'static'
11
+ # end
12
+ #
13
+ # run app
14
+ #
15
+ # Configuration above is the default one, so in most of cases only
16
+ # the following declaration will be enough:
17
+ #
18
+ # run Jagger::Builder.new
19
+ #
20
+ class Builder
21
+ # Public: Constructor. Initializes application and the assets
22
+ # pipeline. Passed block accepts custom configuration.
23
+ def initialize(&block)
24
+ app.instance_eval(&block) if block_given?
25
+ assets.append_paths(app.asset_paths)
26
+ end
27
+
28
+ # Internal: Sinatra application used to serve static files and
29
+ # index page.
30
+ def app
31
+ @app ||= App
32
+ end
33
+
34
+ # Internal: Assets pipeline environment.
35
+ def assets
36
+ @assets ||= Assets.new
37
+ end
38
+
39
+ # Public: Serves the application and assets pipeline together
40
+ # as one rack application.
41
+ #
42
+ # env - The Hash with request environment.
43
+ #
44
+ def call(env)
45
+ map = {
46
+ '/assets' => assets,
47
+ '/' => app.new,
48
+ }
49
+ router = Rack::URLMap.new(map)
50
+ router.call(env)
51
+ end
52
+ end
53
+ end
data/spec/app_spec.rb ADDED
@@ -0,0 +1,36 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe Jagger::App do
4
+ describe "#mock_requests?" do
5
+ it "returns true when requests should be mocked" do
6
+ #ENV['USE_REAL_REQUESTS'] = '0'
7
+ #subject.should be_mock_requests
8
+ end
9
+
10
+ it "returns false when requests should not be mocked" do
11
+ #ENV['USE_REAL_REQUESTS'] = '1'
12
+ #subject.should_not be_mock_requests
13
+ end
14
+ end
15
+
16
+ it "has proper default configuration" do
17
+ app = Jagger::App
18
+ app.asset_paths == %w(src/main/ src/test/ src/look/ lib/)
19
+ app.public_folder.should == 'static'
20
+ app.views.should == 'templates'
21
+ app.layout.should_not be
22
+ end
23
+
24
+ describe "integration" do
25
+ let :app do
26
+ base = Class.new(Jagger::App)
27
+ base.set :views, File.expand_path('../fixtures/templates/', __FILE__)
28
+ base.new
29
+ end
30
+
31
+ it "serves index page" do
32
+ get '/'
33
+ last_response.body.should == 'Hello Jagger!'
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe Jagger::Assets do
4
+ describe "#append_paths" do
5
+ it "registers specified paths under the sprockets instance" do
6
+ Sprockets::Environment.any_instance.tap do |env|
7
+ env.expects(:append_path).with('foo/')
8
+ env.expects(:append_path).with('bar/')
9
+ end
10
+ subject.append_paths(%w(foo/ bar/))
11
+ end
12
+ end
13
+
14
+ describe "#call" do
15
+ it "serves assets via sprockets pipeline" do
16
+ env = { :hello => 'world' }
17
+ Sprockets::Environment.any_instance.expects(:call).with(env)
18
+ subject.call(env)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe Jagger::Builder do
4
+ describe "initialization" do
5
+ it "configures sinatra app" do
6
+ app = Jagger::Builder.new { set :public_folder, 'test' }
7
+ app.app.public_folder.should == 'test'
8
+ end
9
+
10
+ it "registers assets paths" do
11
+ paths = %w(test/)
12
+ Jagger::Assets.any_instance.expects(:append_paths).with(paths)
13
+ app = Jagger::Builder.new { set :asset_paths, paths }
14
+ end
15
+ end
16
+
17
+ describe "integration" do
18
+ let :app do
19
+ Jagger::Builder.new do
20
+ set :asset_paths, [File.expand_path('../fixtures/src/', __FILE__)]
21
+ set :views, File.expand_path('../fixtures/templates/', __FILE__)
22
+ end
23
+ end
24
+
25
+ it "serves index page" do
26
+ get '/'
27
+ last_response.body.should == 'Hello Jagger!'
28
+ end
29
+
30
+ it "serves assets" do
31
+ get '/assets/one.js'
32
+ last_response.body.strip.should == "alert('hello!');"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1 @@
1
+ //= require two
@@ -0,0 +1 @@
1
+ alert('hello!');
@@ -0,0 +1 @@
1
+ Hello Jagger!
@@ -0,0 +1,10 @@
1
+ require 'rspec'
2
+ require 'mocha'
3
+ require 'rack/test'
4
+
5
+ require 'jagger'
6
+
7
+ RSpec.configure do |config|
8
+ config.mock_with :mocha
9
+ include Rack::Test::Methods
10
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jagger
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris Kowalik
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sprockets
16
+ requirement: &19515340 !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: *19515340
25
+ - !ruby/object:Gem::Dependency
26
+ name: sinatra
27
+ requirement: &19514380 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *19514380
36
+ - !ruby/object:Gem::Dependency
37
+ name: rack
38
+ requirement: &19513580 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *19513580
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &19512840 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *19512840
58
+ - !ruby/object:Gem::Dependency
59
+ name: mocha
60
+ requirement: &19510360 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *19510360
69
+ description: ! "Jagger an frontman for your applications. It serves dynamically \ngenerated
70
+ assets via sprockets pipeline, static files and all the \ntemplates. All that makes
71
+ your life much easier.'\n"
72
+ email:
73
+ - chris@nu7hat.ch
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - .rspec
79
+ - Gemfile
80
+ - Gemfile.lock
81
+ - README.md
82
+ - Rakefile
83
+ - jagger.gemspec
84
+ - lib/jagger.rb
85
+ - lib/jagger/app.rb
86
+ - lib/jagger/assets.rb
87
+ - lib/jagger/builder.rb
88
+ - spec/app_spec.rb
89
+ - spec/assets_spec.rb
90
+ - spec/builder_spec.rb
91
+ - spec/fixtures/src/one.js
92
+ - spec/fixtures/src/two.js
93
+ - spec/fixtures/templates/index.erb
94
+ - spec/spec_helper.rb
95
+ homepage: http://github.com/nu7hatch/jagger
96
+ licenses: []
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project: jagger
115
+ rubygems_version: 1.8.15
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: Jagger is your frontman!
119
+ test_files: []