xbrlware-extras 1.1.2.19
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/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/README.md +3 -0
- data/Rakefile +2 -0
- data/lib/xbrlware-extras/context.rb +66 -0
- data/lib/xbrlware-extras/dateutil.rb +16 -0
- data/lib/xbrlware-extras/factory.rb +62 -0
- data/lib/xbrlware-extras/item.rb +77 -0
- data/lib/xbrlware-extras/linkbase.rb +158 -0
- data/lib/xbrlware-extras/version.rb +5 -0
- data/lib/xbrlware-extras.rb +8 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/xbrlware_helpers_spec.rb +212 -0
- data/xbrlware-extras.gemspec +21 -0
- metadata +86 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Jim Lindstrom
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
module Xbrlware
|
2
|
+
|
3
|
+
class Context
|
4
|
+
def write_constructor(file, context_name)
|
5
|
+
period_str = "nil"
|
6
|
+
case
|
7
|
+
when !@period
|
8
|
+
when self.period.is_instant?
|
9
|
+
period_str = "Date.parse(\"#{self.period.value}\")"
|
10
|
+
when self.period.is_duration?
|
11
|
+
period_str = "{"
|
12
|
+
period_str += "\"start_date\" => Date.parse(\"#{self.period.value["start_date"].to_s}\"),"
|
13
|
+
period_str += "\"end_date\" => Date.parse(\"#{self.period.value[ "end_date"].to_s}\")"
|
14
|
+
period_str += "}"
|
15
|
+
end
|
16
|
+
|
17
|
+
entity_str = "nil"
|
18
|
+
case
|
19
|
+
when !@entity || !@entity.segment
|
20
|
+
else
|
21
|
+
identifier_str = "\"#{@entity.identifier}\""
|
22
|
+
segment_str = "{}"
|
23
|
+
entity_str = "Xbrlware::Entity.new(identifier=#{identifier_str}, segment=#{segment_str})"
|
24
|
+
end
|
25
|
+
|
26
|
+
file.puts "#{context_name} = Xbrlware::Factory.Context(:period => #{period_str}, :entity => #{entity_str})"
|
27
|
+
end
|
28
|
+
|
29
|
+
class Period
|
30
|
+
def days
|
31
|
+
Xbrlware::DateUtil.days_between(@value["end_date"], @value["start_date"])
|
32
|
+
end
|
33
|
+
|
34
|
+
def plus_n_months(n)
|
35
|
+
case
|
36
|
+
when is_instant?
|
37
|
+
new_value = @value.dup
|
38
|
+
n.times do
|
39
|
+
new_value = new_value.next_month
|
40
|
+
end
|
41
|
+
return Period.new(new_value)
|
42
|
+
when is_duration?
|
43
|
+
new_value = {"start_date"=>@value["start_date"].dup, "end_date"=>@value["end_date"].dup}
|
44
|
+
n.times do
|
45
|
+
new_value["start_date"] = new_value["start_date"].next_month
|
46
|
+
new_value[ "end_date"] = new_value[ "end_date"].next_month
|
47
|
+
end
|
48
|
+
return Period.new(new_value)
|
49
|
+
end
|
50
|
+
raise RuntimeError.new("not supported")
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_pretty_s
|
54
|
+
case
|
55
|
+
when is_instant?
|
56
|
+
return "#{@value}"
|
57
|
+
when is_duration?
|
58
|
+
return "#{@value["start_date"]} to #{@value["end_date"]}"
|
59
|
+
else
|
60
|
+
return to_s
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Xbrlware
|
2
|
+
|
3
|
+
module DateUtil
|
4
|
+
def self.days_between(date1=Date.today, date2=Date.today)
|
5
|
+
begin
|
6
|
+
date1=Date.parse(date1) if date1.is_a?(String)
|
7
|
+
date2=Date.parse(date2) if date2.is_a?(String)
|
8
|
+
(date1 > date2) ? (recent_date, past_date = date1, date2) : (recent_date, past_date = date2, date1)
|
9
|
+
(recent_date - past_date).round
|
10
|
+
rescue Exception => e
|
11
|
+
0
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Xbrlware
|
2
|
+
class Factory
|
3
|
+
def self.Entity(args = {})
|
4
|
+
entity = Xbrlware::Entity.new(args[:identifier], args[:segment])
|
5
|
+
|
6
|
+
return entity
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.Context(args = {})
|
10
|
+
id = args[:id] || ""
|
11
|
+
entity = args[:entity] || self.Entity()
|
12
|
+
period = args[:period]
|
13
|
+
scenario = args[:scenario]
|
14
|
+
context = Xbrlware::Context.new(id, entity, period, scenario)
|
15
|
+
|
16
|
+
return context
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.Item(args = {})
|
20
|
+
instance = nil
|
21
|
+
name = args[:name] || ""
|
22
|
+
context = args[:context] || self.Context(:period => args[:period])
|
23
|
+
value = args[:value] || ""
|
24
|
+
unit = args[:unit]
|
25
|
+
precision = args[:precision]
|
26
|
+
decimals = args[:decimals] || "-6"
|
27
|
+
footnotes = nil
|
28
|
+
|
29
|
+
item = Xbrlware::Item.new(instance, name, context, value, unit, precision, decimals, footnotes)
|
30
|
+
|
31
|
+
return item
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.CalculationArc(args = {})
|
35
|
+
item_id = args[:item_id] || ""
|
36
|
+
href = ""
|
37
|
+
role = nil
|
38
|
+
order = nil
|
39
|
+
weight = nil
|
40
|
+
priority = nil
|
41
|
+
use = nil
|
42
|
+
label = args[:label] || ""
|
43
|
+
|
44
|
+
arc = Xbrlware::Linkbase::CalculationLinkbase::Calculation::CalculationArc.new(item_id, href, role, order,
|
45
|
+
weight, priority, use, label)
|
46
|
+
|
47
|
+
return arc
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.Calculation(args = {})
|
51
|
+
entity_details=nil
|
52
|
+
title=args[:title] || ""
|
53
|
+
role=args[:role]
|
54
|
+
href=nil
|
55
|
+
arcs=args[:arcs] || []
|
56
|
+
contexts=nil
|
57
|
+
|
58
|
+
return Xbrlware::Linkbase::CalculationLinkbase::Calculation.new(entity_details, title, role, href, arcs, contexts)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Xbrlware
|
2
|
+
|
3
|
+
class ValueMapping
|
4
|
+
attr_accessor :policy
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@unknown_classifier = nil
|
8
|
+
|
9
|
+
@policy = { :credit => :no_action,
|
10
|
+
:debit => :no_action,
|
11
|
+
:unknown => :no_action } # FIXME: a classifier could be used here....
|
12
|
+
end
|
13
|
+
|
14
|
+
def value(name, defn, val)
|
15
|
+
# we ignore 'name' in this implementation
|
16
|
+
|
17
|
+
case @policy[defn]
|
18
|
+
when :no_action then val
|
19
|
+
when :flip then -val
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Item
|
25
|
+
def pretty_name
|
26
|
+
self.name.gsub(/([a-z])([A-Z])/, '\1 \2')
|
27
|
+
end
|
28
|
+
|
29
|
+
def write_constructor(file, item_name)
|
30
|
+
item_context_name = item_name + "_context"
|
31
|
+
if @context.nil?
|
32
|
+
file.puts "#{item_context_name} = nil"
|
33
|
+
else
|
34
|
+
@context.write_constructor(file, item_context_name)
|
35
|
+
end
|
36
|
+
|
37
|
+
file.puts "#{item_name} = Xbrlware::Factory.Item(:name => \"#{@name}\"," +
|
38
|
+
" :decimals => \"#{@decimals}\"," +
|
39
|
+
" :context => #{item_context_name}," +
|
40
|
+
" :value => \"#{@value}\")"
|
41
|
+
if !@def.nil? and !@def["xbrli:balance"].nil?
|
42
|
+
file.puts "#{item_name}.def = { } if #{item_name}.def.nil?"
|
43
|
+
file.puts "#{item_name}.def[\"xbrli:balance\"] = \"#{@def['xbrli:balance']}\""
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def print_tree(indent_count=0)
|
48
|
+
output = "#{indent} #{@label}"
|
49
|
+
|
50
|
+
@items.each do |item|
|
51
|
+
period=item.context.period
|
52
|
+
period_str = period.is_duration? ? "#{period.value["start_date"]} to #{period.value["end_date"]}" : "#{period.value}"
|
53
|
+
output += " [#{item.def["xbrli:balance"]}]" unless item.def.nil?
|
54
|
+
output += " (#{period_str}) = #{item.value}" unless item.nil?
|
55
|
+
end
|
56
|
+
puts indent + output
|
57
|
+
|
58
|
+
@children.each { |child| child.print_tree(indent_count+1) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def is_sub_leaf?
|
62
|
+
@context.entity.segment
|
63
|
+
end
|
64
|
+
|
65
|
+
def value(mapping=nil)
|
66
|
+
definition = case
|
67
|
+
when @def.nil? then :unknown
|
68
|
+
when @def["xbrli:balance"].nil? then :unknown
|
69
|
+
else @def["xbrli:balance"].to_sym
|
70
|
+
end
|
71
|
+
|
72
|
+
mapping = mapping || ValueMapping.new
|
73
|
+
return mapping.value(pretty_name, definition, @value.to_f)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
module Xbrlware
|
2
|
+
|
3
|
+
module Linkbase
|
4
|
+
class Linkbase
|
5
|
+
class Link
|
6
|
+
def clean_downcased_title
|
7
|
+
@title.gsub(/([A-Z]) ([A-Z])/, '\1\2').gsub(/([A-Z]) ([A-Z])/, '\1\2').downcase
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class CalculationLinkbase
|
13
|
+
class Calculation
|
14
|
+
def write_constructor(file, calc_name)
|
15
|
+
file.puts "#{calc_name}_args = {}"
|
16
|
+
file.puts "#{calc_name}_args[:title] = \"#{@title}\""
|
17
|
+
file.puts "#{calc_name}_args[:role] = \"#{@role}\""
|
18
|
+
file.puts "#{calc_name}_args[:arcs] = []"
|
19
|
+
@arcs.each_with_index do |arc, index|
|
20
|
+
arc_name = calc_name + "_arc#{index}"
|
21
|
+
arc.write_constructor(file, arc_name)
|
22
|
+
file.puts "#{calc_name}_args[:arcs].push #{arc_name}"
|
23
|
+
end
|
24
|
+
file.puts "#{calc_name} = Xbrlware::Factory.Calculation(#{calc_name}_args)"
|
25
|
+
end
|
26
|
+
|
27
|
+
def is_disclosure?
|
28
|
+
@title.downcase =~ /^disclosure/ ? true : false
|
29
|
+
end
|
30
|
+
|
31
|
+
def top_level_arcs
|
32
|
+
uniq_arcs = []
|
33
|
+
@arcs.each do |arc|
|
34
|
+
if @arcs.none?{ |other_arc| other_arc.contains_arc?(arc) }
|
35
|
+
uniq_arcs.push arc
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
return uniq_arcs
|
40
|
+
end
|
41
|
+
|
42
|
+
def print_tree(indent_count=0)
|
43
|
+
indent = " " * indent_count
|
44
|
+
puts indent + "Calc: #{@title} (#{@role})"
|
45
|
+
|
46
|
+
@arcs.each { |arc| arc.print_tree(indent_count+1) }
|
47
|
+
|
48
|
+
puts indent + "\n\n"
|
49
|
+
end
|
50
|
+
|
51
|
+
def leaf_items(period)
|
52
|
+
#if @arcs.empty?
|
53
|
+
if top_level_arcs.empty?
|
54
|
+
raise RuntimeError.new("#{self.inspect} (#{@label}) has nil items!") if @items.nil?
|
55
|
+
|
56
|
+
items = @items.select{ |x| !x.is_sub_leaf? }
|
57
|
+
items.select!{ |x| x.context.period.to_pretty_s == period.to_pretty_s } if period
|
58
|
+
|
59
|
+
return items
|
60
|
+
end
|
61
|
+
|
62
|
+
#return @arcs.collect { |child| child.leaf_items(period) }.flatten
|
63
|
+
return top_level_arcs.collect { |child| child.leaf_items(period) }.flatten
|
64
|
+
end
|
65
|
+
|
66
|
+
class CalculationArc
|
67
|
+
def write_constructor(file, arc_name)
|
68
|
+
file.puts "args = {}"
|
69
|
+
file.puts "args[:item_id] = \"#{@item_id}\""
|
70
|
+
file.puts "args[:label] = \"#{@label}\""
|
71
|
+
file.puts "#{arc_name} = Xbrlware::Factory.CalculationArc(args)"
|
72
|
+
file.puts "#{arc_name}.items = []"
|
73
|
+
(@items || []).each_with_index do |item, index|
|
74
|
+
item_name = arc_name + "_item#{index}"
|
75
|
+
item.write_constructor(file, item_name)
|
76
|
+
file.puts "#{arc_name}.items.push #{item_name}"
|
77
|
+
end
|
78
|
+
file.puts "#{arc_name}.children = []"
|
79
|
+
(@children || []).each_with_index do |child, index|
|
80
|
+
child_name = arc_name + "_child#{index}"
|
81
|
+
child.write_constructor(file, child_name)
|
82
|
+
file.puts "#{arc_name}.children.push #{child_name}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def contains_arc?(arc)
|
87
|
+
return false if @children.empty?
|
88
|
+
|
89
|
+
@children.each do |child|
|
90
|
+
return true if (child.label == arc.label) && (child.item_id == arc.item_id)
|
91
|
+
return true if child.contains_arc?(arc)
|
92
|
+
end
|
93
|
+
|
94
|
+
return false
|
95
|
+
end
|
96
|
+
|
97
|
+
def print_tree(indent_count=0)
|
98
|
+
indent = " " * indent_count
|
99
|
+
output = "#{indent} #{@label}"
|
100
|
+
|
101
|
+
(@items || []).each do |item|
|
102
|
+
period = item.context.period
|
103
|
+
period_str = period.is_duration? ? "#{period.value["start_date"]} to #{period.value["end_date"]}" : "#{period.value}"
|
104
|
+
output += " [#{item.def["xbrli:balance"]}]" if item.def
|
105
|
+
output += " (#{period_str}) = #{item.value}" if item.value
|
106
|
+
end
|
107
|
+
puts indent + output
|
108
|
+
|
109
|
+
(@children || []).each { |child| child.print_tree(indent_count+1) }
|
110
|
+
end
|
111
|
+
|
112
|
+
def leaf_items(period)
|
113
|
+
if @children.empty?
|
114
|
+
raise RuntimeError.new("#{self} (#{@label}) has nil items!") if @items.nil?
|
115
|
+
items = @items.select{ |x| !x.is_sub_leaf? }
|
116
|
+
raise RuntimeError.new("#{self} (#{@label}) has a Hash for a period") if period and period.class==Hash
|
117
|
+
items.select!{ |x| x.context.period.to_pretty_s == period.to_pretty_s } if period
|
118
|
+
return items
|
119
|
+
end
|
120
|
+
|
121
|
+
return @children.collect { |child| child.leaf_items(period) }.flatten
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
class PresentationLinkbase
|
128
|
+
class Presentation
|
129
|
+
def print_tree(indent_count=0)
|
130
|
+
indent = " " * indent_count
|
131
|
+
puts indent + "Pres: #{@title} (#{@role})"
|
132
|
+
|
133
|
+
@arcs.each { |arc| arc.print_tree(indent_count+1) }
|
134
|
+
|
135
|
+
puts indent + "\n\n"
|
136
|
+
end
|
137
|
+
|
138
|
+
class PresentationArc
|
139
|
+
def print_tree(indent_count=0)
|
140
|
+
indent = " " * indent_count
|
141
|
+
output = "#{indent} #{@label}"
|
142
|
+
|
143
|
+
@items.each do |item|
|
144
|
+
period=item.context.period
|
145
|
+
period_str = period.is_duration? ? "#{period.value["start_date"]} to #{period.value["end_date"]}" : "#{period.value}"
|
146
|
+
output += " [#{item.def["xbrli:balance"]}]" unless item.def.nil?
|
147
|
+
output += " (#{period_str}) = #{item.value}" unless item.nil?
|
148
|
+
end
|
149
|
+
puts indent + output
|
150
|
+
|
151
|
+
@children.each { |child| child.print_tree(indent_count+1) }
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
# string_helpers_spec.rb
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Xbrlware::Context::Period do
|
6
|
+
describe ".days" do
|
7
|
+
context "when a date range" do
|
8
|
+
let(:value) { {"start_date"=>Date.parse("2011-01-01"), "end_date"=>Date.parse("2011-03-31")} }
|
9
|
+
subject { Xbrlware::Context::Period.new(value).days }
|
10
|
+
|
11
|
+
it { should be_a Fixnum }
|
12
|
+
it { should == Xbrlware::DateUtil.days_between(value["end_date"], value["start_date"]) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
describe ".plus_n_months" do
|
16
|
+
context "when an instantaneous date" do
|
17
|
+
let(:old_value) { Date.parse("2010-12-31") }
|
18
|
+
let(:old) { old = Xbrlware::Context::Period.new(old_value) }
|
19
|
+
|
20
|
+
subject { old.plus_n_months(3) }
|
21
|
+
|
22
|
+
it { should be_a Xbrlware::Context::Period }
|
23
|
+
its(:to_pretty_s) { should == "2011-03-28" }
|
24
|
+
end
|
25
|
+
context "when a date range" do
|
26
|
+
let(:old_value) { {"start_date"=>Date.parse("2011-01-01"), "end_date"=>Date.parse("2011-03-31")} }
|
27
|
+
let(:old) { old = Xbrlware::Context::Period.new(old_value) }
|
28
|
+
|
29
|
+
subject { old.plus_n_months(3) }
|
30
|
+
|
31
|
+
it { should be_a Xbrlware::Context::Period }
|
32
|
+
its(:to_pretty_s) { should == "2011-04-01 to 2011-06-30" }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe Xbrlware::Context do
|
38
|
+
|
39
|
+
describe "write_constructor" do
|
40
|
+
context "when the period is nil" do
|
41
|
+
before(:all) do
|
42
|
+
file_name = "/tmp/xbrlware-extras-context1.rb"
|
43
|
+
item_name = "@item_context"
|
44
|
+
file = File.open(file_name, "w")
|
45
|
+
@orig_item = Xbrlware::Factory.Context()
|
46
|
+
@orig_item.write_constructor(file, item_name)
|
47
|
+
file.close
|
48
|
+
|
49
|
+
eval(File.read(file_name))
|
50
|
+
|
51
|
+
@loaded_item = eval(item_name)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "writes itself to a file, and when reloaded, has the same period" do
|
55
|
+
@loaded_item.period.value.should == @orig_item.period.value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when the period is an instant" do
|
60
|
+
before(:all) do
|
61
|
+
file_name = "/tmp/xbrlware-extras-context2.rb"
|
62
|
+
item_name = "@item_context"
|
63
|
+
file = File.open(file_name, "w")
|
64
|
+
@orig_item = Xbrlware::Factory.Context(:period => Date.parse("2010-01-01"))
|
65
|
+
@orig_item.write_constructor(file, item_name)
|
66
|
+
file.close
|
67
|
+
|
68
|
+
eval(File.read(file_name))
|
69
|
+
|
70
|
+
@loaded_item = eval(item_name)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "writes itself to a file, and when reloaded, has the same period" do
|
74
|
+
@loaded_item.period.to_pretty_s.should == @orig_item.period.to_pretty_s
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when the period is a duration" do
|
79
|
+
before(:all) do
|
80
|
+
file_name = "/tmp/xbrlware-extras-context3.rb"
|
81
|
+
item_name = "@item_context"
|
82
|
+
file = File.open(file_name, "w")
|
83
|
+
@orig_item = Xbrlware::Factory.Context(:period => {"start_date" => Date.parse("2010-01-01"),
|
84
|
+
"end_date" => Date.parse("2011-01-01")})
|
85
|
+
@orig_item.write_constructor(file, item_name)
|
86
|
+
file.close
|
87
|
+
|
88
|
+
eval(File.read(file_name))
|
89
|
+
|
90
|
+
@loaded_item = eval(item_name)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "writes itself to a file, and when reloaded, has the same period" do
|
94
|
+
@loaded_item.period.to_pretty_s.should == @orig_item.period.to_pretty_s
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
describe Xbrlware::Linkbase::CalculationLinkbase::Calculation do
|
102
|
+
describe ".top_level_arcs" do
|
103
|
+
before(:all) do
|
104
|
+
@calc = Xbrlware::Factory.Calculation(:title=>"Statement of Something or Other")
|
105
|
+
@calc.arcs << Xbrlware::Factory.CalculationArc(:label=>"A0")
|
106
|
+
@calc.arcs.first.items = []
|
107
|
+
@calc.arcs.first.items << Xbrlware::Factory.Item(:name=>"A0.I0")
|
108
|
+
|
109
|
+
@calc.arcs << Xbrlware::Factory.CalculationArc(:label=>"B0")
|
110
|
+
@calc.arcs.last.children = []
|
111
|
+
@calc.arcs.last.children << Xbrlware::Factory.CalculationArc(:label=>"B0.B1")
|
112
|
+
|
113
|
+
@calc.arcs.last.children.first.items = []
|
114
|
+
@calc.arcs.last.children.first.items << Xbrlware::Factory.Item(:name=>"B0.B1.I0")
|
115
|
+
|
116
|
+
@calc.arcs.last.children << @calc.arcs.first # B0 contains A0
|
117
|
+
end
|
118
|
+
subject { @calc.top_level_arcs }
|
119
|
+
it { should have(1).items }
|
120
|
+
its(:first) { should be @calc.arcs.last }
|
121
|
+
end
|
122
|
+
|
123
|
+
describe ".is_disclosure?" do
|
124
|
+
context "when its title begins with 'Disclosure'" do
|
125
|
+
let(:calc) { Xbrlware::Factory.Calculation(:title=>"Disclosure of Something or Other") }
|
126
|
+
subject { calc.is_disclosure? }
|
127
|
+
it { should == true }
|
128
|
+
end
|
129
|
+
context "when its title does not begin with 'Disclosure'" do
|
130
|
+
let(:calc) { Xbrlware::Factory.Calculation(:title=>"Statement of Something or Other") }
|
131
|
+
subject { calc.is_disclosure? }
|
132
|
+
it { should == false }
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe Xbrlware::Linkbase::CalculationLinkbase::Calculation::CalculationArc do
|
138
|
+
describe ".write_constructor" do
|
139
|
+
before(:all) do
|
140
|
+
calc = Xbrlware::Factory.Calculation(:title=>"Statement of Something or Other")
|
141
|
+
calc.arcs << Xbrlware::Factory.CalculationArc(:label=>"B0")
|
142
|
+
calc.arcs.last.items = []
|
143
|
+
calc.arcs.last.children = []
|
144
|
+
calc.arcs.last.children << Xbrlware::Factory.CalculationArc(:label=>"B0.B1", :items=>[])
|
145
|
+
calc.arcs.last.children.first.items = []
|
146
|
+
calc.arcs.last.children.first.items << Xbrlware::Factory.Item(:name=>"B0.B1.I0")
|
147
|
+
|
148
|
+
@orig_item = calc.arcs.first
|
149
|
+
|
150
|
+
file_name = "/tmp/xbrlware-extras-calc-arc.rb"
|
151
|
+
item_name = "@item"
|
152
|
+
file = File.open(file_name, "w")
|
153
|
+
@orig_item.write_constructor(file, item_name)
|
154
|
+
file.close
|
155
|
+
|
156
|
+
eval(File.read(file_name))
|
157
|
+
@loaded_item = eval(item_name)
|
158
|
+
end
|
159
|
+
|
160
|
+
it "writes itself to a file, and when reloaded, has the same item_id" do
|
161
|
+
@loaded_item.item_id.should == @orig_item.item_id
|
162
|
+
end
|
163
|
+
it "writes itself to a file, and when reloaded, has the same label" do
|
164
|
+
@loaded_item.label.should == @orig_item.label
|
165
|
+
end
|
166
|
+
it "writes itself to a file, and when reloaded, has the same number of children" do
|
167
|
+
@loaded_item.children.length.should == @orig_item.children.length
|
168
|
+
end
|
169
|
+
it "writes itself to a file, and when reloaded, has the same number of items" do
|
170
|
+
@loaded_item.items.length.should == @orig_item.items.length
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe ".contains_arc?" do
|
175
|
+
before(:each) do
|
176
|
+
@calc = Xbrlware::Factory.Calculation(:title=>"Statement of Something or Other")
|
177
|
+
@calc.arcs << Xbrlware::Factory.CalculationArc(:label=>"A0")
|
178
|
+
@calc.arcs.first.items = []
|
179
|
+
@calc.arcs.first.items << Xbrlware::Factory.Item(:name=>"A0.I0")
|
180
|
+
|
181
|
+
@calc.arcs << Xbrlware::Factory.CalculationArc(:label=>"B0")
|
182
|
+
@calc.arcs.last.children = []
|
183
|
+
@calc.arcs.last.children << Xbrlware::Factory.CalculationArc(:label=>"B0.B1")
|
184
|
+
|
185
|
+
@calc.arcs.last.children.first.items = []
|
186
|
+
@calc.arcs.last.children.first.items << Xbrlware::Factory.Item(:name=>"B0.B1.I0")
|
187
|
+
end
|
188
|
+
context "when the first arc does not contain the second arc" do
|
189
|
+
subject { @calc.arcs.first.contains_arc?(@calc.arcs.last) }
|
190
|
+
it { should == false }
|
191
|
+
end
|
192
|
+
context "when the first arc contains the second arc" do
|
193
|
+
before(:each) do
|
194
|
+
@calc.arcs.last.children << @calc.arcs.first # B0 contains A0
|
195
|
+
end
|
196
|
+
|
197
|
+
subject { @calc.arcs.last.contains_arc?(@calc.arcs.first) }
|
198
|
+
it { should == true }
|
199
|
+
end
|
200
|
+
context "when the first arc contains a second arc that contains the third arc" do
|
201
|
+
before(:each) do
|
202
|
+
@calc.arcs.last.children << Xbrlware::Factory.CalculationArc(:label=>"B0.B2")
|
203
|
+
@calc.arcs.last.children.last.children << @calc.arcs.first # B0.B2 contains A0
|
204
|
+
end
|
205
|
+
|
206
|
+
subject { @calc.arcs.last.contains_arc?(@calc.arcs.first) }
|
207
|
+
it { should == true }
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/xbrlware-extras/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Jim Lindstrom"]
|
6
|
+
gem.email = ["jim.lindstrom@gmail.com"]
|
7
|
+
gem.description = %q{A set of extentions that make it easier to build on top of xbrlware}
|
8
|
+
gem.summary = %q{A set of extentions that make it easier to build on top of xbrlware}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.add_dependency("xbrlware-ruby19", "1.1.2.19")
|
12
|
+
|
13
|
+
gem.add_development_dependency("rspec", "~> 2.0.1")
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($\)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.name = "xbrlware-extras"
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
gem.version = Xbrlware::Extras::VERSION
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xbrlware-extras
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.2.19
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jim Lindstrom
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-31 00:00:00.000000000 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: xbrlware-ruby19
|
17
|
+
requirement: &85581660 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - =
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.1.2.19
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *85581660
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rspec
|
28
|
+
requirement: &85581410 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.1
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *85581410
|
37
|
+
description: A set of extentions that make it easier to build on top of xbrlware
|
38
|
+
email:
|
39
|
+
- jim.lindstrom@gmail.com
|
40
|
+
executables: []
|
41
|
+
extensions: []
|
42
|
+
extra_rdoc_files: []
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- Gemfile
|
46
|
+
- LICENSE
|
47
|
+
- README.md
|
48
|
+
- Rakefile
|
49
|
+
- lib/xbrlware-extras.rb
|
50
|
+
- lib/xbrlware-extras/context.rb
|
51
|
+
- lib/xbrlware-extras/dateutil.rb
|
52
|
+
- lib/xbrlware-extras/factory.rb
|
53
|
+
- lib/xbrlware-extras/item.rb
|
54
|
+
- lib/xbrlware-extras/linkbase.rb
|
55
|
+
- lib/xbrlware-extras/version.rb
|
56
|
+
- spec/spec_helper.rb
|
57
|
+
- spec/xbrlware_helpers_spec.rb
|
58
|
+
- xbrlware-extras.gemspec
|
59
|
+
has_rdoc: true
|
60
|
+
homepage: ''
|
61
|
+
licenses: []
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.6.2
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: A set of extentions that make it easier to build on top of xbrlware
|
84
|
+
test_files:
|
85
|
+
- spec/spec_helper.rb
|
86
|
+
- spec/xbrlware_helpers_spec.rb
|