widget 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.DS_Store +0 -0
- data/.gitignore +4 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +69 -0
- data/LICENCE.txt +20 -0
- data/README.markdown +33 -0
- data/Rakefile +4 -0
- data/_test/marshal.rb +20 -0
- data/_test/widget.hashmodel +0 -0
- data/autotest/discover.rb +2 -0
- data/bin/widget +6 -0
- data/db/hashmodel.dat +0 -0
- data/features/setup/env.rb +5 -0
- data/features/step-definitions/step-definitions.rb +22 -0
- data/features/support/helpers.rb +15 -0
- data/features/widget_creation.feature +13 -0
- data/features/widget_deletion.feature +18 -0
- data/features/widget_details.feature +20 -0
- data/features/widget_list_names.feature +14 -0
- data/features/widget_upgrade.feature +14 -0
- data/images/salandrichard.jpeg +0 -0
- data/images/salandrichard.jpg +0 -0
- data/lib/.DS_Store +0 -0
- data/lib/widget/.DS_Store +0 -0
- data/lib/widget/commandable_config.rb +10 -0
- data/lib/widget/version.rb +3 -0
- data/lib/widget/widget_data.rb +81 -0
- data/lib/widget/widget_viewtroller.rb +80 -0
- data/lib/widget.rb +7 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/widget/widget_spec.rb +88 -0
- data/widget.gemspec +22 -0
- metadata +114 -0
data/.DS_Store
ADDED
Binary file
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
widget (0.0.1)
|
5
|
+
commandable (= 0.2.0.beta2)
|
6
|
+
hashmodel (= 0.4.0.beta2)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
aruba (0.3.3)
|
12
|
+
childprocess (~> 0.1.7)
|
13
|
+
cucumber (~> 0.10)
|
14
|
+
rspec (~> 2.5)
|
15
|
+
builder (3.0.0)
|
16
|
+
childprocess (0.1.7)
|
17
|
+
ffi (~> 0.6.3)
|
18
|
+
commandable (0.2.0.beta2)
|
19
|
+
term-ansicolor-hi (~> 1.0.7)
|
20
|
+
cucumber (0.10.0)
|
21
|
+
builder (>= 2.1.2)
|
22
|
+
diff-lcs (~> 1.1.2)
|
23
|
+
gherkin (~> 2.3.2)
|
24
|
+
json (~> 1.4.6)
|
25
|
+
term-ansicolor (~> 1.0.5)
|
26
|
+
diff-lcs (1.1.2)
|
27
|
+
ffi (0.6.3)
|
28
|
+
rake (>= 0.8.7)
|
29
|
+
file-tail (1.0.5)
|
30
|
+
spruz (>= 0.1.0)
|
31
|
+
gherkin (2.3.5)
|
32
|
+
json (>= 1.4.6)
|
33
|
+
hashmodel (0.4.0.beta2)
|
34
|
+
file-tail
|
35
|
+
sourcify
|
36
|
+
json (1.4.6)
|
37
|
+
rake (0.8.7)
|
38
|
+
rspec (2.5.0)
|
39
|
+
rspec-core (~> 2.5.0)
|
40
|
+
rspec-expectations (~> 2.5.0)
|
41
|
+
rspec-mocks (~> 2.5.0)
|
42
|
+
rspec-core (2.5.1)
|
43
|
+
rspec-expectations (2.5.0)
|
44
|
+
diff-lcs (~> 1.1.2)
|
45
|
+
rspec-mocks (2.5.0)
|
46
|
+
ruby2ruby (1.2.5)
|
47
|
+
ruby_parser (~> 2.0)
|
48
|
+
sexp_processor (~> 3.0)
|
49
|
+
ruby_parser (2.0.6)
|
50
|
+
sexp_processor (~> 3.0)
|
51
|
+
sexp_processor (3.0.5)
|
52
|
+
sourcify (0.4.2)
|
53
|
+
file-tail (>= 1.0.5)
|
54
|
+
ruby2ruby (>= 1.2.5)
|
55
|
+
sexp_processor (>= 3.0.5)
|
56
|
+
spruz (0.2.5)
|
57
|
+
term-ansicolor (1.0.5)
|
58
|
+
term-ansicolor-hi (1.0.7)
|
59
|
+
|
60
|
+
PLATFORMS
|
61
|
+
ruby
|
62
|
+
|
63
|
+
DEPENDENCIES
|
64
|
+
aruba (= 0.3.3)
|
65
|
+
commandable (= 0.2.0.beta2)
|
66
|
+
cucumber (= 0.10.0)
|
67
|
+
hashmodel (= 0.4.0.beta2)
|
68
|
+
rspec (= 2.5.0)
|
69
|
+
widget!
|
data/LICENCE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Mike Bethany
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Widget #
|
2
|
+
|
3
|
+
It does stuff and things!
|
4
|
+
|
5
|
+
## Description ##
|
6
|
+
|
7
|
+
No matter how many specs I write I always find trying to use a thing is a sure way of finding out what it's lacking and where it doesn't actually work. This app is the testbed for doing just that with two of my Gems: [Commandable][], the easiest way to add command line control to your Ruby apps, and [HashModel][] a hash based MVC model that makes searching and updating deeply nested hashes a breeze.
|
8
|
+
|
9
|
+
## Functionality ##
|
10
|
+
|
11
|
+
It makes widgets of course.
|
12
|
+
|
13
|
+
## Instructions ##
|
14
|
+
|
15
|
+
You can install it as a Gem by running:
|
16
|
+
|
17
|
+
rake install
|
18
|
+
|
19
|
+
You can then run it by just typing:
|
20
|
+
|
21
|
+
widget
|
22
|
+
|
23
|
+
Or run it as is by typing
|
24
|
+
|
25
|
+
bin/widget <command> [parameter]
|
26
|
+
|
27
|
+
To see what it can do type
|
28
|
+
|
29
|
+
widget help
|
30
|
+
|
31
|
+
|
32
|
+
[HashModel]: https://github.com/mikbe/hashmodel
|
33
|
+
[Commandable]: https://github.com/mikbe/commandable
|
data/Rakefile
ADDED
data/_test/marshal.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'hashmodel'
|
2
|
+
|
3
|
+
# puts hm
|
4
|
+
# data = Marshal.dump(hm)
|
5
|
+
#File.new("dummy.hashmodel", "r")
|
6
|
+
|
7
|
+
hashmodel_file = "widget.hashmodel"
|
8
|
+
|
9
|
+
hm = HashModel.new
|
10
|
+
hm.add(:name=>"Phish")
|
11
|
+
|
12
|
+
File.open(hashmodel_file, "w"){|file| file.write(Marshal.dump(HashModel.new))} unless File.exist?(hashmodel_file)
|
13
|
+
|
14
|
+
hmo = Marshal.load(File.open(hashmodel_file, "r"))
|
15
|
+
|
16
|
+
puts hmo.class
|
17
|
+
puts hmo
|
18
|
+
|
19
|
+
# hm.add(:name=>"Widgee 5")
|
20
|
+
# put hm
|
Binary file
|
data/bin/widget
ADDED
data/db/hashmodel.dat
ADDED
Binary file
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Before do
|
2
|
+
file_name = File.expand_path((File.dirname(__FILE__) + '/../../db/hashmodel.dat'))
|
3
|
+
File.delete(file_name) if File.exists?(file_name)
|
4
|
+
Widget::Data.reset_instance
|
5
|
+
@data = Widget::Data.instance
|
6
|
+
end
|
7
|
+
|
8
|
+
Given /^I have a widget named "([^"]*)"$/ do |name|
|
9
|
+
@data.create(name)
|
10
|
+
end
|
11
|
+
|
12
|
+
Given /^There are no widgets$/ do
|
13
|
+
@data.delete_all
|
14
|
+
end
|
15
|
+
|
16
|
+
Given /^I have (\d+) widgets named "([^"]*)"$/ do |count, name|
|
17
|
+
(1..count.to_i).each{|n| @data.create(name.gsub("\#{n}", n.to_s))}
|
18
|
+
end
|
19
|
+
|
20
|
+
Then /^the output should contain (\d+) lines matching "([^"]*)"$/ do |count, line|
|
21
|
+
(1..count.to_i).each{|n| all_output.should =~ Regexp.new(line.gsub("\#{n}", n.to_s))}
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Allow an instance class to be "reset"
|
2
|
+
require 'singleton'
|
3
|
+
class <<Singleton
|
4
|
+
def included_with_reset(klass)
|
5
|
+
included_without_reset(klass)
|
6
|
+
class <<klass
|
7
|
+
def reset_instance
|
8
|
+
Singleton.send :__init__, self
|
9
|
+
self
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
alias_method :included_without_reset, :included
|
14
|
+
alias_method :included, :included_with_reset
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: Create Widgets
|
2
|
+
In order to have widgets
|
3
|
+
As a Widget user
|
4
|
+
I want to be able to create a widget
|
5
|
+
|
6
|
+
Scenario: Create a new widget
|
7
|
+
When I run "widget new 'Widgee 5'"
|
8
|
+
Then the output should contain "You created widget Widgee 5"
|
9
|
+
|
10
|
+
Scenario: Try to create a widget that already exists
|
11
|
+
Given I have a widget named "Widgee 5"
|
12
|
+
When I run "widget new 'Widgee 5'"
|
13
|
+
Then the output should contain "Widgee 5 already exists!"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Feature: Delete Widgets
|
2
|
+
In order to get rid of widgets I don't want
|
3
|
+
As a Widget user
|
4
|
+
I want to be able delete widgets
|
5
|
+
|
6
|
+
Scenario: Removing all widgets
|
7
|
+
When I run "widget reset"
|
8
|
+
Then the output should contain "All widgets destroyed"
|
9
|
+
|
10
|
+
Scenario: Remove a widget by name
|
11
|
+
Given I have a widget named "Widgee 5"
|
12
|
+
When I run "widget destroy 'Widgee 5'"
|
13
|
+
Then the output should contain "Widgee 5 destroyed"
|
14
|
+
|
15
|
+
Scenario: Try to remove a widget that doesn't exist
|
16
|
+
Given There are no widgets
|
17
|
+
When I run "widget destroy 'Widgee 5'"
|
18
|
+
Then the output should contain "There is no Widgee 5 in storage"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Show Widget details
|
2
|
+
In order to know all about my widgets
|
3
|
+
As a Widget user
|
4
|
+
I want to be able to show their details
|
5
|
+
|
6
|
+
Scenario: Show a widget's details
|
7
|
+
Given I have a widget named "Widgee 1"
|
8
|
+
When I run "widget show 'Widgee 1'"
|
9
|
+
Then the output should match /Widgee 1: created:(.*)modified(.*)/
|
10
|
+
|
11
|
+
Scenario: Try to show a widget that doesn't exist
|
12
|
+
Given There are no widgets
|
13
|
+
When I run "widget show 'Widgee 1'"
|
14
|
+
Then the output should contain "There is no Widgee 1 in storage"
|
15
|
+
|
16
|
+
Scenario: Show all widget detail
|
17
|
+
Given I have 5 widgets named "Widgee #{n}"
|
18
|
+
When I run "widget show"
|
19
|
+
Then the output should contain 5 lines matching "Widgee #{n}: created:(.*)modified(.*)"
|
20
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: List Widgets
|
2
|
+
In order to know widgets I have
|
3
|
+
As a Widget user
|
4
|
+
I want to be able to list the names of my widgets
|
5
|
+
|
6
|
+
Scenario: List widget names
|
7
|
+
Given I have 5 widgets named "Widgee #{n}"
|
8
|
+
When I run "widget list"
|
9
|
+
Then the output should contain 5 lines matching "Widgee #{n}"
|
10
|
+
|
11
|
+
Scenario: Listing when there are no widgets
|
12
|
+
Given There are no widgets
|
13
|
+
When I run "widget list"
|
14
|
+
Then the output should contain "<none>"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: Show Widget details
|
2
|
+
In order to make my widgets better
|
3
|
+
As a Widget user
|
4
|
+
I want to be able to upgrade my widgets
|
5
|
+
|
6
|
+
Scenario: Upgrade a widget
|
7
|
+
Given I have a widget named "Widgee 1"
|
8
|
+
When I run "widget upgrade 'Widgee 1'"
|
9
|
+
Then the output should contain "You just gave Widgee 1 a fresh coat of paint!"
|
10
|
+
|
11
|
+
Scenario: Try to upgrade a widget that doesn't exist
|
12
|
+
Given There are no widgets
|
13
|
+
When I run "widget upgrade 'Widgee 1'"
|
14
|
+
Then the output should contain "There is no Widgee 1 in storage"
|
Binary file
|
Binary file
|
data/lib/.DS_Store
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Configure Commandable
|
2
|
+
require 'commandable'
|
3
|
+
Commandable.color_output = true
|
4
|
+
Commandable.verbose_parameters = false
|
5
|
+
Commandable.app_name = "commandable"
|
6
|
+
Commandable.app_info =
|
7
|
+
"""
|
8
|
+
\e[92mWidget!\e[0m - It makes stuff and things! Exclamation!
|
9
|
+
Copyright (c) 2112 Richard Christy & Sal Governale
|
10
|
+
"""
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'hashmodel'
|
2
|
+
require 'singleton'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module Widget
|
6
|
+
class Data
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
def initialize(clean_slate=false)
|
10
|
+
hm = HashModel.new
|
11
|
+
save_widgets(HashModel.new) unless File.exist?(HASHMODEL_FILE) || clean_slate
|
12
|
+
@widgets = load_widgets
|
13
|
+
end
|
14
|
+
|
15
|
+
def length
|
16
|
+
@widgets.length
|
17
|
+
end
|
18
|
+
alias :count :length
|
19
|
+
|
20
|
+
# CRUD
|
21
|
+
|
22
|
+
def create(name)
|
23
|
+
return false unless @widgets.where(name).empty?
|
24
|
+
time_now = now
|
25
|
+
@widgets.add(:name=>name, :created_at=>time_now, :modified_at=>time_now)
|
26
|
+
save_widgets
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
def read(name)
|
31
|
+
@widgets.where(name)
|
32
|
+
end
|
33
|
+
|
34
|
+
def update(name)
|
35
|
+
# note the destructive update! method
|
36
|
+
changed = !(@widgets.update!(name, :modified_at=>now).empty?)
|
37
|
+
save_widgets
|
38
|
+
changed
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete(name)
|
42
|
+
return false if @widgets.where(name).empty?
|
43
|
+
@widgets.delete!(name)
|
44
|
+
save_widgets
|
45
|
+
true
|
46
|
+
end
|
47
|
+
|
48
|
+
# CRUD helpers
|
49
|
+
|
50
|
+
def delete_all
|
51
|
+
@widgets.clear
|
52
|
+
save_widgets
|
53
|
+
end
|
54
|
+
|
55
|
+
def read_all
|
56
|
+
@widgets.clone
|
57
|
+
end
|
58
|
+
|
59
|
+
def reload
|
60
|
+
load_widgets
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
HASHMODEL_FILE = File.expand_path((File.dirname(__FILE__) + '/../../db/hashmodel.dat'))
|
66
|
+
|
67
|
+
def load_widgets
|
68
|
+
Marshal.load(File.open(HASHMODEL_FILE, "r"))
|
69
|
+
end
|
70
|
+
|
71
|
+
def save_widgets(widget=@widgets)
|
72
|
+
File.open(HASHMODEL_FILE, "w"){|file| file.write(Marshal.dump(widget))}
|
73
|
+
end
|
74
|
+
|
75
|
+
def now
|
76
|
+
Time.now.xmlschema(4)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Widget
|
2
|
+
class Viewtroller
|
3
|
+
extend Commandable
|
4
|
+
|
5
|
+
# You shouldn't try to call initialize using Commandable because it creates a new
|
6
|
+
# class automatically for instance methods.
|
7
|
+
#
|
8
|
+
# Think of the classes you let Commandable control as entry points to your app.
|
9
|
+
# Don't try to have Commandable do a lot of class creation and manipulation of
|
10
|
+
# your application, just have the methods you call do all that.
|
11
|
+
def initialize
|
12
|
+
@data = Data.instance
|
13
|
+
end
|
14
|
+
|
15
|
+
command "create a new widget"
|
16
|
+
# The method name "new" makes sense here but notice it's not the class.new method
|
17
|
+
def new(name)
|
18
|
+
if @data.create(name)
|
19
|
+
"You created widget #{name}"
|
20
|
+
else
|
21
|
+
"#{name} already exists!"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
command "add a new widget"
|
25
|
+
alias :add :new
|
26
|
+
|
27
|
+
command "show a widget's details, if no name is given shows all widgets"
|
28
|
+
def show(name=nil)
|
29
|
+
if name
|
30
|
+
widgets = @data.read(name)
|
31
|
+
return "There is no #{name} in storage." if widgets.empty?
|
32
|
+
else
|
33
|
+
widgets = @data.read_all
|
34
|
+
return "There are no widgets in storage." if widgets.empty?
|
35
|
+
end
|
36
|
+
print_widgets(widgets)
|
37
|
+
end
|
38
|
+
|
39
|
+
def print_widgets(widgets)
|
40
|
+
widgets.collect{|widget| " #{widget[:name]}: created: #{widget[:created_at]}; modified: #{widget[:modified_at]};"}
|
41
|
+
end
|
42
|
+
|
43
|
+
command "delete all widgets from storage", :priority=>10
|
44
|
+
def reset
|
45
|
+
@data.delete_all
|
46
|
+
"All widgets destroyed. May they rest in peace."
|
47
|
+
end
|
48
|
+
|
49
|
+
command "return a list of existing widget names", :default
|
50
|
+
def list
|
51
|
+
puts "Widgets:"
|
52
|
+
if @data.length > 0
|
53
|
+
@data.read_all.collect{|widget| " #{widget[:name]}"}
|
54
|
+
else
|
55
|
+
" <none>"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
command "destroy an existing widget", :xor
|
60
|
+
def destroy(name)
|
61
|
+
if @data.delete(name)
|
62
|
+
"#{name} destroyed. You heartless bastard!"
|
63
|
+
else
|
64
|
+
"There is no #{name} in storage."
|
65
|
+
end
|
66
|
+
end
|
67
|
+
command "delete an existing widget", :xor
|
68
|
+
alias :delete :destroy
|
69
|
+
|
70
|
+
command "spend lots of money to update a widget", :xor
|
71
|
+
def upgrade(name)
|
72
|
+
if @data.update(name)
|
73
|
+
"You just gave #{name} a fresh coat of paint!"
|
74
|
+
else
|
75
|
+
"There is no #{name} in storage."
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
data/lib/widget.rb
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# Make sure you load and configure Commandable before loading your
|
2
|
+
# application's files or some of the settings won't work properly
|
3
|
+
require 'widget/commandable_config'
|
4
|
+
|
5
|
+
# Now you can load your app's files
|
6
|
+
require 'widget/widget_viewtroller'
|
7
|
+
require 'widget/widget_data'
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
$:.unshift File.expand_path((File.dirname(__FILE__) + '/../lib'))
|
2
|
+
$:.unshift File.expand_path(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require 'rspec'
|
5
|
+
|
6
|
+
# Allow an instance class to be "reset"
|
7
|
+
require 'singleton'
|
8
|
+
class <<Singleton
|
9
|
+
def included_with_reset(klass)
|
10
|
+
included_without_reset(klass)
|
11
|
+
class <<klass
|
12
|
+
def reset_instance
|
13
|
+
Singleton.send :__init__, self
|
14
|
+
self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
alias_method :included_without_reset, :included
|
19
|
+
alias_method :included, :included_with_reset
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'widget'
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
describe Widget::Data do
|
5
|
+
|
6
|
+
before(:each) {
|
7
|
+
file_name = File.expand_path((File.dirname(__FILE__) + '/../../db/hashmodel.dat'))
|
8
|
+
File.delete(file_name) if File.exists?(file_name)
|
9
|
+
@data = Widget::Data.instance
|
10
|
+
Widget::Data.reset_instance
|
11
|
+
}
|
12
|
+
|
13
|
+
context "when creating a widget" do
|
14
|
+
|
15
|
+
context "and there isn't a widget with that name" do
|
16
|
+
it {lambda{@data.create("Widgee 5"); @data.reload}.should change{@data.count}.by(1)}
|
17
|
+
it { @data.create("Widgee 5").should be_true }
|
18
|
+
|
19
|
+
context "but there is another widget" do
|
20
|
+
before(:each){@data.create("Widgee 1"); @data.reload }
|
21
|
+
it {@data.create("Widgee 5").should be_true }
|
22
|
+
it {@data.create("Widgee 5"); @data.reload; @data.length.should == 2 }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "and there is already a widget with that name" do
|
27
|
+
before(:each){@data.create("Widgee 5")}
|
28
|
+
it "doesn't add a widget" do
|
29
|
+
lambda{@data.create("Widgee 5"); @data.reload}.should_not change{@data.length}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when reading widgets" do
|
36
|
+
|
37
|
+
it "should read by name" do
|
38
|
+
widgee_whatever = "Widgee #{rand(100)}"
|
39
|
+
@data.create(widgee_whatever)
|
40
|
+
@data.reload
|
41
|
+
@data.read(widgee_whatever).to_s.should match(/#{widgee_whatever}/)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should read_all widgets" do
|
45
|
+
4.times { |i| @data.create("Widgee #{i}")}
|
46
|
+
@data.reload
|
47
|
+
4.times { |i| @data.read_all.to_s.should match("Widgee #{i}")}
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when deleteing widgets" do
|
53
|
+
before(:each) do
|
54
|
+
10.times { |i| @data.create("Widgee #{i}") }
|
55
|
+
@data.reload
|
56
|
+
end
|
57
|
+
|
58
|
+
context "and you clear them all" do
|
59
|
+
it{@data.delete_all; @data.reload; @data.length.should == 0}
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'and you delete one by name' do
|
63
|
+
let(:widgee){"Widgee 0"}
|
64
|
+
it {lambda{@data.delete(widgee); @data.reload}.should change{@data.length}.from(10).to(9)}
|
65
|
+
it {@data.delete(widgee); ;@data.reload; @data.read(widgee).should be_empty}
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when upgrading a widget" do
|
71
|
+
before(:each) do
|
72
|
+
3.times { |i| @data.create("Widgee #{i}"); @data.reload }
|
73
|
+
end
|
74
|
+
|
75
|
+
context "and the widget exists" do
|
76
|
+
it {lambda{@data.update("Widgee 1")}.should_not raise_error}
|
77
|
+
it {lambda{@data.update("Widgee 1"); @data.reload}.should change{@data.read("Widgee 1")[0][:modified_at].clone}}
|
78
|
+
it {@data.update("Widgee 1").should be_true}
|
79
|
+
end
|
80
|
+
|
81
|
+
context "but the widget doesn't exist" do
|
82
|
+
it {lambda{@data.update("Widgee 99")}.should_not raise_error}
|
83
|
+
it {@data.update("Widgee 99").should be_false}
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
data/widget.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "widget/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "widget"
|
7
|
+
s.version = Widget::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Mike Bethany"]
|
10
|
+
s.email = ["mikbe.tk@gmail.com"]
|
11
|
+
s.homepage = "http://mikbe.tk"
|
12
|
+
s.summary = %q{A demonstration app showing how to use Commandable and HashModle}
|
13
|
+
s.description = %q{A demonstration app showing how to use Commandable and HashModel. It also serves as a test platform for fleshing out problems and designing new features for the aforementioned libraries.}
|
14
|
+
|
15
|
+
s.add_dependency("hashmodel", "0.4.0.beta2")
|
16
|
+
s.add_dependency("commandable", "0.2.0.beta2")
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: widget
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Mike Bethany
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-03-21 00:00:00.000000000 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hashmodel
|
17
|
+
requirement: &2156171880 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - =
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.4.0.beta2
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2156171880
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: commandable
|
28
|
+
requirement: &2156171180 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - =
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.2.0.beta2
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *2156171180
|
37
|
+
description: A demonstration app showing how to use Commandable and HashModel. It
|
38
|
+
also serves as a test platform for fleshing out problems and designing new features
|
39
|
+
for the aforementioned libraries.
|
40
|
+
email:
|
41
|
+
- mikbe.tk@gmail.com
|
42
|
+
executables:
|
43
|
+
- widget
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- .DS_Store
|
48
|
+
- .gitignore
|
49
|
+
- Gemfile
|
50
|
+
- Gemfile.lock
|
51
|
+
- LICENCE.txt
|
52
|
+
- README.markdown
|
53
|
+
- Rakefile
|
54
|
+
- _test/marshal.rb
|
55
|
+
- _test/widget.hashmodel
|
56
|
+
- autotest/discover.rb
|
57
|
+
- bin/widget
|
58
|
+
- db/hashmodel.dat
|
59
|
+
- features/setup/env.rb
|
60
|
+
- features/step-definitions/step-definitions.rb
|
61
|
+
- features/support/helpers.rb
|
62
|
+
- features/widget_creation.feature
|
63
|
+
- features/widget_deletion.feature
|
64
|
+
- features/widget_details.feature
|
65
|
+
- features/widget_list_names.feature
|
66
|
+
- features/widget_upgrade.feature
|
67
|
+
- images/salandrichard.jpeg
|
68
|
+
- images/salandrichard.jpg
|
69
|
+
- lib/.DS_Store
|
70
|
+
- lib/widget.rb
|
71
|
+
- lib/widget/.DS_Store
|
72
|
+
- lib/widget/commandable_config.rb
|
73
|
+
- lib/widget/version.rb
|
74
|
+
- lib/widget/widget_data.rb
|
75
|
+
- lib/widget/widget_viewtroller.rb
|
76
|
+
- spec/spec_helper.rb
|
77
|
+
- spec/widget/widget_spec.rb
|
78
|
+
- widget.gemspec
|
79
|
+
has_rdoc: true
|
80
|
+
homepage: http://mikbe.tk
|
81
|
+
licenses: []
|
82
|
+
post_install_message:
|
83
|
+
rdoc_options: []
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ! '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 1.6.2
|
101
|
+
signing_key:
|
102
|
+
specification_version: 3
|
103
|
+
summary: A demonstration app showing how to use Commandable and HashModle
|
104
|
+
test_files:
|
105
|
+
- features/setup/env.rb
|
106
|
+
- features/step-definitions/step-definitions.rb
|
107
|
+
- features/support/helpers.rb
|
108
|
+
- features/widget_creation.feature
|
109
|
+
- features/widget_deletion.feature
|
110
|
+
- features/widget_details.feature
|
111
|
+
- features/widget_list_names.feature
|
112
|
+
- features/widget_upgrade.feature
|
113
|
+
- spec/spec_helper.rb
|
114
|
+
- spec/widget/widget_spec.rb
|