Permalink
Browse files

Implemented Scenario: Adding a bug

  • Loading branch information...
1 parent cdcc85e commit 525eddc3ff3dfc0e35f067bb75aa95a81525bc04 @bkeepers committed Sep 6, 2011
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -18,11 +18,12 @@ var NewStoryController = Spine.Controller.create({
render: function() {
this.html(this.template());
+ this.el.find('.segmented input:radio:checked').trigger('change');
return this;
},
template: function() {
template = Handlebars.compile($('#new-story-template').html());
- return template();
+ return template(new Story());
}
});
@@ -13,6 +13,7 @@ var StoryController = Spine.Controller.create({
render: function() {
this.html(this.template());
+ this.el.find('.segmented input:radio:checked').trigger('change');
return this;
},
@@ -1,4 +1,4 @@
-var Story = Spine.Model.setup('Story', 'description', 'status', 'position', 'owner_email');
+var Story = Spine.Model.setup('Story', 'description', 'type', 'status', 'position', 'owner_email');
Story.extend(Spine.Model.Ajax).extend({
url: '/stories'
@@ -17,6 +17,18 @@ Story.include({
owner: function() {
return User.findByAttribute('email', this.owner_email);
+ },
+
+ isFeature: function() {
+ return this.type == 'feature' || !this.type;
+ },
+
+ isBug: function() {
+ return this.type == 'bug';
+ },
+
+ isRelease: function() {
+ return this.type == 'release';
}
});
@@ -0,0 +1,4 @@
+$('.segmented input:radio').live('change', function() {
+ $(this).closest('.segmented').find('label.selected').removeClass('selected');
+ $(this).closest('label').addClass('selected');
+});
@@ -27,6 +27,7 @@ body {
@import 'mixins/buttons';
@import 'classes/icons';
@import 'classes/labels';
+@import 'classes/segmented';
@import 'elements/header';
@import 'elements/nav';
@import 'elements/list';
@@ -0,0 +1,59 @@
+.segmented {
+ display: inline-block;
+ margin: 6px 0;
+ @include border-radius(4px);
+ @include box-shadow(0 1px 0 rgba(255,255,255,0.5));
+ border: 1px solid rgba(0,0,0,0.3);
+
+ label {
+ display: block;
+ float:left;
+ line-height:22px;
+ padding: 0 12px;
+ color: #262626;
+ font-weight: bold;
+ border-right: 1px solid #777;
+ border-left: 1px solid rgba(255,255,255,0.5);
+ text-shadow: 0 1px 0 #fff;
+ background: #eee;
+ background: -webkit-linear-gradient(#eee, #ccc 80%);
+ background: -moz-linear-gradient(top, #fff, #ddd);
+
+ &:first-child {
+ -webkit-border-top-left-radius: 3px;
+ -webkit-border-bottom-left-radius: 3px;
+ -moz-border-radius-topleft: 3px;
+ -moz-border-radius-bottomleft: 3px;
+ border-top-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+ border-left:0;
+ }
+
+ &:last-child {
+ -webkit-border-top-right-radius: 3px;
+ -webkit-border-bottom-right-radius: 3px;
+ -moz-border-radius-topright: 3px;
+ -moz-border-radius-bottomright: 3px;
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+ border-right:0;
+ }
+
+ &:active, &.selected {;
+ border-left:0;
+ padding-left:13px;
+ background: #ccc;
+ background: -webkit-linear-gradient(#ccc, #aaa 80%);
+ background: -moz-linear-gradient(top, #ddd, #bbb);
+ text-shadow: 0 1px 0 #eee;
+ -webkit-box-shadow: inset 0 1px 4px rgba(0,0,0,0.3);
+ -moz-box-shadow: inset 0 1px 4px rgba(0,0,0,0.3);
+ box-shadow: inset 0 1px 4px rgba(0,0,0,0.3);
+ }
+
+ input[type=radio] {
+ position:absolute;
+ left:-5000px;
+ }
+ }
+}
@@ -7,8 +7,11 @@
section {
padding:15px;
}
+ header {
+ text-align:center;
+ }
form {
- .scrollable {
+ .content {
bottom:36px;
left:0;
overflow-y:auto;
@@ -31,10 +31,9 @@
display:block;
color:inherit;
text-decoration:none;
-
- &:hover {
- background-color:rgb(248,248,248);
- }
+ }
+ &:hover {
+ background-color:rgb(248,248,248);
}
.owner {
@@ -44,19 +43,23 @@
text-shadow:none;
}
+ &.bug a {
+ background: url(icon-bug.png) no-repeat 14px 10px;
+ }
+
&.approved {
background-color: rgb(238,238,238);
color: rgb(150,150,150);
- a:hover {
+ &:hover {
background-color: rgb(235, 235, 235);
}
.owner {
color:inherit;
}
}
- &.active, &.active a:hover {
+ &.active, &.active:hover {
background: -webkit-linear-gradient(top, rgb(74, 171, 239) 0%, rgb(1,136,222) 80%);
color:#fff;
text-shadow: 0px 1px 1px rgba(0,0,0,0.5);
@@ -5,4 +5,13 @@
-ms-border-radius: $radius;
-khtml-border-radius: $radius;
border-radius: $radius;
+}
+
+@mixin box-shadow($values) {
+ -webkit-box-shadow: $values;
+ -moz-box-shadow: $values;
+ -o-box-shadow: $values;
+ -ms-box-shadow: $values;
+ -khtml-box-shadow: $values;
+ box-shadow: $values;
}
@@ -213,4 +213,10 @@ def with_scope(locator)
When 'I debug' do
debugger
true
-end
+end
+
+Then /^the "([^"]*)" radio should be "([^"]*)"$/ do |field, value|
+ field = find(:xpath, XPath::HTML.field(field, :checked => true))
+ field.value.should == value
+end
+
@@ -11,6 +11,18 @@ Feature: Stories
When I go to the home page
Then I should see "Set up integration tests"
+ Scenario: Adding a bug
+ When I go to the home page
+ And I follow "New Story"
+ And I choose "Bug" within the story editor
+ And I fill in "description" with "Sometimes stuff blows up" within the story editor
+ And I press "Save" within the story editor
+ Then I should see "Sometimes stuff blows up"
+
+ When I go to the home page
+ And I follow "Sometimes stuff blows up"
+ And the "type" radio should be "bug" within the story editor
+
Scenario: Updating a story
Given the following story exists:
| description |
@@ -21,6 +33,7 @@ Feature: Stories
When I fill in "description" with "User can update a story" within the story editor
And I select "Started" from "status" within the story editor
+ And I choose "Bug" within the story editor
And I press "Save" within the story editor
Then I should see "User can update a story" within the story list
@@ -30,6 +43,9 @@ Feature: Stories
Then I should see "User can update a story"
And I should not see "Updating a story"
+ When I follow "User can update a story"
+ Then the "type" radio should be "bug" within the story editor
+
Scenario: Deleting a story
Given the following story exists:
| description |
View
@@ -6,6 +6,7 @@ class Story
store :git, Gaskit.repo, :branch => 'gaskit', :path => 'stories'
attribute :description, String
+ attribute :type, String, :default => 'feature'
attribute :owner_email, String
attribute :status, String, :default => 'pending'
attribute :position, Float
@@ -20,6 +21,14 @@ def self.all
end.sort_by {|m| m.position || 1 }
end
+ def type
+ self[:type]
+ end
+
+ def type=(type)
+ self[:type] = type
+ end
+
private
def self.contents
@@ -1,11 +1,27 @@
<form action="/stories/{{id}}" method="PUT">
<header>
+ <div class="segmented">
+ <label>
+ <input type="radio" name="type" value="feature"{{#f isFeature}} checked{{/f}}>
+ Feature
+ </label>
+ <label>
+ <input type="radio" name="type" value="bug"{{#f isBug}} checked{{/f}}>
+ Bug
+ </label>
+ <label>
+ <input type="radio" name="type" value="release"{{#f isRelease}} checked{{/f}}>
+ Release
+ </label>
+ </div>
+
+
<ul>
<li><button type="submit">Save</button></li>
</ul>
</header>
- <div class="scrollable">
+ <div class="content">
<h2>Description</h2>
<section>
<textarea name="description">{{description}}</textarea>
@@ -1,8 +1,26 @@
<form action="/stories" id="new_story" method="POST">
<header>
+ <div class="segmented">
+ <label>
+ <input type="radio" name="type" value="feature" checked>
+ Feature
+ </label>
+ <label>
+ <input type="radio" name="type" value="bug">
+ Bug
+ </label>
+ <label>
+ <input type="radio" name="type" value="release">
+ Release
+ </label>
+ </div>
+
<ul><li><button type="submit">Save</button></li></ul>
</header>
<div class="content">
- <textarea name="description"></textarea>
+ <h2>Description</h2>
+ <section>
+ <textarea name="description"></textarea>
+ </section>
</div>
</form>
@@ -1,4 +1,4 @@
-<li id="story-{{id}}" class="story {{status}}">
+<li id="story-{{id}}" class="story {{status}} {{type}}">
<a href="#/stories/{{id}}">
{{title}}

0 comments on commit 525eddc

Please sign in to comment.