ruby-trello 0.1.1 → 0.2.0

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/README.md CHANGED
@@ -9,10 +9,11 @@ Seriously, [check it out](http://www.trello.com/).
9
9
 
10
10
  ## Installation
11
11
 
12
- Full disclosure: It doesn't presently work. I'm in the process of implementing
13
- the specs and the functionality. But if you want to check it out, clone the
14
- repo for now. I will produce a gem when it's at least minimally usable. When
15
- that is the case, I'll post that information here.
12
+ ```
13
+ # gem install ruby-trello
14
+ ```
15
+
16
+ Full Disclosure: This library is not complete, but it does function enough to be useful.
16
17
 
17
18
  ## Contributing
18
19
 
data/lib/trello.rb CHANGED
@@ -3,14 +3,17 @@
3
3
  # Use and distribution terms may be found in the file LICENSE included in this distribution.
4
4
 
5
5
  require 'oauth'
6
- require 'yajl'
6
+ require 'json'
7
7
 
8
8
  module Trello
9
+ autoload :Action, 'trello/action'
9
10
  autoload :BasicData, 'trello/basic_data'
10
11
  autoload :Board, 'trello/board'
11
12
  autoload :Card, 'trello/card'
12
13
  autoload :Client, 'trello/client'
14
+ autoload :Item, 'trello/item'
15
+ autoload :ItemState, 'trello/item_state'
13
16
  autoload :List, 'trello/list'
14
17
  autoload :Member, 'trello/member'
15
18
  autoload :Organization, 'trello/organization'
16
- end
19
+ end
@@ -0,0 +1,48 @@
1
+ # Ruby wrapper around the Trello API
2
+ # Copyright (c) 2012, Jeremy Tregunna
3
+ # Use and distribution terms may be found in the file LICENSE included in this distribution.
4
+
5
+ module Trello
6
+ class Action < BasicData
7
+ class << self
8
+ def find(id)
9
+ super(:actions, id)
10
+ end
11
+ end
12
+
13
+ # Fields
14
+
15
+ def id
16
+ fields['id']
17
+ end
18
+
19
+ def type
20
+ fields['type']
21
+ end
22
+
23
+ def data
24
+ fields['data']
25
+ end
26
+
27
+ # Links to other data structures
28
+
29
+ def board
30
+ response = Client.query("/1/actions/#{id}/board")
31
+ Board.new(JSON.parse(response.read_body))
32
+ end
33
+
34
+ def card
35
+ response = Client.query("/1/actions/#{id}/card")
36
+ Card.new(JSON.parse(response.read_body))
37
+ end
38
+
39
+ def list
40
+ response = Client.query("/1/actions/#{id}/list")
41
+ List.new(JSON.parse(response.read_body))
42
+ end
43
+
44
+ def member_creator
45
+ Member.find(fields['idMemberCreator'])
46
+ end
47
+ end
48
+ end
@@ -9,7 +9,7 @@ module Trello
9
9
  class << self
10
10
  def find(path, id)
11
11
  response = Client.query("/1/#{path}/#{id}")
12
- new(Yajl::Parser.parse(response.read_body))
12
+ new(JSON.parse(response.read_body))
13
13
  end
14
14
  end
15
15
 
data/lib/trello/board.rb CHANGED
@@ -7,7 +7,7 @@ module Trello
7
7
  class << self
8
8
  def find(id)
9
9
  response = Client.query("/1/boards/#{id}")
10
- new(Yajl::Parser.parse(response.read_body))
10
+ new(JSON.parse(response.read_body))
11
11
  end
12
12
  end
13
13
 
@@ -35,14 +35,34 @@ module Trello
35
35
 
36
36
  # Links to other data structures
37
37
 
38
+ def actions
39
+ response = Client.query("/1/boards/#{id}/actions")
40
+ JSON.parse(response.read_body).map do |action_fields|
41
+ Action.new(action_fields)
42
+ end
43
+ end
44
+
38
45
  def cards
39
- response = Client.query("/1/boards/#{id}/cards/all")
40
- all_cards = Yajl::Parser.parse(response.read_body)
41
- all_cards.map do |card_fields|
46
+ response = Client.query("/1/boards/#{id}/cards/all")
47
+ JSON.parse(response.read_body).map do |card_fields|
42
48
  Card.new(card_fields)
43
49
  end
44
50
  end
45
51
 
52
+ def lists
53
+ response = Client.query("/1/boards/#{id}/lists/all")
54
+ JSON.parse(response.read_body).map do |list_fields|
55
+ List.new(list_fields)
56
+ end
57
+ end
58
+
59
+ def members
60
+ response = Client.query("/1/boards/#{id}/members/all")
61
+ JSON.parse(response.read_body).map do |member_fields|
62
+ Member.new(member_fields)
63
+ end
64
+ end
65
+
46
66
  def organization
47
67
  Organization.find(fields['idOrganization'])
48
68
  end
data/lib/trello/card.rb CHANGED
@@ -34,15 +34,38 @@ module Trello
34
34
 
35
35
  # Links to other data structures
36
36
 
37
+ def actions
38
+ response = Client.query("/1/cards/#{id}/actions")
39
+ JSON.parse(response.read_body).map do |action_fields|
40
+ Action.new(action_fields)
41
+ end
42
+ end
43
+
37
44
  def board
38
45
  Board.find(fields['idBoard'])
39
46
  end
40
47
 
48
+ def checklists
49
+ response = Client.query("/1/cards/#{id}/checklists")
50
+ JSON.parse(response.read_body).map do |checklist_fields|
51
+ Checklist.new(checklist_fields)
52
+ end
53
+ end
54
+
55
+ def list
56
+ List.find(fields['idList'])
57
+ end
58
+
41
59
  def members
42
60
  fields['idMembers'].map do |member_id|
43
- response = Client.query("/1/members/#{member_id}")
44
- Member.new(Yajl::Parser.parse(response.read_body))
61
+ response = Client.query("/1/members/#{member_id}")
62
+ Member.new(JSON.parse(response.read_body))
45
63
  end
46
64
  end
65
+
66
+ # Add a comment
67
+ def comment(text)
68
+ response = Client.query("/1/cards/#{id}/actions/comments", :method => :put, :params => { :text => text })
69
+ end
47
70
  end
48
71
  end
@@ -0,0 +1,57 @@
1
+ # Ruby wrapper around the Trello API
2
+ # Copyright (c) 2012, Jeremy Tregunna
3
+ # Use and distribution terms may be found in the file LICENSE included in this distribution.
4
+
5
+ module Trello
6
+ class Checklist < BasicData
7
+ class << self
8
+ def find(id)
9
+ super(:checklists, id)
10
+ end
11
+ end
12
+
13
+ # Fields
14
+
15
+ def id
16
+ fields['id']
17
+ end
18
+
19
+ def name
20
+ fields['name']
21
+ end
22
+
23
+ def description
24
+ fields['desc']
25
+ end
26
+
27
+ def closed?
28
+ fields['closed']
29
+ end
30
+
31
+ def url
32
+ fields['url']
33
+ end
34
+
35
+ # Links to other data structures
36
+
37
+ def items
38
+ fields['checkItems'].map do |item_fields|
39
+ Item.new(item_fields)
40
+ end
41
+ end
42
+
43
+ def board
44
+ Board.find(fields['idBoard'])
45
+ end
46
+
47
+ def list
48
+ List.find(fields['idList'])
49
+ end
50
+
51
+ def members
52
+ fields['idMembers'].map do |member_id|
53
+ Member.find(member_id)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,27 @@
1
+ # Ruby wrapper around the Trello API
2
+ # Copyright (c) 2012, Jeremy Tregunna
3
+ # Use and distribution terms may be found in the file LICENSE included in this distribution.
4
+
5
+ module Trello
6
+ class Item < BasicData
7
+ class << self
8
+ def find(nothing)
9
+ raise 'This operation does not make sense'
10
+ end
11
+ end
12
+
13
+ # Fields
14
+
15
+ def id
16
+ fields['id']
17
+ end
18
+
19
+ def name
20
+ fields['name']
21
+ end
22
+
23
+ def type
24
+ fields['type']
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ # Ruby wrapper around the Trello API
2
+ # Copyright (c) 2012, Jeremy Tregunna
3
+ # Use and distribution terms may be found in the file LICENSE included in this distribution.
4
+
5
+ module Trello
6
+ class ItemState < BasicData
7
+ class << self
8
+ def find(nothing)
9
+ raise 'This operation does not make sense'
10
+ end
11
+ end
12
+
13
+ # Fields
14
+
15
+ def id
16
+ fields['id']
17
+ end
18
+
19
+ def state
20
+ fields['state']
21
+ end
22
+
23
+ # Until #item is implemented, this will do
24
+ def item_id
25
+ fields['idItem']
26
+ end
27
+
28
+ # Links to other data structures
29
+
30
+ def item
31
+ # Nothing here for now. I will implement it myself later, but Trello really
32
+ # needs an API to query check items in my estimation. Otherwise, the "idCheckItem"
33
+ # key serves no good purpose. I'd have to know what checklist this state belongs
34
+ # to, and then query all of its items, comparing the ID as I go. O(n) at the best
35
+ # of times. If I don't have the checklist, then we're O(m*n^2). Horrible.
36
+ end
37
+ end
38
+ end
data/lib/trello/list.rb CHANGED
@@ -26,6 +26,13 @@ module Trello
26
26
 
27
27
  # Links to other data structures
28
28
 
29
+ def actions
30
+ response = Client.query("/1/lists/#{id}/actions")
31
+ JSON.parse(response.read_body).map do |action_fields|
32
+ Action.new(action_fields)
33
+ end
34
+ end
35
+
29
36
  def board
30
37
  Board.find(fields['idBoard'])
31
38
  end
data/lib/trello/member.rb CHANGED
@@ -42,18 +42,30 @@ module Trello
42
42
 
43
43
  # Links to other data structures
44
44
 
45
+ def actions
46
+ response = Client.query("/1/members/#{username}/actions")
47
+ JSON.parse(response.read_body).map do |action_fields|
48
+ Action.new(action_fields)
49
+ end
50
+ end
51
+
45
52
  def boards
46
- response = Client.query("/1/members/#{username}/boards/all")
47
- all_boards = Yajl::Parser.parse(response.read_body)
48
- all_boards.map do |board_fields|
53
+ response = Client.query("/1/members/#{username}/boards/all")
54
+ JSON.parse(response.read_body).map do |board_fields|
49
55
  Board.new(board_fields)
50
56
  end
51
57
  end
52
58
 
59
+ def cards
60
+ response = Client.query("/1/members/#{username}/cards/all")
61
+ JSON.parse(response.read_body).map do |card_fields|
62
+ Card.new(card_fields)
63
+ end
64
+ end
65
+
53
66
  def organizations
54
67
  response = Client.query("/1/members/#{username}/organizations/all")
55
- all_orgs = Yajl::Parser.parse(response.read_body)
56
- all_orgs.map do |org_fields|
68
+ JSON.parse(response.read_body).map do |org_fields|
57
69
  Organization.new(org_fields)
58
70
  end
59
71
  end
@@ -35,5 +35,28 @@ module Trello
35
35
  def url
36
36
  @fields['url']
37
37
  end
38
+
39
+ # Links to other data structures
40
+
41
+ def actions
42
+ response = Client.query("/1/organizations/#{id}/actions")
43
+ JSON.parse(response.read_body).map do |action_fields|
44
+ Action.new(action_fields)
45
+ end
46
+ end
47
+
48
+ def boards
49
+ response = Client.query("/1/organizations/#{id}/boards/all")
50
+ JSON.parse(response.read_body).map do |board_fields|
51
+ Board.new(board_fields)
52
+ end
53
+ end
54
+
55
+ def members
56
+ response = Client.query("/1/organizations/#{id}/members/all")
57
+ JSON.parse(response.read_body).map do |member_fields|
58
+ Member.new(member_fields)
59
+ end
60
+ end
38
61
  end
39
62
  end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ module Trello
4
+ describe Action do
5
+ include Helpers
6
+
7
+ before(:all) do
8
+ Client.public_key = 'dummy'
9
+ Client.secret = 'dummy'
10
+ end
11
+
12
+ before(:each) do
13
+ stub_request(:get, "https://api.trello.com/1/actions/abcdef123456789123456789?").
14
+ with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
15
+ to_return(:status => 200, :headers => {}, :body => JSON.generate(actions_details.first))
16
+
17
+ @action = Action.find('abcdef123456789123456789')
18
+ end
19
+
20
+ context "fields" do
21
+ before(:all) do
22
+ @detail = actions_details.first
23
+ end
24
+
25
+ it "gets its id" do
26
+ @action.id.should == @detail['id']
27
+ end
28
+
29
+ it "gets its type" do
30
+ @action.type.should == @detail['type']
31
+ end
32
+
33
+ it "has the same data" do
34
+ @action.data.should == @detail['data']
35
+ end
36
+ end
37
+ end
38
+ end
data/spec/board_spec.rb CHANGED
@@ -12,7 +12,7 @@ module Trello
12
12
  before(:each) do
13
13
  stub_request(:get, "https://api.trello.com/1/boards/abcdef123456789123456789?").
14
14
  with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
15
- to_return(:status => 200, :headers => {}, :body => Yajl::Encoder.encode(boards_details.first))
15
+ to_return(:status => 200, :headers => {}, :body => JSON.generate(boards_details.first))
16
16
 
17
17
  @board = Board.find('abcdef123456789123456789')
18
18
  end
data/spec/card_spec.rb CHANGED
@@ -12,7 +12,7 @@ module Trello
12
12
  before(:each) do
13
13
  stub_request(:get, "https://api.trello.com/1/cards/abcdef123456789123456789?").
14
14
  with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
15
- to_return(:status => 200, :headers => {}, :body => Yajl::Encoder.encode(cards_details.first))
15
+ to_return(:status => 200, :headers => {}, :body => JSON.generate(cards_details.first))
16
16
 
17
17
  @card = Card.find('abcdef123456789123456789')
18
18
  end
@@ -43,7 +43,7 @@ module Trello
43
43
  it "has a board" do
44
44
  stub_request(:get, "https://api.trello.com/1/boards/abcdef123456789123456789?").
45
45
  with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
46
- to_return(:status => 200, :headers => {}, :body => Yajl::Encoder.encode(boards_details.first))
46
+ to_return(:status => 200, :headers => {}, :body => JSON.generate(boards_details.first))
47
47
 
48
48
  @card.board.should_not be_nil
49
49
  end
@@ -53,7 +53,7 @@ module Trello
53
53
  it "has a list of members" do
54
54
  stub_request(:get, "https://api.trello.com/1/boards/abcdef123456789123456789?").
55
55
  with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
56
- to_return(:status => 200, :headers => {}, :body => Yajl::Encoder.encode(boards_details.first))
56
+ to_return(:status => 200, :headers => {}, :body => JSON.generate(boards_details.first))
57
57
  stub_request(:get, "https://api.trello.com/1/members/abcdef123456789123456789?").
58
58
  with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
59
59
  to_return(:status => 200, :headers => {}, :body => user_payload)
File without changes
data/spec/item_spec.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ module Trello
4
+ describe Item do
5
+ before(:all) do
6
+ @detail = {
7
+ 'id' => "abcdef123456789123456789",
8
+ 'name' => "test item",
9
+ 'type' => "check"
10
+ }
11
+
12
+ @item = Item.new(@detail)
13
+ end
14
+
15
+ it "gets its id" do
16
+ @item.id.should == @detail['id']
17
+ end
18
+
19
+ it "gets its name" do
20
+ @item.name.should == @detail['name']
21
+ end
22
+
23
+ it "knows its type" do
24
+ @item.type.should == @detail['type']
25
+ end
26
+ end
27
+ end
File without changes
data/spec/list_spec.rb CHANGED
@@ -12,10 +12,10 @@ module Trello
12
12
  before(:each) do
13
13
  stub_request(:get, "https://api.trello.com/1/lists/abcdef123456789123456789?").
14
14
  with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
15
- to_return(:status => 200, :headers => {}, :body => Yajl::Encoder.encode(lists_details.first))
15
+ to_return(:status => 200, :headers => {}, :body => JSON.generate(lists_details.first))
16
16
  stub_request(:get, "https://api.trello.com/1/boards/abcdef123456789123456789?").
17
17
  with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
18
- to_return(:status => 200, :headers => {}, :body => Yajl::Encoder.encode(boards_details.first))
18
+ to_return(:status => 200, :headers => {}, :body => JSON.generate(boards_details.first))
19
19
 
20
20
  @list = List.find("abcdef123456789123456789")
21
21
  end
data/spec/member_spec.rb CHANGED
@@ -20,8 +20,13 @@ module Trello
20
20
  end
21
21
 
22
22
  context "actions" do
23
- # This spec needs a better name
24
- it "retrieves a list of actions"
23
+ it "retrieves a list of actions" do
24
+ stub_request(:get, "https://api.trello.com/1/members/me/actions?").
25
+ with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
26
+ to_return(:status => 200, :headers => {}, :body => actions_payload)
27
+
28
+ @member.actions.count.should be > 0
29
+ end
25
30
  end
26
31
 
27
32
  context "boards" do
data/spec/spec_helper.rb CHANGED
@@ -29,7 +29,7 @@ module Helpers
29
29
  end
30
30
 
31
31
  def user_payload
32
- Yajl::Encoder.encode(user_details)
32
+ JSON.generate(user_details)
33
33
  end
34
34
 
35
35
  def boards_details
@@ -44,7 +44,7 @@ module Helpers
44
44
  end
45
45
 
46
46
  def boards_payload
47
- Yajl::Encoder.encode(boards_details)
47
+ JSON.generate(boards_details)
48
48
  end
49
49
 
50
50
  def lists_details
@@ -58,7 +58,7 @@ module Helpers
58
58
  end
59
59
 
60
60
  def lists_payload
61
- Yajl::Encoder.encode(lists_details)
61
+ JSON.generate(lists_details)
62
62
  end
63
63
 
64
64
  def cards_details
@@ -75,7 +75,7 @@ module Helpers
75
75
  end
76
76
 
77
77
  def cards_payload
78
- Yajl::Encoder.encode(cards_details)
78
+ JSON.generate(cards_details)
79
79
  end
80
80
 
81
81
  def orgs_details
@@ -89,6 +89,32 @@ module Helpers
89
89
  end
90
90
 
91
91
  def orgs_payload
92
- Yajl::Encoder.encode(orgs_details)
92
+ JSON.generate(orgs_details)
93
+ end
94
+
95
+ def actions_details
96
+ [{
97
+ "id" => "4ee2482134a81a757a08af47",
98
+ "idMemberCreator" => "4ec33ef93a7537000010676d",
99
+ "data"=> {
100
+ "card" => {
101
+ "id" => "4ee2482134a81a757a08af45",
102
+ "name" => "Bytecode outputter"
103
+ },
104
+ "board" => {
105
+ "id" => "4ec54f2f73820a0dea0d1f0e",
106
+ "name" => "Caribou VM"
107
+ },
108
+ "list" => {
109
+ "id" => "4ee238b034a81a757a05cda0",
110
+ "name" => "Assembler"
111
+ }
112
+ },
113
+ "type" => "createCard"
114
+ }]
115
+ end
116
+
117
+ def actions_payload
118
+ JSON.generate(actions_details)
93
119
  end
94
120
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-trello
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-01-07 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yajl-ruby
16
- requirement: &70325350827020 !ruby/object:Gem::Requirement
16
+ requirement: &70240457388560 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.1.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70325350827020
24
+ version_requirements: *70240457388560
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: oauth
27
- requirement: &70325350826560 !ruby/object:Gem::Requirement
27
+ requirement: &70240457399940 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.4.5
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70325350826560
35
+ version_requirements: *70240457399940
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: addressable
38
- requirement: &70325350826100 !ruby/object:Gem::Requirement
38
+ requirement: &70240457481800 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 2.2.6
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70325350826100
46
+ version_requirements: *70240457481800
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
- requirement: &70325350825640 !ruby/object:Gem::Requirement
49
+ requirement: &70240457630780 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: 1.0.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70325350825640
57
+ version_requirements: *70240457630780
58
58
  description: A wrapper around the trello.com API.
59
59
  email: jeremy@tregunna.ca
60
60
  executables: []
@@ -62,18 +62,26 @@ extensions: []
62
62
  extra_rdoc_files:
63
63
  - README.md
64
64
  files:
65
+ - lib/trello/action.rb
65
66
  - lib/trello/basic_data.rb
66
67
  - lib/trello/board.rb
67
68
  - lib/trello/card.rb
69
+ - lib/trello/checklist.rb
68
70
  - lib/trello/client.rb
71
+ - lib/trello/item.rb
72
+ - lib/trello/item_state.rb
69
73
  - lib/trello/list.rb
70
74
  - lib/trello/member.rb
71
75
  - lib/trello/organization.rb
72
76
  - lib/trello.rb
73
77
  - README.md
78
+ - spec/action_spec.rb
74
79
  - spec/board_spec.rb
75
80
  - spec/card_spec.rb
81
+ - spec/checklist_spec.rb
76
82
  - spec/client_spec.rb
83
+ - spec/item_spec.rb
84
+ - spec/item_state_spec.rb
77
85
  - spec/list_spec.rb
78
86
  - spec/member_spec.rb
79
87
  - spec/organization_spec.rb
@@ -104,9 +112,13 @@ signing_key:
104
112
  specification_version: 3
105
113
  summary: A wrapper around the trello.com API.
106
114
  test_files:
115
+ - spec/action_spec.rb
107
116
  - spec/board_spec.rb
108
117
  - spec/card_spec.rb
118
+ - spec/checklist_spec.rb
109
119
  - spec/client_spec.rb
120
+ - spec/item_spec.rb
121
+ - spec/item_state_spec.rb
110
122
  - spec/list_spec.rb
111
123
  - spec/member_spec.rb
112
124
  - spec/organization_spec.rb