widget 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/.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
|