Commits

José Manuel Sánchez Peñarroja  committed de8170d

Added stats sub spec for average stats. Added average value

  • Participants
  • Parent commits 2d0260f

Comments (0)

Files changed (9)

     core.subspec "Data" do |s|
       s.source_files = 'bmf/shared/data/*.{h,m}'
 
-      core.subspec "Data Sources" do |s|
+      s.subspec "Data Sources" do |s|
         s.source_files = 'bmf/shared/data/data sources/**/*.{h,m}'
         s.ios.source_files = 'bmf/ios/data/data sources/**/*.{h,m}'
       end
       
-      core.subspec "Data Stores" do |s|
+      s.subspec "Data Stores" do |s|
         s.source_files = 'bmf/shared/data/data stores/**/*.{h,m}'
         s.ios.source_files = 'bmf/ios/data/data stores/**/*.{h,m}'
       end
       
-      core.subspec "Operations" do |s|
+      s.subspec "Operations" do |s|
         s.source_files = 'bmf/shared/data/operations/**/*.{h,m}'
         s.ios.source_files = 'bmf/ios/data/operations/**/*.{h,m}'
       end
       
-      core.subspec "Loaders" do |s|
+      s.subspec "Loaders" do |s|
         s.source_files = 'bmf/shared/data/loaders/**/*.{h,m}'
       end
 
-      core.subspec "Parsers" do |s|
+      s.subspec "Parsers" do |s|
         s.source_files = 'bmf/shared/data/parsers/**/*.{h,m}'
       end
 
-      core.subspec "Serializers" do |s|
+      s.subspec "Serializers" do |s|
         s.source_files = 'bmf/shared/data/serializers/**/*.{h,m}'
       end
 
-      core.subspec "Writers" do |s|
+      s.subspec "Writers" do |s|
         s.source_files = 'bmf/shared/data/writers/**/*.{h,m}'
       end
     end
     
+    core.subspec "Stats" do |s|
+      s.source_files = 'bmf/shared/stats/**/*.{h,m}'
+    end
+    
     core.subspec "Factories" do |s|
       s.source_files = 'bmf/shared/factories/**/*.{h,m}'
       s.ios.source_files = 'bmf/ios/factories/**/*.{h,m}'

File Example/Example.xcworkspace/xcuserdata/josanchez.xcuserdatad/UserInterfaceState.xcuserstate

Binary file modified.

File Example/Example.xcworkspace/xcuserdata/josanchez.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

             stopOnStyle = "0">
          </BreakpointContent>
       </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Example/bmfTests/bmfStatTests.m"
+            timestampString = "423067075.830446"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "52"
+            endingLineNumber = "52"
+            landmarkName = "SpecBegin()"
+            landmarkType = "6">
+            <Locations>
+               <Location
+                  shouldBeEnabled = "No"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "__27-[StatsSpec spt_defineSpec]_block_invoke_4"
+                  moduleName = "bmfTests"
+                  urlString = "file:///Users/josanchez/prog/bmf/Example/Example/bmfTests/bmfStatTests.m"
+                  timestampString = "423065404.042889"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "51"
+                  endingLineNumber = "51"
+                  offsetFromSymbolStart = "1286">
+               </Location>
+               <Location
+                  shouldBeEnabled = "No"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "__27-[StatsSpec spt_defineSpec]_block_invoke_13"
+                  moduleName = "bmfTests"
+                  urlString = "file:///Users/josanchez/prog/bmf/Example/Example/bmfTests/bmfStatTests.m"
+                  timestampString = "423065404.043444"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "51"
+                  endingLineNumber = "51"
+                  offsetFromSymbolStart = "62">
+               </Location>
+            </Locations>
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Example/bmfTests/bmfStatTests.m"
+            timestampString = "423067075.830446"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "59"
+            endingLineNumber = "59"
+            landmarkName = "SpecBegin()"
+            landmarkType = "6">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "../bmf/shared/stats/BMFAverageStats.m"
+            timestampString = "423066047.517172"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "72"
+            endingLineNumber = "72"
+            landmarkName = "-setDefaultValue:forKey:"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "../bmf/shared/stats/BMFAverageStats.m"
+            timestampString = "423066190.768451"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "73"
+            endingLineNumber = "73"
+            landmarkName = "-setDefaultValue:forKey:"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Example/bmfTests/bmfStatTests.m"
+            timestampString = "423067075.830446"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "60"
+            endingLineNumber = "60"
+            landmarkName = "SpecBegin()"
+            landmarkType = "6">
+            <Locations>
+               <Location
+                  shouldBeEnabled = "No"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "__27-[StatsSpec spt_defineSpec]_block_invoke66"
+                  moduleName = "bmfTests"
+                  urlString = "file:///Users/josanchez/prog/bmf/Example/Example/bmfTests/bmfStatTests.m"
+                  timestampString = "423066729.652639"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "59"
+                  endingLineNumber = "59"
+                  offsetFromSymbolStart = "288">
+               </Location>
+               <Location
+                  shouldBeEnabled = "No"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "__27-[StatsSpec spt_defineSpec]_block_invoke_372"
+                  moduleName = "bmfTests"
+                  urlString = "file:///Users/josanchez/prog/bmf/Example/Example/bmfTests/bmfStatTests.m"
+                  timestampString = "423066729.653152"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "59"
+                  endingLineNumber = "59"
+                  offsetFromSymbolStart = "62">
+               </Location>
+            </Locations>
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "../bmf/shared/stats/BMFAverageStats.m"
+            timestampString = "423066312.076342"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "102"
+            endingLineNumber = "102"
+            landmarkName = "-averageValueForKey:"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "../bmf/shared/stats/BMFAverageStats.m"
+            timestampString = "423066313.700975"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "105"
+            endingLineNumber = "105"
+            landmarkName = "-averageValueForKey:"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "../bmf/shared/stats/BMFAverageStats.m"
+            timestampString = "423068018.805176"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "112"
+            endingLineNumber = "112"
+            landmarkName = "-averageValueForKey:"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Example/bmfTests/bmfStatTests.m"
+            timestampString = "423067050.680944"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "85"
+            endingLineNumber = "85"
+            landmarkName = "SpecBegin()"
+            landmarkType = "6">
+            <Locations>
+               <Location
+                  shouldBeEnabled = "No"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "__27-[StatsSpec spt_defineSpec]_block_invoke106"
+                  moduleName = "bmfTests"
+                  urlString = "file:///Users/josanchez/prog/bmf/Example/Example/bmfTests/bmfStatTests.m"
+                  timestampString = "423068856.462854"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "85"
+                  endingLineNumber = "85"
+                  offsetFromSymbolStart = "296">
+               </Location>
+               <Location
+                  shouldBeEnabled = "No"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "__27-[StatsSpec spt_defineSpec]_block_invoke_2107"
+                  moduleName = "bmfTests"
+                  urlString = "file:///Users/josanchez/prog/bmf/Example/Example/bmfTests/bmfStatTests.m"
+                  timestampString = "423068856.463361"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "85"
+                  endingLineNumber = "85"
+                  offsetFromSymbolStart = "62">
+               </Location>
+            </Locations>
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Example/bmfTests/bmfStatTests.m"
+            timestampString = "423067054.176957"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "66"
+            endingLineNumber = "66"
+            landmarkName = "SpecBegin()"
+            landmarkType = "6">
+            <Locations>
+               <Location
+                  shouldBeEnabled = "No"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "__27-[StatsSpec spt_defineSpec]_block_invoke81"
+                  moduleName = "bmfTests"
+                  urlString = "file:///Users/josanchez/prog/bmf/Example/Example/bmfTests/bmfStatTests.m"
+                  timestampString = "423067096.348836"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "66"
+                  endingLineNumber = "66"
+                  offsetFromSymbolStart = "124">
+               </Location>
+               <Location
+                  shouldBeEnabled = "No"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "__27-[StatsSpec spt_defineSpec]_block_invoke_284"
+                  moduleName = "bmfTests"
+                  urlString = "file:///Users/josanchez/prog/bmf/Example/Example/bmfTests/bmfStatTests.m"
+                  timestampString = "423067096.349505"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "66"
+                  endingLineNumber = "66"
+                  offsetFromSymbolStart = "62">
+               </Location>
+            </Locations>
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "../bmf/shared/stats/BMFAverageStats.m"
+            timestampString = "423067235.141878"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "101"
+            endingLineNumber = "101"
+            landmarkName = "-averageValueForKey:"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "../bmf/shared/stats/BMFAverageStats.m"
+            timestampString = "423068018.805176"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "108"
+            endingLineNumber = "108"
+            landmarkName = "-averageValueForKey:"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Example/bmfTests/bmfStatTests.m"
+            timestampString = "423067281.80734"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "65"
+            endingLineNumber = "65"
+            landmarkName = "SpecBegin()"
+            landmarkType = "6">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "../bmf/shared/stats/BMFAverageStats.m"
+            timestampString = "423067682.154555"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "93"
+            endingLineNumber = "93"
+            landmarkName = "-addValue:forKey:"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Example/bmfTests/bmfStatTests.m"
+            timestampString = "423067865.759252"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "74"
+            endingLineNumber = "74"
+            landmarkName = "SpecBegin()"
+            landmarkType = "6">
+            <Locations>
+               <Location
+                  shouldBeEnabled = "No"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "__27-[StatsSpec spt_defineSpec]_block_invoke92"
+                  moduleName = "bmfTests"
+                  urlString = "file:///Users/josanchez/prog/bmf/Example/Example/bmfTests/bmfStatTests.m"
+                  timestampString = "423067904.793595"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "74"
+                  endingLineNumber = "74"
+                  offsetFromSymbolStart = "406">
+               </Location>
+               <Location
+                  shouldBeEnabled = "No"
+                  ignoreCount = "0"
+                  continueAfterRunningActions = "No"
+                  symbolName = "__27-[StatsSpec spt_defineSpec]_block_invoke_398"
+                  moduleName = "bmfTests"
+                  urlString = "file:///Users/josanchez/prog/bmf/Example/Example/bmfTests/bmfStatTests.m"
+                  timestampString = "423067904.794088"
+                  startingColumnNumber = "9223372036854775807"
+                  endingColumnNumber = "9223372036854775807"
+                  startingLineNumber = "74"
+                  endingLineNumber = "74"
+                  offsetFromSymbolStart = "62">
+               </Location>
+            </Locations>
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "Example/bmfTests/bmfStatTests.m"
+            timestampString = "423069071.906495"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "81"
+            endingLineNumber = "81"
+            landmarkName = "SpecBegin()"
+            landmarkType = "6">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            shouldBeEnabled = "No"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "../bmf/shared/values/BMFAverageValue.m"
+            timestampString = "423069146.458782"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "55"
+            endingLineNumber = "55"
+            landmarkName = "-addValue:"
+            landmarkType = "5">
+         </BreakpointContent>
+      </BreakpointProxy>
    </Breakpoints>
 </Bucket>

File Example/Example/Example.xcodeproj/project.pbxproj

 		AC82DEDD1869873E00CB335E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = AC82DEDB1869873E00CB335E /* InfoPlist.strings */; };
 		AC82DEDF1869873E00CB335E /* ExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AC82DEDE1869873E00CB335E /* ExampleTests.m */; };
 		AC85DA0718FD3DFD00F60102 /* bmfValueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AC85DA0618FD3DFD00F60102 /* bmfValueTests.m */; };
+		ACAEE81E193747760020C42B /* bmfStatTests.m in Sources */ = {isa = PBXBuildFile; fileRef = ACAEE81D193747760020C42B /* bmfStatTests.m */; };
 		ACCFF1491910E65B002BC1FD /* bmfUtilsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = ACCFF1481910E65B002BC1FD /* bmfUtilsTests.m */; };
 		ACD3C2C818EC4D9D002FE462 /* BMFExampleTestConfigurator.m in Sources */ = {isa = PBXBuildFile; fileRef = ACD3C2C718EC4D9D002FE462 /* BMFExampleTestConfigurator.m */; };
 		ACFD504318FE9B0B005511E9 /* ExampleCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ACFD504218FE9B0B005511E9 /* ExampleCollectionViewController.m */; };
 		AC82DEDE1869873E00CB335E /* ExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExampleTests.m; sourceTree = "<group>"; };
 		AC85DA0618FD3DFD00F60102 /* bmfValueTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = bmfValueTests.m; sourceTree = "<group>"; };
 		AC99835E18A4DAEF004AB11B /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Crashlytics.framework; sourceTree = "<group>"; };
+		ACAEE81D193747760020C42B /* bmfStatTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = bmfStatTests.m; sourceTree = "<group>"; };
 		ACB9E965705442149781C224 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		ACCFF1481910E65B002BC1FD /* bmfUtilsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = bmfUtilsTests.m; sourceTree = "<group>"; };
 		ACD3C2C618EC4D9D002FE462 /* BMFExampleTestConfigurator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BMFExampleTestConfigurator.h; sourceTree = "<group>"; };
 				AC472F5E1929E968004FCBEC /* bmfObjectDataStoreTests.m */,
 				AC66CE4F18F2B45000B633C9 /* bmfConditionTests.m */,
 				ACCFF1481910E65B002BC1FD /* bmfUtilsTests.m */,
+				ACAEE81D193747760020C42B /* bmfStatTests.m */,
 				AC1D14C5187D700E008598EB /* Supporting Files */,
 			);
 			path = bmfTests;
 			buildActionMask = 2147483647;
 			files = (
 				AC1D14CB187D700E008598EB /* bmfTests.m in Sources */,
+				ACAEE81E193747760020C42B /* bmfStatTests.m in Sources */,
 				AC52FBEF18F42ECF007FA26E /* bmfDataStoreTests.m in Sources */,
 				AC7BBF3718F6AC0A00CD7BA4 /* bmfEncodingTests.m in Sources */,
 				ACCFF1491910E65B002BC1FD /* bmfUtilsTests.m in Sources */,

File Example/Example/bmfTests/bmfStatTests.m

+//
+//  bmfStatTests.m
+//  Example
+//
+//  Created by Jose Manuel Sánchez Peñarroja on 30/04/14.
+//  Copyright (c) 2014 José Manuel Sánchez. All rights reserved.
+//
+
+#import <XCTest/XCTest.h>
+
+#import <Specta/Specta.h>
+#define EXP_SHORTHAND
+#import <Expecta/Expecta.h>
+#import <OCMock/OCMock.h>
+
+#import <BMF/BMFAverageStats.h>
+#import <BMF/BMFUtils.h>
+
+static NSURL *statsFileUrl = nil;
+static BMFAverageStats *stats = nil;
+
+SpecBegin(Stats)
+
+describe(@"BMFAverageStats", ^{
+	
+	beforeAll(^{
+		statsFileUrl = [NSURL fileURLWithPath:[[BMFUtils applicationCacheDirectory] stringByAppendingPathComponent:@"com.bmfTests"]];
+		stats = [[BMFAverageStats alloc] initWithFileUrl:statsFileUrl];
+		[stats removeAllValues];
+	});
+	
+	beforeEach(^{
+		stats = [[BMFAverageStats alloc] initWithFileUrl:statsFileUrl];
+		[stats removeAllValues];
+	});
+
+	it(@"should return -DBL_MAX if no default values and no value added", ^{
+		
+		stats = nil;
+		
+		expect(^{ stats = [[BMFAverageStats alloc] init]; }).to.raiseAny();
+		expect(stats).to.beNil();
+		expect(^{ stats = [[BMFAverageStats alloc] initWithFileUrl:nil]; }).to.raiseAny();
+		expect(stats).to.beNil();
+		
+		stats = [BMFAverageStats globalStats];
+		expect(stats).notTo.beNil();
+		
+		stats = [[BMFAverageStats alloc] initWithFileUrl:statsFileUrl];
+		expect(stats).notTo.beNil();
+		
+		expect([stats averageValueForKey:@"blah"]).to.equal(-DBL_MAX);
+	});
+	
+	it(@"should use the default value if no values added", ^{
+				
+		expect(stats).notTo.beNil();
+
+		[stats setDefaultValue:5 forKey:@"blah"];
+		expect([stats averageValueForKey:@"blah"]).to.equal(5);
+	});
+	
+	it(@"should use the added value if only one", ^{
+				
+		[stats addValue:5 forKey:@"blah"];
+		expect([stats averageValueForKey:@"blah"]).to.equal(5);
+	});
+	
+	it(@"should clear values correctly", ^{
+		[stats addValue:5 forKey:@"blah"];
+		expect([stats averageValueForKey:@"blah"]).to.equal(5);
+
+		[stats removeAllValuesForKey:@"blah"];
+		expect([stats averageValueForKey:@"blah"]).to.equal(-DBL_MAX);
+	});
+	
+	it(@"should correctly average values", ^{
+		
+		[stats removeAllValuesForKey:@"blah"];
+				
+		[stats addValue:10 forKey:@"blah"];
+		[stats addValue:20 forKey:@"blah"];
+		[stats addValue:30 forKey:@"blah"];
+		
+		expect([stats averageValueForKey:@"blah"]).to.equal(20);
+	});
+	
+	it(@"should keep values when deleted and created again", ^{
+		[stats addValue:10 forKey:@"blah"];
+		[stats addValue:20 forKey:@"blah"];
+		[stats addValue:30 forKey:@"blah"];
+		
+		stats = nil;
+		
+		stats = [[BMFAverageStats alloc] initWithFileUrl:statsFileUrl];
+		
+		expect([stats averageValueForKey:@"blah"]).to.equal(20);
+	});
+});
+
+
+SpecEnd

File bmf/shared/stats/BMFAverageStats.h

+//
+//  BMFAverageStats.h
+//  Pods
+//
+//  Created by Jose Manuel Sánchez Peñarroja on 29/05/14.
+//
+//
+
+#import <Foundation/Foundation.h>
+
+@interface BMFAverageStats : NSObject
+
++ (instancetype) globalStats;
+
+- (instancetype) initWithFileUrl:(NSURL *) fileUrl;
+
+- (void) setDefaultValue:(double) value forKey:(NSString *) key;
+- (void) removeAllValuesForKey:(NSString *) key;
+- (void) addValue:(double) value forKey:(NSString *) key;
+- (double) averageValueForKey:(NSString *) key;
+
+- (void) removeAllValues;
+
+@end

File bmf/shared/stats/BMFAverageStats.m

+//
+//  BMFAverageStats.m
+//  Pods
+//
+//  Created by Jose Manuel Sánchez Peñarroja on 29/05/14.
+//
+//
+
+#import "BMFAverageStats.h"
+
+#import "BMFAverageValue.h"
+
+#import "BMFUtils.h"
+
+#define BMFAVERAGE_FILE @"com.bmf.stats.average.plist"
+
+static BMFAverageStats *globalInstance = nil;
+
+@interface BMFAverageStats()
+
+@property (nonatomic, strong) NSMutableDictionary *valuesDic;
+
+@property (nonatomic, strong) dispatch_queue_t serialQueue;
+
+@property (nonatomic, strong) NSURL *fileUrl;
+
+@end
+
+@implementation BMFAverageStats
+
+
++ (instancetype) globalStats {
+	if (!globalInstance) {
+		NSString *filePath = [[BMFUtils  applicationCacheDirectory] stringByAppendingPathComponent:BMFAVERAGE_FILE];
+		globalInstance = [[self alloc] initWithFileUrl:[NSURL fileURLWithPath:filePath]];
+	}
+	
+	return globalInstance;
+}
+
+- (instancetype) initWithFileUrl:(NSURL *) fileUrl {
+	BMFAssertReturnNil(fileUrl);
+	
+	self = [super init];
+	if (self) {
+		_fileUrl = fileUrl;
+		
+		_serialQueue = dispatch_queue_create("BMFAverageStatsQueue", DISPATCH_QUEUE_SERIAL);
+		
+		dispatch_sync(_serialQueue, ^{
+			[self load];
+		});
+	}
+	return self;
+}
+
+- (instancetype)init {
+	BMFInvalidInit(initWithFileUrl:);
+}
+
+- (BMFAverageValue *) valueForKey: (NSString *) key {
+	BMFAssertReturnNil(key.length>0);
+	
+	if (!self.valuesDic[key]) self.valuesDic[key] = [BMFAverageValue new];
+	
+	return self.valuesDic[key];
+}
+
+- (void) setDefaultValue:(double) value forKey:(NSString *) key {
+	BMFAssertReturn(key.length>0);
+	
+	dispatch_sync(self.serialQueue, ^{
+		BMFAverageValue *averageValue = [self valueForKey:key];
+		averageValue.defaultValue = @(value);
+		[self save];
+	});
+}
+
+- (void) removeAllValuesForKey:(NSString *) key {
+	BMFAssertReturn(key.length>0);
+	
+	dispatch_sync(self.serialQueue, ^{
+		BMFAverageValue *averageValue = [self valueForKey:key];
+		[averageValue clear];
+		[self save];
+	});
+}
+
+- (void) addValue:(double) value forKey:(NSString *) key {
+	BMFAssertReturn(key.length>0);
+	
+	dispatch_sync(self.serialQueue, ^{
+		BMFAverageValue *averageValue = [self valueForKey:key];
+		[averageValue addValue:@(value)];
+		[self save];
+	});
+}
+
+- (double) averageValueForKey:(NSString *) key {
+	BMFAssertReturnZero(key.length>0);
+	
+	__block double result = -DBL_MAX;
+	
+	dispatch_sync(self.serialQueue, ^{
+		if (self.valuesDic[key]) {
+			BMFAverageValue *averageValue = self.valuesDic[key];
+			NSNumber *currentValue = [averageValue currentValue];
+			if (currentValue) result = [currentValue doubleValue];
+		}
+	});
+	
+	return result;
+}
+
+- (void) removeAllValues {
+	dispatch_sync(self.serialQueue, ^{
+		[_valuesDic removeAllObjects];
+		[self save];
+	});
+}
+
+#pragma mark Persistence
+
+- (void) load {
+	NSData *data = [NSData dataWithContentsOfURL:self.fileUrl];
+	if (data) {
+		@try {
+			_valuesDic = [NSKeyedUnarchiver unarchiveObjectWithData:data];
+		}
+		@catch (NSException *exception) {
+			#warning Remove file at url
+			DDLogError(@"Exception reading file at url: %@ %@",self.fileUrl,exception);
+		}
+	}
+	
+	if (!_valuesDic || ![_valuesDic isKindOfClass:[NSMutableDictionary class]]) _valuesDic = [NSMutableDictionary dictionary];
+}
+
+- (void) save {
+	@try {
+		NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self.valuesDic];
+		if (data) [data writeToURL:self.fileUrl atomically:YES];
+	}
+	@catch (NSException *exception) {
+		DDLogError(@"Exeption writing to file url: %@ %@",self.fileUrl,exception);
+	}
+}
+
+@end

File bmf/shared/values/BMFAverageValue.h

+//
+//  BMFAverageValue.h
+//  Pods
+//
+//  Created by Jose Manuel Sánchez Peñarroja on 29/05/14.
+//
+//
+
+#import "BMFValue.h"
+
+@interface BMFAverageValue : BMFValue <NSCoding>
+
+@property (nonatomic, strong) NSNumber *defaultValue;
+
+- (instancetype) initWithDefaultValue:(NSNumber *) value;
+
+- (void) clear;
+- (void) addValue: (NSNumber *) number;
+
+@end

File bmf/shared/values/BMFAverageValue.m

+//
+//  BMFAverageValue.m
+//  Pods
+//
+//  Created by Jose Manuel Sánchez Peñarroja on 29/05/14.
+//
+//
+
+#import "BMFAverageValue.h"
+
+@interface BMFAverageValue()
+
+@property (nonatomic, strong) NSNumber *averageValue;
+@property (nonatomic, assign) NSUInteger numValues;
+
+@end
+
+@implementation BMFAverageValue
+
+- (instancetype) initWithDefaultValue:(NSNumber *) value {
+	self = [super init];
+	if (self) {
+		_defaultValue = value;
+	}
+	return self;
+}
+
+- (instancetype) init {
+	return [self initWithDefaultValue:nil];
+}
+
+- (void) setDefaultValue:(NSNumber *)defaultValue {
+	_defaultValue = defaultValue;
+	
+	if (self.applyValueBlock) self.applyValueBlock(self);
+}
+
+- (id) currentValue {
+	NSNumber *result = self.defaultValue;
+	if (self.numValues>0) {
+		result = self.averageValue;
+	}
+	
+	return [self prepareValue:result];
+}
+
+- (void) clear {
+	self.numValues = 0;
+	self.averageValue = nil;
+}
+
+- (void) addValue: (NSNumber *) number {
+	BMFAssertReturn(number);
+	
+	if (self.numValues==0) {
+		self.numValues = 1;
+		self.averageValue = number;
+		return;
+	}
+	
+	double newItem = number.doubleValue;
+	double average = self.averageValue.doubleValue;
+	NSUInteger nextNumValues = self.numValues+1;
+	
+	average = average*self.numValues/nextNumValues + newItem/nextNumValues;
+	
+	self.numValues = nextNumValues;
+	self.averageValue = @(average);
+}
+
+#pragma mark NSCoding
+
+- (void) encodeWithCoder:(NSCoder *)aCoder {
+	[aCoder encodeObject:self.defaultValue forKey:@"defaultValue"];
+	[aCoder encodeObject:self.averageValue forKey:@"averageValue"];
+	[aCoder encodeInteger:self.numValues forKey:@"numValues"];
+}
+
+- (instancetype) initWithCoder:(NSCoder *)aDecoder {
+	self = [super init];
+	if (self) {
+		_defaultValue = [aDecoder decodeObjectForKey:@"defaultValue"];
+		_averageValue = [aDecoder decodeObjectForKey:@"averageValue"];
+		_numValues = [aDecoder decodeIntegerForKey:@"numValues"];
+	}
+	return self;
+}
+
+@end