├── .gitignore
├── CSwiftV.podspec
├── CSwiftV.xcodeproj
├── CSwiftVTests_Info.plist
├── CSwiftV_Info.plist
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── xcshareddata
│ └── xcschemes
│ └── CSwiftV-Package.xcscheme
├── LICENSE
├── Package.swift
├── README.md
├── Sources
└── CSwiftV
│ └── CSwiftV.swift
└── Tests
├── CSwiftVTests
├── CSwiftVTests.swift
└── XCTestManifests.swift
└── LinuxMain.swift
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
3 | ## Build generated
4 | build/
5 | DerivedData
6 |
7 | ## Various settings
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 |
18 | ## Other
19 | *.xccheckout
20 | *.moved-aside
21 | *.xcuserstate
22 | *.xcscmblueprint
23 |
24 | ## Obj-C/Swift specific
25 | *.hmap
26 | *.ipa
27 |
28 | ## Swift Package Manager
29 | .build
30 |
--------------------------------------------------------------------------------
/CSwiftV.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 |
3 | s.name = "CSwiftV"
4 | s.version = "0.0.9"
5 | s.summary = "A swift CSV parser"
6 |
7 | s.description = <<-DESC
8 | A csv parser conforming (and tested as much) to [rfc4180](http://tools.ietf.org/html/rfc4180#section-2) i.e the closest thing to a csv spec.
9 | DESC
10 |
11 | s.homepage = "https://github.com/daniel1of1/CSwiftV"
12 |
13 | s.license = "MIT"
14 |
15 | s.author = { "Daniel Haight" => "other@haight.io" }
16 | s.social_media_url = "http://twitter.com/daniel1of1"
17 |
18 | s.ios.deployment_target = "8.0"
19 | s.osx.deployment_target = "10.9"
20 | s.swift_version = '5.0'
21 |
22 | s.source = { :git => "https://github.com/daniel1of1/CSwiftV.git", :tag => s.version }
23 |
24 | s.source_files = "Sources/CSwiftV.swift"
25 |
26 | s.requires_arc = true
27 |
28 | end
29 |
--------------------------------------------------------------------------------
/CSwiftV.xcodeproj/CSwiftVTests_Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CFBundleDevelopmentRegion
5 | en
6 | CFBundleExecutable
7 | $(EXECUTABLE_NAME)
8 | CFBundleIdentifier
9 | $(PRODUCT_BUNDLE_IDENTIFIER)
10 | CFBundleInfoDictionaryVersion
11 | 6.0
12 | CFBundleName
13 | $(PRODUCT_NAME)
14 | CFBundlePackageType
15 | BNDL
16 | CFBundleShortVersionString
17 | 1.0
18 | CFBundleSignature
19 | ????
20 | CFBundleVersion
21 | $(CURRENT_PROJECT_VERSION)
22 | NSPrincipalClass
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/CSwiftV.xcodeproj/CSwiftV_Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CFBundleDevelopmentRegion
5 | en
6 | CFBundleExecutable
7 | $(EXECUTABLE_NAME)
8 | CFBundleIdentifier
9 | $(PRODUCT_BUNDLE_IDENTIFIER)
10 | CFBundleInfoDictionaryVersion
11 | 6.0
12 | CFBundleName
13 | $(PRODUCT_NAME)
14 | CFBundlePackageType
15 | FMWK
16 | CFBundleShortVersionString
17 | 1.0
18 | CFBundleSignature
19 | ????
20 | CFBundleVersion
21 | $(CURRENT_PROJECT_VERSION)
22 | NSPrincipalClass
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/CSwiftV.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = "1";
4 | objectVersion = "46";
5 | objects = {
6 | "CSwiftV::CSwiftV" = {
7 | isa = "PBXNativeTarget";
8 | buildConfigurationList = "OBJ_20";
9 | buildPhases = (
10 | "OBJ_23",
11 | "OBJ_25"
12 | );
13 | dependencies = (
14 | );
15 | name = "CSwiftV";
16 | productName = "CSwiftV";
17 | productReference = "CSwiftV::CSwiftV::Product";
18 | productType = "com.apple.product-type.framework";
19 | };
20 | "CSwiftV::CSwiftV::Product" = {
21 | isa = "PBXFileReference";
22 | path = "CSwiftV.framework";
23 | sourceTree = "BUILT_PRODUCTS_DIR";
24 | };
25 | "CSwiftV::CSwiftVPackageTests::ProductTarget" = {
26 | isa = "PBXAggregateTarget";
27 | buildConfigurationList = "OBJ_33";
28 | buildPhases = (
29 | );
30 | dependencies = (
31 | "OBJ_36"
32 | );
33 | name = "CSwiftVPackageTests";
34 | productName = "CSwiftVPackageTests";
35 | };
36 | "CSwiftV::CSwiftVTests" = {
37 | isa = "PBXNativeTarget";
38 | buildConfigurationList = "OBJ_38";
39 | buildPhases = (
40 | "OBJ_41",
41 | "OBJ_43"
42 | );
43 | dependencies = (
44 | "OBJ_45"
45 | );
46 | name = "CSwiftVTests";
47 | productName = "CSwiftVTests";
48 | productReference = "CSwiftV::CSwiftVTests::Product";
49 | productType = "com.apple.product-type.bundle.unit-test";
50 | };
51 | "CSwiftV::CSwiftVTests::Product" = {
52 | isa = "PBXFileReference";
53 | path = "CSwiftVTests.xctest";
54 | sourceTree = "BUILT_PRODUCTS_DIR";
55 | };
56 | "CSwiftV::SwiftPMPackageDescription" = {
57 | isa = "PBXNativeTarget";
58 | buildConfigurationList = "OBJ_27";
59 | buildPhases = (
60 | "OBJ_30"
61 | );
62 | dependencies = (
63 | );
64 | name = "CSwiftVPackageDescription";
65 | productName = "CSwiftVPackageDescription";
66 | productType = "com.apple.product-type.framework";
67 | };
68 | "OBJ_1" = {
69 | isa = "PBXProject";
70 | attributes = {
71 | LastSwiftMigration = "9999";
72 | LastUpgradeCheck = "9999";
73 | };
74 | buildConfigurationList = "OBJ_2";
75 | compatibilityVersion = "Xcode 3.2";
76 | developmentRegion = "English";
77 | hasScannedForEncodings = "0";
78 | knownRegions = (
79 | "en"
80 | );
81 | mainGroup = "OBJ_5";
82 | productRefGroup = "OBJ_13";
83 | projectDirPath = ".";
84 | targets = (
85 | "CSwiftV::CSwiftV",
86 | "CSwiftV::SwiftPMPackageDescription",
87 | "CSwiftV::CSwiftVPackageTests::ProductTarget",
88 | "CSwiftV::CSwiftVTests"
89 | );
90 | };
91 | "OBJ_10" = {
92 | isa = "PBXGroup";
93 | children = (
94 | "OBJ_11"
95 | );
96 | name = "Tests";
97 | path = "";
98 | sourceTree = "SOURCE_ROOT";
99 | };
100 | "OBJ_11" = {
101 | isa = "PBXGroup";
102 | children = (
103 | "OBJ_12"
104 | );
105 | name = "CSwiftVTests";
106 | path = "Tests/CSwiftVTests";
107 | sourceTree = "SOURCE_ROOT";
108 | };
109 | "OBJ_12" = {
110 | isa = "PBXFileReference";
111 | path = "CSwiftVTests.swift";
112 | sourceTree = "";
113 | };
114 | "OBJ_13" = {
115 | isa = "PBXGroup";
116 | children = (
117 | "CSwiftV::CSwiftV::Product",
118 | "CSwiftV::CSwiftVTests::Product"
119 | );
120 | name = "Products";
121 | path = "";
122 | sourceTree = "BUILT_PRODUCTS_DIR";
123 | };
124 | "OBJ_16" = {
125 | isa = "PBXFileReference";
126 | path = "LICENSE";
127 | sourceTree = "";
128 | };
129 | "OBJ_17" = {
130 | isa = "PBXFileReference";
131 | path = "CSwiftV.podspec";
132 | sourceTree = "";
133 | };
134 | "OBJ_18" = {
135 | isa = "PBXFileReference";
136 | path = "README.md";
137 | sourceTree = "";
138 | };
139 | "OBJ_2" = {
140 | isa = "XCConfigurationList";
141 | buildConfigurations = (
142 | "OBJ_3",
143 | "OBJ_4"
144 | );
145 | defaultConfigurationIsVisible = "0";
146 | defaultConfigurationName = "Release";
147 | };
148 | "OBJ_20" = {
149 | isa = "XCConfigurationList";
150 | buildConfigurations = (
151 | "OBJ_21",
152 | "OBJ_22"
153 | );
154 | defaultConfigurationIsVisible = "0";
155 | defaultConfigurationName = "Release";
156 | };
157 | "OBJ_21" = {
158 | isa = "XCBuildConfiguration";
159 | buildSettings = {
160 | ENABLE_TESTABILITY = "YES";
161 | FRAMEWORK_SEARCH_PATHS = (
162 | "$(inherited)",
163 | "$(PLATFORM_DIR)/Developer/Library/Frameworks"
164 | );
165 | HEADER_SEARCH_PATHS = (
166 | "$(inherited)"
167 | );
168 | INFOPLIST_FILE = "CSwiftV.xcodeproj/CSwiftV_Info.plist";
169 | IPHONEOS_DEPLOYMENT_TARGET = "8.0";
170 | LD_RUNPATH_SEARCH_PATHS = (
171 | "$(inherited)",
172 | "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx"
173 | );
174 | MACOSX_DEPLOYMENT_TARGET = "10.10";
175 | OTHER_CFLAGS = (
176 | "$(inherited)"
177 | );
178 | OTHER_LDFLAGS = (
179 | "$(inherited)"
180 | );
181 | OTHER_SWIFT_FLAGS = (
182 | "$(inherited)"
183 | );
184 | PRODUCT_BUNDLE_IDENTIFIER = "CSwiftV";
185 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
186 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
187 | SKIP_INSTALL = "YES";
188 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = (
189 | "$(inherited)"
190 | );
191 | SWIFT_VERSION = "5.0";
192 | TARGET_NAME = "CSwiftV";
193 | TVOS_DEPLOYMENT_TARGET = "9.0";
194 | WATCHOS_DEPLOYMENT_TARGET = "2.0";
195 | };
196 | name = "Debug";
197 | };
198 | "OBJ_22" = {
199 | isa = "XCBuildConfiguration";
200 | buildSettings = {
201 | ENABLE_TESTABILITY = "YES";
202 | FRAMEWORK_SEARCH_PATHS = (
203 | "$(inherited)",
204 | "$(PLATFORM_DIR)/Developer/Library/Frameworks"
205 | );
206 | HEADER_SEARCH_PATHS = (
207 | "$(inherited)"
208 | );
209 | INFOPLIST_FILE = "CSwiftV.xcodeproj/CSwiftV_Info.plist";
210 | IPHONEOS_DEPLOYMENT_TARGET = "8.0";
211 | LD_RUNPATH_SEARCH_PATHS = (
212 | "$(inherited)",
213 | "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx"
214 | );
215 | MACOSX_DEPLOYMENT_TARGET = "10.10";
216 | OTHER_CFLAGS = (
217 | "$(inherited)"
218 | );
219 | OTHER_LDFLAGS = (
220 | "$(inherited)"
221 | );
222 | OTHER_SWIFT_FLAGS = (
223 | "$(inherited)"
224 | );
225 | PRODUCT_BUNDLE_IDENTIFIER = "CSwiftV";
226 | PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
227 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
228 | SKIP_INSTALL = "YES";
229 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = (
230 | "$(inherited)"
231 | );
232 | SWIFT_VERSION = "5.0";
233 | TARGET_NAME = "CSwiftV";
234 | TVOS_DEPLOYMENT_TARGET = "9.0";
235 | WATCHOS_DEPLOYMENT_TARGET = "2.0";
236 | };
237 | name = "Release";
238 | };
239 | "OBJ_23" = {
240 | isa = "PBXSourcesBuildPhase";
241 | files = (
242 | "OBJ_24"
243 | );
244 | };
245 | "OBJ_24" = {
246 | isa = "PBXBuildFile";
247 | fileRef = "OBJ_9";
248 | };
249 | "OBJ_25" = {
250 | isa = "PBXFrameworksBuildPhase";
251 | files = (
252 | );
253 | };
254 | "OBJ_27" = {
255 | isa = "XCConfigurationList";
256 | buildConfigurations = (
257 | "OBJ_28",
258 | "OBJ_29"
259 | );
260 | defaultConfigurationIsVisible = "0";
261 | defaultConfigurationName = "Release";
262 | };
263 | "OBJ_28" = {
264 | isa = "XCBuildConfiguration";
265 | buildSettings = {
266 | LD = "/usr/bin/true";
267 | OTHER_SWIFT_FLAGS = (
268 | "-swift-version",
269 | "5",
270 | "-I",
271 | "$(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2",
272 | "-target",
273 | "x86_64-apple-macosx10.10",
274 | "-sdk",
275 | "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk"
276 | );
277 | SWIFT_VERSION = "5.0";
278 | };
279 | name = "Debug";
280 | };
281 | "OBJ_29" = {
282 | isa = "XCBuildConfiguration";
283 | buildSettings = {
284 | LD = "/usr/bin/true";
285 | OTHER_SWIFT_FLAGS = (
286 | "-swift-version",
287 | "5",
288 | "-I",
289 | "$(TOOLCHAIN_DIR)/usr/lib/swift/pm/4_2",
290 | "-target",
291 | "x86_64-apple-macosx10.10",
292 | "-sdk",
293 | "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk"
294 | );
295 | SWIFT_VERSION = "5.0";
296 | };
297 | name = "Release";
298 | };
299 | "OBJ_3" = {
300 | isa = "XCBuildConfiguration";
301 | buildSettings = {
302 | CLANG_ENABLE_OBJC_ARC = "YES";
303 | COMBINE_HIDPI_IMAGES = "YES";
304 | COPY_PHASE_STRIP = "NO";
305 | DEBUG_INFORMATION_FORMAT = "dwarf";
306 | DYLIB_INSTALL_NAME_BASE = "@rpath";
307 | ENABLE_NS_ASSERTIONS = "YES";
308 | GCC_OPTIMIZATION_LEVEL = "0";
309 | GCC_PREPROCESSOR_DEFINITIONS = (
310 | "$(inherited)",
311 | "SWIFT_PACKAGE=1",
312 | "DEBUG=1"
313 | );
314 | MACOSX_DEPLOYMENT_TARGET = "10.10";
315 | ONLY_ACTIVE_ARCH = "YES";
316 | OTHER_SWIFT_FLAGS = (
317 | "-DXcode"
318 | );
319 | PRODUCT_NAME = "$(TARGET_NAME)";
320 | SDKROOT = "macosx";
321 | SUPPORTED_PLATFORMS = (
322 | "macosx",
323 | "iphoneos",
324 | "iphonesimulator",
325 | "appletvos",
326 | "appletvsimulator",
327 | "watchos",
328 | "watchsimulator"
329 | );
330 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = (
331 | "$(inherited)",
332 | "SWIFT_PACKAGE",
333 | "DEBUG"
334 | );
335 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
336 | USE_HEADERMAP = "NO";
337 | };
338 | name = "Debug";
339 | };
340 | "OBJ_30" = {
341 | isa = "PBXSourcesBuildPhase";
342 | files = (
343 | "OBJ_31"
344 | );
345 | };
346 | "OBJ_31" = {
347 | isa = "PBXBuildFile";
348 | fileRef = "OBJ_6";
349 | };
350 | "OBJ_33" = {
351 | isa = "XCConfigurationList";
352 | buildConfigurations = (
353 | "OBJ_34",
354 | "OBJ_35"
355 | );
356 | defaultConfigurationIsVisible = "0";
357 | defaultConfigurationName = "Release";
358 | };
359 | "OBJ_34" = {
360 | isa = "XCBuildConfiguration";
361 | buildSettings = {
362 | };
363 | name = "Debug";
364 | };
365 | "OBJ_35" = {
366 | isa = "XCBuildConfiguration";
367 | buildSettings = {
368 | };
369 | name = "Release";
370 | };
371 | "OBJ_36" = {
372 | isa = "PBXTargetDependency";
373 | target = "CSwiftV::CSwiftVTests";
374 | };
375 | "OBJ_38" = {
376 | isa = "XCConfigurationList";
377 | buildConfigurations = (
378 | "OBJ_39",
379 | "OBJ_40"
380 | );
381 | defaultConfigurationIsVisible = "0";
382 | defaultConfigurationName = "Release";
383 | };
384 | "OBJ_39" = {
385 | isa = "XCBuildConfiguration";
386 | buildSettings = {
387 | CLANG_ENABLE_MODULES = "YES";
388 | EMBEDDED_CONTENT_CONTAINS_SWIFT = "YES";
389 | FRAMEWORK_SEARCH_PATHS = (
390 | "$(inherited)",
391 | "$(PLATFORM_DIR)/Developer/Library/Frameworks"
392 | );
393 | HEADER_SEARCH_PATHS = (
394 | "$(inherited)"
395 | );
396 | INFOPLIST_FILE = "CSwiftV.xcodeproj/CSwiftVTests_Info.plist";
397 | IPHONEOS_DEPLOYMENT_TARGET = "8.0";
398 | LD_RUNPATH_SEARCH_PATHS = (
399 | "$(inherited)",
400 | "@loader_path/../Frameworks",
401 | "@loader_path/Frameworks"
402 | );
403 | MACOSX_DEPLOYMENT_TARGET = "10.10";
404 | OTHER_CFLAGS = (
405 | "$(inherited)"
406 | );
407 | OTHER_LDFLAGS = (
408 | "$(inherited)"
409 | );
410 | OTHER_SWIFT_FLAGS = (
411 | "$(inherited)"
412 | );
413 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = (
414 | "$(inherited)"
415 | );
416 | SWIFT_VERSION = "5.0";
417 | TARGET_NAME = "CSwiftVTests";
418 | TVOS_DEPLOYMENT_TARGET = "9.0";
419 | WATCHOS_DEPLOYMENT_TARGET = "2.0";
420 | };
421 | name = "Debug";
422 | };
423 | "OBJ_4" = {
424 | isa = "XCBuildConfiguration";
425 | buildSettings = {
426 | CLANG_ENABLE_OBJC_ARC = "YES";
427 | COMBINE_HIDPI_IMAGES = "YES";
428 | COPY_PHASE_STRIP = "YES";
429 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
430 | DYLIB_INSTALL_NAME_BASE = "@rpath";
431 | GCC_OPTIMIZATION_LEVEL = "s";
432 | GCC_PREPROCESSOR_DEFINITIONS = (
433 | "$(inherited)",
434 | "SWIFT_PACKAGE=1"
435 | );
436 | MACOSX_DEPLOYMENT_TARGET = "10.10";
437 | OTHER_SWIFT_FLAGS = (
438 | "-DXcode"
439 | );
440 | PRODUCT_NAME = "$(TARGET_NAME)";
441 | SDKROOT = "macosx";
442 | SUPPORTED_PLATFORMS = (
443 | "macosx",
444 | "iphoneos",
445 | "iphonesimulator",
446 | "appletvos",
447 | "appletvsimulator",
448 | "watchos",
449 | "watchsimulator"
450 | );
451 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = (
452 | "$(inherited)",
453 | "SWIFT_PACKAGE"
454 | );
455 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
456 | USE_HEADERMAP = "NO";
457 | };
458 | name = "Release";
459 | };
460 | "OBJ_40" = {
461 | isa = "XCBuildConfiguration";
462 | buildSettings = {
463 | CLANG_ENABLE_MODULES = "YES";
464 | EMBEDDED_CONTENT_CONTAINS_SWIFT = "YES";
465 | FRAMEWORK_SEARCH_PATHS = (
466 | "$(inherited)",
467 | "$(PLATFORM_DIR)/Developer/Library/Frameworks"
468 | );
469 | HEADER_SEARCH_PATHS = (
470 | "$(inherited)"
471 | );
472 | INFOPLIST_FILE = "CSwiftV.xcodeproj/CSwiftVTests_Info.plist";
473 | IPHONEOS_DEPLOYMENT_TARGET = "8.0";
474 | LD_RUNPATH_SEARCH_PATHS = (
475 | "$(inherited)",
476 | "@loader_path/../Frameworks",
477 | "@loader_path/Frameworks"
478 | );
479 | MACOSX_DEPLOYMENT_TARGET = "10.10";
480 | OTHER_CFLAGS = (
481 | "$(inherited)"
482 | );
483 | OTHER_LDFLAGS = (
484 | "$(inherited)"
485 | );
486 | OTHER_SWIFT_FLAGS = (
487 | "$(inherited)"
488 | );
489 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = (
490 | "$(inherited)"
491 | );
492 | SWIFT_VERSION = "5.0";
493 | TARGET_NAME = "CSwiftVTests";
494 | TVOS_DEPLOYMENT_TARGET = "9.0";
495 | WATCHOS_DEPLOYMENT_TARGET = "2.0";
496 | };
497 | name = "Release";
498 | };
499 | "OBJ_41" = {
500 | isa = "PBXSourcesBuildPhase";
501 | files = (
502 | "OBJ_42"
503 | );
504 | };
505 | "OBJ_42" = {
506 | isa = "PBXBuildFile";
507 | fileRef = "OBJ_12";
508 | };
509 | "OBJ_43" = {
510 | isa = "PBXFrameworksBuildPhase";
511 | files = (
512 | "OBJ_44"
513 | );
514 | };
515 | "OBJ_44" = {
516 | isa = "PBXBuildFile";
517 | fileRef = "CSwiftV::CSwiftV::Product";
518 | };
519 | "OBJ_45" = {
520 | isa = "PBXTargetDependency";
521 | target = "CSwiftV::CSwiftV";
522 | };
523 | "OBJ_5" = {
524 | isa = "PBXGroup";
525 | children = (
526 | "OBJ_6",
527 | "OBJ_7",
528 | "OBJ_10",
529 | "OBJ_13",
530 | "OBJ_16",
531 | "OBJ_17",
532 | "OBJ_18"
533 | );
534 | path = "";
535 | sourceTree = "";
536 | };
537 | "OBJ_6" = {
538 | isa = "PBXFileReference";
539 | explicitFileType = "sourcecode.swift";
540 | path = "Package.swift";
541 | sourceTree = "";
542 | };
543 | "OBJ_7" = {
544 | isa = "PBXGroup";
545 | children = (
546 | "OBJ_8"
547 | );
548 | name = "Sources";
549 | path = "";
550 | sourceTree = "SOURCE_ROOT";
551 | };
552 | "OBJ_8" = {
553 | isa = "PBXGroup";
554 | children = (
555 | "OBJ_9"
556 | );
557 | name = "CSwiftV";
558 | path = "Sources/CSwiftV";
559 | sourceTree = "SOURCE_ROOT";
560 | };
561 | "OBJ_9" = {
562 | isa = "PBXFileReference";
563 | path = "CSwiftV.swift";
564 | sourceTree = "";
565 | };
566 | };
567 | rootObject = "OBJ_1";
568 | }
569 |
--------------------------------------------------------------------------------
/CSwiftV.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
--------------------------------------------------------------------------------
/CSwiftV.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/CSwiftV.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CSwiftV.xcodeproj/xcshareddata/xcschemes/CSwiftV-Package.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
55 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
74 |
76 |
77 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015, Daniel Haight
2 |
3 |
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without modification,
7 | are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice,
10 | this list of conditions and the following disclaimer.
11 | * Redistributions in binary form must reproduce the above copyright notice,
12 | this list of conditions and the following disclaimer in the documentation
13 | and/or other materials provided with the distribution.
14 | * Neither the name of CSwiftV nor the names of its contributors
15 | may be used to endorse or promote products derived from this software
16 | without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 |
30 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.0
2 | import PackageDescription
3 |
4 | let package = Package(
5 | name: "CSwiftV",
6 | products: [
7 | .library(
8 | name: "CSwiftV",
9 | targets: ["CSwiftV"]),
10 | ],
11 | targets: [
12 | .target(
13 | name: "CSwiftV",
14 | dependencies: []),
15 | .testTarget(
16 | name: "CSwiftVTests",
17 | dependencies: ["CSwiftV"]),
18 | ]
19 | )
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CSwiftV
2 |
3 | A csv parser conforming (and tested as much) to [rfc4180](http://tools.ietf.org/html/rfc4180#section-2) i.e the closest thing to a csv spec.
4 |
5 | It is currently all in memory so not suitable for very large files.
6 |
7 | ### TL;DR
8 |
9 | ```swift
10 | let inputString = "Year,Make,Model,Description,Price\r\n1997,Ford,E350,descrition,3000.00\r\n1999,Chevy,Venture,another description,4900.00\r\n"
11 |
12 | let csv = CSwiftV(with: inputString)
13 |
14 | let rows = csv.rows // [
15 | // ["1997","Ford","E350","descrition","3000.00"],
16 | // ["1999","Chevy","Venture","another description","4900.00"]
17 | // ]
18 |
19 | let headers = csv.headers // ["Year","Make","Model","Description","Price"]
20 |
21 | let keyedRows = csv.keyedRows // [
22 | // ["Year":"1997","Make":"Ford","Model":"E350","Description":"descrition","Price":"3000.00"],
23 | // ["Year":"1999","Make":"Chevy","Model":"Venture","Description":"another, description","Price":"4900.00"]
24 | // ]
25 |
26 | ```
27 |
--------------------------------------------------------------------------------
/Sources/CSwiftV/CSwiftV.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CSwiftV.swift
3 | // CSwiftV
4 | //
5 | // Created by Daniel Haight on 30/08/2014.
6 | // Copyright (c) 2014 ManyThings. All rights reserved.
7 | //
8 |
9 | import class Foundation.NSCharacterSet
10 |
11 | extension String {
12 |
13 | var isEmptyOrWhitespace: Bool {
14 | return isEmpty || trimmingCharacters(in: .whitespaces) == ""
15 | }
16 |
17 | var isNotEmptyOrWhitespace: Bool {
18 | return !isEmptyOrWhitespace
19 | }
20 |
21 | }
22 |
23 | // MARK: Parser
24 | public class CSwiftV {
25 |
26 | /// The number of columns in the data
27 | private let columnCount: Int
28 | /// The headers from the data, an Array of String
29 | public let headers: [String]
30 | /// An array of Dictionaries with the values of each row keyed to the header
31 | public let keyedRows: [[String: String]]?
32 | /// An Array of the rows in an Array of String form, equivalent to keyedRows, but without the keys
33 | public let rows: [[String]]
34 |
35 | /// Creates an instance containing the data extracted from the `with` String
36 | /// - Parameter with: The String obtained from reading the csv file.
37 | /// - Parameter separator: The separator used in the csv file, defaults to ","
38 | /// - Parameter headers: The array of headers from the file. If not included, it will be populated with the ones from the first line
39 | public init(with string: String, separator: String = ",", headers: [String]? = nil) {
40 | var parsedLines = CSwiftV.records(from: string.replacingOccurrences(of: "\r\n", with: "\n")).map { CSwiftV.cells(forRow: $0, separator: separator) }
41 | self.headers = headers ?? parsedLines.removeFirst()
42 | rows = parsedLines
43 | columnCount = self.headers.count
44 |
45 | let tempHeaders = self.headers
46 | keyedRows = rows.map { field -> [String: String] in
47 | var row = [String: String]()
48 | // Only store value which are not empty
49 | for (index, value) in field.enumerated() where value.isNotEmptyOrWhitespace {
50 | if index < tempHeaders.count {
51 | row[tempHeaders[index]] = value
52 | }
53 | }
54 | return row
55 | }
56 | }
57 |
58 | /// Creates an instance containing the data extracted from the `with` String
59 | /// - Parameter with: The string obtained from reading the csv file.
60 | /// - Parameter headers: The array of headers from the file. I f not included, it will be populated with the ones from the first line
61 | /// - Attention: In this conveniennce initializer, we assume that the separator between fields is ","
62 | public convenience init(with string: String, headers: [String]?) {
63 | self.init(with: string, separator:",", headers:headers)
64 | }
65 |
66 | /// Analizes a row and tries to obtain the different cells contained as an Array of String
67 | /// - Parameter forRow: The string corresponding to a row of the data matrix
68 | /// - Parameter separator: The string that delimites the cells or fields inside the row. Defaults to ","
69 | internal static func cells(forRow string: String, separator: String = ",") -> [String] {
70 | return CSwiftV.split(separator, string: string)
71 | }
72 |
73 | /// Analizes the CSV data as an String, and separates the different rows as an individual String each.
74 | /// - Parameter forRow: The string corresponding the whole data
75 | /// - Attention: Assumes "\n" as row delimiter, needs to filter string for "\r\n" first
76 | internal static func records(from string: String) -> [String] {
77 | return CSwiftV.split("\n", string: string).filter { $0.isNotEmptyOrWhitespace }
78 | }
79 |
80 | /// Tries to preserve the parity between open and close characters for different formats. Analizes the escape character count to do so
81 | private static func split(_ separator: String, string: String) -> [String] {
82 | func oddNumberOfQuotes(_ string: String) -> Bool {
83 | return string.components(separatedBy: "\"").count % 2 == 0
84 | }
85 |
86 | let initial = string.components(separatedBy: separator)
87 | var merged = [String]()
88 | for newString in initial {
89 | guard let record = merged.last , oddNumberOfQuotes(record) == true else {
90 | merged.append(newString)
91 | continue
92 | }
93 | merged.removeLast()
94 | let lastElem = record + separator + newString
95 | merged.append(lastElem)
96 | }
97 | return merged
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/Tests/CSwiftVTests/CSwiftVTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CSwiftVTests.swift
3 | // CSwiftVTests
4 | //
5 | // Created by Daniel Haight on 30/08/2014.
6 | // Copyright (c) 2014 ManyThings. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import XCTest
11 |
12 | @testable import CSwiftV
13 |
14 | public let emptyColumns = "Year,Make,Model,Description,Price\r\n1997,Ford,,descrition,3000.00\r\n1999,Chevy,Venture,another description,\r\n"
15 |
16 | public let newLineSeparation = "Year,Make,Model,Description,Price\r\n1997,Ford,E350,descrition,3000.00\r\n1999,Chevy,Venture,another description,4900.00\r\n"
17 |
18 | public let newLineSeparationNoCR = "Year,Make,Model,Description,Price\n1997,Ford,E350,descrition,3000.00\n1999,Chevy,Venture,another description,4900.00\n"
19 |
20 | public let newLineSeparationNoEnd = "Year,Make,Model,Description,Price\r\n1997,Ford,E350,descrition,3000.00\r\n1999,Chevy,Venture,another description,4900.00"
21 |
22 | public let withoutHeader = "1997,Ford,E350,descrition,3000.00\r\n1999,Chevy,Venture,another description,4900.00"
23 |
24 | public let longerColumns = "Year,Make,Model,Description,Price\r\n1997,Ford,E350,descrition,3000.00\r\n1999,Chevy,Venture,another description,4900.00,extra column\r\n"
25 |
26 | public let withRandomQuotes = "Year,Make,Model,Description,Price\r\n1997,Ford,\"E350\",descrition,3000.00\r\n1999,Chevy,Venture,\"another description\",4900.00"
27 |
28 | public let withCommasInQuotes = "Year,Make,Model,Description,Price\r\n1997,Ford,\"E350\",descrition,3000.00\r\n1999,Chevy,Venture,\"another, amazing, description\",4900.00"
29 |
30 | public let withQuotesInQuotes = "Year,Make,Model,Description,Price\r\n1997,Ford,\"E350\",descrition,3000.00\r\n1999,Chevy,Venture,\"another, \"\"amazing\"\", description\",4900.00"
31 |
32 | public let withNewLinesInQuotes = "Year,Make,Model,Description,Price\n1997,Ford,\"E350\",descrition,3000.00\n1999,Chevy,Venture,\"another, \"\"amazing\"\",\n\ndescription\n\",4900.00\n"
33 |
34 | public let withTabSeparator = "Year\tMake\tModel\tDescription\tPrice\r\n1997\tFord\t\"E350\"\tdescrition\t3000.00\r\n1999\tChevy\tVenture\t\"another\t \"\"amazing\"\"\t description\"\t4900.00\r\n"
35 |
36 | public let singleString = "1999,Chevy,Venture,\"another, \"\"amazing\"\",\n\ndescription\n\",4900.00"
37 |
38 | class CSwiftVTests: XCTestCase {
39 |
40 | lazy var nativeSwiftStringCSV: String = {
41 | var string = "Timestamp,Number1,Number2"
42 | for _ in 1...10_000 {
43 | string += ("20150101000100,100,0\n")
44 | }
45 | return string
46 | }()
47 |
48 | var testString: String!
49 |
50 | // modelling from http://tools.ietf.org/html/rfc4180#section-2
51 |
52 | //1. Each record is located on a separate line, delimited by a line
53 | //break (CRLF). For example:
54 |
55 | //aaa,bbb,ccc CRLF
56 | //zzz,yyy,xxx CRLF
57 | func testThatItParsesLinesSeperatedByNewLines() {
58 | testString = newLineSeparation
59 |
60 | let arrayUnderTest = CSwiftV(with: testString).rows
61 |
62 | let expectedArray = [
63 | ["1997","Ford","E350","descrition","3000.00"],
64 | ["1999","Chevy","Venture","another description","4900.00"]
65 | ]
66 |
67 | XCTAssertEqual(arrayUnderTest[0], expectedArray[0])
68 | XCTAssertEqual(arrayUnderTest[1], expectedArray[1])
69 | }
70 |
71 | func testThatItParsesLinesSeperatedByNewLinesNoCR() {
72 | testString = newLineSeparationNoCR
73 |
74 | let arrayUnderTest = CSwiftV(with: testString).rows
75 |
76 | let expectedArray = [
77 | ["1997","Ford","E350","descrition","3000.00"],
78 | ["1999","Chevy","Venture","another description","4900.00"]
79 | ]
80 |
81 | XCTAssertEqual(arrayUnderTest[0], expectedArray[0])
82 | XCTAssertEqual(arrayUnderTest[1], expectedArray[1])
83 | }
84 |
85 | //2. The last record in the file may or may not have an ending line
86 | //break. For example:
87 |
88 | //aaa,bbb,ccc CRLF
89 | //zzz,yyy,xxx
90 |
91 | func testThatItParsesLinesSeperatedByNewLinesWithoutNewLineAtEnd() {
92 |
93 | testString = newLineSeparationNoEnd
94 |
95 | let arrayUnderTest = CSwiftV(with: testString).rows
96 |
97 | let expectedArray = [
98 | ["1997","Ford","E350","descrition","3000.00"],
99 | ["1999","Chevy","Venture","another description","4900.00"]
100 | ]
101 |
102 | XCTAssertEqual(arrayUnderTest[0], expectedArray[0])
103 | XCTAssertEqual(arrayUnderTest[1], expectedArray[1])
104 | }
105 |
106 | //3. There maybe an optional header line appearing as the first line
107 | //of the file with the same format as normal record lines. This
108 | //header will contain names corresponding to the fields in the file
109 | //and should contain the same number of fields as the records in
110 | //the rest of the file (the presence or absence of the header line
111 | //should be indicated via the optional "header" parameter of this
112 | //MIME type). For example:
113 |
114 | //field_name,field_name,field_name CRLF
115 | //aaa,bbb,ccc CRLF
116 | //zzz,yyy,xxx CRLF
117 | func testThatItParsesHeadersCorrectly() {
118 |
119 | testString = newLineSeparationNoEnd
120 |
121 | let arrayUnderTest : [String] = CSwiftV(with: testString).headers
122 |
123 | let expectedArray = ["Year","Make","Model","Description","Price"]
124 |
125 | XCTAssertEqual(arrayUnderTest, expectedArray)
126 |
127 | }
128 |
129 | // still 3. in RFC. This is the first decision we make in
130 | // api design with regards to headers. Currently if nothing
131 | // is passed in to the `headers` parameter (as is the case)
132 | // with the convenience initialiser. We assume that the csv
133 | // contains headers. If the headers are passed in, then we
134 | // assume that the csv file does not contain them and expect
135 | // it to be parsed accordingly.
136 | func testThatItParsesRowsWithoutHeaders() {
137 |
138 | testString = withoutHeader
139 |
140 | let arrayUnderTest = CSwiftV(with: testString, separator:",", headers:["Year","Make","Model","Description","Price"]).rows
141 |
142 | //XCTAssertNil(arrayUnderTest)
143 |
144 | let expectedArray = [
145 | ["1997","Ford","E350","descrition","3000.00"],
146 | ["1999","Chevy","Venture","another description","4900.00"]
147 | ]
148 |
149 | XCTAssertEqual(arrayUnderTest[0], expectedArray[0])
150 | XCTAssertEqual(arrayUnderTest[1], expectedArray[1])
151 | }
152 |
153 | // Covers the case where a row is longer than the header row.
154 | func testThatItParsesRowsLongerThanHeaders() {
155 |
156 | testString = longerColumns
157 | let csv = CSwiftV(with: testString)
158 |
159 | let expectedArray = [
160 | ["1997","Ford","E350","descrition","3000.00"],
161 | ["1999","Chevy","Venture","another description","4900.00","extra column"]
162 | ]
163 |
164 | XCTAssertEqual(csv.rows[0], expectedArray[0])
165 | XCTAssertEqual(csv.rows[1], expectedArray[1])
166 |
167 | let expectedKeyedRows = [
168 | ["Year":"1997", "Make": "Ford", "Model": "E350", "Description": "descrition", "Price":"3000.00"],
169 | ["Year":"1999", "Make": "Chevy", "Model": "Venture", "Description":"another description", "Price":"4900.00"]
170 | ]
171 |
172 | XCTAssertEqual(csv.keyedRows![0], expectedKeyedRows[0])
173 | XCTAssertEqual(csv.keyedRows![1], expectedKeyedRows[1])
174 | }
175 |
176 |
177 | // 4. Within the header and each record, there may be one or more
178 | // fields, separated by commas. Each line should contain the same
179 | // number of fields throughout the file. Spaces are considered part
180 | // of a field and should not be ignored. The last field in the
181 | // record must not be followed by a comma. For example:
182 | //
183 | // aaa,bbb,ccc
184 | //
185 | // This is covered by previous test cases since there are spaces in
186 | // fields and no commas at the end of the lines
187 | //
188 | // 5. Each field may or may not be enclosed in double quotes (however
189 | // some programs, such as Microsoft Excel, do not use double quotes
190 | // at all). If fields are not enclosed with double quotes, then
191 | // double quotes may not appear inside the fields. For example:
192 | //
193 | // "aaa","bbb","ccc" CRLF
194 | // zzz,yyy,xxx
195 | func testThatItParsesFieldswithQuotes() {
196 |
197 | testString = withRandomQuotes
198 |
199 | let arrayUnderTest = CSwiftV(with: testString).rows
200 |
201 | let expectedArray = [
202 | ["1997","Ford","\"E350\"","descrition","3000.00"],
203 | ["1999","Chevy","Venture","\"another description\"","4900.00"]
204 | ]
205 |
206 | XCTAssertEqual(arrayUnderTest[0], expectedArray[0])
207 | XCTAssertEqual(arrayUnderTest[1], expectedArray[1])
208 | }
209 |
210 | // 6. Fields containing line breaks (CRLF), double quotes, and commas
211 | // should be enclosed in double-quotes. For example:
212 | //
213 | // "aaa","b CRLF
214 | // bb","ccc" CRLF
215 | // zzz,yyy,xxx
216 |
217 | func testThatItParsesFieldswithCommasInQuotes() {
218 |
219 | testString = withCommasInQuotes
220 |
221 | let arrayUnderTest = CSwiftV(with: testString).rows
222 |
223 | let expectedArray = [
224 | ["1997","Ford","\"E350\"","descrition","3000.00"],
225 | ["1999","Chevy","Venture","\"another, amazing, description\"","4900.00"]
226 | ]
227 |
228 | XCTAssertEqual(arrayUnderTest[0], expectedArray[0])
229 | XCTAssertEqual(arrayUnderTest[1], expectedArray[1])
230 | }
231 |
232 | func testThatItParsesFieldswithNewLinesInQuotes() {
233 |
234 | testString = withNewLinesInQuotes
235 |
236 | let arrayUnderTest = CSwiftV(with: testString).rows
237 |
238 | let expectedArray = [
239 | ["1997","Ford","\"E350\"","descrition","3000.00"],
240 | ["1999","Chevy","Venture","\"another, \"\"amazing\"\",\n\ndescription\n\"","4900.00"]
241 | ]
242 |
243 | XCTAssertEqual(arrayUnderTest[0], expectedArray[0])
244 | XCTAssertEqual(arrayUnderTest[1], expectedArray[1])
245 | }
246 |
247 | // 7. If double-quotes are used to enclose fields, then a double-quote
248 | // appearing inside a field must be escaped by preceding it with
249 | // another double quote. For example:
250 | //
251 | // "aaa","b""bb","ccc"
252 |
253 | func testThatItParsesFieldswithQuotesInQuotes() {
254 |
255 | testString = withQuotesInQuotes
256 |
257 | let arrayUnderTest = CSwiftV(with: testString).rows
258 |
259 | let expectedArray = [
260 | ["1997","Ford","\"E350\"","descrition","3000.00"],
261 | ["1999","Chevy","Venture","\"another, \"\"amazing\"\", description\"","4900.00"]
262 | ]
263 |
264 | XCTAssertEqual(arrayUnderTest[0], expectedArray[0])
265 | XCTAssertEqual(arrayUnderTest[1], expectedArray[1])
266 | }
267 |
268 | func testThatCanReturnKeyedRows() {
269 |
270 | testString = withQuotesInQuotes
271 |
272 | let arrayUnderTest = CSwiftV(with: testString).keyedRows!
273 |
274 | let expectedArray = [
275 | ["Year":"1997","Make":"Ford","Model":"\"E350\"","Description":"descrition","Price":"3000.00"],
276 | ["Year":"1999","Make":"Chevy","Model":"Venture","Description":"\"another, \"\"amazing\"\", description\"","Price":"4900.00"]
277 | ]
278 |
279 | XCTAssertEqual(arrayUnderTest[0], expectedArray[0])
280 | XCTAssertEqual(arrayUnderTest[1], expectedArray[1])
281 | }
282 |
283 | func testThatItCanParseArbitrarySeparators() {
284 |
285 | testString = withTabSeparator
286 |
287 | let arrayUnderTest = CSwiftV(with: testString, separator:"\t").keyedRows!
288 |
289 | let expectedArray = [
290 | ["Year":"1997","Make":"Ford","Model":"\"E350\"","Description":"descrition","Price":"3000.00"],
291 | ["Year":"1999","Make":"Chevy","Model":"Venture","Description":"\"another\t \"\"amazing\"\"\t description\"","Price":"4900.00"]
292 | ]
293 |
294 | XCTAssertEqual(arrayUnderTest[0], expectedArray[0])
295 | XCTAssertEqual(arrayUnderTest[1], expectedArray[1])
296 | }
297 |
298 | func testThatItCanGetCellsFromAstring() {
299 | testString = withNewLinesInQuotes
300 |
301 | let arrayUnderTest = CSwiftV.records(from: testString)
302 |
303 | let expectedArray = [
304 | "Year,Make,Model,Description,Price",
305 | "1997,Ford,\"E350\",descrition,3000.00",
306 | "1999,Chevy,Venture,\"another, \"\"amazing\"\",\n\ndescription\n\",4900.00"
307 | ]
308 |
309 | XCTAssertEqual(arrayUnderTest, expectedArray)
310 | }
311 |
312 |
313 | func testThatItCanGetCells() {
314 | testString = singleString
315 |
316 | let arrayUnderTest = CSwiftV.cells(forRow: testString)
317 |
318 | let expectedArray = [
319 | "1999",
320 | "Chevy",
321 | "Venture",
322 | "\"another, \"\"amazing\"\",\n\ndescription\n\"",
323 | "4900.00"
324 | ]
325 |
326 | XCTAssertEqual(arrayUnderTest, expectedArray)
327 | }
328 |
329 | func testWhenCellsAreEmpty() {
330 |
331 | testString = emptyColumns
332 | let csv = CSwiftV(with: testString)
333 |
334 | let expectedArray = [
335 | ["1997","Ford","","descrition","3000.00"],
336 | ["1999","Chevy","Venture","another description",""]
337 | ]
338 |
339 | XCTAssertEqual(csv.rows[0], expectedArray[0])
340 | XCTAssertEqual(csv.rows[1], expectedArray[1])
341 |
342 | let expectedKeyedRows = [
343 | ["Year":"1997", "Make": "Ford", "Description":"descrition", "Price":"3000.00"],
344 | ["Year":"1999", "Make": "Chevy", "Model":"Venture", "Description":"another description"]
345 | ]
346 |
347 | XCTAssertEqual(csv.keyedRows![0], expectedKeyedRows[0])
348 | XCTAssertEqual(csv.keyedRows![1], expectedKeyedRows[1])
349 | }
350 |
351 | func testPerformance() {
352 | let testString = nativeSwiftStringCSV
353 | measure {
354 | let _ = CSwiftV(with: testString)
355 | }
356 | }
357 |
358 | }
359 |
--------------------------------------------------------------------------------
/Tests/CSwiftVTests/XCTestManifests.swift:
--------------------------------------------------------------------------------
1 | #if !canImport(ObjectiveC)
2 | import XCTest
3 |
4 | extension CSwiftVTests {
5 | // DO NOT MODIFY: This is autogenerated, use:
6 | // `swift test --generate-linuxmain`
7 | // to regenerate.
8 | static let __allTests__CSwiftVTests = [
9 | ("testPerformance", testPerformance),
10 | ("testThatCanReturnKeyedRows", testThatCanReturnKeyedRows),
11 | ("testThatItCanGetCells", testThatItCanGetCells),
12 | ("testThatItCanGetCellsFromAstring", testThatItCanGetCellsFromAstring),
13 | ("testThatItCanParseArbitrarySeparators", testThatItCanParseArbitrarySeparators),
14 | ("testThatItParsesFieldswithCommasInQuotes", testThatItParsesFieldswithCommasInQuotes),
15 | ("testThatItParsesFieldswithNewLinesInQuotes", testThatItParsesFieldswithNewLinesInQuotes),
16 | ("testThatItParsesFieldswithQuotes", testThatItParsesFieldswithQuotes),
17 | ("testThatItParsesFieldswithQuotesInQuotes", testThatItParsesFieldswithQuotesInQuotes),
18 | ("testThatItParsesHeadersCorrectly", testThatItParsesHeadersCorrectly),
19 | ("testThatItParsesLinesSeperatedByNewLines", testThatItParsesLinesSeperatedByNewLines),
20 | ("testThatItParsesLinesSeperatedByNewLinesNoCR", testThatItParsesLinesSeperatedByNewLinesNoCR),
21 | ("testThatItParsesLinesSeperatedByNewLinesWithoutNewLineAtEnd", testThatItParsesLinesSeperatedByNewLinesWithoutNewLineAtEnd),
22 | ("testThatItParsesRowsLongerThanHeaders", testThatItParsesRowsLongerThanHeaders),
23 | ("testThatItParsesRowsWithoutHeaders", testThatItParsesRowsWithoutHeaders),
24 | ("testTheBadOne", testTheBadOne),
25 | ("testWhenCellsAreEmpty", testWhenCellsAreEmpty),
26 | ]
27 | }
28 |
29 | public func __allTests() -> [XCTestCaseEntry] {
30 | return [
31 | testCase(CSwiftVTests.__allTests__CSwiftVTests),
32 | ]
33 | }
34 | #endif
35 |
--------------------------------------------------------------------------------
/Tests/LinuxMain.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import CSwiftVTests
4 |
5 | var tests = [XCTestCaseEntry]()
6 | tests += CSwiftVTests.__allTests()
7 |
8 | XCTMain(tests)
9 |
--------------------------------------------------------------------------------