so_far_so_good 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9521b2d0cb4777d080a409ff1631f60c70bff35e
4
- data.tar.gz: 248816b662685c753f72d37e0ee42be875f7af8b
3
+ metadata.gz: c0ca888a79d1abea3f16bac6d5fa7706cc1b2c10
4
+ data.tar.gz: fa8aa37486a39179474fdbef201352217ae3f596
5
5
  SHA512:
6
- metadata.gz: ef818c8d2c48bad1bd567654aa5f0e16b91063575d414afd63153d019239801ef160181b890072c84c5eeed87a89ef1fa26adf849fd72e054d266052a2f35f41
7
- data.tar.gz: 1cdf454823ef2468c531c86d06e9e3a7a4e2e5e6b58e5bafb81a828f0aa9309b6c2ec38271e9b0da355aa3cea0308f5e16ad54606c11349aa96e39ba54a530e2
6
+ metadata.gz: 2f54bb0f2a247aaeb8a2b4199f5c98d573e815494634821f1f6c7c8a9c2c4d33b40519723b8bc1a56767d8d4d0a31bfff7c9ef1388d7da2053596dfadeadd545
7
+ data.tar.gz: 42aa3e271d119b52e5ed3a646838e82f5a8c5a830a246ff1f5bab5dfbde384c03d61a11d0ccf7b3b35d8e8ffa396b3fb9f2f17d79d698d06937a5b11342945d0
data/.travis.yml ADDED
@@ -0,0 +1,2 @@
1
+ langauage: ruby
2
+ script: "script/cibuild"
data/README.md CHANGED
@@ -2,21 +2,96 @@
2
2
 
3
3
  A Ruby Gem to parse and manipulate the Federal Acquisition Regulation
4
4
 
5
+ [![Gem Version](https://badge.fury.io/rb/so_far_so_good.svg)](http://badge.fury.io/rb/so_far_so_good) [![Build Status](https://travis-ci.org/benbalter/so_far_so_good.svg)](https://travis-ci.org/benbalter/so_far_so_good)
6
+
5
7
  ## What it does
6
8
 
7
- Right now, it simply gives you a hash of FAR 52.2x clauses and their description, but soon, much, much more!
9
+ So FAR so Good is a Ruby Gem to interact with the Federal Acquisition Regulation. Right now, it only supports section 52.20x, the FAR standard contracting clause templates.
10
+
11
+ For any contract clause, it will provide:
12
+
13
+ * The section number
14
+ * The subject
15
+ * Whether it's a reserved section
16
+ * The formal citation
17
+ * The body (full clause text)
18
+ * The extract (what's inserted into the contract)
19
+
20
+ It will give you access to this information in object-oriented Ruby, as JSON, or as a markdown table for use elsewhere.
8
21
 
9
22
  ## Usage
10
23
 
24
+ ### Basic usage
25
+
11
26
  ```ruby
12
- SoFarSoGood.clauses
13
- > {"52.200"=>"Scope of subpart.",
14
- "52.201"=>"[Reserved]",
15
- "52.202-1"=>"Definitions.",
16
- "52.203-1"=>"[Reserved]",...
17
- }
27
+ # Get all clauses
28
+ clauses = SoFarSoGood.clauses
29
+ => [#<SoFarSoGood::Clause @number="52.200" @subject="Scope of subpart." @reserved="false",
30
+ #<SoFarSoGood::Clause @number="52.202-1" @subject="Definitions." @reserved="false",
31
+ #<SoFarSoGood::Clause @number="52.203-1" @subject="[Reserved]" @reserved="true",
32
+ #<SoFarSoGood::Clause @number="52.203-2" @subject="Certificate of Independent Price Determination." @reserved="false",
33
+ #<SoFarSoGood::Clause @number="52.203-3" @subject="Gratuities." @reserved="false", ... ]
34
+
35
+ # Get a list of clause numbers
36
+ SoFarSoGood::Clauses.numbers
37
+ => ["52.200", "52.202-1", "52.203-1", "52.203-2", "52.203-3", "52.203-4", "52.203-5", ... ]
38
+
39
+ # Get a list of clause numbers, excluding reserved clauses
40
+ SoFarSoGood::Clauses.numbers(:exclude_reserved => true)
41
+ => ["52.200", "52.202-1", "52.203-1", "52.203-2", "52.203-3", "52.203-4", "52.203-5", ... ]
42
+
43
+ # Get a list of clause subjects
44
+ SoFarSoGood::Clauses.subjects
45
+ => ["Scope of subpart.", "Definitions.", "[Reserved]", "Certificate of Independent Price Determination.", ... ]
18
46
  ```
19
47
 
48
+ ### Working with individual clauses
49
+
50
+ ```ruby
51
+ # Get a specific clause
52
+ clause = SoFarSoGood::Clauses["52.202-1"]
53
+ => #<SoFarSoGood::Clause @number="52.202-1" @subject="Definitions." @reserved="false"
54
+
55
+ clause.number
56
+ => "52.202-1"
57
+
58
+ clause.subject
59
+ => "Definitions"
60
+
61
+ clause.reserved?
62
+ => false
63
+
64
+ clause.citation
65
+ => "[69 FR 34228, June 18, 2004]"
66
+
67
+ # The full clause body
68
+ clause.body
69
+ => "As prescribed in 2.201, insert the following clause:..."
70
+
71
+ # The actual clause text to be inserted in the contract
72
+ clause.extract
73
+ => "Definitions (JUL 2004)(a) When a solicitation provision or contract clause uses a word..."
74
+ ```
75
+
76
+ ### Using clause data elsewhere
77
+
78
+ ```ruby
79
+
80
+ SoFarSoGood::Clauses.list.to_json
81
+ => "[{\"number\":\"52.200\",\"subject\":\"Scope of subpart.\",\"reserverd\":false,\"citation\":..."
82
+
83
+ puts SoFarSoGood::Clauses.to_md
84
+ |-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
85
+ | Clause | Description |
86
+ |-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
87
+ | 52.200 | Scope of subpart. |
88
+ | 52.202-1 | Definitions. |
89
+ | 52.203-2 | Certificate of Independent Price Determination. |
90
+ | 52.203-3 | Gratuities. |
91
+ | 52.203-5 | Covenant Against Contingent Fees. |
92
+ ```
93
+
94
+
20
95
  ## Installation
21
96
 
22
97
  Add this line to your application's Gemfile:
@@ -7,12 +7,12 @@ require_relative "so_far_so_good/clause"
7
7
 
8
8
  module SoFarSoGood
9
9
  class << self
10
- def vendor_directory
11
- File.expand_path "../vendor", File.dirname(__FILE__)
10
+ def clauses(options = {})
11
+ SoFarSoGood::Clauses.clauses(options)
12
12
  end
13
13
 
14
- def clauses
15
- SoFarSoGood::Clauses.clauses
14
+ def vendor_directory
15
+ File.expand_path "../vendor", File.dirname(__FILE__)
16
16
  end
17
17
  end
18
18
  end
@@ -17,6 +17,10 @@ module SoFarSoGood
17
17
  @body = node.children.css("P").text.strip
18
18
  end
19
19
 
20
+ def reserved?
21
+ !!@reserved
22
+ end
23
+
20
24
  def to_hash
21
25
  {
22
26
  :number => @number,
@@ -31,5 +35,9 @@ module SoFarSoGood
31
35
  def to_json(options = {})
32
36
  to_hash.to_json(options)
33
37
  end
38
+
39
+ def inspect
40
+ "#<SoFarSoGood::Clause @number=\"#{@number}\" @subject=\"#{@subject}\" @reserved=\"#{@reserved}\""
41
+ end
34
42
  end
35
43
  end
@@ -4,17 +4,23 @@ module SoFarSoGood
4
4
 
5
5
  HEADINGS = ["Clause", "Description"]
6
6
 
7
- def numbers
8
- @numbers ||= clauses.map { |c| c.number }
7
+ def numbers(options = {})
8
+ @numbers ||= clauses(options).map { |c| c.number }
9
9
  end
10
10
 
11
- def subjects
12
- @subjects ||= clauses.map { |c| c.subject }
11
+ def subjects(options = {})
12
+ @subjects ||= clauses(options).map { |c| c.subject }
13
13
  end
14
14
  alias_method :descriptions, :subjects
15
15
 
16
- def clauses
16
+ def clauses(options = {})
17
+ options = {:exclude_reserved => false}.merge(options)
17
18
  @clauses ||= sections.map { |node| SoFarSoGood::Clause.new(node) }
19
+ if options[:exclude_reserved]
20
+ @clauses.reject { |c| c.reserved }
21
+ else
22
+ @clauses
23
+ end
18
24
  end
19
25
  alias_method :list, :clauses
20
26
 
@@ -23,7 +29,11 @@ module SoFarSoGood
23
29
  end
24
30
 
25
31
  def to_json
26
- @json ||= sections.to_json
32
+ @json ||= clauses.to_json
33
+ end
34
+
35
+ def [](number)
36
+ clauses.find { |c| c.number == number }
27
37
  end
28
38
 
29
39
  private
@@ -42,8 +52,8 @@ module SoFarSoGood
42
52
  @subpart ||= doc.css("PART SUBPART")[4].children.css("SECTION")
43
53
  end
44
54
 
45
- def rows
46
- @rows ||= clauses.reject { |c| c.reserved }.map { |c| [c.number, c.subject]}
55
+ def rows(options={})
56
+ @rows ||= clauses(options).map { |c| [c.number, c.subject]}
47
57
  end
48
58
  end
49
59
  end
@@ -1,3 +1,3 @@
1
1
  module SoFarSoGood
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,27 @@
1
+ require 'helper'
2
+
3
+ class TestSoFarSoGoodClause < Minitest::Test
4
+
5
+ def setup
6
+ @nodes = SoFarSoGood::Clauses.send(:sections)
7
+ end
8
+
9
+ should "parse a section node" do
10
+ clause = SoFarSoGood::Clause.new(@nodes[6])
11
+ assert_equal "52.203-5", clause.number
12
+ assert_equal "Covenant Against Contingent Fees.", clause.subject
13
+ refute clause.reserved
14
+ assert_includes clause.citation, "48 FR 42478"
15
+ assert_includes clause.body, "As prescribed in 3.404,"
16
+ assert_includes clause.extract, "The Contractor warrants that no person or agency"
17
+ end
18
+
19
+ should "know if its reserved" do
20
+ refute SoFarSoGood::Clauses["52.203-5"].reserved?
21
+ assert SoFarSoGood::Clauses["52.203-1"].reserved?
22
+ end
23
+
24
+ should "put out valid json" do
25
+ assert JSON.parse SoFarSoGood::Clauses["52.203-5"].to_json
26
+ end
27
+ end
@@ -10,7 +10,7 @@ class TestSoFarSoGoodClauses < Minitest::Test
10
10
  end
11
11
 
12
12
  should "parse the rows" do
13
- assert_equal 567, SoFarSoGood::Clauses.send(:rows).count
13
+ assert_equal 616, SoFarSoGood::Clauses.send(:rows).count
14
14
  assert_equal ["52.200", "Scope of subpart."], SoFarSoGood::Clauses.send(:rows).first
15
15
  end
16
16
 
@@ -27,4 +27,16 @@ class TestSoFarSoGoodClauses < Minitest::Test
27
27
  should "put out valid JSON" do
28
28
  assert !!JSON.parse(SoFarSoGood::Clauses.list.to_json)
29
29
  end
30
+
31
+ should "return a particular clause" do
32
+ assert_equal "52.202-1", SoFarSoGood::Clauses["52.202-1"].number
33
+ end
34
+
35
+ should "return all clauses" do
36
+ assert_equal 616, SoFarSoGood::Clauses.list.count
37
+ end
38
+
39
+ should "filter reserved clauses" do
40
+ assert_equal 567, SoFarSoGood::Clauses.list(:exclude_reserved => true).count
41
+ end
30
42
  end
@@ -9,4 +9,8 @@ class TestSoFarSoGood < Minitest::Test
9
9
  assert_equal Array, SoFarSoGood.clauses.class
10
10
  assert_equal 616, SoFarSoGood.clauses.count
11
11
  end
12
+
13
+ should "accept clause options" do
14
+ assert_equal 567, SoFarSoGood.clauses(:exclude_reserved => true).count
15
+ end
12
16
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: so_far_so_good
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Balter
@@ -102,6 +102,7 @@ extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
104
  - ".gitignore"
105
+ - ".travis.yml"
105
106
  - Gemfile
106
107
  - LICENSE.md
107
108
  - README.md
@@ -118,6 +119,7 @@ files:
118
119
  - script/vendor
119
120
  - so_far_so_good.gemspec
120
121
  - test/helper.rb
122
+ - test/so_far_so_good_clause_test.rb
121
123
  - test/so_far_so_good_clauses_test.rb
122
124
  - test/so_far_so_good_test.rb
123
125
  - vendor/CFR-2010-title48-vol2-chap1-subchapH.xml
@@ -147,5 +149,6 @@ specification_version: 4
147
149
  summary: ''
148
150
  test_files:
149
151
  - test/helper.rb
152
+ - test/so_far_so_good_clause_test.rb
150
153
  - test/so_far_so_good_clauses_test.rb
151
154
  - test/so_far_so_good_test.rb