aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Gemfile.lock6
-rw-r--r--lib/model_attribute.rb100
-rw-r--r--spec/lib/model_attribute_spec.rb117
3 files changed, 220 insertions, 3 deletions
diff --git a/Gemfile.lock b/Gemfile.lock
index fef3270a3..1d05e0540 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -305,7 +305,7 @@ GEM
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mimemagic (0.3.2)
- mini_portile2 (2.2.0)
+ mini_portile2 (2.3.0)
minitest (5.10.3)
multi_json (1.12.1)
multi_test (0.1.2)
@@ -319,8 +319,8 @@ GEM
net-ssh-gateway (2.0.0)
net-ssh (>= 4.0.0)
newrelic_rpm (4.0.0.332)
- nokogiri (1.8.0)
- mini_portile2 (~> 2.2.0)
+ nokogiri (1.8.1)
+ mini_portile2 (~> 2.3.0)
open4 (1.3.4)
orm_adapter (0.5.0)
parser (2.4.0.0)
diff --git a/lib/model_attribute.rb b/lib/model_attribute.rb
new file mode 100644
index 000000000..60580e306
--- /dev/null
+++ b/lib/model_attribute.rb
@@ -0,0 +1,100 @@
+class ModelAttribute
+ attr_reader :klass, :name, :data_type
+
+ def self.all
+ @__all__ ||= []
+ end
+
+ def self.define(klass, name, data_type)
+ all << new(klass, name, data_type)
+ end
+
+ def self.classes
+ all
+ .map(&:klass)
+ .map(&:to_s)
+ .map(&:camelize)
+ .uniq
+ end
+
+ def self.group_by_class
+ all.group_by(&:klass)
+ end
+
+ def self.from_code(code)
+ klass, name = code.split('#').map(&:to_sym)
+
+ methods_by_class(klass).select do |model_attr|
+ model_attr.name == name
+ end.first
+ end
+
+ def self.methods_by_class(klass)
+ all.select do |model_attr|
+ model_attr.klass == klass
+ end
+ end
+
+ def self.methods_by_class_and_type(klass, type)
+ methods_by_class(klass).select do |model_attr|
+ model_attr.data_type == type
+ end
+ end
+
+ def initialize(klass, name, data_type)
+ @klass = klass
+ @name = name
+ @data_type = data_type
+ end
+
+ # Chouette::Route
+ define :route, :name, :string
+ define :route, :published_name, :string
+ define :route, :comment, :string
+ define :route, :number, :string
+ define :route, :direction, :string
+ define :route, :wayback, :string
+
+ # Chouette::JourneyPattern
+ define :journey_pattern, :name, :string
+ define :journey_pattern, :published_name, :string
+ define :journey_pattern, :comment, :string
+ define :journey_pattern, :registration_number, :string
+ define :journey_pattern, :section_status, :integer
+
+ # Chouette::VehicleJourney
+ define :vehicle_journey, :comment, :string
+ define :vehicle_journey, :status_value, :string
+ define :vehicle_journey, :transport_mode, :string
+ define :vehicle_journey, :facility, :string
+ define :vehicle_journey, :published_journey_name, :string
+ define :vehicle_journey, :published_journey_identifier, :string
+ define :vehicle_journey, :vehicle_type_identifier, :string
+ define :vehicle_journey, :number, :integer
+ define :vehicle_journey, :mobility_restricted_suitability, :boolean
+ define :vehicle_journey, :flexible_service, :boolean
+
+ # Chouette::Footnote
+ define :footnote, :code, :string
+ define :footnote, :label, :string
+
+ # Chouette::TimeTable
+ define :time_table, :version, :string
+ define :time_table, :comment, :string
+ define :time_table, :start_date, :date
+ define :time_table, :end_date, :date
+ define :time_table, :color, :string
+
+ # Chouette::RoutingConstraintZone
+ define :routing_constraint_zone, :name, :string
+
+ def code
+ "#{@klass}##{@name}"
+ end
+
+ def ==(other)
+ klass == other.klass &&
+ name == other.name &&
+ data_type == other.data_type
+ end
+end
diff --git a/spec/lib/model_attribute_spec.rb b/spec/lib/model_attribute_spec.rb
new file mode 100644
index 000000000..427e01490
--- /dev/null
+++ b/spec/lib/model_attribute_spec.rb
@@ -0,0 +1,117 @@
+RSpec.describe ModelAttribute do
+ describe ".define" do
+ it "adds a new instance of ModelAttribute to .all" do
+ expect do
+ ModelAttribute.define(:route, :name, :string)
+ end.to change { ModelAttribute.all.length }.by(1)
+
+ model_attr = ModelAttribute.all.last
+
+ expect(model_attr).to be_an_instance_of(ModelAttribute)
+ expect(model_attr.klass).to eq(:route)
+ expect(model_attr.name).to eq(:name)
+ expect(model_attr.data_type).to eq(:string)
+ end
+ end
+
+ describe ".classes" do
+ it "returns the list of classes of ModelAttributes in .all" do
+ ModelAttribute.instance_variable_set(:@__all__, [
+ ModelAttribute.new(:route, :name, :string),
+ ModelAttribute.new(:journey_pattern, :name, :string),
+ ModelAttribute.new(:time_table, :start_date, :date)
+ ])
+
+ expect(ModelAttribute.classes).to match_array([
+ 'Route',
+ 'JourneyPattern',
+ 'TimeTable'
+ ])
+ end
+ end
+
+ describe ".from_code" do
+ it "returns a ModelAttribute from a given code" do
+ ModelAttribute.instance_variable_set(:@__all__, [
+ ModelAttribute.new(:journey_pattern, :name, :string)
+ ])
+
+ expect(ModelAttribute.from_code('journey_pattern#name')).to eq(
+ ModelAttribute.new(:journey_pattern, :name, :string)
+ )
+ end
+ end
+
+ describe ".group_by_class" do
+ it "returns all ModelAttributes grouped by klass" do
+ ModelAttribute.instance_variable_set(:@__all__, [
+ ModelAttribute.new(:route, :name, :string),
+ ModelAttribute.new(:route, :published_name, :string),
+ ModelAttribute.new(:journey_pattern, :name, :string),
+ ModelAttribute.new(:vehicle_journey, :number, :integer)
+ ])
+
+ expect(ModelAttribute.group_by_class).to eq({
+ route: [
+ ModelAttribute.new(:route, :name, :string),
+ ModelAttribute.new(:route, :published_name, :string),
+ ],
+ journey_pattern: [
+ ModelAttribute.new(:journey_pattern, :name, :string),
+ ],
+ vehicle_journey: [
+ ModelAttribute.new(:vehicle_journey, :number, :integer)
+ ]
+ })
+ end
+ end
+
+ describe ".methods_by_class" do
+ it "returns all ModelAttributes for a given class" do
+ ModelAttribute.instance_variable_set(:@__all__, [
+ ModelAttribute.new(:route, :name, :string),
+ ModelAttribute.new(:route, :published_name, :string),
+ ModelAttribute.new(:route, :direction, :string),
+ ModelAttribute.new(:journey_pattern, :name, :string)
+ ])
+
+ expect(ModelAttribute.methods_by_class(:route)).to match_array([
+ ModelAttribute.new(:route, :name, :string),
+ ModelAttribute.new(:route, :published_name, :string),
+ ModelAttribute.new(:route, :direction, :string)
+ ])
+ end
+ end
+
+ describe ".methods_by_class_and_type" do
+ it "returns ModelAttributes of a certain class and type" do
+ ModelAttribute.instance_variable_set(:@__all__, [
+ ModelAttribute.new(:route, :name, :string),
+ ModelAttribute.new(:route, :checked_at, :date),
+ ModelAttribute.new(:journey_pattern, :name, :string),
+ ModelAttribute.new(:journey_pattern, :section_status, :integer)
+ ])
+
+ expect(ModelAttribute.methods_by_class_and_type(:route, :string)).to match_array([
+ ModelAttribute.new(:route, :name, :string)
+ ])
+ end
+ end
+
+ describe "#code" do
+ it "returns a string representation of the attribute" do
+ model_attr = ModelAttribute.new(:route, :name, :string)
+
+ expect(model_attr.code).to eq('route#name')
+ end
+ end
+
+ describe "#==" do
+ it "returns true when :klass, :name, and :data_type attributes match" do
+ route_name = ModelAttribute.new(:route, :name, :string)
+ other_route_name = ModelAttribute.new(:route, :name, :string)
+
+ expect(route_name == other_route_name).to be true
+ end
+ end
+end