diff --git a/CHANGELOG.md b/CHANGELOG.md index f7f26d5..4a4e473 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 None. +## [1.0.0-alpha.5] - 2023-02-20 + +### Added + +- Add automated tests and GitHub actions. +- Handle optional parameters (named parameters). + +### Changed + +- Price is a BlankNode (ontology version 1.7.1). +- Update README.md. + ## [1.0.0-alpha.4] - 2023-02-13 ### Changed @@ -43,6 +55,7 @@ None. - Initial version of this library. [unreleased]: https://github.com/datafoodconsortium/connector-ruby/compare/v1.0.0...HEAD +[1.0.0-alpha.5]: https://github.com/datafoodconsortium/connector-ruby/compare/v1.0.0-alpha.4...v1.0.0-alpha.5 [1.0.0-alpha.4]: https://github.com/datafoodconsortium/connector-ruby/compare/v1.0.0-alpha.3...v1.0.0-alpha.4 [1.0.0-alpha.3]: https://github.com/datafoodconsortium/connector-ruby/compare/v1.0.0-alpha.2...v1.0.0-alpha.3 [1.0.0-alpha.2]: https://github.com/datafoodconsortium/connector-ruby/compare/v1.0.0-alpha.1...v1.0.0-alpha.2 diff --git a/README.md b/README.md index ff64865..2826d19 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,52 @@ -The Data Food Connector is a tool to help you to integrate the DFC standard within you application. Each concept of the DFC ontology can be manipulated with the help of the corresponding class supplied by the connector. +# Data Food Consortium Ruby connector + +The Data Food Consortium connector is a tool to help you to integrate the DFC standard within you application. Each concept of the DFC ontology can be manipulated with the help of the corresponding class supplied by the connector. This connector will also help you to generate the JSON-LD required by the other DFC compliant platforms to exchange data. -The [Data Food Consortium](https://datafoodconsortium.org) project (DFC) which aims to provide interoperability between food supply chain platforms. We use the semantizer library inside our connector library to help developers to exchange JSON-LD data expressed with the DFC ontology. +The [Data Food Consortium](https://datafoodconsortium.org) project (DFC) which aims to provide interoperability between food supply chain platforms. We use the [Semantizer library](https://github.com/assemblee-virtuelle/semantizer-ruby/) inside our connector library to help developers to exchange JSON-LD data expressed with the DFC ontology. -# Get started +## Get started You can install the connector with the following command: `gem install datafoodconsortium-connector`. Then in you Ruby file, import the newly installed connector: -``` +```RB require 'datafoodconsortium/connector' ``` The connector is a singleton. To get it, access the instance member of the class: -``` +```RB connector = DataFoodConsortium::Connector::Connector.instance ``` You can then load our different SKOS vocabularies providing the corresponding JSON-LD files: -``` +```RB connector.loadMeasures(JSON.parse(File.read("/path/to/measures.json"))) connector.loadFacets(JSON.parse(File.read("/path/to/facets.json"))) connector.loadProductTypes(JSON.parse(File.read("/path/to/productTypes.json"))) ``` Then you can create product like: -``` -tomato = DataFoodConsortium::Connector::SuppliedProduct.new("Tomato", "Awesome tomato") +```RB +tomato = DataFoodConsortium::Connector::SuppliedProduct.new( + "https://myplatform.com/tomato", + name: "Tomato", + description: "Awesome tomato" +) ``` -Don't forget to set its semantic id (URI) so the object will not being considered as a blank node: -``` -tomato.semanticId = "https://myplatform.com/tomato" -``` +__Remark:__ The first argument is the semantic id (URI) of the object. Be sure to provide one except for anonymous objects like `Price`, `QuantitativeValue`, `NutrientCharacteristic`, `PhysicalCharacteristic` and `AllergenCharacteristic`. -You can set the different properties of the object, like adding a certification. The connector provide helpers to get the certification from the previously loaded vocabularies: -``` +You can set the different properties for the object, like adding a certification. The connector provide helpers to get the certification from the previously loaded vocabularies: +```RB tomato.addCertification(connector.FACETS.CERTIFICATION.BIODYNAMICLABEL.DEMETER) ``` +__Remark:__ To get a list of possible values you can browse our [VocBench](https://vocbench.datafoodconsortium.org/vocbench3/) (you must register and ask an admin for permission). To ease this process we have planned to publish another tool which does not require registration ([ShowVoc](http://showvoc.uniroma2.it/)). Alternatively we would generate a documentation listing the different taxons. + To finish you can export the DFC object to JSON-LD with: -``` +```RB puts connector.export(tomato) ``` @@ -51,16 +56,20 @@ This will output DFC compliant valid JSON-LD: ```JSON { "@context": "http://static.datafoodconsortium.org/ontologies/context.json", + "@id": "https://myplatform.com/tomato", "@type": "dfc-b:SuppliedProduct", "dfc-b:name": "Tomato", "dfc-b:description": "Awesome tomato", + "dfc-b:alcoholPercentage": 0.0, + "dfc-b:lifetime": "", + "dfc-b:usageOrStorageCondition": "", "dfc-b:hasCertification": "dfc-f:Demeter", - "@id": "https://myplatform.com/tomato" + "dfc-b:totalTheoreticalStock": 0.0 } ``` __Important:__ Please note that the exporter does not dereference the objects. If you want to include them in the output, just pass these objects to the `export` method: -``` +```RB puts connector.export(catalogItem, tomato) ``` @@ -75,12 +84,153 @@ This will append the added object into the `@graph`: "@id": "https://myplatform.com/catalogItem" }, { + "@id": "https://myplatform.com/tomato", "@type": "dfc-b:SuppliedProduct", "dfc-b:name": "Tomato", "dfc-b:description": "Awesome tomato", + "dfc-b:alcoholPercentage": 0.0, + "dfc-b:lifetime": "", + "dfc-b:usageOrStorageCondition": "", "dfc-b:hasCertification": "dfc-f:Demeter", - "@id": "https://myplatform.com/tomato" + "dfc-b:totalTheoreticalStock": 0.0 } ] } -``` \ No newline at end of file +``` + +## Complete example + +This example demonstrates how to export a producer's data in JSON-LD like required by the [DFC 1.7.1 practical example](https://datafoodconsortium.gitbook.io/dfc-standard-documentation/appendixes/practical-examples/version-1.7). + +```RB +# Customer category defined by the Enterprise. +customerCategory = DataFoodConsortium::Connector::CustomerCategory.new( + "https://myplatform.com/cc", + description: "description" +) + +# SuppliedProduct suppled by the Enterprise. +suppliedProduct = DataFoodConsortium::Connector::SuppliedProduct.new( + "https://myplatform.com/sp", + name: "name", + description: "description", + productType: connector.PRODUCT_TYPES.VEGETABLE.ARTICHOKE, + quantity: DataFoodConsortium::Connector::QuantitativeValue.new( + unit: connector.MEASURES.UNIT.QUANTITYUNIT.KILOGRAM, + value: 1.2 + ), + totalTheoreticalStock: 123, + alcoholPercentage: 2.6, + lifetime: "lifetime", + usageOrStorageConditions: "usageOrStorageConditions", + certifications: [connector.FACETS.CERTIFICATION.BIODYNAMICLABEL.DEMETER], + claims: [ + connector.FACETS.CLAIM.NUTRITIONALCLAIM.ENERGYFREE, + connector.FACETS.CLAIM.NUTRITIONALCLAIM.FATFREE, + connector.FACETS.CLAIM.NUTRITIONALCLAIM.HIGHFIBRE + ], + allergenCharacteristics: [ + + ], + nutrientCharacteristics: [ + DataFoodConsortium::Connector::NutrientCharacteristic.new( + nutrientDimension: connector.MEASURES.DIMENSION.NUTRIENTDIMENSION.CALCIUM, + unit: connector.MEASURES.UNIT.QUANTITYUNIT.GRAM, + value: 8.47 + ) + ], + physicalCharacteristics: [ + DataFoodConsortium::Connector::PhysicalCharacteristic.new( + physicalDimension: connector.MEASURES.DIMENSION.PHYSICALDIMENSION.WEIGHT, + unit: connector.MEASURES.UNIT.QUANTITYUNIT.KILOGRAM, + value: 3.25 + ) + ], + geographicalOrigin: connector.FACETS.TERRITORIALORIGIN.EUROPE.FRANCE.NORMANDY, + natureOrigin: connector.FACETS.NATUREORIGIN.PLANTORIGIN, + partOrigin: connector.FACETS.NATUREORIGIN.PLANTORIGIN +) + +# The Offer sell a CatalogItem for a price to a CustomerCategory. +offer = DataFoodConsortium::Connector::Offer.new( + "https://myplatform.com/o", + price: DataFoodConsortium::Connector::Price.new( + value: 12.78, + vatRate: 5.22, + unit: connector.MEASURES.UNIT.CURRENCYUNIT.EURO + ), + stockLimitation: 52, + offeredTo: customerCategory +) + +# The CatalogItem holds the stock limitation and allows the product to be sold through an Offer. +catalogItem = DataFoodConsortium::Connector::CatalogItem.new( + "https://myplatform.com/ci", + product: suppliedProduct, + sku: "sku", + stockLimitation: 10, + offers: [offer] +) + +# The Enterprise that the producer is affiliated to. +enterprise = DataFoodConsortium::Connector::Enterprise.new( + "https://myplatform.com/e", + name: "name", + description: "description", + vatNumber: "vatNumber", + customerCategories: [customerCategory], + suppliedProducts: [suppliedProduct], + catalogItems: [catalogItem], +) + +# Address of the producer. +address = DataFoodConsortium::Connector::Address.new( + "https://myplatform.com/a", + street: "street", + postalCode: "postalCode", + city: "city", + country: "country" +) + +# The producer itself. +person = DataFoodConsortium::Connector::Person.new( + "https://myplatform.com/p", + firstName: "firstName", + lastName: "lastName", + affiliatedOrganizations: [enterprise], + localizations: [address] +) +``` + +To export all of these information into JSON-LD, use: +```RB +connector.export( + person, + address, + enterprise, + customerCategory, + suppliedProduct, + catalogItem, + offer +) +``` + +## Documentation + +A basic documentation could be generated with [Yard](https://yardoc.org/). + +You could install it with `gem install yard`. + +To produce the documentation just type `yard doc`. Then open the `index.html` file in the `/doc` folder. + +## Tests + +Some unit tests are in the `/test` folder. + +To run them, just type `rake`. + +## Contributing + +Contributions are welcome. + +The Pull Requests should be made on our [source code generator repository](https://github.com/datafoodconsortium/connector-codegen-ruby) as the code hosted on this repository is generated. diff --git a/connector.gemspec b/connector.gemspec index 919c9cc..183b11d 100644 --- a/connector.gemspec +++ b/connector.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = "datafoodconsortium-connector" - s.version = "1.0.0-alpha.4" + s.version = "1.0.0-alpha.5" s.summary = "Data Food Consortium connector" s.description = "A library to easily integrate the DFC standard within your application." s.authors = ["Maxime Lecoq"] @@ -10,7 +10,7 @@ Gem::Specification.new do |s| "https://github.com/datafoodconsortium/connector-ruby/" s.license = "MIT" - s.add_runtime_dependency "virtual_assembly-semantizer", "~> 1.0", ">= 1.0.2" + s.add_runtime_dependency "virtual_assembly-semantizer", "~> 1.0", ">= 1.0.3" s.add_development_dependency "minitest" s.add_development_dependency "rake" end diff --git a/lib/datafoodconsortium/connector.rb b/lib/datafoodconsortium/connector.rb index 31c0807..0e70d46 100644 --- a/lib/datafoodconsortium/connector.rb +++ b/lib/datafoodconsortium/connector.rb @@ -6,26 +6,27 @@ module Connector require 'datafoodconsortium/connector/skos_parser' require 'datafoodconsortium/connector/agent.rb' require 'datafoodconsortium/connector/enterprise.rb' - require 'datafoodconsortium/connector/customer_category.rb' require 'datafoodconsortium/connector/person.rb' + require 'datafoodconsortium/connector/customer_category.rb' + require 'datafoodconsortium/connector/offer.rb' require 'datafoodconsortium/connector/repository.rb' - require 'datafoodconsortium/connector/catalog_item.rb' + require 'datafoodconsortium/connector/price.rb' require 'datafoodconsortium/connector/order.rb' - require 'datafoodconsortium/connector/offer.rb' + require 'datafoodconsortium/connector/catalog_item.rb' require 'datafoodconsortium/connector/order_line.rb' - require 'datafoodconsortium/connector/address.rb' - require 'datafoodconsortium/connector/geographical_origin.rb' - require 'datafoodconsortium/connector/physical_characteristic.rb' require 'datafoodconsortium/connector/allergen_dimension.rb' - require 'datafoodconsortium/connector/allergen_characteristic.rb' - require 'datafoodconsortium/connector/nutrient_characteristic.rb' require 'datafoodconsortium/connector/characteristic.rb' - require 'datafoodconsortium/connector/product_type.rb' + require 'datafoodconsortium/connector/address.rb' + require 'datafoodconsortium/connector/characteristic_dimension.rb' + require 'datafoodconsortium/connector/nutrient_characteristic.rb' require 'datafoodconsortium/connector/part_origin.rb' - require 'datafoodconsortium/connector/quantitative_value.rb' require 'datafoodconsortium/connector/unit.rb' + require 'datafoodconsortium/connector/quantitative_value.rb' require 'datafoodconsortium/connector/certification.rb' - require 'datafoodconsortium/connector/characteristic_dimension.rb' + require 'datafoodconsortium/connector/product_type.rb' + require 'datafoodconsortium/connector/physical_characteristic.rb' + require 'datafoodconsortium/connector/allergen_characteristic.rb' + require 'datafoodconsortium/connector/geographical_origin.rb' require 'datafoodconsortium/connector/nature_origin.rb' require 'datafoodconsortium/connector/defined_product.rb' require 'datafoodconsortium/connector/supplied_product.rb' diff --git a/lib/datafoodconsortium/connector/address.rb b/lib/datafoodconsortium/connector/address.rb index b999896..4bf7387 100644 --- a/lib/datafoodconsortium/connector/address.rb +++ b/lib/datafoodconsortium/connector/address.rb @@ -27,19 +27,30 @@ class DataFoodConsortium::Connector::Address include VirtualAssembly::Semantizer::SemanticObject + # @return [String] attr_accessor :street + + # @return [String] attr_accessor :postalCode + + # @return [String] attr_accessor :city + + # @return [String] attr_accessor :country - def initialize(street, postalCode, city, country) - super() + # @param semanticId [String] + # @param street [String] + # @param postalCode [String] + # @param city [String] + # @param country [String] + def initialize(semanticId, street: "", postalCode: "", city: "", country: "") + super(semanticId) + @street = street + @postalCode = postalCode + @city = city + @country = country self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#Address" - self.street = street - self.postalCode = postalCode - self.city = city - self.country = country - registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasStreet") { self.street } registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasPostalCode") { self.postalCode } registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasCity") { self.city } diff --git a/lib/datafoodconsortium/connector/agent.rb b/lib/datafoodconsortium/connector/agent.rb index 54f69e6..53baa4b 100644 --- a/lib/datafoodconsortium/connector/agent.rb +++ b/lib/datafoodconsortium/connector/agent.rb @@ -29,33 +29,42 @@ class DataFoodConsortium::Connector::Agent include VirtualAssembly::Semantizer::SemanticObject + # @return [Contactable] attr_accessor :contacts + + # @return [Localizable] attr_accessor :localizations - def initialize() - super() + # @param semanticId [String] + # @param contacts [Contactable] + # @param localizations [Localizable] + def initialize(semanticId, contacts: [], localizations: []) + super(semanticId) + @contacts = contacts + @localizations = localizations self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#Agent" - - self.contacts = [] - self.localizations = [] registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasAddress") { self.localizations } end + def addContact(contact) self.contacts.push(contact) end + def addLocalization(localization) self.localizations.push(localization) end + def removeContact(contact) - raise "Not implemented" + raise "Not yet implemented." end + def removeLocalization(localization) - raise "Not implemented" + raise "Not yet implemented." end diff --git a/lib/datafoodconsortium/connector/allergen_characteristic.rb b/lib/datafoodconsortium/connector/allergen_characteristic.rb index 938db42..2efdd88 100644 --- a/lib/datafoodconsortium/connector/allergen_characteristic.rb +++ b/lib/datafoodconsortium/connector/allergen_characteristic.rb @@ -21,22 +21,25 @@ # SOFTWARE. +require "datafoodconsortium/connector/characteristic" -require "datafoodconsortium/connector/characteristic" require "virtual_assembly/semantizer" class DataFoodConsortium::Connector::AllergenCharacteristic < DataFoodConsortium::Connector::Characteristic + # @return [IAllergenDimension] attr_accessor :allergenDimension - def initialize(quantityUnit, quantityValue, allergenDimension) - super(quantityUnit, quantityValue) + # @param allergenDimension [IAllergenDimension] + # @param unit [IUnit] + # @param value [Real] + def initialize(allergenDimension: nil, unit: nil, value: 0.0) + super(unit: unit, value: value) + @allergenDimension = allergenDimension self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#AllergenCharacteristic" - self.allergenDimension = allergenDimension - registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasAllergenDimension") { self.allergenDimension } end diff --git a/lib/datafoodconsortium/connector/allergen_dimension.rb b/lib/datafoodconsortium/connector/allergen_dimension.rb index a502aa7..8805225 100644 --- a/lib/datafoodconsortium/connector/allergen_dimension.rb +++ b/lib/datafoodconsortium/connector/allergen_dimension.rb @@ -20,8 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - require "datafoodconsortium/connector/characteristic_dimension" + require "virtual_assembly/semantizer" class DataFoodConsortium::Connector::AllergenDimension < DataFoodConsortium::Connector::CharacteristicDimension diff --git a/lib/datafoodconsortium/connector/catalog_item.rb b/lib/datafoodconsortium/connector/catalog_item.rb index 3a1916e..b99f844 100644 --- a/lib/datafoodconsortium/connector/catalog_item.rb +++ b/lib/datafoodconsortium/connector/catalog_item.rb @@ -29,18 +29,30 @@ class DataFoodConsortium::Connector::CatalogItem include VirtualAssembly::Semantizer::SemanticObject + # @return [IDefinedProduct] attr_accessor :product + + # @return [String] attr_accessor :sku + + # @return [Real] attr_accessor :stockLimitation + + # @return [IOffer] attr_accessor :offers - def initialize(product) - super() + # @param semanticId [String] + # @param product [IDefinedProduct] + # @param sku [String] + # @param stockLimitation [Real] + # @param offers [IOffer] + def initialize(semanticId, product: nil, sku: "", stockLimitation: 0.0, offers: []) + super(semanticId) + @product = product + @sku = sku + @stockLimitation = stockLimitation + @offers = offers self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#CatalogItem" - self.product = product - self.sku = nil - self.stockLimitation = nil - self.offers = [] registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#references") { self.product } registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#sku") { self.sku } registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#stockLimitation") { self.stockLimitation } @@ -50,13 +62,7 @@ def initialize(product) - def addOffer(offer) - self.offers.push(offer) - end - def addOffer(offer) - self.offers.push(offer) - end end diff --git a/lib/datafoodconsortium/connector/certification.rb b/lib/datafoodconsortium/connector/certification.rb index 8ece5d2..4130c57 100644 --- a/lib/datafoodconsortium/connector/certification.rb +++ b/lib/datafoodconsortium/connector/certification.rb @@ -20,8 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - require "datafoodconsortium/connector/skos_concept" + require "virtual_assembly/semantizer" class DataFoodConsortium::Connector::Certification < DataFoodConsortium::Connector::SKOSConcept diff --git a/lib/datafoodconsortium/connector/characteristic.rb b/lib/datafoodconsortium/connector/characteristic.rb index b84d6fe..5c18f38 100644 --- a/lib/datafoodconsortium/connector/characteristic.rb +++ b/lib/datafoodconsortium/connector/characteristic.rb @@ -23,6 +23,7 @@ require "datafoodconsortium/connector/quantitative_value" + require "virtual_assembly/semantizer" class DataFoodConsortium::Connector::Characteristic < DataFoodConsortium::Connector::QuantitativeValue @@ -30,9 +31,10 @@ class DataFoodConsortium::Connector::Characteristic < DataFoodConsortium::Connec - def initialize(quantityUnit, quantityValue) - super(quantityUnit, quantityValue) - + # @param unit [IUnit] + # @param value [Real] + def initialize(unit: nil, value: 0.0) + super(unit: unit, value: value) diff --git a/lib/datafoodconsortium/connector/customer_category.rb b/lib/datafoodconsortium/connector/customer_category.rb index 8537c4a..893ea7e 100644 --- a/lib/datafoodconsortium/connector/customer_category.rb +++ b/lib/datafoodconsortium/connector/customer_category.rb @@ -27,16 +27,15 @@ class DataFoodConsortium::Connector::CustomerCategory include VirtualAssembly::Semantizer::SemanticObject - attr_accessor :name + # @return [String] attr_accessor :description - def initialize(name, description) - super() + # @param semanticId [String] + # @param description [String] + def initialize(semanticId, description: "") + super(semanticId) + @description = description self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#CustomerCategory" - self.name = name - self.description = description - - registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#name") { self.name } registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#description") { self.description } end diff --git a/lib/datafoodconsortium/connector/defined_product.rb b/lib/datafoodconsortium/connector/defined_product.rb index 9e7de32..d04b948 100644 --- a/lib/datafoodconsortium/connector/defined_product.rb +++ b/lib/datafoodconsortium/connector/defined_product.rb @@ -38,42 +38,90 @@ class DataFoodConsortium::Connector::DefinedProduct include VirtualAssembly::Semantizer::SemanticObject + # @return [String] attr_accessor :name + + # @return [String] attr_accessor :description + + # @return [IProductType] attr_accessor :productType + + # @return [Quantifiable] attr_accessor :quantity + + # @return [Real] attr_accessor :alcoholPercentage + + # @return [String] attr_accessor :lifetime + + # @return [Claimable] attr_accessor :claims + + # @return [String] attr_accessor :usageOrStorageConditions + + # @return [IAllergenCharacteristic] attr_accessor :allergenCharacteristics + + # @return [INutrientCharacteristic] attr_accessor :nutrientCharacteristics + + # @return [IPhysicalCharacteristic] attr_accessor :physicalCharacteristics + + # @return [IGeographicalOrigin] attr_accessor :geographicalOrigin + + # @return [ICatalogItem] attr_accessor :catalogItems + + # @return [ICertification] attr_accessor :certifications + + # @return [INatureOrigin] attr_accessor :natureOrigin + + # @return [IPartOrigin] attr_accessor :partOrigin - def initialize(name, description) - super() + # @param semanticId [String] + # @param name [String] + # @param description [String] + # @param productType [IProductType] + # @param quantity [Quantifiable] + # @param alcoholPercentage [Real] + # @param lifetime [String] + # @param claims [Claimable] + # @param usageOrStorageConditions [String] + # @param allergenCharacteristics [IAllergenCharacteristic] + # @param nutrientCharacteristics [INutrientCharacteristic] + # @param physicalCharacteristics [IPhysicalCharacteristic] + # @param geographicalOrigin [IGeographicalOrigin] + # @param catalogItems [ICatalogItem] + # @param certifications [ICertification] + # @param natureOrigin [INatureOrigin] + # @param partOrigin [IPartOrigin] + def initialize(semanticId, name: "", description: "", productType: nil, quantity: nil, alcoholPercentage: 0.0, lifetime: "", claims: [], usageOrStorageConditions: "", allergenCharacteristics: [], nutrientCharacteristics: [], physicalCharacteristics: [], geographicalOrigin: nil, catalogItems: [], certifications: [], natureOrigin: [], partOrigin: []) + super(semanticId) + @name = name + @description = description + @productType = productType + @quantity = quantity + @alcoholPercentage = alcoholPercentage + @lifetime = lifetime + @claims = claims + @usageOrStorageConditions = usageOrStorageConditions + @allergenCharacteristics = allergenCharacteristics + @nutrientCharacteristics = nutrientCharacteristics + @physicalCharacteristics = physicalCharacteristics + @geographicalOrigin = geographicalOrigin + @catalogItems = catalogItems + @certifications = certifications + @natureOrigin = natureOrigin + @partOrigin = partOrigin self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#DefinedProduct" - self.name = name - self.description = description - self.productType = nil - self.quantity = nil - self.alcoholPercentage = nil - self.lifetime = nil - self.claims = [] - self.usageOrStorageConditions = nil - self.allergenCharacteristics = [] - self.nutrientCharacteristics = [] - self.physicalCharacteristics = [] - self.geographicalOrigin = nil - self.catalogItems = [] - self.certifications = [] - self.natureOrigin = [] - self.partOrigin = [] registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#name") { self.name } registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#description") { self.description } registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasType") { self.productType } @@ -93,64 +141,79 @@ def initialize(name, description) end + def addClaim(claim) self.claims.push(claim) end + def removeClaim(claim) - raise "Not implemented" + raise "Not yet implemented." end + def addAllergenCharacteristic(allergenCharacteristic) self.allergenCharacteristics.push(allergenCharacteristic) end + def addNutrientCharacteristic(nutrientCharacteristic) self.nutrientCharacteristics.push(nutrientCharacteristic) end + def addPhysicalCharacteristic(physicalCharacteristic) self.physicalCharacteristics.push(physicalCharacteristic) end + def addNatureOrigin(natureOrigin) self.natureOrigin.push(natureOrigin) end + def addPartOrigin(partOrigin) self.partOrigin.push(partOrigin) end + def removeAllergenCharacteristic(allergenCharacteristic) - raise "Not implemented" + raise "Not yet implemented." end + def removeNutrientCharacteristic(nutrientCharacteristic) - raise "Not implemented" + raise "Not yet implemented." end + def removePhysicalCharacteristic(physicalCharacteristic) - raise "Not implemented" + raise "Not yet implemented." end + def removeNatureOrigin(natureOrigin) - raise "Not implemented" + raise "Not yet implemented." end + def removePartOrigin(partOrigin) - raise "Not implemented" + raise "Not yet implemented." end + def addCatalogItem(catalogItem) self.catalogItems.push(catalogItem) end + def addCertification(certification) self.certifications.push(certification) end + def removeCertification(certification) - raise "Not implemented" + raise "Not yet implemented." end diff --git a/lib/datafoodconsortium/connector/enterprise.rb b/lib/datafoodconsortium/connector/enterprise.rb index 5dab7a4..7b8a7fa 100644 --- a/lib/datafoodconsortium/connector/enterprise.rb +++ b/lib/datafoodconsortium/connector/enterprise.rb @@ -20,35 +20,55 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +require "datafoodconsortium/connector/supplied_product" -require "datafoodconsortium/connector/supplied_product" - require "datafoodconsortium/connector/agent" + require "virtual_assembly/semantizer" class DataFoodConsortium::Connector::Enterprise < DataFoodConsortium::Connector::Agent + # @return [String] attr_accessor :name + + # @return [String] attr_accessor :description + + # @return [String] attr_accessor :vatNumber + + # @return [ICustomerCategory] attr_accessor :customerCategories + + # @return [SuppliedProduct] attr_accessor :suppliedProducts + + # @return [ICatalogItem] attr_accessor :catalogItems - def initialize(name) - super() + # @param semanticId [String] + # @param name [String] + # @param description [String] + # @param vatNumber [String] + # @param customerCategories [ICustomerCategory] + # @param suppliedProducts [SuppliedProduct] + # @param catalogItems [ICatalogItem] + # @param contacts [Contactable] + # @param localizations [Localizable] + def initialize(semanticId, name: "", description: "", vatNumber: "", customerCategories: [], suppliedProducts: [], catalogItems: [], contacts: [], localizations: []) + super(semanticId, contacts: contacts, localizations: localizations) + @name = name + @description = description + @vatNumber = vatNumber + @customerCategories = customerCategories + @suppliedProducts = suppliedProducts + @catalogItems = catalogItems self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#Enterprise" - self.name = name - self.description = nil - self.vatNumber = nil - self.customerCategories = [] - self.suppliedProducts = [] - self.catalogItems = [] registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasName") { self.name } registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasDescription") { self.description } registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#VATnumber") { self.vatNumber } @@ -58,25 +78,6 @@ def initialize(name) end - def addCustomerCategory(customerCategory) - self.customerCategories.push(customerCategory) - end - - def addSupplyProduct(suppliedProduct) - self.suppliedProducts.push(suppliedProduct) - end - - def addCatalogItem(catalogItem) - self.catalogItems.push(catalogItem) - end - - def addSupplyProduct(suppliedProduct) - self.suppliedProducts.push(suppliedProduct) - end - - def addCatalogItem(catalogItem) - self.catalogItems.push(catalogItem) - end def addCustomerCategory(customerCategory) self.customerCategories.push(customerCategory) diff --git a/lib/datafoodconsortium/connector/geographical_origin.rb b/lib/datafoodconsortium/connector/geographical_origin.rb index 562b23e..ca3051a 100644 --- a/lib/datafoodconsortium/connector/geographical_origin.rb +++ b/lib/datafoodconsortium/connector/geographical_origin.rb @@ -20,8 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - require "datafoodconsortium/connector/skos_concept" + require "virtual_assembly/semantizer" class DataFoodConsortium::Connector::GeographicalOrigin < DataFoodConsortium::Connector::SKOSConcept diff --git a/lib/datafoodconsortium/connector/nutrient_characteristic.rb b/lib/datafoodconsortium/connector/nutrient_characteristic.rb index a7162b0..da642bb 100644 --- a/lib/datafoodconsortium/connector/nutrient_characteristic.rb +++ b/lib/datafoodconsortium/connector/nutrient_characteristic.rb @@ -22,21 +22,24 @@ - require "datafoodconsortium/connector/characteristic" + require "virtual_assembly/semantizer" class DataFoodConsortium::Connector::NutrientCharacteristic < DataFoodConsortium::Connector::Characteristic + # @return [INutrientDimension] attr_accessor :nutrientDimension - def initialize(quantityUnit, quantityValue, nutrientDimension) - super(quantityUnit, quantityValue) + # @param nutrientDimension [INutrientDimension] + # @param unit [IUnit] + # @param value [Real] + def initialize(nutrientDimension: nil, unit: nil, value: 0.0) + super(unit: unit, value: value) + @nutrientDimension = nutrientDimension self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#NutrientCharacteristic" - self.nutrientDimension = nutrientDimension - registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasNutrientDimension") { self.nutrientDimension } end diff --git a/lib/datafoodconsortium/connector/offer.rb b/lib/datafoodconsortium/connector/offer.rb index 44628e1..a16848e 100644 --- a/lib/datafoodconsortium/connector/offer.rb +++ b/lib/datafoodconsortium/connector/offer.rb @@ -29,18 +29,30 @@ class DataFoodConsortium::Connector::Offer include VirtualAssembly::Semantizer::SemanticObject + # @return [IPrice] attr_accessor :price + + # @return [Real] attr_accessor :stockLimitation + + # @return [ICatalogItem] attr_accessor :offeredItem + + # @return [ICustomerCategory] attr_accessor :offeredTo - def initialize(offeredItem, offeredTo) - super() + # @param semanticId [String] + # @param price [IPrice] + # @param stockLimitation [Real] + # @param offeredItem [ICatalogItem] + # @param offeredTo [ICustomerCategory] + def initialize(semanticId, price: nil, stockLimitation: 0.0, offeredItem: nil, offeredTo: nil) + super(semanticId) + @price = price + @stockLimitation = stockLimitation + @offeredItem = offeredItem + @offeredTo = offeredTo self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#Offer" - self.offeredItem = offeredItem - self.offeredTo = offeredTo - self.price = nil - self.stockLimitation = nil registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#price") { self.price } registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#stockLimitation") { self.stockLimitation } registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#offeredItem") { self.offeredItem } @@ -48,9 +60,6 @@ def initialize(offeredItem, offeredTo) end - def addOffer(offer) - self..push(offer) - end end diff --git a/lib/datafoodconsortium/connector/part_origin.rb b/lib/datafoodconsortium/connector/part_origin.rb index 8d949d9..06ab1ce 100644 --- a/lib/datafoodconsortium/connector/part_origin.rb +++ b/lib/datafoodconsortium/connector/part_origin.rb @@ -20,8 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - require "datafoodconsortium/connector/skos_concept" + require "virtual_assembly/semantizer" class DataFoodConsortium::Connector::PartOrigin < DataFoodConsortium::Connector::SKOSConcept diff --git a/lib/datafoodconsortium/connector/person.rb b/lib/datafoodconsortium/connector/person.rb index 904a9f2..334db0c 100644 --- a/lib/datafoodconsortium/connector/person.rb +++ b/lib/datafoodconsortium/connector/person.rb @@ -29,28 +29,41 @@ class DataFoodConsortium::Connector::Person < DataFoodConsortium::Connector::Age + # @return [String] attr_accessor :firstName + + # @return [String] attr_accessor :lastName + + # @return [Onboardable] attr_accessor :affiliatedOrganizations - def initialize(firstName, lastName) - super() + # @param semanticId [String] + # @param firstName [String] + # @param lastName [String] + # @param affiliatedOrganizations [Onboardable] + # @param contacts [Contactable] + # @param localizations [Localizable] + def initialize(semanticId, firstName: "", lastName: "", affiliatedOrganizations: [], contacts: [], localizations: []) + super(semanticId, contacts: contacts, localizations: localizations) + @firstName = firstName + @lastName = lastName + @affiliatedOrganizations = affiliatedOrganizations self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#Person" - self.firstName = firstName - self.lastName = lastName - self.affiliatedOrganizations = [] registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#firstName") { self.firstName } registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#familyName") { self.lastName } registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#affiliates") { self.affiliatedOrganizations } end + def affiliateTo(organization) self.affiliatedOrganizations.push(organization) end + def leaveAffiliatedOrganization(organization) - raise "Not implemented" + raise "Not yet implemented." end diff --git a/lib/datafoodconsortium/connector/physical_characteristic.rb b/lib/datafoodconsortium/connector/physical_characteristic.rb index 0e0799f..3e4aad3 100644 --- a/lib/datafoodconsortium/connector/physical_characteristic.rb +++ b/lib/datafoodconsortium/connector/physical_characteristic.rb @@ -20,9 +20,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +require "datafoodconsortium/connector/characteristic" -require "datafoodconsortium/connector/characteristic" require "virtual_assembly/semantizer" @@ -30,13 +30,16 @@ class DataFoodConsortium::Connector::PhysicalCharacteristic < DataFoodConsortium + # @return [IPhysicalDimension] attr_accessor :physicalDimension - def initialize(quantityUnit, quantityValue, physicalDimension) - super(quantityUnit, quantityValue) + # @param physicalDimension [IPhysicalDimension] + # @param unit [IUnit] + # @param value [Real] + def initialize(physicalDimension: nil, unit: nil, value: 0.0) + super(unit: unit, value: value) + @physicalDimension = physicalDimension self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#PhysicalCharacteristic" - self.physicalDimension = physicalDimension - registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasPhysicalDimension") { self.physicalDimension } end diff --git a/lib/datafoodconsortium/connector/price.rb b/lib/datafoodconsortium/connector/price.rb new file mode 100644 index 0000000..8721186 --- /dev/null +++ b/lib/datafoodconsortium/connector/price.rb @@ -0,0 +1,55 @@ +# MIT License +# +# Copyright (c) 2023 Maxime Lecoq +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +require "virtual_assembly/semantizer" + +class DataFoodConsortium::Connector::Price + + include VirtualAssembly::Semantizer::SemanticObject + + # @return [Real] + attr_accessor :value + + # @return [Real] + attr_accessor :vatRate + + # @return [IUnit] + attr_accessor :unit + + # @param value [Real] + # @param vatRate [Real] + # @param unit [IUnit] + def initialize(value: 0.0, vatRate: 0.0, unit: nil) + super() + @value = value + @vatRate = vatRate + @unit = unit + self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#Price" + registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#value") { self.value } + registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#VATrate") { self.vatRate } + registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasUnit") { self.unit } + end + + + +end diff --git a/lib/datafoodconsortium/connector/quantitative_value.rb b/lib/datafoodconsortium/connector/quantitative_value.rb index 5b326d4..e273fbc 100644 --- a/lib/datafoodconsortium/connector/quantitative_value.rb +++ b/lib/datafoodconsortium/connector/quantitative_value.rb @@ -21,23 +21,28 @@ # SOFTWARE. + require "virtual_assembly/semantizer" class DataFoodConsortium::Connector::QuantitativeValue include VirtualAssembly::Semantizer::SemanticObject - attr_accessor :quantityUnit - attr_accessor :quantityValue + # @return [IUnit] + attr_accessor :unit + + # @return [Real] + attr_accessor :value - def initialize(quantityUnit, quantityValue) + # @param unit [IUnit] + # @param value [Real] + def initialize(unit: nil, value: 0.0) super() + @unit = unit + @value = value self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#QuantitativeValue" - self.quantityUnit = quantityUnit - self.quantityValue = quantityValue - - registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasUnit") { self.quantityUnit } - registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#value") { self.quantityValue } + registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasUnit") { self.unit } + registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#value") { self.value } end diff --git a/lib/datafoodconsortium/connector/skos_concept.rb b/lib/datafoodconsortium/connector/skos_concept.rb index 476653c..6624c8f 100644 --- a/lib/datafoodconsortium/connector/skos_concept.rb +++ b/lib/datafoodconsortium/connector/skos_concept.rb @@ -29,19 +29,29 @@ class DataFoodConsortium::Connector::SKOSConcept include VirtualAssembly::Semantizer::SemanticObject + # @return [ISKOSConcept] attr_accessor :broaders + + # @return [ISKOSConceptScheme] attr_accessor :schemes + + # @return [ISKOSConcept] attr_accessor :narrowers + + # @return [ISKOSLabel] attr_accessor :prefLabels - def initialize() + # @param broaders [ISKOSConcept] + # @param schemes [ISKOSConceptScheme] + # @param narrowers [ISKOSConcept] + # @param prefLabels [ISKOSLabel] + def initialize(broaders: [], schemes: [], narrowers: [], prefLabels: []) super() + @broaders = broaders + @schemes = schemes + @narrowers = narrowers + @prefLabels = prefLabels self.semanticType = "http://www.w3.org/2004/02/skos/core#Concept" - - self.broaders = [] - self.schemes = [] - self.narrowers = [] - self.prefLabels = [] registerSemanticProperty("http://www.w3.org/2004/02/skos/core#broader") { self.broaders } registerSemanticProperty("http://www.w3.org/2004/02/skos/core#inScheme") { self.schemes } registerSemanticProperty("http://www.w3.org/2004/02/skos/core#narrower") { self.narrowers } @@ -49,36 +59,28 @@ def initialize() end - def addBroader(broader) - self.broaders.push(broader) - end - def addScheme(scheme) - self.schemes.push(scheme) - end - def addNarrower(narrower) - self.narrowers.push(narrower) - end - def addPrefLabel(prefLabel) - self.prefLabels.push(prefLabel) - end + def removeBroader(broader) - raise "Not implemented" + raise "Not yet implemented." end + def removeScheme(scheme) - raise "Not implemented" + raise "Not yet implemented." end + def removeNarrower(narrower) - raise "Not implemented" + raise "Not yet implemented." end + def removePrefLabel(prefLabel) - raise "Not implemented" + raise "Not yet implemented." end diff --git a/lib/datafoodconsortium/connector/supplied_product.rb b/lib/datafoodconsortium/connector/supplied_product.rb index 6c73c56..a52ce2c 100644 --- a/lib/datafoodconsortium/connector/supplied_product.rb +++ b/lib/datafoodconsortium/connector/supplied_product.rb @@ -27,15 +27,38 @@ class DataFoodConsortium::Connector::SuppliedProduct < DataFoodConsortium::Conne + # @return [Real] + attr_accessor :totalTheoreticalStock - def initialize(name, description) - super(name, description) + # @param semanticId [String] + # @param totalTheoreticalStock [Real] + # @param name [String] + # @param description [String] + # @param productType [IProductType] + # @param quantity [Quantifiable] + # @param alcoholPercentage [Real] + # @param lifetime [String] + # @param claims [Claimable] + # @param usageOrStorageConditions [String] + # @param allergenCharacteristics [IAllergenCharacteristic] + # @param nutrientCharacteristics [INutrientCharacteristic] + # @param physicalCharacteristics [IPhysicalCharacteristic] + # @param geographicalOrigin [IGeographicalOrigin] + # @param catalogItems [ICatalogItem] + # @param certifications [ICertification] + # @param natureOrigin [INatureOrigin] + # @param partOrigin [IPartOrigin] + def initialize(semanticId, totalTheoreticalStock: 0.0, name: "", description: "", productType: nil, quantity: nil, alcoholPercentage: 0.0, lifetime: "", claims: [], usageOrStorageConditions: "", allergenCharacteristics: [], nutrientCharacteristics: [], physicalCharacteristics: [], geographicalOrigin: nil, catalogItems: [], certifications: [], natureOrigin: [], partOrigin: []) + super(semanticId, name: name, description: description, productType: productType, quantity: quantity, alcoholPercentage: alcoholPercentage, lifetime: lifetime, claims: claims, usageOrStorageConditions: usageOrStorageConditions, allergenCharacteristics: allergenCharacteristics, nutrientCharacteristics: nutrientCharacteristics, physicalCharacteristics: physicalCharacteristics, geographicalOrigin: geographicalOrigin, catalogItems: catalogItems, certifications: certifications, natureOrigin: natureOrigin, partOrigin: partOrigin) + @totalTheoreticalStock = totalTheoreticalStock self.semanticType = "http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#SuppliedProduct" - - - + registerSemanticProperty("http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#totalTheoreticalStock") { self.totalTheoreticalStock } end + + + + end diff --git a/test/connector.rb b/test/connector.rb new file mode 100644 index 0000000..98136f1 --- /dev/null +++ b/test/connector.rb @@ -0,0 +1,17 @@ +require 'datafoodconsortium/connector' + +def connector + @connector ||= DataFoodConsortium::Connector::Connector.instance.tap do |c| + c.loadMeasures(parse_json_file("measures.json")) + c.loadFacets(parse_json_file("facets.json")) + c.loadProductTypes(parse_json_file("productTypes.json")) + end +end + +def parse_json_file(name) + JSON.parse( + File.read( + File.join(File.dirname(__FILE__), name) + ) + ) +end diff --git a/test/test_address.rb b/test/test_address.rb new file mode 100644 index 0000000..92cd674 --- /dev/null +++ b/test/test_address.rb @@ -0,0 +1,27 @@ +require 'connector' +require "minitest/autorun" +require 'datafoodconsortium/connector' + +class AddressTest < Minitest::Test + + def test_export_empty + a = DataFoodConsortium::Connector::Address.new("https://myplatform.com/a") + actual = connector.export(a) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/a","@type":"dfc-b:Address","dfc-b:hasStreet":"","dfc-b:hasPostalCode":"","dfc-b:hasCity":"","dfc-b:hasCountry":""}' + assert_equal expected, actual + end + + def test_export_complete + a = DataFoodConsortium::Connector::Address.new( + "https://myplatform.com/a", + street: "street", + postalCode: "postalCode", + city: "city", + country: "country" + ) + actual = connector.export(a) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/a","@type":"dfc-b:Address","dfc-b:hasStreet":"street","dfc-b:hasPostalCode":"postalCode","dfc-b:hasCity":"city","dfc-b:hasCountry":"country"}' + assert_equal expected, actual + end + +end \ No newline at end of file diff --git a/test/test_catalog_item.rb b/test/test_catalog_item.rb new file mode 100644 index 0000000..4792083 --- /dev/null +++ b/test/test_catalog_item.rb @@ -0,0 +1,29 @@ +require 'connector' +require "minitest/autorun" +require 'datafoodconsortium/connector' + +class CatalogItemTest < Minitest::Test + + def test_export_empty + ci = DataFoodConsortium::Connector::CatalogItem.new("https://myplatform.com/ci") + actual = connector.export(ci) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/ci","@type":"dfc-b:CatalogItem","dfc-b:sku":"","dfc-b:stockLimitation":0.0}' + assert_equal expected, actual + end + + def test_export_complete + sp = DataFoodConsortium::Connector::CatalogItem.new("https://myplatform.com/sp") + offer = DataFoodConsortium::Connector::CatalogItem.new("https://myplatform.com/o") + ci = DataFoodConsortium::Connector::CatalogItem.new( + "https://myplatform.com/ci", + product: sp, + sku: "sku", + stockLimitation: 10, + offers: [offer] + ) + actual = connector.export(ci) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/ci","@type":"dfc-b:CatalogItem","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#references":"https://myplatform.com/sp","dfc-b:sku":"sku","dfc-b:stockLimitation":10,"http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#offeredThrough":"https://myplatform.com/o"}' + assert_equal expected, actual + end + +end \ No newline at end of file diff --git a/test/test_connector.rb b/test/test_connector.rb deleted file mode 100644 index 793d201..0000000 --- a/test/test_connector.rb +++ /dev/null @@ -1,35 +0,0 @@ -require "minitest/autorun" -require 'datafoodconsortium/connector' - -class ConnectorTest < Minitest::Test - def test_export - tomato = DataFoodConsortium::Connector::SuppliedProduct.new( - "Tomato", "Awesome tomato" - ) - tomato.semanticId = "https://myplatform.com/tomato" - tomato.addCertification(connector.FACETS.CERTIFICATION.BIODYNAMICLABEL.DEMETER) - - exported_tomato = connector.export(tomato) - assert_equal tomato_json, exported_tomato - end - - def connector - @connector ||= DataFoodConsortium::Connector::Connector.instance.tap do |c| - c.loadMeasures(parse_json_file("measures.json")) - c.loadFacets(parse_json_file("facets.json")) - c.loadProductTypes(parse_json_file("productTypes.json")) - end - end - - def parse_json_file(name) - JSON.parse( - File.read( - File.join(File.dirname(__FILE__), name) - ) - ) - end - - def tomato_json - '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@type":"dfc-b:SuppliedProduct","dfc-b:name":"Tomato","dfc-b:description":"Awesome tomato","dfc-b:hasCertification":"dfc-f:Demeter","@id":"https://myplatform.com/tomato"}' - end -end diff --git a/test/test_customer_category.rb b/test/test_customer_category.rb new file mode 100644 index 0000000..0418730 --- /dev/null +++ b/test/test_customer_category.rb @@ -0,0 +1,24 @@ +require 'connector' +require "minitest/autorun" +require 'datafoodconsortium/connector' + +class CustomerCategoryTest < Minitest::Test + + def test_export_empty + cc = DataFoodConsortium::Connector::CustomerCategory.new("https://myplatform.com/cc") + actual = connector.export(cc) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/cc","@type":"dfc-b:CustomerCategory","dfc-b:description":""}' + assert_equal expected, actual + end + + def test_export_complete + cc = DataFoodConsortium::Connector::CustomerCategory.new( + "https://myplatform.com/cc", + description: "description" + ) + actual = connector.export(cc) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/cc","@type":"dfc-b:CustomerCategory","dfc-b:description":"description"}' + assert_equal expected, actual + end + +end \ No newline at end of file diff --git a/test/test_enterprise.rb b/test/test_enterprise.rb new file mode 100644 index 0000000..2865558 --- /dev/null +++ b/test/test_enterprise.rb @@ -0,0 +1,63 @@ +require 'connector' +require "minitest/autorun" +require 'datafoodconsortium/connector' + +class EnterpriseTest < Minitest::Test + + def test_export_empty + e = DataFoodConsortium::Connector::Enterprise.new("https://myplatform.com/e") + actual = connector.export(e) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/e","@type":"dfc-b:Enterprise","dfc-b:hasName":"","dfc-b:hasDescription":"","dfc-b:VATnumber":""}' + assert_equal expected, actual + end + + def test_export_complete + e = DataFoodConsortium::Connector::Enterprise.new( + "https://myplatform.com/e", + name: "name", + description: "description", + vatNumber: "vatNumber", + customerCategories: [ + DataFoodConsortium::Connector::CustomerCategory.new("https://myplatform.com/cc") + ], + suppliedProducts: [ + DataFoodConsortium::Connector::SuppliedProduct.new("https://myplatform.com/sp") + ], + catalogItems: [ + DataFoodConsortium::Connector::CatalogItem.new("https://myplatform.com/ci") + ], + contacts: [], + localizations: [] + ) + actual = connector.export(e) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/e","@type":"dfc-b:Enterprise","dfc-b:hasName":"name","dfc-b:hasDescription":"description","dfc-b:VATnumber":"vatNumber","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#defines":"https://myplatform.com/cc","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#supplies":"https://myplatform.com/sp","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#manages":"https://myplatform.com/ci"}' + assert_equal expected, actual + end + + def test_export_complete_multiple + e = DataFoodConsortium::Connector::Enterprise.new( + "https://myplatform.com/e", + name: "name", + description: "description", + vatNumber: "vatNumber", + customerCategories: [ + DataFoodConsortium::Connector::CustomerCategory.new("https://myplatform.com/cc"), + DataFoodConsortium::Connector::CustomerCategory.new("https://myplatform.com/cc2") + ], + suppliedProducts: [ + DataFoodConsortium::Connector::SuppliedProduct.new("https://myplatform.com/sp"), + DataFoodConsortium::Connector::SuppliedProduct.new("https://myplatform.com/sp2") + ], + catalogItems: [ + DataFoodConsortium::Connector::CatalogItem.new("https://myplatform.com/ci"), + DataFoodConsortium::Connector::CatalogItem.new("https://myplatform.com/ci2") + ], + contacts: [], + localizations: [] + ) + actual = connector.export(e) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/e","@type":"dfc-b:Enterprise","dfc-b:hasName":"name","dfc-b:hasDescription":"description","dfc-b:VATnumber":"vatNumber","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#defines":["https://myplatform.com/cc","https://myplatform.com/cc2"],"http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#supplies":["https://myplatform.com/sp","https://myplatform.com/sp2"],"http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#manages":["https://myplatform.com/ci","https://myplatform.com/ci2"]}' + assert_equal expected, actual + end + +end \ No newline at end of file diff --git a/test/test_export.rb b/test/test_export.rb new file mode 100644 index 0000000..e988f75 --- /dev/null +++ b/test/test_export.rb @@ -0,0 +1,100 @@ +require 'connector' +require "minitest/autorun" +require 'datafoodconsortium/connector' + +class ExportTest < Minitest::Test + + def test_export + a = DataFoodConsortium::Connector::Address.new( + "https://myplatform.com/a", + street: "street", + postalCode: "postalCode", + city: "city", + country: "country" + ) + cc = DataFoodConsortium::Connector::CustomerCategory.new( + "https://myplatform.com/cc", + description: "description" + ) + sp = DataFoodConsortium::Connector::SuppliedProduct.new( + "https://myplatform.com/sp", + name: "name", + description: "description", + productType: connector.PRODUCT_TYPES.VEGETABLE.ARTICHOKE, + quantity: DataFoodConsortium::Connector::QuantitativeValue.new( + unit: connector.MEASURES.UNIT.QUANTITYUNIT.KILOGRAM, + value: 1.2 + ), + totalTheoreticalStock: 123, + alcoholPercentage: 2.6, + lifetime: "lifetime", + usageOrStorageConditions: "usageOrStorageConditions", + certifications: [connector.FACETS.CERTIFICATION.BIODYNAMICLABEL.DEMETER], + claims: [ + connector.FACETS.CLAIM.NUTRITIONALCLAIM.ENERGYFREE, + connector.FACETS.CLAIM.NUTRITIONALCLAIM.FATFREE, + connector.FACETS.CLAIM.NUTRITIONALCLAIM.HIGHFIBRE + ], + allergenCharacteristics: [ + + ], + nutrientCharacteristics: [ + DataFoodConsortium::Connector::NutrientCharacteristic.new( + nutrientDimension: connector.MEASURES.DIMENSION.NUTRIENTDIMENSION.CALCIUM, + unit: connector.MEASURES.UNIT.QUANTITYUNIT.GRAM, + value: 8.47 + ) + ], + physicalCharacteristics: [ + DataFoodConsortium::Connector::PhysicalCharacteristic.new( + physicalDimension: connector.MEASURES.DIMENSION.PHYSICALDIMENSION.WEIGHT, + unit: connector.MEASURES.UNIT.QUANTITYUNIT.KILOGRAM, + value: 3.25 + ) + ], + geographicalOrigin: connector.FACETS.TERRITORIALORIGIN.EUROPE.FRANCE.NORMANDY, + natureOrigin: connector.FACETS.NATUREORIGIN.PLANTORIGIN, + partOrigin: connector.FACETS.NATUREORIGIN.PLANTORIGIN + ) + o = DataFoodConsortium::Connector::Offer.new( + "https://myplatform.com/o", + price: DataFoodConsortium::Connector::Price.new( + value: 12.78, + vatRate: 5.22, + unit: connector.MEASURES.UNIT.CURRENCYUNIT.EURO + ), + stockLimitation: 52, + offeredTo: cc + ) + ci = DataFoodConsortium::Connector::CatalogItem.new( + "https://myplatform.com/ci", + product: sp, + sku: "sku", + stockLimitation: 10, + offers: [o] + ) + e = DataFoodConsortium::Connector::Enterprise.new( + "https://myplatform.com/e", + name: "name", + description: "description", + vatNumber: "vatNumber", + customerCategories: [cc], + suppliedProducts: [sp], + catalogItems: [ci], + contacts: [], + localizations: [] + ) + p = DataFoodConsortium::Connector::Person.new( + "https://myplatform.com/p", + firstName: "firstName", + lastName: "lastName", + affiliatedOrganizations: [e], + contacts: [], + localizations: [a] + ) + actual = connector.export(p, a, e, cc, sp, ci, o) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@graph":[{"@id":"https://myplatform.com/p","@type":"dfc-b:Person","dfc-b:hasAddress":"https://myplatform.com/a","dfc-b:firstName":"firstName","dfc-b:familyName":"lastName","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#affiliates":"https://myplatform.com/e"},{"@id":"https://myplatform.com/a","@type":"dfc-b:Address","dfc-b:hasStreet":"street","dfc-b:hasPostalCode":"postalCode","dfc-b:hasCity":"city","dfc-b:hasCountry":"country"},{"@id":"https://myplatform.com/e","@type":"dfc-b:Enterprise","dfc-b:hasName":"name","dfc-b:hasDescription":"description","dfc-b:VATnumber":"vatNumber","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#defines":"https://myplatform.com/cc","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#supplies":"https://myplatform.com/sp","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#manages":"https://myplatform.com/ci"},{"@id":"https://myplatform.com/cc","@type":"dfc-b:CustomerCategory","dfc-b:description":"description"},{"@id":"https://myplatform.com/sp","@type":"dfc-b:SuppliedProduct","dfc-b:name":"name","dfc-b:description":"description","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasType":"http://static.datafoodconsortium.org/data/productTypes.rdf#artichoke","dfc-b:hasQuantity":{"@type":"dfc-b:QuantitativeValue","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasUnit":"dfc-m:Kilogram","dfc-b:value":1.2},"dfc-b:alcoholPercentage":2.6,"dfc-b:lifetime":"lifetime","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasClaim":["dfc-f:EnergyFree","dfc-f:FatFree","dfc-f:HighFibre"],"dfc-b:usageOrStorageCondition":"usageOrStorageConditions","dfc-b:hasNutrientCharacteristic":{"@type":"dfc-b:NutrientCharacteristic","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasUnit":"dfc-m:Gram","dfc-b:value":8.47,"dfc-b:hasNutrientDimension":"dfc-m:Calcium"},"dfc-b:hasPhysicalCharacteristic":{"@type":"dfc-b:PhysicalCharacteristic","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasUnit":"dfc-m:Kilogram","dfc-b:value":3.25,"http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasPhysicalDimension":"dfc-m:Weight"},"http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasGeographicalOrigin":"dfc-f:Normandy","dfc-b:hasCertification":"dfc-f:Demeter","dfc-b:hasNatureOrigin":"dfc-f:PlantOrigin","dfc-b:hasPartOrigin":"dfc-f:PlantOrigin","dfc-b:totalTheoreticalStock":123},{"@id":"https://myplatform.com/ci","@type":"dfc-b:CatalogItem","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#references":"https://myplatform.com/sp","dfc-b:sku":"sku","dfc-b:stockLimitation":10,"http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#offeredThrough":"https://myplatform.com/o"},{"@id":"https://myplatform.com/o","@type":"dfc-b:Offer","dfc-b:price":{"@type":"dfc-b:Price","dfc-b:value":12.78,"dfc-b:VATrate":5.22,"http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasUnit":"dfc-m:Euro"},"dfc-b:stockLimitation":52,"dfc-b:offeredTo":"https://myplatform.com/cc"}]}' + assert_equal expected, actual + end + +end \ No newline at end of file diff --git a/test/test_offer.rb b/test/test_offer.rb new file mode 100644 index 0000000..a52a8d7 --- /dev/null +++ b/test/test_offer.rb @@ -0,0 +1,33 @@ +require 'connector' +require "minitest/autorun" +require 'datafoodconsortium/connector' + +class OfferTest < Minitest::Test + + def test_export_empty + o = DataFoodConsortium::Connector::Offer.new("https://myplatform.com/o") + actual = connector.export(o) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/o","@type":"dfc-b:Offer","dfc-b:stockLimitation":0.0}' + assert_equal expected, actual + end + + def test_export_complete + ci = DataFoodConsortium::Connector::CatalogItem.new("https://myplatform.com/ci") + cc = DataFoodConsortium::Connector::CustomerCategory.new("https://myplatform.com/cc") + o = DataFoodConsortium::Connector::Offer.new( + "https://myplatform.com/o", + price: DataFoodConsortium::Connector::Price.new( + value: 12.78, + vatRate: 5.22, + unit: connector.MEASURES.UNIT.CURRENCYUNIT.EURO + ), + stockLimitation: 52, + offeredItem: ci, + offeredTo: cc + ) + actual = connector.export(o) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/o","@type":"dfc-b:Offer","dfc-b:price":{"@type":"dfc-b:Price","dfc-b:value":12.78,"dfc-b:VATrate":5.22,"http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasUnit":"dfc-m:Euro"},"dfc-b:stockLimitation":52,"dfc-b:offeredItem":"https://myplatform.com/ci","dfc-b:offeredTo":"https://myplatform.com/cc"}' + assert_equal expected, actual + end + +end \ No newline at end of file diff --git a/test/test_person.rb b/test/test_person.rb new file mode 100644 index 0000000..59ef62a --- /dev/null +++ b/test/test_person.rb @@ -0,0 +1,32 @@ +require 'connector' +require "minitest/autorun" +require 'datafoodconsortium/connector' + +class PersonTest < Minitest::Test + + def test_export_empty + p = DataFoodConsortium::Connector::Person.new("https://myplatform.com/p") + actual = connector.export(p) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/p","@type":"dfc-b:Person","dfc-b:firstName":"","dfc-b:familyName":""}' + assert_equal expected, actual + end + + def test_export_complete + p = DataFoodConsortium::Connector::Person.new( + "https://myplatform.com/p", + firstName: "firstName", + lastName: "lastName", + affiliatedOrganizations: [ + DataFoodConsortium::Connector::Enterprise.new("https://myplatform.com/e") + ], + contacts: [], + localizations: [ + DataFoodConsortium::Connector::Address.new("https://myplatform.com/a") + ] + ) + actual = connector.export(p) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/p","@type":"dfc-b:Person","dfc-b:hasAddress":"https://myplatform.com/a","dfc-b:firstName":"firstName","dfc-b:familyName":"lastName","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#affiliates":"https://myplatform.com/e"}' + assert_equal expected, actual + end + +end \ No newline at end of file diff --git a/test/test_supplied_product.rb b/test/test_supplied_product.rb new file mode 100644 index 0000000..109a861 --- /dev/null +++ b/test/test_supplied_product.rb @@ -0,0 +1,63 @@ +require 'connector' +require "minitest/autorun" +require 'datafoodconsortium/connector' + +class SuppliedProductTest < Minitest::Test + + def test_export_empty + sp = DataFoodConsortium::Connector::SuppliedProduct.new("https://myplatform.com/sp") + actual = connector.export(sp) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/sp","@type":"dfc-b:SuppliedProduct","dfc-b:name":"","dfc-b:description":"","dfc-b:alcoholPercentage":0.0,"dfc-b:lifetime":"","dfc-b:usageOrStorageCondition":"","dfc-b:totalTheoreticalStock":0.0}' + assert_equal expected, actual + end + + def test_export_complete + quantity = DataFoodConsortium::Connector::QuantitativeValue.new( + unit: connector.MEASURES.UNIT.QUANTITYUNIT.KILOGRAM, + value: 1.2 + ) + + sp = DataFoodConsortium::Connector::SuppliedProduct.new( + "https://myplatform.com/sp", + name: "name", + description: "description", + productType: connector.PRODUCT_TYPES.VEGETABLE.ARTICHOKE, + quantity: quantity, + totalTheoreticalStock: 123, + alcoholPercentage: 2.6, + lifetime: "lifetime", + usageOrStorageConditions: "usageOrStorageConditions", + certifications: [connector.FACETS.CERTIFICATION.BIODYNAMICLABEL.DEMETER], + claims: [ + connector.FACETS.CLAIM.NUTRITIONALCLAIM.ENERGYFREE, + connector.FACETS.CLAIM.NUTRITIONALCLAIM.FATFREE, + connector.FACETS.CLAIM.NUTRITIONALCLAIM.HIGHFIBRE + ], + allergenCharacteristics: [ + + ], + nutrientCharacteristics: [ + DataFoodConsortium::Connector::NutrientCharacteristic.new( + nutrientDimension: connector.MEASURES.DIMENSION.NUTRIENTDIMENSION.CALCIUM, + unit: connector.MEASURES.UNIT.QUANTITYUNIT.GRAM, + value: 8.47 + ) + ], + physicalCharacteristics: [ + DataFoodConsortium::Connector::PhysicalCharacteristic.new( + physicalDimension: connector.MEASURES.DIMENSION.PHYSICALDIMENSION.WEIGHT, + unit: connector.MEASURES.UNIT.QUANTITYUNIT.KILOGRAM, + value: 3.25 + ) + ], + geographicalOrigin: connector.FACETS.TERRITORIALORIGIN.EUROPE.FRANCE.NORMANDY, + natureOrigin: connector.FACETS.NATUREORIGIN.PLANTORIGIN, + partOrigin: connector.FACETS.NATUREORIGIN.PLANTORIGIN + ) + + actual = connector.export(sp) + expected = '{"@context":"http://static.datafoodconsortium.org/ontologies/context.json","@id":"https://myplatform.com/sp","@type":"dfc-b:SuppliedProduct","dfc-b:name":"name","dfc-b:description":"description","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasType":"http://static.datafoodconsortium.org/data/productTypes.rdf#artichoke","dfc-b:hasQuantity":{"@type":"dfc-b:QuantitativeValue","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasUnit":"dfc-m:Kilogram","dfc-b:value":1.2},"dfc-b:alcoholPercentage":2.6,"dfc-b:lifetime":"lifetime","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasClaim":["dfc-f:EnergyFree","dfc-f:FatFree","dfc-f:HighFibre"],"dfc-b:usageOrStorageCondition":"usageOrStorageConditions","dfc-b:hasNutrientCharacteristic":{"@type":"dfc-b:NutrientCharacteristic","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasUnit":"dfc-m:Gram","dfc-b:value":8.47,"dfc-b:hasNutrientDimension":"dfc-m:Calcium"},"dfc-b:hasPhysicalCharacteristic":{"@type":"dfc-b:PhysicalCharacteristic","http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasUnit":"dfc-m:Kilogram","dfc-b:value":3.25,"http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasPhysicalDimension":"dfc-m:Weight"},"http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl#hasGeographicalOrigin":"dfc-f:Normandy","dfc-b:hasCertification":"dfc-f:Demeter","dfc-b:hasNatureOrigin":"dfc-f:PlantOrigin","dfc-b:hasPartOrigin":"dfc-f:PlantOrigin","dfc-b:totalTheoreticalStock":123}' + assert_equal expected, actual + end + +end