lotion 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,12 +2,14 @@
2
2
  *.rbc
3
3
  .bundle
4
4
  .config
5
+ .dat*
6
+ .repl_history
5
7
  .yardoc
8
+ build
9
+ coverage
10
+ doc
6
11
  Gemfile.lock
7
12
  InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
13
  lib/bundler/man
12
14
  pkg
13
15
  rdoc
@@ -15,3 +17,4 @@ spec/reports
15
17
  test/tmp
16
18
  test/version_tmp
17
19
  tmp
20
+ _yardoc
@@ -0,0 +1,6 @@
1
+ guard 'motion', :all_after_pass => true do
2
+ watch( 'Gemfile.lock' )
3
+ watch( 'app/app_delegate.rb' )
4
+ watch( %r{^spec/.+_spec\.rb$} )
5
+ watch( %r{^lib/(.+)\.rb$} ){ |m| "./spec/#{m[1]}_spec.rb" }
6
+ end
data/README.md CHANGED
@@ -1,9 +1,13 @@
1
1
  # Lotion
2
2
 
3
- TODO: Write a gem description
3
+ This library is a work in progress. Hit that "watch" button, son!
4
4
 
5
5
  ## Installation
6
6
 
7
+ RubyMotion projects don't come with a Gemfile by default. Create one:
8
+
9
+ bundle init
10
+
7
11
  Add this line to your application's Gemfile:
8
12
 
9
13
  gem 'lotion'
@@ -16,9 +20,19 @@ Or install it yourself as:
16
20
 
17
21
  $ gem install lotion
18
22
 
23
+ Finally, include Lotion in your project by adding the following to your Rakefile:
24
+
25
+ # after require 'motion/project'
26
+ require 'bundler'
27
+ Bundler.require
28
+
29
+ # inside app setup
30
+ app.files += Lotion::Dependencies( __FILE__ )
31
+ app.files_dependencies 'app/app_delegate.rb' => Lotion::Dependencies( __FILE__ )
32
+
19
33
  ## Usage
20
34
 
21
- TODO: Write usage instructions here
35
+ # TODO
22
36
 
23
37
  ## Contributing
24
38
 
data/Rakefile CHANGED
@@ -1,5 +1,18 @@
1
- #!/usr/bin/env rake
2
- require 'bundler/gem_tasks'
3
- require 'rspec/core/rake_task'
1
+ # -*- coding: utf-8 -*-
2
+ $:.unshift '/Library/RubyMotion/lib'
3
+ $:.unshift 'lib'
4
+
5
+ require 'motion/project/template/ios'
6
+ require 'lotion/project'
7
+ require 'lotion/version'
8
+
9
+ require 'guard/motion'
10
+ require 'motion-stump'
4
11
 
5
- RSpec::Core::RakeTask.new :spec
12
+ Motion::Project::App.setup do |app|
13
+ app.name = 'TestSuite'
14
+ app.identifier = 'com.jeremyruppel.lotion.TestSuite'
15
+ app.version = Lotion::VERSION
16
+ end
17
+
18
+ require 'bundler/gem_tasks'
@@ -0,0 +1,5 @@
1
+ class AppDelegate
2
+ def application( application, didFinishLaunchingWithOptions:launchOptions )
3
+ true
4
+ end
5
+ end
@@ -1,9 +1,39 @@
1
1
  require 'lotion/version'
2
+ require 'codependency'
2
3
 
3
4
  module Lotion
5
+ class << self
4
6
 
5
- FILES = Dir[ File.expand_path( File.join( __FILE__, '../**/*.rb' ) ) ].sort.freeze
7
+ ##
8
+ # Public API for accessing the dependency graph. Checks to make sure
9
+ # we are in a RubyMotion Rakefile, then yields the graph to the block.
10
+ # Projects and libraries can use this to add themselves to the
11
+ # dependency graph search path.
12
+ def require
13
+ unless defined?( Motion::Project::Config )
14
+ raise <<-EOS
15
+ ====================================================
16
+ This file must be required in a RubyMotion Rakefile.
17
+ ====================================================
18
+ EOS
19
+ end
6
20
 
7
- autoload :Application, 'lotion/application'
8
- autoload :Concern, 'lotion/concern'
21
+ yield graph
22
+ end
23
+
24
+ private
25
+
26
+ ##
27
+ # The shared dependency graph. Projects and libraries should access
28
+ # this through `Lotion.require`.
29
+ def graph
30
+ @graph ||= Codependency::Graph.new
31
+ end
32
+ end
33
+ end
34
+
35
+ ##
36
+ # Add this library to the load path.
37
+ Lotion.require do |graph|
38
+ graph.path << File.expand_path( '..', __FILE__ )
9
39
  end
@@ -1,9 +1,39 @@
1
+ #= require lotion/command
2
+ #= require lotion/notifications
3
+
1
4
  module Lotion
2
5
  module Application
3
- extend Lotion::Concern
6
+ include Lotion::Notifications
7
+
8
+ ##
9
+ #
10
+ def screen
11
+ UIScreen.mainScreen
12
+ end
13
+
14
+ ##
15
+ #
16
+ def window
17
+ @window ||= UIWindow.alloc.initWithFrame screen.bounds
18
+ end
19
+
20
+ ##
21
+ #
22
+ def on( name, command )
23
+ notification_center.addObserver command,
24
+ selector:'call:', name:name, object:nil
25
+ end
26
+
27
+ ##
28
+ #
29
+ def views
30
+ @views ||= Hash.new { |h, k| h[ k ] = k.alloc.init }
31
+ end
4
32
 
5
- def application( application, options ) #didFinishLaunchingWithOptions:launchOptions
6
- true
33
+ ##
34
+ #
35
+ def application( application, didFinishLaunchingWithOptions:launchOptions )
36
+ notify 'application:startup', launchOptions
7
37
  end
8
38
  end
9
39
  end
@@ -0,0 +1,45 @@
1
+ #= require lotion/notifications
2
+
3
+ module Lotion
4
+ class Command
5
+ include Lotion::Notifications
6
+
7
+ ##
8
+ #
9
+ def initialize( notification )
10
+ @notification = notification
11
+ end
12
+ attr_reader :notification
13
+
14
+ ##
15
+ #
16
+ # TODO this could be a macro on Module
17
+ def call
18
+ raise NotImplementedError, 'Lotion::Command subclasses are expected to define #call'
19
+ end
20
+
21
+ ##
22
+ #
23
+ def self.call( notification )
24
+ new( notification ).call
25
+ end
26
+
27
+ ##
28
+ # TODO delegate
29
+ def name
30
+ notification.name
31
+ end
32
+
33
+ ##
34
+ # TODO delegate
35
+ def object
36
+ notification.object
37
+ end
38
+
39
+ ##
40
+ # TODO delegate
41
+ def userInfo
42
+ notification.userInfo
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,20 @@
1
+ module Lotion
2
+ module Notifications
3
+
4
+ ##
5
+ # Publishes a notification named `name` to the default
6
+ # notification center. You can optionally pass an `info`
7
+ # object that will be available to any subscribers
8
+ # of the notification.
9
+ def notify( name, info=nil )
10
+ notification_center.postNotificationName name,
11
+ object:self, userInfo:info
12
+ end
13
+
14
+ ##
15
+ # The shared notification center instance.
16
+ def notification_center
17
+ NSNotificationCenter.defaultCenter
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require 'lotion'
2
+
3
+ Lotion.require do |graph|
4
+
5
+ Motion::Project::App.setup do |app|
6
+ # Add the app dir to the search path
7
+ graph.path << './app'
8
+
9
+ # Scan the app dir for dependent files
10
+ graph.scan './app/**/*.rb'
11
+
12
+ # Scan the specs dir for dependent files
13
+ # FIXME add once https://github.com/HipByte/RubyMotion/pull/84 merges
14
+ graph.scan File.join( app.specs_dir, '**/*.rb' ) # if app.spec_mode
15
+
16
+ # Add the dependency graph to the app
17
+ app.files += graph.files
18
+ app.files_dependencies graph
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module Lotion
2
- VERSION = "0.0.1"
2
+ VERSION = '0.1.0'
3
3
  end
@@ -15,7 +15,10 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Lotion::VERSION
17
17
 
18
- gem.add_dependency 'rake', '>= 0.9.2.2'
18
+ gem.add_dependency 'rake', '>= 0.9.2.2'
19
+ gem.add_dependency 'codependency', '>= 2.3.2'
19
20
 
20
- gem.add_development_dependency 'rspec', '>= 2.10.0'
21
+ gem.add_development_dependency 'guard-motion', '0.1.1'
22
+ gem.add_development_dependency 'rb-fsevent', '~> 0.9.1'
23
+ gem.add_development_dependency 'motion-stump', '0.2.0'
21
24
  end
@@ -0,0 +1,13 @@
1
+ module Bacon
2
+ module Matchers
3
+
4
+ ##
5
+ #
6
+ def be_a( klass )
7
+ lambda { |obj| obj.is_a?( klass ) }
8
+ end
9
+ alias :be_an :be_a
10
+ end
11
+ end
12
+
13
+ Bacon::Context.send :include, Bacon::Matchers
@@ -0,0 +1,12 @@
1
+ module Bacon
2
+ module Subject
3
+
4
+ ##
5
+ # Syntactic sugar for creating an anonymous class in a before block.
6
+ def subject( base=Object, &block )
7
+ block_given? ? before { @subject = Class.new( base, &block ).new } : @subject
8
+ end
9
+ end
10
+ end
11
+
12
+ Bacon::Context.send :include, Bacon::Subject
@@ -1,16 +1,49 @@
1
- require 'spec_helper'
1
+ #= require lotion/application
2
2
 
3
3
  describe Lotion::Application do
4
- subject { Class.new do
4
+
5
+ subject do
5
6
  include Lotion::Application
6
- end.new }
7
+ end
8
+ before do
9
+ @center = subject.notification_center
10
+ end
11
+ it 'includes the correct concerns' do
12
+ subject.should be_a( Lotion::Notifications )
13
+ end
14
+ it 'defines #screen' do
15
+ subject.screen.should == UIScreen.mainScreen
16
+ end
17
+ it 'defines #window' do
18
+ subject.window.should be_a( UIWindow )
19
+ end
20
+ it 'defined #views' do
21
+ subject.views.should be_a( Hash )
22
+ end
23
+ it 'notifies after application startup' do
24
+ options = { :foo => 'bar' }
25
+
26
+ @center.mock! 'postNotificationName:object:userInfo:' do |name, from, info|
27
+ name.should == 'application:startup'
28
+ from.should == subject
29
+ info.should == options
30
+ end
7
31
 
8
- it { should respond_to( :application ) }
32
+ subject.application( nil, didFinishLaunchingWithOptions:options ).should == true
33
+ end
34
+ it 'responds to #on' do
35
+ subject.should.respond_to :on
36
+ end
37
+ it 'attaches commands to notifications' do
38
+ command = stub :call, :return => true
9
39
 
10
- let( :application ){ double 'application' }
11
- let( :options ){ double 'launch options' }
40
+ @center.mock! 'addObserver:selector:name:object:' do |klass, selector, name, object|
41
+ klass.should == command
42
+ selector.should == 'call:'
43
+ name.should == 'foo'
44
+ object.should == nil
45
+ end
12
46
 
13
- it 'should return true, of course' do
14
- subject.application( application, options ).should == true
47
+ subject.on 'foo', command
15
48
  end
16
49
  end
@@ -0,0 +1,33 @@
1
+ describe Lotion::Command do
2
+
3
+ before do
4
+ # TODO this mock syntax blows.
5
+ @notification = stub( :name, :return => 'foo' )
6
+ @command = Class.new( Lotion::Command ) do
7
+ def call; name.reverse; end
8
+ end
9
+ @subject = @command.new @notification
10
+ end
11
+
12
+ it 'includes the correct concerns' do
13
+ @subject.should be_a( Lotion::Notifications )
14
+ end
15
+ it 'responds to #notification' do
16
+ @subject.should.respond_to :notification
17
+ end
18
+ it 'exposes the correct notification methods' do
19
+ @subject.notification.mock! :name, :return => 'foo'
20
+ @subject.notification.mock! :object, :return => 'bar'
21
+ @subject.notification.mock! :userInfo, :return => 'baz'
22
+
23
+ @subject.name.should == 'foo'
24
+ @subject.object.should == 'bar'
25
+ @subject.userInfo.should == 'baz'
26
+ end
27
+ it 'treats .call as a factory method' do
28
+ @command.call( @notification ).should == 'oof'
29
+ end
30
+ it 'expects subclasses to override #call' do
31
+ lambda { Lotion::Command.new( @notification ).call }.should.raise( NotImplementedError )
32
+ end
33
+ end
@@ -0,0 +1,32 @@
1
+ describe Lotion::Notifications do
2
+
3
+ subject do
4
+ include Lotion::Notifications
5
+ end
6
+ before do
7
+ @center = subject.notification_center
8
+ @method = 'postNotificationName:object:userInfo'
9
+ end
10
+ it 'has the correct notification center' do
11
+ subject.notification_center.should == NSNotificationCenter.defaultCenter
12
+ end
13
+ it 'responds to #notify' do
14
+ subject.should.respond_to :notify
15
+ end
16
+ it 'sends a notification to the notification center' do
17
+ @center.mock! @method do |name, from, info|
18
+ name.should == 'foo'
19
+ from.should == subject
20
+ info.should == nil
21
+ end
22
+ subject.notify 'foo'
23
+ end
24
+ it 'passes along the user info hash to the notification center' do
25
+ @center.mock! @method do |name, from, info|
26
+ name.should == 'foo'
27
+ from.should == subject
28
+ info.should == { :foo => 'bar' }
29
+ end
30
+ subject.notify 'foo', :foo => 'bar'
31
+ end
32
+ end
@@ -0,0 +1,5 @@
1
+ # This file exists just so guard doesn't freak out when project.rb
2
+ # is modified. Since this file should only be included in a Rakefile,
3
+ # there is nothing to test in the RubyMotion runtime.
4
+ describe 'Lotion::Project' do
5
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lotion
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-08 00:00:00.000000000 Z
12
+ date: 2013-06-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -28,21 +28,69 @@ dependencies:
28
28
  - !ruby/object:Gem::Version
29
29
  version: 0.9.2.2
30
30
  - !ruby/object:Gem::Dependency
31
- name: rspec
31
+ name: codependency
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
35
  - - ! '>='
36
36
  - !ruby/object:Gem::Version
37
- version: 2.10.0
38
- type: :development
37
+ version: 2.3.2
38
+ type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
- version: 2.10.0
45
+ version: 2.3.2
46
+ - !ruby/object:Gem::Dependency
47
+ name: guard-motion
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - '='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.1.1
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.1.1
62
+ - !ruby/object:Gem::Dependency
63
+ name: rb-fsevent
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.9.1
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.9.1
78
+ - !ruby/object:Gem::Dependency
79
+ name: motion-stump
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - '='
84
+ - !ruby/object:Gem::Version
85
+ version: 0.2.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - '='
92
+ - !ruby/object:Gem::Version
93
+ version: 0.2.0
46
94
  description: Silky smooth helpers for RubyMotion
47
95
  email:
48
96
  - jeremy.ruppel@gmail.com
@@ -52,18 +100,24 @@ extra_rdoc_files: []
52
100
  files:
53
101
  - .gitignore
54
102
  - Gemfile
103
+ - Guardfile
55
104
  - LICENSE
56
105
  - README.md
57
106
  - Rakefile
107
+ - app/app_delegate.rb
58
108
  - lib/lotion.rb
59
109
  - lib/lotion/application.rb
60
- - lib/lotion/concern.rb
110
+ - lib/lotion/command.rb
111
+ - lib/lotion/notifications.rb
112
+ - lib/lotion/project.rb
61
113
  - lib/lotion/version.rb
62
114
  - lotion.gemspec
115
+ - spec/helpers/matchers.rb
116
+ - spec/helpers/subject.rb
63
117
  - spec/lotion/application_spec.rb
64
- - spec/lotion/concern_spec.rb
65
- - spec/lotion/files_spec.rb
66
- - spec/spec_helper.rb
118
+ - spec/lotion/command_spec.rb
119
+ - spec/lotion/notifications_spec.rb
120
+ - spec/lotion/project_spec.rb
67
121
  homepage: ''
68
122
  licenses: []
69
123
  post_install_message:
@@ -84,12 +138,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
138
  version: '0'
85
139
  requirements: []
86
140
  rubyforge_project:
87
- rubygems_version: 1.8.19
141
+ rubygems_version: 1.8.23
88
142
  signing_key:
89
143
  specification_version: 3
90
144
  summary: Silky smooth helpers for RubyMotion
91
145
  test_files:
146
+ - spec/helpers/matchers.rb
147
+ - spec/helpers/subject.rb
92
148
  - spec/lotion/application_spec.rb
93
- - spec/lotion/concern_spec.rb
94
- - spec/lotion/files_spec.rb
95
- - spec/spec_helper.rb
149
+ - spec/lotion/command_spec.rb
150
+ - spec/lotion/notifications_spec.rb
151
+ - spec/lotion/project_spec.rb
152
+ has_rdoc:
@@ -1,22 +0,0 @@
1
- module Lotion
2
- module Concern
3
-
4
- def self.extended( base )
5
- base.instance_exec do
6
-
7
- def included( base=nil, &block )
8
- if block_given?
9
- @_included_block = block
10
- else
11
- if const_defined? :ClassMethods
12
- base.extend const_get( :ClassMethods )
13
- end
14
- if @_included_block
15
- base.class_eval &@_included_block
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,46 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Lotion::Concern do
4
-
5
- let( :concern ){ Module.new do
6
- extend Lotion::Concern
7
-
8
- included do
9
- $woot = self
10
- end
11
-
12
- def foo
13
- 'foo!'
14
- end
15
-
16
- module ClassMethods
17
-
18
- def bar
19
- 'bar!'
20
- end
21
- end
22
- end }
23
-
24
- let( :klass ){ Class.new }
25
-
26
- before do
27
- klass.send :include, concern
28
- end
29
-
30
- describe 'class methods' do
31
- subject { klass }
32
- it { should respond_to( :bar ) }
33
- its( :bar ){ should eq( 'bar!' ) }
34
- end
35
-
36
- describe 'instance methods' do
37
- subject { klass.new }
38
- it { should respond_to( :foo ) }
39
- its( :foo ){ should eq( 'foo!' ) }
40
- end
41
-
42
- describe 'included block' do
43
- subject { $woot }
44
- it { should eq( klass ) }
45
- end
46
- end
@@ -1,11 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Lotion do
4
- subject { Lotion::FILES }
5
-
6
- let( :path ){ File.expand_path( File.join( __FILE__, '../../..' ) ) }
7
-
8
- it { should include( "#{path}/lib/lotion.rb" ) }
9
- it { should include( "#{path}/lib/lotion/concern.rb" ) }
10
- it { should include( "#{path}/lib/lotion/version.rb" ) }
11
- end
@@ -1,6 +0,0 @@
1
- require 'lotion'
2
-
3
- RSpec.configure do |config|
4
- config.color_enabled = true
5
- config.formatter = :documentation
6
- end